单行计算器,无法弄清楚最后一个功能



我正在用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

我知道错误出在计算函数中。谁能弄清楚我做错了什么。

谢谢。

您的计算未按预期工作

提示

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

相关内容

最新更新