Reputation: 1042
I am trying to write a basic s-expression calculator in Python using s-expression which can contains add or multiply or both or none or just an integar number.
I tried the following snippet:
def calc(expr):
print(expression[0])
if isinstance(expr, int):
return expr
elif expr[0] == '+':
return calc(expr[1]) + calc(expr[2])
elif expr[0] == '*':
return calc(expr[1]) * calc(expr[2])
else:
raise ValueError("Unknown operator: %s" % expr[0])
# Example usage
# expression = ('+', ('*', 3, 4), 5)
expression = (7)
result = calc(expression)
print(result)
When I tried to pass the expression ('+', ('*', 3, 4), 5)
, it gives the correct answer but when I just try to use number 7 or 7 inside tuple (7), it gives the above error. How to solve this?
Upvotes: 0
Views: 70
Reputation: 3735
You print
used to debug is not correctly placed, or assume expression to be a Sequence, not an int.
[Good practice] Don't print a global variable but local: print(expr)
.
This is less confusing and will help you for debugging this code.
[Branch simplification] Replace every elif
with if
. Since you return in every branch, you don't need elif
. Remove the else
too. This will allows you to place code after the first if that will be run for all remaining branches without having to place it in every elif
.
def calc(expr: int | tuple):
print(expr)
if isinstance(expr, int):
return expr
if expr[0] == '+':
return calc(expr[1]) + calc(expr[2])
if expr[0] == '*':
return calc(expr[1]) * calc(expr[2])
raise ValueError("Unknown operator: %s" % expr[0])
print
below the first if
.def calc(expr: int | tuple):
if isinstance(expr, int):
return expr
print(expr)
if expr[0] == '+':
return calc(expr[1]) + calc(expr[2])
if expr[0] == '*':
return calc(expr[1]) * calc(expr[2])
raise ValueError("Unknown operator: %s" % expr[0])
This code works, both for (7)
and ('+', ('*', 3, 4), 5)
.
Upvotes: 0