I googled little around for correct way to not reinventing of the wheel for expression evaluation (even I had done some simple evaluation check for my Tkinter calculator snippet earlier). After getting totally upset with this example, I made this with some struggles with __builtins__
globals parameter of eval. First I kept the dictionary of variables approach, then I turned to keyword parameters, the format is so much nicer.
To put some topping, I put __call__
also as synonym for evaluation. That means you can call the class as functions and give any values of variables as keyword parameters. See example at line 94. There you can see(line 92), that you can add to allowed functions dynamically, complex failed the first test. Be sure to append, not extend if you add single function name or interesting things happen ;)
Output of test cases:
abs(-3) = 3
name 'complex' is not defined
1 + float(2) + sin(x + y) / e + pi = 5.9787984802
name 'abc' is not defined
__ and builtins not allowed
dir() = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'dir', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'float', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'int', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'round', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'x', 'y']
name 'g' is not defined
__ and builtins not allowed
complex(z) = (-4.3+0j)
float(x) = 6.0