Módulo 14 - Tratamento básico de erros
Prática: a calculadora à prova de erros
11 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026
O que você vai aprender
- Diagnosticar os pontos fracos da calculadora do módulo 6.
- Construir a função pedir_numero com while True e try/except ValueError.
- Tratar a divisão por zero com aviso amigável em vez de queda.
- Montar o código final completo e testá-lo com entradas de má fé.
Ouvir o resumo desta aula
Um recap de cerca de 2 minutos na voz do Valim, para ouvir no trânsito ou na academia.
Ler a transcrição do resumo
Resumo da aula: Prática: a calculadora à prova de erros.
Os objetivos desta aula. Diagnosticar os pontos fracos da calculadora do módulo 6. Construir a função pedir_numero com while True e try/except ValueError. Tratar a divisão por zero com aviso amigável em vez de queda. Montar o código final completo e testá-lo com entradas de má fé.
Veja o essencial, parte por parte.
O plano da blindagem. A calculadora do módulo 6 cai se o usuário digitar letra no lugar de número ou dividir por zero.
A peça central: a função pedir_numero. while True + try/except + return no sucesso: memorize o trio, ele é o jeito clássico de ler dados com segurança.
O código final completo. Desafio 1: envolva a calculadora num while para que, após cada resultado, ela pergunte se o usuário quer fazer outra conta.
Esse foi o resumo do essencial. Para se aprofundar, leia a aula completa e responda os exercícios.
O plano da blindagem
Hora de cumprir a promessa feita lá no módulo 3: revisitar a calculadora com ferramentas novas. A versão do módulo 6 funcionava bem no cenário ideal, com um usuário educado digitando números certinhos. Só que programa de verdade não vive no cenário ideal. Faça o teste da má fé: rode a sua calculadora antiga e digite banana no primeiro número. Traceback com ValueError e programa no chão. Digite zero como divisor: ZeroDivisionError. Um programa que qualquer distração derruba não está pronto.
- Ponto fraco 1: float(input()) cai com ValueError se a entrada não for número.
- Ponto fraco 2: uma operação fora de +, -, * e / passa sem conferência.
- Ponto fraco 3: divisão por zero derruba tudo com ZeroDivisionError.
O plano de blindagem ataca os três pontos com o que você já tem no cinto de ferramentas: funções do módulo 13, while do módulo 8 e o try/except da aula passada. A peça central é um padrão que você vai reutilizar pelo resto da vida de programador: o loop de validação, que pede o dado, tenta usar, e repete a pergunta com uma mensagem amigável enquanto vier coisa inválida. O programa não briga com o usuário e não desiste dele; só insiste até dar certo.
A peça central: a função pedir_numero
Como a calculadora pede dois números, escrever a blindagem duas vezes seria repetição, e o módulo 13 ensinou o remédio para repetição: função. A pedir_numero abaixo junta while True com try/except num padrão de quatro linhas de lógica que resolve a leitura segura de números para sempre.
def pedir_numero(mensagem):
while True:
texto = input(mensagem)
try:
return float(texto)
except ValueError:
print(f"Ops: '{texto}' não é um número. Tente de novo.")O loop de validação: tenta converter; se der ValueError, avisa e o while pergunta de novo.
Acompanhe o fluxo com calma, porque ele tem uma sutileza elegante. O while True parece o loop infinito que o módulo 8 mandou evitar, mas repare no return dentro do try: quando a conversão funciona, o return devolve o número E encerra a função na hora, loop incluído. A saída do loop é o sucesso. Quando a conversão falha, o except mostra a mensagem amigável, com o valor rejeitado entre aspas para o usuário ver o que digitou, e o while volta ao input. Resultado: a função só retorna número válido, não importa quantas tentativas custe.
Primeiro número: banana
Ops: 'banana' não é um número. Tente de novo.
Primeiro número: 12,5
Ops: '12,5' não é um número. Tente de novo.
Primeiro número: 12.5A função em ação, insistindo com educação. Detalhe brasileiro: o Python usa ponto decimal, então 12,5 com vírgula também é rejeitado.
O código final completo
Agora a montagem final, atacando também os pontos fracos 2 e 3. A operação é validada com um while simples: enquanto o texto digitado não estiver entre as quatro aceitas, o programa explica e pede de novo. E a divisão por zero é resolvida ANTES da conta, com um if que detecta o caso e reabre a pergunta do divisor. É a validação com if e o try/except trabalhando juntos, cada um no que faz melhor, como combinamos na aula passada.
def pedir_numero(mensagem):
while True:
texto = input(mensagem)
try:
return float(texto)
except ValueError:
print(f"Ops: '{texto}' não é um número. Tente de novo.")
print("=== CALCULADORA À PROVA DE ERROS ===")
a = pedir_numero("Primeiro número: ")
b = pedir_numero("Segundo número: ")
operacao = input("Operação (+, -, * ou /): ")
while operacao not in ("+", "-", "*", "/"):
print("Operação inválida. Use +, -, * ou /.")
operacao = input("Operação (+, -, * ou /): ")
if operacao == "/" and b == 0:
print("Divisão por zero não existe. Preciso de outro divisor.")
while b == 0:
b = pedir_numero("Segundo número (diferente de zero): ")
if operacao == "+":
resultado = a + b
elif operacao == "-":
resultado = a - b
elif operacao == "*":
resultado = a * b
else:
resultado = a / b
print(f"Resultado: {a} {operacao} {b} = {resultado}")A calculadora blindada completa: números validados em loop, operação conferida e divisão por zero avisada.
=== CALCULADORA À PROVA DE ERROS ===
Primeiro número: dez
Ops: 'dez' não é um número. Tente de novo.
Primeiro número: 10
Segundo número: 0
Operação (+, -, * ou /): dividir
Operação inválida. Use +, -, * ou /.
Operação (+, -, * ou /): /
Divisão por zero não existe. Preciso de outro divisor.
Segundo número (diferente de zero): 4
Resultado: 10.0 / 4.0 = 2.5O teste da má fé, agora sem vítimas: três entradas erradas seguidas e nenhum traceback.
Digite o código no Playground ou no VS Code e repita o teste da má fé do começo da aula: letra no número, operação inventada, zero no divisor. Compare a experiência com a versão do módulo 6 e sinta a diferença de qualidade. Essa é a marca de um programa robusto: ele não promete que o usuário nunca vai errar; ele promete reagir bem quando errar. Guarde a pedir_numero com carinho, porque o gerenciador de tarefas do projeto final vai precisar exatamente dela.
Teste rápido
Na função pedir_numero, o que acontece quando o usuário digita "abc"?
Perguntas frequentes
- Por que usar while True se o curso ensinou a evitar loop infinito?
- Porque este loop tem saída garantida e proposital: o return dispara na primeira conversão bem-sucedida e encerra função e loop juntos. Loop infinito de verdade é o que não tem caminho de saída; o while True com return no sucesso é um padrão clássico e seguro de validação.
- Por que tratar a divisão por zero com if em vez de try/except?
- As duas formas funcionam, e um except ZeroDivisionError seria perfeitamente válido. O if foi escolhido porque conferir b == 0 antes permite pedir outro divisor na hora, mantendo o fluxo da conversa. Regra prática: o que dá para prever, valide com if; o que só se descobre tentando, trate com try/except.
- Por que a função usa float e não int?
- Para a calculadora aceitar valores com casas decimais, como 12.5, que o int rejeitaria. O custo é o resultado sair como 10.0 em vez de 10. O desafio 2 propõe a versão pedir_inteiro exatamente para você sentir a diferença entre as duas conversões.
- E se o usuário digitar espaços antes do número, tipo ' 10 '?
- Funciona: o float do Python ignora espaços nas pontas do texto antes de converter. Já '1 0', com espaço no meio, é rejeitado com ValueError, e a sua blindagem responde pedindo de novo. Teste os dois casos no Playground para confirmar.
- Posso copiar a pedir_numero para outros programas meus?
- Deve. Foi desenhada para isso: recebe a mensagem como parâmetro, então serve para pedir idade, preço, nota ou qualquer número. Reaproveitar funções testadas em vez de reescrever é hábito profissional, e o projeto final do curso vai usar essa mesma função.
- A calculadora blindada ainda tem alguma fraqueza?
- Tem, e enxergar isso é sinal de maturidade: ela não aceita vírgula decimal à brasileira (desafio 3), faz uma conta só por execução (desafio 1) e insiste para sempre em vez de desistir com elegância (desafio 4). Robustez é escada, não interruptor: cada versão cobre mais casos que a anterior.
Fontes
Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.