Projeto: Sistema de Gerenciamento de Cartões de Visita
Este é o projeto final da Fase 2. Todo o conhecimento das lições anteriores — listas, dicionários, comprehensions, métodos de string — será usado para construir um sistema de gerenciamento de cartões de visita real e utilizável via linha de comando. Completar este projeto significa que você realmente dominou os conceitos centrais de containers do Python.
Requisitos do Projeto
Vamos construir um "Gerenciador de Cartões de Visita" que executa no terminal e suporta os seguintes recursos:
1. Adicionar cartão — digite nome, telefone, email
2. Exibir todos os cartões — liste em formato de tabela
3. Buscar cartões — busque por nome (suporta busca difusa)
4. Modificar cartão — atualize informações por nome
5. Deletar cartão — delete por nome
6. Estatísticas — mostre total, estatísticas de domínio de email
7. Sair do programa
Os dados são armazenados usando lista + dicionário: todos os cartões em uma lista, cada cartão como um dicionário.
1. Design da Estrutura de Dados
Exemplo: Estrutura de Dados do Cartão de Visita
# Cada cartão é um dicionário
# Todos os cartões são armazenados em uma lista
[
{"name": "João Silva", "phone": "13800138000", "email": "joao@example.com"},
{"name": "Maria Souza", "phone": "13900139000", "email": "maria@teste.com"},
]
2. Código Completo
Salve este arquivo como card_manager.py e execute diretamente:
Exemplo: Sistema de Gerenciamento de Cartões de Visita
# ====== Sistema de Gerenciamento de Cartões de Visita ======
# Armazenamento de dados
cards = []
def show_menu():
"""Exibe o menu principal"""
print("\n" + "=" * 35)
print("Sistema de Gerenciamento de Cartões")
print("=" * 35)
print("1. Adicionar Cartão")
print("2. Listar Todos os Cartões")
print("3. Buscar Cartões")
print("4. Modificar Cartão")
print("5. Deletar Cartão")
print("6. Estatísticas")
print("7. Sair")
print("=" * 35)
def add_card():
"""Adiciona um cartão de visita"""
print("\n--- Adicionar Cartão ---")
name = input("Nome: ").strip()
if not name:
print("Nome não pode estar vazio!")
return
phone = input("Telefone: ").strip()
email = input("Email: ").strip()
# Verifica nome duplicado
for card in cards:
if card["name"] == name:
print(f"Um cartão com nome {name} já existe. Não é possível adicionar duplicata.")
return
cards.append({"name": name, "phone": phone, "email": email})
print(f"Cartão de {name} adicionado.")
def list_cards():
"""Exibe todos os cartões"""
if not cards:
print("\nNenhum cartão ainda.")
return
print("\n--- Todos os Cartões ---")
print(f"{'#':<4}{'Nome':<10}{'Telefone':<15}{'Email':<25}")
print("-" * 54)
for i, card in enumerate(cards, 1):
print(f"{i:<4}{card['name']:<10}{card['phone']:<15}{card['email']:<25}")
print(f"\nTotal: {len(cards)} cartões")
def search_card():
"""Busca cartões (suporta busca difusa)"""
if not cards:
print("\nNenhum cartão ainda.")
return
keyword = input("\nDigite o nome para buscar (correspondência parcial suportada): ").strip()
if not keyword:
print("Por favor, digite uma palavra-chave!")
return
# List comprehension + in para busca difusa
results = [card for card in cards if keyword in card["name"]]
if not results:
print(f"Nenhum cartão encontrado correspondendo a '{keyword}'.")
return
print(f"\n--- Encontrados {len(results)} cartões ---")
for card in results:
print(f"Nome: {card['name']}")
print(f"Telefone: {card['phone']}")
print(f"Email: {card['email']}")
print("-" * 20)
def modify_card():
"""Modifica um cartão"""
if not cards:
print("\nNenhum cartão ainda.")
return
name = input("\nDigite o nome para modificar: ").strip()
for card in cards:
if card["name"] == name:
print(f"Cartão de {name} encontrado. Digite novas informações (Enter para manter atual):")
new_name = input(f"Nome ({card['name']}): ").strip()
new_phone = input(f"Telefone ({card['phone']}): ").strip()
new_email = input(f"Email ({card['email']}): ").strip()
if new_name:
card["name"] = new_name
if new_phone:
card["phone"] = new_phone
if new_email:
card["email"] = new_email
print(f"Cartão de {name} foi atualizado.")
return
print(f"Nenhum cartão encontrado para {name}.")
def delete_card():
"""Deleta um cartão"""
if not cards:
print("\nNenhum cartão ainda.")
return
name = input("\nDigite o nome para deletar: ").strip()
for i, card in enumerate(cards):
if card["name"] == name:
confirm = input(f"Tem certeza que deseja deletar o cartão de {name}? (s/n): ")
if confirm.lower() == "s":
cards.pop(i)
print(f"Cartão de {name} foi deletado.")
else:
print("Exclusão cancelada.")
return
print(f"Nenhum cartão encontrado para {name}.")
def show_stats():
"""Exibe estatísticas dos dados"""
if not cards:
print("\nNenhum cartão ainda.")
return
print("\n--- Estatísticas ---")
print(f"Total de cartões: {len(cards)}")
# Conta domínios de email
domains = {}
for card in cards:
email = card["email"]
if "@" in email:
domain = email.split("@")[1]
domains[domain] = domains.get(domain, 0) + 1
if domains:
print("\nDistribuição de domínios de email:")
for domain, count in sorted(domains.items(), key=lambda x: x[1], reverse=True):
print(f" {domain}: {count}")
# Conta quantos têm telefone e email
has_phone = sum(1 for card in cards if card["phone"])
has_email = sum(1 for card in cards if card["email"])
print(f"\nCom telefone: {has_phone}")
print(f"Com email: {has_email}")
# ====== Programa Principal ======
print("Bem-vindo ao Sistema de Gerenciamento de Cartões de Visita!")
print("Digite o número correspondente para selecionar uma função.")
while True:
show_menu()
choice = input("Selecione opção (1-7): ").strip()
if choice == "1":
add_card()
elif choice == "2":
list_cards()
elif choice == "3":
search_card()
elif choice == "4":
modify_card()
elif choice == "5":
delete_card()
elif choice == "6":
show_stats()
elif choice == "7":
print("Obrigado por usar! Até logo!")
break
else:
print("Escolha inválida. Digite um número entre 1 e 7.")
Abordagem de design de código: Cada recurso é implementado como uma função independente. O programa principal usa um laço while + if-elif para despacho. Isso torna a estrutura do código clara — adicionar um novo recurso requer apenas uma nova função e um ramo elif.
3. Execução de Exemplo
Bem-vindo ao Sistema de Gerenciamento de Cartões de Visita!
Digite o número correspondente para selecionar uma função.
===================================
Sistema de Gerenciamento de Cartões
===================================
1. Adicionar Cartão
2. Listar Todos os Cartões
3. Buscar Cartões
4. Modificar Cartão
5. Deletar Cartão
6. Estatísticas
7. Sair
===================================
Selecione opção (1-7): 1
--- Adicionar Cartão ---
Nome: João Silva
Telefone: 13800138000
Email: joao@example.com
Cartão de João Silva adicionado.
Selecione opção (1-7): 2
--- Todos os Cartões ---
# Nome Telefone Email
──────────────────────────────────────────────────────
1 João Silva 13800138000 joao@example.com
Total: 1 cartão
4. Sugestões de Extensão
Após completar o projeto, tente adicionar estes recursos:
| Recurso | Ideia de Implementação |
|---|---|
| Persistência de dados | Use json.dump() para salvar em arquivo e json.load() para carregar na inicialização (operações de arquivo serão abordadas depois) |
| Gerenciamento de grupos | Adicione um campo group aos cartões (colegas/amigos/família), organize com um dicionário por grupo |
| Importação/exportação de dados | Use join() para gerar arquivos CSV que podem ser abertos no Excel |
| Exibição ordenada | Ordene por nome: sorted(cards, key=lambda c: c["name"]) |
| Exclusão em lote | Aceite múltiplos nomes separados por vírgula, faça um laço de exclusões |
❓ Perguntas Frequentes
P: Por que usar lista + dicionário em vez de operações diretas de arquivo? R: Este projeto foca em operações de container — a lista armazena todos os cartões, dicionários armazenam cartões individuais. Isso permite praticar CRUD de lista e operações de chave-valor de dicionário. E/S de arquivo (persistência) será abordada na Fase 3. Domine containers primeiro, depois operações de arquivo — uma abordagem passo a passo. P: Os dados são perdidos quando o programa fecha. O que devo fazer? R: Isso é normal — nossos dados estão armazenados na memória, que é liberada quando o programa termina. Para persistir dados, depois de aprender operações de arquivo e o módulo JSON, use
json.dump(cards, open("data.json", "w"))para salvar em disco. P: A busca difusa usa a palavra-chavein. É sensível a maiúsculas/minúsculas? R: Sim."João" in "João Silva"é True, mas"joão" in "João"é False (sensível a maiúsculas). Se você precisar de busca insensível a maiúsculas, converta para minúsculas antes de comparar:keyword.lower() in card["name"].lower().
📖 Resumo
- O sistema de gerenciamento de cartões de visita usa uma lista para todos os dados e dicionários para registros individuais — o padrão de organização de dados mais comum
- Design modular: cada recurso é uma função independente; o programa principal usa um laço para despacho
enumerate()gera exibições de lista numeradas- List comprehensions implementam busca difusa
- O método
get()do dicionário é usado para contagem de frequência - O projeto, embora simples, cobre todos os conceitos centrais da Fase 2
📝 Atividades
-
Iniciante (Dificuldade ⭐): Adicione um novo recurso ao sistema de cartões — exibir cartões ordenados por nome (usando
sorted()com o parâmetrokey). -
Intermediário (Dificuldade ⭐⭐): Adicione um recurso de "gerenciamento de grupos" ao sistema de cartões. Adicione um campo
groupa cada cartão ("colegas," "amigos," "família"), depois implemente uma opção de menu para visualizar cartões por grupo. -
Avançado (Dificuldade ⭐⭐⭐): Escreva um "sistema de gerenciamento de livros" do zero sem consultar o código acima. Recursos incluem: adicionar livro (título, autor, ano), exibir todos, buscar por autor, ordenar por ano, contar livros por autor. Use lista + dicionário para armazenamento, tudo executando na linha de comando.



