Last active
December 31, 2015 13:59
-
-
Save mpkocher/7997413 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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