def test_indenting(self): sio = StringIO() f = Indenting(sio) self.assertFalse(f.wrote_any) print('Zero', file=f) self.assertTrue(f.wrote_any) with indent(f): print('Indented\nonce', file=f) with indent(f): print('Indented twice', file=f) print(file=f) print('Back to once\n', file=f) print('Back to nothing', file=f) expect = '''Zero Indented once Indented twice Back to once Back to nothing ''' self.assertEqual(sio.getvalue(), expect) self.assertTrue(f.wrote_any)
def genfunc(file, fixup, ignored_env): if cartprod_names: print(' = '.join(nm for nm in cartprod_names + ['None']), file=file) for preline in condition_prelines: print(preline, file=file) if cartprod_elems: found_tup = env.gensym('_found_tup') tup_elems = ', '.join(as_pyexpr(e) for e in cartprod_elems) whole_crit = f"TupAnd({', '.join(whole_tuple_conditions)})" print( f"{found_tup} = CartesianProduct({tup_elems}, whole_tuple_criterion={whole_crit}).see_one(_g)", file=file) print(f"if {found_tup}:", file=file) with indent(file): if len(cartprod_elems) == 1: print(f"({cartprod_names[0]},) = {found_tup}", file=file) else: print(' = '.join( nm for nm in cartprod_names + [found_tup]), file=file) condition_exprs.insert(0, found_tup) if condition_exprs: print(f"if {' and '.join(condition_exprs)}:", file=file) with indent(file): self.gen_actions(action_prelines, action_exprs, file) if nextgen: print('else:', file=file) with indent(file): gen(nextgen, file, fixup, ignored_env) else: self.gen_actions(action_prelines, action_exprs, file) if nextgen: nextgen(file, fixup, ignored_env)
def log(self, f: Indenting, **kwargs) -> None: print(self.name, file=f) with indent(f): for k, v in kwargs.items(): if isinstance(v, dict): print(f'{short(k)}=', file=f) with indent(f): pr(v, key=short, file=f) else: print(f'{short(k)}={short(v)}', file=f)
def gen(self, file, fixup, env): if self.cond_expr: self.cond_expr.gen_prelines(file, fixup, env) print(f"if {as_pyexpr(self.cond_expr)}:", file=file) with indent(file), env: self.gen_then(file, fixup, env) if self.else_expr: print('else:', file=file) with indent(file), env: self.else_expr.gen(file, fixup, env) else: self.gen_then(file, fixup, env)
def pr(self): '''Prints the slipnet.''' p = Indenting(sys.stdout, prefix=' ') for node in sorted(self.nodes, key=str): print(str(node), file=p) with indent(p): for neighbor in sorted(self.neighbors(node), key=str): print(f'{self.weight(node, neighbor): .2f} {neighbor}', file=p)
def gen_actions(self, file, fixup, env): if self.actions: print('def actions(self):', file=file) with indent(file): print('_g = self.g', file=file) print('_result = []', file=file) for action in self.actions: gen(action, file, fixup, env) print('return _result', file=file)
def logging(lg: Union[Loggable, None], *args, **kwargs): # TODO Document how to use this in a 'with' statement. try: if lg is None: lo(*args, **kwargs) elif logging_is_enabled(lg): lg.log(_logfile, *args, **kwargs) with indent(_logfile): yield _logfile finally: pass
def gen_display_name(self, file, fixup, env): #HACK Should display all non-neighbor args pyexprs = filter_none(lambda p: p.display_name_pyexpr(), self.params) if pyexprs: #print('def display_name(self, _g):', file=file) print('def display_name(self):', file=file) s = ', '.join(f"{{{p}}}" for p in pyexprs) with indent(file): print( #f"return '{self.name}(' + {s} + ')'", f"return f\"{self.name}({s})\"", file=file)
def _gen_tupfunc(self, file, fixup, env): '''Sets .func_name and generates the definition for the function to be passed to TupFunc.''' self.func_name = env.gensym('_f') print(f"def {self.func_name}(_g, _tup):", file=file) with indent(file): self._gen_unpack('_tup', file, fixup, env) for wtc in self.whole_tuple_criteria: wtc.gen_prelines(file, fixup, env) wtcs_py = ' and '.join( as_pyexpr(wtc) for wtc in self.whole_tuple_criteria) print(f"return {wtcs_py}", file=file)
def log(self, f: Indenting, deltas=Sequence[Delta], **kwargs) -> None: print(self.name, file=f) with indent(f): if not deltas: print('No Deltas.', file=f) else: amts: List[float] = [] for delta in sorted(deltas, key=attrgetter('amt')): print(short(delta), file=f) amts.append(delta.amt) print( f'mean={mean(amts):1.8f} hmean={harmonic_mean(amts):1.8f} gmean={geometric_mean(amts):1.8f} median={median(amts):1.8f}', file=f)
def gen_init(self, file, fixup, env): return #TODO rm the rest if self.params or self.inits: #TODO Ideally, we should generate no __init__ function if the #Class has no params not shared by its ancestors and no #initializers. inargs = ', '.join(f'{a}=None' for a in self.args) absorb = '\n'.join(f"kwargs['{a}'] = {a}" for a in self.args) print(f'def __init__(self, {inargs}, **kwargs):', file=file) with indent(file): print(absorb, file=file) print('super().__init__(**kwargs)', file=file) for init in self.inits: gen(init, file, fixup, env)
def gen(self, file, fixup, env): print(f'''class {self.name}({self.str_ancestors()}):''', file=file) file.wrote_any = False with indent(file): self.add_class_var('node_params', repr(NodeParams(*self.params)), no_suffix=True, add_after_class_defns=False) self.gen_class_vars(file, fixup, env) self.gen_init(file, fixup, env) self.gen_actions(file, fixup, env) self.gen_display_name(file, fixup, env) if not file.wrote_any: print('pass\n', file=file) else: print(file=file)
def gen_prelines(self, file, fixup, env): self.tup_name = env.gensym('_found_tup') #print(f"{self.elem_names_comma()} = None", file=file) print(' = '.join(self.elem_names() + ['None']), file=file) for ns in self.nodesearches: ns.expr.gen_prelines(file, fixup, env) ns_py = ', '.join(as_pyexpr(ns.expr) for ns in self.nodesearches) if self.whole_tuple_criteria: self._gen_tupfunc(file, fixup, env) crit_py = f"TupFunc({self.func_name})" if len(self.nodesearches) != 1: crit_py = f"TupAnd(no_dups, {crit_py})" wtc_py = f", whole_tuple_criterion={crit_py}" else: wtc_py = '' print( f"{self.tup_name} = CartesianProduct({ns_py}{wtc_py}).see_one(_g)", file=file) print(f"if {self.tup_name}:", file=file) with indent(file): self._gen_unpack(self.tup_name, file, fixup, env)