SankeyExcelParser 1.0.0b0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. SankeyExcelParser/__init__.py +0 -0
  2. SankeyExcelParser/io_excel.py +1867 -0
  3. SankeyExcelParser/io_excel_constants.py +811 -0
  4. SankeyExcelParser/sankey.py +3138 -0
  5. SankeyExcelParser/sankey_utils/__init__.py +0 -0
  6. SankeyExcelParser/sankey_utils/data.py +1118 -0
  7. SankeyExcelParser/sankey_utils/excel_source.py +31 -0
  8. SankeyExcelParser/sankey_utils/flux.py +344 -0
  9. SankeyExcelParser/sankey_utils/functions.py +278 -0
  10. SankeyExcelParser/sankey_utils/node.py +340 -0
  11. SankeyExcelParser/sankey_utils/protos/__init__.py +0 -0
  12. SankeyExcelParser/sankey_utils/protos/flux.py +84 -0
  13. SankeyExcelParser/sankey_utils/protos/node.py +386 -0
  14. SankeyExcelParser/sankey_utils/protos/sankey_object.py +135 -0
  15. SankeyExcelParser/sankey_utils/protos/tag_group.py +95 -0
  16. SankeyExcelParser/sankey_utils/sankey_object.py +165 -0
  17. SankeyExcelParser/sankey_utils/table_object.py +37 -0
  18. SankeyExcelParser/sankey_utils/tag.py +95 -0
  19. SankeyExcelParser/sankey_utils/tag_group.py +206 -0
  20. SankeyExcelParser/su_trace.py +239 -0
  21. SankeyExcelParser/tests/integration/__init__.py +0 -0
  22. SankeyExcelParser/tests/integration/test_base.py +356 -0
  23. SankeyExcelParser/tests/integration/test_run_check_input.py +100 -0
  24. SankeyExcelParser/tests/integration/test_run_conversions.py +96 -0
  25. SankeyExcelParser/tests/integration/test_run_load_input.py +94 -0
  26. SankeyExcelParser/tests/unit/__init__.py +0 -0
  27. SankeyExcelParser-1.0.0b0.data/scripts/run_parse_and_write_excel.py +155 -0
  28. SankeyExcelParser-1.0.0b0.data/scripts/run_parse_excel.py +115 -0
  29. SankeyExcelParser-1.0.0b0.dist-info/METADATA +113 -0
  30. SankeyExcelParser-1.0.0b0.dist-info/RECORD +32 -0
  31. SankeyExcelParser-1.0.0b0.dist-info/WHEEL +5 -0
  32. SankeyExcelParser-1.0.0b0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,340 @@
1
+ """
2
+ Author : Vincent LE DOZE
3
+ Date : 31/05/23
4
+
5
+ This file contains descriptions for Node class
6
+
7
+ """
8
+
9
+ # Local modules -----------------------------------------------------
10
+ from SankeyExcelParser.sankey_utils.protos.flux import _ProtoFlux
11
+ from SankeyExcelParser.sankey_utils.protos.node import _ProtoNode
12
+
13
+
14
+ # CLASS ----------------------------------------------------------------------------
15
+ class Node(_ProtoNode):
16
+ """
17
+ Define a node object.
18
+ Inherits from `_ProtoNode`, but add methods to deal with other Nodes.
19
+ """
20
+
21
+ def __init__(
22
+ self,
23
+ name: str,
24
+ level: int,
25
+ **kwargs
26
+ ):
27
+ # Init super
28
+ _ProtoNode.__init__(self, name, level)
29
+ # Add constructor values
30
+ self.update(**kwargs)
31
+
32
+ def update(
33
+ self,
34
+ **kwargs
35
+ ):
36
+ for key, value in kwargs.items():
37
+ setattr(self, key, value)
38
+
39
+ @property
40
+ def children_ids(self):
41
+ if not self.has_at_least_one_child():
42
+ return [[]]
43
+ return [[_.id for _ in grp] for grp in self._children_grps if len(grp) > 0]
44
+
45
+ @property
46
+ def parents_ids(self):
47
+ return [_.id for _ in self._parents]
48
+
49
+ def add_child(self, node: _ProtoNode, childrengrp_id: int = -1):
50
+ """
51
+ Add child to a children list.
52
+
53
+ Parameters
54
+ ----------
55
+ :param node: Child node to add.
56
+ :type node: _ProtoNode
57
+
58
+ :param childrengrp_id: Children group in which we should add child to.
59
+ :type childrengrp_id: int, optionnal (default=-1)
60
+ """
61
+ # Verify that we don't already have that child
62
+ # Add new groupe
63
+ if self._create_new_children_grp:
64
+ self._children_grps.append([])
65
+ self._create_new_children_grp = False
66
+ # Secure childgroup index
67
+ if childrengrp_id > 0:
68
+ while childrengrp_id >= len(self._children_grps):
69
+ self._children_grps.append([])
70
+ # Protection
71
+ if node not in self._children_grps[childrengrp_id]:
72
+ # Add child
73
+ self._children_grps[childrengrp_id].append(node)
74
+ # Add self to child's parent
75
+ node._add_parent(self)
76
+
77
+ def create_new_children_group(self):
78
+ self._create_new_children_grp = True
79
+
80
+ def has_at_least_one_child(self):
81
+ for _ in self._children_grps:
82
+ if len(_) > 0:
83
+ return True
84
+ return False
85
+
86
+ def is_child_of_given_node(self, node: _ProtoNode):
87
+ return (self in node.parents)
88
+
89
+ def get_set_of_all_base_children(self):
90
+ if self.has_at_least_one_child():
91
+ children_set = set()
92
+ for children_grp in self._children_grps:
93
+ for child in children_grp:
94
+ children_set |= child.get_set_of_all_base_children()
95
+ return children_set
96
+ return set([self])
97
+
98
+ def autocompute_level_and_children_levels(self, min_level=1):
99
+ """
100
+ Autocompute level based on parenthood leveling.
101
+ Returns max level that has been reached from children.
102
+ """
103
+ # Update own level
104
+ self._level = max(self._level, min_level)
105
+ # Init max level value
106
+ max_level = self._level
107
+ # Update sub-levels
108
+ for children_grp in self._children_grps:
109
+ # Secure: Start from a common min level for given children grp
110
+ min_children_level = min_level + 1
111
+ for child in children_grp:
112
+ min_children_level = max(child.level, min_children_level)
113
+ # Propagate level computing
114
+ for child in children_grp:
115
+ max_children_level = \
116
+ child.autocompute_level_and_children_levels(min_level=min_children_level)
117
+ max_level = max(max_children_level, max_level)
118
+ # Return max level
119
+ return max_level
120
+
121
+ def _add_parent(self, node: _ProtoNode):
122
+ """
123
+ Add parent.
124
+
125
+ Parameters
126
+ ----------
127
+ :param node: Parent node to add.
128
+ :type node: _ProtoNode
129
+ """
130
+ if node not in self._parents:
131
+ self._parents.append(node)
132
+
133
+ def has_parents(self):
134
+ return len(self._parents) > 0
135
+
136
+ def is_parent_of_given_node(self, node: _ProtoNode):
137
+ return node.is_child_of_given_node(self)
138
+
139
+ def add_input_flux(self, flux: _ProtoFlux):
140
+ self._input_flux.append(flux)
141
+
142
+ def add_output_flux(self, flux: _ProtoFlux):
143
+ self._output_flux.append(flux)
144
+
145
+ def get_flux_from_given_node(self, node: _ProtoNode):
146
+ """
147
+ Return the flux node->self
148
+
149
+ Parameters
150
+ ----------
151
+ :param node: Node where flux must arrive from
152
+ :type node: _ProtoNode
153
+
154
+ Returns
155
+ -------
156
+ :return: Flux that as been ask if found, otherwise None
157
+ :rtype: _ProtoFlux | None
158
+ """
159
+ for flux in self._input_flux:
160
+ if flux.orig == node:
161
+ return flux
162
+ return None
163
+
164
+ def get_flux_to_given_node(self, node: _ProtoNode):
165
+ """
166
+ Return the flux self->node
167
+
168
+ Parameters
169
+ ----------
170
+ :param node: Node where flux must go to
171
+ :type node: _ProtoNode
172
+
173
+ Returns
174
+ -------
175
+ :return: Flux that as been ask if found, otherwise None
176
+ :rtype: _ProtoFlux | None
177
+ """
178
+ for flux in self._output_flux:
179
+ if flux.dest == node:
180
+ return flux
181
+ return None
182
+
183
+ def update_table(
184
+ self,
185
+ level: int,
186
+ taggs_names: list,
187
+ extra_infos_names: list,
188
+ lineages_processed: list,
189
+ lineages_tables: list,
190
+ current_lineage_table: list,
191
+ lineages_entries,
192
+ current_lineage_entries,
193
+ lineages_entries__levels,
194
+ current_lineage_entries__levels
195
+ ):
196
+ """
197
+ Update a panda table with this node infos.
198
+ The columns are organized as :
199
+
200
+ 1. Level
201
+ 2. Name
202
+ 3. Mat balance
203
+ 4. Color
204
+ 5. All node tags (multiple columns) : for each column we have the respective tags or None
205
+ 6. Definition
206
+ 14. All remaining extra infos (if present, multiple columns)
207
+
208
+ Parameters
209
+ ----------
210
+ :param level: Level that will be indicated on table for the node.
211
+ Can be different form actual level because of multiplicity of parents
212
+ :type level: int
213
+
214
+ :param taggs_names: List of tag groups for node tags columns
215
+ :type taggs_names: list[str] | list[TagGroup]
216
+
217
+ :param extra_infos_names: List of extra infos to search for extra infos columns
218
+ :type extra_infos_names: list[str]
219
+
220
+ :param lineages_processed: List of children grp that have already been added to table
221
+ :type lineages_processed: list[list[Node]] (modified)
222
+
223
+ :param lineages_tables: List of all tables (2-D list) of all possible lineages of nodes
224
+ :type lineages_tables: list[list[list[str]]] (modified)
225
+
226
+ :param current_lineage_table: Table (2-D list) containing infos of all current lineage related nodes
227
+ :type current_lineage_table: list[list[str]] (modified)
228
+
229
+ :param lineages_entries:
230
+ List of all lists of nodes that have been added to lineages_tables.
231
+ Used to colorize table.
232
+ :type lineages_entries: list[list[Node]] (modified)
233
+
234
+ :param current_lineage_entries:
235
+ List of nodes that have been added to current_lineage_table.
236
+ Used to colorize table.
237
+ :type current_lineage_entries: list[Node] (modified)
238
+
239
+ :param lineages_entries__level:
240
+ List of all lists of nodes' levels that have been added to lineages_tables.
241
+ Used to colorize table.
242
+ :type lineages_entries: list[list[int]] (modified)
243
+
244
+ :param current_lineage_entries__level:
245
+ List of nodes' levels that have been added to current_lineage_table.
246
+ Used to colorize table.
247
+ :type current_lineage_entries: list[int] (modified)
248
+ """
249
+ # Create table line with corresponding data for self
250
+ line_node = [
251
+ level,
252
+ self.name,
253
+ self.mat_balance,
254
+ self.color]
255
+ # Add tags
256
+ line_node += self.get_tags_from_taggroups(
257
+ taggs_names, return_names_instead_of_refs=True)
258
+ # Add definition
259
+ line_node.append(self.definition)
260
+ # Add extra info cols if needed
261
+ for extra_info_name in extra_infos_names:
262
+ if extra_info_name in self.extra_infos.keys():
263
+ line_node.append(self.extra_infos[extra_info_name])
264
+ else:
265
+ line_node.append(None)
266
+ # Add line to the table
267
+ current_lineage_table.append(line_node)
268
+ current_lineage_entries.append(self)
269
+ current_lineage_entries__levels.append(level)
270
+ # If we have children for this node, we add them directly under
271
+ if self.has_at_least_one_child():
272
+ main_lineages_processed = False
273
+ # I do not pass by decorator here, because I need the pointer to childgroup for lineages_processed
274
+ for childgroup in self._children_grps:
275
+ # Pass already processed lineage
276
+ if childgroup in lineages_processed:
277
+ continue
278
+ # Recursively process children for main lineage (first children grp)
279
+ if not main_lineages_processed:
280
+ for child in childgroup:
281
+ child.update_table(
282
+ level+1,
283
+ taggs_names,
284
+ extra_infos_names,
285
+ lineages_processed,
286
+ lineages_tables,
287
+ current_lineage_table,
288
+ lineages_entries,
289
+ current_lineage_entries,
290
+ lineages_entries__levels,
291
+ current_lineage_entries__levels)
292
+ main_lineages_processed = True
293
+ else:
294
+ if len(childgroup) > 0: # Protection
295
+ # Start a new lineage (from level = 1)
296
+ new_line_node = line_node.copy()
297
+ new_line_node[0] = 1
298
+ new_lineage_table = [new_line_node]
299
+ lineages_tables.append(new_lineage_table)
300
+ # Update list of level / nodes for table colorization
301
+ new_lineage_entries = [self]
302
+ new_lineage_entries__levels = [1]
303
+ lineages_entries.append(new_lineage_entries)
304
+ lineages_entries__levels.append(new_lineage_entries__levels)
305
+ # Recursively process children for new lineage
306
+ for child in childgroup:
307
+ child.update_table(
308
+ 2,
309
+ taggs_names,
310
+ extra_infos_names,
311
+ lineages_processed,
312
+ lineages_tables,
313
+ new_lineage_table,
314
+ lineages_entries,
315
+ new_lineage_entries,
316
+ lineages_entries__levels,
317
+ new_lineage_entries__levels)
318
+ lineages_processed.append(childgroup)
319
+
320
+ def get_as_dict(self):
321
+ # Init output
322
+ output = {}
323
+ # Get values
324
+ output['name'] = self.name
325
+ output['tags'] = [
326
+ [_.group.name, _.name] for _ in self.tags]
327
+ output['parents'] = [_.name for _ in self.parents]
328
+ output['childrens'] = \
329
+ [[_.name for _ in grp]
330
+ for grp in self.children_grps]
331
+ output['mat_balance'] = self.mat_balance
332
+ output['color'] = self.color
333
+ output['definition'] = self.definition
334
+ return output
335
+
336
+ def __repr__(self):
337
+ s = '{}'.format(self._name)
338
+ for tag in self._tags:
339
+ s += ' | {}'.format(tag)
340
+ return s
File without changes
@@ -0,0 +1,84 @@
1
+ """
2
+ Author : Vincent LE DOZE
3
+ Date : 31/05/23
4
+
5
+ This file contains descriptions for proto Flux class
6
+
7
+ """
8
+
9
+ # Local modules -----------------------------------------------------
10
+ from SankeyExcelParser.sankey_utils.sankey_object import SankeyObject
11
+ from SankeyExcelParser.sankey_utils.protos.node import _ProtoNode
12
+
13
+
14
+ # CLASS ----------------------------------------------------------------------------
15
+ class _ProtoFlux(SankeyObject):
16
+ """
17
+ Define a prototype for flux object.
18
+ Does nothing except defining attributes.
19
+ Inherits from `SankeyObject`
20
+
21
+ Parameters
22
+ ----------
23
+ :param id: Flux id (standardized))
24
+ :type id: str
25
+
26
+ :param orig: Flux starting node
27
+ :type orig: _ProtoNode
28
+
29
+ :param dest: Flux ending node
30
+ :type dest: _ProtoNode
31
+
32
+ :param datas: All datas for the flux
33
+ :type datas: list [Data, ...]
34
+
35
+ :param results: All datas (as results) for the flux
36
+ :type results: list [Data, ...]
37
+ """
38
+
39
+ def __init__(
40
+ self,
41
+ orig: _ProtoNode,
42
+ dest: _ProtoNode,
43
+ **kwargs
44
+ ):
45
+ # Init super constructor
46
+ SankeyObject.__init__(self)
47
+ # Create attributs
48
+ self._id = orig.id+'---'+dest.id
49
+ self._orig = orig
50
+ self._dest = dest
51
+
52
+ @property
53
+ def id(self):
54
+ return self._id
55
+
56
+ @property
57
+ def orig(self):
58
+ return self._orig
59
+
60
+ @property
61
+ def dest(self):
62
+ return self._dest
63
+
64
+ @property
65
+ def natural_unit(self):
66
+ return self._orig.get_natural_unit()
67
+
68
+ @natural_unit.setter
69
+ def natural_unit(self, _):
70
+ # Unit apply only to origin
71
+ self._orig._add_natural_unit(_)
72
+
73
+ @property
74
+ def factor(self):
75
+ return self._orig.get_factor()
76
+
77
+ @factor.setter
78
+ def factor(self, _):
79
+ # Unit apply only to origin
80
+ self._orig.add_factor(_)
81
+
82
+ @property
83
+ def tooltips(self):
84
+ return self._orig.tooltips