-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTree.py
144 lines (115 loc) · 4.66 KB
/
Tree.py
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
import re
from peewee import SqliteDatabase, CharField, IntegerField, Model, ForeignKeyField, DataError, DatabaseError
db = SqliteDatabase('Tree.db')
def print_tree():
for e in Node.select():
print(e.name)
print('___')
for e in Parent.select():
print(e.parent_id.get_id(), e.children_id.get_id())
print('___')
class Node(Model):
name = CharField()
data = CharField(null=True)
@staticmethod
def is_contain_id(node_id):
return len(Node.select().where(Node.id == node_id)) != 0
class Meta:
database = db
class Parent(Model):
children_id = ForeignKeyField(model=Node)
parent_id = ForeignKeyField(model=Node)
@staticmethod
def get_parent_id(children_id):
print(children_id)
if not Node.is_contain_id(children_id):
raise DataError('Id not exist in database')
parent = Parent.select().where(Parent.children_id == children_id).get()
return parent.parent_id.get_id()
@staticmethod
def get_childrens_id(parent_id):
if not Node.is_contain_id(parent_id):
raise DataError('Id not exist in database')
result = []
for e in Parent.select().where(Parent.parent_id == parent_id):
result.append(e.get_id())
return result
class Meta:
database = db
class Tree:
def __init__(self):
Node.create_table(safe=True)
Parent.create_table(safe=True)
if not Node.is_contain_id(0):
Node.create(name='', id=0)
Node.create(name='.')
Parent.create(parent_id=0, children_id=1)
def get_element_id(self, names):
current_id = 0
for name in names:
is_children_exist = False
for children_id in Parent.get_childrens_id(current_id):
if Node.get_by_id(children_id).name == name:
current_id = children_id
is_children_exist = True
break
if not is_children_exist:
raise DatabaseError('Incorrect path')
return current_id
def get_elements(self, node_id):
elements = []
if not Node.is_contain_id(node_id):
raise IndexError('Id not exist in database')
for children_id in Parent.get_childrens_id(node_id):
elements.append(Node.get_by_id(children_id))
return elements
def get_data_of_element(self, node_id):
if not Node.is_contain_id(node_id):
raise IndexError('Id not exist in database')
node = Node.get_by_id(node_id)
return "{} - {}".format(node.name, node.data)
def put(self, name, node_id=0, data=None):
if not Node.is_contain_id(node_id):
raise IndexError('Id not exist in database')
parent = Node.get_by_id(node_id)
if not Tree.is_name_correct(name, node_id):
raise DataError("Name isn't corrent")
parent_id = parent.get_id()
new_element = Node.create(name=name, data=data)
new_id = new_element.get_id()
Parent.create(children_id=new_id, parent_id=parent_id)
def post(self, name, node_id, data=None):
if not Node.is_contain_id(node_id):
raise IndexError('Id not exist in database')
element = Node.get_by_id(node_id)
if not Tree.is_name_correct(name, Parent.get_parent_id(node_id), element.id):
raise DataError("Name isn't correct")
element.data = data
element.name = name
element.save()
def delete(self, node_id, delete_prev_edges=True):
edges_id = []
for edge in Parent.select().where(Parent.parent_id == node_id):
children_id = edge.children_id.get_id()
self.delete(children_id, False)
edges_id.append(edge.get_id())
Node.delete_by_id(node_id)
if delete_prev_edges:
for edge in Parent.select().where(Parent.children_id == node_id):
edges_id.append(edge.get_id())
for edge_id in edges_id:
Parent.delete_by_id(edge_id)
@staticmethod
def is_name_correct(name, parent_id, current_id=None):
for children_id in Parent.get_childrens_id(parent_id):
if Node.get_by_id(children_id).name == name:
if children_id != current_id:
return False
return re.match(r'([a-zA-Zа-яА-Я]+ )*[a-zA-Zа-яА-Я]+', name) and \
not Tree.is_name_in_branch(name, parent_id)
@staticmethod
def is_name_in_branch(name, parent_id):
if parent_id == 0:
return False
return Node.get_by_id(parent_id).name == name or \
Tree.is_name_in_branch(name, Parent.get_parent_id(parent_id))