tricc-oo 1.5.16__tar.gz → 1.5.19__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.5.16 → tricc_oo-1.5.19}/PKG-INFO +1 -1
  2. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/pyproject.toml +1 -1
  3. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tests/test_cql.py +17 -7
  4. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/converters/cql_to_operation.py +10 -4
  5. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/converters/drawio_type_map.py +2 -3
  6. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/models/base.py +33 -4
  7. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/serializers/xls_form.py +1 -1
  8. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/strategies/output/base_output_strategy.py +4 -0
  9. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/strategies/output/xls_form.py +8 -1
  10. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/visitors/tricc.py +41 -20
  11. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo.egg-info/PKG-INFO +1 -1
  12. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/README.md +0 -0
  13. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/setup.cfg +0 -0
  14. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tests/build.py +0 -0
  15. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tests/to_ocl.py +0 -0
  16. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/__init__.py +0 -0
  17. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/converters/__init__.py +0 -0
  18. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/converters/codesystem_to_ocl.py +0 -0
  19. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/converters/cql/cqlLexer.py +0 -0
  20. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/converters/cql/cqlListener.py +0 -0
  21. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/converters/cql/cqlParser.py +0 -0
  22. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/converters/cql/cqlVisitor.py +0 -0
  23. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/converters/datadictionnary.py +0 -0
  24. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/converters/tricc_to_xls_form.py +0 -0
  25. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/converters/utils.py +0 -0
  26. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/converters/xml_to_tricc.py +0 -0
  27. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/models/__init__.py +0 -0
  28. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/models/calculate.py +0 -0
  29. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/models/lang.py +0 -0
  30. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/models/ocl.py +0 -0
  31. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/models/ordered_set.py +0 -0
  32. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/models/tricc.py +0 -0
  33. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/parsers/__init__.py +0 -0
  34. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/parsers/xml.py +0 -0
  35. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/serializers/__init__.py +0 -0
  36. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/serializers/planuml.py +0 -0
  37. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/strategies/__init__.py +0 -0
  38. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/strategies/input/__init__.py +0 -0
  39. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/strategies/input/base_input_strategy.py +0 -0
  40. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/strategies/input/drawio.py +0 -0
  41. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/strategies/output/spice.py +0 -0
  42. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/strategies/output/xlsform_cdss.py +0 -0
  43. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/strategies/output/xlsform_cht.py +0 -0
  44. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/strategies/output/xlsform_cht_hf.py +0 -0
  45. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/visitors/__init__.py +0 -0
  46. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/visitors/utils.py +0 -0
  47. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo/visitors/xform_pd.py +0 -0
  48. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo.egg-info/SOURCES.txt +0 -0
  49. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo.egg-info/dependency_links.txt +0 -0
  50. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/tricc_oo.egg-info/requires.txt +0 -0
  51. {tricc_oo-1.5.16 → tricc_oo-1.5.19}/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.5.16
3
+ Version: 1.5.19
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tricc-oo"
7
- version = "1.5.16"
7
+ version = "1.5.19"
8
8
  description = "Python library that converts CDSS L2 in L3"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -11,13 +11,8 @@ class TestCql(unittest.TestCase):
11
11
  operator=TriccOperator.AND,
12
12
  reference=[
13
13
  TriccOperation(
14
- operator=TriccOperator.NOT,
15
- reference=[
16
- TriccOperation(
17
- operator=TriccOperator.ISNULL,
18
- reference=[TriccReference("p_weight")]
19
- )
20
- ]
14
+ operator=TriccOperator.ISNOTNULL,
15
+ reference=[TriccReference("p_weight")]
21
16
  ),
22
17
  TriccOperation(
23
18
  operator=TriccOperator.MORE,
@@ -46,6 +41,21 @@ class TestCql(unittest.TestCase):
46
41
  )
47
42
  self.assertEqual(str(dg_operation), str(dg_expected))
48
43
 
44
+ def test_implied_concat(self):
45
+ if_cql = "'A' & \"B\" & 'C'"
46
+ cc_operation = transform_cql_to_operation(if_cql)
47
+ cc_expected = TriccOperation(
48
+ operator=TriccOperator.CONCATENATE,
49
+ reference=[
50
+ TriccStatic(value='A'),
51
+ TriccReference("B"),
52
+ TriccStatic(value='C')
53
+ ]
54
+ )
55
+ self.assertEqual(str(cc_operation), str(cc_expected))
56
+
57
+
58
+
49
59
  def test_if(self):
50
60
  if_cql = "if AgeInDays() < 60 then 'newborn' else 'child'"
51
61
  if_operation = transform_cql_to_operation(if_cql)
@@ -3,7 +3,7 @@ from tricc_oo.converters.cql.cqlLexer import cqlLexer
3
3
  from tricc_oo.converters.cql.cqlParser import cqlParser
4
4
  from tricc_oo.converters.cql.cqlVisitor import cqlVisitor
5
5
  from tricc_oo.converters.utils import clean_name
6
- from tricc_oo.models.base import TriccOperator, TriccOperation, TriccStatic, TriccReference, not_clean, or_join, and_join
6
+ from tricc_oo.models.base import TriccOperator, TriccOperation, TriccStatic, TriccReference, not_clean, or_join, and_join, string_join
7
7
  import logging
8
8
 
9
9
  logger = logging.getLogger("default")
@@ -21,8 +21,10 @@ FUNCTION_MAP = {
21
21
  'Concatenate': TriccOperator.CONCATENATE,
22
22
  'Izscore': TriccOperator.IZSCORE,
23
23
  'Zscore': TriccOperator.ZSCORE,
24
+ 'Round': TriccOperator.ROUND,
24
25
  'DrugDosage': TriccOperator.DRUG_DOSAGE,
25
26
  'HasQualifier': TriccOperator.HAS_QUALIFIER,
27
+ 'DateTimeToDecimal' : TriccOperator.DATETIME_TO_DECIMAL
26
28
  }
27
29
  # TODO
28
30
  # Min
@@ -214,7 +216,11 @@ class cqlToXlsFormVisitor(cqlVisitor):
214
216
  if operator == TriccOperator.AND:
215
217
  return and_join([left, right])
216
218
  elif operator == TriccOperator.OR:
217
- return or_join([left, right])
219
+ return or_join([left, right])
220
+ elif operator == TriccOperator.CONCATENATE:
221
+ left = "" if left is None else left
222
+ right = "" if right is None else right
223
+ return string_join(left, right)
218
224
  else:
219
225
  op = TriccOperation(operator, [left, right])
220
226
  return op
@@ -285,10 +291,10 @@ class cqlToXlsFormVisitor(cqlVisitor):
285
291
  op_map = {
286
292
  '+': TriccOperator.PLUS,
287
293
  '-': TriccOperator.MINUS,
288
- '&': TriccOperator.AND
294
+ '&': TriccOperator.CONCATENATE
289
295
  }
290
296
  return self.__std_operator(op_map.get(op_text), ctx)
291
-
297
+
292
298
 
293
299
  def visitTypeExpression(self, ctx):
294
300
  to_type = ctx.getChild(2).getText()
@@ -45,7 +45,6 @@ TYPE_MAP = {
45
45
  "constraint_message",
46
46
  "relevance",
47
47
  "priority", "trigger", "default"
48
-
49
48
  ],
50
49
  "mandatory_attributes": ["label", "name", "list_name"],
51
50
  "model": TriccNodeSelectOne
@@ -99,13 +98,13 @@ TYPE_MAP = {
99
98
 
100
99
  TriccNodeType.text: {
101
100
  "objects": ["UserObject", "object"],
102
- "attributes": ["save", "relevance","priority", "trigger", "default"],
101
+ "attributes": ["save", "relevance","priority", "trigger", "default", "constraint", "constraint_message"],
103
102
  "mandatory_attributes": ["label", 'name'],
104
103
  "model": TriccNodeText
105
104
  },
106
105
  TriccNodeType.date: {
107
106
  "objects": ["UserObject", "object"],
108
- "attributes": ["save", "relevance","priority", "trigger", "default"],
107
+ "attributes": ["save", "relevance","priority", "trigger", "default", "constraint", "constraint_message"],
109
108
  "mandatory_attributes": ["label", "name"],
110
109
  "model": TriccNodeDate
111
110
  },
@@ -336,7 +336,8 @@ class TriccReference(TriccStatic):
336
336
 
337
337
  class TriccOperator(StrEnum):
338
338
  AND = 'and' # and between left and rights
339
- ADD_OR = 'and_or' # left and one of the righs
339
+ ADD_OR = 'and_or' # left and one of the righs
340
+ #ADD_STRING: 'add_string'
340
341
  OR = 'or' # or between left and rights
341
342
  NATIVE = 'native' #default left is native expression
342
343
  ISTRUE = 'istrue' # left is right
@@ -357,6 +358,7 @@ class TriccOperator(StrEnum):
357
358
  NOT = 'not'
358
359
  ISNULL = 'isnull'
359
360
  ISNOTNULL= 'isnotnull'
361
+ ROUND = 'round'
360
362
 
361
363
  CASE = 'case' # ref (equal value, res), (equal value,res)
362
364
  IFS = 'ifs' #(cond, res), (cond,res)
@@ -364,7 +366,6 @@ class TriccOperator(StrEnum):
364
366
 
365
367
  # CDSS Specific
366
368
  HAS_QUALIFIER = 'has_qualifier'
367
-
368
369
  ZSCORE = 'zscore' # left table_name, right Y, gender give Z
369
370
  IZSCORE = 'izscore' #left table_name, right Z, gender give Y
370
371
  AGE_DAY = 'age_day' # age from dob
@@ -383,6 +384,7 @@ class TriccOperator(StrEnum):
383
384
  CAST_DATE = 'cast_date'
384
385
  PARENTHESIS = 'parenthesis'
385
386
  CONCATENATE = 'concatenate'
387
+ DATETIME_TO_DECIMAL = 'datetime_to_decimal'
386
388
 
387
389
  RETURNS_BOOLEAN =[
388
390
  TriccOperator.ADD_OR,
@@ -414,6 +416,8 @@ RETURNS_NUMBER = [
414
416
  TriccOperator.AGE_YEAR,
415
417
  TriccOperator.ZSCORE,
416
418
  TriccOperator.IZSCORE,
419
+ TriccOperator.ROUND,
420
+ TriccOperator.DATETIME_TO_DECIMAL,
417
421
  TriccOperator.PLUS,
418
422
  TriccOperator.MINUS,
419
423
  TriccOperator.DIVIDED,
@@ -456,7 +460,8 @@ class TriccOperation(BaseModel):
456
460
  return hash(self.__repr__())
457
461
 
458
462
  def __repr__(self):
459
- return "TriccOperation:"+self.__str__()
463
+ str_ref = map(repr, self.reference)
464
+ return f"TriccOperation:{self.operator}({', '.join(map(str, str_ref))})"
460
465
 
461
466
  def __eq__(self, other):
462
467
  return self.__str__() == str(other)
@@ -658,7 +663,7 @@ def clean_or_list(list_or, elm_and=None):
658
663
  if len(list_or) == 0:
659
664
  return []
660
665
 
661
- return sorted(list(set(list_or)), key=str)
666
+ return sorted(list(set(list_or)), key=repr)
662
667
 
663
668
  def and_join(argv):
664
669
  argv=clean_and_list(argv)
@@ -671,6 +676,30 @@ def and_join(argv):
671
676
  TriccOperator.AND,
672
677
  argv
673
678
  )
679
+
680
+
681
+ def string_join(left: Union[str, TriccOperation], right: Union[str, TriccOperation]) -> TriccOperation:
682
+ """
683
+ Concatenates two arguments (strings or TriccOperation) into a TriccOperation with CONCATENATE operator.
684
+ If either argument is a TriccOperation with CONCATENATE operator, its operands are merged into the result.
685
+ """
686
+ # Initialize operands list for the new TriccOperation
687
+ operands: List[Union[str, TriccOperation]] = []
688
+
689
+ # Check if left is a TriccOperation with CONCATENATE
690
+ if isinstance(left, TriccOperation) and left.operator == TriccOperator.CONCATENATE:
691
+ operands.extend(left.reference) # Merge left's operands
692
+ else:
693
+ operands.append(left) # Add left as-is
694
+
695
+ # Check if right is a TriccOperation with CONCATENATE
696
+ if isinstance(right, TriccOperation) and right.operator == TriccOperator.CONCATENATE:
697
+ operands.extend(right.reference) # Merge right's operands
698
+ else:
699
+ operands.append(right) # Add right as-is
700
+
701
+ # Return a new TriccOperation with the merged operands
702
+ return TriccOperation(operator=TriccOperator.CONCATENATE, reference=operands)
674
703
 
675
704
  # function that make a 2 part and
676
705
  # @param left part
@@ -264,7 +264,7 @@ def get_xfrom_trad(strategy, node, column, mapping, clean_html=False):
264
264
  issubclass(node.__class__, TriccNodeDisplayCalculateBase)
265
265
  and column == "calculation"
266
266
  and isinstance(value, str)
267
- and not value.startswith("number")
267
+ and not (value.startswith("number") or value.startswith("round"))
268
268
  and getattr(node, "expression", None)
269
269
  and node.expression.get_datatype() in ("number", "boolean")
270
270
  ):
@@ -131,6 +131,10 @@ class BaseOutPutStrategy:
131
131
  raise NotImplementedError(f"This type of opreration is not supported in this strategy")
132
132
  def tricc_operation_zscore(self, ref_expressions):
133
133
  raise NotImplementedError(f"This type of opreration is not supported in this strategy")
134
+ def tricc_operation_datetime_to_decimal(self, ref_expressions):
135
+ raise NotImplementedError(f"This type of opreration is not supported in this strategy")
136
+ def tricc_operation_round(self, ref_expressions):
137
+ raise NotImplementedError(f"This type of opreration is not supported in this strategy")
134
138
  def tricc_operation_izscore(self, ref_expressions):
135
139
  raise NotImplementedError(f"This type of opreration is not supported in this strategy")
136
140
  def tricc_operation_age_day(self, ref_expressions):
@@ -569,6 +569,13 @@ class XLSFormStrategy(BaseOutPutStrategy):
569
569
  # return ((Math.pow((y / m), l) - 1) / (s * l));
570
570
  return f"(pow({y} div ({m}), {ll}) -1) div (({s}) div ({ll}))"
571
571
 
572
+ def tricc_operation_datetime_to_decimal(self, ref_expressions):
573
+ return f"decimal-date-time({ref_expressions[0]})"
574
+
575
+ def tricc_operation_round(self, ref_expressions):
576
+ return f"round({ref_expressions[0]})"
577
+
578
+
572
579
 
573
580
  def tricc_operation_izscore(self, ref_expressions):
574
581
  z, ll, m, s = self.get_zscore_params(ref_expressions)
@@ -671,7 +678,7 @@ class XLSFormStrategy(BaseOutPutStrategy):
671
678
  if isinstance(r, TriccOperation):
672
679
  return self.get_tricc_operation_expression(r)
673
680
  elif isinstance(r, TriccReference):
674
- logger.warning(f"reference still used in the calculate {r.value}")
681
+ logger.warning(f"reference `{r.value}` still used in a calculate")
675
682
  return f"${{{get_export_name(r.value)}}}"
676
683
  elif isinstance(r, TriccStatic):
677
684
  if isinstance(r.value, bool) :#or r.value in ('true', 'false')
@@ -607,6 +607,21 @@ def process_reference(node, processed_nodes, calculates, used_calculates=None,
607
607
  return False
608
608
  elif modified_expression and replace_reference:
609
609
  node.trigger = modified_expression
610
+ if isinstance(getattr(node, 'constraint', None), (TriccOperation, TriccReference)):
611
+ modified_expression = process_operation_reference(
612
+ node.constraint,
613
+ node,
614
+ processed_nodes=processed_nodes,
615
+ calculates=calculates,
616
+ used_calculates=used_calculates,
617
+ replace_reference=replace_reference,
618
+ warn=warn,
619
+ codesystems=codesystems
620
+ )
621
+ if modified_expression is False:
622
+ return False
623
+ elif modified_expression and replace_reference:
624
+ node.constraint = modified_expression
610
625
 
611
626
  if isinstance(getattr(node, 'default', None), (TriccOperation, TriccReference)):
612
627
  modified_expression = process_operation_reference(
@@ -1675,26 +1690,32 @@ def get_prev_instance_skip_expression(node, processed_nodes, process, expression
1675
1690
 
1676
1691
  # end def
1677
1692
  def get_process_skip_expression(node, processed_nodes, process, expression=None):
1678
-
1679
- end_expressions = []
1680
- f_end_expression = get_end_expression(processed_nodes)
1681
- if f_end_expression:
1682
- end_expressions.append(f_end_expression)
1683
- b_end_expression = get_end_expression(processed_nodes, 'pause')
1684
- if b_end_expression:
1685
- end_expressions.append(b_end_expression)
1686
- if process[0] in PROCESSES:
1687
- for p in PROCESSES[PROCESSES.index(process[0])+1:]:
1688
- p_end_expression = get_end_expression(processed_nodes, p)
1689
- if p_end_expression:
1690
- end_expressions.append(p_end_expression)
1691
- if end_expressions:
1692
- if expression:
1693
- end_expressions.append(expression)
1694
- if len(end_expressions) == 1:
1695
- expression = end_expressions[0]
1696
- else:
1697
- expression = and_join(end_expressions)
1693
+ list_ends = OrderedSet(
1694
+ filter(
1695
+ lambda x: issubclass(x.__class__, TriccNodeEnd),
1696
+ processed_nodes
1697
+ )
1698
+ )
1699
+ if list_ends:
1700
+ end_expressions = []
1701
+ f_end_expression = get_end_expression(list_ends)
1702
+ if f_end_expression:
1703
+ end_expressions.append(f_end_expression)
1704
+ b_end_expression = get_end_expression(list_ends, 'pause')
1705
+ if b_end_expression:
1706
+ end_expressions.append(b_end_expression)
1707
+ if process[0] in PROCESSES:
1708
+ for p in PROCESSES[PROCESSES.index(process[0])+1:]:
1709
+ p_end_expression = get_end_expression(list_ends, p)
1710
+ if p_end_expression:
1711
+ end_expressions.append(p_end_expression)
1712
+ if end_expressions:
1713
+ if expression:
1714
+ end_expressions.append(expression)
1715
+ if len(end_expressions) == 1:
1716
+ expression = end_expressions[0]
1717
+ else:
1718
+ expression = and_join(end_expressions)
1698
1719
  return expression
1699
1720
 
1700
1721
  def get_end_expression(processed_nodes, process=None):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tricc-oo
3
- Version: 1.5.16
3
+ Version: 1.5.19
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