Modeval (or Modular Eval) is a modular and secure string evaluation library that can be used to create custom parsers or interpreters.
Install with: pip install modeval
If performance is not really a concern, you can use the meval()
function.
from modeval import meval
# Evalute string. Spaces are automatically removed.
print( meval('1 * (2-3)') )
Creating a parser class is more efficient for crunching lots of expressions with the same ruleset.
from modeval import Parser
# Create a new parser with the default ruleset.
p = Parser()
# Evalute string. Spaces are automatically removed.
print( p.eval('1 * (2-3)') )
The Parser class will use a basic mathematical ruleset if no ruleset is specified. Use the default ruleset as a guide on how to make custom ones.
from modeval import Parser, Ruleset, meval
import operator # (standard library)
default_ruleset = Ruleset()
# Notice the order of the array follows order of operations.
default_ruleset.operators = [
[('^', operator.pow), ('**', operator.pow)],
[('*', operator.mul), ('/', operator.truediv)],
[('+', operator.add), ('-', operator.sub)]
]
p = Parser(ruleset = default_ruleset)
meval('1+1', ruleset=default_ruleset) # Rulesets can also be supplied to meval()
The second item in the tuple must be the function that will be called when the operator is used. The attached method must have two inputs in the correct order (L + R
is parsed as add(L, R)
).
Modeval also supports functions like sin()
, but they are not included in the default ruleset. However, they are included in scientific_ruleset
which can be imported and used. Adding custom functions works as follows:
from modeval import Parser, Ruleset
import math # (standard library)
custom_ruleset = Ruleset()
# Function order does not matter, so an extra layer of grouping is not needed.
custom_ruleset.functions = [
('sin', math.sin),
('cos', math.cos),
('tan', math.tan)
]
p = Parser(ruleset = custom_ruleset)
# You can now use "sin(...)" in the input string for eval().
Speaking of sin()
, what about pi
? Modeval also supports custom variables. They can be set like this:
from modeval import Parser, Ruleset
import math # (standard library)
custom_ruleset = Ruleset()
custom_ruleset.variables = [
('pi', math.pi) # Keep in mind this needs to be a value and not a reference to function.
]
p = Parser(ruleset = custom_ruleset)
# Now you can use "pi" just like any other number.
The function parse_parentheses()
is also available for use. It takes one string as an input and will output a nested array depending on the parenthesis grouping in the input string.
For example: parse_parentheses('ab(c(d))') ==> ['a', 'b', ['c', ['d']]]