4
Unit tests for Graph Class in base.py
5
-------------------------------------
7
>>> from networkx import *
8
>>> from networkx.isomorph import graph_could_be_isomorphic
9
>>> is_isomorphic=graph_could_be_isomorphic
10
>>> from networkx.operators import convert_node_labels_to_integers as cnlti
16
>>> P1=cnlti(path_graph(1),first_label=1)
17
>>> P3=cnlti(path_graph(3),first_label=1)
18
>>> P10=cnlti(path_graph(10),first_label=1)
19
>>> K1=cnlti(complete_graph(1),first_label=1)
20
>>> K3=cnlti(complete_graph(3),first_label=1)
21
>>> K4=cnlti(complete_graph(4),first_label=1)
22
>>> K5=cnlti(complete_graph(5),first_label=1)
23
>>> K10=cnlti(complete_graph(10),first_label=1)
28
>>> G = Graph(name="test")
29
>>> print G # test of __str__
34
datastructure : vdict_of_dicts
47
Test if a non-hashable object is in the Graph. A python dict will
48
raise a TypeError, but for a Graph class a simple False should be
49
returned (see Graph __contains__). If it cannot be a node then it is
55
>>> G.has_node({'A':1})
58
>>> G.delete_node('A')
61
>>> G.add_nodes_from(list("ABCDEFGHIJKL"))
64
>>> G.delete_nodes_from(['H','I','J','K','L'])
65
>>> G.add_nodes_from([1,2,3,4])
67
[1, 2, 3, 4, 'A', 'B', 'C', 'D', 'E', 'F', 'G']
68
>>> sorted(G) # test __iter__
69
[1, 2, 3, 4, 'A', 'B', 'C', 'D', 'E', 'F', 'G']
76
>>> [] in G # never raise a Key or TypeError in this test
87
test node portion of clear()
93
Test add_node and delete_node acting for various nbunch
98
>>> G.add_node('m') # no complaints
99
>>> G.delete_node('j') # NetworkXError
100
Traceback (most recent call last):
102
NetworkXError: node j not in graph
103
>>> G.delete_node('m')
109
>>> G.add_nodes_from(list("ABCD"))
110
>>> G.add_nodes_from(P3) # add nbunch of nodes (nbunch=Graph)
111
>>> sorted(G.nodes())
112
[1, 2, 3, 'A', 'B', 'C', 'D']
113
>>> G.delete_nodes_from(P3) # delete nbunch of nodes (nbunch=Graph)
114
>>> sorted(G.nodes())
119
>>> nbunch=set("ABCDEFGHIJKL")
120
>>> G.add_nodes_from(nbunch)
124
nbunch is a dict with nodes as keys
126
>>> nbunch={'I':"foo",'J':2,'K':True,'L':"spam"}
127
>>> G.delete_nodes_from(nbunch)
128
>>> sorted(G.nodes())
129
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
131
nbunch is an iterator
133
>>> n_iter=P3.nodes_iter()
134
>>> G.add_nodes_from(n_iter)
135
>>> sorted(G.nodes())
136
[1, 2, 3, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
137
>>> n_iter=P3.nodes_iter() # rebuild same iterator
138
>>> G.delete_nodes_from(n_iter) # delete nbunch of nodes (nbunch=iterator)
139
>>> sorted(G.nodes())
140
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
145
>>> G.add_nodes_from(nbunch)
146
>>> sorted(G.nodes())
147
[1, 2, 3, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
154
Traceback (most recent call last):
156
ValueError: need more than 1 value to unpack
158
>>> G.add_edge('A','B') # testing add_edge()
159
>>> G.add_edge('A','B') # should fail silently
160
>>> G.has_edge('A','B') # testing has_edge()
162
>>> G.has_edge('A','C')
164
>>> G.has_edge( ('A','B') )
166
>>> G.has_edge('B','A') # G is undirected, so B->A is an edge
168
>>> G.has_neighbor('A','C') # same as has_edge
170
>>> G.has_neighbor('A','B')
173
>>> G.add_edge('A','C') # test directedness
174
>>> G.add_edge('C','A')
175
>>> G.delete_edge('C','A')
176
>>> G.has_edge('A','C') # G is undirected
178
>>> G.has_edge('C','A')
182
>>> G.add_edge('A','A') # test self loops
183
>>> G.has_edge('A','A') # should not have edge
186
>>> G.add_edge('X','X')
187
>>> G.has_node('X') # added node but not self loop
189
>>> G.delete_node('X')
192
>>> G.add_edge('A','Z') # should add the node silently
196
>>> G.add_edges_from([('B','C')]) # test add_edges_from()
197
>>> G.has_edge('B','C')
199
>>> G.has_edge('C','B') # undirected
201
>>> G.add_edges_from([('D','F'),('B','D')])
202
>>> G.has_edge('D','F')
204
>>> G.has_edge('B','D')
206
>>> G.has_edge('D','B') # undirected
208
>>> G.add_edges_from([tuple('IJ'),list('KK'),tuple('JK')]) # after failing silently, should add 2nd edge
209
>>> G.has_edge(('I','J'))
211
>>> G.has_edge(('K','K'))
213
>>> G.has_edge(('J','K'))
215
>>> G.has_edge(('K','J')) # undirected
218
>>> G.add_path(list('ACDE')) # test add_path() and add_cycle()
219
>>> G.has_edge('D','E')
221
>>> G.has_edge('E','C')
223
>>> G.add_cycle(list('MNOP'))
224
>>> G.has_edge('O','P')
226
>>> G.has_edge('P','M')
228
>>> G.delete_node('P') # tests delete_node()'s handling of edges.
229
>>> G.has_edge('P','M')
233
>>> G.delete_edge('M') # test delete_edge()
234
Traceback (most recent call last):
236
ValueError: need more than 1 value to unpack
238
>>> G.add_edge('N','M')
239
>>> G.has_edge('M','N')
241
>>> G.delete_edge('M','N')
242
>>> G.has_edge('M','N')
244
>>> G.has_edge('N','M') # undirected
246
>>> G.delete_edges_from([list('HI'),list('DF'),tuple('KK'),tuple('JK')]) # self loop fails silently
247
>>> G.has_edge('H','I')
249
>>> G.has_edge('J','K')
251
>>> G.delete_edges_from([list('IJ'),list('KK'),list('JK')])
252
>>> G.has_edge('I','J')
254
>>> G.delete_nodes_from(set('ZEFHIMNO'))
255
>>> sorted(G.nodes())
256
[1, 2, 3, 'A', 'B', 'C', 'D', 'G', 'J', 'K']
257
>>> G.delete_nodes_from([1,2,3])
258
>>> sorted(G.nodes())
259
['A', 'B', 'C', 'D', 'G', 'J', 'K']
260
>>> sorted(G.edges())
261
[('A', 'B'), ('A', 'C'), ('B', 'D'), ('C', 'B'), ('C', 'D')]
263
Test G.edges(nbunch) with various forms of nbunch
265
node not in nbunch should be quietly ignored
267
>>> sorted(G.edges(6)) # non-iterable non-node
268
Traceback (most recent call last):
270
NetworkXError: nbunch is not a node or a sequence of nodes.
272
>>> sorted(G.edges('Z')) # iterable non-node
275
nbunch can be an empty list
277
>>> sorted(G.edges([]))
282
>>> sorted(G.edges(['A','B']))
283
[('A', 'B'), ('A', 'C'), ('B', 'C'), ('B', 'D')]
287
>>> sorted(G.edges(set(['A','B'])))
288
[('A', 'B'), ('A', 'C'), ('B', 'C'), ('B', 'D')]
290
nbunch can be a graph
293
>>> G1.add_nodes_from('AB')
294
>>> sorted(G.edges(G1)) # nbunch is a graph
295
[('A', 'B'), ('A', 'C'), ('B', 'C'), ('B', 'D')]
297
nbunch can be a dict with nodes as keys
299
>>> ndict={'A': "thing1", 'B': "thing2"}
300
>>> sorted(G.edges(ndict))
301
[('A', 'B'), ('A', 'C'), ('B', 'C'), ('B', 'D')]
303
nbunch can be a single node
305
>>> sorted(G.edges('A'))
306
[('A', 'B'), ('A', 'C')]
309
Test G.edges_iter(nbunch) with various forms of nbunch
311
node not in nbunch should be quietly ignored
313
>>> sorted(G.edges_iter('Z'))
316
nbunch can be an empty list
318
>>> sorted(G.edges_iter([]))
323
>>> sorted(G.edges_iter(['A','B']))
324
[('A', 'B'), ('A', 'C'), ('B', 'C'), ('B', 'D')]
328
>>> sorted(G.edges_iter(set(['A','B'])))
329
[('A', 'B'), ('A', 'C'), ('B', 'C'), ('B', 'D')]
331
nbunch can be a graph
334
>>> G1.add_nodes_from(['A','B'])
335
>>> sorted(G.edges_iter(G1)) # nbunch is a graph
336
[('A', 'B'), ('A', 'C'), ('B', 'C'), ('B', 'D')]
338
nbunch can be a dict with nodes as keys
340
>>> ndict={'A': "thing1", 'B': "thing2"}
341
>>> sorted(G.edges_iter(ndict))
342
[('A', 'B'), ('A', 'C'), ('B', 'C'), ('B', 'D')]
344
nbunch can be a single node
346
>>> sorted(G.edges_iter('A'))
347
[('A', 'B'), ('A', 'C')]
349
nbunch can be nothing (whole graph)
351
>>> sorted(G.edges_iter())
352
[('A', 'B'), ('A', 'C'), ('B', 'D'), ('C', 'B'), ('C', 'D')]
353
>>> sorted(G.nodes_iter())
354
['A', 'B', 'C', 'D', 'G', 'J', 'K']
357
Node and Edge Boundaries
358
------------------------
360
null graph has empty boundaries
362
>>> null.node_boundary([])
364
>>> null.node_boundary([],[])
366
>>> null.node_boundary([1,2,3])
368
>>> null.node_boundary([1,2,3],[4,5,6])
370
>>> null.node_boundary([1,2,3],[3,4,5])
374
>>> null.edge_boundary([])
376
>>> null.edge_boundary([],[])
378
>>> null.edge_boundary([1,2,3])
380
>>> null.edge_boundary([1,2,3],[4,5,6])
382
>>> null.edge_boundary([1,2,3],[3,4,5])
385
Check boundaries in path graph.
387
>>> P10.node_boundary([])
389
>>> P10.node_boundary([],[])
391
>>> P10.node_boundary([1,2,3])
393
>>> sorted(P10.node_boundary([4,5,6]))
395
>>> sorted(P10.node_boundary([3,4,5,6,7]))
397
>>> P10.node_boundary([8,9,10])
399
>>> sorted(P10.node_boundary([4,5,6],[9,10]))
401
>>> P10.node_boundary([1,2,3],[3,4,5])
402
Traceback (most recent call last):
404
NetworkXError: nbunch1 and nbunch2 are not disjoint
407
>>> P10.edge_boundary([])
409
>>> P10.edge_boundary([],[])
411
>>> P10.edge_boundary([1,2,3])
413
>>> sorted(P10.edge_boundary([4,5,6]))
415
>>> sorted(P10.edge_boundary([3,4,5,6,7]))
417
>>> P10.edge_boundary([8,9,10])
419
>>> sorted(P10.edge_boundary([4,5,6],[9,10]))
421
>>> P10.edge_boundary([1,2,3],[3,4,5])
422
Traceback (most recent call last):
424
NetworkXError: nbunch1 and nbunch2 are not disjoint
426
Check boundaries in a complete graph
428
>>> K10.node_boundary([])
430
>>> K10.node_boundary([],[])
432
>>> sorted(K10.node_boundary([1,2,3]))
433
[4, 5, 6, 7, 8, 9, 10]
434
>>> sorted(K10.node_boundary([4,5,6]))
435
[1, 2, 3, 7, 8, 9, 10]
436
>>> sorted(K10.node_boundary([3,4,5,6,7]))
438
>>> sorted(K10.node_boundary([4,5,6],[]))
440
>>> K10.node_boundary(K10)
442
>>> K10.node_boundary([1,2,3],[3,4,5])
443
Traceback (most recent call last):
445
NetworkXError: nbunch1 and nbunch2 are not disjoint
448
>>> K10.edge_boundary([])
450
>>> K10.edge_boundary([],[])
452
>>> len(K10.edge_boundary([1,2,3]))
454
>>> len(K10.edge_boundary([4,5,6,7]))
456
>>> len(K10.edge_boundary([3,4,5,6,7]))
458
>>> len(K10.edge_boundary([8,9,10]))
460
>>> sorted(K10.edge_boundary([4,5,6],[9,10]))
461
[(4, 9), (4, 10), (5, 9), (5, 10), (6, 9), (6, 10)]
462
>>> K10.edge_boundary([1,2,3],[3,4,5])
463
Traceback (most recent call last):
465
NetworkXError: nbunch1 and nbunch2 are not disjoint
468
Check boundaries in the petersen graph
470
cheeger(G,k)=min(|bdy(S)|/|S| for |S|=k, 0<k<=|V(G)|/2)
472
>>> from random import sample
473
>>> P=petersen_graph()
474
>>> def cheeger(G,k):
475
... return min([float(len(G.node_boundary(sample(G.nodes(),k))))/k for n in xrange(100)])
476
>>> print "%4.2f"%cheeger(P,1)
478
>>> print "%4.2f"%cheeger(P,2)
480
>>> print "%4.2f"%cheeger(P,3)
482
>>> print "%4.2f"%cheeger(P,4)
484
>>> print "%4.2f"%cheeger(P,5)
486
>>> print "%4.2f"%cheeger(P,6)
488
>>> print "%4.2f"%cheeger(P,7)
490
>>> print "%4.2f"%cheeger(P,8)
492
>>> print "%4.2f"%cheeger(P,9)
494
>>> print "%4.2f"%cheeger(P,10)
500
degree of single node must return single int
505
degree of single node in iterable container must return list
510
with_labels=True always return a dict
512
>>> G.degree('A',with_labels=True)
515
>>> G.degree(['A','B'])
517
>>> G.degree(['A','B'],with_labels=True)
520
>>> sorted(G.degree())
521
[0, 0, 0, 2, 2, 3, 3]
522
>>> sorted(list(G.degree_iter()))
523
[0, 0, 0, 2, 2, 3, 3]
527
>>> P3.degree(['A','B']) # silently ignore nodes not in P3
529
>>> sorted(P5.degree(P3)) # nbunch can be a graph
531
>>> sorted(P3.degree(P5)) # nbunch can be a graph thats way to big
535
>>> list(P5.degree_iter([]))
537
>>> dict( P5.degree_iter([],with_labels=True) )
539
>>> dict(P5.degree_iter([],with_labels=True))
542
>>> null=null_graph()
545
>>> null.degree(with_labels=True)
547
>>> list(null.degree_iter())
549
>>> dict(null.degree_iter(with_labels=True))
564
>>> H=G.copy() # copy
576
>>> SG=G.subgraph(['A','B','D'])
577
>>> sorted(SG.nodes())
579
>>> sorted(SG.edges())
580
[('A', 'B'), ('B', 'D')]
584
>>> DG=G.to_directed()
597
>>> sorted(DG.out_edges(list('AB')))
598
[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('B', 'D')]
599
>>> DG.delete_edge('A','B')
600
>>> DG.has_edge('B','A') # this deletes B-A but not A-B
602
>>> DG.has_edge('A','B')
613
>>> sorted(G.neighbors('A'))
615
>>> sorted(G.neighbors_iter('A'))
618
>>> sorted(G.neighbors('G'))
620
>>> sorted(G.neighbors('j'))
621
Traceback (most recent call last):
623
NetworkXError: node j not in graph
630
['A', 'B', 'C', 'D', 'G', 'J', 'K']
631
>>> sorted(nodes_iter(G))
632
['A', 'B', 'C', 'D', 'G', 'J', 'K']
634
[('A', 'B'), ('A', 'C'), ('B', 'D'), ('C', 'B'), ('C', 'D')]
635
>>> sorted(edges_iter(G))
636
[('A', 'B'), ('A', 'C'), ('B', 'D'), ('C', 'B'), ('C', 'D')]
637
>>> sorted(degree(G))
638
[0, 0, 0, 2, 2, 3, 3]
639
>>> sorted(neighbors(G,'A'))
641
>>> number_of_nodes(G)
643
>>> number_of_edges(G)
645
>>> density(G)==5/(7*(7-1)*0.5)
647
>>> degree_histogram(G)
655
>>> sorted(G.nodes_iter())
656
['A', 'B', 'C', 'D', 'G', 'J', 'K']
657
>>> sorted(G.edges_iter())
658
[('A', 'B'), ('A', 'C'), ('B', 'D'), ('C', 'B'), ('C', 'D')]
659
>>> sorted(G.degree_iter())
660
[0, 0, 0, 2, 2, 3, 3]
661
>>> sorted(G.degree_iter(with_labels=True))
662
[('A', 2), ('B', 3), ('C', 3), ('D', 2), ('G', 0), ('J', 0), ('K', 0)]
663
>>> sorted(G.neighbors_iter('A'))
665
>>> sorted(G.neighbors_iter('X'))
666
Traceback (most recent call last):
668
NetworkXError: node X not in graph
671
>>> number_of_nodes(G)
673
>>> number_of_edges(G)
680
Subgraph of a null graph is a null graph
682
>>> nullgraph=null_graph()
685
>>> is_isomorphic(H,nullgraph)
688
Subgraph of an empty graph is an empty graph. test 1
690
>>> E5=empty_graph(5)
691
>>> E10=empty_graph(10)
692
>>> H=E10.subgraph([])
693
>>> is_isomorphic(H,nullgraph)
696
Subgraph of an empty graph is an empty graph. test 2
698
>>> H=E10.subgraph([1,2,3,4,5])
699
>>> is_isomorphic(H,E5)
702
Subgraph of a complete graph is a complete graph
704
>>> K1=complete_graph(1)
705
>>> K3=complete_graph(3)
706
>>> K5=complete_graph(5)
707
>>> H=K5.subgraph([1,2,3])
708
>>> is_isomorphic(H,K3)
711
Test G.subgraph(nbunch), where nbunch is a single node
714
>>> is_isomorphic(H,K1)
717
>>> H=J5.subgraph(1,inplace=True)
718
>>> is_isomorphic(H,K1)
720
>>> is_isomorphic(J5,K1)
723
Test G.subgraph(nbunch), where nbunch is a set
725
>>> H=K5.subgraph(set([1]))
726
>>> is_isomorphic(H,K1)
729
>>> H=J5.subgraph(set([1]),inplace=True)
730
>>> is_isomorphic(H,K1)
732
>>> is_isomorphic(J5,K1)
735
Test G.subgraph(nbunch), where nbunch is an iterator
737
>>> H=K5.subgraph(iter(K3))
738
>>> is_isomorphic(H,K3)
741
>>> H=J5.subgraph(iter(K3),inplace=True)
742
>>> is_isomorphic(H,K3)
744
>>> is_isomorphic(J5,K3)
747
Test G.subgraph(nbunch), where nbunch is another graph
749
>>> H=K5.subgraph(K3)
750
>>> is_isomorphic(H,K3)
753
>>> H=J5.subgraph(K3,inplace=True)
754
>>> is_isomorphic(H,K3)
756
>>> is_isomorphic(J5,K3)
760
Test for no error when nbunch has node not in G.nodes()
762
>>> H=K5.subgraph([9])
763
>>> is_isomorphic(H,null_graph())