Módulo 16 - Projeto final: agenda de contatos
Os métodos da agenda
11 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026
O que você vai aprender
- Escrever adicionar_contato para incluir um contato na agenda.
- Criar listar, devolvendo os contatos guardados.
- Implementar buscar_por_nome com uma compreensão de lista.
- Entender por que operar pela classe é melhor que mexer na lista por fora.
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: Os métodos da agenda.
Os objetivos desta aula. Escrever adicionar_contato para incluir um contato na agenda. Criar listar, devolvendo os contatos guardados. Implementar buscar_por_nome com uma compreensão de lista. Entender por que operar pela classe é melhor que mexer na lista por fora.
Veja o essencial, parte por parte.
Adicionar e listar. adicionar_contato recebe um contato e o inclui na lista interna.
Buscar com uma compreensão. Buscar um contato pelo nome é onde as compreensões brilham.
O ganho de operar pela classe. Um método, uma tarefa: adicionar não deveria também imprimir.
Esse foi o resumo do essencial. Para se aprofundar, leia a aula completa e responda os exercícios.
Adicionar e listar
Na aula anterior você colocou um contato na agenda com agenda.contatos.append(ana). Funciona, mas expõe a lista interna para o mundo. Quem usa a agenda não deveria precisar saber que, por dentro, ela guarda os contatos em uma lista chamada contatos. Métodos resolvem isso: eles dão à agenda um vocabulário próprio. Em vez de mexer na lista, você pede à agenda para adicionar. Se um dia a estrutura interna mudar, quem chama os métodos nem percebe.
class Agenda:
def __init__(self):
self.contatos = []
def adicionar_contato(self, contato):
self.contatos.append(contato)
def listar(self):
return list(self.contatos)adicionar_contato inclui um contato; listar devolve uma cópia da lista.
adicionar_contato é curto de propósito: recebe um contato e o guarda. Poderia crescer depois, por exemplo salvando em arquivo a cada inclusão, sem que ninguém de fora precise mudar. Já listar devolve list(self.contatos), uma cópia nova da lista, e não a lista original. É uma proteção pequena e valiosa: quem recebe a lista pode percorrê-la à vontade sem risco de alterar por acidente os dados internos da agenda. Devolver e depois iterar deixa a impressão a cargo de quem chama.
Buscar com uma compreensão
Buscar um contato pelo nome é onde as compreensões brilham. A ideia é percorrer os contatos e ficar com os que batem com o nome procurado. Um detalhe importante de usabilidade: a busca deve ignorar maiúsculas e minúsculas, para que procurar por ana encontre Ana Souza. Fazemos isso comparando tudo em minúsculo com o método lower. Uma compreensão de lista expressa esse filtro em uma linha limpa.
def buscar_por_nome(self, nome):
encontrados = [
c for c in self.contatos
if nome.lower() in c.nome.lower()
]
return encontrados[0] if encontrados else None
# Uso rapido
agenda = Agenda()
agenda.adicionar_contato(Contato("Ana Souza", "11999998888", "ana@exemplo.com"))
agenda.adicionar_contato(Contato("Bruno Lima", "11888887777"))
for contato in agenda.listar():
print(contato)
print(agenda.buscar_por_nome("ana")) # Ana Souza | 11999998888 | ana@exemplo.com
print(agenda.buscar_por_nome("carla")) # NoneA busca filtra com uma compreensão e devolve o primeiro encontrado, ou None.
Leia a compreensão como uma frase: para cada contato c na agenda, fique com ele se o nome procurado, em minúsculo, aparece dentro do nome do contato, em minúsculo. O in permite busca parcial, então mica encontra Micaela. No fim, o método devolve o primeiro da lista de encontrados, ou None se ninguém bateu. Esse None é uma escolha provisória. Ele funciona, mas obriga quem chama a lembrar de testar se veio None antes de usar. Na próxima aula, você troca esse None por algo mais expressivo: uma exceção própria, que avisa o problema em alto e bom som.
O ganho de operar pela classe
Repare no que mudou de qualidade. Antes, para usar a agenda, era preciso conhecer a sua tripa: a lista contatos e o método append das listas. Agora, a agenda oferece verbos claros: adicionar_contato, listar, buscar_por_nome. Quem usa a agenda conversa com ela nesse vocabulário e ignora como ela guarda as coisas por dentro. Esse princípio tem nome, encapsulamento, e é uma das maiores vantagens de organizar o programa em classes. O objeto esconde o como e oferece o quê.
Note também que os métodos não imprimem nada, com exceção do trecho de teste. Quem decide mostrar na tela é o código que usa a agenda, mais tarde o menu. Essa separação entre calcular e mostrar é o que permite, na aula de testes, verificar a agenda automaticamente: um teste chama buscar_por_nome e confere o que voltou, sem precisar ler a tela. Métodos que só imprimem seriam quase impossíveis de testar. Guardar essa disciplina agora rende muito lá na frente.
Teste rápido
Por que buscar_por_nome compara nome.lower() com c.nome.lower()?
Perguntas frequentes
- Por que listar devolve list(self.contatos) e não self.contatos direto?
- Para devolver uma cópia, não a lista interna. Assim, quem recebe pode percorrê-la sem risco de alterar por acidente os dados da agenda. É uma proteção barata contra bugs difíceis de achar, em que um trecho distante modifica a lista sem querer.
- A busca parcial com in não pode trazer o contato errado?
- Pode trazer mais de um, se vários nomes contiverem o texto. Por isso o método devolve o primeiro encontrado. Para uma agenda pequena e didática, isso basta. Um programa maior mostraria a lista de correspondências para o usuário escolher.
- Poderia usar um laço for com append em vez da compreensão?
- Sim, e o resultado seria o mesmo. A compreensão é preferida por ser mais curta e por deixar clara a intenção de filtrar em uma linha. É o jeito pythônico. Se a lógica ficasse complexa demais para uma linha, aí sim o laço explícito seria mais legível.
- Por que devolver None quando não encontra, se depois vamos trocar?
- Porque o projeto é incremental: primeiro uma versão simples que funciona, depois uma melhor. Devolver None é a solução mais direta e serve para ver a busca operando. Na aula 4 você percebe o problema dela e a substitui por uma exceção.
- adicionar_contato deveria impedir contatos repetidos?
- Poderia, e seria uma boa melhoria. Na versão do curso, mantemos simples: ele apenas adiciona. Evitar duplicatas é um dos exercícios sugeridos na última aula, usando buscar_por_nome antes de incluir.
- O que significa encapsulamento, citado na aula?
- É esconder os detalhes internos de um objeto e oferecer só uma interface clara. A agenda esconde que guarda contatos em uma lista e oferece métodos como adicionar_contato. Quem usa não precisa conhecer o interior, o que deixa o código mais fácil de mudar.
Fontes
Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.