A safe and simple math evaluator for Python, built with rply.
View on PyPI
Expr.py is a simple but safe math expression evaluator made for Python.
It can evaluate pretty advanced math concepts without crashing your computer.
Made using rply
- Fully object oriented
- Completely typed for intellisense
- Protection against DoS attacks
- Customizable and extendable
- Follows order of operations
- Floating point precision
You should install expr.py using pip
:
$ pip install -U expr.py
Here is a simple program to get started:
import expr
if __name__ == '__main__':
expression = '6 + 5 * 2'
print(expr.evaluate(expression)) # 16
The following operations are supported by expr.py:
+
(addition)-
(subtraction)*
(multiplication)/
(division)//
(floor division)%
(modulo)^
(exponentation)!
(factorial)
The most basic way of defining variables is by
passing in the variables
kwarg into the evaluator.
expr.evaluate('2x', variables={'x': 2}) # 4
You can also let the input define variables:
expr.evaluate('x = 5')
expr.evaluate('6 + x') # 11
There are by default, 2 predefined constants. (pi
and e
)
You can define functions through the builtins
kwarg:
def f(x):
return x + 1
expr.evaluate('f(5)', builtins={'f': f}) # 6
You can also define functions via input:
expr.evaluate('f(x) = 2x')
expr.evaluate('f(3)') # 6
There are a few builtin functions:
sqrt
cbrt
log
log10
ln
rad
sin
cos
tan
asin
acos
atan
This concept is pretty simple, anything in parentheses will be evaluated before anything outside of them.
expr.evaluate('5 * 6 + 2') # 32
expr.evaluate('5 * (6 + 2)') # 40
You can create different states so that each can store their own variables and functions independently from others.
To do this, use expr.create_state
:
state = expr.create_state()
print(state.evaluate('0.1 + 0.2')) # 0.3
Note: All parameters belong in create_state
rather than in evaluate
for states.
Again, variables and functions are independent from each other:
state1 = expr.create_state()
state1.evaluate('x = 1')
state2 = expr.create_state()
state2.evaluate('x') # error (x is not defined)
state1.evaluate('x') # 1
This update mainly brings bug fixes from v0.1.
- You can now pass in custom classes into
Parser.evaluate
- Constants are now precise to around 30 places.
- New constants (
phi
,tau
)
v0.2 changes the way some builtin functions are processed for boosts on both performance and precision.
sqrt
now usesDecimal.sqrt
log10
now usesDecimal.log10
ln
now usesDecimal.ln
cbrt
now usesinput ** expr.one_third
sin
now usesexpr.sin
cos
now usesexpr.cos
- Fixed unary minus interfering with implicit multiplication.
- in v0.1:
5-3
=-15
- in v0.2:
5-3
=2
- in v0.1:
- Many functions now have positional-only arguments for slight performance boosts
- This drops support for Python 3.7
- Messages retrieved from
ParsingError.friendly
are now much more descriptive.
- Unary plus is now supported (E.g.
+5
) - Scientific notation is now supported (E.g.
4E-2
)- To reduce conflics, 'E' must be captialized.
This means that2e9
would evaluate to2 * e * 9
, for example.
- To reduce conflics, 'E' must be captialized.
- The
cls
kwarg is now supported inexpr.evaluate
- Catch
OverflowError
in theexpr.Overflow
parsing error. - Fix invalid typings with
Callable