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``. .. sourcecode:: python 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__()`` .. sourcecode:: python 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. .. sourcecode:: python >>> >>> 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()``. .. sourcecode:: python 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()``. .. sourcecode:: python >>> >>> 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. .. sourcecode:: python 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, .. sourcecode:: python 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. .. sourcecode:: python >>> >>> 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. .. sourcecode:: python >>> 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 +"). .. sourcecode:: python >>> 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 >>>