from anytree import Node from anytree import RenderTree from anytree import LevelOrderIter, LevelOrderGroupIter from anytree.search import find, findall cut = Node("cut") cool = Node("cool", parent=cut) press = Node("press into pan", parent=cool) stir = Node("stir until coated", parent=press) cereal = Node("crispy rice cereal (6 cups)", parent=stir) melt_stir = Node("stir until melted", parent=stir) marshmellows = Node("marshmellows (10 oz.)", parent=melt_stir) melt = Node("melt", parent=melt_stir) butter = Node("butter (3 tbsp)", parent=melt) output_lines = {} leaves = [node for node in sorted(cut.leaves, key=lambda node: node.depth, reverse=True)] max_leaf_name_length = max([len(leaf.name) for leaf in leaves]) for leaf in leaves: line = f"| {leaf.name.ljust(max_leaf_name_length)} |" output_lines[leaf] = line max_depth = max([leaf.depth for leaf in leaves]) for cur_depth in range(max_depth-1, -1, -1): max_name_length = max([len(node.name) for node in findall(cut, lambda node: node.depth == cur_depth and not node in cut.leaves)]) max_name_length = max(max_name_length, 10) for leaf in leaves: task = find(cut, lambda node: node.depth == cur_depth and node in leaf.path) if task and not task in cut.leaves: output_lines[leaf] += f" {task.name.center(max_name_length)} |" else: output_lines[leaf] += f" {"".ljust(max_name_length)} " for key in output_lines.keys(): print(output_lines[key]) print("") output_lines = [""] * len(cut.leaves) cur_line = 0 last_depth = cut.depth for node in LevelOrderIter(cut): if node in cut.leaves: continue if last_depth != node.depth: cur_line = 0 output_lines[cur_line] = f" {node.name} " + output_lines[cur_line] cur_line += len(node.children) + 1 last_depth = node.depth for line in output_lines: print(line) rows = [] leaves = [] for i in range(len(cut.leaves)): rows.append([]) leaves.append({"name":"wrong"}) cur_row = 0 for level in LevelOrderGroupIter(cut): cur_row = 0 for node in reversed(level): leaf_count = len(node.leaves) if node in cut.leaves: leaves[cur_row] = node else: rows[cur_row].append(f'{node.name}') cur_row += max(leaf_count, 1) last_depth = node.depth for i, leaf in enumerate(leaves): rows[i].append(f"{leaf.name}") rows[i].reverse() print("") for cell in rows[i]: print(cell) print("")