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:

TEXT
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

PYTHON
# 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"},
]
▶ Experimente

2. Código Completo

Salve este arquivo como card_manager.py e execute diretamente:

Exemplo: Sistema de Gerenciamento de Cartões de Visita

PYTHON
# ====== 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.")
▶ Experimente

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

TEXT
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-chave in. É 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


📝 Atividades

  1. Iniciante (Dificuldade ⭐): Adicione um novo recurso ao sistema de cartões — exibir cartões ordenados por nome (usando sorted() com o parâmetro key).

  2. Intermediário (Dificuldade ⭐⭐): Adicione um recurso de "gerenciamento de grupos" ao sistema de cartões. Adicione um campo group a cada cartão ("colegas," "amigos," "família"), depois implemente uma opção de menu para visualizar cartões por grupo.

  3. 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.

100%