Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from enum import IntEnum
- from collections import deque
- import config
- const = IntEnum('Constants', 'START END', start=-1)
- class Base:
- def __init__(self, data=None, **kwargs):
- self.id = kwargs.get('id')
- self.name = kwargs.get('name')
- self.parent = kwargs.get('parent')
- self.columns = kwargs.get('columns')
- if data:
- self.id = data.get('id')
- self.name = data.get('name')
- self.parent = data.get('parent')
- self.columns = data.get('columns')
- @property
- def tree(self):
- item = self
- while not isinstance(item, Tree):
- item = item.parent
- return item
- def get(self, column):
- if not column:
- return self.name
- elif self and len(self.columns) > column >= 1:
- return self.columns[column-1]
- def set(self, column, value):
- if column < 0:
- return
- if column > len(self.columns):
- self.columns.append(value)
- else:
- self.columns[column-1] = value
- def is_node(self, item=None):
- if not item:
- item = self
- return True if isinstance(item, Node) else False
- class Leaf(Base):
- def __init__(self, data=None, **kwargs):
- super().__init__(data, **kwargs)
- if self.id is None and self.parent:
- self.id = self.tree.next_id()
- elif self.parent:
- for node in self.parent:
- if node.id == self.id:
- self.id = self.tree.next_id()
- return
- else:
- self.id = self.tree.next_id()
- class Node(Base, deque):
- def __init__(self, data=None, **kwargs):
- Base.__init__(self, data, **kwargs)
- deque.__init__(self)
- if self.id is None and self.parent:
- self.id = self.tree.next_id()
- elif self.parent:
- for node in self.parent:
- if node.id == self.id:
- self.id = self.tree.next_id()
- return
- self.id = self.tree.next_id()
- elif not isinstance(self, Tree):
- self.id = self.tree.next_id()
- @property
- def children(self):
- return self
- def show(self, parent=None, indent=3):
- def walk(_parent, level=0):
- for idx, _node in enumerate(_parent):
- pad = '' if not level else ' ' * (indent * level)
- print(f' {_node.id}:{pad} {_node.name}, {_node.columns}')
- if _parent.is_node(_node):
- walk(_node, level+1)
- print('-----------------------------------------------------')
- print(f'ID: Name, Columns: {str(self.tree.headings)}')
- print('-----------------------------------------------------')
- walk(parent if parent else self)
- print('-----------------------------------------------------')
- def query(self, query):
- if isinstance(query, int):
- return self.query_by_id(query)
- elif isinstance(query, str):
- return self.query_by_name(query)
- def populate(self, data, **kwargs):
- self.tree.populate(data, parent=self)
- def get_cell(self, row, column):
- item = self.query(row)
- if not item:
- return
- if column:
- return item.get(column)
- else:
- return self.name
- def set_cell(self, row, column, value):
- item = self.query(row)
- if column:
- item.set(column, value)
- else:
- item.name = value
- def query_by_id(self, _id):
- def walk(_item):
- if _item.id == _id:
- return _item
- if not _item.is_node():
- return
- for child in _item:
- if child.is_node():
- _result = walk(child)
- if _result:
- return _result
- elif child.id == _id:
- return child
- for item in self:
- result = walk(item)
- if result:
- return result
- def query_by_name(self, name):
- def walk(_item):
- if _item.name == name:
- return _item
- if not _item.is_node():
- return
- for child in _item:
- if child.is_node():
- _result = walk(child)
- if _result:
- return _result
- elif child.name == name:
- return child
- for item in self:
- result = walk(item)
- if result:
- return result
- class Tree(Node):
- def __init__(self, data=None):
- self.size = 0
- self.headings = ['Type', 'Size', 'Parent']
- super().__init__()
- self.name = '.'
- self.parent = None
- self.populate(data)
- def next_id(self):
- self.size += 1
- return self.size
- def reindex(self, start=0):
- def walk(_parent, level=0):
- for _node in _parent:
- _node.id = self.next_id()
- if _parent.is_node(_node):
- walk(_node, level+1)
- self.size = start
- walk(self)
- def populate(self, data, **kwargs):
- if not data:
- return
- def walk(_parent, _item):
- if 'children' in _item:
- _item['columns'] = ['Node', '0 items', _parent.name]
- item = Node(parent=_parent, **_item)
- if 'children' in _item and len(_item['children']):
- for node in _item['children']:
- walk(item, node)
- else:
- _item['columns'] = ['Leaf', '0 Kb', _parent.name]
- item = Leaf(parent=_parent, **_item)
- _parent.append(item)
- parent = kwargs.get('parent', self)
- if isinstance(data, list):
- for cfg in data:
- walk(parent, cfg)
- def main():
- t = Tree()
- # Create node with kwargs.
- node = Node(parent=t, name='Test 4', columns=['Node', '0 items', t.name])
- t.append(node)
- leaf = Leaf(parent=t, name='Test 1', columns=['Leaf', '0 Kb', t.name])
- t.append(leaf)
- # Create node with dict.
- node = Node({'parent': t, 'name': 'Test 2', 'columns': ['Node', '0 items', t.name]})
- t.append(node)
- node = Node(parent=t, name='Test 3', columns=['Node', '0 items', t.name])
- t.append(node)
- leaf = Leaf(parent=node, name='Leaf 3-1', columns=['Leaf', '0 Kb', node.name])
- node.append(leaf)
- t.show()
- cfg = [{
- 'name': 'Node 1a',
- 'children': [
- {
- 'name': 'Leaf 1a',
- },
- {
- 'name': 'Leaf 2a',
- },
- {
- 'name': 'Sub Node 1a',
- 'children': [
- {
- 'name': 'Sub Leaf 1a',
- },
- ]
- },
- ],
- }]
- t = Tree(cfg)
- node = t[0]
- node.set(1, 'Test')
- t.show()
- t.set_cell(5, 0, 'New Name')
- t.show()
- t.query(4).populate(cfg)
- t.show()
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement