mathjson-solver 1.13.0__tar.gz → 1.15.0__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.
@@ -0,0 +1,166 @@
1
+ Metadata-Version: 2.4
2
+ Name: mathjson-solver
3
+ Version: 1.15.0
4
+ Summary: Utilities for MathJSON evaluation
5
+ Home-page: https://github.com/LongenesisLtd/mathjson-solver
6
+ Author: Martins Mednis
7
+ Author-email: mrt@mednis.info
8
+ Project-URL: Bug Tracker, https://github.com/LongenesisLtd/mathjson-solver/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.6
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Dynamic: author
16
+ Dynamic: author-email
17
+ Dynamic: classifier
18
+ Dynamic: description
19
+ Dynamic: description-content-type
20
+ Dynamic: home-page
21
+ Dynamic: license-file
22
+ Dynamic: project-url
23
+ Dynamic: requires-python
24
+ Dynamic: summary
25
+
26
+ # MathJSON Solver
27
+
28
+ [![PyPI](https://img.shields.io/pypi/v/mathjson-solver.svg)](https://pypi.org/project/mathjson-solver/)
29
+ [![PyPI Downloads](https://static.pepy.tech/badge/mathjson-solver/month)](https://pepy.tech/projects/mathjson-solver)
30
+ [![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)
31
+
32
+ A reliable Python library for numerically evaluating mathematical expressions in MathJSON format. Perfect for applications that need to safely execute user-provided formulas, calculate dynamic equations, or process mathematical data.
33
+
34
+ **What is MathJSON?** MathJSON represents mathematical expressions as JSON arrays, like `["Add", 1, 2, 3]` for 1+2+3. This format is safe, structured, and easy to generate programmatically.
35
+
36
+ Inspired by [CortexJS Compute Engine](https://cortexjs.io/compute-engine/) though designed as an independent implementation focused on our specific use cases.
37
+
38
+ ## Table of Contents
39
+ - [Installation](#installation)
40
+ - [Quick Start](#quick-start)
41
+ - [Supported Operations](#supported-operations)
42
+ - [Error Handling](#error-handling)
43
+ - [Use Cases](#use-cases)
44
+ - [Testing](#testing)
45
+ - [Community](#community)
46
+ - [Contributing](#contributing)
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ pip install mathjson-solver
52
+ ```
53
+
54
+ **Requirements:** Python 3.7+
55
+
56
+ **Optional:** numpy (only required for `TrapezoidalIntegrate` function)
57
+
58
+ ## Quick Start
59
+
60
+ ```python
61
+ from mathjson_solver import create_solver, MathJSONException
62
+
63
+ # Define variables and create solver
64
+ parameters = {"x": 2, "y": 3}
65
+ solver = create_solver(parameters)
66
+
67
+ # Evaluate expressions
68
+ basic_math = solver(["Add", "x", "y", 4])
69
+ print(basic_math) # 9 (because 2+3+4=9)
70
+
71
+ # More complex expressions
72
+ result = solver(["Multiply", ["Add", "x", 1], ["Subtract", "y", 1]])
73
+ print(result) # 6 (because (2+1) * (3-1) = 6)
74
+
75
+ # Handle errors gracefully
76
+ try:
77
+ solver(["Divide", 1, 0])
78
+ except MathJSONException as e:
79
+ print(f"Math error: {e}")
80
+ # Math error: Problem in Divide. ['Divide', 1, 0]. division by zero
81
+ ```
82
+
83
+ ## Supported Operations
84
+
85
+ The library supports a comprehensive set of mathematical operations:
86
+
87
+ * **Arithmetic:** Add, Sum, Subtract, Multiply, Divide, Negate, Power, Square, Root, Sqrt, Abs, Round
88
+ * **Trigonometry:** Sin, Cos, Tan, Arcsin, Arccos, Arctan
89
+ * **Logarithms:** Log, Log2, Log10, Exp
90
+ * **Comparison:** Equal, StrictEqual, NotEqual, Greater, GreaterEqual, Less, LessEqual
91
+ * **Logic & Sets:** Any, All, Not, In, NotIn, ContainsAnyOf, ContainsAllOf, ContainsNoneOf
92
+ * **Statistics:** Average, Max, Min, Median, Length
93
+ * **Arrays:** Array creation and manipulation with Map function
94
+ * **Control Flow:** If statements, Switch-Case, Constants definition
95
+ * **Type Conversion:** Int, Float, Str, IsDefined
96
+ * **Date/Time:** Strptime, Strftime, Today, Now, TimeDelta functions
97
+ * **Advanced:** HasMatchingSublist, TrapezoidalIntegrate (requires numpy), Variable references
98
+ * **Constants:** Pi
99
+
100
+ [View complete documentation with examples →](https://github.com/LongenesisLtd/mathjson-solver/blob/main/docs/README.md)
101
+
102
+ ## Error Handling
103
+
104
+ MathJSON Solver raises `MathJSONException` for invalid expressions or mathematical errors:
105
+
106
+ ```python
107
+ from mathjson_solver import create_solver, MathJSONException
108
+
109
+ solver = create_solver({})
110
+
111
+ # Handle specific math errors
112
+ try:
113
+ result = solver(["Sqrt", -1]) # Invalid: square root of negative
114
+ except MathJSONException as e:
115
+ print(f"Cannot evaluate: {e}")
116
+
117
+ # Handle malformed expressions
118
+ try:
119
+ result = solver(["UnknownFunction", 1, 2])
120
+ except MathJSONException as e:
121
+ print(f"Unsupported operation: {e}")
122
+ ```
123
+
124
+ ## Use Cases
125
+
126
+ * **Dynamic Formulas:** Let users create custom calculations in web applications
127
+ * **Scientific Computing:** Evaluate mathematical models with variable parameters
128
+ * **Business Logic:** Process complex pricing rules or scoring algorithms
129
+ * **Data Processing:** Apply mathematical transformations to datasets
130
+ * **Health Applications:** Calculate medical scores, dosages, or risk assessments
131
+
132
+ ## Testing
133
+
134
+ Install development dependencies and run tests:
135
+
136
+ ```bash
137
+ # Install pytest if not already installed
138
+ pip install pytest
139
+
140
+ # Run tests from project directory
141
+ pytest
142
+
143
+ # Run with coverage
144
+ pytest --cov=mathjson_solver
145
+ ```
146
+
147
+ ## Community
148
+
149
+ - **Questions & Discussion:** [GitHub Issues](https://github.com/LongenesisLtd/mathjson-solver/issues)
150
+ - **Bug Reports & Feature Requests:** [GitHub Issues](https://github.com/LongenesisLtd/mathjson-solver/issues)
151
+ - **Documentation:** [Complete Function Reference](https://github.com/LongenesisLtd/mathjson-solver/blob/main/docs/README.md)
152
+
153
+ ## Contributing
154
+
155
+ We welcome contributions! Please feel free to:
156
+ - Report bugs or request features via [GitHub Issues](https://github.com/LongenesisLtd/mathjson-solver/issues)
157
+ - Submit pull requests with improvements
158
+
159
+
160
+ ## License
161
+
162
+ [View license information](https://github.com/LongenesisLtd/mathjson-solver/blob/main/LICENSE)
163
+
164
+ ---
165
+
166
+ Made with ❤️ by [Longenesis](https://longenesis.com/team)
@@ -0,0 +1,141 @@
1
+ # MathJSON Solver
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/mathjson-solver.svg)](https://pypi.org/project/mathjson-solver/)
4
+ [![PyPI Downloads](https://static.pepy.tech/badge/mathjson-solver/month)](https://pepy.tech/projects/mathjson-solver)
5
+ [![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)
6
+
7
+ A reliable Python library for numerically evaluating mathematical expressions in MathJSON format. Perfect for applications that need to safely execute user-provided formulas, calculate dynamic equations, or process mathematical data.
8
+
9
+ **What is MathJSON?** MathJSON represents mathematical expressions as JSON arrays, like `["Add", 1, 2, 3]` for 1+2+3. This format is safe, structured, and easy to generate programmatically.
10
+
11
+ Inspired by [CortexJS Compute Engine](https://cortexjs.io/compute-engine/) though designed as an independent implementation focused on our specific use cases.
12
+
13
+ ## Table of Contents
14
+ - [Installation](#installation)
15
+ - [Quick Start](#quick-start)
16
+ - [Supported Operations](#supported-operations)
17
+ - [Error Handling](#error-handling)
18
+ - [Use Cases](#use-cases)
19
+ - [Testing](#testing)
20
+ - [Community](#community)
21
+ - [Contributing](#contributing)
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install mathjson-solver
27
+ ```
28
+
29
+ **Requirements:** Python 3.7+
30
+
31
+ **Optional:** numpy (only required for `TrapezoidalIntegrate` function)
32
+
33
+ ## Quick Start
34
+
35
+ ```python
36
+ from mathjson_solver import create_solver, MathJSONException
37
+
38
+ # Define variables and create solver
39
+ parameters = {"x": 2, "y": 3}
40
+ solver = create_solver(parameters)
41
+
42
+ # Evaluate expressions
43
+ basic_math = solver(["Add", "x", "y", 4])
44
+ print(basic_math) # 9 (because 2+3+4=9)
45
+
46
+ # More complex expressions
47
+ result = solver(["Multiply", ["Add", "x", 1], ["Subtract", "y", 1]])
48
+ print(result) # 6 (because (2+1) * (3-1) = 6)
49
+
50
+ # Handle errors gracefully
51
+ try:
52
+ solver(["Divide", 1, 0])
53
+ except MathJSONException as e:
54
+ print(f"Math error: {e}")
55
+ # Math error: Problem in Divide. ['Divide', 1, 0]. division by zero
56
+ ```
57
+
58
+ ## Supported Operations
59
+
60
+ The library supports a comprehensive set of mathematical operations:
61
+
62
+ * **Arithmetic:** Add, Sum, Subtract, Multiply, Divide, Negate, Power, Square, Root, Sqrt, Abs, Round
63
+ * **Trigonometry:** Sin, Cos, Tan, Arcsin, Arccos, Arctan
64
+ * **Logarithms:** Log, Log2, Log10, Exp
65
+ * **Comparison:** Equal, StrictEqual, NotEqual, Greater, GreaterEqual, Less, LessEqual
66
+ * **Logic & Sets:** Any, All, Not, In, NotIn, ContainsAnyOf, ContainsAllOf, ContainsNoneOf
67
+ * **Statistics:** Average, Max, Min, Median, Length
68
+ * **Arrays:** Array creation and manipulation with Map function
69
+ * **Control Flow:** If statements, Switch-Case, Constants definition
70
+ * **Type Conversion:** Int, Float, Str, IsDefined
71
+ * **Date/Time:** Strptime, Strftime, Today, Now, TimeDelta functions
72
+ * **Advanced:** HasMatchingSublist, TrapezoidalIntegrate (requires numpy), Variable references
73
+ * **Constants:** Pi
74
+
75
+ [View complete documentation with examples →](https://github.com/LongenesisLtd/mathjson-solver/blob/main/docs/README.md)
76
+
77
+ ## Error Handling
78
+
79
+ MathJSON Solver raises `MathJSONException` for invalid expressions or mathematical errors:
80
+
81
+ ```python
82
+ from mathjson_solver import create_solver, MathJSONException
83
+
84
+ solver = create_solver({})
85
+
86
+ # Handle specific math errors
87
+ try:
88
+ result = solver(["Sqrt", -1]) # Invalid: square root of negative
89
+ except MathJSONException as e:
90
+ print(f"Cannot evaluate: {e}")
91
+
92
+ # Handle malformed expressions
93
+ try:
94
+ result = solver(["UnknownFunction", 1, 2])
95
+ except MathJSONException as e:
96
+ print(f"Unsupported operation: {e}")
97
+ ```
98
+
99
+ ## Use Cases
100
+
101
+ * **Dynamic Formulas:** Let users create custom calculations in web applications
102
+ * **Scientific Computing:** Evaluate mathematical models with variable parameters
103
+ * **Business Logic:** Process complex pricing rules or scoring algorithms
104
+ * **Data Processing:** Apply mathematical transformations to datasets
105
+ * **Health Applications:** Calculate medical scores, dosages, or risk assessments
106
+
107
+ ## Testing
108
+
109
+ Install development dependencies and run tests:
110
+
111
+ ```bash
112
+ # Install pytest if not already installed
113
+ pip install pytest
114
+
115
+ # Run tests from project directory
116
+ pytest
117
+
118
+ # Run with coverage
119
+ pytest --cov=mathjson_solver
120
+ ```
121
+
122
+ ## Community
123
+
124
+ - **Questions & Discussion:** [GitHub Issues](https://github.com/LongenesisLtd/mathjson-solver/issues)
125
+ - **Bug Reports & Feature Requests:** [GitHub Issues](https://github.com/LongenesisLtd/mathjson-solver/issues)
126
+ - **Documentation:** [Complete Function Reference](https://github.com/LongenesisLtd/mathjson-solver/blob/main/docs/README.md)
127
+
128
+ ## Contributing
129
+
130
+ We welcome contributions! Please feel free to:
131
+ - Report bugs or request features via [GitHub Issues](https://github.com/LongenesisLtd/mathjson-solver/issues)
132
+ - Submit pull requests with improvements
133
+
134
+
135
+ ## License
136
+
137
+ [View license information](https://github.com/LongenesisLtd/mathjson-solver/blob/main/LICENSE)
138
+
139
+ ---
140
+
141
+ Made with ❤️ by [Longenesis](https://longenesis.com/team)
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = mathjson-solver
3
- version = 1.13.0
3
+ version = 1.15.0
4
4
  author = Martins Mednis
5
5
  author_email = mrt@mednis.info
6
6
  description = Utilities for MathJSON evaluation
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="mathjson-solver",
8
- version="1.13.0",
8
+ version="1.15.0",
9
9
  author="Martins Mednis",
10
10
  author_email="mrt@mednis.info",
11
11
  description="Utilities for MathJSON evaluation",
@@ -1,5 +1,5 @@
1
1
  import numbers
2
- from typing import Union
2
+ from typing import Union, Any
3
3
  from functools import reduce
4
4
  import math
5
5
  from copy import deepcopy
@@ -8,6 +8,14 @@ import logging
8
8
  import traceback
9
9
  import datetime
10
10
 
11
+ NUMPY_AVAILABLE = False
12
+ try:
13
+ import numpy as np
14
+
15
+ NUMPY_AVAILABLE = True
16
+ except ImportError:
17
+ pass
18
+
11
19
  NoneType = type(None)
12
20
 
13
21
 
@@ -46,6 +54,8 @@ def is_numeric(x):
46
54
  float(x)
47
55
  except ValueError:
48
56
  return False
57
+ except TypeError:
58
+ return False
49
59
  else:
50
60
  return True
51
61
 
@@ -141,6 +151,16 @@ def comparison_safe_converter(x):
141
151
  return x
142
152
 
143
153
 
154
+ def comparison_safe_converter_for_pairs(
155
+ v1, v2
156
+ ) -> (Union[str, float], Union[str, float]):
157
+ if is_numeric(v1):
158
+ v1 = float(v1)
159
+ if is_numeric(v2):
160
+ v2 = float(v2)
161
+ return v1, v2
162
+
163
+
144
164
  def create_mathjson_solver(solver_parameters):
145
165
  def f(s, *args):
146
166
  if args:
@@ -160,10 +180,15 @@ def create_mathjson_solver(solver_parameters):
160
180
  tmp = 0
161
181
  for i, x in enumerate(s[1:]):
162
182
  res = f(x, c)
183
+ if is_numeric(res):
184
+ res = float(res)
163
185
  if i == 0:
164
186
  tmp = res
165
187
  else:
166
- tmp = tmp + res
188
+ try:
189
+ tmp = tmp + res
190
+ except TypeError:
191
+ pass
167
192
 
168
193
  # if isinstance(res, list):
169
194
  # l_res.append(sum([xx for xx in res[1:]]))
@@ -180,15 +205,25 @@ def create_mathjson_solver(solver_parameters):
180
205
  # tmp = tmp + x
181
206
  # return tmp
182
207
 
208
+ # def Sum(s):
209
+ # l_res = []
210
+ # for x in s[1:]:
211
+ # res = f(x, c)
212
+ # if isinstance(res, list):
213
+ # l_res.append(sum([xx for xx in res[1:]]))
214
+ # else:
215
+ # l_res.append(res)
216
+ # return sum(l_res)
217
+
183
218
  def Sum(s):
184
- l_res = []
219
+ l_res = ["Array"]
185
220
  for x in s[1:]:
186
221
  res = f(x, c)
187
222
  if isinstance(res, list):
188
- l_res.append(sum([xx for xx in res[1:]]))
223
+ l_res.append(Add(["Array"] + [xx for xx in res[1:]]))
189
224
  else:
190
225
  l_res.append(res)
191
- return sum(l_res)
226
+ return Add(l_res)
192
227
 
193
228
  def Max(s):
194
229
  if isinstance(s[1], str):
@@ -222,7 +257,6 @@ def create_mathjson_solver(solver_parameters):
222
257
 
223
258
  def Length(s):
224
259
  if isinstance(s[1], str):
225
-
226
260
  return len([x for x in f(s[1], c)][1:])
227
261
  else:
228
262
  return len([x for x in s[1][1:]])
@@ -352,6 +386,24 @@ def create_mathjson_solver(solver_parameters):
352
386
  return not f(s[1])
353
387
 
354
388
  def Map(s):
389
+ """
390
+ ["Map", list, function, more parameters]
391
+ The `function` must accept at least one parameter. That is for the current loop element.
392
+ The `more parameters` are for any additional parameters that function might have.
393
+ """
394
+ z = f(s[1], c)
395
+ if isinstance(z, list):
396
+ retlist = ["Array"]
397
+ for x in z[1:]:
398
+ try:
399
+ the_function_name = s[2][0]
400
+ ss = [the_function_name, x] + s[3:]
401
+ retlist.append(f(ss, c))
402
+ except MathJSONException:
403
+ retlist.append(x)
404
+ return retlist
405
+
406
+ def StrictMap(s):
355
407
  """
356
408
  ["Map", list, function, more parameters]
357
409
  The `function` must accept at least one parameter. That is for the current loop element.
@@ -366,6 +418,22 @@ def create_mathjson_solver(solver_parameters):
366
418
  retlist.append(f(ss, c))
367
419
  return retlist
368
420
 
421
+ def Filter(s):
422
+ """
423
+ ["Filter", list, function, more parameters]
424
+ The `function` must accept at least one parameter. That is for the current loop element.
425
+ The `more parameters` are for any additional parameters that function might have.
426
+ """
427
+ z = f(s[1], c)
428
+ if isinstance(z, list):
429
+ retlist = ["Array"]
430
+ for x in z[1:]:
431
+ the_function_name = s[2][0]
432
+ ss = [the_function_name, x] + s[3:]
433
+ if f(ss, c):
434
+ retlist.append(x)
435
+ return retlist
436
+
369
437
  def HasMatchingSublist(s):
370
438
  """
371
439
  ["HasMatchingSublist", list, required_match_count, position, contiguous, function, more parameters]
@@ -438,6 +506,108 @@ def create_mathjson_solver(solver_parameters):
438
506
  # Todo: This does not work
439
507
  return s[1] in c.keys()
440
508
 
509
+ def Greater(s):
510
+ v1, v2 = comparison_safe_converter_for_pairs(f(s[1], c), f(s[2], c))
511
+ try:
512
+ return v1 > v2
513
+ except TypeError:
514
+ return False
515
+
516
+ def GreaterEqual(s):
517
+ v1, v2 = comparison_safe_converter_for_pairs(f(s[1], c), f(s[2], c))
518
+ try:
519
+ return v1 >= v2
520
+ except TypeError:
521
+ return False
522
+
523
+ def Less(s):
524
+ v1, v2 = comparison_safe_converter_for_pairs(f(s[1], c), f(s[2], c))
525
+ try:
526
+ return v1 < v2
527
+ except TypeError:
528
+ return False
529
+
530
+ def LessEqual(s):
531
+ v1, v2 = comparison_safe_converter_for_pairs(f(s[1], c), f(s[2], c))
532
+ try:
533
+ return v1 <= v2
534
+ except TypeError:
535
+ return False
536
+
537
+ # sin, cos, tan, arcsin, arccos, arctan
538
+ def Sin(s):
539
+ return math.sin(f(s[1], c))
540
+
541
+ def Arcsin(s):
542
+ return math.asin(f(s[1], c))
543
+
544
+ def Cos(s):
545
+ return math.cos(f(s[1], c))
546
+
547
+ def Arccos(s):
548
+ return math.acos(f(s[1], c))
549
+
550
+ def Tan(s):
551
+ return math.tan(f(s[1], c))
552
+
553
+ def Arctan(s):
554
+ return math.atan(f(s[1], c))
555
+
556
+ def Pi(s):
557
+ return math.pi
558
+
559
+ def Variable(s):
560
+ """
561
+ ["Variable", variable_name]
562
+ The `variable_name` must be a string.
563
+ """
564
+ variable_name = s[1]
565
+ if variable_name in c:
566
+ return f(c[variable_name], c)
567
+ else:
568
+ raise KeyError(f"Variable '{variable_name}' is not defined")
569
+
570
+ def Function(s):
571
+ """
572
+ ["Function", function_expression, parameters]
573
+ The `function_name` must be a callable function.
574
+ The `parameters` are the arguments to be passed to the function.
575
+ """
576
+ function_expression = s[1]
577
+ arguments = s[2:]
578
+ return 0
579
+ # return f(function_expression, c) function_name(*parameters)
580
+
581
+ def TrapezoidalIntegrate(s):
582
+ """
583
+ ["TrapezoidalIntegrate", function_expression, start, end, n, variable]
584
+ """
585
+ if not NUMPY_AVAILABLE:
586
+ raise ImportError(
587
+ "TrapezoidalIntegrate requires 'numpy'. Install with 'pip install numpy'."
588
+ )
589
+ function_expression = s[1]
590
+ start = f(s[2], c)
591
+ end = f(s[3], c)
592
+ n = f(s[4], c)
593
+ variable = s[5]
594
+
595
+ t = np.linspace(start, end, n + 1)
596
+
597
+ # Calculate the integral using the trapezoidal rule
598
+
599
+ values = []
600
+ for x in t:
601
+ variable_name = variable[1]
602
+ variable_value = x
603
+ c[variable_name] = variable_value
604
+ values.append(f(function_expression, c))
605
+ h = (end - start) / n
606
+ # print("values=", values)
607
+ return h * (0.5 * values[0] + np.sum(values[1:-1]) + 0.5 * values[-1])
608
+
609
+ # return total_area
610
+
441
611
  constructs = {
442
612
  "Sum": Sum,
443
613
  "Add": Add,
@@ -461,15 +631,22 @@ def create_mathjson_solver(solver_parameters):
461
631
  "Log": lambda s: math.log(f(s[1], c)),
462
632
  "Log2": lambda s: math.log2(f(s[1], c)),
463
633
  "Log10": lambda s: math.log10(f(s[1], c)),
634
+ "Ln": lambda s: math.log(f(s[1], c)),
464
635
  # "Equal": lambda s: f"{f(s[1], c)}" == f"{f(s[2], c)}",
465
636
  "Equal": lambda s: comparison_safe_converter(f(s[1], c))
466
637
  == comparison_safe_converter(f(s[2], c)),
467
638
  "StrictEqual": lambda s: f(s[1], c) == f(s[2], c),
468
- "Greater": lambda s: f(s[1], c) > f(s[2], c),
469
- "GreaterEqual": lambda s: f(s[1], c) >= f(s[2], c),
470
- "Less": lambda s: f(s[1], c) < f(s[2], c),
471
- "LessEqual": lambda s: f(s[1], c) <= f(s[2], c),
472
- "NotEqual": lambda s: f(s[1], c) != f(s[2], c),
639
+ # "Greater": lambda s: f(s[1], c) > f(s[2], c),
640
+ "Greater": Greater,
641
+ # "GreaterEqual": lambda s: f(s[1], c) >= f(s[2], c),
642
+ "GreaterEqual": GreaterEqual,
643
+ # "Less": lambda s: f(s[1], c) < f(s[2], c),
644
+ "Less": Less,
645
+ # "LessEqual": lambda s: f(s[1], c) <= f(s[2], c),
646
+ "LessEqual": LessEqual,
647
+ # "NotEqual": lambda s: f(s[1], c) != f(s[2], c),
648
+ "NotEqual": lambda s: comparison_safe_converter(f(s[1], c))
649
+ != comparison_safe_converter(f(s[2], c)),
473
650
  "Abs": lambda s: abs(f(s[1], c)),
474
651
  "Round": lambda s: (
475
652
  round(f(s[1], c), f(s[2], c))
@@ -500,6 +677,8 @@ def create_mathjson_solver(solver_parameters):
500
677
  # "IsDefined": lambda s: s[1] in c,
501
678
  "IsDefined": IsDefined,
502
679
  "Map": Map,
680
+ "StrictMap": StrictMap,
681
+ "Filter": Filter,
503
682
  "HasMatchingSublist": HasMatchingSublist,
504
683
  "Strptime": Strptime,
505
684
  "Strftime": Strftime,
@@ -509,6 +688,16 @@ def create_mathjson_solver(solver_parameters):
509
688
  "TimeDeltaHours": TimeDeltaHours,
510
689
  "TimeDeltaMinutes": TimeDeltaMinutes,
511
690
  "TimeDeltaDays": TimeDeltaDays,
691
+ "Function": Function,
692
+ "Variable": Variable,
693
+ "TrapezoidalIntegrate": TrapezoidalIntegrate,
694
+ "Sin": Sin,
695
+ "Cos": Cos,
696
+ "Tan": Tan,
697
+ "Arcsin": Arcsin,
698
+ "Arccos": Arccos,
699
+ "Arctan": Arctan,
700
+ "Pi": Pi,
512
701
  }
513
702
  if s[0] in constructs:
514
703
  try:
@@ -563,6 +752,7 @@ def extract_variables(s: Union[list, int, float, str], li: set, ignore_list: set
563
752
  "Log",
564
753
  "Log2",
565
754
  "Log10",
755
+ "Ln",
566
756
  "Equal",
567
757
  "Greater",
568
758
  "GreaterEqual",
@@ -603,6 +793,16 @@ def extract_variables(s: Union[list, int, float, str], li: set, ignore_list: set
603
793
  "TimeDeltaHours",
604
794
  "TimeDeltaMinutes",
605
795
  "TimeDeltaDays",
796
+ "Function",
797
+ "Variable",
798
+ "TrapezoidalIntegrate",
799
+ "Sin",
800
+ "Cos",
801
+ "Tan",
802
+ "Arcsin",
803
+ "Arccos",
804
+ "Arctan",
805
+ "Pi",
606
806
  ]
607
807
  if isinstance(s, str):
608
808
  if s in ignore_list: