tricc-oo 1.4.4__tar.gz → 1.4.5__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.5}/PKG-INFO +2 -1
  2. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/pyproject.toml +1 -1
  3. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/models/ordered_set.py +33 -0
  4. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/models/tricc.py +1 -1
  5. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/serializers/xls_form.py +1 -0
  6. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/strategies/input/drawio.py +1 -1
  7. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/strategies/output/spice.py +1 -1
  8. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/strategies/output/xls_form.py +1 -1
  9. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/visitors/tricc.py +50 -78
  10. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo.egg-info/PKG-INFO +1 -1
  11. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/LICENSE.md +0 -0
  12. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/README.md +0 -0
  13. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/setup.cfg +0 -0
  14. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tests/build.py +0 -0
  15. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tests/test_cql.py +0 -0
  16. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tests/to_ocl.py +0 -0
  17. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/__init__.py +0 -0
  18. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/converters/__init__.py +0 -0
  19. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/converters/codesystem_to_ocl.py +0 -0
  20. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/converters/cql/cqlLexer.py +0 -0
  21. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/converters/cql/cqlListener.py +0 -0
  22. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/converters/cql/cqlParser.py +0 -0
  23. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/converters/cql/cqlVisitor.py +0 -0
  24. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/converters/cql_to_operation.py +0 -0
  25. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/converters/datadictionnary.py +0 -0
  26. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/converters/drawio_type_map.py +0 -0
  27. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/converters/tricc_to_xls_form.py +0 -0
  28. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/converters/utils.py +0 -0
  29. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/converters/xml_to_tricc.py +0 -0
  30. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/models/__init__.py +0 -0
  31. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/models/base.py +0 -0
  32. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/models/calculate.py +0 -0
  33. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/models/lang.py +0 -0
  34. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/models/ocl.py +0 -0
  35. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/parsers/__init__.py +0 -0
  36. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/parsers/xml.py +0 -0
  37. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/serializers/__init__.py +0 -0
  38. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/serializers/planuml.py +0 -0
  39. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/strategies/__init__.py +0 -0
  40. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/strategies/input/__init__.py +0 -0
  41. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/strategies/input/base_input_strategy.py +0 -0
  42. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/strategies/output/base_output_strategy.py +0 -0
  43. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/strategies/output/xlsform_cdss.py +0 -0
  44. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/strategies/output/xlsform_cht.py +0 -0
  45. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/strategies/output/xlsform_cht_hf.py +0 -0
  46. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/visitors/__init__.py +0 -0
  47. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo/visitors/xform_pd.py +0 -0
  48. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo.egg-info/SOURCES.txt +0 -0
  49. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo.egg-info/dependency_links.txt +0 -0
  50. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/tricc_oo.egg-info/requires.txt +0 -0
  51. {tricc_oo-1.4.4 → tricc_oo-1.4.5}/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.5
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,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tricc-oo"
7
- version = "1.4.4"
7
+ version = "1.4.5"
8
8
  description = "Python library that converts CDSS L2 in L3"
9
9
  readme = "README.md"
10
10
 
@@ -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 ..
@@ -39,14 +39,17 @@ def get_last_version(name, processed_nodes, _list=None):
39
39
  if isinstance(_list, dict):
40
40
  _list = _list[name].values() if name in _list else []
41
41
  if _list is None:
42
- _list = get_versions(name, processed_nodes)
42
+ if isinstance(processed_nodes, OrderedSet):
43
+ return processed_nodes.find_last(lambda item: hasattr(item, 'name') and item.name == name and not isinstance(item, TriccNodeSelectOption))
44
+ else:
45
+ _list = get_versions(name, processed_nodes)
43
46
  if _list:
44
47
  for sim_node in _list:
45
48
  # get the max version while not taking a node that have a next node before next calc
46
49
  if ((max_version is None
47
50
  or max_version.activity.path_len < sim_node.activity.path_len
48
51
  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)
52
+ or (max_version.path_len == sim_node.path_len and hash(max_version.id) < hash(sim_node.id))
50
53
  ) ):
51
54
  max_version = sim_node
52
55
  if not max_version:
@@ -110,24 +113,53 @@ def process_calculate(node,processed_nodes, stashed_nodes, calculates, used_calc
110
113
  ):
111
114
  if kwargs.get('warn', True):
112
115
  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
116
+ last_version = get_last_version(node.name, processed_nodes) if issubclass(node.__class__, (TriccNodeDisplayModel, TriccNodeDisplayCalculateBase)) and not isinstance(node, TriccNodeSelectOption) else None
117
+ #last_version = processed_nodes.find_prev(node, lambda item: hasattr(item, 'name') and item.name == node.name)
114
118
  if last_version:
115
119
  # 0-100 for manually specified instance. 100-200 for auto instance
116
120
  node.version = last_version.version + 1
117
121
  last_version.last = False
118
122
  node.path_len = max(node.path_len, last_version.path_len + 1)
119
123
  # 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)):
124
+ if not issubclass(node.__class__, (TriccNodeInputModel)):
121
125
  node.last = True
126
+ if (
127
+ issubclass(node.__class__, (TriccNodeDisplayCalculateBase )) and node.name is not None
128
+ ):
129
+ node_name = node.name if not isinstance(node, TriccNodeEnd) else 'tricc_end'
130
+
131
+ #logger.debug("set last to false for node {} and add its link it to next one".format(last_used_calc.get_name()))
132
+ if node.prev_nodes:
133
+ set_prev_next_node(last_version, node)
134
+ else:
135
+ expression = node.expression or node.expression_reference or node.relevance
136
+ datatype = expression.get_datatype()
137
+ if datatype == 'boolean':
138
+ expression_reference = TriccOperation(
139
+ TriccOperator.OR,
140
+ [TriccOperation(TriccOperator.ISTRUE, [last_version]), expression]
141
+ )
142
+
143
+ elif datatype == 'number':
144
+ expression = TriccOperation(
145
+ TriccOperator.PLUS,
146
+ [last_version, expression]
147
+ )
148
+ else:
149
+ expression = TriccOperation(
150
+ TriccOperator.COALESCE,
151
+ [last_version, expression]
152
+ )
153
+ if node.expression:
154
+ node.expression = expression
155
+ elif node.expression_reference:
156
+ node.expression_reference = expression
157
+ elif node.relevance:
158
+ node.relevance = expression
122
159
  else:
123
160
  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")
161
+
162
+
131
163
  calc = TriccNodeCalculate(
132
164
  id=generate_id(),
133
165
  name=node.name,
@@ -151,8 +183,9 @@ def process_calculate(node,processed_nodes, stashed_nodes, calculates, used_calc
151
183
  last_version
152
184
  ]
153
185
  )
186
+
154
187
 
155
-
188
+
156
189
  # if has prev, create condition
157
190
  if hasattr(node, 'relevance') and (node.relevance is None or isinstance(node.relevance, TriccOperation)):
158
191
  node.relevance = get_node_expressions(node, processed_nodes=processed_nodes)
@@ -182,28 +215,14 @@ def process_calculate(node,processed_nodes, stashed_nodes, calculates, used_calc
182
215
  if issubclass(r.__class__, (TriccNodeDisplayCalculateBase )):
183
216
  add_used_calculate(node, r, calculates, used_calculates, processed_nodes)
184
217
 
185
- generate_calculates(node,calculates, used_calculates,processed_nodes=processed_nodes)
186
- if last_version:
218
+ generate_calculates(node,calculates, used_calculates,processed_nodes=processed_nodes)
219
+ if last_version and hasattr(node, 'relevance'):
187
220
  if isinstance(node, TriccNodeInputModel):
188
221
  version_relevance = TriccOperation(
189
222
  TriccOperator.ISNULL,
190
223
  [last_version]
191
224
  )
192
225
  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
226
  version_relevance = TriccOperation(
208
227
  TriccOperator.NOT,
209
228
  [
@@ -236,53 +255,6 @@ def process_calculate(node,processed_nodes, stashed_nodes, calculates, used_calc
236
255
  elif hasattr(node, 'relevance'):
237
256
  node.relevance = version_relevance
238
257
 
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
258
  #update_calc_version(calculates,node_name)
287
259
  #if hasattr(node, 'next_nodes'):
288
260
  #node.next_nodes=reorder_node_list(node.next_nodes, node.group)
@@ -690,7 +662,7 @@ def process_operation_reference(operation, node, processed_nodes, calculates, us
690
662
  last_found = node_in_act[0]
691
663
  else:
692
664
  last_found = get_last_version(name=ref, processed_nodes=processed_nodes)
693
- if last_found is None:
665
+ if last_found is None:
694
666
  if codesystems:
695
667
  concept = lookup_codesystems_code(codesystems, ref)
696
668
  if not concept:
@@ -974,7 +946,7 @@ def get_data_for_log(node):
974
946
  node.instance)
975
947
 
976
948
  def stashed_node_func(node, callback, recursive=False, **kwargs):
977
- processed_nodes = kwargs.get('processed_nodes', set())
949
+ processed_nodes = kwargs.get('processed_nodes', OrderedSet())
978
950
  stashed_nodes = kwargs.get('stashed_nodes', OrderedSet())
979
951
  path_len = 0
980
952
  walktrhough_tricc_node_processed_stached(node, callback, processed_nodes, stashed_nodes, path_len, recursive,
@@ -1574,7 +1546,7 @@ def export_proposed_diags(activity, diags=None, **kwargs):
1574
1546
  if isinstance(node, TriccNodeActivity):
1575
1547
  diags = export_proposed_diags(node, diags, **kwargs)
1576
1548
  if isinstance(node, TriccNodeProposedDiagnosis):
1577
- if node.last\
1549
+ if node.last is not False\
1578
1550
  and not any([diag.name == node.name for diag in diags]):
1579
1551
  diags.append(node)
1580
1552
  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.5
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes