📚 Pré-requisitos Teóricos: este projeto aplica conceitos ensinados em Especialização em Sistemas com Python. Recomendado revisar antes de começar.

🐍 Projeto 01: Processador de Arquivos em Lote Desktop

Guia de Engenharia de Software: Arquitetura MVC, Dataclasses, Enums, Type Hints e Interface Desktop

Trilha de Especialização Pedagógica — Nível Intermediário (Curso 25: Sistemas Desktop com Python & POO)


🎯 Objetivo & Escopo do Projeto

Este projeto atua como a ponte pedagógica fundamental entre os scripts introdutórios e a arquitetura de software profissional. Nele, o estudante aprende a construir um Processador e Sanitizador de Arquivos em Lote para automação de rotinas de escritórios de contabilidade e despachantes, aplicando:

  1. Type Hints Estritos (PEP 484 & PEP 585): anotações de tipo completas em funções, métodos e coleções genéricas (list[T], Optional[str], Tuple[int, int], Callable).
  2. Dataclasses Modernas (@dataclass(slots=True)): modelagem de entidades de domínio com baixo consumo de memória e sem código boilerplate.
  3. Enumerações Fortemente Tipadas (enum.Enum): eliminação de “strings mágicas” através dos enums StatusProcessamento e TipoOperacao.
  4. Encapsulamento com @property: cálculo dinâmico de extensões e formatação amigável de tamanhos (B, KB, MB).
  5. Arquitetura em Camadas (Padrão MVC): desacoplamento rigoroso entre Modelos (models.py), Regras de Negócio/Serviços (services.py), Interface Desktop (app.py) e CLI (cli.py).
  6. Robustez de I/O com Fallback de Encodings: tratamento automático de encodings divergentes (UTF-8, Latin-1, CP1252) para evitar travamentos em arquivos corrompidos.

🏛️ Diagrama de Arquitetura MVC

flowchart TD
    subgraph View ["🖥️ Camada de Apresentação (View / Controller)"]
        GUI["app.py (AppProcessadorLote)\nTkinter / ttk.Treeview / Progressbar"]
        CLI["cli.py (Interface de Terminal)\nExecução em lote sem GUI"]
    end

    subgraph Service ["⚙️ Camada de Serviços / Negócio (Service)"]
        SVC["services.py (ProcessadorArquivosService)\nTransformação, Encodings e Callbacks"]
    end

    subgraph Model ["📦 Camada de Domínio / Dados (Model)"]
        M1["ArquivoLote (@dataclass)\nMetadados, @property tamanho_formatado"]
        M2["ConfiguracaoLote (@dataclass)\nOperação, prefixo, sufixo e destino"]
        E1["StatusProcessamento (Enum)"]
        E2["TipoOperacao (Enum)"]
    end

    GUI -->|Invoca| SVC
    CLI -->|Invoca| SVC
    SVC -->|Manipula| M1
    SVC -->|Utiliza| M2
    M1 --> E1
    M2 --> E2

    style View fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
    style Service fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
    style Model fill:#fffde7,stroke:#fbc02d,stroke-width:2px

📂 Estrutura de Pastas e Arquivos

sistemas_python_01_desktop_poo/
├── models.py                # Entidades Dataclass, Enums e Type Hints PEP 484/585
├── services.py              # Regras de transformação, tratamento de encodings e callbacks
├── app.py                   # Interface Gráfica Desktop com Tkinter / ttk.Treeview
├── cli.py                   # Interface de Linha de Comando interativa
├── main.py                  # Hub Launcher central (GUI, CLI ou Testes)
├── tests/
│   └── test_processor.py    # Suíte de testes unitários automatizados com unittest
├── docs/
│   └── adr/                 # Architectural Decision Records (ADRs)
└── index.md                 # Guia técnico e documentação pedagógica

🚀 Como Executar no Laboratório

1. Abra o terminal na pasta deste projeto

No VS Code / PyCharm, abra a pasta deste projeto (File > Open Folder) ou navegue via terminal:

cd sistemas_python_01_desktop_poo

2. Execute o Hub Launcher ou Modos Específicos

# Executar o Hub Launcher (Menu interativo):
python main.py

# Ou executar diretamente a Interface Gráfica Desktop:
python app.py

# Executar a Interface de Linha de Comando (CLI):
python cli.py

# Executar a Suíte de Testes Unitários:
python -m unittest discover -s tests

[!TIP] Dica para execução a partir da raiz do repositório: Se você abriu o repositório completo no VS Code, basta executar: python proj_aplicacoes_full_stack/projetos/sistemas_python_01_desktop_poo/main.py


📖 Destaques Técnicos do Código

1. Modelos de Domínio com Dataclasses e Enums (models.py)

from dataclasses import dataclass, field
from enum import Enum
import os
from typing import Optional

class StatusProcessamento(str, Enum):
    PENDENTE = "Pendente"
    PROCESSANDO = "Processando"
    SUCESSO = "Sucesso"
    ERRO = "Erro"

class TipoOperacao(str, Enum):
    RENOMEAR_PREFIXO = "Adicionar Prefixo/Sufixo"
    SANITIZAR_ENCODING = "Sanitizar Encoding (UTF-8)"
    MAIUSCULAS = "Converter Conteúdo para MAIÚSCULAS"
    MINUSCULAS = "Converter Conteúdo para minúsculas"

@dataclass(slots=True)
class ArquivoLote:
    caminho_origem: str
    nome_original: str = field(init=False)
    tamanho_bytes: int = field(init=False)
    status: StatusProcessamento = StatusProcessamento.PENDENTE
    mensagem_erro: Optional[str] = None
    caminho_destino: Optional[str] = None

    def __post_init__(self) -> None:
        self.nome_original = os.path.basename(self.caminho_origem)
        self.tamanho_bytes = os.path.getsize(self.caminho_origem) if os.path.exists(self.caminho_origem) else 0

    @property
    def tamanho_formatado(self) -> str:
        if self.tamanho_bytes < 1024:
            return f"{self.tamanho_bytes} B"
        elif self.tamanho_bytes < 1024 * 1024:
            return f"{self.tamanho_bytes / 1024:.2f} KB"
        return f"{self.tamanho_bytes / (1024 * 1024):.2f} MB"

2. Serviço de Processamento com Fallback de Encodings (services.py)

class ProcessadorArquivosService:
    def processar_lote(self, arquivos: list[ArquivoLote], config: ConfiguracaoLote) -> tuple[int, int]:
        sucessos, erros = 0, 0
        total = len(arquivos)
        for indice, arq in enumerate(arquivos, start=1):
            try:
                self._processar_arquivo_individual(arq, config)
                sucessos += 1
            except Exception as e:
                arq.marcar_erro(str(e))
                erros += 1
            if self.callback_progresso:
                self.callback_progresso(indice, total, arq)
        return sucessos, erros

🧪 Validação dos Testes Unitários

Ran 4 tests in 0.032s — OK

Os testes automatizados cobrem:


⬅️ Ver Todos os Projetos no Super-Hub 📚 Trilha Sistemas com Python 🏠 Página Inicial