Write a program to calculate the value of an expression step by step in Python:
Question:
Enter the string “(2 + 3 * 4) / 2 – (3^2 - 3)”. Export:
= (2 + 12) / 2 – (3^2 – 3)
= 14/2 – (3^2 – 3)
= 7 – (3^2 – 3)
= 7 – (9 – 3)
= 7 – 6
= 1
How should I deal with such results?
Answers:
Here’s some code that does something slightly like what you asked for:
import ast
import copy
expr = "(2 + 3 * 4) / 2 - (3**2 - 3)"
tree = ast.parse(expr,mode="eval")
class EvalLeaves(ast.NodeTransformer):
def visit_BinOp(self, node):
match node:
case ast.BinOp(left=ast.Constant(), right=ast.Constant()):
return ast.Constant(eval(compile(ast.Expression(ast.fix_missing_locations(node)), "<input>", "eval")))
case _:
return ast.BinOp(left=self.visit(node.left),op=node.op,right=self.visit(node.right))
print(expr)
while True:
new_tree = EvalLeaves().visit(copy.deepcopy(tree))
if ast.dump(tree) == ast.dump(new_tree):
break
tree = new_tree
print("=", ast.unparse(new_tree))
Output:
(2 + 3 * 4) / 2 - (3**2 - 3)
= (2 + 12) / 2 - (9 - 3)
= 14 / 2 - 6
= 7.0 - 6
= 1.0
Exercises/problems for the reader:
- evaluation order the same as in your example
- uses Python syntax, e.g.
**
for exponentiation rather than ^
Enter the string “(2 + 3 * 4) / 2 – (3^2 - 3)”. Export:
= (2 + 12) / 2 – (3^2 – 3)
= 14/2 – (3^2 – 3)
= 7 – (3^2 – 3)
= 7 – (9 – 3)
= 7 – 6
= 1
How should I deal with such results?
Here’s some code that does something slightly like what you asked for:
import ast
import copy
expr = "(2 + 3 * 4) / 2 - (3**2 - 3)"
tree = ast.parse(expr,mode="eval")
class EvalLeaves(ast.NodeTransformer):
def visit_BinOp(self, node):
match node:
case ast.BinOp(left=ast.Constant(), right=ast.Constant()):
return ast.Constant(eval(compile(ast.Expression(ast.fix_missing_locations(node)), "<input>", "eval")))
case _:
return ast.BinOp(left=self.visit(node.left),op=node.op,right=self.visit(node.right))
print(expr)
while True:
new_tree = EvalLeaves().visit(copy.deepcopy(tree))
if ast.dump(tree) == ast.dump(new_tree):
break
tree = new_tree
print("=", ast.unparse(new_tree))
Output:
(2 + 3 * 4) / 2 - (3**2 - 3)
= (2 + 12) / 2 - (9 - 3)
= 14 / 2 - 6
= 7.0 - 6
= 1.0
Exercises/problems for the reader:
- evaluation order the same as in your example
- uses Python syntax, e.g.
**
for exponentiation rather than^