简体   繁体   English

"python中的计算器"

[英]Calculator in python

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.我正在尝试制作可以使用基本 4 个运算符解决表达式的计算器,例如 1+2*3-4\/5,但是它不起作用,我不知道出了什么问题。 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])<\/code> Here is code当我运行它时,我在 8 中得到了无数个错误。 line return ret(parts[0]) * ret(parts[2])<\/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'))

The main thing you are doing wrong is that you are checking the value of c rather that the partitioned operator.您做错的主要事情是您正在检查c的值而不是分区运算符。 You can also unpack the result from s.partition to make things a little easier by using left and right for the actual operations.您还可以解包s.partition的结果,通过使用 left 和 right 进行实际操作,使事情变得更容易一些。

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我的意思是,如果你有一个像4+4*3这样的表达式,你想把它分成

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

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:如果输入中不存在分区字符, .partition()将返回空字符串:

 >>> '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() .所以,你会打电话给s.partition('*')但从来没有检查是否任何这样的运营商存在,导致无条件调用ret() You'll always call ret(parts[0]) * ret(parts[2]) regardless of wether * is present in s or not.无论*是否存在于s您都会始终调用ret(parts[0]) * ret(parts[2])

The solution is to either test for the operator first or to check the return value of .partition() .的解决方案是用于测试的操作者首先或检查的返回值.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:您可以使用分配解包将.partition()的 3 个返回值分配给更简单的名称:

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.接下来,您可以使用operator模块简化所有这些,该模块具有执行与算术运算相同的操作的函数。 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))

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...您定义函数的方式将始终尝试按“*”分割,它基本上使用相同的参数递归调用 ret 函数...

You'll have to check first whether an "operator" is present in your argument string at all.您必须首先检查参数字符串中是否存在“运算符”。

Think again!再想一想!

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.在您的代码中,您对s.partition(c)的结果没有条件,因此即使分区结果为('anything', '', '')您也会对第一个 if 进行递归。

Edited已编辑

Here is a simple python calculator program, feel free to use it:这是一个简单的python计算器程序,请随意使用:

#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!")

how to condition users input of number 1 & number 2, if its in string.如果它在字符串中,如何调节用户输入的数字 1 和数字 2。 with if/else or try/except.使用 if/else 或 try/except。

print("\n Select A Number \n")
print("Press 1 for Addition")
print("Press 2 for Subtraction")
print("Press 3 for multiplication")
print("Press 4 for Division \n")

while True:
    user = input("Enter A Choice(1/2/3/4): ")
    if user in ('1','2','3','4'):
        num1 = int(input("Enter First Number: "))
        num2 = int(input("Enter Second Number: "))

        if user == '1':
            print(f"{num1} + {num2} = {num1 + num2}")
            print("Thanks For Usnig This Calculator")
        elif user == '2':
            print(f"{num1} - {num2} = {num1 - num2}")
            print("Thanks For Usnig This Calculator")
        elif user == '3':
            print(f"{num1} * {num2} = {num1 * num2}")
            print("Thanks For Usnig This Calculator")
        elif user == '4':
            print(f"{num1} / {num2} = {num1 / num2}")
            print("Thanks For Usnig This Calculator")
        else:
            print("Please Enter Correct Choice")
    else:
        print("Invalid")
#1. Create a class with the name Calculator
class Calculator:
    #2. Declare two class variables num1 and num2
    num1=""
    num2=""
    result=""
    option=""
    #3. Initialize the class variables num1 and num2 in constructor __init__()
    def __init__(self):
        self.num1=0
        self.num2=0
        self.result=0
        self.option=0
    #4. Make getter and setter function for variables
    def getNum1(self):
        return self.num1
    def setNum1(self,n1):
        self.num1=n1 
    def getNum2(self):
        return self.num2
    def setNum2(self,n2):
        self.num2=n2
    def getResult(self):
        return self.result
    def setResult(self,r):
        self.result=int(r)
    def getOption(self):
        return self.option
    def setOption(self,op):
        self.option=op
    
    #5. Create Main Manu function to display choices
    def mainMenu(self):
        print("==============")
        print("==CALCULATOR==")
        print("==============")
        print("Menu:")    
        print("1. Addtion")
        print("2. Subtraction")
        print("3. Multiplication")
        print("4. Division")
        print("5. Remainer")
        print("6. Exit")
        print("")
        self.setOption(int(input("Enter Option:")))
        self.setNum1(int(input("Enter Number1:")))
        self.setNum2(int(input("Enter Number2:")))
        
    #6. Make a function Take Input
    def takeInput(self):
        if self.option==1:
            self.setResult(self.getNum1()+self.getNum2())
        elif self.option==2:
            self.setResult(self.getNum1()-self.getNum2())
        elif self.option==3:
            self.setResult(self.getNum1()*self.getNum2())
        elif self.option==4:
            self.setResult(self.getNum1()/self.getNum2())
        elif self.option==5:
            self.setResult(self.getNum1()%self.getNum2())
            
    #7. Make a display function to display the output
    def display(self):
        resultOption=""
        print("")
        if self.option==1:
            resultOption="Addition"
        elif self.option==2:
            resultOption="Subtraction"
        elif self.option==3:
            resultOption="Multiplication"
        elif self.option==4:
            resultOption="Division"
        elif self.option==5:
            resultOption="Remainder"
        if self.option==1 or self.option==2 or self.option==3 or self.option==4 or self.option==5:
            print(resultOption+":"+str(self.getResult()))
        else:
            print("Invalid Input")
        self.option=input("press x to exit, 0 to continue...")
        if self.option=="x":
            pass
        else:
            self.option=int(self.option)
            

#8. Create Object of Calculator Class  
c1=Calculator()
op=0

#9. Get option in while loop until x is pressed
while(c1.getOption()!='x'):
    #10.    Call display menu, input and display functions to display the output
    c1.mainMenu()
    c1.takeInput()
    c1.display()

I have an alternative to your code.我有一个替代你的代码。 The user can enter stuff like: 8*6/4-3+3 and this will still work.用户可以输入如下内容:8*6/4-3+3 并且这仍然有效。 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:"它将退出“while True:”

Code (Python v3.3.0):代码(Python v3.3.0):

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

Here is simple code in python for creating a calculator same as in Python terminal.这是 Python 中的简单代码,用于创建与 Python 终端中相同的计算器。

number = input("")
print number

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM