1from toolz import curried as tlz 2from toolz import curry 3 4from . import lib as lib 5from . import subcomponent as subcomponent 6from .popularity_contest import popularity_contest 7from .split_paths import split_paths 8 9from .lib import ( 10 # references_graph_to_igraph 11 debug, 12 pick_attrs 13) 14 15funcs = tlz.merge( 16 pick_attrs( 17 [ 18 "flatten", 19 "over", 20 "split_every", 21 "limit_layers", 22 "remove_paths", 23 "reverse" 24 ], 25 lib 26 ), 27 pick_attrs( 28 [ 29 "subcomponent_in", 30 "subcomponent_out", 31 ], 32 subcomponent 33 ), 34 { 35 "split_paths": split_paths, 36 "popularity_contest": popularity_contest, 37 "map": tlz.map 38 } 39) 40 41 42@curry 43def nth_or_none(index, xs): 44 try: 45 return xs[index] 46 except IndexError: 47 return None 48 49 50def preapply_func(func_call_data): 51 [func_name, *args] = func_call_data 52 debug("func_name", func_name) 53 debug("args", args) 54 debug('func_name in ["over"]', func_name in ["over"]) 55 56 # TODO: these could be handled in more generic way by defining, for each 57 # function, which of the args are expected to be functions which need 58 # pre-applying. 59 if func_name == "over": 60 [first_arg, second_arg] = args 61 args = [first_arg, preapply_func(second_arg)] 62 63 elif func_name == "map": 64 args = [preapply_func(args[0])] 65 66 return funcs[func_name](*args) 67 68 69@curry 70def pipe(pipeline, data): 71 debug("pipeline", pipeline) 72 partial_funcs = list(tlz.map(preapply_func, pipeline)) 73 debug('partial_funcs', partial_funcs) 74 return tlz.pipe( 75 data, 76 *partial_funcs 77 ) 78 79 80funcs["pipe"] = pipe