Sistema de Gerenciamento de Pessoas com Python

Professor do dev explica apontando para uma interface cotendo um formulário que pede o cadastro de um nome, gênero e data de nascimento.

Vamos construir um Sistema de Gerenciamento de Pessoas em Python, utilizando classes para modelar a entidade Pessoa e funções para persistir (salvar) os dados em um arquivo de texto. Este post é o seu mapa para transformar conceitos de POO em um projeto prático.

Introdução

Sabe aquela sensação de ler um livro de receitas, mas nunca de fato preparar um prato? No desenvolvimento, é parecido. Aprendemos sobre classes e programação orientada a objetos (POO), mas para realmente dominar o assunto, precisamos colocar o conhecimento em prática em um projeto completo. Este mini-sistema de gerenciamento de pessoas será a sua primeira “receita” de sucesso, consolidando o uso de classes e a manipulação de arquivos (pessoas.txt). Ele simula o coração de qualquer aplicação: modelar dados (a Pessoa) e persistir esses dados (salvar).

🛠️ Passo 1: O “Molde” da Pessoa

Todo sistema de gerenciamento precisa de um molde para os objetos que ele gerencia. No nosso caso, é a Pessoa. Pense na classe Pessoa como a planta de uma casa: ela define o que toda pessoa deve ter.

Vamos criar o arquivo pessoa.py:

# pessoa.py
from datetime import date, datetime

class Pessoa:
    """
    Representa uma pessoa com nome, gênero e data de nascimento.
    """
    def __init__(self, nome: str, genero: str, data_nascimento: str):
        """
        Inicializa uma nova Pessoa.

        :param nome: Nome completo da pessoa.
        :param genero: Gênero da pessoa ('M' ou 'F').
        :param data_nascimento: Data de nascimento no formato 'dd/mm/aaaa'.
        """
        self.nome: str = nome
        self.genero: str = genero
        self.data_nascimento: str = data_nascimento  # 'dd/mm/aaaa'

    def calcular_idade(self) -> int:
        """Calcula a idade atual da pessoa."""
        # 'dd/mm/aaaa' -> objeto date
        data_nasc_obj: date = datetime.strptime(self.data_nascimento, '%d/%m/%Y').date()
        hoje: date = date.today()

        # Verifica se o aniversário já passou este ano
        idade: int = hoje.year - data_nasc_obj.year
        if hoje < date(hoje.year, data_nasc_obj.month, data_nasc_obj.day):
            idade -= 1
        
        return idade

    def __str__(self) -> str:
        """Representação em string."""
        return f"{self.nome}|{self.data_nascimento}|{self.genero}"

💾 Passo 2: Nosso arquivo de Pessoas

Os dados não podem sumir quando o programa é desligado, concorda? Precisamos de um lugar para guardá-los, que no nosso caso será o arquivo pessoas.txt.

Vamos criar o arquivo manipulador_arquivo.py para separar as funções responsáveis por guardar e pegar os dados das pessoas:

# manipulador_arquivo.py
from typing import List
from pessoa import Pessoa

ARQUIVO = 'pessoas.txt'

def carregar_pessoas() -> List[Pessoa]:
    """Carrega as pessoas do arquivo TXT e retorna uma lista de objetos Pessoa."""
    pessoas: List[Pessoa] = []
    try:
        with open(ARQUIVO, 'r', encoding='utf-8') as dados:
            for linha in dados:
                # Retorna uma lista com os dados quebrando onde havia '|'
                partes = linha.strip().split('|')
                if len(partes) == 3:
                    pessoa = Pessoa(partes[0], partes[1], partes[2])
                    pessoas.append(pessoa)
    except FileNotFoundError:
        # Se o arquivo não existir, retorna uma lista vazia
        pass
    return pessoas

def salvar_pessoas(pessoas: List[Pessoa]) -> None:
    """Salva a lista atualizada de pessoas no arquivo TXT."""
    with open(ARQUIVO, 'w', encoding='utf-8') as f:
        for pessoa in pessoas:
            f.write(str(pessoa))

O que significa Persistência: Persistência é o ato de garantir que os dados de uma aplicação sobrevivam mesmo após o programa ser encerrado. O módulo manipulador_arquivo.py garante essa persistência.

💻 Passo 3: O “Painel de Controle”

Este é o módulo que junta tudo: a classe Pessoa e as funções de manipulação de arquivo. É aqui que nosso menu principal vai rodar, dando controle ao usuário.

Vamos criar o arquivo main.py:

# main.py
from typing import List
from pessoa import Pessoa
from manipulador_arquivo import carregar_pessoas, salvar_pessoas

def exibir_menu() -> str:
    """Exibe o menu de opções e retorna a escolha do usuário."""
    print("\n--- Sistema de Gerenciamento de Pessoas ---")
    print("1. Listar Pessoas")
    print("2. Adicionar Nova Pessoa")
    print("3. Remover Pessoa")
    print("4. Sair do Sistema")
    escolha = input("Escolha uma opção (1-4): ")
    return escolha

def listar_pessoas(pessoas: List[Pessoa]) -> None:
    """Lista todas as pessoas cadastradas."""
    if not pessoas:
        print("\n❌ Nenhuma pessoa cadastrada.")
        return

    print("\n--- Lista de Pessoas Cadastradas ---")
    for i, pessoa in enumerate(pessoas):
        # O método __str__ é chamado para converter Pessoa para string
        print(f"{i+1}. {pessoa}")
    print("-" * 35)

def adicionar_pessoa(pessoas: List[Pessoa]) -> None:
    """Pede os dados e adiciona uma nova pessoa à lista."""
    print("\n--- Adicionar Nova Pessoa ---")
    nome = input("Nome completo: ")
    genero = input("Gênero (M/F): ").upper()
    data_nascimento = input("Data de Nascimento (dd/mm/aaaa): ")
    
    try:
        nova_pessoa = Pessoa(nome, genero, data_nascimento)
        pessoas.append(nova_pessoa)
        salvar_pessoas(pessoas)
        print(f"\n✅ Pessoa '{nome}' adicionada e salva com sucesso!")
    except:
        print("Erro ao adicionar pessoa! Dados inválidos!")

def remover_pessoa(pessoas: List[Pessoa]) -> None:
    """Remove uma pessoa da lista pelo índice."""
    listar_pessoas(pessoas)
    if not pessoas:
        return
    
    try:
        indice = int(input("Digite o NÚMERO da pessoa para remover (ou 0 para cancelar): "))
        if indice == 0:
            print("❌ Remoção cancelada.")
            return

        # Listas em Python são base 0, o usuário vê base 1
        indice_real = indice - 1
        
        if 0 <= indice_real < len(pessoas):
            pessoa_removida = pessoas.pop(indice_real)
            salvar_pessoas(pessoas)
            print(f"\n✅ Pessoa '{pessoa_removida.nome}' removida e arquivo atualizado!")
        else:
            print("\n❌ Número inválido.")
    except ValueError:
        print("\n❌ Entrada inválida. Digite um número.")


def main():
    """Lógica principal do sistema."""
    pessoas: List[Pessoa] = carregar_pessoas() # Carrega dados ao iniciar

    while True:
        escolha = exibir_menu()

        if escolha == '1':
            listar_pessoas(pessoas)
        elif escolha == '2':
            adicionar_pessoa(pessoas)
        elif escolha == '3':
            remover_pessoa(pessoas)
        elif escolha == '4':
            print("\n👋 Saindo do sistema. Até a próxima!")
            break
        else:
            print("\n⚠️ Opção inválida. Tente novamente.")

if __name__ == "__main__":
    main()

Como Rodar?

  1. Crie os três arquivos: pessoa.py, manipulador_arquivo.py e main.py com o código acima.
  2. Abra o terminal na pasta onde salvou os arquivos.
  3. Execute: python main.py
  4. O menu aparecerá, permitindo que você adicione, liste e remova as pessoas.

Conclusão

Este mini-projeto demonstra um pouco do poder da Programação Orientada a Objetos em conjunto com a manipulação de arquivos. A classe Pessoa modela os dados, o módulo manipulador_arquivo garante a persistência, e o main.py serve como a interface amigável. É assim que o desenvolvimento de software acontece: quebrando um problema grande em partes pequenas e gerenciáveis.

Rolar para cima