Hello!!

What is your opinion about improving the export and import of graphs?

My conclusion of the sage-devel thread "Code duplication and aliases in methods" is that at the moment the source code in graph theory is not so optimal organized. As promised, I want to show some modifications that would lead to a better design.

I found following members dealing with import or export of the class Graph.

- returning a string to represent a graph:
g.graph6_string, g.graphviz_string, g.dumps

- export of a graph to a file
g.graphviz_to_file_named, g.dump, g.save, g.db, (g.write_to_eps seems to involve g.plot)

- import of a graph from a file
none found??  Oh, they are hidden in the class constructors!!


Including this functionality into the class Graph makes this class heavier and more difficult to understand - in my opinion (see the "single responsibility principle" [1]). Hence, I would create two separate classes for that. Actually, there is no need to have pairs of import/export functions. Maybe one wants to read some special format only but does not need to write in that format. Or vice verse. Hence, I separate the import functions from the export ones.

My approach uses static classes, that is, they contain no data and only member functions. For every programming task, there is only one instance which exports the graphs (and one for importing). Since we have two different types of graphs, Graph and Digraph, we need some case distinction...

Some pseudo code about the classes - just to get the idea - hope you can understand :-)

{{{
def GraphExporter:
    def graphviz(graph_object, filename, more_options)  # calls
                                helper functions according to type
    def _graphviz_Graph(graph_object, filename, more_options)
    def _graphviz_DiGraph(graph_object, filename, more_options)

    def sage_format(graph_object, filename, more_options)  # calls
                                helper functions according to type
    def _sage_format_Graph(graph_object, filename, more_options)
    def _sage_format_DiGraph(graph_object, filename, more_options)

    def graph6_string(graph_object) returns string
    def graphviz_string(graph_object) returns string

def GraphImporter:
    def graphviz(filename, more_options) returns Graph_or_DiGraph_object
    def graphviz_get_type(filename, more_options) returns graph_type
    def _graphviz_Graph(filename, more_options) returns Graph_object
    def _graphviz_DiGraph(filename, more_options) returns DiGraph_object

    def sage_format(filename, more_options) returns (Di)Graph_object
    def sage_format_get_type(filename, more_options) returns graph_type
    def _sage_format_Graph(filename, more_options) returns Graph_object
    def _sage_format_DiGraph(filename, more_options) returns DiGraph_object

    def graph6_string(string) returns graph_object
    def graphviz_string(string) returns graph_object
}}}

Advantages of this design:
+ Adding a new import or export format is easier since the class Graph/DiGraph will not be touched. + The classes Graph and DiGraph will have less members. Files like graph.py and digraph.py will slightly lose weight...

Disadvantage(s):
- There is one more file and two more classes..., Anything else?


Example code for reading unknown file and then write it in another format:
{{{
   GI = GraphImporter()
   G = GI.graphviz("/home/sage/myfile.viz")
   GraphExporter().sage_format(G, "/home/sage/myfile.sage")
}}}

What do you think about this approach? I might have overseen things since I am quite new to sage...

Birk

[1] https://en.wikipedia.org/wiki/Single_responsibility_principle

--
--
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org

Reply via email to