Почему эти выражения не эквивалентны? - PullRequest
0 голосов
/ 08 мая 2019

В качестве домашнего задания я должен написать на python двоичное дерево, на котором я могу выполнять простые операции, а затем распечатать выражение в обратной польской записи. Мой первоначальный ответ был в основном правильным, в конце концов, последняя функция post_fix() давала мне ошибку 'NoneType' object has no attribute 'left'. Это был мой оригинальный ответ:

class N:
    "un noeud de l'arbre"
    def __init__(self, c, l=None, r=None):
        self.content = c
        self.left = l
        self.right = r

    def print_tree(self):
        if self.left is not None:
            self.left.print_tree()         
        print(self.content) 
        if self.right is not None:   
            self.right.print_tree()

expression_1 = N('*', N('+', N(7), N(3)), N(4))
expression_2 = N('+', N(7), N('*', N(3), N(4)))

def isnumber(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

def calcule(x, oper, y):
    "applique l'operateur à x et y et retourne le résultat"
    if isnumber(x) and isnumber(y):
        if oper == '+':
            return x + y
        elif oper == '-':
            return x - y
        if oper == '*':
            return x * y
        elif oper == '/':
            return x / y
        else: 
            print('\033[1;31mERROR: "{}" is not a valid operator.\033[1;m'.format(oper))
            return None
    else: 
        print ('\033[1;31mERROR: operands must be numerical values.\033[1;m')

def evalue(arbre):
    "evalue l'expression logée dans l'arbre"
    if type(arbre.content) in (float, int):
        return arbre.content
    else:
        operator = arbre.content
        vg = evalue(arbre.left)
        vd = evalue(arbre.right)
        return calcule(vg, operator, vd)

def post_fix(arbre):
    "retourne l'expression de cet arbre en notation post-fixée"
    pf = ''
    if arbre.left is not None :
        pf = pf + post_fix(arbre.left) + ' '
    if arbre.right is not None :
        pf = pf + post_fix(arbre.right) + ' '
    return pf + arbre.content

print('Expression 1 en notation post-fix:', post_fix(expression_1))  
print('Expression 2 en notation post-fix:', post_fix(expression_2))  

Был дан правильный правильный способ определения post_fix():

def post_fix(arbre):
    "retourne l'expression de cet arbre en notation post-fixée"
    pf = str()
    if arbre.left is not None :
        pf = pf + post_fix(arbre.left) + ' '
    if arbre.right is not None :
        pf = pf + post_fix(arbre.right) + ' '
    return pf + str(arbre.content)

Может ли кто-нибудь сказать мне разницу между ними и причину, по которой мое первоначальное объявление привело к ошибке? Заранее спасибо.

EDIT: После принятого ответа я заметил, что главной проблемой была несовместимость типов, тем не менее вопрос остается открытым: указана ошибка 'NoneType' object has no attribute 'left'. Я использовал Jupyter.

1 Ответ

0 голосов
/ 08 мая 2019

Я на самом деле получаю ошибку следующим образом, когда я запускаю ваш код

return pf + arbre.content
TypeError: can only concatenate str (not "int") to str

Что говорит о том, что вы не можете объединить int и str, следовательно, первый подход не будет работать, но вы можете объединить их после преобразования int в str, что мы и делаем сделать при втором подходе

In [16]: x = 'a'   

In [17]: y = 2                                                                                                                 

In [18]: x+y                                                                                                                   
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-18-259706549f3d> in <module>
----> 1 x+y

TypeError: can only concatenate str (not "int") to str

In [19]: x+str(y)                                                                                                              
Out[19]: 'a2'

Как видите, конкатенация строки и целого числа вызвала ошибку, но такая ошибка не генерировалась, когда вы конвертировали строку в целое число, а затем конкатенировали, что происходит в вашем первом и втором способе post_fix соответственно

...