1
2
3
4 """ Implements a class used to represent N-ary trees
5
6 """
7 import cPickle
8
9
10
11
12
14 """ This is your bog standard Tree class.
15
16 the root of the tree is just a TreeNode like all other members.
17 """
18 - def __init__(self,parent,name,label=None,data=None,level=0,isTerminal=0):
19 """ constructor
20
21 **Arguments**
22
23 - parent: the parent of this node in the tree
24
25 - name: the name of the node
26
27 - label: the node's label (should be an integer)
28
29 - data: an optional data field
30
31 - level: an integer indicating the level of this node in the hierarchy
32 (used for printing)
33
34 - isTerminal: flags a node as being terminal. This is useful for those
35 times when it's useful to know such things.
36
37 """
38 self.children = []
39 self.parent = parent
40 self.name = name
41 self.data = data
42 self.terminalNode = isTerminal
43 self.label = label
44 self.level = level
45 self.examples = []
47 """ Set the names of each node in the tree from a list of variable names.
48
49 **Arguments**
50
51 - varNames: a list of names to be assigned
52
53 **Notes**
54
55 1) this works its magic by recursively traversing all children
56
57 2) The assumption is made here that the varNames list can be indexed
58 by the labels of tree nodes
59
60 """
61 if self.GetTerminal():
62 return
63 else:
64 for child in self.GetChildren():
65 child.NameTree(varNames)
66 self.SetName(varNames[self.GetLabel()])
67 NameModel=NameTree
68
70 """ Adds a TreeNode to the local list of children
71
72 **Arguments**
73
74 - node: the node to be added
75
76 **Note**
77
78 the level of the node (used in printing) is set as well
79
80 """
81 node.SetLevel(self.level + 1)
82 self.children.append(node)
83
84 - def AddChild(self,name,label=None,data=None,isTerminal=0):
85 """ Creates a new TreeNode and adds a child to the tree
86
87 **Arguments**
88
89 - name: the name of the new node
90
91 - label: the label of the new node (should be an integer)
92
93 - data: the data to be stored in the new node
94
95 - isTerminal: a toggle to indicate whether or not the new node is
96 a terminal (leaf) node.
97
98 **Returns*
99
100 the _TreeNode_ which is constructed
101
102 """
103 child = TreeNode(self,name,label,data,level=self.level+1,isTerminal=isTerminal)
104 self.children.append(child)
105 return child
106
108 """ Removes the child node
109
110 **Arguments**
111
112 - child: a TreeNode
113
114 """
115 self.children.remove(child)
116
118 """ Replaces a given child with a new one
119
120 **Arguments**
121
122 - index: an integer
123
124 - child: a TreeNode
125
126 """
127 self.children[index] = newChild
128
130 """ Returns a python list of the children of this node
131
132 """
133 return self.children
134
136 """ Destroys this node and all of its children
137
138 """
139 for child in self.children:
140 child.Destroy()
141 self.children = None
142
143 self.parent = None
144
146 """ Returns the name of this node
147
148 """
149 return self.name
151 """ Sets the name of this node
152
153 """
154 self.name = name
155
157 """ Returns the data stored at this node
158
159 """
160 return self.data
162 """ Sets the data stored at this node
163
164 """
165 self.data=data
166
168 """ Returns whether or not this node is terminal
169
170 """
171 return self.terminalNode
173 """ Sets whether or not this node is terminal
174
175 """
176 self.terminalNode = isTerminal
177
179 """ Returns the label of this node
180
181 """
182 return self.label
184 """ Sets the label of this node (should be an integer)
185
186 """
187 self.label=label
188
190 """ Returns the level of this node
191
192 """
193 return self.level
195 """ Sets the level of this node
196
197 """
198 self.level=level
199
201 """ Returns the parent of this node
202
203 """
204 return self.parent
206 """ Sets the parent of this node
207
208 """
209 self.parent = parent
210
211
212 - def Print(self,level=0,showData=0):
213 """ Pretty prints the tree
214
215 **Arguments**
216
217 - level: sets the number of spaces to be added at the beginning of the output
218
219 - showData: if this is nonzero, the node's _data_ value will be printed as well
220
221 **Note**
222
223 this works recursively
224
225 """
226 if showData:
227 print '%s%s: %s'%(' '*level,self.name,str(self.data))
228 else:
229 print '%s%s'%(' '*level,self.name)
230
231 for child in self.children:
232 child.Print(level+1,showData=showData)
233
234 - def Pickle(self,fileName='foo.pkl'):
235 """ Pickles the tree and writes it to disk
236
237 """
238 pFile = open(fileName,'w+')
239 cPickle.dump(self,pFile)
240
242 """ returns a string representation of the tree
243
244 **Note**
245
246 this works recursively
247
248 """
249 here = '%s%s\n'%(' '*self.level,self.name)
250 for child in self.children:
251 here = here + str(child)
252 return here
253
255 """ allows tree1 == tree2
256
257 **Note**
258
259 This works recursively
260
261
262 """
263 try:
264 nChildren = len(self.children)
265 if cmp(type(self),type(other)):
266 return cmp(type(self),type(other))
267 elif cmp(self.name,other.name):
268 return cmp(self.name,other.name)
269 elif cmp(self.label,other.label):
270 return cmp(self.label,other.label)
271 if nChildren < len(other.children):
272 return -1
273 elif nChildren > len(other.children):
274 return 1
275 else:
276 for i in xrange(nChildren):
277 res = cmp(self.children[i],other.children[i])
278 if res != 0:
279 return res
280 except AttributeError:
281 return -1
282
283 return 0
284
285
286 if __name__ == '__main__':
287 tree = TreeNode(None,'root')
288 for i in xrange(3):
289 child = tree.AddChild('child %d'%i)
290 print tree
291 tree.GetChildren()[1].AddChild('grandchild')
292 tree.GetChildren()[1].AddChild('grandchild2')
293 tree.GetChildren()[1].AddChild('grandchild3')
294 print tree
295 tree.Pickle('save.pkl')
296 print 'prune'
297 tree.PruneChild(tree.GetChildren()[1])
298 print 'done'
299 print tree
300
301 import copy
302 tree2 = copy.deepcopy(tree)
303 print 'tree==tree2', tree==tree2
304
305 foo = [tree]
306 print 'tree in [tree]:', tree in foo,foo.index(tree)
307 print 'tree2 in [tree]:', tree2 in foo, foo.index(tree2)
308
309 tree2.GetChildren()[1].AddChild('grandchild4')
310 print 'tree==tree2', tree==tree2
311 tree.Destroy()
312