Калькулятор назначения в том, что не может использовать оценку. Это дает тип ошибки: объект 'NoneType' не повторяется в последней функции

1

Учитель дал нам код для этого задания, которое должно быть использовано. проблема возникает, когда цикл while в функции калькулятора имеет тип "Нет" в качестве объекта с возможностью итерации в цикле. Я не знаю, как это исправить и все еще отвечаю требованиям назначения.

Я попытался найти способ заставить его запустить эту конкретную итерацию и изменить тип, но я не уверен.

Есть ли способ, которым я могу просто заставить его игнорировать ошибку и запустить последнюю итерацию?

def findNextOpr(txt):
    """
        Takes a string and returns -1 if there is no operator in txt, otherwise returns 
        the position of the leftmost operator. +, -, *, / are all the 4 operators

        >>> findNextOpr('  3*   4 - 5')
        3
        >>> findNextOpr('8   4 - 5')
        6
        >>> findNextOpr('89 4 5')
        -1
    """
    if len(txt)<=0 or not isinstance(txt,str):
        return "type error: findNextOpr"

    # --- YOU CODE STARTS HERE
    if txt.find("-") != -1 or txt.find("+") != -1 or txt.find("*") != -1 or txt.find("/") != -1:
        minus = txt.find("-")
        plus = txt.find("+")
        div = txt.find("/")
        mult = txt.find("*")

        if mult == -1:
            mult = 1000000000000000000
        if div == -1:
            div = 10000000000000000000
        if minus == -1:
            minus = 100000000000000000000
        if plus == -1:
            plus = 1000000000000000000000


        if mult < div and mult < plus and mult < minus:
            hold = mult
        elif div < mult and div < plus and div < minus:
            hold = div
        elif minus < div and minus < plus and minus < mult:
            hold = minus
        else:
            hold = plus

        return hold

    return -1

"""
    l = len(txt)
    txtOut = ''
    for i in range(0, l, 1):
        hold = expr[i]
        # a new str is made from the old rather than the messy process of mutilating it
        #if hold == " ":
        #   txtOut += str("")
        #else:
        txtOut += str(hold)

"""

    # ---  CODE ENDS HERE


def isNumber(txt):
    """
        Takes a string and returns True if txt is convertible to float, False otherwise 

        >>> isNumber('1   2 3')
        False
        >>> isNumber('-  156.3')
        False
        >>> isNumber('29.99999999')
        True
        >>> isNumber('    5.9999 ')
        True
    """
    if not isinstance(txt, str):
        return "type error: isNumber"
    if len(txt)==0:
        return False

    # --- YOU CODE STARTS HERE
    l = len(txt)
    txtOut = ''
    txt = txt.lower()
    l = len(txt)
    safe = True
    safeSpace = True
    terminateNext = False
    txtOut = ''
    for i in range(0, l, 1):
        hold = txt[i]
        test = hold.isdigit()

        if hold == ".":
            if safe == True:
                test = True
                safe = False

            else:
                return False

        if hold == " ":
            if safeSpace == True:
                test = True
            if safeSpace == False:
                test = True
                terminateNext = True

        if hold == "-" and safeSpace:
            test = True
            safeSpace = False


        if test == False:
            return False

        else:
            txtOut += str(hold)
            if hold.isdigit():
                safeSpace = False
                if terminateNext == True:
                        return False
    return True


    # ---  CODE ENDS HERE

def getNextNumber(expr, pos):
    """
        expr is a given arithmetic formula of type string
        pos is the start position in expr
          1st returned value = the next number (None if N/A)
          2nd returned value = the next operator (None if N/A)
          3rd retruned value = the next operator position (None if N/A)

        >>> getNextNumber('8  +    5    -2',0)
        (8.0, '+', 3)
        >>> getNextNumber('8  +    5    -2',4)
        (5.0, '-', 13)
        >>> getNextNumber('4.5 + 3.15         /   5',0)
        (4.5, '+', 4)
        >>> getNextNumber('4.5 + 3.15         /   5',10)
        (None, '/', 19)
    """

    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

    operator = findNextOpr(expr[pos:])
    if operator == -1:
        newNumber1 = float(expr[len(expr)-1])
        opElement = None
        opOut = None
    else:


        opOut = operator + pos
        hold = expr[pos:opOut].strip()

        #if hold == '-' or hold == '+' or hold == '/' or hold == "*" and l > 1:
        if isNumber(hold):
            newNumber1 = float(hold)
            opElement = expr[pos + operator]


        else:
            newNumber1 = None
            opElement = expr[pos + operator]
        return newNumber1, opElement, opOut


    """txtOut = ''
    txtNext = ''
    opElement = ''
    newNumber1 = None
    txt = expr.lower()
    l = len(txt)
    i= 0

    for i in range(pos, l, 1):
        hold = txt[i]

        if hold == '-' or hold == '+' or hold == '/' or hold == "*" and l > 1:
            break
        txtOut += hold

    if isNumber(txtOut) == True:
        print(txtOut)
        newNumber1 = float(txtOut)
    else:
        print("Error fix if you see this")

    for z in range(pos, (i-1), 1):
        hold = txt[z]
        txtNext += hold

    operator = findNextOpr(txtNext)
    if operator == -1:
        opOut = None
        opElement = None
    else:
        opOut = operator
        opElement = txtNext[operator]



    return newNumber1,opElement ,opOut

    #getNextNumber(txtNext,findNextOpr(txtNext))"""

    # ---  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
    else:
        return "error in exeOpr"


def calculator(expr):
    """
        Takes a string and returns the calculated result if the arithmethic expression is value,
        and error message otherwise 

        >>> calculator("   -4 +3 -2")
        -3.0
        >>> calculator("-4 +3 -2 / 2")
        -2.0
        >>> calculator("-4 +3   - 8 / 2")
        -5.0
        >>> calculator("   -4 +    3   - 8 / 2")
        -5.0
        >>> calculator("23 / 12 - 223 + 5.25 * 4 * 3423")
        71661.91666666667
        >>> calculator("2 - 3*4")
        -10.0
        >>> calculator("4++ 3 +2")
        'error message'
        >>> calculator("4 3 +2")
        'input error line B: calculator'
    """


    if len(expr)<=0 or not isinstance(expr,str): #Line A     
        return "input error line A: calculator"

    # Concatenate '0' at he beginning of the expression if it starts with a negative number to get '-' when calling getNextNumber
    # "-2.0 + 3 * 4.0 " becomes "0-2.0 + 3 * 4.0 ".
    addResult = 0
    mulResult = 0
    addLastOpr = 0
    expr=expr.strip()
    if expr[0]=="-":
        expr = "0 " + expr
    newNumber, newOpr, oprPos = getNextNumber(expr, 0)

    # Initialization. Holding two modes for operator precedence: "addition" and "multiplication"
    if newNumber is None: #Line B
        return "input error line B: calculator"
    elif newOpr is None:
        return newNumber
    elif newOpr=="+" or newOpr=="-":
        mode="add"
        addResult=newNumber     #value so far in the addition mode     
    elif newOpr=="*" or newOpr=="/":
        mode="mul"
        addResult=0
        mulResult=newNumber     #value so far in the mulplication mode
        addLastOpr = "+"
    pos=oprPos+1                #the new current position
    opr=newOpr                  #the new current operator


    #==============================================================================================================
    #Calculation starts here, get next number-operator and perform case analysis. Conpute values using exeOpr
    while True:
    # --- YOU CODE STARTS HERE

        l = len(expr)
        safe = True

        for i in range(0, l, 1):
            hold = expr[i]

        if hold == "*" or hold == '/' or hold == '-' or hold == '+':

            if safe == False:
                return "error"

            safe = False

        if hold.isdigit == True:
            safe = True


        #print(getNextNumber(expr, pos))

###===============================================
        newNumber, newOpr, oprPos, = getNextNumber(expr, pos)
        print(getNextNumber(expr, pos))

        #if newOpr == None:
        #    newOpr = ''
        #if oprPos == None:
        #   oprPos = -1


        if newNumber == None:
            return 'error'


        elif mode == 'add':
            if newOpr == None:
                return exeOpr(addResult, opr, newNumber)
            elif newOpr == "+" or newOpr == "-":
                addResult = exeOpr(addResult, opr, newNumber)
            elif newOpr == "*" or newOpr == "/":
                mode = "mul"
                mulResult = float(newNumber)
                addLastOpr = opr

        elif mode == "mul":
            if newOpr == None:
                mulResult = exeOpr(mulResult, opr, newNumber)
                return exeOpr(addResult, addLastOpr,mulResult)
            elif newOpr == "+" or newOpr == "-":
                mulResult = exeOpr(mulResult, opr, newNumber)
                addResult = exeOpr(addResult, addLastOpr,mulResult)
                mode = 'add'
            elif newOpr == "*" or newOpr == "/":
                mulResult = exeOpr(mulResult, opr, newNumber)

        pos = oprPos + 1
        opr = newOpr

    ###===============================================
# ---  CODE ENDS HERE

#print(calculator("23 / 12 - 223 + 5.25 * 4 * 3423"))
#print(findNextOpr(("23  12 - 223 + 5.25 * 4 * 3423")))
#print(findNextOpr(("23  12  223  5.25  4  3423")))
#print(isNumber("23432423"))
#print(isNumber("23432.425645453"))
#print(isNumber("-23432423       "))
#print(isNumber("           23432.423"))
#rint(isNumber("              23.43.2423        "))
#print(isNumber("              23432423             "))
print(getNextNumber("1+3   *     7",0))
print(calculator('1+38*3*2*3*2*     7'))
Теги:
nonetype

1 ответ

1
Лучший ответ

Ваша проблема заключается в функции getNextNumber. У вас есть случай (когда оператор == -1), где вы ничего не возвращаете, поэтому возвращаемое значение не может быть распаковано.

operator = findNextOpr(expr[pos:])
if operator == -1:
    newNumber1 = float(expr[len(expr)-1])
    opElement = None
    opOut = None
else: # <-- It was within this else before

    opOut = operator + pos
    hold = expr[pos:opOut].strip()

    if isNumber(hold):
        newNumber1 = float(hold)
        opElement = expr[pos + operator]


    else:
        newNumber1 = None
        opElement = expr[pos + operator]
    print("%",newNumber1, opElement, opOut)
return newNumber1, opElement, opOut # <-- Culprit line, This need to be indented like this.

Последняя строка в приведенном выше коде (строка 169 в вашей программе) находилась в указанной инструкции else (строка 154), что означает, что она не будет запущена вообще, если operator был -1.

Надеюсь, это помогло вам :)

  • 0
    Большое спасибо за ответ на это извините, я не кредитовал вас раньше. Это было для задания «все или ничего», которое должно было состояться в прошлую пятницу в 11:59, и размещение здесь было последним средством. Я так рад, что наконец-то узнал, в чем была ошибка после буквального разочарования. Я, честно говоря, ошеломлен тем, насколько сильно моя оценка пострадает за одну отсутствующую вкладку (например,> 2% итоговой оценки). И что профессор не уловил этого, когда кто-то, с кем я работал, написал им об этом по электронной почте. Честно говоря, я не могу отблагодарить вас достаточно, потому что я никогда бы этого не понял, и это кумулятивное задание.
  • 0
    Извини, что не смог помочь тебе быстрее! Это была маленькая ошибка, которую мог совершить кто угодно, и иногда вам просто нужна свежая пара глаз, чтобы понять, что не так :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню