Sugestão de roteiro para fazer este EP

Após estudar e entender o enunciado do EP e baixar os arquivos implemente a classe Calculadora baseando-se nos métodos utilizados na função main() e nos exemplos de execução da calculadora disponíveis neste enunciado. Implemente apenas um método de cada vez, e teste o funcionamento do método antes de continuar com os demais.

__init__()

Comece escrevendo o método __init__() que é o construtor da classe Calculadora.

def __init__(self):
    '''(Calculadora) -> Calculadora

    Cria e retorna uma Calculadora.

    Construtor da classe é um método 'mágico' que
         nao tem return.
    '''
print("Vixe! Ainda não fiz esse método.")

Depois de escrevê-la, execute o módulo (= Run -> Run Module) e teste-a no Python Shell. Verifique se os atributos de estados (= variáveis) foram inicializados corretamente.

__str__()

Escreva o método __str__()

def __str__(self):
    ''' (Calculadora) -> str

    Recebe uma calculadora referenciada por self e
    crie e retorna um string representando o estado da
    calculadora.

    O string retornado pode ser usado pelas funções print()
    e str().

    O estado da calculadora é formado por:

       - (list de Tokens) fila dos tokens a serem processados;
       - (Pilha) pilha de execução;
       - (dict) dicionário de variáveis; e
       - (bool) indicador de modo verboso.

    A string retorna deve ser no formato mostrado no enunciado.

    Dica: utilize a função tokens_para_str() do módulo
          tokeniza.py para lista de tokens.
          utilize a função str() sobre objetos Pilha e dict.
    '''
    return "Vixe! Ainda não fiz esse método."

O seu método __str__() deve produzir resultados iguais aos que estão nos exemplos deste enunciado.

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

troca_modo_verboso()

Agora, escreva o método troca_modo_verboso().

def troca_modo_verboso(self):
    '''(Calculadora) -> None

    Recebe uma calculadora referenciada por self, altera
    o seu modo verboso e imprime uma mensagem indicano se
    o modo foi ativado ou desativado.
    '''
    print("Vixe! Ainda não fiz esse método!")

Os exemplos a seguir mostram o funcionamente do método troca_modo_verboso().

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

>>> hp1.troca_modo_verboso()
AVISO: modo verboso ativado.
>>> print(hp1)
lista de tokens: []
pilha de execução: []
dicionário de variáveis: {}
modo verboso: ativado

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

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

>>> hp2.troca_modo_verboso()
AVISO: modo verboso ativado.
>>> print(hp2)
lista de tokens: []
pilha de execução: []
dicionário de variáveis: {}
modo verboso: ativado

mostre_variaveis()

Escreva o método mostre_variaveis() e veja os testes mais adiante.

def mostre_variaveis(self):
    '''(Calculadora) -> None

    Recebe uma calculadora referenciada por self e imprime
    o conteudo do seu dicionário de variáveis.

    A impressão deve ser no fornato mostrado no enunciado.
    '''
    print("Vixe! Ainda não fiz esse método.")

eval()

Este é possivelmente o método mais importante da calculadora,

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

    Recebe uma string representado 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.
    '''

O modo verboso será muito útil durante a fase de desenvolvimento e teste do método eval(). Implemente e teste eval() utilizando o modo verboso para, a cada token processado, mostrar o conteúdo da:

  • fila de tokens a serem processados e da
  • pilha de execução.

Inicialmente, teste eval() com expressões que contenham apenas números e supondo que as expressões estão corretas, como nos exemplos a seguir.

>>>
>>> hp = Calculadora()
>>> hp.eval("2")
2.0
>>> hp.eval("1 2+")
3.0
>>> hp.eval("2 3 -")
-1.0
>>> hp.eval("3 2 4 *-")
-5.0
>>> hp.eval("2 3 /2+")
2.6666666666666665
>>> hp.eval("2 3%")
2.0
>>> hp.eval("5 2 2/ %")
0.0
>>> hp.troca_modo_verboso()
AVISO: modo verboso ativado.
>>> hp.eval("2")
lista de tokens: [N(2)]
pilha de execução: []
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: []
pilha de execução: [N(2)]
dicionário de variáveis: {}
modo verboso: ativado

2.0
>>> hp.eval("1 2+")
lista de tokens: [N(1), N(2), O('+')]
pilha de execução: []
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: [N(2), O('+')]
pilha de execução: [N(1)]
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: [O('+')]
pilha de execução: [N(1), N(2)]
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: []
pilha de execução: [N(3)]
dicionário de variáveis: {}
modo verboso: ativado

3.0
>>> hp.eval("2 3 -")
lista de tokens: [N(2), N(3), O('-')]
pilha de execução: []
dicionário de variáveis: {}
modo verboso: ativado

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

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

lista de tokens: []
pilha de execução: [N(-1)]
dicionário de variáveis: {}
modo verboso: ativado

-1.0
>>> hp.eval("3 2 4 *-")
lista de tokens: [N(3), N(2), N(4), O('*'), O('-')]
pilha de execução: []
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: [N(2), N(4), O('*'), O('-')]
pilha de execução: [N(3)]
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: [N(4), O('*'), O('-')]
pilha de execução: [N(3), N(2)]
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: [O('*'), O('-')]
pilha de execução: [N(3), N(2), N(4)]
dicionário de variáveis: {}
modo verboso: ativado

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

lista de tokens: []
pilha de execução: [N(-5)]
dicionário de variáveis: {}
modo verboso: ativado

-5.0
>>> hp.eval("2 3 /2+")
lista de tokens: [N(2), N(3), O('/'), N(2), O('+')]
pilha de execução: []
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: [N(3), O('/'), N(2), O('+')]
pilha de execução: [N(2)]
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: [O('/'), N(2), O('+')]
pilha de execução: [N(2), N(3)]
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: [N(2), O('+')]
pilha de execução: [N(0.666667)]
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: [O('+')]
pilha de execução: [N(0.666667), N(2)]
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: []
pilha de execução: [N(2.66667)]
dicionário de variáveis: {}
modo verboso: ativado

2.6666666666666665
>>> hp.troca_modo_verboso()
AVISO: modo verboso desativado.
>>> hp.eval("12.25 15 + 4 *")
109.0
>>>

Depois (apenas depois!), que o método eval() estiver funcionado para expressões corretas que contenham apenas números, implemente e teste eval() para expressões corretas que contenham números e variáveis.

>>> hp1 = Calculadora()
>>> hp1.eval("a 1 =")
1.0
>>> hp1.mostre_variaveis()
{a: 1}
>>> hp1.eval("a")
1.0
>>> hp1.eval("b 2 =")
2.0
>>> hp1.eval("b")
2.0
>>> hp1.mostre_variaveis()
{b: 2, a: 1}
>>> hp1.eval("c a b 2*+ =")
5.0
>>> hp1.mostre_variaveis()
{b: 2, a: 1, c: 5}
>>> hp2 = Calculadora()
>>> hp2.mostre_variaveis()
{}
>>> hp2.troca_modo_verboso()
AVISO: modo verboso ativado.
>>> hp2.eval("a 1 =")
lista de tokens: [V('a'), N(1), O('=')]
pilha de execução: []
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: [N(1), O('=')]
pilha de execução: [V('a')]
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: [O('=')]
pilha de execução: [V('a'), N(1)]
dicionário de variáveis: {}
modo verboso: ativado

lista de tokens: []
pilha de execução: [N(1)]
dicionário de variáveis: {'a': 1.0}
modo verboso: ativado

1.0
>>> hp2.eval("b 2 =")
lista de tokens: [V('b'), N(2), O('=')]
pilha de execução: []
dicionário de variáveis: {'a': 1.0}
modo verboso: ativado

lista de tokens: [N(2), O('=')]
pilha de execução: [V('b')]
dicionário de variáveis: {'a': 1.0}
modo verboso: ativado

lista de tokens: [O('=')]
pilha de execução: [V('b'), N(2)]
dicionário de variáveis: {'a': 1.0}
modo verboso: ativado

lista de tokens: []
pilha de execução: [N(2)]
dicionário de variáveis: {'b': 2.0, 'a': 1.0}
modo verboso: ativado

2.0
>>> hp2.eval("c a b 2*+ =")
lista de tokens: [V('c'), V('a'), V('b'), N(2), O('*'), O('+'), O('=')]
pilha de execução: []
dicionário de variáveis: {'b': 2.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [V('a'), V('b'), N(2), O('*'), O('+'), O('=')]
pilha de execução: [V('c')]
dicionário de variáveis: {'b': 2.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [V('b'), N(2), O('*'), O('+'), O('=')]
pilha de execução: [V('c'), V('a')]
dicionário de variáveis: {'b': 2.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [N(2), O('*'), O('+'), O('=')]
pilha de execução: [V('c'), V('a'), V('b')]
dicionário de variáveis: {'b': 2.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [O('*'), O('+'), O('=')]
pilha de execução: [V('c'), V('a'), V('b'), N(2)]
dicionário de variáveis: {'b': 2.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [O('+'), O('=')]
pilha de execução: [V('c'), V('a'), N(4)]
dicionário de variáveis: {'b': 2.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: [O('=')]
pilha de execução: [V('c'), N(5)]
dicionário de variáveis: {'b': 2.0, 'a': 1.0}
modo verboso: ativado

lista de tokens: []
pilha de execução: [N(5)]
dicionário de variáveis: {'b': 2.0, 'a': 1.0, 'c': 5.0}
modo verboso: ativado

5.0
>>> hp1.mostre_variaveis()
{b: 2, a: 1, c: 5}
>>> hp2.mostre_variaveis()
{b: 2, a: 1, c: 5}
>>> hp2.eval("c 1!=")
lista de tokens: [V('c'), N(1), O('!'), O('=')]
pilha de execução: []
dicionário de variáveis: {'b': 2.0, 'a': 1.0, 'c': 5.0}
modo verboso: ativado

lista de tokens: [N(1), O('!'), O('=')]
pilha de execução: [V('c')]
dicionário de variáveis: {'b': 2.0, 'a': 1.0, 'c': 5.0}
modo verboso: ativado

lista de tokens: [O('!'), O('=')]
pilha de execução: [V('c'), N(1)]
dicionário de variáveis: {'b': 2.0, 'a': 1.0, 'c': 5.0}
modo verboso: ativado

lista de tokens: [O('=')]
pilha de execução: [V('c'), N(-1)]
dicionário de variáveis: {'b': 2.0, 'a': 1.0, 'c': 5.0}
modo verboso: ativado

lista de tokens: []
pilha de execução: [N(-1)]
dicionário de variáveis: {'b': 2.0, 'a': 1.0, 'c': -1.0}
modo verboso: ativado

-1.0
>>> hp2.troca_modo_verboso()
AVISO: modo verboso desativado.
>>> hp1.eval("a 123 =")
123.0
>>> hp1.mostre_variaveis()
{b: 2, a: 123, c: 5}
>>> hp2.mostre_variaveis()
{b: 2, a: 1, c: -1}
>>> hp1.eval("b a =")
123.0
>>> hp2.eval("b a=")
1.0
>>> hp1.mostre_variaveis()
{b: 123, a: 123, c: 5}
>>> hp2.mostre_variaveis()
{b: 1, a: 1, c: -1}
>>>

Finalmente, depois (apenas depois!) que a sua calculadora estiver funcionando para expressões corretas com números e variáveis, insira no código o tratamento de erros de expressões.

Procure não permitir que a calculadora “morra” ao tratar de expressões inválidas. Se desejar, você pode fazer a calculadora imprimir mensagens de erro adicionais quando a expressão for inválida, por exemplo quando:

  • a pilha de execução terminar com tamanho diferente de 1, após processar o último token da lista (como na expressão “2 3 4”);
  • utilizar uma variável que não tenha sido inicializada (como em “2 var +”, onde var não tenha sido inicializada);
  • não há operandos suficientes na pilha (como na expressão “2 +”).
>>> hp = Calculadora()
>>> hp.eval("2 3 4")
ERRO: falta(m) operador(es) nessa expressão
>>> hp.eval("2 var+")
ERRO: Variável 'var' não tem valor
>>> hp.eval("2 +")
ERRO: falta(m) operandor(s) para processar o operador: +
>>> hp.eval("+")
ERRO: falta(m) operando(s) para processar o operador: +
>>> hp.eval("media")
ERRO: Variável 'media' não tem valor
>>>

Table Of Contents

This Page