10  Erros e Exceções em Python

Quando o código não funciona como esperado: entendendo e resolvendo problemas 🛠️

10.1 O que você saberá se ler este capítulo?

Este capítulo é seu “manual de primeiros socorros” para quando o código não funciona! 🚨

10.1.1 Você vai aprender:

  1. Como identificar erros - Reconhecer os tipos mais comuns de erros
  2. Por que os erros acontecem - Entender as causas por trás de cada erro
  3. Como resolver erros - Estratégias práticas para corrigir problemas
  4. Prevenção de erros - Como evitar que os erros aconteçam
  5. Debugging básico - Técnicas para encontrar e corrigir bugs

10.1.2 Como usar este capítulo:

  • Leia quando der erro - Use como consulta rápida
  • Entenda o motivo - Não só “como corrigir”, mas “por que aconteceu”
  • Aprenda a prevenir - Evite que o mesmo erro aconteça novamente

Dica importante: Erros são normais! Todo programador enfrenta erros diariamente. O importante é saber como lidar com eles!

10.2 Os Erros Mais Comuns em Python

Vamos conhecer os “vilões” mais frequentes que aparecem quando programamos! 🦹‍♂️

10.2.1 Lista dos Erros Mais Comuns:

Erro Quando acontece Analogia
IndexError Acessar posição que não existe em lista/tupla Tentar pegar o 6º item de uma lista com 5 itens
IOError Problema ao ler/gravar arquivo Tentar abrir um livro que não existe na estante
KeyError Acessar chave que não existe em dicionário Procurar uma palavra que não está no dicionário
NameError Usar variável antes de defini-la Chamar alguém pelo nome sem saber o nome
TypeError Operação incompatível com o tipo Tentar somar maçãs com laranjas
ValueError Tipo correto, mas valor inválido Tentar dividir por zero
ZeroDivisionError Dividir por zero Tentar dividir uma pizza em 0 pedaços

10.2.2 Por que esses erros são importantes?

  • São os mais frequentes - 80% dos erros que você vai encontrar
  • Têm soluções claras - Cada um tem uma forma específica de resolver
  • São previsíveis - Você pode aprender a evitá-los

Dica: Não se assuste com os erros! Eles são como sinais de trânsito - te avisam quando algo não está certo!

10.2.3 IndexError - Acessando o que não existe!

O que acontece: Você tenta acessar uma posição que não existe em uma lista ou tupla.

10.2.3.1 Analogia da Receita de Bolo:

Imagine uma receita com 10 etapas numeradas de 1 a 10. Se você tentar seguir a “etapa 11”, vai dar problema! É exatamente isso que acontece com o IndexError - você está tentando acessar uma posição que não existe.

10.2.3.2 Exemplo do Erro:

lista = ["maçã", "banana", "laranja"]  # Lista com 3 itens (índices 0, 1, 2)
print(lista[3])  # ❌ ERRO! Tentando acessar índice 3, mas só existem 0, 1, 2

10.2.3.3 Como Resolver:

  1. Verificar o tamanho da lista antes de acessar
  2. Usar índices válidos (lembre-se que começam em 0!)
  3. Usar len() para saber quantos itens existem

10.2.3.4 Solução Prática:

lista = ["maçã", "banana", "laranja"]
if len(lista) > 3:  # Verifica se tem pelo menos 4 itens
    print(lista[3])
else:
    print("Índice não existe!")

💡 Dica: Lembre-se que os índices começam em 0! Uma lista com 3 itens tem índices 0, 1 e 2! 🎯

10.2.4 IOError - Problemas com Arquivos!

O que acontece: Erro ao tentar ler, escrever ou acessar um arquivo.

10.2.4.1 Analogia da Receita de Bolo:

A receita pede ovos, mas quando você abre a geladeira… não tem ovos! É exatamente isso que acontece com o IOError - você está tentando acessar um arquivo que não existe ou não pode ser acessado.

10.2.4.2 Exemplo do Erro:

arquivo = open("receita.txt", "r")  # ❌ ERRO! Arquivo não existe

10.2.4.3 Como Resolver:

  1. Verificar se o arquivo existe no local correto
  2. Verificar o caminho do arquivo
  3. Verificar permissões de acesso
  4. Usar tratamento de erros com try/except

10.2.4.4 Solução Prática:

try:
    arquivo = open("receita.txt", "r")
    conteudo = arquivo.read()
    arquivo.close()
except FileNotFoundError:
    print("Arquivo não encontrado! Verifique o nome e localização.")

💡 Dica: Sempre verifique se o arquivo existe antes de tentar abri-lo! É como verificar se tem ovos na geladeira antes de começar a receita! 🥚

10.2.5 KeyError - Chave não encontrada!

O que acontece: Você tenta acessar uma chave que não existe em um dicionário.

10.2.5.1 Analogia da Receita de Bolo:

Imagine um livro de receitas com páginas de 1 a 50. Se você tentar encontrar uma receita na “página 60”, vai dar problema! É exatamente isso que acontece com o KeyError - você está procurando uma chave que não existe no dicionário.

10.2.5.2 Exemplo do Erro:

pessoa = {"nome": "João", "idade": 25, "sexo": "masculino"}
endereco = pessoa["endereco"]  # ❌ ERRO! Chave "endereco" não existe

10.2.5.3 Como Resolver:

  1. Verificar se a chave existe antes de acessar
  2. Usar get() para acessar chaves com valor padrão
  3. Verificar as chaves disponíveis com keys()

10.2.5.4 Solução Prática:

pessoa = {"nome": "João", "idade": 25, "sexo": "masculino"}

# Opção 1: Verificar se a chave existe
if "endereco" in pessoa:
    print(pessoa["endereco"])
else:
    print("Chave não encontrada!")

# Opção 2: Usar get() com valor padrão
endereco = pessoa.get("endereco", "Não informado")
print(endereco)

💡 Dica: Use get() quando não tem certeza se a chave existe! É mais seguro que acessar diretamente! 🛡️

10.2.6 NameError - Variável não encontrada!

O que acontece: O Python não consegue encontrar a definição de uma variável ou função que você está tentando usar.

10.2.6.1 Analogia da Receita de Bolo:

Imagine que você está seguindo uma receita que pede “açúcar”, mas você não tem açúcar na cozinha! É exatamente isso que acontece com o NameError - você está tentando usar algo que não foi definido ainda.

10.2.6.2 Exemplos do Erro:

print(nome)  # ❌ ERRO! Variável "nome" não foi definida
print(idade)  # ❌ ERRO! Variável "idade" não foi definida

10.2.6.3 Como Resolver:

  1. Definir a variável antes de usar
  2. Verificar se digitou o nome corretamente
  3. Verificar o escopo da variável (onde ela foi definida)
  4. Verificar se a função foi importada ou definida

10.2.6.4 Solução Prática:

# ERRO: Usar antes de definir
print(nome)

# CORRETO: Definir antes de usar
nome = "João"
print(nome)

# CORRETO: Verificar se existe antes de usar
if 'nome' in locals():
    print(nome)
else:
    print("Variável não definida!")

💡 Dica: Sempre defina suas variáveis antes de usar! É como ter todos os ingredientes prontos antes de começar a receita! 🥘

10.2.7 TypeError - Tipos incompatíveis!

O que acontece: Você tenta fazer uma operação entre tipos de dados que não são compatíveis.

10.2.7.1 Analogia da Receita de Bolo:

Imagine que a receita pede para misturar 2 colheres de açúcar com 1 colher de farinha. Você sabe que açúcar e farinha são ingredientes diferentes e não podem ser misturados diretamente! É exatamente isso que acontece com o TypeError - você está tentando misturar tipos que não combinam.

10.2.7.2 Exemplos do Erro:

1. Somando número com texto:

x = 42
s = "olá"
result = s + x  # ❌ ERRO! Não pode somar texto com número

2. Tentando iterar sobre None:

lista = None
for item in lista:  # ❌ ERRO! None não pode ser iterado
    print(item)

3. Chamando número como função:

x = 42
x()  # ❌ ERRO! Número não é uma função

10.2.7.3 Como Resolver:

1. Converter tipos antes de operar:

x = 42
s = "olá"
result = s + str(x)  # ✅ CORRETO! Converte número para texto
print(result)  # Saída: "olá42"

2. Verificar se não é None antes de iterar:

lista = None
if lista is not None:
    for item in lista:
        print(item)
else:
    print("Lista está vazia!")

3. Verificar se é função antes de chamar:

x = 42
if callable(x):
    x()
else:
    print("x não é uma função!")

💡 Dica: Sempre verifique os tipos antes de fazer operações! É como verificar se os ingredientes são compatíveis antes de misturar! 🥄

10.2.7.4 Mais Exemplos de TypeError:

4. Tentando modificar string (imutável):

texto = "olá"
texto[0] = "O"  # ❌ ERRO! Strings são imutáveis

5. Tentando modificar tupla (imutável):

coordenadas = (1, 2)
coordenadas[0] = 3  # ❌ ERRO! Tuplas são imutáveis

6. Tentando somar string com lista:

texto = "olá"
lista = ["mundo"]
resultado = texto + lista  # ❌ ERRO! Tipos incompatíveis

10.2.7.5 Como Resolver:

4. Para strings imutáveis:

texto = "olá"
novo_texto = "O" + texto[1:]  # ✅ CORRETO! Cria nova string
print(novo_texto)  # Saída: "Olá"

5. Para tuplas imutáveis:

coordenadas = (1, 2)
novas_coordenadas = (3, coordenadas[1])  # ✅ CORRETO! Cria nova tupla
print(novas_coordenadas)  # Saída: (3, 2)

6. Para tipos incompatíveis:

texto = "olá"
lista = ["mundo"]
resultado = texto + " " + " ".join(lista)  # ✅ CORRETO! Converte para string
print(resultado)  # Saída: "olá mundo"

💡 Dica: Lembre-se que strings e tuplas são imutáveis! Se precisar modificar, crie uma nova versão! 🔄

10.2.8 ValueError - Valor inválido!

O que acontece: O tipo de dado está correto, mas o valor é inválido para a operação que está sendo realizada.

10.2.8.1 Analogia da Receita de Bolo:

Imagine que a receita pede para medir 1 xícara de açúcar, mas você acidentalmente coloca farinha na xícara! O tipo está certo (ingrediente em pó), mas o valor está errado (farinha em vez de açúcar). É exatamente isso que acontece com o ValueError!

10.2.8.2 Exemplos do Erro:

1. Tentando converter texto para número:

numero = int("banana")  # ❌ ERRO! "banana" não é um número

2. Tentando calcular raiz quadrada de número negativo:

import math
resultado = math.sqrt(-4)  # ❌ ERRO! Raiz quadrada de negativo não existe

3. Tentando converter string com vírgula para float:

numero = float("15,5")  # ❌ ERRO! Python usa ponto, não vírgula

4. Tentando extrair mais valores do que existem:

a, b, c = (1, 2)  # ❌ ERRO! Só tem 2 valores, mas queremos 3

10.2.8.3 Como Resolver:

1. Para conversão de texto para número:

texto = "banana"
if texto.isdigit():
    numero = int(texto)
else:
    print("Não é um número válido!")

2. Para raiz quadrada de negativo:

import math
numero = -4
if numero >= 0:
    resultado = math.sqrt(numero)
else:
    print("Não é possível calcular raiz quadrada de número negativo!")

3. Para vírgula em float:

texto = "15,5"
texto_corrigido = texto.replace(",", ".")  # ✅ CORRETO! Substitui vírgula por ponto
numero = float(texto_corrigido)
print(numero)  # Saída: 15.5

4. Para extração de valores:

valores = (1, 2)
if len(valores) == 3:
    a, b, c = valores
else:
    print(f"Só temos {len(valores)} valores, mas precisamos de 3!")

💡 Dica: Sempre verifique se o valor faz sentido antes de usar! É como verificar se o ingrediente é o correto antes de adicionar à receita! 🥄

10.2.9 ZeroDivisionError - Divisão por zero!

O que acontece: Você tenta dividir um número por zero, o que é matematicamente impossível.

10.2.9.1 Analogia da Receita de Bolo:

Imagine que você tem uma pizza e quer dividir em pedaços iguais. Se você tentar dividir em 0 pedaços, não faz sentido! É exatamente isso que acontece com o ZeroDivisionError - você está tentando fazer uma divisão que não existe matematicamente.

10.2.9.2 Exemplos do Erro:

1. Divisão direta por zero:

resultado = 10 / 0  # ❌ ERRO! Não é possível dividir por zero

2. Divisão com variável que pode ser zero:

denominador = 0
resultado = 10 / denominador  # ❌ ERRO! Denominador é zero

3. Calculando média de lista vazia:

lista = []
media = sum(lista) / len(lista)  # ❌ ERRO! len(lista) é 0

10.2.9.3 Como Resolver:

1. Verificar se o denominador não é zero:

numerador = 10
denominador = 0

if denominador != 0:
    resultado = numerador / denominador
    print(resultado)
else:
    print("Não é possível dividir por zero!")

2. Para cálculo de média:

lista = [1, 2, 3, 4, 5]

if len(lista) > 0:
    media = sum(lista) / len(lista)
    print(f"Média: {media}")
else:
    print("Lista está vazia! Não é possível calcular a média.")

3. Usando try/except para capturar o erro:

try:
    resultado = 10 / 0
except ZeroDivisionError:
    print("Erro: Divisão por zero não é permitida!")

💡 Dica: Sempre verifique se o denominador não é zero antes de dividir! É como verificar se tem ingredientes suficientes antes de começar a receita! 🍕

10.3 Resumo do Capítulo

Agora você conhece os “vilões” mais comuns que aparecem quando programamos! 🦹‍♂️

10.3.1 Principais Erros e Como Resolver:

Erro Causa Solução
IndexError Acessar posição inexistente Verificar tamanho da lista
IOError Arquivo não encontrado Verificar se arquivo existe
KeyError Chave não existe no dicionário Usar get() ou verificar se existe
NameError Variável não definida Definir variável antes de usar
TypeError Tipos incompatíveis Converter tipos ou verificar compatibilidade
ValueError Valor inválido Verificar se valor faz sentido
ZeroDivisionError Divisão por zero Verificar se denominador não é zero

10.3.2 Dicas Gerais para Evitar Erros:

  1. Sempre verifique se os dados existem antes de usar
  2. Use tratamento de erros com try/except quando necessário
  3. Teste seu código com diferentes valores
  4. Leia as mensagens de erro - elas te ajudam a encontrar o problema
  5. Não tenha medo dos erros - eles são parte do aprendizado!

🎯 Lembre-se: Erros são normais! Todo programador enfrenta erros diariamente. O importante é saber como lidar com eles e aprender com cada um! 🚀

10.4 Referências Bibliográficas

  • GEEKSFORGEEKS. Python String Operations. Disponível em: https://www.geeksforgeeks.org/python-strings/. Acesso em: 03 mar. 2023.
  • MATTHES, E. Python Crash Course: A Hands-On, Project-Based Introduction to Programming. No Starch Press, 2019.
  • PYTHON. Built-in Exceptions. Disponível em: https://docs.python.org/3/library/exceptions.html. Acesso em: 03 mar. 2023.
  • PYTHON. Built-in Types: Strings. Disponível em: https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str. Acesso em: 03 mar. 2023.
  • PYTHON. 4. More Control Flow Tools. Python Documentation, 2022. Disponível em: https://docs.python.org/3/tutorial/controlflow.html#tuples-and-sequences. Acesso em: 03 mar. 2023.
  • SWEIGART, A. Automate the Boring Stuff with Python: Practical Programming for Total Beginners. No Starch Press, 2019.
  • W3SCHOOLS. Python Built-in Exceptions. Disponível em: https://www.w3schools.com/python/python_ref_exceptions.asp. Acesso em: 03 mar. 2023.