Calculator in python

女生的网名这么多〃 提交于 2020-01-05 13:52:49

问题


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. When I run it, I am getting infinte number of errors in 8. line return ret(parts[0]) * ret(parts[2]) Here is code

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

回答1:


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))



回答2:


The main thing you are doing wrong is that you are checking the value of c rather that the partitioned operator. You can also unpack the result from s.partition to make things a little easier by using left and right for the actual operations.

def ret(s):
    s = str(s)
    if s.isdigit():
        return float(s)
    for c in ('-','+','*','/'):
        left, op, right = s.partition(c)
        if op == '*':
            return ret(left) * ret(right)
        elif op == '/':
            return ret(left) / ret(right)
        elif op == '+':
            return ret(left) + ret(right)
        elif op == '-':
            return ret(left) - ret(right)
print(ret('1+2'))

Also, you will need to reverse the order of your operations as you want to first do addition and subtraction, followed by multiplication and division.

What I mean is, if you have an expression like 4+4*3, you want to divide it into

ret(4) + ret(4 * 3)

Since it is a recursive call, you want the operators with the highest precedence to be the last on the call stack so they are executed first when the function returns.

As an example:

print(ret('1+2*6'))
print(ret('3*8+6/2'))

OUTPUT

13.0
27.0



回答3:


In your code you have no condition on the result of s.partition(c), so even if the partition results in ('anything', '', '') you will do a recursion on the first if.

Edited




回答4:


Here is a simple python calculator program, feel free to use it:

#Python calculator

def menu():
    print ("Welcome to calculator.py")
    print ("your options are:")
    print (" ")
    print ("1) Addition")
    print ("2) Subtraction")
    print ("3) Multiplication")
    print ("4) Division")
    print ("5) Quit calculator.py")
    print (" ")
    return input ("Choose your option: ")

def add(a,b):
    print (a, "+", b, "=", a + b)

def sub(a,b):
    print (b, "-", a, "=", b - a)

def mul(a,b):
    print (a, "*", b, "=", a * b)

def div(a,b):
    print (a, "/", b, "=", a / b)

loop = 1
choice = 0
while loop == 1:
    choice = menu()
    if choice == 1:
        add(input("Add this: "),input("to this: "))
    elif choice == 2:
        sub(input("Subtract this: "),input("from this: "))
    elif choice == 3:
        mul(input("Multiply this: "),input("by this: "))
    elif choice == 4:
        div(input("Divide this: "),input("by this: "))
    elif choice == 5:
        loop = 0

print ("Thank you for using calculator.py!")



回答5:


Your dispatching is incorrect. The way you defined your function it will always try to split by '*', which basically calls the ret function recursively with the same arguments...

You'll have to check first whether an "operator" is present in your argument string at all.

Think again!




回答6:


I have an alternative to your code. The user can enter stuff like: 8*6/4-3+3 and this will still work. Very compact and if you want a command to exit out of the:

while True:

Just add:

if(y == "end" or y == "End"):
    break

And it will exit out of the "while True:"

Code (Python v3.3.0):

while True:
    x = "x="
    y = input(" >> ")
    x += y
    exec(x)
    print(x)



回答7:


Here is simple code in python for creating a calculator same as in Python terminal.

number = input("")
print number


来源:https://stackoverflow.com/questions/15109396/calculator-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!