def union(self, other, intersection=None): """return the union of two dicts >>> from vector_dict.VectorDict import convert_tree, VectorDict,Element,Path >>> b = VectorDict( int, { 'a' : VectorDict( int, dict( b = 1, c = 1 ) ) } ) >>> a = VectorDict( int, { 'a' : VectorDict( int, dict( b = 1, d = 2, c=1 ) ), 'e' : 1 } ) >>> b.union(a) defaultdict(<type 'int'>, {'a': defaultdict(<type 'int'>, {'c': 1, 'b': 1, 'd': 2}), 'e': 1}) >>> a = VectorDict( int, { 'a' : VectorDict( int, dict( b = 1, d = 2, c=3 ) ) } ) >>> b.union(a) Traceback (most recent call last): File "<input>", line 1, in <module> File "vector_dict/VectorDict.py", line 669, in union return self + other - self.intersection(other) File "vector_dict/VectorDict.py", line 658, in intersection new_dict[k] = (self[k]).intersection( other[k] ) File "vector_dict/VectorDict.py", line 663, in intersection other[k] Exception: ('CollisionError', '1 != 3') """ ###Dont work #return - self.intersection(other) + self + other ## take intersection union = intersection or self.intersection(other) ## add self not in intersection ### easy case common_keys = set( union.keys() ) orthogonal_keys_self = set(self).symmetric_difference( set( union.keys() )) orthogonal_keys_other = set(other).symmetric_difference( set( union.keys() ) ) for k in orthogonal_keys_self: if not is_leaf(self[k]): union[k] += self[k] else: raise( Exception("Wtf?") ) for k in orthogonal_keys_other: if not is_leaf(other[k]): union[k] += other[k] for k in common_keys: if not self[k] == other[k]: if isinstance(union[k], VectorDict) : union[k] = self[k].union(other[k], intersection and intersection.get(k) or VectorDict() ) else: union[k] = self[k].union(other[k]) return union
def test_find1(self): self.assertEqual( [ e for e in self.cplx.find( lambda p, v: ( not is_leaf(v) and v.match_tree( dict( c= has_type(float) , d = is_container ) ) )) ][0][0], ('b',))
def __call__(self, src): dst = VectorDict(VectorDict, {}) for coord, funct in self.iteritems(): if not is_leaf(funct): real_func = lambda v: funct(v) else: real_func = funct dst.build_path(*(list(coord.dst) + [real_func(src.at(coord.src))])) return dst
def test_is_leaf(self): """ we need a is_leaf more specialized must have a bug somewhre in find / match_tre TODO have one that tells is not vector_dict """ self.assertEqual( all( [ is_leaf(e) for e in [ set(), frozenset(), list(), (e for e in range(0,10)), 3.0, 2, False, "ljlkjkl", ]]), True )
def build_path( self, *path): """ implementation of constructing a path in a tree, argument is a serie of key >>> a = VectorDict(int, {}) >>> a.build_path( 'k', 1 ) >>> a.tprint() { k = 1, } >>> a.build_path( 'b', 'n', [ 1 ] ) >>> a.build_path( 'd', 'e', 2 ) >>> a.build_path( 'd', 'f', 4 ) >>> a.tprint() { k : 1, b : { n : [1], }, d : { e : 2, f : 4, }, } """ if len(path) == 2: key, value = path[0:2] if key in self.keys() or self.get(key): raise ValueError( "collision of values") self.__setitem__( key, value ) if len(path) > 2: key, value = path[0:2] if key in self.keys() and self.get(key): if value in self[key].keys(): self[key].build_path( path[1:]) else: if key in self.keys(): raise Exception("Path already present") if not is_leaf( self[key] ): self[key] += tree_from_path( *path[1:] ) else: self.__setitem__(key, tree_from_path( *path[1:] ))
def match_tree(self, a_tree): """does the tree given has an argument match the actual tree. if tree leaves are Clauses, the match_tree will apply the clauses. **Direct Match** >>> a_tree = dict( b = dict( c = 3.0, d = dict( e = True) ), ) >>> complex_dict = convert_tree( a_tree ) >>> complex_dict.match_tree( dict( c= 3.0 ,d = dict( e = True) )) >>> False >>> complex_dict.match_tree( dict( b=dict( c=3.0 ,d = dict( e = True) )) >>> True **Match with clauses** >>> from vector_dict.Clause import Clause, anything >>> complex_dict.match_tree( dict( b=dict( c=3.0 , d=anything ) ) ) >>> True >>> complex_dict.match_tree({ 'b': { 'c': Clause( lambda v : 1 < v < 5), 'd' : anything } } ) >>> True """ match_to_find = len(a_tree.keys()) if not set(a_tree).issubset( set(self.keys())): return False for k,v in a_tree.iteritems(): if k in self: if is_leaf(v): #terminaison of the comparison tree if isinstance( v, Clause ) or isinstance( v , types.FunctionType ): # if it is a clause apply it to the targeted tree match_to_find -= v(self.get(k)) else: ## it is not a clause val = self.get(k) ## BUG not all leaves are supposed to support - if is_leaf(val): match_to_find -= v == val else: match_to_find -= v in val else: ## the comparison tree goes on sub_tree = self.get(k) if not is_leaf(sub_tree): ## the compared tree goes on ## we recurse match_to_find -= sub_tree.match_tree( v ) else: ### the compared tree is smaller than the comparison ## tree match_to_find -= v ==sub_tree #return False return 0 == match_to_find