The best way to solve this would be to use Abstract Syntax Tree of Python. We can get that using ast
module.
import ast, _ast
ops = {_ast.Mult: "*", _ast.Add: "+", _ast.BitXor: "pow", _ast.Div: "/"}
def rec(n):
if isinstance(n, _ast.Expr):
return rec(n.value)
elif isinstance(n, _ast.BinOp):
if isinstance(n.op, _ast.BitXor):
return "{}({}, {})".format(ops[type(n.op)], rec(n.left),rec(n.right))
else:
return "({} {} {})".format(rec(n.left), ops[type(n.op)],rec(n.right))
elif isinstance(n, _ast.Name):
return n.id
elif isinstance(n, _ast.Num):
return n.n
print rec(ast.parse("(((a+b)^2) + ((c+d)^(1/2))) * e").body[0])
# ((pow((a + b), 2) + pow((c + d), (1 / 2))) * e)
Note: Since ^
means Binary XOR operation in Python, you need to enclose that expression with an extra parenthesis, like I have shown in the example.
First, we check if it is an expression, then we process its value. If it is a binary operation, we check of it is Bitwise XOR, in that case we return the result in a different format, otherwise we return the result like left op right
. If the current item looks like a name, then we return its id
or if it is a number we return the attribute n
.