44 _NetworkXBuiltin ,
55 nx ,
66)
7- from mathics .core .expression import String
7+ from mathics .core .expression import Integer , String
8+ from typing import Callable , Optional
9+
10+ # TODO: Can this code can be DRY'd more?
11+
12+
13+ def graph_helper (
14+ graph_generator_func : Callable ,
15+ options : dict ,
16+ can_digraph : bool ,
17+ graph_layout : str ,
18+ root : Optional [int ] = None ,
19+ * args ,
20+ ** kwargs
21+ ) -> Optional [Callable ]:
22+ should_digraph = can_digraph and options ["System`Directed" ].to_python ()
23+ try :
24+ G = (
25+ graph_generator_func (* args , create_using = nx .DiGraph , ** kwargs )
26+ if should_digraph
27+ else graph_generator_func (* args , ** kwargs )
28+ )
29+ except MemoryError :
30+ evaluation .message (self .get_name (), "mem" , expression )
31+ return None
32+ G .graph_layout = options ["System`GraphLayout" ].get_string_value () or String (
33+ graph_layout
34+ )
35+ G .vertex_labeling = options ["System`VertexLabeling" ]
36+ g = Graph (G )
837
9- # TODO: this code can be DRY'd a bit.
38+ if root is not None :
39+ G .root = g .root = root
40+ G .title = g .title = options ["System`PlotLabel" ]
41+ return g
1042
1143
1244class BalancedTree (_NetworkXBuiltin ):
@@ -38,32 +70,19 @@ def apply(self, r, h, expression, evaluation, options):
3870
3971 if py_r < 0 :
4072 evaluation .message (self .get_name (), "ilsmp" , expression )
41- return
73+ return None
4274
4375 py_h = h .get_int_value ()
4476 if py_h < 0 :
4577 evaluation .message (self .get_name (), "ilsmp2" , expression )
46- return
47-
48- graph_create = nx .DiGraph if options ["System`Directed" ].to_python () else nx .Graph
49-
50- try :
51- G = nx .balanced_tree (py_r , py_h , create_using = graph_create )
52- except MemoryError :
53- evaluation .message (self .get_name (), "mem" , expression )
54- return
55-
56- options ["GraphLayout" ] = options ["System`GraphLayout" ].get_string_value () or String (
57- "tree"
58- )
59- options ["VertexLabeling" ] = options ["System`VertexLabeling" ]
60- g = Graph (G , options = options )
61-
62- g .r = r
63- g .h = h
64- G .root = g .root = 0
65- G .title = g .title = options ["System`PlotLabel" ]
66-
78+ return None
79+
80+ args = (py_r , py_h )
81+ g = graph_helper (nx .balanced_tree , options , True , "tree" , 0 , * args )
82+ if not g :
83+ return None
84+ g .G .r = r
85+ g .G .h = h
6786 return g
6887
6988
@@ -74,7 +93,7 @@ class BarbellGraph(_NetworkXBuiltin):
7493 <dd>Barbell Graph: two complete graphs connected by a path.
7594 </dl>
7695
77- >> BarBellGraph[2, 3 ]
96+ >> BarBellGraph[4, 1 ]
7897 = -Graph-
7998
8099 """
@@ -97,16 +116,13 @@ def apply(self, m1, m2, expression, evaluation, options):
97116 evaluation .message (self .get_name (), "ilsmp" , expression )
98117 return
99118
100- G = nx .barbell_graph (py_m1 , py_m2 )
119+ args = (py_m1 , py_m2 )
120+ g = graph_helper (nx .barbell_graph , options , False , "spring" , None , * args )
121+ if not g :
122+ return None
101123
102- options ["GraphLayout" ] = options ["System`GraphLayout" ].get_string_value () or String (
103- "spring"
104- )
105- options ["VertexLabeling" ] = options ["System`VertexLabeling" ]
106- g = Graph (G , options = options )
107- g .m1 = m1
108- g .m2 = m2
109- G .title = g .title = options ["System`PlotLabel" ]
124+ g .G .m1 = m1
125+ g .G .m2 = m2
110126 return g
111127
112128
@@ -143,20 +159,11 @@ def apply(self, n, expression, evaluation, options):
143159 evaluation .message (self .get_name (), "ilsmp" , expression )
144160 return
145161
146- try :
147- G = nx .binomial_tree (py_n )
148- except MemoryError :
149- evaluation .message (self .get_name (), "mem" , expression )
150- return
151-
152- options ["GraphLayout" ] = options ["System`GraphLayout" ].get_string_value () or String (
153- "tree"
154- )
155- options ["VertexLabeling" ] = options ["System`VertexLabeling" ]
156- g = Graph (G , options = options )
157- g .n = n
158- G .root = g .root = 0
159- G .title = g .title = options ["System`PlotLabel" ]
162+ args = (py_n ,)
163+ g = graph_helper (nx .binomial_tree , options , False , "tree" , 0 , * args )
164+ if not g :
165+ return None
166+ g .G .n = n
160167 return g
161168
162169
@@ -189,9 +196,9 @@ def apply(self, n, expression, evaluation, options):
189196
190197 G = nx .complete_graph (py_n )
191198
192- options ["GraphLayout" ] = options ["System`GraphLayout" ]. get_string_value () or String (
193- "circular "
194- )
199+ options ["GraphLayout" ] = options [
200+ "System`GraphLayout "
201+ ]. get_string_value () or String ( "circular" )
195202 options ["VertexLabeling" ] = options ["System`VertexLabeling" ]
196203 g = Graph (G , options = options )
197204 g .n = n
@@ -242,36 +249,26 @@ def apply(self, r, n, expression, evaluation, options):
242249 evaluation .message (self .get_name (), "ilsmp" , expression )
243250 return
244251
245- graph_create = nx .DiGraph if options ["System`Directed" ].to_python () else nx .Graph
246-
247- try :
248- G = nx .full_rary_tree (py_r , py_n , create_using = graph_create )
249- except MemoryError :
250- evaluation .message (self .get_name (), "mem" , expression )
251- return
252+ args = (py_r , py_n )
253+ g = graph_helper (nx .full_rary_tree , options , True , "tree" , 0 , * args )
254+ if not g :
255+ return None
252256
253- options ["GraphLayout" ] = options ["System`GraphLayout" ].get_string_value () or String (
254- "tree"
255- )
256- options ["VertexLabeling" ] = options ["System`VertexLabeling" ]
257- g = Graph (G , options = options )
258- g .r = r
259- g .n = n
260- G .root = g .root = 0
261- G .title = g .title = options ["System`PlotLabel" ]
257+ g .G .r = r
258+ g .G .n = n
262259 return g
263260
264261
265262class GraphAtlas (_NetworkXBuiltin ):
266- """
267- <dl>
263+ """<dl>
268264 <dt>'GraphAtlas[$n$]'
269- <dd>gives graph number $i$ from the Networkx's Graph Atlas. There are about 1200 of them.
265+ <dd>gives graph number $i$ from the Networkx's Graph
266+ Atlas. There are about 1200 of them and get large as $i$
267+ increases.
270268 </dl>
271269
272270 >> GraphAtlas[1000]
273271 = -Graph-
274-
275272 """
276273
277274 messages = {
@@ -286,10 +283,11 @@ def apply(self, n, expression, evaluation, options):
286283 evaluation .message (self .get_name (), "ilsmp" , expression )
287284 return
288285
289- G = nx .graph_atlas (py_n )
290- g = Graph (G )
286+ args = (py_n ,)
287+ g = graph_helper (nx .graph_atlas , options , False , "spring" , None , * args )
288+ if not g :
289+ return None
291290 g .n = n
292- G .title = g .title = options ["System`PlotLabel" ]
293291 return g
294292
295293
@@ -330,16 +328,12 @@ def apply(self, k, n, expression, evaluation, options):
330328
331329 from pymathics .graph .harary import hkn_harary_graph
332330
333- G = hkn_harary_graph (py_k , py_n )
334-
335- options ["GraphLayout" ] = options ["System`GraphLayout" ].get_string_value () or String (
336- "spring"
337- )
338- options ["VertexLabeling" ] = options ["System`VertexLabeling" ]
339- g = Graph (G , options = options )
340- g .n = n
341- G .root = g .root = 0
342- G .title = g .title = options ["System`PlotLabel" ]
331+ args = (py_k , py_n )
332+ g = graph_helper (hkn_harary_graph , options , False , "circular" , None , * args )
333+ if not g :
334+ return None
335+ g .k = py_k
336+ g .n = py_n
343337 return g
344338
345339
@@ -380,16 +374,12 @@ def apply(self, n, m, expression, evaluation, options):
380374
381375 from pymathics .graph .harary import hnm_harary_graph
382376
383- G = hnm_harary_graph (py_n , py_m )
384-
385- options ["GraphLayout" ] = options ["System`GraphLayout" ].get_string_value () or String (
386- "circular"
387- )
388- options ["VertexLabeling" ] = options ["System`VertexLabeling" ]
389- g = Graph (G , options = options )
390- g .n = n
391- G .root = g .root = 0
392- G .title = g .title = options ["System`PlotLabel" ]
377+ args = (py_n , py_m )
378+ g = graph_helper (hmn_harary_graph , options , False , "circular" , None , * args )
379+ if not g :
380+ return None
381+ g .n = py_n
382+ g .m = py_m
393383 return g
394384
395385
@@ -417,15 +407,11 @@ def apply(self, n, expression, evaluation, options):
417407 evaluation .message (self .get_name (), "ilsmp" , expression )
418408 return
419409
420- G = nx .random_tree (py_n )
421-
422- options ["GraphLayout" ] = options ["System`GraphLayout" ].get_string_value () or String (
423- "circular"
424- )
425- options ["VertexLabeling" ] = options ["System`VertexLabeling" ]
426- g = Graph (G , options = options )
427- g .n = n
428- G .root = g .root = 0
410+ args = (py_n ,)
411+ g = graph_helper (nx .random_tree , options , False , "tree" , 0 , * args )
412+ if not g :
413+ return None
414+ g .G .n = n
429415 return g
430416
431417
@@ -452,18 +438,9 @@ def apply(self, n, expression, evaluation, options):
452438 evaluation .message (self .get_name (), "ilsmp" , expression )
453439 return
454440
455- try :
456- G = nx .star_graph (py_n )
457- except MemoryError :
458- evaluation .message (self .get_name (), "mem" , expression )
459- return
460-
461- options ["GraphLayout" ] = options ["System`GraphLayout" ].get_string_value () or String (
462- "spring"
463- )
464- options ["VertexLabeling" ] = options ["System`VertexLabeling" ]
465-
466- g = Graph (G , options = options )
467- g .n = n
468- G .title = g .title = options ["System`PlotLabel" ]
441+ args = (py_n ,)
442+ g = graph_helper (nx .star_graph , options , False , "spring" , 0 , * args )
443+ if not g :
444+ return None
445+ g .G .n = n
469446 return g
0 commit comments