gpt4 book ai didi

python - 计算器输出错误答案

转载 作者:行者123 更新时间:2023-12-01 08:53:54 25 4
gpt4 key购买 nike

import math
def findNextOpr(txt):
if len(txt)<=0 or not isinstance(txt,str):
return "type error: findNextOpr"

# --- YOU CODE STARTS HERE
if type(txt) == str:
opr_list = ["+", "-", "*", "/", '^']
for i in range(len(txt)):
if txt[i] in opr_list:
return(i)
return(-1)




# --- CODE ENDS HERE


def isNumber(txt):
if not isinstance(txt, str):
return "type error: isNumber"
if len(txt)==0:
return False

# --- YOU CODE STARTS HERE
if type(txt) == str:
try:
float(txt)
return True
except ValueError:
return False

def getNextNumber(expr, pos):

if len(expr)==0 or not isinstance(expr, str) or pos<0 or pos>=len(expr) or not isinstance(pos, int):
return None, None, "type error: getNextNumber"
# --- YOU CODE STARTS HERE
txt = expr[pos:]
oprPos = findNextOpr(txt)
if oprPos != -1:
if isNumber(txt[:oprPos]) == True:
return float(txt[:oprPos]), txt[oprPos], oprPos+pos

else:
return None, txt[oprPos], oprPos+pos
else:
if isNumber(txt):
return float(txt), None, None

else:
return None,None,None
# --- CODE ENDS HERE

def exeOpr(num1, opr, num2):

#This function is just an utility function for calculator(expr). It is skipping type check

if opr=="+":
return num1+num2
elif opr=="-":
return num1-num2
elif opr=="*":
return num1*num2
elif opr=="/":
return num1/num2
elif opr=="^":
return num1**num2
else:
return "error in exeOpr"


def calculator(expr):
if len(expr)<=0 or not isinstance(expr,str):
return "error"

expr = expr.strip()
if expr[0]!="-":
newNumber, newOpr, oprPos = getNextNumber(expr, 0)

else:
newNumber, newOpr, oprPos = getNextNumber(expr, 1)
newNumber *= -1

if newNumber is None:
return "error"

elif newOpr is None:
return newNumber

elif newOpr=="+" or newOpr=="-":
mode="add"
addResult=newNumber
mulResult=None
expResult=None

elif newOpr=="*" or newOpr=="/":
mode="mul"
addResult=0
mulResult=newNumber
expResult=None

elif newOpr=="^":
mode="exp"
expResult=newNumber
addResult=0
mulResult=None
pos=oprPos+1
opr=newOpr
oldopr=None

while True:
newNumber, newOpr, oprPos = getNextNumber(expr, pos)
if newNumber is None:
return "input error: line B in calculator"

elif newOpr is None:
if mode=='add':
if opr=='*':
return exeOpr(addResult, oldopr, mulResult*newNumber)
elif opr=='/':
return exeOpr(addResult, oldopr, mulResult/newNumber)
else:
return exeOpr(addResult, opr, newNumber)
elif mode=='mul':
if expResult==None:
expResult=0

if mulResult==None:
mulResult=0
return addResult + exeOpr(mulResult, opr, newNumber)

elif mode=="exp":
if expResult<0:
expResult=exeOpr(expResult,opr,newNumber)
if expResult>0:
expResult=-1*expResult

else:
expResult=exeOpr(expResult,opr,newNumber)

if mulResult!=0 and (oldopr=='*' or oldopr=='/'):
mulResult=exeOpr(mulResult,oldopr,expResult)
expResult=0

elif newOpr=='+' or newOpr=='-':
if expResult==None:
expResult=0

if mulResult==None:
mulResult=0

if mode=='add':
addResult = exeOpr(addResult, opr, newNumber)
mulResult = 0
expResult= 0

elif mode=='mul':
addResult += exeOpr(mulResult, opr, newNumber)
mulResult = 0
expResult= 0

elif mode=='exp':
if expResult<0:
expResult=exeOpr(expResult,opr,newNumber)
if expResult>0:
expResult=-1*expResult
addResult+=expResult

else:
addResult+=exeOpr(expResult,opr,newNumber)

if oldopr=='*' or oldopr=='/':
expResult=exeOpr(expResult,opr,newNumber)
mulResult=exeOpr(mulResult,oldopr,expResult)
addResult+=mulResult

mulResult = 0
expResult = 0

mode='add'

elif newOpr=="*" or newOpr=="/":
if mode=='add':
if opr=='-':
oldopr='-'
mulResult = newNumber

elif opr=='+':
#print('here1')
oldopr='+'
mulResult = newNumber
mode='mul'
else:
mulResult = newNumber

elif mode=='mul':
mulResult = exeOpr(mulResult, opr, newNumber)

elif mode=='exp':
if expResult<0:
expResult=exeOpr(expResult,opr,newNumber)
if expResult>0:
expResult=-1*expResult
else:
expResult=exeOpr(expResult,opr,newNumber)

if mulResult !=0 and (oldopr=='*' or oldopr=='/'):
mulResult=exeOpr(mulResult,oldopr,expResult)
expResult=0

else:
mulResult=expResult
expResult=0
mode='mul'
elif newOpr=='^':
if mode=='add':
if expResult==None:
expResult=0

if mulResult==None:
mulResult=0

if opr=='-':
expResult = -newNumber

else:
expResult = newNumber
oldopr=opr
elif mode=='mul':
expResult=newNumber
oldopr=opr

mode='exp'

if oprPos==None:
break

pos=oprPos + 1
opr=newOpr

if mulResult== None:
mulResult=0

if expResult==None:
expResult=0

return addResult+mulResult+expResult

上面是我的函数计算器代码,没有任何错误,但是当我运行代码并尝试时计算器('-5 + 60/3^3 * 4 - 2 * 4^2')我得到 35.888888888888886 但答案应该是 -28.11111111111111我的代码中是否存在我找不到的错误?我认为它可能在计算器部分,因为其他一切都可以在测试中完美运行,但我只是找不到在哪里。

有人告诉我,在类里面解决问题的一种方法是使用节点/堆栈类可能会有所帮助,但是除了创建另一个类之外还有其他解决方案吗

最佳答案

calculator大循环中,当opr-时,您忘记更改mulResult的符号。

为了调试它,我在exeOpr函数中添加了一条打印语句,以便我们可以看到计算器在每一步都在做什么。那么通过查看部分结果就很容易确定了。

完整的新代码如下:

    import math

def findNextOpr(txt):
if len(txt) <= 0 or not isinstance(txt, str):
return "type error: findNextOpr"

# --- YOU CODE STARTS HERE
if type(txt) == str:
opr_list = ["+", "-", "*", "/", '^']
for i in range(len(txt)):
if txt[i] in opr_list:
return (i)
return (-1)


# --- CODE ENDS HERE


def isNumber(txt):
if not isinstance(txt, str):
return "type error: isNumber"
if len(txt) == 0:
return False

# --- YOU CODE STARTS HERE
if type(txt) == str:
try:
float(txt)
return True
except ValueError:
return False


def getNextNumber(expr, pos):
if len(expr) == 0 or not isinstance(expr, str) or pos < 0 or pos >= len(expr) or not isinstance(pos, int):
return None, None, "type error: getNextNumber"

# --- YOU CODE STARTS HERE
txt = expr[pos:]
oprPos = findNextOpr(txt)
if oprPos != -1:
if isNumber(txt[:oprPos]):
return float(txt[:oprPos]), txt[oprPos], oprPos + pos

else:
return None, txt[oprPos], oprPos + pos
else:
if isNumber(txt):
return float(txt), None, None
else:
return None, None, None


# --- CODE ENDS HERE

def exeOpr(num1, opr, num2):
# This function is just an utility function for calculator(expr). It is skipping type check
print("%s %s %s" % (num1, opr, num2)) # <==== DEBUGGING PRINT

if opr == "+":
return num1 + num2
elif opr == "-":
return num1 - num2
elif opr == "*":
return num1 * num2
elif opr == "/":
return num1 / num2
elif opr == "^":
return num1 ** num2
else:
return "error in exeOpr"


def calculator(expr):
if len(expr) <= 0 or not isinstance(expr, str):
return "error"

expr = expr.strip()
if expr[0] != "-":
newNumber, newOpr, oprPos = getNextNumber(expr, 0)

else:
newNumber, newOpr, oprPos = getNextNumber(expr, 1)
newNumber *= -1

if newNumber is None:
return "error"

elif newOpr is None:
return newNumber

elif newOpr == "+" or newOpr == "-":
mode = "add"
addResult = newNumber
mulResult = None
expResult = None

elif newOpr == "*" or newOpr == "/":
mode = "mul"
addResult = 0
mulResult = newNumber
expResult = None

elif newOpr == "^":
mode = "exp"
expResult = newNumber
addResult = 0
mulResult = None
pos = oprPos + 1
opr = newOpr
oldopr = None

while True:
newNumber, newOpr, oprPos = getNextNumber(expr, pos)
if newNumber is None:
return "input error: line B in calculator"

elif newOpr is None:
if mode == 'add':
if opr == '*':
return exeOpr(addResult, oldopr, mulResult * newNumber)
elif opr == '/':
return exeOpr(addResult, oldopr, mulResult / newNumber)
else:
return exeOpr(addResult, opr, newNumber)
elif mode == 'mul':
if expResult == None:
expResult = 0

if mulResult == None:
mulResult = 0
return addResult + exeOpr(mulResult, opr, newNumber)

elif mode == "exp":
if expResult < 0:
expResult = exeOpr(expResult, opr, newNumber)
if expResult > 0:
expResult = -1 * expResult

else:
expResult = exeOpr(expResult, opr, newNumber)

if mulResult != 0 and (oldopr == '*' or oldopr == '/'):
mulResult = exeOpr(mulResult, oldopr, expResult)
expResult = 0

elif newOpr == '+' or newOpr == '-':
if expResult == None:
expResult = 0

if mulResult == None:
mulResult = 0

if mode == 'add':
addResult = exeOpr(addResult, opr, newNumber)
mulResult = 0
expResult = 0

elif mode == 'mul':
addResult += exeOpr(mulResult, opr, newNumber)
mulResult = 0
expResult = 0

elif mode == 'exp':
if expResult < 0:
expResult = exeOpr(expResult, opr, newNumber)
if expResult > 0:
expResult = -1 * expResult
addResult += expResult

else:
addResult += exeOpr(expResult, opr, newNumber)

if oldopr == '*' or oldopr == '/':
expResult = exeOpr(expResult, opr, newNumber)
mulResult = exeOpr(mulResult, oldopr, expResult)
addResult += mulResult

mulResult = 0
expResult = 0

mode = 'add'

elif newOpr == "*" or newOpr == "/":
if mode == 'add':
if opr == '-':
oldopr = '-'
mulResult = -newNumber # <====== THIS IS THE PLACE I CHANGED

elif opr == '+':
# print('here1')
oldopr = '+'
mulResult = newNumber
mode = 'mul'
else:
mulResult = newNumber

elif mode == 'mul':
mulResult = exeOpr(mulResult, opr, newNumber)

elif mode == 'exp':
if expResult < 0:
expResult = exeOpr(expResult, opr, newNumber)
if expResult > 0:
expResult = -1 * expResult
else:
expResult = exeOpr(expResult, opr, newNumber)

if mulResult != 0 and (oldopr == '*' or oldopr == '/'):
mulResult = exeOpr(mulResult, oldopr, expResult)
expResult = 0

else:
mulResult = expResult
expResult = 0
mode = 'mul'
elif newOpr == '^':
if mode == 'add':
if expResult == None:
expResult = 0

if mulResult == None:
mulResult = 0

if opr == '-':
expResult = -newNumber

else:
expResult = newNumber
oldopr = opr
elif mode == 'mul':
expResult = newNumber
oldopr = opr

mode = 'exp'

if oprPos == None:
break

pos = oprPos + 1
opr = newOpr

if mulResult == None:
mulResult = 0

if expResult == None:
expResult = 0

return addResult + mulResult + expResult


x = calculator('-5 + 60 / 3^3 * 4 - 2 * 4^2')
print(x)

关于python - 计算器输出错误答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52910371/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com