Spaces:
Running
Running
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 | |