单线计算器,无法弄清楚最后的功能

时间:2017-06-30 15:57:34

标签: python calculator

我在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函数中。任何人都可以弄清楚我做错了什么。

感谢。

1 个答案:

答案 0 :(得分:1)

您的计算方法无法按预期工作

HINT

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