Sugestão de roteiro para fazer este EP

Após estudar e entender o enunciado do EP, baixe os arquivos para este EP9.

Em seguida, depois de alterar o nome do módulo esqueleto_calculadora.py para calculadora.py copie a implementação que você fez da classe Calculadora para o EP8.

Se você não fez o EP8, ainda assim você poderá fazer quase a totalidade deste EP.

O EP9 consiste, essencialmente, na implementação da função infixa_para_posfixa() que está no módulo calculadora.py.

def infixa_para_posfixa(infixa):
    '''(list de Tokens) -> list de Tokens

    Recebe uma lista infixa de Tokens representando uma
    expressão em notação infixa e retorna uma lista de
    tokens representando uma expressão equivalente
    na notação posfixa.

    Essa função utiliza uma pilha que contém apenas
    operadores e abre parênteses. Veja as notas de aula.

    Pode ser útil utilizar nessa função o dicionário PREC do
    modulo operadores.py. Nesse dicionário as chaves são os
    operadores (str) e os valores (int) representam a
    precedência dos operadores: quanto maior o valor, maior
    a precedência.

    Exemplos:
    >>>
    >>> tokens = tokeniza("a = 2 * 31.4")
    >>> imprima_tokens(tokens)
    [V('a'), O('='), N(2), O('*'), N(31.4)]
    >>> posfixa = infixa_para_posfixa(tokens)
    >>> imprima_tokens(posfixa)
    [V('a'), N(2), N(31.4), O('*'), O('=')]
    >>>
    >>> tokens = tokeniza("2+3+4")
    >>> imprima_tokens(tokens)
    [N(2), O('+'), N(3), O('+'), N(4)]
    >>> posfixa = infixa_para_posfixa(tokens)
    >>> imprima_tokens(posfixa)
    [N(2), N(3), O('+'), N(4), O('+')]
    >>>
    >>> tokens = tokeniza("2^3^4")
    >>> imprima_tokens(tokens)
    [N(2), O('^'), N(3), O('^'), N(4)]
    >>> posfixa = infixa_para_posfixa(tokens)
    >>> imprima_tokens(posfixa)
    [N(2), N(3), N(4), O('^'), O('^')]
    >>>
    >>> tokens = tokeniza("(2+3)*4")
    >>> imprima_tokens(tokens)
    [P('('), N(2), O('+'), N(3), P(')'), O('*'), N(4)]
    >>> posfixa = infixa_para_posfixa(tokens)
    >>> imprima_tokens(posfixa)
    [N(2), N(3), O('+'), N(4), O('*')]
    >>>
    >>> tokens = tokeniza("22+33*4.4")
    >>> imprima_tokens(tokens)
    [N(22), O('+'), N(33), O('*'), N(4.4)]
    >>> posfixa = infixa_para_posfixa(tokens)
    >>> imprima_tokens(posfixa)
    [N(22), N(33), N(4.4), O('*'), O('+')]
    >>>
    '''

Para implementar a função infixa_para_posfixa() você deve consultar as notas de aula ou estudar uma das duas referências a seguir:

Depois de carregar o módulo calculadora.py execute o módulo (= Run -> Run Module) e teste a função infixa_para_posfixa() no Python Shell. Os exemplos a seguir mostram o comportamento da função.

Python 3.4.3 (default, Mar 26 2015, 22:03:40)
[GCC 4.9.2] on linux
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
>>> tokens = tokeniza("11")
>>> imprima_tokens(tokens)
[N(11)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(11)]
>>>
>>> tokens = tokeniza("11 2.34 aa bb cc")
>>> imprima_tokens(tokens)
[N(11), N(2.34), V('aa'), V('bb'), V('cc')]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(11), N(2.34), V('aa'), V('bb'), V('cc')]
>>>
>>> tokens = tokeniza("11 + 22")
>>> imprima_tokens(tokens)
[N(11), O('+'), N(22)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(11), N(22), O('+')]
>>>
>>> tokens = tokeniza("1 + 2 - 3")
>>> imprima_tokens(tokens)
[N(1), O('+'), N(2), O('-'), N(3)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(1), N(2), O('+'), N(3), O('-')]
>>>
>>> tokens = tokeniza("1 - 2 + 3")
>>> imprima_tokens(tokens)
[N(1), O('-'), N(2), O('+'), N(3)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(1), N(2), O('-'), N(3), O('+')]
>>>
>>> tokens = tokeniza("1 + 2 * 3")
>>> imprima_tokens(tokens)
[N(1), O('+'), N(2), O('*'), N(3)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(1), N(2), N(3), O('*'), O('+')]
>>>
>>> tokens = tokeniza("1 / 2 * 3 % 4")
>>> imprima_tokens(tokens)
[N(1), O('/'), N(2), O('*'), N(3), O('%'), N(4)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(1), N(2), O('/'), N(3), O('*'), N(4), O('%')]
>>>
>>> tokens = tokeniza("!1")
>>> imprima_tokens(tokens)
[O('!'), N(1)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(1), O('!')]
>>>
>>> tokens = tokeniza("!1 + 2")
>>> imprima_tokens(tokens)
[O('!'), N(1), O('+'), N(2)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(1), O('!'), N(2), O('+')]
>>>
>>> tokens = tokeniza("1 + !2")
>>> imprima_tokens(tokens)
[N(1), O('+'), O('!'), N(2)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(1), N(2), O('!'), O('+')]
>>>
>>> tokens = tokeniza("1 + !2 * 3")
>>> imprima_tokens(tokens)
[N(1), O('+'), O('!'), N(2), O('*'), N(3)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(1), N(2), O('!'), N(3), O('*'), O('+')]
>>>
>>> tokens = tokeniza("(1 + 2) * 3")
>>> imprima_tokens(tokens)
[P('('), N(1), O('+'), N(2), P(')'), O('*'), N(3)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(1), N(2), O('+'), N(3), O('*')]
>>>
>>> tokens = tokeniza("4 / (1 + 2 * 3) * 3")
>>> imprima_tokens(tokens)
[N(4), O('/'), P('('), N(1), O('+'), N(2), O('*'), N(3), P(')'), O('*'), N(3)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(4), N(1), N(2), N(3), O('*'), O('+'), O('/'), N(3), O('*')]
>>>
>>> tokens = tokeniza("a + (b + (c + (d + (e + f))))")
>>> imprima_tokens(tokens)
[V('a'), O('+'), P('('), V('b'), O('+'), P('('), V('c'), O('+'), P('('), V('d'), O('+'), P('('), V('e'), O('+'), V('f'), P(')'), P(')'), P(')'), P(')')]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[V('a'), V('b'), V('c'), V('d'), V('e'), V('f'), O('+'), O('+'), O('+'), O('+'), O('+')]
>>>
>>> tokens = tokeniza("a + (b * (c / (d % (e - f))))")
>>> imprima_tokens(tokens)
[V('a'), O('+'), P('('), V('b'), O('*'), P('('), V('c'), O('/'), P('('), V('d'), O('%'), P('('), V('e'), O('-'), V('f'), P(')'), P(')'), P(')'), P(')')]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[V('a'), V('b'), V('c'), V('d'), V('e'), V('f'), O('-'), O('%'), O('/'), O('*'), O('+')]
>>>
>>> tokens = tokeniza("2 ^ 3 ^ 4 ^ 5")
>>> imprima_tokens(tokens)
[N(2), O('^'), N(3), O('^'), N(4), O('^'), N(5)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(2), N(3), N(4), N(5), O('^'), O('^'), O('^')]
>>>
>>> tokens = tokeniza("!!!!2")
>>> imprima_tokens(tokens)
[O('!'), O('!'), O('!'), O('!'), N(2)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(2), O('!'), O('!'), O('!'), O('!')]
>>>
>>> tokens = tokeniza("!2 ^ !3 ^ !4 ^ !5")
>>> imprima_tokens(tokens)
[O('!'), N(2), O('^'), O('!'), N(3), O('^'), O('!'), N(4), O('^'), O('!'), N(5)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[N(2), N(3), N(4), N(5), O('!'), O('^'), O('!'), O('^'), O('!'), O('^'), O('!')]
>>>
>>> tokens = tokeniza("a = 2 + 3 * 4")
>>> imprima_tokens(tokens)
[V('a'), O('='), N(2), O('+'), N(3), O('*'), N(4)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[V('a'), N(2), N(3), N(4), O('*'), O('+'), O('=')]
>>>
>>> tokens = tokeniza("a = b = c = 0")
>>> imprima_tokens(tokens)
[V('a'), O('='), V('b'), O('='), V('c'), O('='), N(0)]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[V('a'), V('b'), V('c'), N(0), O('='), O('='), O('=')]
>>> tokens = tokeniza("a = b = c = a + b * c")
>>> imprima_tokens(tokens)
[V('a'), O('='), V('b'), O('='), V('c'), O('='), V('a'), O('+'), V('b'), O('*'), V('c')]
>>> posfixa = infixa_para_posfixa(tokens)
>>> imprima_tokens(posfixa)
[V('a'), V('b'), V('c'), V('a'), V('b'), V('c'), O('*'), O('+'), O('='), O('='), O('=')]
>>>

eval()

Se você não fez o EP8, então entregue o módulo calculadora.py apenas com a função infixa_para_posfixa() que você implementou, além do resto do esqueleto que está no módulo que você baixou.

Para terminar este EP só falta agora você fazer algumas pequenas alteração no método eval() da classe Calculadora que você fez para o EP8.

Abaixo está a especificação do método eval() que você implementou para o EP8.

def eval(self, exp = ''):
    ''' (str) -> float ou None

    Recebe um string representando uma expressão em
    notação posfixa e retorna o valor da expressão.

    Se algum erro for detectado na expressão a função
    retorna None.
    '''

A seguir está a documentação do novo método eval() para o EP9. Verifique qual a difereça.

def eval(self, exp = ''):
    ''' (str) -> float ou None

    Recebe um string representando uma expressão em
    NOTAÇÃO INFIXA e retorna o valor da expressão.

    Se algum erro for detectado na expressão a função
    retorna None.
    '''

Depois das alterações, carregue o módulo calculadora.py execute-o (= Run -> Run Module). Veja abaixo alguns testes do novo método eval()

Python 3.4.3 (default, Mar 26 2015, 22:03:40)
[GCC 4.9.2] on linux
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
>>> hp = Calculadora()
>>> hp.eval("1 + 2")
3.0
>>> hp.eval("1+2 *3")
7.0
>>> hp.eval("(1+2) *3")
9.0
>>> hp.eval("a = 1 + 2")
3.0
>>> hp.mostre_variaveis()
{'a': 3}
>>> hp.eval("a = a + 2")
5.0
>>> hp.mostre_variaveis()
{'a': 5}
>>> hp.eval("d = a")
5.0
>>> hp.mostre_variaveis()
{'d': 5, 'a': 5}
>>> hp.eval("c = e = f = d = a = 1")
1.0
>>> hp.mostre_variaveis()
{'c': 1, 'd': 1, 'e': 1, 'f': 1, 'a': 1}
>>> hp.troca_modo_verboso()
AVISO: modo verboso ativado.
>>> hp.eval("1 + 2 - 3")
eval(): string expr  = '1 + 2 - 3'
eval(): lista tokens = [N(1), O('+'), N(2), O('-'), N(3)]
lista de tokens: [N(1), N(2), O('+'), N(3), O('-')]
pilha de execução: []
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [N(2), O('+'), N(3), O('-')]
pilha de execução: [N(1)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [O('+'), N(3), O('-')]
pilha de execução: [N(1), N(2)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [N(3), O('-')]
pilha de execução: [N(3)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [O('-')]
pilha de execução: [N(3), N(3)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: []
pilha de execução: [N(0)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

0.0
>>> hp.eval("(1+2)*3/4")
eval(): string expr  = '(1+2)*3/4'
eval(): lista tokens = [P('('), N(1), O('+'), N(2), P(')'), O('*'), N(3), O('/'), N(4)]
lista de tokens: [N(1), N(2), O('+'), N(3), O('*'), N(4), O('/')]
pilha de execução: []
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [N(2), O('+'), N(3), O('*'), N(4), O('/')]
pilha de execução: [N(1)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [O('+'), N(3), O('*'), N(4), O('/')]
pilha de execução: [N(1), N(2)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [N(3), O('*'), N(4), O('/')]
pilha de execução: [N(3)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [O('*'), N(4), O('/')]
pilha de execução: [N(3), N(3)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [N(4), O('/')]
pilha de execução: [N(9)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [O('/')]
pilha de execução: [N(9), N(4)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: []
pilha de execução: [N(2.25)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

2.25
>>> hp.eval("2 ^ 2 ^ 3")
eval(): string expr  = '2 ^ 2 ^ 3'
eval(): lista tokens = [N(2), O('^'), N(2), O('^'), N(3)]
lista de tokens: [N(2), N(2), N(3), O('^'), O('^')]
pilha de execução: []
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [N(2), N(3), O('^'), O('^')]
pilha de execução: [N(2)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [N(3), O('^'), O('^')]
pilha de execução: [N(2), N(2)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [O('^'), O('^')]
pilha de execução: [N(2), N(2), N(3)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [O('^')]
pilha de execução: [N(2), N(8)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: []
pilha de execução: [N(256)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

256.0
>>> hp.eval("(2 ^ 2) ^ 3")
eval(): string expr  = '(2 ^ 2) ^ 3'
eval(): lista tokens = [P('('), N(2), O('^'), N(2), P(')'), O('^'), N(3)]
lista de tokens: [N(2), N(2), O('^'), N(3), O('^')]
pilha de execução: []
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [N(2), O('^'), N(3), O('^')]
pilha de execução: [N(2)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [O('^'), N(3), O('^')]
pilha de execução: [N(2), N(2)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [N(3), O('^')]
pilha de execução: [N(4)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [O('^')]
pilha de execução: [N(4), N(3)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: []
pilha de execução: [N(64)]
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: ativado

64.0
>>> hp.mostre_variaveis()
{'c': 1, 'd': 1, 'e': 1, 'f': 1, 'a': 1}
>>> hp.troca_modo_verboso()
AVISO: modo verboso desativado.
>>> hp.eval("2 ^ 2 ^ 3")
256.0
>>> hp.eval("(2 ^ 2) ^ 3")
64.0
>>> hp.eval("3 + !3")
0.0
>>> hp.eval("3 + !!3")
6.0
>>> hp.eval("3 + !!!3")
0.0
>>> hp.eval("3 + !!!!3") # :-)
6.0
>>> print(hp)
lista de tokens: []
pilha de execução: []
dicionário de variáveis: {'c': 1.0, 'd': 1.0, 'e': 1.0, 'f': 1.0, 'a': 1.0}
modo verboso: desativado

>>> hp = Calculadora()
>>> print(hp)
lista de tokens: []
pilha de execução: []
dicionário de variáveis: {}
modo verboso: desativado

>>> hp.eval("a = 1")
1.0
>>> hp.eval("b = 2")
2.0
>>> hp.eval("c = 3")
3.0
>>> hp.mostre_variaveis()
{'b': 2, 'c': 3, 'a': 1}
>>> hp.eval("c = a = b = a + b * c")
7.0
>>> hp.mostre_variaveis()
{'b': 7, 'c': 7, 'a': 7}
>>>

Finalmente, depois que as suas implementações acima estiverem funcionando, você pode testar a sua calculadora por completo. Para isso basta executar o módulo main.py.

Table Of Contents

This Page