diff HashTree.py @ 48:f59bdd5f4890

Merge with 5c6ad316e1ceef48e323907ab81dd50e7ef743b2
author dwinter
date Mon, 29 Apr 2013 16:02:24 +0200
parents 196db636a8fd
children 1ed79b33200c
line wrap: on
line diff
--- a/HashTree.py	Mon Apr 29 16:01:24 2013 +0200
+++ b/HashTree.py	Mon Apr 29 16:02:24 2013 +0200
@@ -44,10 +44,7 @@
             else:
                 sub = [self.value]
                 
-            keys = self.children.keys()
-            keys.sort()
-            for k in keys:
-                #logging.debug("getSubtreeList: k=%s sub=%s"%(k,sub))
+            for k in sorted(self.children.keys()):
                 sub.extend(self.children.get(k).getSubtreeAsList())
                 
             return sub
@@ -59,29 +56,55 @@
             return "(%s:%s)"%(self.key, self.value)
         else:
             sub = "(%s:%s):["%(self.key, self.value)
-            keys = self.children.keys()
-            keys.sort()
-            for k in keys:
+            for k in sorted(self.children.keys()):
                 sub += self.children.get(k).getSubtreeAsText()
                 sub += ", "
                 
             return sub + "] "
 
+    
+
 
 class HashTree:
     """Tree using dictionaries"""
     
+    # root HashTreeNode
     root = None
+    # separator by which key strings are split into parts
     keySeparator = '.'
+    # function applied to key parts
     keyFn = None
     
     def __init__(self, keySeparator='.', keyFn=None):
-        """creates a HashTree"""
+        """creates a HashTree.
+        
+        @param keySeparator string by which key strings are split into parts
+        @param keyFn function applied to key parts (e.g. int if key parts are numbers)
+        """
         self.root = HashTreeNode()
         self.keySeparator = keySeparator
         self.keyFn = keyFn
     
 
+    def _splitkey(self, key):
+        """returns a list of key parts"""
+        if isinstance(key, basestring):
+            # its a string - split
+            keys = key.split(self.keySeparator)
+            if self.keyFn is not None:
+                keys = [self.keyFn(k) for k in keys]
+                
+        elif isinstance(key, list):
+            # its a list - keep
+            keys = key
+            
+        else:
+            # not a list - wrap in list
+            keys = [key]
+            
+        return keys
+
+
     def getNode(self, key):
         """gets node under key from the tree.
         key can be sequence of key string or a single string using keySeparator.
@@ -90,22 +113,11 @@
         if key is None:
             return self.root
 
-        if isinstance(key, basestring):
-            keys = key.split(self.keySeparator)
-            if self.keyFn is not None:
-                keys = [self.keyFn(k) for k in keys]
-                
-        elif isinstance(key, list):
-            keys = key
-            
-        else:
-            keys = [key]
+        keys = self._splitkey(key)
             
         node = self.root
         for k in keys:
-            #logging.debug("getNode node=%s k=%s"%(node, repr(k)))
             node = node.getNode(k)
-            #logging.debug("getNode got:%s"%(node))
             if node is None:
                 return None
             
@@ -127,16 +139,7 @@
         """adds value under key to the tree.
         key can be sequence of key string or a single string using keySeparator.
         """
-        #logging.debug("add(key=%s, value=%s)"%(repr(key), value))
-        if isinstance(key, basestring):
-            keys = key.split(self.keySeparator)
-            if self.keyFn is not None:
-                keys = [self.keyFn(k) for k in keys]
-        elif isinstance(key, list):
-            keys = key
-        else:
-            keys = [key]
-            
+        keys = self._splitkey(key)
         node = self.root
         for k in keys:
             nextnode = node.getNode(k)
@@ -147,6 +150,34 @@
             node = nextnode
             
         node.value = value
+
         
-    
+    def getChildrenOf(self, key):
+        """returns the list of child (values) of the node under key."""
+        node = self.getNode(key)
+        if node.children is None:
+            return []
+        else:
+            # sort children by key
+            childlist = sorted(node.children.items(), key=lambda x:x[0])
+            # and return the values
+            return [n.value for (k, n) in childlist if n.value is not None]
+
+
+    def getAncestorsOf(self, key):
+        """returns the list of ancestor (values) of the node under key.
+        ordered from root up."""
+        keys = self._splitkey(key)
+        node = self.root
+        ancestors = []
+        for k in keys:
+            if node.value is not None:
+                ancestors.append(node.value)
+                
+            node = node.getNode(k)
+            if node is None:
+                return ancestors
+            
+        return ancestors
+