Skip to content

Instantly share code, notes, and snippets.

@mpkocher
Last active December 31, 2015 13:59
Show Gist options
  • Save mpkocher/7997413 to your computer and use it in GitHub Desktop.
Save mpkocher/7997413 to your computer and use it in GitHub Desktop.
import functools
import sys
def _record_starts_with(a_character, record):
"""Returns Bool"""
return record.startswith(a_character)
def _apply_filter_to_record(my_filter, record):
"""Returns bool"""
return my_filter(record)
def _apply_filters_to_record(my_filters, record):
"""Returns bool"""
for my_filter in my_filters:
# exit after the first filter is broken
if not my_filter(record):
return False
return True
def apply_filters(my_filter_funcs, my_list, record):
"""Apply multiple filters"""
if not isinstance(my_filter_funcs, (list, tuple)):
my_filter_funcs = [my_filter_funcs]
if _apply_filters_to_record(my_filter_funcs, record):
my_list.append(record)
def applyer(iterable, funcs):
for i, it in enumerate(iterable):
# printing to show that the data is only iterated over once.
print "Iteration {i}. {t}".format(i=i, t=it)
for func in funcs:
func(it)
def runner():
"""Run basic example.
Threre's three steps.
1. Define Filter functions f(record) -> bool
2. Define aggregator container that will be closed over (using a closure)
3. Use functools.partial to build the function f(record)
4. Glory
"""
# This could be any iterable, rows in a CSV
names = 'ashley ralph rake steve aaron raccoon camel_in_the_tent'.split()
# these will be used close over the state. In the filter_stats example
# these are classes (Aggregator) which have an apply(record) method.
# In general, this is a very general mechanism.
list_with_a = []
list_with_r = []
list_with_rac = []
# Define Filter functions. f(record) -> bool
starts_with_a = functools.partial(_record_starts_with, 'a')
starts_with_r = functools.partial(_record_starts_with, 'r')
starts_with_rac = lambda record: record.startswith('rac')
# Build Filter + Aggregator closure
fa = functools.partial(apply_filters, starts_with_a, list_with_a)
fr = functools.partial(apply_filters, starts_with_r, list_with_r)
#Apply multi-functions. This is the public API
frac = functools.partial(apply_filters, [starts_with_r, starts_with_rac], list_with_rac)
applyer(names, [fa, fr, frac])
# Output the
# In pbreports, this data would be used to create tables, attributes, plots
print "Output for aggregator(s)."
print list_with_a
print list_with_r
print list_with_rac
#(core)7997413 $> python iterables_with_functools.py
#Iteration 0. ashley
#Iteration 1. ralph
#Iteration 2. rake
#Iteration 3. steve
#Iteration 4. aaron
#Iteration 5. raccoon
#Iteration 6. camel_in_the_tent
#Output for aggregator(s).
#['ashley', 'aaron']
#['ralph', 'rake', 'raccoon']
#['raccoon']
def main():
runner()
if __name__ == '__main__':
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment