mathjson-solver 1.14.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.14.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.14.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",
@@ -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
 
@@ -526,6 +534,80 @@ def create_mathjson_solver(solver_parameters):
526
534
  except TypeError:
527
535
  return False
528
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
+
529
611
  constructs = {
530
612
  "Sum": Sum,
531
613
  "Add": Add,
@@ -549,6 +631,7 @@ def create_mathjson_solver(solver_parameters):
549
631
  "Log": lambda s: math.log(f(s[1], c)),
550
632
  "Log2": lambda s: math.log2(f(s[1], c)),
551
633
  "Log10": lambda s: math.log10(f(s[1], c)),
634
+ "Ln": lambda s: math.log(f(s[1], c)),
552
635
  # "Equal": lambda s: f"{f(s[1], c)}" == f"{f(s[2], c)}",
553
636
  "Equal": lambda s: comparison_safe_converter(f(s[1], c))
554
637
  == comparison_safe_converter(f(s[2], c)),
@@ -605,6 +688,16 @@ def create_mathjson_solver(solver_parameters):
605
688
  "TimeDeltaHours": TimeDeltaHours,
606
689
  "TimeDeltaMinutes": TimeDeltaMinutes,
607
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,
608
701
  }
609
702
  if s[0] in constructs:
610
703
  try:
@@ -659,6 +752,7 @@ def extract_variables(s: Union[list, int, float, str], li: set, ignore_list: set
659
752
  "Log",
660
753
  "Log2",
661
754
  "Log10",
755
+ "Ln",
662
756
  "Equal",
663
757
  "Greater",
664
758
  "GreaterEqual",
@@ -699,6 +793,16 @@ def extract_variables(s: Union[list, int, float, str], li: set, ignore_list: set
699
793
  "TimeDeltaHours",
700
794
  "TimeDeltaMinutes",
701
795
  "TimeDeltaDays",
796
+ "Function",
797
+ "Variable",
798
+ "TrapezoidalIntegrate",
799
+ "Sin",
800
+ "Cos",
801
+ "Tan",
802
+ "Arcsin",
803
+ "Arccos",
804
+ "Arctan",
805
+ "Pi",
702
806
  ]
703
807
  if isinstance(s, str):
704
808
  if s in ignore_list:
@@ -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)
@@ -3,6 +3,14 @@ import os
3
3
  import pytest
4
4
  import re
5
5
 
6
+ NUMPY_AVAILABLE = False
7
+ try:
8
+ import numpy as np
9
+
10
+ NUMPY_AVAILABLE = True
11
+ except ImportError:
12
+ np = None
13
+
6
14
  sys.path.append(os.path.join(os.path.dirname(__file__), "../src/"))
7
15
 
8
16
  from mathjson_solver import create_solver, MathJSONException, extract_variables
@@ -478,6 +486,195 @@ def test_solver_simple(parameters, expression, expected_result):
478
486
  assert solver(expression) == expected_result
479
487
 
480
488
 
489
+ def _create_numpy_test_cases():
490
+ """Create test cases that require numpy, only if numpy is available."""
491
+ if not NUMPY_AVAILABLE:
492
+ return []
493
+
494
+ return [
495
+ # 1. Polynomial Function f(x) = x²
496
+ (
497
+ {},
498
+ [
499
+ "TrapezoidalIntegrate",
500
+ ["Power", ["Variable", "x"], 2],
501
+ 0,
502
+ 1,
503
+ 10,
504
+ ["Variable", "x"],
505
+ ],
506
+ np.float64(0.3350000000000001),
507
+ ),
508
+ # 2. Trigonometric Function f(x) = sin(x)
509
+ (
510
+ {},
511
+ [
512
+ "TrapezoidalIntegrate",
513
+ ["Sin", ["Variable", "x"]],
514
+ 0,
515
+ ["Pi"],
516
+ 100,
517
+ ["Variable", "x"],
518
+ ],
519
+ np.float64(1.9998355038874436),
520
+ ),
521
+ # 3. Exponential Function f(x) = e^x
522
+ (
523
+ {},
524
+ [
525
+ "TrapezoidalIntegrate",
526
+ ["Exp", ["Variable", "x"]],
527
+ 0,
528
+ 1,
529
+ 100,
530
+ ["Variable", "x"],
531
+ ],
532
+ np.float64(1.7182961474504177),
533
+ ),
534
+ # 4. Rational Function f(x) = 1/(1+x²)
535
+ (
536
+ {},
537
+ [
538
+ "TrapezoidalIntegrate",
539
+ ["Divide", 1, ["Add", 1, ["Power", ["Variable", "x"], 2]]],
540
+ 0,
541
+ 1,
542
+ 100,
543
+ ["Variable", "x"],
544
+ ],
545
+ np.float64(0.7853939967307823),
546
+ ),
547
+ # 5. Product of Functions f(x) = x·sin(x)
548
+ (
549
+ {},
550
+ [
551
+ "TrapezoidalIntegrate",
552
+ ["Multiply", ["Variable", "x"], ["Sin", ["Variable", "x"]]],
553
+ 0,
554
+ ["Pi"],
555
+ 100,
556
+ ["Variable", "x"],
557
+ ],
558
+ np.float64(3.1413342637004176),
559
+ ),
560
+ # 6. Logarithmic Function f(x) = ln(x)
561
+ (
562
+ {},
563
+ [
564
+ "TrapezoidalIntegrate",
565
+ ["Ln", ["Variable", "x"]],
566
+ 1,
567
+ 2,
568
+ 100,
569
+ ["Variable", "x"],
570
+ ],
571
+ np.float64(0.38629019447752866),
572
+ ),
573
+ # 7. Function with Singularity f(x) = 1/√x
574
+ (
575
+ {},
576
+ [
577
+ "TrapezoidalIntegrate",
578
+ ["Divide", 1, ["Sqrt", ["Variable", "x"]]],
579
+ 0.01,
580
+ 1,
581
+ 100,
582
+ ["Variable", "x"],
583
+ ],
584
+ np.float64(1.8038847804497282),
585
+ ),
586
+ # 8. Highly Oscillatory Function f(x) = sin(10x)·cos(3x)
587
+ (
588
+ {},
589
+ [
590
+ "TrapezoidalIntegrate",
591
+ [
592
+ "Multiply",
593
+ ["Sin", ["Multiply", 10, ["Variable", "x"]]],
594
+ ["Cos", ["Multiply", 3, ["Variable", "x"]]],
595
+ ],
596
+ 0,
597
+ ["Multiply", 2, ["Pi"]],
598
+ 100,
599
+ ["Variable", "x"],
600
+ ],
601
+ np.float64(5.787724498767512e-16), # effectively zero
602
+ ),
603
+ # 9. Function with Multiple Local Extrema x²·sin(1/x)
604
+ (
605
+ {},
606
+ [
607
+ "TrapezoidalIntegrate",
608
+ [
609
+ "Multiply",
610
+ ["Power", ["Variable", "x"], 2],
611
+ ["Sin", ["Divide", 1, ["Variable", "x"]]],
612
+ ],
613
+ 0.1,
614
+ 1,
615
+ 500,
616
+ ["Variable", "x"],
617
+ ],
618
+ np.float64(0.2866184933855661),
619
+ ),
620
+ # 10. Rapidly Varying Function f(x) = e^(-x²)
621
+ (
622
+ {},
623
+ [
624
+ "TrapezoidalIntegrate",
625
+ [
626
+ "Exp",
627
+ ["Multiply", -1, ["Power", ["Variable", "x"], 2]],
628
+ ],
629
+ -5,
630
+ 5,
631
+ 500,
632
+ ["Variable", "x"],
633
+ ],
634
+ np.float64(1.7724538509027818),
635
+ ),
636
+ # 11. Function with Discontinuity f(x) = 1/x
637
+ (
638
+ {},
639
+ [
640
+ "TrapezoidalIntegrate",
641
+ ["Divide", 1, ["Variable", "x"]],
642
+ 0.001,
643
+ 1,
644
+ 1000,
645
+ ["Variable", "x"],
646
+ ],
647
+ np.float64(6.984825983783107), # 6.90776 is more accurate
648
+ ),
649
+ # 12. Function with Sharp Peak f(x) = 1/(1+100x²)
650
+ (
651
+ {},
652
+ [
653
+ "TrapezoidalIntegrate",
654
+ [
655
+ "Divide",
656
+ 1,
657
+ ["Add", 1, ["Multiply", 100, ["Power", ["Variable", "x"], 2]]],
658
+ ],
659
+ -1,
660
+ 1,
661
+ 1000,
662
+ ["Variable", "x"],
663
+ ],
664
+ np.float64(0.29422552179014305),
665
+ ),
666
+ ]
667
+
668
+
669
+ @pytest.mark.skipif(not NUMPY_AVAILABLE, reason="NumPy not available")
670
+ @pytest.mark.parametrize(
671
+ "parameters, expression, expected_result", _create_numpy_test_cases()
672
+ )
673
+ def test_integrals(parameters, expression, expected_result):
674
+ solver = create_solver(parameters)
675
+ assert solver(expression) == expected_result
676
+
677
+
481
678
  def test_raises_divide():
482
679
  solver = create_solver({})
483
680
  with pytest.raises(
@@ -1,76 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: mathjson-solver
3
- Version: 1.14.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
- ![Coverage](https://img.shields.io/badge/coverage-91-green)
31
-
32
- _MathJSON Solver_ is a Python module to numerically evaluate MathJSON expressions, like `["Add", 1, 2]`. It is developed by [Longenesis](https://longenesis.com/team) to enable numerical evaluation of user provided mathematical expressions in Longenesis digital health products. Its development was inspired by [CortexJS](https://cortexjs.io/compute-engine/) Compute Engine.
33
-
34
- Please ask questions and share feedback in our Gitter chat [https://gitter.im/mathjson-solver/community](https://gitter.im/mathjson-solver/community).
35
- [![Gitter](https://badges.gitter.im/mathjson-solver/community.svg)](https://gitter.im/mathjson-solver/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
36
-
37
- ## How to use
38
- ```python
39
- from mathjson_solver import create_solver
40
-
41
- parameters = {"x": 2, "y": 3}
42
- expression = ["Add", "x", "y", 4]
43
-
44
- solver = create_solver(parameters)
45
- answer = solver(expression)
46
-
47
- print(answer)
48
- # 9, because 2+3+4=9
49
- ```
50
-
51
- ## Currently supported constructs
52
- Find the full list of supported constructs in the [docs/README.md](https://github.com/LongenesisLtd/mathjson-solver/blob/main/docs/README.md).
53
-
54
-
55
- ## Exception handling
56
-
57
- A `MathJSONException` is raised when expression cannot be evaluated. Import `MathJSONException` to handle it:
58
- ```python
59
- from mathjson_solver import create_solver, MathJSONException
60
-
61
- solver = create_solver({})
62
- try:
63
- solver(["Divide", 1, 0])
64
- except MathJSONException:
65
- pass
66
- # invoke your own exception logger here
67
- ```
68
-
69
- Left unhandled, the exception will look like `MathJSONException("Problem in Divide. ['Divide', 1, 0]. division by zero")`.
70
-
71
-
72
- ## How to run tests
73
- Make sure you have `pytest` installed. Then `cd` into project directory and run:
74
- ```bash
75
- pytest
76
- ```
@@ -1,51 +0,0 @@
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
- ![Coverage](https://img.shields.io/badge/coverage-91-green)
6
-
7
- _MathJSON Solver_ is a Python module to numerically evaluate MathJSON expressions, like `["Add", 1, 2]`. It is developed by [Longenesis](https://longenesis.com/team) to enable numerical evaluation of user provided mathematical expressions in Longenesis digital health products. Its development was inspired by [CortexJS](https://cortexjs.io/compute-engine/) Compute Engine.
8
-
9
- Please ask questions and share feedback in our Gitter chat [https://gitter.im/mathjson-solver/community](https://gitter.im/mathjson-solver/community).
10
- [![Gitter](https://badges.gitter.im/mathjson-solver/community.svg)](https://gitter.im/mathjson-solver/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
11
-
12
- ## How to use
13
- ```python
14
- from mathjson_solver import create_solver
15
-
16
- parameters = {"x": 2, "y": 3}
17
- expression = ["Add", "x", "y", 4]
18
-
19
- solver = create_solver(parameters)
20
- answer = solver(expression)
21
-
22
- print(answer)
23
- # 9, because 2+3+4=9
24
- ```
25
-
26
- ## Currently supported constructs
27
- Find the full list of supported constructs in the [docs/README.md](https://github.com/LongenesisLtd/mathjson-solver/blob/main/docs/README.md).
28
-
29
-
30
- ## Exception handling
31
-
32
- A `MathJSONException` is raised when expression cannot be evaluated. Import `MathJSONException` to handle it:
33
- ```python
34
- from mathjson_solver import create_solver, MathJSONException
35
-
36
- solver = create_solver({})
37
- try:
38
- solver(["Divide", 1, 0])
39
- except MathJSONException:
40
- pass
41
- # invoke your own exception logger here
42
- ```
43
-
44
- Left unhandled, the exception will look like `MathJSONException("Problem in Divide. ['Divide', 1, 0]. division by zero")`.
45
-
46
-
47
- ## How to run tests
48
- Make sure you have `pytest` installed. Then `cd` into project directory and run:
49
- ```bash
50
- pytest
51
- ```
@@ -1,76 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: mathjson-solver
3
- Version: 1.14.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
- ![Coverage](https://img.shields.io/badge/coverage-91-green)
31
-
32
- _MathJSON Solver_ is a Python module to numerically evaluate MathJSON expressions, like `["Add", 1, 2]`. It is developed by [Longenesis](https://longenesis.com/team) to enable numerical evaluation of user provided mathematical expressions in Longenesis digital health products. Its development was inspired by [CortexJS](https://cortexjs.io/compute-engine/) Compute Engine.
33
-
34
- Please ask questions and share feedback in our Gitter chat [https://gitter.im/mathjson-solver/community](https://gitter.im/mathjson-solver/community).
35
- [![Gitter](https://badges.gitter.im/mathjson-solver/community.svg)](https://gitter.im/mathjson-solver/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
36
-
37
- ## How to use
38
- ```python
39
- from mathjson_solver import create_solver
40
-
41
- parameters = {"x": 2, "y": 3}
42
- expression = ["Add", "x", "y", 4]
43
-
44
- solver = create_solver(parameters)
45
- answer = solver(expression)
46
-
47
- print(answer)
48
- # 9, because 2+3+4=9
49
- ```
50
-
51
- ## Currently supported constructs
52
- Find the full list of supported constructs in the [docs/README.md](https://github.com/LongenesisLtd/mathjson-solver/blob/main/docs/README.md).
53
-
54
-
55
- ## Exception handling
56
-
57
- A `MathJSONException` is raised when expression cannot be evaluated. Import `MathJSONException` to handle it:
58
- ```python
59
- from mathjson_solver import create_solver, MathJSONException
60
-
61
- solver = create_solver({})
62
- try:
63
- solver(["Divide", 1, 0])
64
- except MathJSONException:
65
- pass
66
- # invoke your own exception logger here
67
- ```
68
-
69
- Left unhandled, the exception will look like `MathJSONException("Problem in Divide. ['Divide', 1, 0]. division by zero")`.
70
-
71
-
72
- ## How to run tests
73
- Make sure you have `pytest` installed. Then `cd` into project directory and run:
74
- ```bash
75
- pytest
76
- ```