我在python中编写一个单行计算器。它需要能够接受任何长度的表达式和多个运算符。然后它按照操作顺序返回答案。
即。 “2/4 - 2 * 3 + 4”,它返回-1.5
这是我到目前为止所拥有的
def findNextOpr(s): #DONE
#this function is used to find the next operator in the string s
if len(s)<=0 or not isinstance(s,str):
print("type mimatch error: findNextOpr")
return "type mimatch error: findNextOpr"
s = list(s) #converts s to a list
operator = ["+", "-", "/", "*"]
for i in s:
if i in operator:
return i
else:
return -1
def isNumber(s): #DONE
#this function is used to check if it's a number
#checks if string s meets the requirements
if len(s)==0 or not isinstance(s, str):
print("type mismatch error: isNumber")
return "type mismatch error: isNumber"
#strip string of all whitespace.
s = s.strip(" ")
s = s[0:] #removes minus signs but only from the front of string
try: #checks to make sure s2 is a number and doesn't have more than 1 period
s=float(s)
return True
except:
return False
def getNextNumber(expr, pos): #DONE
#checks to make sure expr and pos match the requirements. returns error if they don't
if len(expr)==0 or not isinstance(expr, str) or pos<0 or pos>=len(expr) or not isinstance(pos, int):
print("type mismatch error: getNextNumber")
return None, None, "type mismatch error: getNextNumber"
s = expr[pos:] #sets string1 equal to position that was passed
op=['-','+','*','/']
newOpr = findNextOpr(s) #newOpr equals left-most operator, calls findNext to achieve this
if newOpr in op:
if expr.find(newOpr,pos)>=pos:
oprPos=expr.find(newOpr,pos)
else:
newOpr=None
if newOpr==None:
oprPos = None
if isNumber(expr[pos:oprPos]): #checks to make sure if string is actually a #
newNumber = float(expr[pos:oprPos])
else:
newNumber = None #if it is a #, assigns value to newNumber
return newNumber, newOpr, oprPos
def exeOpr(num1, opr, num2):
#This is a simple utility function skipping type check
if opr=="+":
return num1+num2
elif opr=="-":
return num1-num2
elif opr=="*":
return num1*num2
elif opr=="/":
return num1/num2
else:
return None
def calc(expr):
#the below line checks if expr is a string
if not isinstance(expr, str) or len(expr) <= 0:
print("argument error: line A in eval_expr")
return "argument error: line A in eval_expr"
#below line creates three variables
#sets them equal to whatever is returned by the getNextNumber function
#the getNextNumber function is called. It passes the expr and integer 0
newNumber, newOpr, oprPos = getNextNumber(expr, 0)
#if newNumber is none, return error
#if newOpr is none, return newNumber
#if newOpr is add/sub set mode=add, create addResult=newNumber and mulResult = None
#if newOpr is mult/div set mode=mul, crate addResult=0 and mulResult=newNumber
if newNumber is None:
print("input formula error: line B in eval_expr")
return "input formula error: line B in eval_expr"
elif newOpr is None:
return newNumber
elif newOpr=="+" or newOpr=="-":
mode="add"
addResult=newNumber #saves # at first index to addResult if 1st operator is + or -
mulResult=None
elif newOpr=="*" or newOpr=="/":
mode="mul"
addResult=0
lastOpr = "+"
mulResult=newNumber #saves # at first index to mulResult if 1st operator is + or -
#pos and opr are created
pos=oprPos+1 #current positon
opr=newOpr #current operator
while True:
newNumber, newOpr, oprPos = getNextNumber(expr, pos)
#--- code while loop ---#
while True:
newNumber, newOpr, oprPos=getNextNumber(expr, pos)
#if expr[pos:] == " 3- 2*1":
# pdb.set_trace()
if newNumber== None and pos>=len(expr):
return "Expression error"
elif newOpr== None and mode=='add':
return exeOpr(addResult, opr, newNumber)
elif newOpr== None and mode=='mul':
return exeOpr(mulResult, opr, newNumber)
elif (newOpr== "+" or newOpr=='-') and mode=='add' :
addResult= exeOpr(addResult,opr,newNumber)
pos= oprPos+1
opr=newOpr
elif (newOpr=="*" or newOpr=='/') and mode=='add':
addResult= newNumber
lastOpr= opr
mulResult= exeOpr(addResult,newOpr, newNumber)
mode='mul'
pos= oprPos+1
opr=newOpr
elif (newOpr=="*" or newOpr=="/") and mode=="mul":
mulResult= exeOpr(mulResult, opr, newNumber)
pos= oprPos+1
opr=newOpr
elif (newOpr=="-" or newOpr=='+') and mode=="mul":
mulResult=exeOpr(mulResult,opr, newNumber)
addResult= exeOpr(mulResult, lastOpr, newNumber)
mode="add"
pos= oprPos+1
opr=newOpr
#--- end of function ---#
expr = "2 / 4 - 2 * 3 + 4"
print(calc(expr))
除输出外,一切正常。当我运行程序时,我得到了13.0的答案
我知道错误在calc函数中。任何人都可以弄清楚我做错了什么。
感谢。
答案 0 :(得分:1)
您的计算方法无法按预期工作
def exeOpr(num1, opr, num2):
#This is a simple utility function skipping type check
if opr=="+":
print "{} + {}".format(num1, num2)
return num1+num2
elif opr=="-":
print "{} - {}".format(num1, num2)
return num1-num2
elif opr=="*":
print "{} * {}".format(num1, num2)
return num1*num2
elif opr=="/":
print "{} / {}".format(num1, num2)
return num1/num2
else:
return None
<强>输出强>
2.0 / 4.0
0.5 + 4.0
2.0 * 2.0
4.0 * 3.0
12.0 - 3.0
9.0 + 4.0
13.0