1
resposta

[Sugestão] Calculadora com tratamento de erros

class Calculadora:
    operadores_validos = {
        '+': lambda num1, num2: num1 + num2,
        '-': lambda num1, num2: num1 - num2,
        '*': lambda num1, num2: num1 * num2,
        '/': lambda num1, num2: num1 / num2
    }

    def __init__(self, num1: float, num2: float) -> None:
        self.num1 = num1
        self.num2 = num2

    def _tratar_erros(self, operador: str) -> list:
        try:
            num1 = float(self.num1)
            num2 = float(self.num2)
        except ValueError:
            raise ValueError('Entrada inválida: Os valores fornecidos não são números válidos.')
        if operador not in self.__class__.operadores_validos:
            raise ValueError(f'O operador "{operador}" é inválido!')
        if operador == '/' and num2 == 0:
            raise ValueError('Erro: Divisão por zero não é permitida!')
        return num1, num2

    def calcular(self, operador: str):
        try:
            num1, num2 = self._tratar_erros(operador)
            resultado = self.__class__.operadores_validos[operador](num1, num2)
            print(f'Resultado: {resultado}')
        except (ValueError, ZeroDivisionError) as e:
            print(f'Não foi possível calcular: {e}')
        except Exception as e:
            print(f'Ocorreu um erro inesperado: {e}')


num1 = input('Digite o primeiro número: ')
operacao = input('Escolha a operação (+, -, *, /): ')
num2 = input('Digite o segundo número: ')
c1 = Calculadora(num1, num2)
c1.calcular(operacao)
1 resposta

Oii, José. Tudo bem?

A sua proposta para o desafio da calculadora demonstra que você já tá explorando conceitos avançados de Python, como orientação a objetos e o uso de dicionários com funções lambda. É muito interessante ver como você buscou uma estrutura que centraliza a lógica das operações.

Pontos fortes do que você elaborou:

  • Uso de dicionário para operadores: Centralizar os cálculos em um dicionário com lambda é uma forma inteligente de evitar múltiplos blocos if/elif, tornando a expansão do código mais simples no futuro.
  • Tipagem e boas práticas: O uso de -> None e a definição de tipos (float) mostram uma preocupação com a clareza e manutenção do código.
  • Captura de erros genéricos: Incluir um except Exception é uma boa prática para evitar que o programa encerre abruptamente por motivos que não foram previstos inicialmente.

Abaixo, deixo alguns pontos de atenção para que sua solução fique ainda mais alinhada com os requisitos do desafio e com o funcionamento da Orientação a Objetos:

Validação e instanciação:
No seu código, você passa os valores para a classe e depois tenta convertê-los dentro de um método de tratamento de erros. Em um cenário real, o ideal é que a classe receba dados já validados ou que o próprio construtor (__init__) cuide dessa integridade. Da forma como está, se o float(self.num1) falhar, o erro só aparece quando você chama o método calcular, e não no momento em que o objeto é criado.

Tratamento de exceções específicas:
O desafio pedia mensagens de erro muito específicas para cada situação. Notei que você unificou quase tudo em ValueError dentro do método _tratar_erros. No caso da divisão por zero, o Python já possui a exceção nativa ZeroDivisionError. Usar a exceção correta ajuda outros desenvolvedores a entenderem exatamente qual regra de negócio ou erro técnico ocorreu.

Parabéns pela iniciativa de ir além do básico e aplicar uma estrutura de classe no desafio. Continue praticando essa visão modular.

Conteúdos relacionados
Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!