Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!
Olá, Alex. Como vai?
Sensacional ver você alcançando o arquivo Alura ex036.py! Olhando a estrutura do seu código, fica claro que você já cruzou a linha de programador iniciante e está construindo arquiteturas de código muito elegantes e maduras.
O design dessa calculadora ficou sensacional. Em vez de usar aquela estrutura clássica e gigantesca cheia de if / elif / else para cada operação, você utilizou um dicionário de funções lambda (que aparece parcialmente mapeado no topo). Essa técnica é conhecida no mercado como o padrão de projeto Command ou tabelas de despacho (dispatch tables). Você mapeia o símbolo do operador (a chave) diretamente para a expressão lógica que deve ser executada (o valor). É um código extremamente limpo, rápido e profissional!
Também achei excelente a sua validação na linha 6 para evitar o clássico erro de divisão por zero, além do tratamento na linha 20 com .is_integer() para limpar os números decimais desnecessários e exibir 600 em vez de 600.0 no terminal. O resultado ficou impecável!
Para expandir ainda mais o seu conhecimento sobre essa estrutura de dicionários com funções, quero compartilhar duas dicas técnicas muito valiosas:
.get()Na sua linha 15, você fez uma validação usando o operador in: if operacao in calculadora:. Essa abordagem está 100% correta.
Contudo, os dicionários em Python possuem um método nativo chamado .get() que foi desenhado exatamente para buscar uma chave com segurança. Se a chave existir, ele traz o valor; se não existir, ele retorna None (ou um valor padrão que você escolher), sem quebrar o programa.
Veja como você poderia unificar o teste de existência e a execução em um bloco ainda mais enxuto:
# Tenta buscar a função lambda correspondente no dicionário
funcao_operacao = calculadora.get(operacao)
if funcao_operacao:
# Se encontrou a operação, executa passando os números
resultado = funcao_operacao(num1, num2)
# (Seu bloco de formatação visual do resultado continua aqui...)
else:
print("Operação inválida.")
Na linha 6 do seu código, você colocou uma proteção maravilhosa: if y != 0 else "Erro (divisão por zero)".
Essa blindagem impede que o Python lance uma exceção e trave o script. Porém, fique atento a um detalhe do fluxo: se o usuário tentar dividir por zero, a sua variável resultado passará a guardar uma string (o texto "Erro (divisão por zero)").
Logo em seguida, na linha 20, o seu código faz a seguinte checagem:
if isinstance(resultado, float) and resultado.is_integer():
Como "Erro (divisão por zero)" é um texto (string) e não um float, o Python simplesmente pulará esse bloco if com segurança e imprimirá na tela: O resultado é: Erro (divisão por zero). O programa não vai quebrar, o que é ótimo!
Porém, para seguir as melhores práticas estritas de desenvolvimento (onde funções matemáticas devem retornar idealmente números ou erros controlados), muitos programadores preferem que, em caso de erro matemático, a função retorne um valor especial do Python chamado None ou o próprio valor de indeterminação flutuante float('nan') (Not a Number).
Tratar o erro logo na exibição final impede que strings fiquem "passeando" por variáveis que deveriam ser puramente numéricas:
# Exemplo de tratamento na hora do print caso o resultado seja None
if resultado is None:
print("Não é possível realizar divisão por zero.")
else:
print(f"O resultado é: {resultado}")
Parabéns, Alex! Chegar ao exercício 36 com esse nível de sofisticação técnica, aplicando lambdas, dicionários estruturados e métodos de tipagem como isinstance é a prova do seu enorme progresso. Continue firme com essa consistência fantástica!
Espero que possa ter lhe ajudado!