Spaces:
Paused
Paused
| import random | |
| from itertools import product | |
| from textwrap import dedent | |
| import pytest | |
| import networkx as nx | |
| def test_forest_str_directed(): | |
| # Create a directed forest with labels | |
| graph = nx.balanced_tree(r=2, h=2, create_using=nx.DiGraph) | |
| for node in graph.nodes: | |
| graph.nodes[node]["label"] = "node_" + chr(ord("a") + node) | |
| node_target = dedent( | |
| """ | |
| βββ 0 | |
| βββΌ 1 | |
| β βββΌ 3 | |
| β βββΌ 4 | |
| βββΌ 2 | |
| βββΌ 5 | |
| βββΌ 6 | |
| """ | |
| ).strip() | |
| label_target = dedent( | |
| """ | |
| βββ node_a | |
| βββΌ node_b | |
| β βββΌ node_d | |
| β βββΌ node_e | |
| βββΌ node_c | |
| βββΌ node_f | |
| βββΌ node_g | |
| """ | |
| ).strip() | |
| # Basic node case | |
| ret = nx.forest_str(graph, with_labels=False) | |
| print(ret) | |
| assert ret == node_target | |
| # Basic label case | |
| ret = nx.forest_str(graph, with_labels=True) | |
| print(ret) | |
| assert ret == label_target | |
| # Custom write function case | |
| lines = [] | |
| ret = nx.forest_str(graph, write=lines.append, with_labels=False) | |
| assert ret is None | |
| assert lines == node_target.split("\n") | |
| # Smoke test to ensure passing the print function works. To properly test | |
| # this case we would need to capture stdout. (for potential reference | |
| # implementation see :class:`ubelt.util_stream.CaptureStdout`) | |
| ret = nx.forest_str(graph, write=print) | |
| assert ret is None | |
| def test_write_network_text_empty_graph(): | |
| def _graph_str(g, **kw): | |
| printbuf = [] | |
| nx.write_network_text(g, printbuf.append, end="", **kw) | |
| return "\n".join(printbuf) | |
| assert _graph_str(nx.DiGraph()) == "β" | |
| assert _graph_str(nx.Graph()) == "β" | |
| assert _graph_str(nx.DiGraph(), ascii_only=True) == "+" | |
| assert _graph_str(nx.Graph(), ascii_only=True) == "+" | |
| def test_write_network_text_within_forest_glyph(): | |
| g = nx.DiGraph() | |
| g.add_nodes_from([1, 2, 3, 4]) | |
| g.add_edge(2, 4) | |
| lines = [] | |
| write = lines.append | |
| nx.write_network_text(g, path=write, end="") | |
| nx.write_network_text(g, path=write, ascii_only=True, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| βββ 1 | |
| βββ 2 | |
| β βββΌ 4 | |
| βββ 3 | |
| +-- 1 | |
| +-- 2 | |
| : L-> 4 | |
| +-- 3 | |
| """ | |
| ).strip() | |
| assert text == target | |
| def test_forest_str_directed_multi_tree(): | |
| tree1 = nx.balanced_tree(r=2, h=2, create_using=nx.DiGraph) | |
| tree2 = nx.balanced_tree(r=2, h=2, create_using=nx.DiGraph) | |
| forest = nx.disjoint_union_all([tree1, tree2]) | |
| ret = nx.forest_str(forest) | |
| print(ret) | |
| target = dedent( | |
| """ | |
| βββ 0 | |
| β βββΌ 1 | |
| β β βββΌ 3 | |
| β β βββΌ 4 | |
| β βββΌ 2 | |
| β βββΌ 5 | |
| β βββΌ 6 | |
| βββ 7 | |
| βββΌ 8 | |
| β βββΌ 10 | |
| β βββΌ 11 | |
| βββΌ 9 | |
| βββΌ 12 | |
| βββΌ 13 | |
| """ | |
| ).strip() | |
| assert ret == target | |
| tree3 = nx.balanced_tree(r=2, h=2, create_using=nx.DiGraph) | |
| forest = nx.disjoint_union_all([tree1, tree2, tree3]) | |
| ret = nx.forest_str(forest, sources=[0, 14, 7]) | |
| print(ret) | |
| target = dedent( | |
| """ | |
| βββ 0 | |
| β βββΌ 1 | |
| β β βββΌ 3 | |
| β β βββΌ 4 | |
| β βββΌ 2 | |
| β βββΌ 5 | |
| β βββΌ 6 | |
| βββ 14 | |
| β βββΌ 15 | |
| β β βββΌ 17 | |
| β β βββΌ 18 | |
| β βββΌ 16 | |
| β βββΌ 19 | |
| β βββΌ 20 | |
| βββ 7 | |
| βββΌ 8 | |
| β βββΌ 10 | |
| β βββΌ 11 | |
| βββΌ 9 | |
| βββΌ 12 | |
| βββΌ 13 | |
| """ | |
| ).strip() | |
| assert ret == target | |
| ret = nx.forest_str(forest, sources=[0, 14, 7], ascii_only=True) | |
| print(ret) | |
| target = dedent( | |
| """ | |
| +-- 0 | |
| : |-> 1 | |
| : | |-> 3 | |
| : | L-> 4 | |
| : L-> 2 | |
| : |-> 5 | |
| : L-> 6 | |
| +-- 14 | |
| : |-> 15 | |
| : | |-> 17 | |
| : | L-> 18 | |
| : L-> 16 | |
| : |-> 19 | |
| : L-> 20 | |
| +-- 7 | |
| |-> 8 | |
| | |-> 10 | |
| | L-> 11 | |
| L-> 9 | |
| |-> 12 | |
| L-> 13 | |
| """ | |
| ).strip() | |
| assert ret == target | |
| def test_forest_str_undirected_multi_tree(): | |
| tree1 = nx.balanced_tree(r=2, h=2, create_using=nx.Graph) | |
| tree2 = nx.balanced_tree(r=2, h=2, create_using=nx.Graph) | |
| tree2 = nx.relabel_nodes(tree2, {n: n + len(tree1) for n in tree2.nodes}) | |
| forest = nx.union(tree1, tree2) | |
| ret = nx.forest_str(forest, sources=[0, 7]) | |
| print(ret) | |
| target = dedent( | |
| """ | |
| βββ 0 | |
| β βββ 1 | |
| β β βββ 3 | |
| β β βββ 4 | |
| β βββ 2 | |
| β βββ 5 | |
| β βββ 6 | |
| βββ 7 | |
| βββ 8 | |
| β βββ 10 | |
| β βββ 11 | |
| βββ 9 | |
| βββ 12 | |
| βββ 13 | |
| """ | |
| ).strip() | |
| assert ret == target | |
| ret = nx.forest_str(forest, sources=[0, 7], ascii_only=True) | |
| print(ret) | |
| target = dedent( | |
| """ | |
| +-- 0 | |
| : |-- 1 | |
| : | |-- 3 | |
| : | L-- 4 | |
| : L-- 2 | |
| : |-- 5 | |
| : L-- 6 | |
| +-- 7 | |
| |-- 8 | |
| | |-- 10 | |
| | L-- 11 | |
| L-- 9 | |
| |-- 12 | |
| L-- 13 | |
| """ | |
| ).strip() | |
| assert ret == target | |
| def test_forest_str_undirected(): | |
| # Create a directed forest | |
| graph = nx.balanced_tree(r=2, h=2, create_using=nx.Graph) | |
| # arbitrary starting point | |
| nx.forest_str(graph) | |
| node_target0 = dedent( | |
| """ | |
| βββ 0 | |
| βββ 1 | |
| β βββ 3 | |
| β βββ 4 | |
| βββ 2 | |
| βββ 5 | |
| βββ 6 | |
| """ | |
| ).strip() | |
| # defined starting point | |
| ret = nx.forest_str(graph, sources=[0]) | |
| print(ret) | |
| assert ret == node_target0 | |
| # defined starting point | |
| node_target2 = dedent( | |
| """ | |
| βββ 2 | |
| βββ 0 | |
| β βββ 1 | |
| β βββ 3 | |
| β βββ 4 | |
| βββ 5 | |
| βββ 6 | |
| """ | |
| ).strip() | |
| ret = nx.forest_str(graph, sources=[2]) | |
| print(ret) | |
| assert ret == node_target2 | |
| def test_forest_str_errors(): | |
| ugraph = nx.complete_graph(3, create_using=nx.Graph) | |
| with pytest.raises(nx.NetworkXNotImplemented): | |
| nx.forest_str(ugraph) | |
| dgraph = nx.complete_graph(3, create_using=nx.DiGraph) | |
| with pytest.raises(nx.NetworkXNotImplemented): | |
| nx.forest_str(dgraph) | |
| def test_forest_str_overspecified_sources(): | |
| """ | |
| When sources are directly specified, we won't be able to determine when we | |
| are in the last component, so there will always be a trailing, leftmost | |
| pipe. | |
| """ | |
| graph = nx.disjoint_union_all( | |
| [ | |
| nx.balanced_tree(r=2, h=1, create_using=nx.DiGraph), | |
| nx.balanced_tree(r=1, h=2, create_using=nx.DiGraph), | |
| nx.balanced_tree(r=2, h=1, create_using=nx.DiGraph), | |
| ] | |
| ) | |
| # defined starting point | |
| target1 = dedent( | |
| """ | |
| βββ 0 | |
| β βββΌ 1 | |
| β βββΌ 2 | |
| βββ 3 | |
| β βββΌ 4 | |
| β βββΌ 5 | |
| βββ 6 | |
| β βββΌ 7 | |
| β βββΌ 8 | |
| """ | |
| ).strip() | |
| target2 = dedent( | |
| """ | |
| βββ 0 | |
| β βββΌ 1 | |
| β βββΌ 2 | |
| βββ 3 | |
| β βββΌ 4 | |
| β βββΌ 5 | |
| βββ 6 | |
| βββΌ 7 | |
| βββΌ 8 | |
| """ | |
| ).strip() | |
| lines = [] | |
| nx.forest_str(graph, write=lines.append, sources=graph.nodes) | |
| got1 = "\n".join(lines) | |
| print("got1: ") | |
| print(got1) | |
| lines = [] | |
| nx.forest_str(graph, write=lines.append) | |
| got2 = "\n".join(lines) | |
| print("got2: ") | |
| print(got2) | |
| assert got1 == target1 | |
| assert got2 == target2 | |
| def test_write_network_text_iterative_add_directed_edges(): | |
| """ | |
| Walk through the cases going from a disconnected to fully connected graph | |
| """ | |
| graph = nx.DiGraph() | |
| graph.add_nodes_from([1, 2, 3, 4]) | |
| lines = [] | |
| write = lines.append | |
| write("--- initial state ---") | |
| nx.write_network_text(graph, path=write, end="") | |
| for i, j in product(graph.nodes, graph.nodes): | |
| write(f"--- add_edge({i}, {j}) ---") | |
| graph.add_edge(i, j) | |
| nx.write_network_text(graph, path=write, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| # defined starting point | |
| target = dedent( | |
| """ | |
| --- initial state --- | |
| βββ 1 | |
| βββ 2 | |
| βββ 3 | |
| βββ 4 | |
| --- add_edge(1, 1) --- | |
| βββ 1 βΎ 1 | |
| β βββΌ ... | |
| βββ 2 | |
| βββ 3 | |
| βββ 4 | |
| --- add_edge(1, 2) --- | |
| βββ 1 βΎ 1 | |
| β βββΌ 2 | |
| β βββΌ ... | |
| βββ 3 | |
| βββ 4 | |
| --- add_edge(1, 3) --- | |
| βββ 1 βΎ 1 | |
| β βββΌ 2 | |
| β βββΌ 3 | |
| β βββΌ ... | |
| βββ 4 | |
| --- add_edge(1, 4) --- | |
| βββ 1 βΎ 1 | |
| βββΌ 2 | |
| βββΌ 3 | |
| βββΌ 4 | |
| βββΌ ... | |
| --- add_edge(2, 1) --- | |
| βββ 2 βΎ 1 | |
| βββΌ 1 βΎ 1 | |
| βββΌ 3 | |
| βββΌ 4 | |
| βββΌ ... | |
| --- add_edge(2, 2) --- | |
| βββ 1 βΎ 1, 2 | |
| βββΌ 2 βΎ 2 | |
| β βββΌ ... | |
| βββΌ 3 | |
| βββΌ 4 | |
| βββΌ ... | |
| --- add_edge(2, 3) --- | |
| βββ 1 βΎ 1, 2 | |
| βββΌ 2 βΎ 2 | |
| β βββΌ 3 βΎ 1 | |
| β βββΌ ... | |
| βββΌ 4 | |
| βββΌ ... | |
| --- add_edge(2, 4) --- | |
| βββ 1 βΎ 1, 2 | |
| βββΌ 2 βΎ 2 | |
| β βββΌ 3 βΎ 1 | |
| β βββΌ 4 βΎ 1 | |
| β βββΌ ... | |
| βββΌ ... | |
| --- add_edge(3, 1) --- | |
| βββ 2 βΎ 1, 2 | |
| βββΌ 1 βΎ 1, 3 | |
| β βββΌ 3 βΎ 2 | |
| β β βββΌ ... | |
| β βββΌ 4 βΎ 2 | |
| β βββΌ ... | |
| βββΌ ... | |
| --- add_edge(3, 2) --- | |
| βββ 3 βΎ 1, 2 | |
| βββΌ 1 βΎ 1, 2 | |
| β βββΌ 2 βΎ 2, 3 | |
| β β βββΌ 4 βΎ 1 | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- add_edge(3, 3) --- | |
| βββ 1 βΎ 1, 2, 3 | |
| βββΌ 2 βΎ 2, 3 | |
| β βββΌ 3 βΎ 1, 3 | |
| β β βββΌ ... | |
| β βββΌ 4 βΎ 1 | |
| β βββΌ ... | |
| βββΌ ... | |
| --- add_edge(3, 4) --- | |
| βββ 1 βΎ 1, 2, 3 | |
| βββΌ 2 βΎ 2, 3 | |
| β βββΌ 3 βΎ 1, 3 | |
| β β βββΌ 4 βΎ 1, 2 | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- add_edge(4, 1) --- | |
| βββ 2 βΎ 1, 2, 3 | |
| βββΌ 1 βΎ 1, 3, 4 | |
| β βββΌ 3 βΎ 2, 3 | |
| β β βββΌ 4 βΎ 1, 2 | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- add_edge(4, 2) --- | |
| βββ 3 βΎ 1, 2, 3 | |
| βββΌ 1 βΎ 1, 2, 4 | |
| β βββΌ 2 βΎ 2, 3, 4 | |
| β β βββΌ 4 βΎ 1, 3 | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- add_edge(4, 3) --- | |
| βββ 4 βΎ 1, 2, 3 | |
| βββΌ 1 βΎ 1, 2, 3 | |
| β βββΌ 2 βΎ 2, 3, 4 | |
| β β βββΌ 3 βΎ 1, 3, 4 | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- add_edge(4, 4) --- | |
| βββ 1 βΎ 1, 2, 3, 4 | |
| βββΌ 2 βΎ 2, 3, 4 | |
| β βββΌ 3 βΎ 1, 3, 4 | |
| β β βββΌ 4 βΎ 1, 2, 4 | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_iterative_add_undirected_edges(): | |
| """ | |
| Walk through the cases going from a disconnected to fully connected graph | |
| """ | |
| graph = nx.Graph() | |
| graph.add_nodes_from([1, 2, 3, 4]) | |
| lines = [] | |
| write = lines.append | |
| write("--- initial state ---") | |
| nx.write_network_text(graph, path=write, end="") | |
| for i, j in product(graph.nodes, graph.nodes): | |
| if i == j: | |
| continue | |
| write(f"--- add_edge({i}, {j}) ---") | |
| graph.add_edge(i, j) | |
| nx.write_network_text(graph, path=write, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- initial state --- | |
| βββ 1 | |
| βββ 2 | |
| βββ 3 | |
| βββ 4 | |
| --- add_edge(1, 2) --- | |
| βββ 3 | |
| βββ 4 | |
| βββ 1 | |
| βββ 2 | |
| --- add_edge(1, 3) --- | |
| βββ 4 | |
| βββ 2 | |
| βββ 1 | |
| βββ 3 | |
| --- add_edge(1, 4) --- | |
| βββ 2 | |
| βββ 1 | |
| βββ 3 | |
| βββ 4 | |
| --- add_edge(2, 1) --- | |
| βββ 2 | |
| βββ 1 | |
| βββ 3 | |
| βββ 4 | |
| --- add_edge(2, 3) --- | |
| βββ 4 | |
| βββ 1 | |
| βββ 2 | |
| β βββ 3 β 1 | |
| βββ ... | |
| --- add_edge(2, 4) --- | |
| βββ 3 | |
| βββ 1 | |
| β βββ 2 β 3 | |
| β β βββ 4 β 1 | |
| β βββ ... | |
| βββ ... | |
| --- add_edge(3, 1) --- | |
| βββ 3 | |
| βββ 1 | |
| β βββ 2 β 3 | |
| β β βββ 4 β 1 | |
| β βββ ... | |
| βββ ... | |
| --- add_edge(3, 2) --- | |
| βββ 3 | |
| βββ 1 | |
| β βββ 2 β 3 | |
| β β βββ 4 β 1 | |
| β βββ ... | |
| βββ ... | |
| --- add_edge(3, 4) --- | |
| βββ 1 | |
| βββ 2 | |
| β βββ 3 β 1 | |
| β β βββ 4 β 1, 2 | |
| β βββ ... | |
| βββ ... | |
| --- add_edge(4, 1) --- | |
| βββ 1 | |
| βββ 2 | |
| β βββ 3 β 1 | |
| β β βββ 4 β 1, 2 | |
| β βββ ... | |
| βββ ... | |
| --- add_edge(4, 2) --- | |
| βββ 1 | |
| βββ 2 | |
| β βββ 3 β 1 | |
| β β βββ 4 β 1, 2 | |
| β βββ ... | |
| βββ ... | |
| --- add_edge(4, 3) --- | |
| βββ 1 | |
| βββ 2 | |
| β βββ 3 β 1 | |
| β β βββ 4 β 1, 2 | |
| β βββ ... | |
| βββ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_iterative_add_random_directed_edges(): | |
| """ | |
| Walk through the cases going from a disconnected to fully connected graph | |
| """ | |
| rng = random.Random(724466096) | |
| graph = nx.DiGraph() | |
| graph.add_nodes_from([1, 2, 3, 4, 5]) | |
| possible_edges = list(product(graph.nodes, graph.nodes)) | |
| rng.shuffle(possible_edges) | |
| graph.add_edges_from(possible_edges[0:8]) | |
| lines = [] | |
| write = lines.append | |
| write("--- initial state ---") | |
| nx.write_network_text(graph, path=write, end="") | |
| for i, j in possible_edges[8:12]: | |
| write(f"--- add_edge({i}, {j}) ---") | |
| graph.add_edge(i, j) | |
| nx.write_network_text(graph, path=write, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- initial state --- | |
| βββ 3 βΎ 5 | |
| βββΌ 2 βΎ 2 | |
| βββΌ 4 βΎ 4 | |
| β βββΌ 5 | |
| β β βββΌ 1 βΎ 1 | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- add_edge(4, 1) --- | |
| βββ 3 βΎ 5 | |
| βββΌ 2 βΎ 2 | |
| βββΌ 4 βΎ 4 | |
| β βββΌ 5 | |
| β β βββΌ 1 βΎ 1, 4 | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- add_edge(2, 1) --- | |
| βββ 3 βΎ 5 | |
| βββΌ 2 βΎ 2 | |
| βββΌ 4 βΎ 4 | |
| β βββΌ 5 | |
| β β βββΌ 1 βΎ 1, 4, 2 | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- add_edge(5, 2) --- | |
| βββ 3 βΎ 5 | |
| βββΌ 2 βΎ 2, 5 | |
| βββΌ 4 βΎ 4 | |
| β βββΌ 5 | |
| β β βββΌ 1 βΎ 1, 4, 2 | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- add_edge(1, 5) --- | |
| βββ 3 βΎ 5 | |
| βββΌ 2 βΎ 2, 5 | |
| βββΌ 4 βΎ 4 | |
| β βββΌ 5 βΎ 1 | |
| β β βββΌ 1 βΎ 1, 4, 2 | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_nearly_forest(): | |
| g = nx.DiGraph() | |
| g.add_edge(1, 2) | |
| g.add_edge(1, 5) | |
| g.add_edge(2, 3) | |
| g.add_edge(3, 4) | |
| g.add_edge(5, 6) | |
| g.add_edge(6, 7) | |
| g.add_edge(6, 8) | |
| orig = g.copy() | |
| g.add_edge(1, 8) # forward edge | |
| g.add_edge(4, 2) # back edge | |
| g.add_edge(6, 3) # cross edge | |
| lines = [] | |
| write = lines.append | |
| write("--- directed case ---") | |
| nx.write_network_text(orig, path=write, end="") | |
| write("--- add (1, 8), (4, 2), (6, 3) ---") | |
| nx.write_network_text(g, path=write, end="") | |
| write("--- undirected case ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, sources=[1], end="") | |
| write("--- add (1, 8), (4, 2), (6, 3) ---") | |
| nx.write_network_text(g.to_undirected(), path=write, sources=[1], end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- directed case --- | |
| βββ 1 | |
| βββΌ 2 | |
| β βββΌ 3 | |
| β βββΌ 4 | |
| βββΌ 5 | |
| βββΌ 6 | |
| βββΌ 7 | |
| βββΌ 8 | |
| --- add (1, 8), (4, 2), (6, 3) --- | |
| βββ 1 | |
| βββΌ 2 βΎ 4 | |
| β βββΌ 3 βΎ 6 | |
| β βββΌ 4 | |
| β βββΌ ... | |
| βββΌ 5 | |
| β βββΌ 6 | |
| β βββΌ 7 | |
| β βββΌ 8 βΎ 1 | |
| β βββΌ ... | |
| βββΌ ... | |
| --- undirected case --- | |
| βββ 1 | |
| βββ 2 | |
| β βββ 3 | |
| β βββ 4 | |
| βββ 5 | |
| βββ 6 | |
| βββ 7 | |
| βββ 8 | |
| --- add (1, 8), (4, 2), (6, 3) --- | |
| βββ 1 | |
| βββ 2 | |
| β βββ 3 | |
| β β βββ 4 β 2 | |
| β β βββ 6 | |
| β β βββ 5 β 1 | |
| β β βββ 7 | |
| β β βββ 8 β 1 | |
| β βββ ... | |
| βββ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_complete_graph_ascii_only(): | |
| graph = nx.generators.complete_graph(5, create_using=nx.DiGraph) | |
| lines = [] | |
| write = lines.append | |
| write("--- directed case ---") | |
| nx.write_network_text(graph, path=write, ascii_only=True, end="") | |
| write("--- undirected case ---") | |
| nx.write_network_text(graph.to_undirected(), path=write, ascii_only=True, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- directed case --- | |
| +-- 0 <- 1, 2, 3, 4 | |
| |-> 1 <- 2, 3, 4 | |
| | |-> 2 <- 0, 3, 4 | |
| | | |-> 3 <- 0, 1, 4 | |
| | | | |-> 4 <- 0, 1, 2 | |
| | | | | L-> ... | |
| | | | L-> ... | |
| | | L-> ... | |
| | L-> ... | |
| L-> ... | |
| --- undirected case --- | |
| +-- 0 | |
| |-- 1 | |
| | |-- 2 - 0 | |
| | | |-- 3 - 0, 1 | |
| | | | L-- 4 - 0, 1, 2 | |
| | | L-- ... | |
| | L-- ... | |
| L-- ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_with_labels(): | |
| graph = nx.generators.complete_graph(5, create_using=nx.DiGraph) | |
| for n in graph.nodes: | |
| graph.nodes[n]["label"] = f"Node(n={n})" | |
| lines = [] | |
| write = lines.append | |
| nx.write_network_text(graph, path=write, with_labels=True, ascii_only=False, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| # Non trees with labels can get somewhat out of hand with network text | |
| # because we need to immediately show every non-tree edge to the right | |
| target = dedent( | |
| """ | |
| βββ Node(n=0) βΎ Node(n=1), Node(n=2), Node(n=3), Node(n=4) | |
| βββΌ Node(n=1) βΎ Node(n=2), Node(n=3), Node(n=4) | |
| β βββΌ Node(n=2) βΎ Node(n=0), Node(n=3), Node(n=4) | |
| β β βββΌ Node(n=3) βΎ Node(n=0), Node(n=1), Node(n=4) | |
| β β β βββΌ Node(n=4) βΎ Node(n=0), Node(n=1), Node(n=2) | |
| β β β β βββΌ ... | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_complete_graphs(): | |
| lines = [] | |
| write = lines.append | |
| for k in [0, 1, 2, 3, 4, 5]: | |
| g = nx.generators.complete_graph(k) | |
| write(f"--- undirected k={k} ---") | |
| nx.write_network_text(g, path=write, end="") | |
| for k in [0, 1, 2, 3, 4, 5]: | |
| g = nx.generators.complete_graph(k, nx.DiGraph) | |
| write(f"--- directed k={k} ---") | |
| nx.write_network_text(g, path=write, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- undirected k=0 --- | |
| β | |
| --- undirected k=1 --- | |
| βββ 0 | |
| --- undirected k=2 --- | |
| βββ 0 | |
| βββ 1 | |
| --- undirected k=3 --- | |
| βββ 0 | |
| βββ 1 | |
| β βββ 2 β 0 | |
| βββ ... | |
| --- undirected k=4 --- | |
| βββ 0 | |
| βββ 1 | |
| β βββ 2 β 0 | |
| β β βββ 3 β 0, 1 | |
| β βββ ... | |
| βββ ... | |
| --- undirected k=5 --- | |
| βββ 0 | |
| βββ 1 | |
| β βββ 2 β 0 | |
| β β βββ 3 β 0, 1 | |
| β β β βββ 4 β 0, 1, 2 | |
| β β βββ ... | |
| β βββ ... | |
| βββ ... | |
| --- directed k=0 --- | |
| β | |
| --- directed k=1 --- | |
| βββ 0 | |
| --- directed k=2 --- | |
| βββ 0 βΎ 1 | |
| βββΌ 1 | |
| βββΌ ... | |
| --- directed k=3 --- | |
| βββ 0 βΎ 1, 2 | |
| βββΌ 1 βΎ 2 | |
| β βββΌ 2 βΎ 0 | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- directed k=4 --- | |
| βββ 0 βΎ 1, 2, 3 | |
| βββΌ 1 βΎ 2, 3 | |
| β βββΌ 2 βΎ 0, 3 | |
| β β βββΌ 3 βΎ 0, 1 | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- directed k=5 --- | |
| βββ 0 βΎ 1, 2, 3, 4 | |
| βββΌ 1 βΎ 2, 3, 4 | |
| β βββΌ 2 βΎ 0, 3, 4 | |
| β β βββΌ 3 βΎ 0, 1, 4 | |
| β β β βββΌ 4 βΎ 0, 1, 2 | |
| β β β β βββΌ ... | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_multiple_sources(): | |
| g = nx.DiGraph() | |
| g.add_edge(1, 2) | |
| g.add_edge(1, 3) | |
| g.add_edge(2, 4) | |
| g.add_edge(3, 5) | |
| g.add_edge(3, 6) | |
| g.add_edge(5, 4) | |
| g.add_edge(4, 1) | |
| g.add_edge(1, 5) | |
| lines = [] | |
| write = lines.append | |
| # Use each node as the starting point to demonstrate how the representation | |
| # changes. | |
| nodes = sorted(g.nodes()) | |
| for n in nodes: | |
| write(f"--- source node: {n} ---") | |
| nx.write_network_text(g, path=write, sources=[n], end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- source node: 1 --- | |
| βββ 1 βΎ 4 | |
| βββΌ 2 | |
| β βββΌ 4 βΎ 5 | |
| β βββΌ ... | |
| βββΌ 3 | |
| β βββΌ 5 βΎ 1 | |
| β β βββΌ ... | |
| β βββΌ 6 | |
| βββΌ ... | |
| --- source node: 2 --- | |
| βββ 2 βΎ 1 | |
| βββΌ 4 βΎ 5 | |
| βββΌ 1 | |
| βββΌ 3 | |
| β βββΌ 5 βΎ 1 | |
| β β βββΌ ... | |
| β βββΌ 6 | |
| βββΌ ... | |
| --- source node: 3 --- | |
| βββ 3 βΎ 1 | |
| βββΌ 5 βΎ 1 | |
| β βββΌ 4 βΎ 2 | |
| β βββΌ 1 | |
| β βββΌ 2 | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ 6 | |
| --- source node: 4 --- | |
| βββ 4 βΎ 2, 5 | |
| βββΌ 1 | |
| βββΌ 2 | |
| β βββΌ ... | |
| βββΌ 3 | |
| β βββΌ 5 βΎ 1 | |
| β β βββΌ ... | |
| β βββΌ 6 | |
| βββΌ ... | |
| --- source node: 5 --- | |
| βββ 5 βΎ 3, 1 | |
| βββΌ 4 βΎ 2 | |
| βββΌ 1 | |
| βββΌ 2 | |
| β βββΌ ... | |
| βββΌ 3 | |
| β βββΌ 6 | |
| β βββΌ ... | |
| βββΌ ... | |
| --- source node: 6 --- | |
| βββ 6 βΎ 3 | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_star_graph(): | |
| graph = nx.star_graph(5, create_using=nx.Graph) | |
| lines = [] | |
| write = lines.append | |
| nx.write_network_text(graph, path=write, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| βββ 1 | |
| βββ 0 | |
| βββ 2 | |
| βββ 3 | |
| βββ 4 | |
| βββ 5 | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_path_graph(): | |
| graph = nx.path_graph(3, create_using=nx.Graph) | |
| lines = [] | |
| write = lines.append | |
| nx.write_network_text(graph, path=write, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| βββ 0 | |
| βββ 1 | |
| βββ 2 | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_lollipop_graph(): | |
| graph = nx.lollipop_graph(4, 2, create_using=nx.Graph) | |
| lines = [] | |
| write = lines.append | |
| nx.write_network_text(graph, path=write, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| βββ 5 | |
| βββ 4 | |
| βββ 3 | |
| βββ 0 | |
| β βββ 1 β 3 | |
| β β βββ 2 β 0, 3 | |
| β βββ ... | |
| βββ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_wheel_graph(): | |
| graph = nx.wheel_graph(7, create_using=nx.Graph) | |
| lines = [] | |
| write = lines.append | |
| nx.write_network_text(graph, path=write, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| βββ 1 | |
| βββ 0 | |
| β βββ 2 β 1 | |
| β β βββ 3 β 0 | |
| β β βββ 4 β 0 | |
| β β βββ 5 β 0 | |
| β β βββ 6 β 0, 1 | |
| β βββ ... | |
| βββ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_circular_ladder_graph(): | |
| graph = nx.circular_ladder_graph(4, create_using=nx.Graph) | |
| lines = [] | |
| write = lines.append | |
| nx.write_network_text(graph, path=write, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| βββ 0 | |
| βββ 1 | |
| β βββ 2 | |
| β β βββ 3 β 0 | |
| β β β βββ 7 | |
| β β β βββ 6 β 2 | |
| β β β β βββ 5 β 1 | |
| β β β β βββ 4 β 0, 7 | |
| β β β βββ ... | |
| β β βββ ... | |
| β βββ ... | |
| βββ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_dorogovtsev_goltsev_mendes_graph(): | |
| graph = nx.dorogovtsev_goltsev_mendes_graph(4, create_using=nx.Graph) | |
| lines = [] | |
| write = lines.append | |
| nx.write_network_text(graph, path=write, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| βββ 15 | |
| βββ 0 | |
| β βββ 1 β 15 | |
| β β βββ 2 β 0 | |
| β β β βββ 4 β 0 | |
| β β β β βββ 9 β 0 | |
| β β β β β βββ 22 β 0 | |
| β β β β β βββ 38 β 4 | |
| β β β β βββ 13 β 2 | |
| β β β β β βββ 34 β 2 | |
| β β β β β βββ 39 β 4 | |
| β β β β βββ 18 β 0 | |
| β β β β βββ 30 β 2 | |
| β β β β βββ ... | |
| β β β βββ 5 β 1 | |
| β β β β βββ 12 β 1 | |
| β β β β β βββ 29 β 1 | |
| β β β β β βββ 40 β 5 | |
| β β β β βββ 14 β 2 | |
| β β β β β βββ 35 β 2 | |
| β β β β β βββ 41 β 5 | |
| β β β β βββ 25 β 1 | |
| β β β β βββ 31 β 2 | |
| β β β β βββ ... | |
| β β β βββ 7 β 0 | |
| β β β β βββ 20 β 0 | |
| β β β β βββ 32 β 2 | |
| β β β βββ 10 β 1 | |
| β β β β βββ 27 β 1 | |
| β β β β βββ 33 β 2 | |
| β β β βββ 16 β 0 | |
| β β β βββ 23 β 1 | |
| β β β βββ ... | |
| β β βββ 3 β 0 | |
| β β β βββ 8 β 0 | |
| β β β β βββ 21 β 0 | |
| β β β β βββ 36 β 3 | |
| β β β βββ 11 β 1 | |
| β β β β βββ 28 β 1 | |
| β β β β βββ 37 β 3 | |
| β β β βββ 17 β 0 | |
| β β β βββ 24 β 1 | |
| β β β βββ ... | |
| β β βββ 6 β 0 | |
| β β β βββ 19 β 0 | |
| β β β βββ 26 β 1 | |
| β β βββ ... | |
| β βββ ... | |
| βββ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_tree_max_depth(): | |
| orig = nx.balanced_tree(r=1, h=3, create_using=nx.DiGraph) | |
| lines = [] | |
| write = lines.append | |
| write("--- directed case, max_depth=0 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=0) | |
| write("--- directed case, max_depth=1 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=1) | |
| write("--- directed case, max_depth=2 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=2) | |
| write("--- directed case, max_depth=3 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=3) | |
| write("--- directed case, max_depth=4 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=4) | |
| write("--- undirected case, max_depth=0 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=0) | |
| write("--- undirected case, max_depth=1 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=1) | |
| write("--- undirected case, max_depth=2 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=2) | |
| write("--- undirected case, max_depth=3 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=3) | |
| write("--- undirected case, max_depth=4 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=4) | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- directed case, max_depth=0 --- | |
| β ... | |
| --- directed case, max_depth=1 --- | |
| βββ 0 | |
| βββΌ ... | |
| --- directed case, max_depth=2 --- | |
| βββ 0 | |
| βββΌ 1 | |
| βββΌ ... | |
| --- directed case, max_depth=3 --- | |
| βββ 0 | |
| βββΌ 1 | |
| βββΌ 2 | |
| βββΌ ... | |
| --- directed case, max_depth=4 --- | |
| βββ 0 | |
| βββΌ 1 | |
| βββΌ 2 | |
| βββΌ 3 | |
| --- undirected case, max_depth=0 --- | |
| β ... | |
| --- undirected case, max_depth=1 --- | |
| βββ 0 β 1 | |
| βββ ... | |
| --- undirected case, max_depth=2 --- | |
| βββ 0 | |
| βββ 1 β 2 | |
| βββ ... | |
| --- undirected case, max_depth=3 --- | |
| βββ 0 | |
| βββ 1 | |
| βββ 2 β 3 | |
| βββ ... | |
| --- undirected case, max_depth=4 --- | |
| βββ 0 | |
| βββ 1 | |
| βββ 2 | |
| βββ 3 | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_graph_max_depth(): | |
| orig = nx.erdos_renyi_graph(10, 0.15, directed=True, seed=40392) | |
| lines = [] | |
| write = lines.append | |
| write("--- directed case, max_depth=None ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=None) | |
| write("--- directed case, max_depth=0 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=0) | |
| write("--- directed case, max_depth=1 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=1) | |
| write("--- directed case, max_depth=2 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=2) | |
| write("--- directed case, max_depth=3 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=3) | |
| write("--- undirected case, max_depth=None ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=None) | |
| write("--- undirected case, max_depth=0 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=0) | |
| write("--- undirected case, max_depth=1 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=1) | |
| write("--- undirected case, max_depth=2 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=2) | |
| write("--- undirected case, max_depth=3 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=3) | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- directed case, max_depth=None --- | |
| βββ 4 | |
| β βββΌ 0 βΎ 3 | |
| β βββΌ 5 βΎ 7 | |
| β β βββΌ 3 | |
| β β βββΌ 1 βΎ 9 | |
| β β β βββΌ 9 βΎ 6 | |
| β β β βββΌ 6 | |
| β β β β βββΌ ... | |
| β β β βββΌ 7 βΎ 4 | |
| β β β β βββΌ 2 | |
| β β β β βββΌ ... | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββ 8 | |
| --- directed case, max_depth=0 --- | |
| β ... | |
| --- directed case, max_depth=1 --- | |
| βββ 4 | |
| β βββΌ ... | |
| βββ 8 | |
| --- directed case, max_depth=2 --- | |
| βββ 4 | |
| β βββΌ 0 βΎ 3 | |
| β βββΌ 5 βΎ 7 | |
| β β βββΌ ... | |
| β βββΌ 7 βΎ 9 | |
| β βββΌ ... | |
| βββ 8 | |
| --- directed case, max_depth=3 --- | |
| βββ 4 | |
| β βββΌ 0 βΎ 3 | |
| β βββΌ 5 βΎ 7 | |
| β β βββΌ 3 | |
| β β βββΌ ... | |
| β βββΌ 7 βΎ 9 | |
| β βββΌ 2 | |
| β βββΌ ... | |
| βββ 8 | |
| --- undirected case, max_depth=None --- | |
| βββ 8 | |
| βββ 2 | |
| βββ 7 | |
| βββ 4 | |
| β βββ 0 | |
| β β βββ 3 | |
| β β βββ 1 | |
| β β β βββ 9 β 7 | |
| β β β βββ 6 | |
| β β βββ 5 β 4, 7 | |
| β βββ ... | |
| βββ ... | |
| --- undirected case, max_depth=0 --- | |
| β ... | |
| --- undirected case, max_depth=1 --- | |
| βββ 8 | |
| βββ 2 β 7 | |
| βββ ... | |
| --- undirected case, max_depth=2 --- | |
| βββ 8 | |
| βββ 2 | |
| βββ 7 β 4, 5, 9 | |
| βββ ... | |
| --- undirected case, max_depth=3 --- | |
| βββ 8 | |
| βββ 2 | |
| βββ 7 | |
| βββ 4 β 0, 5 | |
| β βββ ... | |
| βββ 5 β 4, 3 | |
| β βββ ... | |
| βββ 9 β 1, 6 | |
| βββ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_clique_max_depth(): | |
| orig = nx.complete_graph(5, nx.DiGraph) | |
| lines = [] | |
| write = lines.append | |
| write("--- directed case, max_depth=None ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=None) | |
| write("--- directed case, max_depth=0 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=0) | |
| write("--- directed case, max_depth=1 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=1) | |
| write("--- directed case, max_depth=2 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=2) | |
| write("--- directed case, max_depth=3 ---") | |
| nx.write_network_text(orig, path=write, end="", max_depth=3) | |
| write("--- undirected case, max_depth=None ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=None) | |
| write("--- undirected case, max_depth=0 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=0) | |
| write("--- undirected case, max_depth=1 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=1) | |
| write("--- undirected case, max_depth=2 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=2) | |
| write("--- undirected case, max_depth=3 ---") | |
| nx.write_network_text(orig.to_undirected(), path=write, end="", max_depth=3) | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- directed case, max_depth=None --- | |
| βββ 0 βΎ 1, 2, 3, 4 | |
| βββΌ 1 βΎ 2, 3, 4 | |
| β βββΌ 2 βΎ 0, 3, 4 | |
| β β βββΌ 3 βΎ 0, 1, 4 | |
| β β β βββΌ 4 βΎ 0, 1, 2 | |
| β β β β βββΌ ... | |
| β β β βββΌ ... | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- directed case, max_depth=0 --- | |
| β ... | |
| --- directed case, max_depth=1 --- | |
| βββ 0 βΎ 1, 2, 3, 4 | |
| βββΌ ... | |
| --- directed case, max_depth=2 --- | |
| βββ 0 βΎ 1, 2, 3, 4 | |
| βββΌ 1 βΎ 2, 3, 4 | |
| β βββΌ ... | |
| βββΌ 2 βΎ 1, 3, 4 | |
| β βββΌ ... | |
| βββΌ 3 βΎ 1, 2, 4 | |
| β βββΌ ... | |
| βββΌ 4 βΎ 1, 2, 3 | |
| βββΌ ... | |
| --- directed case, max_depth=3 --- | |
| βββ 0 βΎ 1, 2, 3, 4 | |
| βββΌ 1 βΎ 2, 3, 4 | |
| β βββΌ 2 βΎ 0, 3, 4 | |
| β β βββΌ ... | |
| β βββΌ 3 βΎ 0, 2, 4 | |
| β β βββΌ ... | |
| β βββΌ 4 βΎ 0, 2, 3 | |
| β β βββΌ ... | |
| β βββΌ ... | |
| βββΌ ... | |
| --- undirected case, max_depth=None --- | |
| βββ 0 | |
| βββ 1 | |
| β βββ 2 β 0 | |
| β β βββ 3 β 0, 1 | |
| β β β βββ 4 β 0, 1, 2 | |
| β β βββ ... | |
| β βββ ... | |
| βββ ... | |
| --- undirected case, max_depth=0 --- | |
| β ... | |
| --- undirected case, max_depth=1 --- | |
| βββ 0 β 1, 2, 3, 4 | |
| βββ ... | |
| --- undirected case, max_depth=2 --- | |
| βββ 0 | |
| βββ 1 β 2, 3, 4 | |
| β βββ ... | |
| βββ 2 β 1, 3, 4 | |
| β βββ ... | |
| βββ 3 β 1, 2, 4 | |
| β βββ ... | |
| βββ 4 β 1, 2, 3 | |
| --- undirected case, max_depth=3 --- | |
| βββ 0 | |
| βββ 1 | |
| β βββ 2 β 0, 3, 4 | |
| β β βββ ... | |
| β βββ 3 β 0, 2, 4 | |
| β β βββ ... | |
| β βββ 4 β 0, 2, 3 | |
| βββ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_custom_label(): | |
| # Create a directed forest with labels | |
| graph = nx.erdos_renyi_graph(5, 0.4, directed=True, seed=359222358) | |
| for node in graph.nodes: | |
| graph.nodes[node]["label"] = f"Node({node})" | |
| graph.nodes[node]["chr"] = chr(node + ord("a") - 1) | |
| if node % 2 == 0: | |
| graph.nodes[node]["part"] = chr(node + ord("a")) | |
| lines = [] | |
| write = lines.append | |
| write("--- when with_labels=True, uses the 'label' attr ---") | |
| nx.write_network_text(graph, path=write, with_labels=True, end="", max_depth=None) | |
| write("--- when with_labels=False, uses str(node) value ---") | |
| nx.write_network_text(graph, path=write, with_labels=False, end="", max_depth=None) | |
| write("--- when with_labels is a string, use that attr ---") | |
| nx.write_network_text(graph, path=write, with_labels="chr", end="", max_depth=None) | |
| write("--- fallback to str(node) when the attr does not exist ---") | |
| nx.write_network_text(graph, path=write, with_labels="part", end="", max_depth=None) | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- when with_labels=True, uses the 'label' attr --- | |
| βββ Node(1) | |
| βββΌ Node(3) βΎ Node(2) | |
| βββΌ Node(0) | |
| β βββΌ Node(2) βΎ Node(3), Node(4) | |
| β β βββΌ ... | |
| β βββΌ Node(4) | |
| β βββΌ ... | |
| βββΌ ... | |
| --- when with_labels=False, uses str(node) value --- | |
| βββ 1 | |
| βββΌ 3 βΎ 2 | |
| βββΌ 0 | |
| β βββΌ 2 βΎ 3, 4 | |
| β β βββΌ ... | |
| β βββΌ 4 | |
| β βββΌ ... | |
| βββΌ ... | |
| --- when with_labels is a string, use that attr --- | |
| βββ a | |
| βββΌ c βΎ b | |
| βββΌ ` | |
| β βββΌ b βΎ c, d | |
| β β βββΌ ... | |
| β βββΌ d | |
| β βββΌ ... | |
| βββΌ ... | |
| --- fallback to str(node) when the attr does not exist --- | |
| βββ 1 | |
| βββΌ 3 βΎ c | |
| βββΌ a | |
| β βββΌ c βΎ 3, e | |
| β β βββΌ ... | |
| β βββΌ e | |
| β βββΌ ... | |
| βββΌ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_write_network_text_vertical_chains(): | |
| graph1 = nx.lollipop_graph(4, 2, create_using=nx.Graph) | |
| graph1.add_edge(0, -1) | |
| graph1.add_edge(-1, -2) | |
| graph1.add_edge(-2, -3) | |
| graph2 = graph1.to_directed() | |
| graph2.remove_edges_from([(u, v) for u, v in graph2.edges if v > u]) | |
| lines = [] | |
| write = lines.append | |
| write("--- Undirected UTF ---") | |
| nx.write_network_text(graph1, path=write, end="", vertical_chains=True) | |
| write("--- Undirected ASCI ---") | |
| nx.write_network_text( | |
| graph1, path=write, end="", vertical_chains=True, ascii_only=True | |
| ) | |
| write("--- Directed UTF ---") | |
| nx.write_network_text(graph2, path=write, end="", vertical_chains=True) | |
| write("--- Directed ASCI ---") | |
| nx.write_network_text( | |
| graph2, path=write, end="", vertical_chains=True, ascii_only=True | |
| ) | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- Undirected UTF --- | |
| βββ 5 | |
| β | |
| 4 | |
| β | |
| 3 | |
| βββ 0 | |
| β βββ 1 β 3 | |
| β β β | |
| β β 2 β 0, 3 | |
| β βββ -1 | |
| β β β | |
| β β -2 | |
| β β β | |
| β β -3 | |
| β βββ ... | |
| βββ ... | |
| --- Undirected ASCI --- | |
| +-- 5 | |
| | | |
| 4 | |
| | | |
| 3 | |
| |-- 0 | |
| | |-- 1 - 3 | |
| | | | | |
| | | 2 - 0, 3 | |
| | |-- -1 | |
| | | | | |
| | | -2 | |
| | | | | |
| | | -3 | |
| | L-- ... | |
| L-- ... | |
| --- Directed UTF --- | |
| βββ 5 | |
| β½ | |
| 4 | |
| β½ | |
| 3 | |
| βββΌ 0 βΎ 1, 2 | |
| β β½ | |
| β -1 | |
| β β½ | |
| β -2 | |
| β β½ | |
| β -3 | |
| βββΌ 1 βΎ 2 | |
| β βββΌ ... | |
| βββΌ 2 | |
| βββΌ ... | |
| --- Directed ASCI --- | |
| +-- 5 | |
| ! | |
| 4 | |
| ! | |
| 3 | |
| |-> 0 <- 1, 2 | |
| | ! | |
| | -1 | |
| | ! | |
| | -2 | |
| | ! | |
| | -3 | |
| |-> 1 <- 2 | |
| | L-> ... | |
| L-> 2 | |
| L-> ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_collapse_directed(): | |
| graph = nx.balanced_tree(r=2, h=3, create_using=nx.DiGraph) | |
| lines = [] | |
| write = lines.append | |
| write("--- Original ---") | |
| nx.write_network_text(graph, path=write, end="") | |
| graph.nodes[1]["collapse"] = True | |
| write("--- Collapse Node 1 ---") | |
| nx.write_network_text(graph, path=write, end="") | |
| write("--- Add alternate path (5, 3) to collapsed zone") | |
| graph.add_edge(5, 3) | |
| nx.write_network_text(graph, path=write, end="") | |
| write("--- Collapse Node 0 ---") | |
| graph.nodes[0]["collapse"] = True | |
| nx.write_network_text(graph, path=write, end="") | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- Original --- | |
| βββ 0 | |
| βββΌ 1 | |
| β βββΌ 3 | |
| β β βββΌ 7 | |
| β β βββΌ 8 | |
| β βββΌ 4 | |
| β βββΌ 9 | |
| β βββΌ 10 | |
| βββΌ 2 | |
| βββΌ 5 | |
| β βββΌ 11 | |
| β βββΌ 12 | |
| βββΌ 6 | |
| βββΌ 13 | |
| βββΌ 14 | |
| --- Collapse Node 1 --- | |
| βββ 0 | |
| βββΌ 1 | |
| β βββΌ ... | |
| βββΌ 2 | |
| βββΌ 5 | |
| β βββΌ 11 | |
| β βββΌ 12 | |
| βββΌ 6 | |
| βββΌ 13 | |
| βββΌ 14 | |
| --- Add alternate path (5, 3) to collapsed zone | |
| βββ 0 | |
| βββΌ 1 | |
| β βββΌ ... | |
| βββΌ 2 | |
| βββΌ 5 | |
| β βββΌ 11 | |
| β βββΌ 12 | |
| β βββΌ 3 βΎ 1 | |
| β βββΌ 7 | |
| β βββΌ 8 | |
| βββΌ 6 | |
| βββΌ 13 | |
| βββΌ 14 | |
| --- Collapse Node 0 --- | |
| βββ 0 | |
| βββΌ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def test_collapse_undirected(): | |
| graph = nx.balanced_tree(r=2, h=3, create_using=nx.Graph) | |
| lines = [] | |
| write = lines.append | |
| write("--- Original ---") | |
| nx.write_network_text(graph, path=write, end="", sources=[0]) | |
| graph.nodes[1]["collapse"] = True | |
| write("--- Collapse Node 1 ---") | |
| nx.write_network_text(graph, path=write, end="", sources=[0]) | |
| write("--- Add alternate path (5, 3) to collapsed zone") | |
| graph.add_edge(5, 3) | |
| nx.write_network_text(graph, path=write, end="", sources=[0]) | |
| write("--- Collapse Node 0 ---") | |
| graph.nodes[0]["collapse"] = True | |
| nx.write_network_text(graph, path=write, end="", sources=[0]) | |
| text = "\n".join(lines) | |
| print(text) | |
| target = dedent( | |
| """ | |
| --- Original --- | |
| βββ 0 | |
| βββ 1 | |
| β βββ 3 | |
| β β βββ 7 | |
| β β βββ 8 | |
| β βββ 4 | |
| β βββ 9 | |
| β βββ 10 | |
| βββ 2 | |
| βββ 5 | |
| β βββ 11 | |
| β βββ 12 | |
| βββ 6 | |
| βββ 13 | |
| βββ 14 | |
| --- Collapse Node 1 --- | |
| βββ 0 | |
| βββ 1 β 3, 4 | |
| β βββ ... | |
| βββ 2 | |
| βββ 5 | |
| β βββ 11 | |
| β βββ 12 | |
| βββ 6 | |
| βββ 13 | |
| βββ 14 | |
| --- Add alternate path (5, 3) to collapsed zone | |
| βββ 0 | |
| βββ 1 β 3, 4 | |
| β βββ ... | |
| βββ 2 | |
| βββ 5 | |
| β βββ 11 | |
| β βββ 12 | |
| β βββ 3 β 1 | |
| β βββ 7 | |
| β βββ 8 | |
| βββ 6 | |
| βββ 13 | |
| βββ 14 | |
| --- Collapse Node 0 --- | |
| βββ 0 β 1, 2 | |
| βββ ... | |
| """ | |
| ).strip() | |
| assert target == text | |
| def generate_test_graphs(): | |
| """ | |
| Generate a gauntlet of different test graphs with different properties | |
| """ | |
| import random | |
| rng = random.Random(976689776) | |
| num_randomized = 3 | |
| for directed in [0, 1]: | |
| cls = nx.DiGraph if directed else nx.Graph | |
| for num_nodes in range(17): | |
| # Disconnected graph | |
| graph = cls() | |
| graph.add_nodes_from(range(num_nodes)) | |
| yield graph | |
| # Randomize graphs | |
| if num_nodes > 0: | |
| for p in [0.1, 0.3, 0.5, 0.7, 0.9]: | |
| for seed in range(num_randomized): | |
| graph = nx.erdos_renyi_graph( | |
| num_nodes, p, directed=directed, seed=rng | |
| ) | |
| yield graph | |
| yield nx.complete_graph(num_nodes, cls) | |
| yield nx.path_graph(3, create_using=cls) | |
| yield nx.balanced_tree(r=1, h=3, create_using=cls) | |
| if not directed: | |
| yield nx.circular_ladder_graph(4, create_using=cls) | |
| yield nx.star_graph(5, create_using=cls) | |
| yield nx.lollipop_graph(4, 2, create_using=cls) | |
| yield nx.wheel_graph(7, create_using=cls) | |
| yield nx.dorogovtsev_goltsev_mendes_graph(4, create_using=cls) | |
| def test_network_text_round_trip(vertical_chains, ascii_only): | |
| """ | |
| Write the graph to network text format, then parse it back in, assert it is | |
| the same as the original graph. Passing this test is strong validation of | |
| both the format generator and parser. | |
| """ | |
| from networkx.readwrite.text import _parse_network_text | |
| for graph in generate_test_graphs(): | |
| graph = nx.relabel_nodes(graph, {n: str(n) for n in graph.nodes}) | |
| lines = list( | |
| nx.generate_network_text( | |
| graph, vertical_chains=vertical_chains, ascii_only=ascii_only | |
| ) | |
| ) | |
| new = _parse_network_text(lines) | |
| try: | |
| assert new.nodes == graph.nodes | |
| assert new.edges == graph.edges | |
| except Exception: | |
| print("ERROR in round trip with graph") | |
| nx.write_network_text(graph) | |
| raise | |