Nodes and Edges
===============

>>> from pygraphviz import *

Some useful graphs


>>> null=AGraph()
>>> K1=AGraph()
>>> K1.add_node(1)
>>> K3=AGraph()
>>> K3.add_edges_from([(1,2),(1,3),(2,3)])
>>> K5=AGraph()
>>> K5.add_edges_from([(1,2),(1,3),(1,4),(1,5),(2,3),(2,4),(2,5),(3,4),(3,5),(4,5)])

>>> null=AGraph()
>>> P3=AGraph()
>>> P3.add_path([1,2,3])
>>> P5=AGraph()
>>> P5.add_path([1,2,3,4,5])


strict=True
------------

test __init__

>>> A=AGraph()  # empty
>>> A.is_strict()
True
>>> A.nodes()
[]
>>> d={'a':'b','b':'c'}
>>> A=AGraph(data=d) # with data
>>> A.nodes()
['a', 'b', 'c']
>>> sorted(A.edges())
[('a', 'b'), ('b', 'c')]

# A=AGraph(file=file) # in layout_draw.txt


test __str__

>>> A = AGraph(name="test")
>>> print A    
test

>>> A=AGraph()
>>> print A
<BLANKLINE>

test __repr__

>>> A=AGraph()
>>> A.__repr__().expandtabs()
'strict graph {\n}'

test __eq__

>>> H=AGraph()
>>> H==A
True
>>> H is A
False

test __iter__

>>> sorted(list(P3.__iter__()))
['1', '2', '3']
>>> sorted(P3)
['1', '2', '3']


test __contains__

>>> '1' in P3
True

>>> 10 in P3
False

test __len__

>>> len(P3)
3

test __getitem__

>>> P3[1]
['2']
>>> P3[10]
Traceback (most recent call last):
...
KeyError: 'node 10 not in graph'


test add_node

>>> A=AGraph()
>>> A.add_node(1)
>>> A.nodes()
['1']
>>> A.add_node('A')
>>> sorted(A.nodes())
['1', 'A']
>>> A.add_node([1]) # nodes must be strings or have a __str__
>>> sorted(A.nodes())
['1', 'A', '[1]']


test remove_node

>>> A.remove_node([1])
>>> sorted(A.nodes())
['1', 'A']
>>> A.remove_node('A')
>>> A.nodes()
['1']
>>> A.remove_node(1)
>>> A.nodes()
[]
>>> A.remove_node(1)
Traceback (most recent call last):
...
KeyError: 'node 1 not in graph'


test add_nodes_from and remove_nodes_from

>>> A=AGraph()
>>> A.add_nodes_from(range(3))
>>> sorted(A.nodes())
['0', '1', '2']
>>> A.remove_nodes_from(range(3))
>>> A.nodes()
[]
>>> A.remove_nodes_from(range(3))
Traceback (most recent call last):
...
KeyError: 'node 0 not in graph'

test nodes and nodes_iter

>>> sorted(P3.nodes())
['1', '2', '3']
>>> sorted(P3.nodes_iter())
['1', '2', '3']
>>> sorted(P3.iternodes())
['1', '2', '3']

test number_of_nodes and order

>>> P3.number_of_nodes()
3
>>> P3.order()
3

test has_node, get_node, Node

>>> P3.has_node(1)
True
>>> P3.has_node('1')
True
>>> P3.has_node('10')
False
>>> P3.get_node(1)
'1'
>>> one=P3.get_node(1)
>>> nh=one.get_handle()
>>> node=Node(P3,1)
>>> node.get_handle()==nh
True
>>> node
'1'
>>> Node(P3,10)
Traceback (most recent call last):
...
KeyError: 'node 10 not in graph'



test add_edge

>>> A=AGraph()
>>> A.add_edge(1,2)
>>> sorted(A.edges())
[('1', '2')]
>>> e=(2,3)
>>> A.add_edge(e)
>>> sorted([tuple(sorted(e)) for e in A.edges()])
[('1', '2'), ('2', '3')]

test add_edges_from

>>> A=AGraph()
>>> A.add_edges_from([(1,2),(2,3)])
>>> sorted([tuple(sorted(e)) for e in A.edges()])
[('1', '2'), ('2', '3')]

test remove_edge

>>> A.remove_edge(1,2)
>>> sorted(A.edges())
[('2', '3')]
>>> e=(2,3)
>>> A.remove_edge(e)
>>> A.edges()
[]
>>> A.remove_edge(1,2)
Traceback (most recent call last):
...
KeyError: 'edge 1-2 not in graph'


test remove_edges_from

>>> A=AGraph()
>>> A.add_edges_from([(1,2),(2,3)])
>>> sorted([tuple(sorted(e)) for e in A.edges()])
[('1', '2'), ('2', '3')]
>>> A.remove_edges_from([(1,2),(2,3)])
>>> A.edges()
[]

test edges, edges_iter

>>> A=AGraph()
>>> A.add_edges_from([(1,2),(2,3)])
>>> sorted([tuple(sorted(e)) for e in A.edges()])
[('1', '2'), ('2', '3')]
>>> sorted([tuple(sorted(e)) for e in A.edges_iter()])
[('1', '2'), ('2', '3')]
>>> sorted([tuple(sorted(e)) for e in A.iteredges()])
[('1', '2'), ('2', '3')]

test has_edge, get_edge, Edge

>>> P3.has_edge(1,2)
True
>>> P3.has_edge('1','2')
True
>>> P3.has_edge('1','10')
False
>>> P3.get_edge(1,2)
('1', '2')
>>> eone=P3.get_edge(1,2)
>>> eh=eone.handle
>>> edge=Edge(P3,1,2)
>>> edge.handle==eh
True
>>> edge
('1', '2')
>>> A=P3.copy()
>>> A.add_node(10)
>>> Edge(A,1,10)
Traceback (most recent call last):
...
KeyError: 'edge 1-10 not in graph'


test neighbors, neighbors_iter

>>> A=AGraph()
>>> A.add_edges_from([(1,2),(2,3)])
>>> sorted(A.neighbors(2))
['1', '3']
>>> sorted(A.neighbors_iter(2))
['1', '3']
>>> sorted(A.iterneighbors(2))
['1', '3']


test degree, degree_iter

>>> sorted(A.degree())
[1, 1, 2]
>>> sorted(A.degree_iter())
[('1', 1), ('2', 2), ('3', 1)]
>>> sorted(A.iterdegree())
[('1', 1), ('2', 2), ('3', 1)]
>>> sorted(A.iterdegree(A.nodes()))
[('1', 1), ('2', 2), ('3', 1)]
>>> sorted(A.iterdegree(A))
[('1', 1), ('2', 2), ('3', 1)]
>>> A.degree(1)
1
>>> A.degree(2)
2

test number_of_edges, size

>>> A.number_of_edges()
2
>>> A.size()
2

test clear

>>> A.clear()
>>> A.nodes()
[]
>>> A.edges()
[]

test copy

>>> A=P3.copy()
>>> A.nodes()
['1', '2', '3']
>>> A.edges()    
[('1', '2'), ('2', '3')]
>>> A==P3
True
>>> A is P3
False
>>> P3 is P3
True


test add_path add_cycle

>>> A=AGraph()
>>> A.add_path([1,2,3])
>>> A==P3
True
>>> A=AGraph()
>>> A.add_cycle([1,2,3])
>>> A.nodes()
['1', '2', '3']
>>> sorted([tuple(sorted(e)) for e in A.iteredges()])
[('1', '2'), ('1', '3'), ('2', '3')]

strict
------
>>> A=AGraph()
>>> A.add_node(1)
>>> A.add_node(1) # silent falure
>>> A.nodes()
['1']
>>> A.add_edge(1,2)
>>> A.add_edge(1,2) # silent falure
>>> A.edges()
[('1', '2')]
>>> A.add_edge(3,3) # silent falure, but add node 3
>>> A.edges()
[('1', '2')]
>>> A.nodes()
['1', '2', '3']


not strict
----------
>>> A=AGraph(strict=False)
>>> A.is_strict()
False
>>> A.add_node(1)
>>> A.add_node(1)  # silent failure
>>> A.nodes()
['1']
>>> A.add_edge(1,2)
>>> A.add_edge(1,2) 
>>> A.edges()
[('1', '2'), ('1', '2')]
>>> A.add_edge(3,3)
>>> A.edges()
[('1', '2'), ('1', '2'), ('3', '3')]
>>> A.nodes()
['1', '2', '3']

with keyed edge

>>> A.add_edge('3','3','foo')
>>> A.edges()
[('1', '2'), ('1', '2'), ('3', '3'), ('3', '3')]
>>> A.edges(keys=True)
[('1', '2', None), ('1', '2', None), ('3', '3', None), ('3', '3', 'foo')]
>>> eone=A.get_edge(3,3,'foo')
>>> eh=eone.handle
>>> edge=Edge(A,3,3,'foo')
>>> edge.handle==eh
True
>>> edge
('3', '3')
>>> eone
('3', '3')
>>> edge.name
'foo'

graph only
----------

test to_undirected

>>> A=P3.copy()
>>> A.is_undirected()
True
>>> A=A.to_undirected()
>>> A.has_edge(1,2)
True
>>> A.has_edge(2,1)
True

>>> A=P3.to_directed()
>>> A.has_edge(1,2)
True
>>> sorted([tuple(sorted(e)) for e in A.edges()])
[('1', '2'), ('1', '2'), ('2', '3'), ('2', '3')]
>>> A.is_directed()
True
>>> A=A.to_undirected()
>>> A.is_directed()
False
>>> sorted([tuple(sorted(e)) for e in A.edges()])
[('1', '2'), ('2', '3')]



digraph only
------------

>>> A=AGraph(directed=True)
>>> A.add_edge(1,2)
>>> A.has_edge(1,2)
True
>>> A.has_edge(2,1)
False
>>> A.add_edge(2,1)
>>> A.has_edge(2,1)
True

>>> A=AGraph(directed=True)
>>> A.add_edges_from(P3.edges())
>>> sorted([tuple(sorted(e)) for e in A.edges()])
[('1', '2'), ('2', '3')]
>>> sorted([tuple(sorted(e)) for e in A.edges_iter()])
[('1', '2'), ('2', '3')]
>>> sorted([tuple(sorted(e)) for e in A.out_edges()])
[('1', '2'), ('2', '3')]
>>> sorted([tuple(sorted(e)) for e in A.out_edges_iter()])
[('1', '2'), ('2', '3')]
>>> sorted([tuple(sorted(e)) for e in A.in_edges()])
[('1', '2'), ('2', '3')]
>>> sorted([tuple(sorted(e)) for e in A.in_edges_iter()])
[('1', '2'), ('2', '3')]
>>> sorted(A.out_edges(1))
[('1', '2')]
>>> sorted(A.out_edges_iter(1))
[('1', '2')]
>>> sorted(A.in_edges(2))
[('1', '2')]
>>> sorted(A.in_edges_iter(2))
[('1', '2')]

>>> A.predecessors(1)
[]
>>> list(A.predecessors_iter(1))
[]
>>> A.predecessors(2)
['1']
>>> list(A.predecessors_iter(2))
['1']

>>> A.successors(1)
['2']
>>> list(A.successors_iter(1))
['2']
>>> A.successors(2)
['3']
>>> list(A.successors_iter(2))
['3']


>>> sorted(A.out_degree())
[0, 1, 1]
>>> sorted(A.out_degree(with_labels=True).values())
[0, 1, 1]
>>> sorted(A.out_degree_iter())
[('1', 1), ('2', 1), ('3', 0)]
>>> sorted(A.in_degree())
[0, 1, 1]
>>> sorted(A.in_degree_iter())
[('1', 0), ('2', 1), ('3', 1)]

>>> A.in_degree(1)
0
>>> A.out_degree(1)
1
>>> A.in_degree(2)
1
>>> A.out_degree(2)
1

>>> A.string()
'strict digraph {\n\t1 -> 2;\n\t2 -> 3;\n}\n'
>>> A.reverse().string()
'strict digraph {\n\t2 -> 1;\n\t3 -> 2;\n}\n'
