Caderno operacional — problema, hipótese e prova

Situação concreta

O mesmo equipamento aparece duas vezes no cadastro: “Bomba 01” e “BOMBA-1”. Técnicos abrem ordens diferentes e o histórico fica dividido. Neste laboratório, você não construirá um ERP. Criará uma experiência pequena para responder: uma regra simples consegue sinalizar possíveis duplicidades sem bloquear cadastros legítimos?

Pré-requisitos, objetivos e materiais

Leia O mapa antes do código. Instale Python 3 e use um editor de texto. Você produzirá uma pasta com quatro artefatos: problem-card.md, casos.csv, duplicados.py e evidencia.md. Artefato é qualquer resultado persistente que outra pessoa possa inspecionar.

Ao final, você deverá explicar a regra, executá-la, mostrar onde erra e recomendar “seguir”, “reformular” ou “não construir”.

Vocabulário do laboratório

  • Baseline é a referência simples usada para comparação. Aqui, é a igualdade após uma normalização básica.
  • Falso positivo ocorre quando itens diferentes são sinalizados como duplicados.
  • Falso negativo ocorre quando uma duplicidade real não é detectada.
  • Regressão é um comportamento que funcionava e deixa de funcionar após uma mudança.
  • Reprodutibilidade significa que outra pessoa segue as instruções e obtém o mesmo resultado.
  • CSV, comma-separated values, é um formato textual de tabela no qual cada linha representa um registro.
  • Unicode é um padrão para representar caracteres de muitos sistemas de escrita; por isso o código consegue tratar letras acentuadas de forma explícita.

Modelo mental e limite

Você seguirá um ciclo curto:

Fluxo: Descrever o problema, Escrever casos esperados, Executar a baseline, Comparar esperado e observado, Registrar a evidência, Tomar decisãoDescrever o problemaEscrever casos esperadosExecutar a baselineComparar esperado eobservadoRegistrar a evidênciaTomar decisão
Ler o fluxo em texto
  1. 1. Descrever o problema
  2. 2. Escrever casos esperados
  3. 3. Executar a baseline
  4. 4. Comparar esperado e observado
  5. 5. Registrar a evidência
  6. 6. Tomar decisão

O ciclo reduz improviso, mas não descobre sozinho a definição empresarial de duplicidade. Número patrimonial, série e localização podem importar mais que o nome. A regra será uma triagem, não uma autorização automática para excluir registros.

Antes e agora

Antes, a equipe poderia limpar a planilha manualmente e perder o raciocínio usado. Hoje, mesmo um experimento pequeno pode ser versionado com entradas, comando, resultado e decisão. Ferramentas de IA podem sugerir casos, mas não devem inventar o significado de “mesmo equipamento”. O dono do processo valida a regra; o código apenas a executa.

Passo 1 — escreva o cartão do problema

Crie problem-card.md:

# Possíveis equipamentos duplicados
- Ator: analista de cadastro.
- Evento: tentativa de cadastrar um equipamento.
- Entrada: nome informado e nomes existentes.
- Saída: “revisar” ou “não sinalizado”.
- Invariante: o experimento nunca exclui nem mescla registros.
- Fora de escopo: decidir identidade pelo número de série.
- Consequência do falso positivo: revisão humana desnecessária.
- Consequência do falso negativo: histórico permanece dividido.

Leia cada linha para alguém. Se essa pessoa não souber o que o programa pode fazer, revise antes de continuar.

Passo 2 — prepare exemplos antes do código

Crie casos.csv em UTF-8:

existente,novo,esperado
Bomba 01,BOMBA-01,revisar
Gerador Norte,Gerador Norte,revisar
Bomba 01,Bomba 02,nao_sinalizado
Painel A,Painel B,nao_sinalizado
,Bomba 01,entrada_invalida
Bomba 01,,entrada_invalida

Os dois primeiros são positivos, os dois seguintes protegem diferenças legítimas e os últimos testam vazio. Acrescente casos com espaços extras, acentos e nomes iguais em locais diferentes. Local diferente expõe o limite do modelo: o arquivo ainda não possui localização.

Passo 3 — implemente a baseline, bloco a bloco

Crie duplicados.py. Primeiro, importe ferramentas e normalize o texto:

import csv
import re
import sys
import unicodedata

def normalizar(valor: str) -> str:
    sem_acento = "".join(
        caractere
        for caractere in unicodedata.normalize("NFD", valor)
        if unicodedata.category(caractere) != "Mn"
    )
    return re.sub(r"[^a-z0-9]", "", sem_acento.lower())

lower() ignora maiúsculas; a normalização Unicode separa acentos; a expressão regular remove espaços e pontuação. Isso faz “BOMBA-01” e “Bomba 01” virarem bomba01. O limite é evidente: “Bomba 1” e “Bomba 01” continuam diferentes.

Agora classifique:

def classificar(existente: str, novo: str) -> str:
    if not existente.strip() or not novo.strip():
        return "entrada_invalida"
    if normalizar(existente) == normalizar(novo):
        return "revisar"
    return "nao_sinalizado"

A função não retorna “duplicado”; retorna “revisar”. Essa escolha impede que uma heurística seja confundida com certeza.

Por fim, leia o CSV e conte divergências:

def executar(caminho: str) -> int:
    falhas = 0
    with open(caminho, encoding="utf-8", newline="") as arquivo:
        for numero, caso in enumerate(csv.DictReader(arquivo), start=2):
            observado = classificar(caso["existente"], caso["novo"])
            passou = observado == caso["esperado"]
            print(numero, "PASSOU" if passou else "FALHOU", observado)
            falhas += 0 if passou else 1
    return falhas

if __name__ == "__main__":
    raise SystemExit(executar(sys.argv[1]))

with fecha o arquivo mesmo em caso de erro. O código de saída será zero quando tudo passar e diferente de zero quando houver divergência, permitindo automação futura.

Passo 4 — execute e registre

No terminal, dentro da pasta, execute:

python --version
python duplicados.py casos.csv

Copie versão, comando, data, quantidade de casos e saída para evidencia.md. Não copie nomes reais, patrimônio, série ou pessoa responsável. Dados fictícios bastam para testar a mecânica.

Falha controlada e diagnóstico

Altere temporariamente o primeiro esperado para nao_sinalizado e execute. Registre:

  • sintoma: linha 2 falhou;
  • esperado: nao_sinalizado;
  • observado: revisar;
  • hipótese: o caso esperado contradiz a definição aprovada;
  • experimento: comparar o par normalizado;
  • decisão: corrigir o dado de teste, não a função.

Agora acrescente “Bomba 1” versus “Bomba 01” esperando revisar. A falha é diferente: a baseline não trata zeros à esquerda. Não corrija imediatamente. Pergunte se números representam identificadores, versões ou nomes. Remover zeros indiscriminadamente pode transformar equipamentos distintos em falsos positivos.

Aplicação em manutenção/ERP e segurança

Em produção, obtenha candidatos pela API oficial do ERP, com permissão apenas de leitura. Não consulte diretamente tabelas nem envie toda a base para um serviço externo. A decisão de mesclar continua humana e deve registrar autor, registros envolvidos e justificativa. A tela precisa mostrar os campos que levaram ao alerta.

Limite tentativas e tamanho das entradas; texto é dado não confiável. Não monte comandos de sistema ou consultas de banco concatenando o nome recebido. Este laboratório não acessa rede nem banco justamente para isolar a hipótese.

Exercício guiado e transferência

Acrescente a coluna local. Defina com o responsável se nomes iguais em locais diferentes devem ser revisados. Antes de programar, escreva quatro novos casos. Depois altere a função para receber localização e execute novamente todos os casos antigos. Isso pratica regressão: uma mudança não deve quebrar comportamento aprovado sem decisão explícita.

Transfira o método para outro problema, como localizar manuais por código. Preserve o ciclo, mas redefina falso positivo e falso negativo. O custo dos dois erros pode se inverter.

Desafio e evidência de conclusão

Entregue os quatro arquivos e peça a outra pessoa que execute somente com suas instruções. Ela deve responder:

  1. Qual é o limite conhecido da normalização?
  2. Qual caso realmente falhou e por quê?
  3. A regra pode excluir um cadastro?
  4. Qual decisão final a evidência sustenta?

Critérios de aceite:

  • pelo menos dez casos incluem normal, vazio, limite e contraexemplo;
  • comando termina com zero no conjunto aprovado e diferente de zero no caso provocado;
  • outra pessoa reproduz a saída;
  • evidência não contém dados pessoais ou empresariais reais;
  • decisão final é “seguir”, “reformular” ou “não construir”, acompanhada do motivo.

Conclusão

Você começou com uma dor, não com uma ferramenta; tornou “duplicado” discutível por meio de exemplos; implementou uma baseline pequena; provocou duas falhas com causas diferentes; e gerou evidência reproduzível. Esse hábito reduz código desperdiçado e torna conversas com desenvolvedores mais precisas.

Fontes oficiais

Teste de fixação

Comprove o que você aprendeu

Responda todas as questões. O gabarito comentado só aparece depois do envio.

1. Qual descrição indica que o `problem-card.md` começou pelo problema, e não por uma tecnologia escolhida?
2. Por que escrever vazio, limite, duplicado, concorrente e inválido antes da implementação?
3. Duas hipóteses explicam uma falha. Qual experimento é mais informativo?

Consulta universal

O que você quer encontrar?

Títulos, capítulos, conceitos, termos, laboratórios e ferramentas em uma única busca.

Digite pelo menos dois caracteres.