Home > Back-end >  using python recursion to calculate the Parenthesis part not working
using python recursion to calculate the Parenthesis part not working

Time:02-06

If I enter input with parentheses it resolves only what is inside the parentheses and not what is after or before, if I enter two expressions with parentheses it returns None. you can see it in the code.

def divide(a, b):
    return a/b
def pow(a, b):
    return a**b
def addA(a, b):
    return a b
def subA(a, b):
    return a-b
def mul (a, b):
    return a*b
operators = {
  ' ': addA,
  '-': subA,
  '*': mul,
  '/': divide,
  '^' : pow,


}

def calculate(s):
    if s.isdigit():
        return float(s)
    elif '[' in s:
        start = s.index('[')
        end = s.rindex(']')
        return calculate(s[start   1:end])
    for c in operators.keys():
        left, operator, right = s.partition(c)
        if operator in operators:
            return operators[operator](calculate(left), calculate(right))

calc = input("Type calculation:\n")
print("Answer: "   str(calculate(calc)))

input: [2 2] [2 2] output: None

input [2 3]*2 output 5

CodePudding user response:

Nice idea.

    elif '[' in s:
        ...
        return calculate(s[start   1:end])

Beautifully simple. But, alas, wrong.

Consider 1 1 1 [8 9] 2 2 2.

Is there a [ bracket in there? Yes. And the recursive call correctly computes 17. But we're ignoring the 1's and the 2's.

Also, when the for finishes and we fall of the end of the function we return None. Consider doing something else in that case, perhaps raise a fatal error.


You probably want to invert the order of operations, so higher priority ops will bind more tightly.


You will find you can iterate through the edit - debug cycle much more quickly if you write some simple unit tests that lock in "working" behavior. Only the last test fails ATM.

class CalculateTest(unittest.TestCase):
    def test_addition(self):
        self.assertEqual(5, calculate("2 3"))
        self.assertEqual(5, calculate("[2 3]"))
        self.assertEqual(9, calculate("2 3 4"))
        self.assertEqual(9, calculate("2 [3 4]"))

I found it convenient to have the function always return a float.


Once you have this function in better shape, please let us know how it turned out.

CodePudding user response:

You're encountering the problem because the calculate function only takes into account the first occurrence of an operator in the string s, and it doesn't handle expressions with multiple pairs of parentheses.

You can modify the calculate function to recursively evaluate expressions inside multiple pairs of parentheses until there's only one set of parentheses left, and then perform the calculation.

Try the following:

def extract_expression(s):
    start = s.index('[')
    end = s.rindex(']')
    return s[start   1:end]

def calculate(s): 
    while '[' in s:
        sub_expression = extract_expression(s)
        result = calculate(sub_expression)
        s = s.replace('['   sub_expression   ']', str(result))

    if s.isdigit():
        return float(s)

    for c in operators.keys():
        left, operator, right = s.partition(c)
        if operator in operators:
            return operators[operator](calculate(left), calculate(right))

calc = input("Type calculation:\n")
print("Answer: "   str(calculate(calc)))

input: [2 2] [2 2]

output: 8.0

input: [2 3]*2

output: 10.0

  • Related