mathjson-solver 1.20.0__tar.gz → 1.20.2__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 (114) hide show
  1. mathjson_solver-1.20.2/.claude/settings.local.json +7 -0
  2. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/PKG-INFO +2 -2
  3. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/SECURITY.md +2 -2
  4. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/docs/README.md +2 -2
  5. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/pyproject.toml +1 -1
  6. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/src/mathjson_solver/__main__.py +13 -1
  7. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_datetime.py +14 -0
  8. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_extract_variables.py +1 -0
  9. mathjson_solver-1.20.2/untracked/activity_stuff.json +2156 -0
  10. mathjson_solver-1.20.2/untracked/ehab312.pdf +0 -0
  11. mathjson_solver-1.20.2/untracked/ehab312_supplementary_data/ehab312-suppl_data/Supplementary material_20210604_v2.docx +0 -0
  12. mathjson_solver-1.20.2/untracked/score2-op.json +968 -0
  13. mathjson_solver-1.20.2/untracked/score2.json +976 -0
  14. mathjson_solver-1.20.0/unsorted_uncommited2/NCI_50_CASES_WORKSHEET.md +0 -156
  15. mathjson_solver-1.20.0/unsorted_uncommited2/NCI_AGE35-39_ANALYSIS.md +0 -74
  16. mathjson_solver-1.20.0/unsorted_uncommited2/NCI_AGE35-44_ANALYSIS.md +0 -106
  17. mathjson_solver-1.20.0/unsorted_uncommited2/NCI_COMPARISON_REPORT.md +0 -34
  18. mathjson_solver-1.20.0/unsorted_uncommited2/NCI_COMPLETE_VALIDATION_ANALYSIS.md +0 -198
  19. mathjson_solver-1.20.0/unsorted_uncommited2/NCI_VALIDATION_WORKSHEET.md +0 -53
  20. mathjson_solver-1.20.0/unsorted_uncommited2/R_CODE_VERIFICATION_ANALYSIS.md +0 -214
  21. mathjson_solver-1.20.0/unsorted_uncommited2/corrected_comparison.txt +0 -109
  22. mathjson_solver-1.20.0/unsorted_uncommited2/final_comparison.txt +0 -109
  23. mathjson_solver-1.20.0/unsorted_uncommited2/full_comparison.md +0 -191
  24. mathjson_solver-1.20.0/unsorted_uncommited2/gail_continuous_model_visualization.html +0 -257
  25. mathjson_solver-1.20.0/unsorted_uncommited2/gail_continuous_model_visualization.md +0 -126
  26. mathjson_solver-1.20.0/unsorted_uncommited2/generate_comprehensive_comparison.py +0 -107
  27. mathjson_solver-1.20.0/unsorted_uncommited2/test_interval_analysis.py +0 -61
  28. mathjson_solver-1.20.0/unsorted_uncommited2/updated_comparison.txt +0 -109
  29. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/DESCRIPTION +0 -11
  30. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/NAMESPACE +0 -2
  31. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/R/absolute.risk.R +0 -190
  32. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/R/check.summary.R +0 -27
  33. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/R/error.table.R +0 -50
  34. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/R/error.table.all.R +0 -34
  35. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/R/list.constants.R +0 -23
  36. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/R/recode.check.R +0 -139
  37. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/R/relative.risk.R +0 -51
  38. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/R/risk.summary.R +0 -18
  39. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/data/BrCa_1_AR.rda +0 -0
  40. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/data/BrCa_beta.rda +0 -0
  41. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/data/BrCa_lambda1.rda +0 -0
  42. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/data/BrCa_lambda2.rda +0 -0
  43. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/data/exampledata.rda +0 -0
  44. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/BCRA-package.Rd +0 -65
  45. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/BrCa_1_AR.Rd +0 -22
  46. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/BrCa_beta.Rd +0 -22
  47. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/BrCa_lambda1.Rd +0 -28
  48. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/BrCa_lambda2.Rd +0 -28
  49. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/absolute.risk.Rd +0 -50
  50. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/check.summary.Rd +0 -43
  51. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/error.table.Rd +0 -37
  52. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/error.table.all.Rd +0 -36
  53. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/exampledata.Rd +0 -42
  54. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/list.constants.Rd +0 -35
  55. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/recode.check.Rd +0 -120
  56. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/relative.risk.Rd +0 -45
  57. mathjson_solver-1.20.0/unsorted_uncommitted/BCRA_2.0/BCRA/man/risk.summary.Rd +0 -38
  58. mathjson_solver-1.20.0/unsorted_uncommitted/CLEAN_MODEL_USAGE.md +0 -225
  59. mathjson_solver-1.20.0/unsorted_uncommitted/COSTANTINO1999_RESULTS_TABLE.md +0 -137
  60. mathjson_solver-1.20.0/unsorted_uncommitted/EXACT_PATIENT_EXAMPLES.md +0 -118
  61. mathjson_solver-1.20.0/unsorted_uncommitted/FINAL_IMPLEMENTATION_SUMMARY.md +0 -286
  62. mathjson_solver-1.20.0/unsorted_uncommitted/GAIL_MODEL_IMPLEMENTATION_REPORT.md +0 -107
  63. mathjson_solver-1.20.0/unsorted_uncommitted/INTEGRATION_MODEL_VALIDATION_COMPARISON.md +0 -112
  64. mathjson_solver-1.20.0/unsorted_uncommitted/NCI_VALIDATION_STRATEGY.md +0 -112
  65. mathjson_solver-1.20.0/unsorted_uncommitted/best_so_far/man_test_gail_model_nci_validated_no_beta.py +0 -619
  66. mathjson_solver-1.20.0/unsorted_uncommitted/best_so_far/man_test_nci_discrete_implementation_no_beta.py +0 -480
  67. mathjson_solver-1.20.0/unsorted_uncommitted/gail_continuous_model_mathjson.json +0 -445
  68. mathjson_solver-1.20.0/unsorted_uncommitted/publications/costantino_1999.pdf +0 -0
  69. mathjson_solver-1.20.0/unsorted_uncommitted/publications/gail_1989.pdf +0 -0
  70. mathjson_solver-1.20.0/unsorted_uncommitted/tests/generate_exact_patient_examples.py +0 -423
  71. mathjson_solver-1.20.0/unsorted_uncommitted/tests/test_bcpt_validation_integration.py +0 -268
  72. mathjson_solver-1.20.0/unsorted_uncommitted/tests/test_gail_approximated_model_nci_validated.py +0 -409
  73. mathjson_solver-1.20.0/unsorted_uncommitted/tests/test_gail_exact_nci_implementation.py +0 -519
  74. mathjson_solver-1.20.0/unsorted_uncommitted/tests/test_gail_exact_with_cumulative.py +0 -387
  75. mathjson_solver-1.20.0/unsorted_uncommitted/tests/test_gail_exact_with_reduce.py +0 -332
  76. mathjson_solver-1.20.0/unsorted_uncommitted/tests/test_gail_model_costantino_integration.py +0 -553
  77. mathjson_solver-1.20.0/unsorted_uncommitted/tests/test_gail_model_nci_validated_fixed.py +0 -558
  78. mathjson_solver-1.20.0/unsorted_uncommitted/tests/test_nci_calculator_validation.py +0 -289
  79. mathjson_solver-1.20.0/unsorted_uncommitted/tests/test_patient_examples_comparison.py +0 -319
  80. mathjson_solver-1.20.0/untracked/chart.csv +0 -17
  81. mathjson_solver-1.20.0/untracked/cvd_risk.json +0 -509
  82. mathjson_solver-1.20.0/untracked/image.png +0 -0
  83. mathjson_solver-1.20.0/untracked/score2.csv +0 -49
  84. mathjson_solver-1.20.0/untracked/score2_mid.csv +0 -49
  85. mathjson_solver-1.20.0/untracked/score2_results2.xlsx +0 -0
  86. mathjson_solver-1.20.0/untracked/score2_table.py +0 -121
  87. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  88. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/.github/workflows/python-app.yml +0 -0
  89. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/.github/workflows/test-coverage.yml +0 -0
  90. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/.gitignore +0 -0
  91. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/CODE_OF_CONDUCT.md +0 -0
  92. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/CONTRIBUTING.md +0 -0
  93. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/LICENSE +0 -0
  94. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/README.md +0 -0
  95. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/docs/integration-test-cases.md +0 -0
  96. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/logo.png +0 -0
  97. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/logo.svg +0 -0
  98. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/src/mathjson_solver/__init__.py +0 -0
  99. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_TrapezoidalIntegratel.py +0 -0
  100. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_atindex.py +0 -0
  101. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_cumulative.py +0 -0
  102. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_equal.py +0 -0
  103. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_exceptions.py +0 -0
  104. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_findinterval.py +0 -0
  105. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_gail_model.py +0 -0
  106. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_interpolate.py +0 -0
  107. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_range.py +0 -0
  108. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_reduce_simple.py +0 -0
  109. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_scalars.py +0 -0
  110. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_sets.py +0 -0
  111. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_simple_cases.py +0 -0
  112. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_slice.py +0 -0
  113. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_state_tuples_reduce.py +0 -0
  114. {mathjson_solver-1.20.0 → mathjson_solver-1.20.2}/tests/test_with_pytest.py +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(grep -n \"^OPERATORS\\\\|^operators\\\\|: solve_\\\\|'.*':\\\\s*$\\\\|def solve_\" /home/martins/workspace/longenesis/mathjson-solver/src/mathjson_solver/__main__.py)"
5
+ ]
6
+ }
7
+ }
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: mathjson-solver
3
- Version: 1.20.0
3
+ Version: 1.20.2
4
4
  Summary: Utilities for MathJSON evaluation
5
5
  Project-URL: Homepage, https://github.com/LongenesisLtd/mathjson-solver
6
6
  Project-URL: Bug Tracker, https://github.com/LongenesisLtd/mathjson-solver/issues
@@ -5,8 +5,8 @@
5
5
 
6
6
  | Version | Supported |
7
7
  | ------- | ------------------ |
8
- | 1.13.x | :white_check_mark: |
9
- | < 1.13.x | :x: |
8
+ | 1.20.x | :white_check_mark: |
9
+ | < 1.20.x | :x: |
10
10
 
11
11
 
12
12
  ## Reporting a Vulnerability
@@ -327,7 +327,7 @@ If a constant definition raises an exception (e.g. because a referenced paramete
327
327
  # Result: 11.25 (c_old was never needed)
328
328
  ```
329
329
 
330
- A constant that failed to compute can be detected with `["Equal", "c_old", None]`.
330
+ A constant that failed to compute resolves to `None`, which is falsy. Use `["IsFalse", "c_old"]` to detect it (or `["IsTrue", "c_old"]` to confirm it computed successfully).
331
331
 
332
332
  ### If Statement
333
333
  ```
@@ -824,7 +824,7 @@ The logical complement of `IsDefined`. Returns `True` if the name is not defined
824
824
  ["Constants", ["x", 5], ["IsUndefined", "y"]] # True
825
825
  ```
826
826
 
827
- Note: when a `Constants` definition raises an exception, that constant is set to `None` (see null-propagation below). In that case `IsUndefined` still returns `False` — the name is defined, just with a `None` value. Use `["Equal", "val", None]` to test for that explicitly.
827
+ Note: when a `Constants` definition raises an exception, that constant is set to `None` (see null-propagation below). In that case `IsUndefined` still returns `False` — the name is defined, just with a `None` value. Use `["IsFalse", "val"]` to detect a failed constant (since `None` is falsy).
828
828
 
829
829
  ---
830
830
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "mathjson-solver"
7
- version = "1.20.0"
7
+ version = "1.20.2"
8
8
  authors = [{name = "Martins Mednis", email = "mrt@mednis.info"}]
9
9
  description = "Utilities for MathJSON evaluation"
10
10
  readme = "README.md"
@@ -617,6 +617,8 @@ def create_mathjson_solver(solver_parameters):
617
617
 
618
618
  def Strftime(s):
619
619
  dt = _try_parse_datetime(f(s[1], c))
620
+ if not isinstance(dt, (datetime.datetime, datetime.date)):
621
+ raise ValueError(f"Strftime: could not parse input as datetime: {dt!r}")
620
622
  parameters = f(s[2], c)
621
623
  return dt.strftime(parameters)
622
624
 
@@ -1233,11 +1235,18 @@ def extract_variables(s: Union[list, int, float, str], li: set, ignore_list: set
1233
1235
  "ContainsNoneOf",
1234
1236
  "Int",
1235
1237
  "Float",
1238
+ "Floor",
1239
+ "Ceil",
1236
1240
  "Str",
1237
1241
  "Not",
1238
1242
  "IsDefined",
1239
1243
  "IsUndefined",
1244
+ "StrictEqual",
1245
+ "NotEqual",
1246
+ "StrictSwitch",
1240
1247
  "Map",
1248
+ "StrictMap",
1249
+ "Filter",
1241
1250
  "HasMatchingSublist",
1242
1251
  "Strptime",
1243
1252
  "Strftime",
@@ -1259,10 +1268,13 @@ def extract_variables(s: Union[list, int, float, str], li: set, ignore_list: set
1259
1268
  "AtIndex",
1260
1269
  "Slice",
1261
1270
  "CumulativeProduct",
1271
+ "CumulativeSum",
1262
1272
  "Interp",
1263
1273
  "FindIntervalIndex",
1264
1274
  "TrapezoidalIntegrate",
1265
1275
  "TrapezoidalIntegrate",
1276
+ "Reduce",
1277
+ "Appended",
1266
1278
  "Sin",
1267
1279
  "Cos",
1268
1280
  "Tan",
@@ -1282,7 +1294,7 @@ def extract_variables(s: Union[list, int, float, str], li: set, ignore_list: set
1282
1294
  for x in s[1:-1]:
1283
1295
  ignore_list.add(x[0])
1284
1296
  li.update(extract_variables(x[1], li, ignore_list))
1285
- li.update(extract_variables(x[-1], li, ignore_list))
1297
+ li.update(extract_variables(s[-1], li, ignore_list))
1286
1298
  elif s[0] == "If":
1287
1299
  for elif_block in s[1:-1]: # s[1] is list
1288
1300
  for x in elif_block:
@@ -134,6 +134,20 @@ class TestStrftime:
134
134
  result = solver(["Strftime", "2025-06-15T14:30:45", "%Y-%m-%d %H:%M:%S"])
135
135
  assert result == "2025-06-15 14:30:45"
136
136
 
137
+ def test_strftime_raises_on_unparseable_input(self):
138
+ """Strftime must raise MathJSONException (not AttributeError) for unparseable input."""
139
+ from mathjson_solver import MathJSONException
140
+ solver = create_solver({})
141
+ with pytest.raises(MathJSONException):
142
+ solver(["Strftime", "not-a-date", "%Y-%m-%d"])
143
+
144
+ def test_strftime_raises_on_none_input(self):
145
+ """Strftime must raise MathJSONException when input resolves to None."""
146
+ from mathjson_solver import MathJSONException
147
+ solver = create_solver({})
148
+ with pytest.raises(MathJSONException):
149
+ solver(["Strftime", None, "%Y-%m-%d"])
150
+
137
151
 
138
152
  class TestDatetimeChaining:
139
153
  """Test complex datetime operation chains."""
@@ -15,6 +15,7 @@ from mathjson_solver import extract_variables
15
15
  ({"a": 5}, ["Sum", 2, "a", 3], set()),
16
16
  ({"a": 5, "b": 6}, ["Sum", 2, "a", "c"], set(["c"])),
17
17
  ({}, ["Constants", ["c", 1], ["d", ["Add", 2, "a"]], "d"], set(["a"])),
18
+ ({}, ["Constants", ["c", 1], ["b", ["Add", 2, "a"]], "d"], set(["a", "d"])),
18
19
  # Now with "ugly" variables that mimic the ones used for deep referencing.
19
20
  (
20
21
  {},