Python Mathematical Expression Evaluator
Based on js-expression-eval, by Matthew Crumley (email@matthewcrumley.com, http://silentmatt.com/) https://github.com/silentmatt/js-expression-eval
Ported to Python and modified by @cansadadeserfeliz.
You are free to use and modify this code in anyway you find useful. Please leave this comment in the code to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code, but don't feel like you have to let me know or ask permission.
Installation
pip install py_expression_eval
Tests
Documentation
All the classes and methods of py-expression-eval were written as similar as possible to their analogues from js-expression-eval to make it easier to use for validation on back-end side.
Parser
Parser is the main class of the library that contains the methods to parse, evaluate and simplify mathematical expressions. In order to use the library you need to create an instance of this class:
> from py_expression_eval import Parser > parser = Parser()
Once you instantiated Parser class, you can create Expression object using parse method:
> parser.parse('2 * 3') Out: <py_expression_eval.Expression instance at 0x7f40cc4e5ef0>
Parser.Expression
evaluate() takes a dictionary with variables as a parameter and returns the value of the expression:
> parser.parse('2 * 3').evaluate({}) Out: 6 > parser.parse('2 * 3.0').evaluate({}) Out: 6.0 > parser.parse('2 * x').evaluate({'x': 7}) Out: 14 > parser.parse('2 * x').evaluate({'x': 7.0}) Out: 14.0
substitute() creates a new expression where specified variables are replaces with a new expression. For example, to replace x with 3 + x in 2 * x expression we use the following code:
> parser.parse('2 * x').substitute('x', '3 + x').toString() Out: '(2*(3+x))'
variables() returns a list of the variables for the expression:
> parser.parse('2 * x + y').variables() Out: ['x', 'y']
simplify() simplifies the expression. For example,
> parser.parse('2 * 3 * x + y').simplify({}).toString() Out: '((6*x)+y)' > parser.parse('2 * 3 * x + y').simplify({'x': -1}).toString() Out: '(-6+y)' > parser.parse('cos(PI) + x').simplify({}).toString() Out: '(-1.0+x)'
toString() converts the expression to a string.
Available operators, constants and functions
| Expression | Example | Output |
|---|---|---|
| + | parser.parse('2 + 2').evaluate({}) |
4 |
| - | parser.parse('3 - 1').evaluate({}) |
2 |
* |
parser.parse('2 * 3').evaluate({}) |
6 |
| / | parser.parse('5 / 2').evaluate({}) |
2.5 |
| % | parser.parse('5 % 2').evaluate({}) |
1 |
| ^ | parser.parse('5 ^ 2').evaluate({}) |
25.0 |
| PI | parser.parse('PI').evaluate({}) |
3.141592653589793 |
| E | parser.parse('E').evaluate({}) |
2.718281828459045 |
| sin(x) | parser.parse('sin(0)').evaluate({}) |
0.0 |
| cos(x) | parser.parse('cos(PI)').evaluate({}) |
- 1.0 |
| tan(x) | parser.parse('tan(0)').evaluate({}) |
0.0 |
| asin(x) | parser.parse('asin(0)').evaluate({}) |
0.0 |
| acos(x) | parser.parse('acos(-1)').evaluate({}) |
3.141592653589793 |
| atan(x) | parser.parse('atan(PI)').evaluate({}) |
1.2626272556789118 |
| log(x) | parser.parse('log(1)').evaluate({}) |
0.0 |
| log(x, base) | parser.parse('log(16, 2)').evaluate({}) |
4.0 |
| abs(x) | parser.parse('abs(-1)').evaluate({}) |
1 |
| ceil(x) | parser.parse('ceil(2.7)').evaluate({}) |
3.0 |
| floor(x) | parser.parse('floor(2.7)').evaluate({}) |
2.0 |
| round(x) | parser.parse('round(2.7)').evaluate({}) |
3.0 |
| exp(x) | parser.parse('exp(2)').evaluate({}) |
7.38905609893065 |
| and | parser.parse('a and b').evaluate({'a':True, 'b':True}) |
True |
| or | parser.parse('a or b').evaluate({'a':True, 'b':True}) |
True |
| xor | parser.parse('a xor b').evaluate({'a':True, 'b':True}) |
False |
| not | parser.parse('a and not b').evaluate({'a':True, 'b':True}) |
False |
| in | parser.parse('1 in (1,2,3)').evaluate({}) |
True |
Examples
from py_expression_eval import Parser parser = Parser() parser.parse('2 * 3').evaluate({}) # 6 parser.parse('2 ^ x').evaluate({'x': 3}) # 8.0 parser.parse('2 * x + 1').evaluate({'x': 3}) # 7 parser.parse('2 + 3 * x').evaluate({'x': 4}) # 14 parser.parse('(2 + 3) * x').evaluate({'x': 4}) # 20 parser.parse('2-3^x').evaluate({'x': 4}) # -79.0 parser.parse('-2-3^x').evaluate({'x': 4}) # -83.0 parser.parse('-3^x').evaluate({'x': 4}) # -81.0 parser.parse('(-3)^x').evaluate({'x': 4}) # 81.0 parser.parse('2*x + y').evaluate({'x': 4, 'y': 1}) # 9 parser.parse('round(log(2.7))').evaluate({}) # 1.0 # substitute expr = parser.parse('2 * x + 1') expr2 = expr.substitute('x', '4 * x') # ((2*(4*x))+1) expr2.evaluate({'x': 3}) # 25 # simplify expr = parser.parse('x * (y * atan(1))').simplify({'y': 4}) expr.toString() # x*3.141592 expr.evaluate({'x': 2}) # 6.283185307179586 # get variables expr = parser.parse('x * (y * atan(1))') expr.variables() # ['x', 'y'] expr.simplify({'y': 4}).variables() # ['x']
Available operations
from py_expression_eval import Parser parser = Parser() parser.parse('2 + 3').evaluate({}) # 5 parser.parse('2 - 3').evaluate({}) # -1 parser.parse('2 * 3').evaluate({}) # 6 parser.parse('2 / 3').evaluate({}) # 0.6666666666666666 parser.parse('2 % 3').evaluate({}) # 2 parser.parse('-2').evaluate({}) # -2 parser.parse('abs(-2)').evaluate({}) # 2 parser.parse('ceil(1.4)').evaluate({}) # 2.0 parser.parse('floor(1.4)').evaluate({}) # 1.0 parser.parse('round(1.4)').evaluate({}) # 1.0 parser.parse('2^3').evaluate({}) # 8.0 parser.parse('sqrt(16)').evaluate({}) # 4.0 parser.parse('sin(3.14)').evaluate({}) # 0.0015926529164868282 parser.parse('cos(3.14)').evaluate({}) # -0.9999987317275395 parser.parse('tan(3.14)').evaluate({}) # -0.0015926549364072232 parser.parse('asin(1)').evaluate({}) # 1.5707963267948966 parser.parse('acos(1)').evaluate({}) # 0.0 parser.parse('atan(1)').evaluate({}) # 0.7853981633974483 parser.parse('log(2.7)').evaluate({}) # 0.9932517730102834 parser.parse('exp(1)').evaluate({}) # 2.718281828459045 parser.parse('log(E)').evaluate({}) # 1.0 parser.parse('cos(PI)').evaluate({}) # -1.0 parser.parse('x||y').evaluate({'x': 2, 'y': 3}) # '23' parser.parse('num in (1,2,3)').evaluate({'num': 1}) # True parser.parse('"word" in "word in sentence"').evaluate({}) # True
Upload package to PyPi
Generating distribution archives
python3 setup.py sdist bdist_wheel
Upload distribution
ls -a dist/
twine upload dist/py_expression_eval-0.3.9*
Check on: https://pypi.org/project/py-expression-eval/0.3.9/
More details: https://packaging.python.org/tutorials/packaging-projects/