Llama-3.1-8B-DALv0.1
/
venv
/lib
/python3.12
/site-packages
/networkx
/readwrite
/tests
/test_text.py
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 | |