[geneagrapher] 10/226: Implemented Geneagrapher class, which allows the tool to be used from the command line to produce "ancestor graphs". This resolves ticket #6.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Sat Jul 11 17:10:31 UTC 2015
This is an automated email from the git hooks/post-receive script.
dtorrance-guest pushed a commit to branch master
in repository geneagrapher.
commit c72325824089e56f7dca2724aed2f9395a3e8c28
Author: David Alber <alber.david at gmail.com>
Date: Sat May 3 04:18:18 2008 +0000
Implemented Geneagrapher class, which allows the tool to be used from the command line to produce "ancestor graphs". This resolves ticket #6.
---
src/GGraph.py | 50 +++++++++++++++++++++++++++++---------------------
src/geneagrapher.py | 35 +++++++++++++++++++++++++----------
src/tests.py | 44 ++++++++++++++++++++++++++------------------
3 files changed, 80 insertions(+), 49 deletions(-)
diff --git a/src/GGraph.py b/src/GGraph.py
index 1123fef..3b5186a 100644
--- a/src/GGraph.py
+++ b/src/GGraph.py
@@ -27,9 +27,9 @@ class Record:
# Verify we got the types wanted.
if not isinstance(self.name, basestring):
raise TypeError("Unexpected parameter type: expected string value for 'name'")
- if not isinstance(self.institution, basestring):
+ if not isinstance(self.institution, basestring) and self.institution is not None:
raise TypeError("Unexpected parameter type: expected string value for 'institution'")
- if not isinstance(self.year, int):
+ if not isinstance(self.year, int) and self.year is not None:
raise TypeError("Unexpected parameter type: expected integer value for 'year'")
if not isinstance(self.id, int):
raise TypeError("Unexpected parameter type: expected integer value for 'id'")
@@ -45,14 +45,14 @@ class Record:
Return True if this record has an institution associated with it,
else False.
"""
- return self.institution != ""
+ return self.institution is not None
def hasYear(self):
"""
Return True if this record has a year associated with it, else
False.
"""
- return self.year != -1
+ return self.year is not None
class Node:
@@ -114,24 +114,28 @@ class Graph:
"""
Class storing the representation of a genealogy graph.
"""
- def __init__(self, head=None):
+ def __init__(self, heads=None):
"""
Graph class constructor.
Parameters:
- head: a Node object representing the tree head (can be
- omitted to create an empty graph)
+ heads: a list of Node objects representing the tree head
+ (can be omitted to create an empty graph)
"""
- self.head = head
+ self.heads = heads
- # Verify type of head is what we expect.
- if self.head is not None and not isinstance(self.head, Node):
- raise TypeError("Unexpected parameter type: expected Node object for 'head'")
-
- if self.head is not None:
- self.nodes = {head.id(): head}
- else:
- self.nodes = {}
+ # Verify type of heads is what we expect.
+ if self.heads is not None:
+ if not isinstance(self.heads, list):
+ raise TypeError("Unexpected parameter type: expected list of Node objects for 'heads'")
+ for head in self.heads:
+ if not isinstance(head, Node):
+ raise TypeError("Unexpected parameter type: expected list of Node objects for 'heads'")
+
+ self.nodes = {}
+ if self.heads is not None:
+ for head in self.heads:
+ self.nodes[head.id()] = head
def hasNode(self, id):
"""
@@ -155,7 +159,7 @@ class Graph:
"""
return self.nodes.keys()
- def addNode(self, name, institution, year, id, ancestors):
+ def addNode(self, name, institution, year, id, ancestors, isHead=False):
"""
Add a new node to the graph if a matching node is not already
present.
@@ -164,8 +168,10 @@ class Graph:
record = Record(name, institution, year, id)
node = Node(record, ancestors)
self.nodes[id] = node
- if self.head is None:
- self.head = node
+ if self.heads is None:
+ self.heads = [node]
+ elif isHead:
+ self.heads.append(node)
else:
msg = "node with id %d already exists" % (id)
raise DuplicateNodeError(msg)
@@ -175,10 +181,12 @@ class Graph:
Return a string that contains the content of the Graphviz dotfile
format for this graph.
"""
- if self.head is None:
+ if self.heads is None:
return ""
- queue = [self.head.id()]
+ queue = []
+ for head in self.heads:
+ queue.append(head.id())
edges = ""
dotfile = ""
diff --git a/src/geneagrapher.py b/src/geneagrapher.py
index f54d478..c142f36 100644
--- a/src/geneagrapher.py
+++ b/src/geneagrapher.py
@@ -12,6 +12,7 @@ class Geneagrapher:
self.leaf_ids = []
self.get_ancestors = True
self.get_descendents = False
+ self.verbose = False
self.write_filename = None
def parseInput(self):
@@ -23,20 +24,29 @@ class Geneagrapher:
self.parser.set_usage("%prog [options] ID ...")
self.parser.set_description('Create a Graphviz "dot" file for a mathematics genealogy, where ID is a record identifier from the Mathematics Genealogy Project. Multiple IDs may be passed.')
- self.parser.add_option("-f", "--file", dest="filename", help="write report to FILE [default: stdout]",
- metavar="FILE", default=None)
- self.parser.add_option("--without-ancestors", action="store_false", dest="get_ancestors", default=True,
- help="do not get ancestors of any input IDs")
- self.parser.add_option("--with-descendents", action="store_true", dest="get_descendents", default=False,
- help="do not get ancestors of any input IDs")
+ self.parser.add_option("-f", "--file", dest="filename",
+ help="write report to FILE [default: stdout]", metavar="FILE", default=None)
+ self.parser.add_option("--without-ancestors", action="store_false", dest="get_ancestors",
+ default=True, help="do not get ancestors of any input IDs")
+ self.parser.add_option("--with-descendents", action="store_true", dest="get_descendents",
+ default=False, help="do not get ancestors of any input IDs")
+ self.parser.add_option("--verbose", "-v", action="store_true", dest="verbose", default=False,
+ help="print information showing progress")
+ self.parser.add_option("--version", "-V", action="store_true", dest="print_version", default=False,
+ help="print geneagrapher version and exit")
(options, args) = self.parser.parse_args()
+ if options.print_version:
+ print "Geneagrapher Version 0.2"
+ self.parser.exit()
+
if len(args) == 0:
raise SyntaxError("%s: error: no record IDs passed" % (self.parser.get_prog_name()))
-
+
self.get_ancestors = options.get_ancestors
self.get_descendents = options.get_descendents
+ self.verbose = options.verbose
self.write_filename = options.filename
for arg in args:
self.leaf_ids.append(int(arg))
@@ -46,18 +56,23 @@ class Geneagrapher:
Populate the graph member by grabbing the mathematician
pages and extracting relevant data.
"""
- grab_queue = self.leaf_ids
+ grab_queue = list(self.leaf_ids)
while len(grab_queue) != 0:
id = grab_queue.pop()
if not self.graph.hasNode(id):
# Then this information has not yet been grabbed.
grabber = grab.Grabber(id)
+ if self.verbose:
+ print "Grabbing record #%d" % (id)
try:
[name, institution, year, advisors] = grabber.extractNodeInformation()
except ValueError:
# The given id does not exist in the Math Genealogy Project's database.
raise
- self.graph.addNode(name, institution, year, id, advisors)
+ if id in self.leaf_ids:
+ self.graph.addNode(name, institution, year, id, advisors, True)
+ else:
+ self.graph.addNode(name, institution, year, id, advisors)
if self.get_ancestors:
grab_queue += advisors
@@ -78,4 +93,4 @@ if __name__ == "__main__":
print geneagrapher.parser.get_usage()
print e
geneagrapher.buildGraph()
- geneagrapher.generateDotFile()
\ No newline at end of file
+ geneagrapher.generateDotFile()
diff --git a/src/tests.py b/src/tests.py
index 06e8119..15abc32 100644
--- a/src/tests.py
+++ b/src/tests.py
@@ -52,9 +52,9 @@ class TestRecordMethods(unittest.TestCase):
record = GGraph.Record("Carl Friedrich Gauss", "Universitaet Helmstedt", 1799, 18231)
self.assert_(record.hasInstitution())
- def test009_hasInstitution_yes(self):
+ def test009_hasInstitution_no(self):
# Verify hasInstitution() method returns False when the conditions are right.
- record = GGraph.Record("Carl Friedrich Gauss", "", 1799, 18231)
+ record = GGraph.Record("Carl Friedrich Gauss", None, 1799, 18231)
self.assert_(not record.hasInstitution())
def test010_hasYear_yes(self):
@@ -64,7 +64,7 @@ class TestRecordMethods(unittest.TestCase):
def test011_hasYear_no(self):
# Verify hasYear() method returns False when the conditions are right.
- record = GGraph.Record("Carl Friedrich Gauss", "Universitaet Helmstedt", -1, 18231)
+ record = GGraph.Record("Carl Friedrich Gauss", "Universitaet Helmstedt", None, 18231)
self.assert_(not record.hasYear())
class TestNodeMethods(unittest.TestCase):
@@ -98,7 +98,7 @@ class TestNodeMethods(unittest.TestCase):
def test005_str_no_year(self):
# Test __str__() method for Node containing record without year.
- record = GGraph.Record("Carl Friedrich Gauss", "Universitaet Helmstedt", -1, 18231)
+ record = GGraph.Record("Carl Friedrich Gauss", "Universitaet Helmstedt", None, 18231)
node = GGraph.Node(record, [])
nodestr = node.__str__()
nodestrexpt = "Carl Friedrich Gauss \\nUniversitaet Helmstedt"
@@ -106,7 +106,7 @@ class TestNodeMethods(unittest.TestCase):
def test006_str_no_inst(self):
# Test __str__() method for Node containing record without institution.
- record = GGraph.Record("Carl Friedrich Gauss", "", 1799, 18231)
+ record = GGraph.Record("Carl Friedrich Gauss", None, 1799, 18231)
node = GGraph.Node(record, [])
nodestr = node.__str__()
nodestrexpt = "Carl Friedrich Gauss \\n(1799)"
@@ -115,7 +115,7 @@ class TestNodeMethods(unittest.TestCase):
def test007_str_no_inst_no_id(self):
# Test __str__() method for Node containing record without institution
# or year.
- record = GGraph.Record("Carl Friedrich Gauss", "", -1, 18231)
+ record = GGraph.Record("Carl Friedrich Gauss", None, None, 18231)
node = GGraph.Node(record, [])
nodestr = node.__str__()
nodestrexpt = "Carl Friedrich Gauss"
@@ -157,21 +157,21 @@ class TestGraphMethods(unittest.TestCase):
def setUp(self):
self.record1 = GGraph.Record("Carl Friedrich Gauss", "Universitaet Helmstedt", 1799, 18231)
self.node1 = GGraph.Node(self.record1, [])
- self.graph1 = GGraph.Graph(self.node1)
+ self.graph1 = GGraph.Graph([self.node1])
def test001_init_empty(self):
# Test the constructor.
graph = GGraph.Graph()
- self.assertEquals(graph.head, None)
+ self.assertEquals(graph.heads, None)
def test002_init(self):
# Test the constructor.
- self.assert_(self.graph1.head == self.node1)
+ self.assert_(self.graph1.heads == [self.node1])
self.assertEquals(self.graph1.nodes.keys(), [18231])
self.assertEquals(self.graph1.nodes[18231], self.node1)
- def test003_init_bad_head(self):
- # Test the constructor when passed a bad type for the head parameter.
+ def test003_init_bad_heads(self):
+ # Test the constructor when passed a bad type for the heads parameter.
self.assertRaises(TypeError, GGraph.Graph, 3)
def test004_has_node_true(self):
@@ -205,20 +205,28 @@ class TestGraphMethods(unittest.TestCase):
# Test the addNode() method.
self.graph1.addNode("Leonhard Euler", "Universitaet Basel", 1726, 38586, [])
self.assertEquals([38586, 18231], self.graph1.getNodeList())
+ self.assertEquals(self.graph1.heads, [self.node1])
- def test010_add_node_head(self):
- # Test the addNode() method when no head exists.
+ def test010_add_second_node_head(self):
+ # Test the addNode() method when adding a second node and
+ # marking it as a head node.
+ self.graph1.addNode("Leonhard Euler", "Universitaet Basel", 1726, 38586, [], True)
+ self.assertEquals([38586, 18231], self.graph1.getNodeList())
+ self.assertEquals(self.graph1.heads, [self.node1, self.graph1.getNode(38586)])
+
+ def test011_add_node_head(self):
+ # Test the addNode() method when no heads exist.
graph = GGraph.Graph()
- self.assertEquals(graph.head, None)
+ self.assertEquals(graph.heads, None)
graph.addNode("Leonhard Euler", "Universitaet Basel", 1726, 38586, [])
- self.assertEquals(graph.head, graph.getNode(38586))
+ self.assertEquals(graph.heads, [graph.getNode(38586)])
- def test011_add_node_already_present(self):
+ def test012_add_node_already_present(self):
self.graph1.addNode("Leonhard Euler", "Universitaet Basel", 1726, 38586, [])
self.assertEquals([38586, 18231], self.graph1.getNodeList())
self.assertRaises(GGraph.DuplicateNodeError, self.graph1.addNode, "Leonhard Euler", "Universitaet Basel", 1726, 38586, [])
- def test012_generate_dot_file(self):
+ def test013_generate_dot_file(self):
# Test the generateDotFile() method.
dotfileexpt = """digraph genealogy {
graph [charset="utf-8"];
@@ -232,7 +240,7 @@ class TestGraphMethods(unittest.TestCase):
dotfile = self.graph1.generateDotFile()
self.assertEquals(dotfile, dotfileexpt)
- def test013_generate_dot_file(self):
+ def test014_generate_dot_file(self):
# Test the generateDotFile() method.
graph = GGraph.Graph()
graph.addNode("Carl Friedrich Gauss", "Universitaet Helmstedt", 1799, 18231, [18230])
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/geneagrapher.git
More information about the debian-science-commits
mailing list