View difference between Paste ID: Qkhvybi7 and q08hh2kx
SHOW: | | - or go back to the newest paste.
1
import re
2
class AccountTree():
3
    def __init__(self):
4
        self.struct = {}  # На Всяко дете, кой е прекия родител
5
        self.children = None
6
        self.top_digits = {}  # На коя сметка колко цифри има в първата група
7
        self.groups = {}  # На коя сметка колко групи има
8
        self.top_group_min_digits_count = None     # Беше None
9
        self.top_group_max_digits_count = None     # Беше None
10-
        self.top_group_min_digits_count = None  # Беше None
10+
        self.max_groups_count = None               # Беше None
11-
        self.top_group_max_digits_count = None  # Беше None
11+
12-
        self.max_groups_count = None  # Беше None
12+
13-
        self.max_depth = None
13+
    def add_code(self, code):   # TODO IZPOLZWAM 1 Прави STRUCT !!!
14-
        self.all_accs = []
14+
15
        # "123-456-789" дава ["123", "456", "789"]
16
        groups_digits = re.findall('[0-9]+', code)
17-
    def add_code(self, code):  # TODO IZPOLZWAM 1 Прави STRUCT !!!
17+
18
        groups_seps = re.findall('[^0-9]+', code)
19
        groups_digits_len = len(groups_digits)
20
21
        # Следим максималния брой аналитични сметки
22
        if self.max_groups_count is None:
23
            self.max_groups_count = groups_digits_len
24
        elif groups_digits_len > self.max_groups_count: # МОже би трябва да е IF ???
25
            self.max_groups_count = groups_digits_len
26
27-
        elif groups_digits_len > self.max_groups_count:  # МОже би трябва да е IF ???
27+
28
        #1
29
        #12     -------TODO----- ВАЖНО -> ТОП родителя е този, който е подаден от Excel с най-малко цифри !!!
30-
        # 1
30+
        #123    -------TODO---- -> Няма смисъл да раздробяваме на по-малки кодове сметките в Оборотната ведомост !
31-
        # 12     -------TODO----- ВАЖНО -> ТОП родителя е този, който е подаден от Excel с най-малко цифри !!!
31+
        #123-456
32-
        # 123    -------TODO---- -> Няма смисъл да раздробяваме на по-малки кодове сметките в Оборотната ведомост !
32+
        #123-456-789
33-
        # 123-456
33+
34-
        # 123-456-789
34+
35
        top_group_digits = groups_digits[0]  # Първата група
36
        #print("top_group_digits", top_group_digits)
37-
        # print("top_group_digits", top_group_digits)
37+
38
39
        # В ancestors ще трупаме [сметка, родител, пра-родител и т.н.] но по цели групи от цифри
40
        ancestors = []
41
        ancestors_top_group_digits = []
42
        ancestors_groups = []
43
        # За ["123", "456", "789"] len1 ще мине през 3, 2, 1
44
        for len1 in range(groups_digits_len, 0, -1):
45
            # len1=3 дава ["123", "456", "789"]
46
            # len1=2 дава ["123", "456"]
47
            # len1=1 дава ["123"]
48
            code1 = ""
49
            # len1=3, то idx ше мине през 0, 1, 2
50
            # len1=2, то idx ше мине през 0, 1
51
            # len1=1, то idx ше мине през 0
52
            for idx in range(len1):
53
                if code1 != "":
54
                    code1 += groups_seps[idx - 1]
55
                    pass
56
                code1 += groups_digits[idx]
57
            ancestors.append(code1)
58
            ancestors_top_group_digits.append(top_group_digits_len)
59
            ancestors_groups.append(len1)
60
61
        # Следим коя е най-дългата първа група
62
        if self.top_group_max_digits_count is None:
63
            self.top_group_max_digits_count = top_group_digits_len
64
        elif top_group_digits_len > self.top_group_max_digits_count:
65
            self.top_group_max_digits_count = top_group_digits_len
66
        # Следим коя е най-късата първа група
67
        if self.top_group_min_digits_count is None:
68
            self.top_group_min_digits_count = top_group_digits_len
69
        elif top_group_digits_len < self.top_group_min_digits_count:
70
            self.top_group_min_digits_count = top_group_digits_len
71-
        for len1 in range(top_group_digits_len - 1, 0, -1):
71+
72-
            # print("len1", len1)
72+
73
        #print("top_group_digits_len", top_group_digits_len)
74
        for len1 in range(top_group_digits_len-1, 0, -1):
75
            #print("len1", len1)
76
            code1 = top_group_digits[0: len1]
77
            ancestors.append(code1)
78
            ancestors_top_group_digits.append(len1)
79
            ancestors_groups.append(1)
80-
        if self.max_depth is None:
80+
        # print("След анализ на първата група: ancestors", ancestors)
81-
            self.max_depth = ancestors_len
81+
82-
        elif ancestors_len > self.max_depth:
82+
83-
            self.max_depth = ancestors_len
83+
84
        ancestors_len = len(ancestors)
85
        for idx in range(ancestors_len):
86
            child = ancestors[idx]
87
            child_top_group_digits_len = ancestors_top_group_digits[idx]
88
            child_groups = ancestors_groups[idx]
89
            parent_idx = idx + 1
90
            if parent_idx < ancestors_len:  # Бащата присъства в списъка
91
                parent = ancestors[parent_idx]  # Вземаме бащата от списъка
92
            else:  # Бащата не е в списъка
93
                parent = ""  # Затова бащата е коренът
94
95
            if child in self.struct:
96
                # Няма нужда са се минава нататък през родителите му, понеже те вече са вписани
97-
                if len(child) > 0 and child not in self.all_accs: # TODO -> НЕ СЪДЪРЖА ВСИЧКИ СМЕТКИ !!!
97+
                #print(f"Вече е вписано, че {child} има родител {parent}, пропускаме останалото родословие")
98-
                    self.all_accs.append(parent)
98+
99-
                if len(parent) > 0 and parent not in self.all_accs:
99+
100-
                    self.all_accs.append(parent)
100+
101
                self.top_digits[child] = child_top_group_digits_len
102
                self.groups[child] = child_groups
103
        # print('ancestors', ancestors)
104
    def get_max_groups_count(self):
105
        return self.max_groups_count
106
107
    def get_top_group_max_digits_count(self):
108
        return self.top_group_max_digits_count
109
110
    def get_top_group_digits(self, code):
111
        return self.top_digits[code]
112
113
    def get_groups(self, code):
114
        return self.groups[code]
115
116
    # Връща дълбочината на дадена сметка в дървото
117
    def get_depth(self, code):  # TODO Izpolzwam 2
118-
    def get_max_depth(self):
118+
119-
        return self.max_depth
119+
120
        # Такава сметка има
121
        depth = 0
122
        next_code = code
123
        while next_code in self.struct:
124
            depth += 1
125
            next_code = self.struct[next_code]
126
127
        return depth
128
129
130
131
    def print_struct(self):     # TODO up_struct = children ????
132
        print('struct', self.struct) # struct {'10-100-20-25': '10-100-20', '10-100-20': '10-100', '10-100': '10', '10': '1', '1': ''}
133-
    def print_struct(self):  # TODO up_struct = children ????
133+
134-
        print('struct', self.struct)  # struct {'10-100-20-25': '10-100-20', '10-100-20': '10-100', '10-100': '10', '10': '1', '1': ''}
134+
135
        for key in self.struct:
136
            if self.struct[key] == self.struct[key]:
137
                key_up_struct = self.struct[key]
138
                if key_up_struct in up_struct:
139
                    up_struct[key_up_struct] += [key]
140
                elif key_up_struct not in up_struct:
141
                    up_struct[key_up_struct] = [key]
142
        # Сортиране на децата -> List in value
143
        for parent_acc in up_struct:
144
            up_struct[parent_acc].sort()
145
146
        print('up_struct', up_struct)
147
148
149
    # Връща list с само преките деца на даден code
150
    def get_children(self, code):
151
152
        if self.children is None:
153
            self.children = {}
154
            # Ще бъде речник с изброени преки деца на всяка сметка {"150": ["150-1", "150-2", ...], ...}
155
            for child in self.struct:
156
                parent = self.struct[child]
157-
        if code in self.children:  # Ако кодът има деца...
157+
158
                    self.children[parent] = []
159
                self.children[parent].append(child)
160-
        return []  # Затова връщаме празен списък
160+
161
        if code in self.children: # Ако кодът има деца...
162
            return self.children[code]  # връшаме ги Връща лист !
163-
    def get_all_children(self, code, max_depth=None):
163+
164-
        if max_depth is None:
164+
165-
            max_depth = self.max_depth
165+
        return []   # Затова връщаме празен списък
166
167
    # Връща list с всички деца, внуци и т.н. на даден код
168
    def get_all_children(self, code, max_depth = 999):
169
        if max_depth == 0:
170
            return []
171-
        # print(f"АААААА {code} има за деца {children}")
171+
172
        processed = []
173
        children = self.get_children(code)
174-
            # print(f"get_all_children() depth {depth}")
174+
        #print(f"АААААА {code} има за деца {children}")
175
        depth = 0
176-
            children_on_this_depth = 0
176+
177
            children1 = []
178
            for child in children:
179
                children1.append(child)
180
                if child in processed:  # вече сме добавили преките деца на това дете
181
                    continue  # затова пропускаме
182-
                # print(f"Ниво {depth}: {child} има за деца {children2}")
182+
183-
                children_on_this_depth += len(children2)
183+
                #print(f"Ниво {depth}: {child} има за деца {children2}")
184
                processed.append(child)
185
                for child2 in children2:
186
                    children1.append(child2)
187-
            if children_on_this_depth == 0:
187+
            #print(f"Заместваме {children} с {children1}")
188
            children = children1
189
            depth += 1
190
        return children
191
192
    def get_parent(self, acc_code):
193
        # print(f"acc_code {acc_code}")
194-
        if acc_code is None or acc_code == '':
194+
        # print('self.struct[acc_code]: ', self.struct[acc_code])
195
        if acc_code is None:
196-
        if acc_code in self.struct:  # Писано от мен
196+
197
        print(self.struct)
198
        # if acc_code in self.struct[acc_code]: # Писано от Владо
199-
    def get_all_parents(self, acc_code):
199+
        if acc_code in self.struct: # Писано от мен
200-
        parents = []
200+
201-
        # Почваме от даения код, вземаме родителя, после неговия родител и т.н. докато опрем в корена
201+
202
    def get_ancestors(self, acc_code):
203
        ancestors = []
204
        # Почваме от даения код, вземаме родителя, после неговия родител и т.н.
205
        # докато опрем в корена
206-
                break  # няма повече родители
206+
207-
            parents.append(parent)  # Добавяме родителя в списъка с предци
207+
208-
            browse_code = parent
208+
209-
        return parents
209+
210
            	break   # няма повече родители
211-
    # Листа на дървото = тези които нямат деца = най-дълбоки деца
211+
            ancestors.push(parent)  # Добавяме родителя в списъка с предци
212-
    def get_leaves(self):
212+
        return ancestors
213-
        # всички които имат родители са KEY в struct
213+
    
214-
        # всики които имат деца са VALUE в struct
214+
    # В TrialBalanceFilter на много места се искаме да знаем дали code1 е дете на code2.
215-
        # значи листа са тези които ги няма в стойностите, но ги има в ключовете
215+
    # Там правим сложни аналзи на групи цифри -- те трябва да се махнат.
216-
        values = self.struct.values() # list1
216+
    # ТАМ има self.acc_tree, което е обект от клас AccountTree
217-
        keys = self.struct.keys()  # list2
217+
    # AccountTree tрябва да се сдобие с методи като is_child() по-долу,
218-
        #leaves = има в keys, но ги няма в values
218+
    # kойто да отговаря на тоя въпрос като използва своя self.struct
219-
        leaves = set(keys).difference(values)
219+
    def is_child(self, child, parent):
220-
        return leaves
220+
        # Трябва да връша true или false
221
        pass
222-
    def get_leaves_bycode(self, list_accs: list):
222+
    def is_parent(self, child, parent):
223-
        list_leaves_bycode = []
223+
        # Трябва да връша true или false
224-
        # TODO -> Подавам код и проверяван дали е родител
224+
        pass
225-
        print('get_leaves_bycode list_accs: ', list_accs)
225+
226-
        for leaf in list_accs:
226+
227-
            is_parent = self.is_parent(leaf)
227+
228-
            if not is_parent:
228+
229-
                list_leaves_bycode.append(leaf)
229+
    acc_tree.add_code("100")
230-
        return list_leaves_bycode
230+
231
    acc_tree.get_parent('100')
232-
    def get_all_deepest_parents(self):
232+