I have a server running python which has the feature of acting as a simple calculator. I want it to be able to calculate things about as complex as a normal scientific calculator with simple functions. 1+1
, 4+(7*2)
, sin(12)-3
, etc. A google search brought up ast.literal_eval
but it seems to be useless for this case, as it only seems to handle one term at a time, and throws an error when given something simple like 1+1
. Here is the code I have now. Is there a better way to do this?
def safeeval(scaryuserinput):
mathfunctions = 'acos|acosh|asin|asinh|atan|atan2|atanh|ceil|copysign|cos|cosh|degrees|e|erf|erfc|exp|expm1|fabs|factorial|floor|fmod|frexp|fsum|gamma|hypot|isinf|isnan|ldexp|lgamma|log|log10|log1p|modf|pi|pow|radians|sin|sinh|sqrt|tan|tanh|trunc'
functions = []
functionre = re.compile(mathfunctions)
for x in re.findall(functionre, scaryuserinput):
functions.append(x)
scaryuserinput = scaryuserinput.replace("\x00", "")
scaryuserinput = functionre.sub("\x00", scaryuserinput)
scaryuserinput = ''.join([x for x in scaryuserinput if x in "1234567890+-/*^%(),.\x00"])
for x in functions:
scaryuserinput = scaryuserinput.replace("\x00", "math." + x, 1)
return eval(scaryuserinput)