annotate HashTree.py @ 111:7f651bf040c4

more styles for sliders.
author casties
date Tue, 28 May 2013 10:45:56 +0200
parents 246d87d33f25
children 1acfcaaa5ca3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
1 import logging
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
2
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
3 class HashTreeNode:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
4 """Node of a HashTree.
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
5 Has a value and keeps children in a dict indexed by key."""
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
6 key = None
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
7 value = None
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
8 children = None
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
9
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
10 def __init__(self, key=None, value=None, children=None):
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
11 """create node"""
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
12 self.key = key
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
13 self.value = value
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
14 self.children = children
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
15
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
16
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
17 def getNode(self, key):
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
18 """return node under key"""
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
19 if self.children is None:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
20 return None
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
21 else:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
22 return self.children.get(key, None)
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
23
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
24
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
25 def addNode(self, node):
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
26 """add child node using key from node"""
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
27 if self.children is None:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
28 self.children = {node.key : node}
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
29 else:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
30 self.children[node.key] = node
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
31
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
32
105
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
33 def getSubtreeAsList(self, depthFirst=True):
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
34 """Return the subtree as flattened list sorted by key."""
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
35 if self.children is None:
105
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
36 if depthFirst:
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
37 if self.value is None:
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
38 return []
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
39 else:
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
40 return [self.value]
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
41
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
42 else:
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
43 # breadth first - value has already been added
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
44 return []
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
45
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
46 else:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
47 if self.value is None:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
48 sub = []
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
49 else:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
50 sub = [self.value]
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
51
105
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
52 if depthFirst:
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
53 # depth first
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
54 for k in sorted(self.children.keys()):
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
55 sub.extend(self.children.get(k).getSubtreeAsList())
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
56
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
57 else:
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
58 # breadth first
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
59 clist = sorted(self.children.values(), key=lambda x:x.key)
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
60 # add all children
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
61 sub.extend([c.value for c in clist if c.value is not None])
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
62 # then their children
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
63 for c in clist:
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
64 sub.extend(c.getSubtreeAsList(depthFirst=True))
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
65
105
246d87d33f25 CLOSED - # 79: sortierung der liste der projekte pro abteilung
casties
parents: 97
diff changeset
66 return sub
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
67
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
68
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
69 def getSubtreeAsText(self):
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
70 """prints whole tree as text"""
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
71 if self.children is None:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
72 return "(%s:%s)"%(self.key, self.value)
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
73 else:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
74 sub = "(%s:%s):["%(self.key, self.value)
43
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
75 for k in sorted(self.children.keys()):
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
76 sub += self.children.get(k).getSubtreeAsText()
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
77 sub += ", "
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
78
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
79 return sub + "] "
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
80
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
81
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
82
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
83
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
84 class HashTree:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
85 """Tree using dictionaries"""
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
86
43
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
87 # root HashTreeNode
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
88 root = None
43
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
89 # separator by which key strings are split into parts
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
90 keySeparator = '.'
43
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
91 # function applied to key parts
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
92 keyFn = None
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
93
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
94 def __init__(self, keySeparator='.', keyFn=None):
52
1ed79b33200c more work on projects and cleanup.
casties
parents: 43
diff changeset
95 """Create a HashTree.
43
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
96
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
97 @param keySeparator string by which key strings are split into parts
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
98 @param keyFn function applied to key parts (e.g. int if key parts are numbers)
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
99 """
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
100 self.root = HashTreeNode()
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
101 self.keySeparator = keySeparator
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
102 self.keyFn = keyFn
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
103
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
104
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
105 def _splitkey(self, key):
52
1ed79b33200c more work on projects and cleanup.
casties
parents: 43
diff changeset
106 """Return a list of key parts"""
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
107 if isinstance(key, basestring):
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
108 # its a string - split
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
109 keys = key.split(self.keySeparator)
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
110 if self.keyFn is not None:
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
111 keys = [self.keyFn(k) for k in keys]
43
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
112
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
113 elif isinstance(key, list):
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
114 # its a list - keep
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
115 keys = key
43
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
116
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
117 else:
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
118 # not a list - wrap in list
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
119 keys = [key]
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
120
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
121 return keys
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
122
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
123
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
124 def getNode(self, key):
52
1ed79b33200c more work on projects and cleanup.
casties
parents: 43
diff changeset
125 """Return node under key from the tree.
1ed79b33200c more work on projects and cleanup.
casties
parents: 43
diff changeset
126
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
127 key can be sequence of key string or a single string using keySeparator.
30
aa4ab114c28a more work on projects.
casties
parents: 29
diff changeset
128 If key is None, returns root node.
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
129 """
30
aa4ab114c28a more work on projects.
casties
parents: 29
diff changeset
130 if key is None:
aa4ab114c28a more work on projects.
casties
parents: 29
diff changeset
131 return self.root
aa4ab114c28a more work on projects.
casties
parents: 29
diff changeset
132
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
133 keys = self._splitkey(key)
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
134
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
135 node = self.root
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
136 for k in keys:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
137 node = node.getNode(k)
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
138 if node is None:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
139 return None
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
140
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
141 return node
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
142
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
143
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
144 def get(self, key):
52
1ed79b33200c more work on projects and cleanup.
casties
parents: 43
diff changeset
145 """Return value under key from the tree.
1ed79b33200c more work on projects and cleanup.
casties
parents: 43
diff changeset
146
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
147 key can be sequence of key string or a single string using keySeparator.
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
148 """
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
149 node = self.getNode(key)
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
150 if node is None:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
151 return None
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
152
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
153 return node.value
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
154
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
155
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
156 def add(self, key, value):
52
1ed79b33200c more work on projects and cleanup.
casties
parents: 43
diff changeset
157 """Add value under key to the tree.
1ed79b33200c more work on projects and cleanup.
casties
parents: 43
diff changeset
158
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
159 key can be sequence of key string or a single string using keySeparator.
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
160 """
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
161 keys = self._splitkey(key)
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
162 node = self.root
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
163 for k in keys:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
164 nextnode = node.getNode(k)
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
165 if nextnode is None:
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
166 nextnode = HashTreeNode(key=k)
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
167 node.addNode(nextnode)
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
168
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
169 node = nextnode
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
170
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
171 node.value = value
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
172
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
173
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
174 def getChildrenOf(self, key):
52
1ed79b33200c more work on projects and cleanup.
casties
parents: 43
diff changeset
175 """Return the list of child (values) of the node under key."""
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
176 node = self.getNode(key)
97
7b96a85552aa fix bugs in project editing.
casties
parents: 52
diff changeset
177 if getattr(node, 'children', None) is None:
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
178 return []
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
179 else:
43
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
180 # sort children by key
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
181 childlist = sorted(node.children.items(), key=lambda x:x[0])
196db636a8fd fixed sorting of project lists.
casties
parents: 39
diff changeset
182 # and return the values
97
7b96a85552aa fix bugs in project editing.
casties
parents: 52
diff changeset
183 return [n.value for k, n in childlist if n.value is not None]
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
184
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
185
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
186 def getAncestorsOf(self, key):
52
1ed79b33200c more work on projects and cleanup.
casties
parents: 43
diff changeset
187 """Return the list of ancestor (values) of the node under key.
1ed79b33200c more work on projects and cleanup.
casties
parents: 43
diff changeset
188
1ed79b33200c more work on projects and cleanup.
casties
parents: 43
diff changeset
189 Order: root element first."""
39
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
190 keys = self._splitkey(key)
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
191 node = self.root
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
192 ancestors = []
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
193 for k in keys:
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
194 if node.value is not None:
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
195 ancestors.append(node.value)
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
196
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
197 node = node.getNode(k)
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
198 if node is None:
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
199 return ancestors
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
200
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
201 return ancestors
bbad6a092861 more work on projects.
casties
parents: 34
diff changeset
202
27
9a75eb1b31b3 more work on projects.
casties
parents:
diff changeset
203