Visão Geral do Projeto
Este projeto desenvolve um algoritmo de verificação de plágio que calcula a taxa de similaridade entre um texto original e uma versão potencialmente plagiada. O sistema aceita caminhos de arquivo via argumentos de linha de comando para o texto original, o texto comparado e o arquivo de saída, produzindo um resultado de taxa de repetição com precisão de duas casas decimais.
Estrutura do Código e Design de Interface
O código é organizado em dois módulos principais: verificador.py (lógica central) e teste_verificador.py (testes unitários). A arquitetura é modular, com funções dedicadas para operações de arquivo, processamento de texto e cálculo de similaridade.
Módulos e Funções Chave
- Operações de Arquivo:
ler_arquivo(caminho: str) -> str: Lê um arquivo de texto, tratando exceções de codificação e arquivo não encontrado.gravar_resultado(caminho: str, taxa: float) -> None: Escreve a taxa de similaridade formatada em um arquivo.
- Processamento de Texto:
preprocessar_texto(texto: str) -> list: Realiza limpeza de pontuação e segmentação de palavras usando a biblioteca jieba.construir_vocabulario(palavras1: list, palavras2: list) -> set: Cria um vocabulário unificado a partir dos textos.
- Cálculo de Similaridade:
calcular_frequencia_palavras(palavras: list, vocabulario: set) -> list: Gera um vetor de frequência de palavras.similaridade_cosseno(vetor1: list, vetor2: list) -> float: Calcula a similaridade entre dois vetores.computar_similaridade(texto1: str, texto2: str) -> float: Integra o fluxo completo, retornando a taxa de repetição.
Princípio do Algoritmo
O sistema emprega o algoritmo de similaridade de cosseno, repersentando textos como vetores em um espaço multidimensional, onde cada dimensão corresponde a uma palavra. A fórmula é:
similaridade = (A · B) / (||A|| × ||B||)
Aqui, A·B é o produto escalar, e ||A|| e ||B|| são as normas dos vetores. Valores mais próximos de 1 indicam maior similaridade.
Otimização de Desempenho
Uma análise inicial com cProfile revelou gargalos na segmentação de texto (jieba) e no cálculo de vetores (complexidade O(n²)). As melhorias incluíram:
- Uso do modo rápido do jieba (
jieba.lcut(texto, cut_all=False)) para reduzir o tempo de segmentação. - Substituição de listas por dicionários para contagem de frequência, reduzindo a complexidade para O(n).
- Leitura de arquivos grandes com geradores para minimizar o consumo de memória.
Em testes com texto de 100.000 caracteres, o tempo de execução caiu de 1,82s para 0,65s, e o uso de memória de 48MB para 22MB.
Testes Unitários
Testes abrangentes foram projetados para cobrir cenários normais, de limite e exceções. Exemplo de teste para similaridade de cosseno:
import unittest
from verificador import computar_similaridade, ler_arquivo, gravar_resultado
class TesteVerificador(unittest.TestCase):
def test_textos_identicos(self):
"""Verifica taxa 1.00 para textos iguais."""
texto_fonte = "Conteúdo original de teste para análise."
texto_comparado = "Conteúdo original de teste para análise."
resultado = computar_similaridade(texto_fonte, texto_comparado)
self.assertAlmostEqual(resultado, 1.0, places=2)
def test_textos_similares(self):
"""Testa similaridade parcial."""
original = "O algoritmo processa os dados de entrada."
plagiado = "O método processa as informações de entrada."
taxa = computar_similaridade(original, plagiado)
self.assertTrue(0.5 <= taxa <= 0.9)
def test_texto_vazio(self):
"""Lida com entradas vazias."""
self.assertEqual(computar_similaridade("", "amostra"), 0.0)
self.assertEqual(computar_similaridade("amostra", ""), 0.0)
A cobertura de código atingiu 98,7% nas linhas e 100% nas funções, com foco em caminhos lógicos críticos.
Tratamento de Exceções
O sistema implementa tratamento robusto para erros comuns:
- Arquivo Não Encontrado: Captura
FileNotFoundErrore exibe mensgaem informativa. - Erro de Codificação: Tenta múltiplas codificações (ex.: UTF-8, GBK) ao ler arquivos.
- Argumentos Insuficientes: Valida argumentos de linha de comando, lançando
IndexErrorcom instruções de uso. - Divisão por Zero: Para textos vazios, retorna similaridade 1.0 em vez de gerar erro.