Created
March 12, 2023 12:45
-
-
Save M0r13n/5df080f2502565795a8f2d096dc7e69c to your computer and use it in GitHub Desktop.
Safe evaluation of mathematical expressions in Python.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ast | |
import operator as op | |
DEFINED_OPS = { | |
ast.Add: op.add, | |
ast.Sub: op.sub, | |
ast.Mult: op.mul, | |
ast.Div: op.truediv, | |
ast.USub: op.neg, | |
} | |
def safe_eval(node): | |
if isinstance(node, ast.Num): | |
return node.n | |
elif isinstance(node, ast.BinOp): | |
left = safe_eval(node.left) | |
right = safe_eval(node.right) | |
return DEFINED_OPS[type(node.op)](left, right) | |
elif isinstance(node, ast.UnaryOp): | |
return DEFINED_OPS[type(node.op)](safe_eval(node.operand)) | |
else: | |
print(type(node)) | |
raise TypeError(node) | |
def eval_expr(exp:str): | |
return safe_eval(ast.parse(exp, mode='eval').body) | |
if __name__ == '__main__': | |
assert eval_expr('1 + 1') == 2 | |
assert eval_expr('1 + 1 * 5') == 6 | |
assert eval_expr('(1 + 1) * 5') == 10 | |
assert eval_expr('((1 + 1) + 2) * 5') == 20 | |
assert eval_expr('((1 + - 1) + 2) * 5') == 10 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment