Calculator in python

后端 未结 7 845
别那么骄傲
别那么骄傲 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:19

    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!")
    
    0 讨论(0)
  • 2021-01-27 02:30

    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

    0 讨论(0)
  • 2021-01-27 02:34

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

    number = input("")
    print number
    
    0 讨论(0)
  • 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))
    
    0 讨论(0)
  • 2021-01-27 02:39

    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
    
    0 讨论(0)
  • 2021-01-27 02:41

    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!

    0 讨论(0)
提交回复
热议问题