File: tree.py

package info (click to toggle)
python-scipy 0.6.0-12
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 32,016 kB
  • ctags: 46,675
  • sloc: cpp: 124,854; ansic: 110,614; python: 108,664; fortran: 76,260; objc: 424; makefile: 384; sh: 10
file content (260 lines) | stat: -rw-r--r-- 7,906 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
import sys

from ga_util import shallow_clone


class AddError(Exception):
    """ Cannot add to the tree.
    """

class ParentError(Exception):
    """ Parent is incorrect.
    """

class base_tree_node(object):
    objects_ever = 0
    objects = 0
    circular = 0

    def inc(self):
        base_tree_node.objects = base_tree_node.objects + 1
        base_tree_node.objects_ever = base_tree_node.objects_ever + 1

    def dec(self):
        base_tree_node.objects = base_tree_node.objects - 1

    def __init__(self,child_count,node_type='',derive_type='', parent=None):
#               print 'trenode init',type(parent)
        self.inc()
        if parent is None:
            self.symbol_table = {}
        self.node_type = node_type
        self.derive_type = derive_type
        self.child_count = child_count
        self._children = []
        self.set_parent(parent)
        self.label = node_type

    #so that we don't overwrite the general creation function in a derived class
    #and screw up clone
    def _create(self,parent = None):
        """
        make lean and mean cause its called a ton
        """
        self.inc()
        new = shallow_clone(self)
        new.set_parent(parent)
        #next 2 lines removed to higher level for speed
        #new._children = []
        #if parent is None: new.symbol_table = {}
        return new

    def create(self,parent = None):
        new = self._create(parent)
        new._children = []
        if parent is None:
            new.symbol_table = {}
        return new

    def clone(self,parent = None):
        """
        make lean and mean cause its called a ton
        """
        new = self._create(parent)
        new._children = [x.clone(parent) for x in self._children]
        if parent is None:
            new.generate_symbol_table()
        return new

    def set_parent(self,parent):
        self.parent = parent

    def get_parent(self):
        return self.parent

    def generate_symbol_table(self):
        self.symbol_table = {}
        self._generate_symbol_table(self.symbol_table)

    def _generate_symbol_table(self,symbol_table):
        """
        Return:

        symbol_table -- a dictionary with derive_type
                 symbols as its keys.  Each value is a
                 list of all the nodes in this tree with
                 that derive_type.
        """
        for child in self._children:
            child._generate_symbol_table(symbol_table)
        if symbol_table.has_key(self.derive_type):
            symbol_table[self.derive_type].append(self)
        else:   symbol_table[self.derive_type] = [self]

    def parent_test(self):
        for child in self._children:
            child.parent_test()
        for child in self._children:
            if not child.get_parent() is self:
                #pdb.set_trace()
                raise ParentError

    def node_count(self,type=None):
        cnt = 0
        for child in self._children:
            cnt = cnt + child.node_count(type)
        if self.node_type == type or type is None:
            cnt = cnt + 1
        return cnt

    def apply_node(self,func,args):
        for child in self._children:
            child.apply_node(func,args)
        apply(func,(self,)+args)

    def add_child(self,node):
        if len(self._children) < self.child_count:
            node.set_parent(self)
            self._children.append(node)
        else:
            raise AddError('too many children')

    def filled(self):
        return len(self._children) >= self.child_count

    def children(self):
        return self._children

    def leaves(self):
        if self.child_count == 0:
            return 1
        else:
            leaves = 0
            for child in self._children:
                leaves = leaves + child.leaves()
        return leaves

    def depth(self):
        if self.child_count == 0:
            return 1
        else:
            return max(map(tree_node.depth,self._children)) + 1

    def ancestors(self):
        if self.get_parent(): return self.get_parent().ancestors() + 1
        return 1

    def root(self):
        if self.get_parent(): return self.get_parent().root()
        return self

    # I needed this to output string chromosomes for antennas
    # rethink this later
    def file_output(self,file):
        for child in self._children: child.file_output(file)

    def __repr__(self):
        res = '%s %s' % (self.label, self.derive_type)
        if len(self._children):
#                               res = res + ':%s' % self._children
            res =  res + '\n' + '\t'*self.ancestors()
            res = res + '%s' % self._children
        return res

    def delete_circulars(self):
        #if hasattr(self,'parent'):
        #       if self.parent is None: print 'deleting root ciculars'
        base_tree_node.circular = base_tree_node.circular + 1
        self.symbol_table = None
        for child in self._children:
            if len(child._children):
                child.delete_circulars()
            else:
                base_tree_node.circular = base_tree_node.circular + 1
            child.parent = None
            if sys.getrefcount(child) > 3:
            #       print 'aaaah!', sys.getrefcount(child)
                pass
            del child

    def __del__(self):
#               print 'tree_node killed:',tree_node.objects
        self.dec()
        #base_tree_node.objects = base_tree_node.objects - 1

    def __cmp__(self,other):
        #like ga_list compare...
        try:
            return cmp(self.__dict__,other.__dict__)
        except AttributeError:
            return 1

    def __setstate__(self,state):
        for key in state.keys():
            setattr(self, key, state[key])
        self.inc()


##core dumps on linux
#import weakdict
#class weak_tree_node(base_tree_node,weakdict.WeakValue):
#        def __init__(self,child_count,node_type='',derive_type='', parent=None):
#                weakdict.WeakValue.__init__(self)
#                base_tree_node.__init__(self,child_count,node_type,derive_type, parent)
#        def set_parent(self,parent):
#                print 'in set'
#                if not hasattr(self,'parent'):
#                        self.parent = weakdict.WeakDict()
#                if parent: self.parent[0] = parent
#                elif self.parent.has_key(0): del self.parent[0]
#                print 'out set'
#        def get_parent(self):
#                print 'in get'
#                if self.parent.has_key(0): p =  self.parent[0]
#                else: p = None
#                print 'out get'
#                return p
#        def delete_circulars(self):
#                pass

#import mxProxy
#class proxy_tree_node(base_tree_node):
#        passobj = 2 #could be anything
#        def set_parent(self,parent):
#                self.parent = mxProxy.WeakProxy(parent,None,self.passobj)
#        def get_parent(self):
#                if self.parent: return self.parent.proxy_object(self.passobj)
#                return None
#        def delete_circulars(self):
#                pass

tree_node = base_tree_node
#tree_node = weak_tree_node
#tree_node = proxy_tree_node

def ref():
    print 'current', base_tree_node.objects
    print 'ever', base_tree_node.objects_ever
    print 'circular deletes', base_tree_node.circular

def test_treenode():
    a = tree_node(2,'root')
    a.add_child(tree_node(0,'kid1'))
    a.add_child(tree_node(0,'kid2'))
    print a
    return a
    """
#       regress.test('tree_node: add child',a,notes)
    print a

    notes = 'tree_node: add child'
    a = tree_node(2,'root')
    a.add_child(tree_node(0,'kid1'))
    a.add_child(tree_node(0,'kid2'))
    temp = a.children()[0]
    a.children()[0] = a.children()[1]
    a.children()[1] = temp
    print a
    print a.children()[1].root()
    regress.test('tree_node: swap kids',a,notes)
    """