Utilities for MathJSON evaluation
Project description
MathJSON Solver
MathJSON Solver is a Python module to numerically evaluate MathJSON expressions. It was created by Longenesis to add numerical evaluation capability of user generated mathematical expressions in Longenesis digital health products and later released as open source project. Its development was inspired by CortexJS Compute Engine.
Please ask questions and share feedback in our Gitter chat https://gitter.im/mathjson-solver/community.
What's new
1.4.0
We changed the behavior of Average
to be more forgiving. In version 1.4.0 Average
accepts arrays like [2, 4 ,"6"]
and internally converts numeric strings to floats.
Also, it skips values that cannot be converted to numeric. Internally Average
will convert array [2, "three", 4 ,"6"]
to [2.0, 4.0 ,6.0]
. When given an empty array, Average
now returns None
instead of throwing an error.
How to use
from mathjson_solver import create_solver
parameters = {"x": 2, "y": 3}
expression = ["Add", "x", "y", 4]
solver = create_solver(parameters)
answer = solver(expression)
print(answer)
# 9, because 2+3+4=9
How to run tests
Make sure you have pytest
installed. Then cd
into project directory and run:
pytest
Contributing Code
We welcome your contributions in the form of pull requests.
- Fork the repo;
- Make improvements;
- Make a pull request to share your improvements with the community and to include it into official release.
Currently supported constructs
Math
Sum
(aliasAdd
)Subtract
Multiply
Divide
Negate
Power
Root
Sqrt
Square
Exp
Log
Log2
Log10
Aggregation
Array
Max
Min
Average
Median
Len
All
Any
Conditions
If
Switch
Equal
Greater
GreaterEqual
Less
LessEqual
NotEqual
Typecasting
Int
Float
Additional constructs
Constants
Examples
["Add", 2, 4, 3] # 2+4+3=9
["Subtract", 10, 5, 2] # 10-5-2=3
["Add", 5, 4, ["Negate", 3]] # 5+4+(-3)=6
["Multiply", 2, 3, 4] # 2*3*4=24
["Divide", 10, 5] # 10/5=2.0
["Divide", 10, 4] # 10/4=2.5
["Power", 2, 3] # 2^3=8
["Root", 9, 2] # √9=3.0
["Root", 8, 3] # ∛8=2.0
["Sqrt", 9] # √9=3.0
["Square", 4] # 4^2=16
["Exp", 2] # e^2≅7.389
["Divide", 10, ["Add", 2+3]] # 10/(2+3)=10/5=2
["Log", 2.7183] # ln(2.7183)≅1.0000
["Log2", 8] # log2(8)=3.0
["Log10", 1000] # log10(1000)=3.0
["Equal", 10, 10] # 10==10 = True
["Equal", 10, 12] # 10==10 = False
["Abs", -3.5] # |-3.5| = 3.5
["Round", -5.123456, 2] # -5.12
["Round", -5.123456, 0] # -5.0
["Round", -5.123456] # -5
["Array", 1, 2] # ["Array", 1, 2]
["Max", ["Array", 1, 2, 3, 5, 2]] # 5
["Max", ["Array", 1, 2, ["Sum", 2, 4, 3], 5, 2]] # 9
["Median", ["Array", 1, 2, 3, 5, 2]] # 2
["Average", ["Array", 1, 2, 3, 5, 2]] # 2.6
["Length", ["Array", 1, 2, 3, 5, 2, 9]] # 6
["Length", ["Array"]] # 0
["Any", ["Array", 0, 0, False, 0, 0]] # False
["Any", ["Array", 0, 1, False, 0, 0]] # True
["All", ["Array", 0, 1, False, 0, 0]] # False
["All", ["Array", 0, 1, False, "", 0]] # False
["All", ["Array", 2, 1, True, "zz", 2]] # True
["Int", "12"] # 12
["Int", "12.2"] # 12
["Float", "12.2"] # 12.2
Constants
[
"Constants",
["constant_name1", <expression>],
["constant_name2", <expression>],
["constant_name3", <expression>],
...,
<expression>
]
Constants
construct consists of keyword "Constants" followed by arbitrary number of name&value pairs. The last element in Constants
construct is the expression to calculate using the defined constants.
The following example has two constants defined - x=10
and y=20
. Then the sum of these two constants is calculated and returned.
[
"Constants",
["x", 10],
["y", 20],
["Add","x", "y"]
]
If statement
[
"If",
[
<true-or-false-expression>,
<expression-to-calculate>
],
[
<elseif-true-or-false-expression>,
<expression-to-calculate>
],
...,
<else-expression-to-calculate>
]
Example
[
"If",
[
["Equal", 1, 0],
10
],
[
["Equal", 2, 2],
20
],
9000
]
This construct translates to:
if 1 == 0 then 10
elif 2 == 2 then 20
else 9000
If
expression do not need to be strictly boolean. Any value that is not false are considered true.
Switch-Case statement
["Switch", <on-expression>, <default-result-expression>, [<case1-expression>, <result-expression>], ...],
Switch
construct consists of keyword "Switch" followed by expression whose value will be compared to Cases' values. Then comes the default value. Then follows arbitrary number of Cases.
Example
["Switch", "color", 100, ["red", 10], ["blue", 20], ["green", 30]],
The expression in this example will make solver to look for a constant (or a parameter) with the name "color". If "color" is "red", expression evaluates to 10, if "blue" - to 20, if "green" - to 30. Otherwise to 100. Please note that "color" here is a valid expression that evaluates to the actual value of "color" whether it is a parameter or constant.
Exception handling
A MathJSONException
is raised when expression cannot be evaluated. Import MathJSONException
to handle it:
from mathjson_solver import create_solver, MathJSONException
solver = create_solver({})
try:
solver(["Divide", 1, 0])
except MathJSONException:
pass
# invoke your own exception logger here
Left unhandled, the exception will look like MathJSONException("Problem in Divide. ['Divide', 1, 0]. division by zero")
.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for mathjson_solver-1.4.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c24f34f9a6d3014b2682db0b9c853be8bbe78566e7270ed5e9c8fe33d3a9a9b9 |
|
MD5 | 3573e65ba7f409f84f6b55ea88a99e87 |
|
BLAKE2b-256 | 46b84e5b298cc6b15e22c07bc257ba920456873ce3ef9f484a31f104130e1a08 |