def main(): graph = Graph() root = Node('root') grandpa = Node('grandpa', parents=[root]) tips = [ Node('child', parents=[ Node('mom', parents=[ Node('grandma', parents=[ Node('greatgrandma', parents=[]), ]), grandpa, ]), Node('dad', parents=[ Node('bill', parents=[ Node('martin'), Node('james'), Node('paul'), Node('jon'), ]) ]), Node('stepdad', parents=[grandpa]), ]), Node('foo', [Node('bar')]), ] graph.show_nodes(tips)
def main(): """Run a simple demo of the package's functionality.""" # start-after from asciidag.graph import Graph from asciidag.node import Node graph = Graph() root = Node('root') grandpa = Node('grandpa', parents=[root]) tips = [ Node('child', parents=[ Node('mom', parents=[ Node('grandma', parents=[ Node('greatgrandma', parents=[]), ]), grandpa, ]), Node('dad', parents=[ Node('bill', parents=[ Node('martin'), Node('james'), Node('paul'), Node('jon'), ])]), Node('stepdad', parents=[grandpa]), ]), Node('foo', [Node('bar')]), ] graph.show_nodes(tips)
def display(self) -> str: with tempfile.NamedTemporaryFile(mode='w+', delete=False) as temp: graph = Graph(fh=temp) nodes = sorted(self.get_nodes(), key=lambda n: n.item) graph.show_nodes(nodes) with open(temp.name) as f: f.seek(0) string = "".join(f.readlines()) return string
def test_linear(simple_nodes, capfd): graph = Graph(use_color=False) graph.show_nodes(simple_nodes) verify_out( capfd, r"""* Second * sixth * fifth * fourth * third * second * initial """)
def test_branched(branched_nodes, capfd): graph = Graph(use_color=False) graph.show_nodes(branched_nodes) verify_out( capfd, r"""* Merge branch 'side' |\ | * side-2 | * side-1 * | Second * | sixth * | fifth * | fourth |/ * third * second * initial""")
def test_tangled(tangled_nodes, capfd): """Test the complex set of nodes.""" graph = Graph(use_color=False) graph.show_nodes(tangled_nodes) verify_out( capfd, r"""* Merge tag 'reach' |\ | \ | \ *-. \ Merge tags 'octopus-a' and 'octopus-b' |\ \ \ * | | | seventh | | * | octopus-b | |/ / |/| | | * | octopus-a |/ / | * reach |/ * Merge branch 'tangle' |\ | * Merge branch 'side' (early part) into tangle | |\ | * \ Merge branch 'master' (early part) into tangle | |\ \ | * | | tangle-a * | | | Merge branch 'side' |\ \ \ \ | * | | | side-2 | | |_|/ | |/| | | * | | side-1 * | | | Second * | | | sixth | |_|/ |/| | * | | fifth * | | fourth |/ / * | third |/ * second * initial""")
def ascii_dag(graph: nx.DiGraph, key: Callable[[str], str] = lambda x: x) -> str: """ Render the given DAG as a string, showing dependencies """ outfile = io.StringIO() ascii_graph = AsciiDagGraph(outfile) nodes = {} tips = [] for node in reversed(list(nx.topological_sort(graph))): parent_nodes = [nodes[path] for path in graph.succ[node]] ascii_node = nodes[node] = AsciiDagNode(key(node), parents=parent_nodes) if not graph.pred[node]: tips.append(ascii_node) ascii_graph.show_nodes(tips) return outfile.getvalue()
def graph(): """Fixture to supply an empty graph.""" return Graph(use_color=False)
def graph(): return Graph(use_color=False)
def get_ascii_graph(result: Union[Array, DictOfNamedArrays], use_color: bool = True) -> str: """Return a string representing the computation of *result* using the `asciidag <https://pypi.org/project/asciidag/>`_ package. :arg result: Outputs of the computation (cf. :func:`pytato.generate_loopy`). :arg use_color: Colorized output """ outputs: DictOfNamedArrays = normalize_outputs(result) del result mapper = ArrayToDotNodeInfoMapper() for elem in outputs._data.values(): mapper(elem) nodes = mapper.nodes input_arrays: List[Array] = [] internal_arrays: List[ArrayOrNames] = [] array_to_id: Dict[ArrayOrNames, str] = {} id_gen = UniqueNameGenerator() for array in nodes: array_to_id[array] = id_gen("array") if isinstance(array, InputArgumentBase): input_arrays.append(array) else: internal_arrays.append(array) # Since 'asciidag' prints the DAG from top to bottom (ie, with the inputs # at the bottom), we need to invert our representation of it, that is, the # 'parents' constructor argument to Node() actually means 'children'. from asciidag.node import Node # type: ignore[import] asciidag_nodes: Dict[ArrayOrNames, Node] = {} from collections import defaultdict asciidag_edges: Dict[ArrayOrNames, List[ArrayOrNames]] = defaultdict(list) # Reverse edge directions for array in internal_arrays: for _, v in nodes[array].edges.items(): asciidag_edges[v].append(array) # Add the internal arrays in reversed order for array in internal_arrays[::-1]: ary_edges = [asciidag_nodes[v] for v in asciidag_edges[array]] if array == internal_arrays[-1]: ary_edges.append(Node("Outputs")) asciidag_nodes[array] = Node(f"{nodes[array].title}", parents=ary_edges) # Add the input arrays last since they have no predecessors for array in input_arrays: ary_edges = [asciidag_nodes[v] for v in asciidag_edges[array]] asciidag_nodes[array] = Node(f"{nodes[array].title}", parents=ary_edges) input_node = Node("Inputs", parents=[asciidag_nodes[v] for v in input_arrays]) from asciidag.graph import Graph # type: ignore[import] from io import StringIO f = StringIO() graph = Graph(fh=f, use_color=use_color) graph.show_nodes([input_node]) # Get the graph and remove trailing whitespace res = "\n".join([s.rstrip() for s in f.getvalue().split("\n")]) return res