Build a Calculator
We want to build a simple calculator that can solve arithmetic expressions like 2 + 2 or 4 * 5 - 10 * 2. Write a function calc(expr) that accepts a string as input and returns the answer as a number. It should follow the normal order of operations and support addition, subtraction, multiplication, and division. Don't worry about parentheses or improperly formatted strings.
Examples
calc("1 + 1") # => 2 calc("5 - 1 - 1") # => 3 calc("84 / 1 / 2") # => 42 calc("5/2 - 2*3") # => -3.5
Think about how you would solve the expression by hand and start with a simple example! You should solve sub-expressions like multiplication and division first, and then solve addition and subtraction.
Can you split the expression into sub-expressions and solve them individually?
Since you need the result of smaller expressions to calculate the final result, consider using a stack or recursion.
Does your solution solve the expression using the correct order of operations?
Does subtraction work as you would expect? What does "5 - 2 - 1" return?
This is actually a fairly challenging task to reason through correctly—it tests your logical reasoning as well as your ability to manipulate strings, numbers, and arrays, which makes it a great interview question.
We will implement calc() as a single recursive function. Recursion is a natural choice because math expressions can be easily split into sub-problems and combined later, but there are other valid ways to solve this problem that don't involve recursion. If you came up with a different solution, just make sure to test the functionality and think about the tradeoffs.
Here's how the recursive method works: When we find an operator character, we split the expression into left and right sides, evaluate both sides, and then combine them using the operator. Since recursive functions actually work 'backwards', starting with smaller sub-problems and working up, we actually need to write our procedure in the opposite order of operations—we check for addition and subtraction operators before multiplication and division.
Here's our final solution:
def calc(expr):
for op in ['+', '-', '*', '/']:
if op in expr:
left, right = expr.rsplit(op, 1)
if op == '+': return calc(left) + calc(right)
if op == '-': return calc(left) - calc(right)
if op == '*': return calc(left) * calc(right)
if op == '/': return calc(left) / calc(right)
# Base case: no more operators
return float(expr.strip())Remember, every recursive function needs a base case to prevent infinite recursion. Our base case is when we find a string that doesn't contain any operators, like "12". We simply strip any spaces from the string and cast it to a number with float(expr.strip()).
One detail worth noting: We used python's rsplit function to split our expression into two parts, starting from the right instead of the default left. This is a subtle but important point because subtraction and division are "non-commutative," in other words: the order matters!
def calc(expr): ans = eval(expr) return ans # your code goes # debug your code below print(calc("1 + 1"))