Skip to main content

Python Mathematical Expression Evaluator

Build Status

PyPi version PyPi downloads

Coverage Status

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

python setup.py test

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/

Release files for py-expression-eval 0.3.14

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for py-expression-eval 0.3.14
File Size Uploaded
py_expression_eval-0.3.14.tar.gz 13.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for py-expression-eval 0.3.14
File Interpreter ABI Platform
py_expression_eval-0.3.14-py3-none-any.whl Python 3 none any Details

Total release size:25.7 kB

Release files / py_expression_eval-0.3.14.tar.gz

Download URL py_expression_eval-0.3.14.tar.gz
Size 13.1 kB
Tags Source
SHA-256 checksum
How to use checksums
ea60f9404a18346d5a63854db21c50666dfb4274ae111000165b31c6f8ab93f1
BLAKE2b-256 checksum
How to use checksums
c0a03b006218f45931f02becaec93d18be203c62f4a30dd7b3c2e019539661b0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.6.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.7.3

Release files / py_expression_eval-0.3.14-py3-none-any.whl

Download URL py_expression_eval-0.3.14-py3-none-any.whl
Size 12.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ccbd54b6b0f63040693c4eefa12e618dd1f3463b5c75a9df35881e622b8caa83
BLAKE2b-256 checksum
How to use checksums
225b94159c7bed782ce017a739b8e5bc2ee8de47cc7c6082248cd8ada08ca5e9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.6.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.7.3

Release history Release notifications | RSS feed

This release

0.3.14 This release

2 release files

0.3.12

2 release files

0.3.11

2 release files

0.3.10

2 release files

0.3.9

2 release files

0.3.7

1 release file

0.3.6

2 release files

0.3.5

3 release files

0.3.4

1 release file

0.3.3

1 release file

0.3.2

1 release file

0.3.1

0.3

1 release file

0.2

1 release file

0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page