Calculator in python

后端 未结 7 953
别那么骄傲
别那么骄傲 2021-01-27 01:45

I am trying to make calculator that can solve expressions with basic 4 operators, like 1+2*3-4/5, however it does not work and I do not know what is wrong. Please check my code.

7条回答
  •  死守一世寂寞
    2021-01-27 02:35

    You partition the input string regardless, never checking if the operator is even there. .partition() returns empty strings if the partition character is not present in the input:

     >>> '1+1'.partition('*')
     ('1+1', '', '')
    

    So you'll call s.partition('*') but never check if there is any such operator present, resulting in unconditional calls to ret(). You'll always call ret(parts[0]) * ret(parts[2]) regardless of wether * is present in s or not.

    The solution is to either test for the operator first or to check the return value of .partition(). The latter is probably easiest:

    for c in ('+','-','*','/'):
        parts = s.partition(c)
        if parts[1] == '*':
            return ret(parts[0]) * ret(parts[2])
        elif parts[1] == '/':
            return ret(parts[0]) / ret(parts[2])
        elif parts[1] == '+':
            return ret(parts[0]) + ret(parts[2])
        elif parts[1] == '-':
            return ret(parts[0]) - ret(parts[2])
    

    Note that I reversed the operator order; yes, multiplication and division need to be applied before addition and subtraction, but you are working in reverse here; splitting up the expression into smaller parts, and the operations are then applied when the sub-expression has been processed.

    You could use assignment unpacking to assign the 3 return values of .partition() to easier names:

    for c in ('+','-','*','/'):
        left, operator, right = s.partition(c)
        if operator == '*':
            return ret(left) * ret(right)
        elif operator == '/':
            return ret(left) / ret(right)
        elif operator == '+':
            return ret(left) + ret(right)
        elif operator == '-':
            return ret(left) - ret(right)
    

    Next you can simplify all this by using the operator module, which has functions that perform the same operations as your arithmetic operations. A map should do:

    import operator
    ops = {'*': operator.mul, '/': operator.div, '+': operator.add, '-': operator.sub}
    
    for c in ('+','-','*','/'):
        left, operator, right = s.partition(c)
        if operator in ops:
            return ops[operator](ret(left), ret(right))
    

提交回复
热议问题