Rev 397 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#!/usr/bin/env python__author__ = "Ira W. Snyder (devel@irasnyder.com)"__copyright__ = "Copyright (c) 2006 Ira W. Snyder (devel@irasnyder.com)"__license__ = "GNU GPL v2 (or, at your option, any later version)"from PyCompat import * # fixes for school computersclass Vertex (object):def __init__ (self, label='', value=0, shape='circle', raw_obj=None):self.label = labelself.value = valueself.shape = shapeself.raw_obj = raw_objclass Edge (object):def __init__ (self, color='black', label=''):self.color = colorself.label = labelclass Graph:"""Class that will handle weighted, undirected graphs. It can havearbitrary data stored at each vertex. Note that the simple wayof creating a graph does not allow you to assign data, you mustdo it manually."""def __init__ (self, vertices=[], edges=[]):"""Constructor"""self.vertices = {}self.edges = {}for v in vertices:self.add_vertex (v)for e in edges:(v1, v2) = eself.add_edge (v1, v2)def __get_key (self, v1, v2):"""Create a key for this set of nodes"""key = [v1, v2]key.sort ()return tuple (key)def add_vertex (self, label, data=0, raw_obj=None):"""Add a vertex to the graph"""if self.has_vertex (label):raise ValueError# Create vertex and set the valueself.vertices[label] = Vertex(label, data, raw_obj=raw_obj)def add_edge (self, v1, v2, color='black', label=''):"""Add an edge from v1 to v2 (undirected)"""key = self.__get_key (v1, v2)if self.has_vertex (v1) and self.has_vertex (v2):self.edges[key] = Edge (color, label)else:raise ValueErrordef has_edge (self, v1, v2):"""Check if an edge exists in this graph"""key = self.__get_key (v1, v2)if key in self.edges.keys():return Truereturn Falsedef has_vertex (self, label):"""Check if a vertex exists in this graph"""return label in self.vertices.keys ()def get_children (self, v):"""Get a list of all children of v. In this graph, thatmeans any adjacent nodes."""children = set()# Check that the vertex existsif not self.has_vertex (v):raise ValueErrorfor k in self.edges.keys ():if v in k:for i in k:if i != v:children.add (i)return list(children)def set_vertex_value (self, v, value):"""Store some data at a vertex"""if not self.has_vertex (v):raise ValueErrorself.vertices[v].value = valuedef get_vertex_value (self, v):"""Get the data at a vertex"""if not self.has_vertex (v):raise ValueErrorreturn self.vertices[v].valuedef set_vertex_shape (self, v, shape):if not self.has_vertex (v):raise ValueErrorself.vertices[v].shape = shapedef get_vertex_shape (self, v):if not self.has_vertex (v):raise ValueErrorreturn self.vertices[v].shapedef set_edge_color (self, v1, v2, color):if not self.has_edge (v1, v2):raise ValueErrorkey = self.__get_key (v1, v2)self.edges[key].color = colordef get_edge_color (self, v1, v2):if not self.has_edge (v1, v2):raise ValueErrorkey = self.__get_key (v1, v2)return self.edges[key].colordef get_edge_label (self, v1, v2):if not self.has_edge (v1, v2):raise ValueErrorkey = self.__get_key (v1, v2)return self.edges[key].labeldef set_edge_label (self, v1, v2, label):if not self.has_edge (v1, v2):raise ValueErrorkey = self.__get_key (v1, v2)self.edges[key].label = label################################################################################### Tests are below this point ###################################################################################def run_test (graph, vertex, should_be, suite, test_num):"""Run a test, check the result. Print the status."""c = graph.get_children (vertex)c.sort ()if (c != should_be):print 'Failed test #%d in suite: %s' % (test_num, suite)def run_tests_1 ():"""Run the first set of tests."""SUITE = 'Tests 1'vertices = range (11)edges = ( [0, 1], [0, 9], [0, 8], [8, 10], [8, 7], [9, 6], [9, 5],[6, 7], [1, 4], [1, 3], [1, 2], [2, 0] )g = Graph (vertices, edges)run_test (g, 0, [1, 2, 8, 9], SUITE, 0)run_test (g, 1, [0, 2, 3, 4], SUITE, 1)run_test (g, 2, [0, 1], SUITE, 2)run_test (g, 3, [1], SUITE, 3)run_test (g, 4, [1], SUITE, 4)run_test (g, 5, [9], SUITE ,5)run_test (g, 6, [7, 9], SUITE, 6)run_test (g, 7, [6, 8], SUITE, 7)run_test (g, 8, [0, 7, 10], SUITE, 8)run_test (g, 9, [0, 5, 6], SUITE, 9)run_test (g, 10, [8], SUITE, 10)def run_tests_2 ():"""Run the second set of tests."""SUITE = 'Tests 2'vertices = ['a', 'b', 'c', 'd', 'e']edges = ( ['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'a'], ['b', 'c'],['b', 'e'], ['e', 'b'], ['e', 'c'], ['e', 'd'],['d', 'a'], ['d', 'c'], ['d', 'e'], ['c', 'a'],['c', 'b'], ['c', 'd'], ['c', 'e'] )g = Graph (vertices, edges)run_test (g, 'a', ['b', 'c', 'd'], SUITE, 0)run_test (g, 'b', ['a', 'c', 'e'], SUITE, 1)run_test (g, 'c', ['a', 'b', 'd', 'e'], SUITE, 2)run_test (g, 'd', ['a', 'c', 'e'], SUITE, 3)run_test (g, 'e', ['b', 'c', 'd'], SUITE, 4)def main ():"""Main function."""print 'Running self tests. Any failures will be reported below'run_tests_1 ()run_tests_2 ()if __name__ == '__main__':main ()