Subversion Repositories programming

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
376 ira 1
#!/usr/bin/env python
2
 
3
__author__    = "Ira W. Snyder (devel@irasnyder.com)"
4
__copyright__ = "Copyright (c) 2006 Ira W. Snyder (devel@irasnyder.com)"
5
__license__   = "GNU GPL v2 (or, at your option, any later version)"
6
 
395 ira 7
# Fix for the lame version of python on the school's computers (v2.1)
8
try:
9
	(True, False)
10
except NameError:
11
	(True, False) = (1, 0)
12
 
13
class Vertex:
14
	def __init__ (self, label='', value=0, shape='circle', raw_obj=None):
391 ira 15
		self.label = label
16
		self.value = value
17
		self.shape = shape
395 ira 18
		self.raw_obj = raw_obj
391 ira 19
 
395 ira 20
class Edge:
379 ira 21
	def __init__ (self, color='black', label=''):
22
		self.color = color
23
		self.label = label
24
 
376 ira 25
class Graph:
26
	"""Class that will handle weighted, undirected graphs. It can have
27
	   arbitrary data stored at each vertex. Note that the simple way
28
	   of creating a graph does not allow you to assign data, you must
29
	   do it manually."""
30
 
31
	def __init__ (self, vertices=[], edges=[]):
32
		"""Constructor"""
33
		self.vertices = {}
34
		self.edges = {}
35
 
36
		for v in vertices:
37
			self.add_vertex (v)
38
 
39
		for e in edges:
40
			(v1, v2) = e
41
			self.add_edge (v1, v2)
42
 
43
	def __get_key (self, v1, v2):
44
		"""Create a key for this set of nodes"""
45
		key = [v1, v2]
46
		key.sort ()
47
		return tuple (key)
48
 
395 ira 49
	def add_vertex (self, label, data=0, raw_obj=None):
376 ira 50
		"""Add a vertex to the graph"""
51
		if self.has_vertex (label):
52
			raise ValueError
53
 
54
		# Create vertex and set the value
395 ira 55
		self.vertices[label] = Vertex(label, data, raw_obj=raw_obj)
376 ira 56
 
379 ira 57
	def add_edge (self, v1, v2, color='black', label=''):
376 ira 58
		"""Add an edge from v1 to v2 (undirected)"""
59
 
60
		key = self.__get_key (v1, v2)
61
 
62
		if self.has_vertex (v1) and self.has_vertex (v2):
379 ira 63
			self.edges[key] = Edge (color, label)
376 ira 64
		else:
65
			raise ValueError
66
 
67
	def has_edge (self, v1, v2):
68
		"""Check if an edge exists in this graph"""
69
 
70
		key = self.__get_key (v1, v2)
71
 
72
		if key in self.edges.keys():
73
			return True
74
 
75
		return False
76
 
77
	def has_vertex (self, label):
78
		"""Check if a vertex exists in this graph"""
79
		return label in self.vertices.keys ()
80
 
81
	def get_children (self, v):
82
		"""Get a list of all children of v. In this graph, that
83
		   means any adjacent nodes."""
84
		children = set()
85
 
86
		# Check that the vertex exists
87
		if not self.has_vertex (v):
88
			raise ValueError
89
 
90
		for k in self.edges.keys ():
91
			if v in k:
92
				for i in k:
93
					if i != v:
94
						children.add (i)
95
 
96
		return list(children)
97
 
391 ira 98
	def set_vertex_value (self, v, value):
376 ira 99
		"""Store some data at a vertex"""
392 ira 100
		if not self.has_vertex (v):
101
			raise ValueError
376 ira 102
 
392 ira 103
		self.vertices[v].value = value
104
 
379 ira 105
	def get_vertex_value (self, v):
376 ira 106
		"""Get the data at a vertex"""
392 ira 107
		if not self.has_vertex (v):
108
			raise ValueError
109
 
391 ira 110
		return self.vertices[v].value
376 ira 111
 
391 ira 112
	def set_vertex_shape (self, v, shape):
392 ira 113
		if not self.has_vertex (v):
114
			raise ValueError
115
 
391 ira 116
		self.vertices[v].shape = shape
117
 
118
	def get_vertex_shape (self, v):
392 ira 119
		if not self.has_vertex (v):
120
			raise ValueError
121
 
391 ira 122
		return self.vertices[v].shape
123
 
379 ira 124
	def set_edge_color (self, v1, v2, color):
125
		if not self.has_edge (v1, v2):
126
			raise ValueError
376 ira 127
 
379 ira 128
		key = self.__get_key (v1, v2)
129
		self.edges[key].color = color
130
 
131
	def get_edge_color (self, v1, v2):
132
		if not self.has_edge (v1, v2):
133
			raise ValueError
134
 
135
		key = self.__get_key (v1, v2)
136
		return self.edges[key].color
137
 
138
	def get_edge_label (self, v1, v2):
139
		if not self.has_edge (v1, v2):
140
			raise ValueError
141
 
142
		key = self.__get_key (v1, v2)
143
		return self.edges[key].label
144
 
145
	def set_edge_label (self, v1, v2, label):
146
		if not self.has_edge (v1, v2):
147
			raise ValueError
148
 
149
		key = self.__get_key (v1, v2)
150
		self.edges[key].label = label
151
 
152
 
376 ira 153
################################################################################
154
###                      Tests are below this point                          ###
155
################################################################################
156
 
157
 
158
def run_test (graph, vertex, should_be, suite, test_num):
159
	"""Run a test, check the result. Print the status."""
160
	c = graph.get_children (vertex)
161
	c.sort ()
162
 
163
	if (c != should_be):
164
		print 'Failed test #%d in suite: %s' % (test_num, suite)
165
 
166
def run_tests_1 ():
167
	"""Run the first set of tests."""
168
	SUITE = 'Tests 1'
169
 
170
	vertices = range (11)
171
	edges = ( [0, 1], [0, 9], [0, 8], [8, 10], [8, 7], [9, 6], [9, 5],
172
			[6, 7], [1, 4], [1, 3], [1, 2], [2, 0] )
173
 
174
	g = Graph (vertices, edges)
175
 
176
	run_test (g, 0, [1, 2, 8, 9], SUITE, 0)
177
	run_test (g, 1, [0, 2, 3, 4], SUITE, 1)
178
	run_test (g, 2, [0, 1], SUITE, 2)
179
	run_test (g, 3, [1], SUITE, 3)
180
	run_test (g, 4, [1], SUITE, 4)
181
	run_test (g, 5, [9], SUITE ,5)
182
	run_test (g, 6, [7, 9], SUITE, 6)
183
	run_test (g, 7, [6, 8], SUITE, 7)
184
	run_test (g, 8, [0, 7, 10], SUITE, 8)
185
	run_test (g, 9, [0, 5, 6], SUITE, 9)
186
	run_test (g, 10, [8], SUITE, 10)
187
 
188
def run_tests_2 ():
189
	"""Run the second set of tests."""
190
	SUITE = 'Tests 2'
191
 
192
	vertices = ['a', 'b', 'c', 'd', 'e']
193
	edges = ( ['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'a'], ['b', 'c'],
194
			['b', 'e'], ['e', 'b'], ['e', 'c'], ['e', 'd'],
195
			['d', 'a'], ['d', 'c'], ['d', 'e'], ['c', 'a'],
196
			['c', 'b'], ['c', 'd'], ['c', 'e'] )
197
 
198
	g = Graph (vertices, edges)
199
 
200
	run_test (g, 'a', ['b', 'c', 'd'], SUITE, 0)
201
	run_test (g, 'b', ['a', 'c', 'e'], SUITE, 1)
202
	run_test (g, 'c', ['a', 'b', 'd', 'e'], SUITE, 2)
203
	run_test (g, 'd', ['a', 'c', 'e'], SUITE, 3)
204
	run_test (g, 'e', ['b', 'c', 'd'], SUITE, 4)
205
 
206
def main ():
207
	"""Main function."""
208
 
209
	print 'Running self tests. Any failures will be reported below'
210
 
211
	run_tests_1 ()
212
	run_tests_2 ()
213
 
214
 
215
if __name__ == '__main__':
216
	main ()
217