tricc-oo 1.4.4__tar.gz → 1.4.6__tar.gz

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 (51) hide show
  1. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/PKG-INFO +2 -1
  2. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/pyproject.toml +2 -1
  3. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/models/ordered_set.py +33 -0
  4. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/models/tricc.py +1 -1
  5. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/serializers/xls_form.py +1 -0
  6. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/strategies/input/drawio.py +1 -1
  7. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/strategies/output/spice.py +1 -1
  8. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/strategies/output/xls_form.py +1 -1
  9. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/visitors/tricc.py +53 -79
  10. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo.egg-info/PKG-INFO +2 -2
  11. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo.egg-info/SOURCES.txt +1 -1
  12. /tricc_oo-1.4.4/LICENSE.md → /tricc_oo-1.4.6/LICENSE +0 -0
  13. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/README.md +0 -0
  14. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/setup.cfg +0 -0
  15. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tests/build.py +0 -0
  16. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tests/test_cql.py +0 -0
  17. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tests/to_ocl.py +0 -0
  18. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/__init__.py +0 -0
  19. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/converters/__init__.py +0 -0
  20. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/converters/codesystem_to_ocl.py +0 -0
  21. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/converters/cql/cqlLexer.py +0 -0
  22. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/converters/cql/cqlListener.py +0 -0
  23. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/converters/cql/cqlParser.py +0 -0
  24. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/converters/cql/cqlVisitor.py +0 -0
  25. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/converters/cql_to_operation.py +0 -0
  26. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/converters/datadictionnary.py +0 -0
  27. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/converters/drawio_type_map.py +0 -0
  28. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/converters/tricc_to_xls_form.py +0 -0
  29. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/converters/utils.py +0 -0
  30. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/converters/xml_to_tricc.py +0 -0
  31. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/models/__init__.py +0 -0
  32. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/models/base.py +0 -0
  33. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/models/calculate.py +0 -0
  34. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/models/lang.py +0 -0
  35. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/models/ocl.py +0 -0
  36. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/parsers/__init__.py +0 -0
  37. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/parsers/xml.py +0 -0
  38. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/serializers/__init__.py +0 -0
  39. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/serializers/planuml.py +0 -0
  40. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/strategies/__init__.py +0 -0
  41. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/strategies/input/__init__.py +0 -0
  42. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/strategies/input/base_input_strategy.py +0 -0
  43. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/strategies/output/base_output_strategy.py +0 -0
  44. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/strategies/output/xlsform_cdss.py +0 -0
  45. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/strategies/output/xlsform_cht.py +0 -0
  46. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/strategies/output/xlsform_cht_hf.py +0 -0
  47. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/visitors/__init__.py +0 -0
  48. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo/visitors/xform_pd.py +0 -0
  49. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo.egg-info/dependency_links.txt +0 -0
  50. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo.egg-info/requires.txt +0 -0
  51. {tricc_oo-1.4.4 → tricc_oo-1.4.6}/tricc_oo.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tricc-oo
3
- Version: 1.4.4
3
+ Version: 1.4.6
4
4
  Summary: Python library that converts CDSS L2 in L3
5
5
  Project-URL: Homepage, https://github.com/SwissTPH/tricc
6
6
  Project-URL: Issues, https://github.com/SwissTPH/tricc/issues
@@ -9,6 +9,7 @@ Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Operating System :: OS Independent
10
10
  Requires-Python: >=3.8
11
11
  Description-Content-Type: text/markdown
12
+
12
13
  Requires-Dist: lxml
13
14
  Requires-Dist: html2text
14
15
  Requires-Dist: pydantic
@@ -4,9 +4,10 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tricc-oo"
7
- version = "1.4.4"
7
+ version = "1.4.6"
8
8
  description = "Python library that converts CDSS L2 in L3"
9
9
  readme = "README.md"
10
+ license-files = ["LICENSE"]
10
11
 
11
12
  requires-python = ">=3.8"
12
13
  classifiers = [
@@ -86,6 +86,39 @@ class OrderedSet(Sequence):
86
86
  sorted_keys = sorted(self._od.keys(), key=key, reverse=reverse)
87
87
  self._od = OrderedDict.fromkeys(sorted_keys)
88
88
 
89
+ def find_last(self, filter: callable):
90
+ # Iterate over items in reverse order
91
+ for item in reversed(list(self._od.keys())):
92
+ if filter(item):
93
+ return item
94
+ return None # Return None if no matching item is found
95
+
96
+ def find_first(self, filter: callable):
97
+ for item in list(self._od.keys()):
98
+ if filter(item):
99
+ return item
100
+ return None # Return None if no matching item is found
101
+
102
+
103
+ def find_prev(self, obj, filter: callable):
104
+ # Get the list of keys (items) in the OrderedSet
105
+ keys = list(self._od.keys())
106
+
107
+ # If the object is not in the OrderedSet, start from the end
108
+ if obj not in self._od:
109
+ start_index = len(keys) - 1
110
+ else:
111
+ # Find the index of the given object
112
+ start_index = keys.index(obj)
113
+
114
+ # Iterate backward from the start_index
115
+ for i in range(start_index - 1, -1, -1):
116
+ item = keys[i]
117
+ if filter(item):
118
+ return item
119
+
120
+ return None # Return None if no matching item is found before the object
121
+
89
122
  @classmethod
90
123
  def __get_pydantic_core_schema__(cls, source_type: type, handler: GetCoreSchemaHandler) -> CoreSchema:
91
124
  # Define how Pydantic should handle this type
@@ -16,7 +16,7 @@ class TriccNodeCalculateBase(TriccNodeBaseModel):
16
16
  #input: Dict[TriccOperation, TriccNodeBaseModel] = {}
17
17
  reference: Union[List[Union[TriccNodeBaseModel,TriccStatic]], Expression, TriccStatic] = None
18
18
  expression_reference: Union[str, TriccOperation] = None
19
- last: bool = True
19
+ last: bool = None
20
20
  datatype: str = 'boolean'
21
21
  # to use the enum value of the TriccNodeType
22
22
  class Config:
@@ -418,6 +418,7 @@ def generate_xls_form_export(strategy, node, processed_nodes, stashed_nodes, df_
418
418
  if len(df_calculate[df_calculate.name == get_export_name(node)])==0:
419
419
  df_calculate.loc[len(df_calculate)] = values
420
420
  else:
421
+ df_calculate.loc[len(df_calculate)] = values
421
422
  logger.critical("name {} found twice".format(node.name))
422
423
  elif ODK_TRICC_TYPE_MAP[node.tricc_type] !='':
423
424
  values = []
@@ -134,7 +134,7 @@ class DrawioStrategy(BaseInputStrategy):
134
134
 
135
135
  # do the calculation, expression ...
136
136
 
137
- def linking_nodes(self, node, page, pages, processed_nodes=set(), path=[]):
137
+ def linking_nodes(self, node, page, pages, processed_nodes=OrderedSet(), path=[]):
138
138
  # get the edges that have that node as source
139
139
 
140
140
 
@@ -285,7 +285,7 @@ class SpiceStrategy(BaseOutPutStrategy):
285
285
  )
286
286
 
287
287
 
288
- def activity_export(self, activity, processed_nodes=set(), **kwargs):
288
+ def activity_export(self, activity, processed_nodes=OrderedSet(), **kwargs):
289
289
  stashed_nodes = OrderedSet()
290
290
  calculates = []
291
291
  cur_group = activity
@@ -155,7 +155,7 @@ class XLSFormStrategy(BaseOutPutStrategy):
155
155
 
156
156
  def activity_export(self, activity, processed_nodes=None, **kwargs):
157
157
  if processed_nodes is None:
158
- processed_nodes = set()
158
+ processed_nodes = OrderedSet()
159
159
  stashed_nodes = OrderedSet()
160
160
  # The stashed node are all the node that have all their prevnode processed but not from the same group
161
161
  # This logic works only because the prev node are ordered by group/parent ..
@@ -31,22 +31,27 @@ def get_max_version(dict):
31
31
  return max_version
32
32
 
33
33
  def get_versions(name, iterable):
34
- return [n for n in iterable if ((name == 'tricc_end' and isinstance(n, TriccNodeEnd)) or n.name == name) and not isinstance(n, TriccNodeSelectOption)]
34
+ return [n for n in iterable if version_filter(name)(n)]
35
35
 
36
+ def version_filter(name):
37
+ return lambda item: hasattr(item, 'name') and ( (name == 'tricc_end' and isinstance(item, TriccNodeEnd)) or item.name == name ) and not isinstance(item, TriccNodeSelectOption)
36
38
 
37
39
  def get_last_version(name, processed_nodes, _list=None):
38
40
  max_version = None
39
41
  if isinstance(_list, dict):
40
42
  _list = _list[name].values() if name in _list else []
41
43
  if _list is None:
42
- _list = get_versions(name, processed_nodes)
44
+ if isinstance(processed_nodes, OrderedSet):
45
+ return processed_nodes.find_last(version_filter(name))
46
+ else:
47
+ _list = get_versions(name, processed_nodes)
43
48
  if _list:
44
49
  for sim_node in _list:
45
50
  # get the max version while not taking a node that have a next node before next calc
46
51
  if ((max_version is None
47
52
  or max_version.activity.path_len < sim_node.activity.path_len
48
53
  or max_version.path_len < sim_node.path_len
49
- or max_version.path_len == sim_node.path_len and hash(max_version.id) < hash(sim_node.id)
54
+ or (max_version.path_len == sim_node.path_len and hash(max_version.id) < hash(sim_node.id))
50
55
  ) ):
51
56
  max_version = sim_node
52
57
  if not max_version:
@@ -110,24 +115,53 @@ def process_calculate(node,processed_nodes, stashed_nodes, calculates, used_calc
110
115
  ):
111
116
  if kwargs.get('warn', True):
112
117
  logger.debug('Processing relevance for node {0}'.format(node.get_name()))
113
- last_version = get_last_version(node.name, processed_nodes) if issubclass(node.__class__, (TriccNodeDisplayModel)) and not isinstance(node, TriccNodeSelectOption) else None
118
+ last_version = get_last_version(node.name, processed_nodes) if issubclass(node.__class__, (TriccNodeDisplayModel, TriccNodeDisplayCalculateBase)) and not isinstance(node, TriccNodeSelectOption) else None
119
+ #last_version = processed_nodes.find_prev(node, lambda item: hasattr(item, 'name') and item.name == node.name)
114
120
  if last_version:
115
121
  # 0-100 for manually specified instance. 100-200 for auto instance
116
122
  node.version = last_version.version + 1
117
123
  last_version.last = False
118
124
  node.path_len = max(node.path_len, last_version.path_len + 1)
119
125
  # FIXME this is for XLS form where only calculate are evaluated for a activity that is not triggered
120
- if issubclass(node.__class__, (TriccNodeCalculateBase, TriccNodeNote)):
126
+ if not issubclass(node.__class__, (TriccNodeInputModel)):
121
127
  node.last = True
128
+ if (
129
+ issubclass(node.__class__, (TriccNodeDisplayCalculateBase )) and node.name is not None
130
+ ):
131
+ node_name = node.name if not isinstance(node, TriccNodeEnd) else 'tricc_end'
132
+
133
+ #logger.debug("set last to false for node {} and add its link it to next one".format(last_used_calc.get_name()))
134
+ if node.prev_nodes:
135
+ set_prev_next_node(last_version, node)
136
+ else:
137
+ expression = node.expression or node.expression_reference or node.relevance
138
+ datatype = expression.get_datatype()
139
+ if datatype == 'boolean':
140
+ expression_reference = TriccOperation(
141
+ TriccOperator.OR,
142
+ [TriccOperation(TriccOperator.ISTRUE, [last_version]), expression]
143
+ )
144
+
145
+ elif datatype == 'number':
146
+ expression = TriccOperation(
147
+ TriccOperator.PLUS,
148
+ [last_version, expression]
149
+ )
150
+ else:
151
+ expression = TriccOperation(
152
+ TriccOperator.COALESCE,
153
+ [last_version, expression]
154
+ )
155
+ if node.expression:
156
+ node.expression = expression
157
+ elif node.expression_reference:
158
+ node.expression_reference = expression
159
+ elif node.relevance:
160
+ node.relevance = expression
122
161
  else:
123
162
  node.last = False
124
- # versions = get_versions(node.name, processed_nodes)
125
- # if the last version is already a coalesce no need to take all lat version
126
- # if len(versions)>1:
127
- # if issubclass(last_version.__class__, TriccNodeCalculateBase):
128
- # versions = [last_version]
129
- # else:
130
- # logger.warning(f"several version of {node.get_name()} without a coalesce wrap")
163
+
164
+
131
165
  calc = TriccNodeCalculate(
132
166
  id=generate_id(),
133
167
  name=node.name,
@@ -151,8 +185,9 @@ def process_calculate(node,processed_nodes, stashed_nodes, calculates, used_calc
151
185
  last_version
152
186
  ]
153
187
  )
188
+
154
189
 
155
-
190
+
156
191
  # if has prev, create condition
157
192
  if hasattr(node, 'relevance') and (node.relevance is None or isinstance(node.relevance, TriccOperation)):
158
193
  node.relevance = get_node_expressions(node, processed_nodes=processed_nodes)
@@ -182,28 +217,14 @@ def process_calculate(node,processed_nodes, stashed_nodes, calculates, used_calc
182
217
  if issubclass(r.__class__, (TriccNodeDisplayCalculateBase )):
183
218
  add_used_calculate(node, r, calculates, used_calculates, processed_nodes)
184
219
 
185
- generate_calculates(node,calculates, used_calculates,processed_nodes=processed_nodes)
186
- if last_version:
220
+ generate_calculates(node,calculates, used_calculates,processed_nodes=processed_nodes)
221
+ if last_version and hasattr(node, 'relevance'):
187
222
  if isinstance(node, TriccNodeInputModel):
188
223
  version_relevance = TriccOperation(
189
224
  TriccOperator.ISNULL,
190
225
  [last_version]
191
226
  )
192
227
  elif last_version.relevance:
193
- if last_version.activity.relevance:
194
- version_relevance = TriccOperation(
195
- TriccOperator.NOT,
196
- [
197
- TriccOperation(
198
- TriccOperator.AND,
199
- [
200
- last_version.relevance,
201
- last_version.activity.relevance
202
- ]
203
- )
204
- ]
205
- )
206
- else:
207
228
  version_relevance = TriccOperation(
208
229
  TriccOperator.NOT,
209
230
  [
@@ -236,53 +257,6 @@ def process_calculate(node,processed_nodes, stashed_nodes, calculates, used_calc
236
257
  elif hasattr(node, 'relevance'):
237
258
  node.relevance = version_relevance
238
259
 
239
- if (
240
- issubclass(node.__class__, (TriccNodeDisplayCalculateBase )) and node.name is not None
241
- ):
242
- node_name = node.name if not isinstance(node, TriccNodeEnd) else 'tricc_end'
243
- # generate the calc node version by looking in the processed calculate
244
- # TODO the calculates should not be required with the latest version of get_last_version
245
- last_calc = get_last_version(
246
- node_name,
247
- [p for p in processed_nodes if issubclass(p.__class__, (TriccNodeCalculateBase, TriccNodeDisplayCalculateBase))]
248
- )
249
-
250
- # add calculate is added after the version collection so it is 0 in case there is no calc found_ add_calculate(calculates,node)
251
- # merge is there is unused version ->
252
- # current node not yet in the list so 1 item is enough
253
- node_to_delete = None
254
- if last_calc is not None:
255
- node.path_len = max(node.path_len, last_calc.path_len + 1 )
256
- node.version = last_calc.version + 1
257
- #logger.debug("set last to false for node {} and add its link it to next one".format(last_used_calc.get_name()))
258
- if node.prev_nodes:
259
- set_prev_next_node(last_calc,node)
260
- else:
261
- expression = node.expression or node.expression_reference or node.relevance
262
- datatype = expression.get_datatype()
263
- if datatype == 'boolean':
264
- expression_reference = TriccOperation(
265
- TriccOperator.OR,
266
- [TriccOperation(TriccOperator.ISTRUE, [last_calc]), expression]
267
- )
268
-
269
- elif datatype == 'number':
270
- expression = TriccOperation(
271
- TriccOperator.PLUS,
272
- [last_version, expression]
273
- )
274
- else:
275
- expression = TriccOperation(
276
- TriccOperator.COALESCE,
277
- [last_version, expression]
278
- )
279
- if node.expression:
280
- node.expression = expression
281
- elif node.expression_reference:
282
- node.expression_reference = expression
283
- elif node.relevance:
284
- node.relevance = expression
285
- last_calc.last = False
286
260
  #update_calc_version(calculates,node_name)
287
261
  #if hasattr(node, 'next_nodes'):
288
262
  #node.next_nodes=reorder_node_list(node.next_nodes, node.group)
@@ -690,7 +664,7 @@ def process_operation_reference(operation, node, processed_nodes, calculates, us
690
664
  last_found = node_in_act[0]
691
665
  else:
692
666
  last_found = get_last_version(name=ref, processed_nodes=processed_nodes)
693
- if last_found is None:
667
+ if last_found is None:
694
668
  if codesystems:
695
669
  concept = lookup_codesystems_code(codesystems, ref)
696
670
  if not concept:
@@ -974,7 +948,7 @@ def get_data_for_log(node):
974
948
  node.instance)
975
949
 
976
950
  def stashed_node_func(node, callback, recursive=False, **kwargs):
977
- processed_nodes = kwargs.get('processed_nodes', set())
951
+ processed_nodes = kwargs.get('processed_nodes', OrderedSet())
978
952
  stashed_nodes = kwargs.get('stashed_nodes', OrderedSet())
979
953
  path_len = 0
980
954
  walktrhough_tricc_node_processed_stached(node, callback, processed_nodes, stashed_nodes, path_len, recursive,
@@ -1574,7 +1548,7 @@ def export_proposed_diags(activity, diags=None, **kwargs):
1574
1548
  if isinstance(node, TriccNodeActivity):
1575
1549
  diags = export_proposed_diags(node, diags, **kwargs)
1576
1550
  if isinstance(node, TriccNodeProposedDiagnosis):
1577
- if node.last\
1551
+ if node.last is not False\
1578
1552
  and not any([diag.name == node.name for diag in diags]):
1579
1553
  diags.append(node)
1580
1554
  return diags
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tricc-oo
3
- Version: 1.4.4
3
+ Version: 1.4.6
4
4
  Summary: Python library that converts CDSS L2 in L3
5
5
  Project-URL: Homepage, https://github.com/SwissTPH/tricc
6
6
  Project-URL: Issues, https://github.com/SwissTPH/tricc/issues
@@ -9,7 +9,7 @@ Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Operating System :: OS Independent
10
10
  Requires-Python: >=3.8
11
11
  Description-Content-Type: text/markdown
12
- License-File: LICENSE.md
12
+ License-File: LICENSE
13
13
  Requires-Dist: lxml
14
14
  Requires-Dist: html2text
15
15
  Requires-Dist: pydantic
@@ -1,4 +1,4 @@
1
- LICENSE.md
1
+ LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
4
  tests/build.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes