diff HashTree.py @ 27:9a75eb1b31b3

more work on projects.
author casties
date Mon, 22 Apr 2013 21:01:00 +0200
parents
children 224023958871
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HashTree.py	Mon Apr 22 21:01:00 2013 +0200
@@ -0,0 +1,147 @@
+import logging
+    
+class HashTreeNode:
+    """Node of a HashTree.
+    Has a value and keeps children in a dict indexed by key."""
+    key = None
+    value = None
+    children = None
+    
+    def __init__(self, key=None, value=None, children=None):
+        """create node"""
+        self.key = key
+        self.value = value
+        self.children = children
+
+
+    def getNode(self, key):
+        """return node under key"""
+        if self.children is None:
+            return None
+        else:
+            return self.children.get(key, None)
+
+
+    def addNode(self, node):
+        """add child node using key from node"""
+        if self.children is None:
+            self.children = {node.key : node}
+        else:
+            self.children[node.key] = node
+            
+
+    def getSubtreeList(self):
+        """returns the subtree as list sorted by key (depth first)"""
+        if self.children is None:
+            if self.value is None:
+                return []
+            else:
+                return [self.value]
+            
+        else:
+            if self.value is None:
+                sub = []
+            else:
+                sub = [self.value]
+                
+            keys = self.children.keys()
+            keys.sort()
+            for k in keys:
+                #logging.debug("getSubtreeList: k=%s sub=%s"%(k,sub))
+                sub.extend(self.children.get(k).getSubtreeList())
+                
+            return sub
+
+
+    def getSubtreeAsText(self):
+        """prints whole tree as text"""
+        if self.children is None:
+            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:
+                sub += self.children.get(k).getSubtreeAsText()
+                sub += ", "
+                
+            return sub + "] "
+
+
+class HashTree:
+    """Tree using dictionaries"""
+    
+    root = None
+    keySeparator = '.'
+    keyFn = None
+    
+    def __init__(self, keySeparator='.', keyFn=None):
+        """creates a HashTree"""
+        self.root = HashTreeNode()
+        self.keySeparator = keySeparator
+        self.keyFn = keyFn
+    
+
+    def getNode(self, key):
+        """gets node under key from the tree.
+        key can be sequence of key string or a single string using keySeparator.
+        """
+        #logging.debug("getNode(key=%s)"%(key))
+        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]
+            
+        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
+            
+        return node
+
+
+    def get(self, key):
+        """gets value under key from the tree.
+        key can be sequence of key string or a single string using keySeparator.
+        """
+        node = self.getNode(key)
+        if node is None:
+            return None
+        
+        return node.value
+
+     
+    def add(self, key, value):
+        """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]
+            
+        node = self.root
+        for k in keys:
+            nextnode = node.getNode(k)
+            if nextnode is None:
+                nextnode = HashTreeNode(key=k)
+                node.addNode(nextnode)
+            
+            node = nextnode
+            
+        node.value = value
+        
+    
+