/document-indexing-project

Projeto Trybe de um programa que permita anexar arquivos de texto e opere funções de busca.

Primary LanguagePython

Projeto Trybe - TING / Document Indexing

Projeto Trybe de um programa que permita anexar arquivos de texto e opere funções de busca. 🚀

Sumário


Habilidades

  • Manipular Pilhas

  • Manipular Deque

  • Manipular Nó & Listas ligadas

  • Manipular Listas duplamentes ligadas


Entregáveis

Para entregar o seu projeto você deverá criar um Pull Request neste repositório. Este Pull Request deverá conter os arquivos apresentados na sessão: Desenvolvimento e testes.

Lembre-se que você pode consultar nosso conteúdo sobre Git & GitHub sempre que precisar!


O que deverá ser desenvolvido

A Trybe lhe convida para implementar um programa que simule o algoritmo de indexação de documentos similar ao do Google. Ou seja, um programa que permita anexar arquivos de texto e posteriormente opere funções de busca sobre tais arquivos

Com a quantidade de informações disponíveis na Web, encontrar o que você precisa seria quase impossível sem nenhuma ajuda para classificá-las. Os sistemas de classificação do Google organizam centenas de bilhões de páginas da Web, no índice da pesquisa, para fornecer os resultados mais úteis e relevantes em uma fração de segundo. Além disso tudo, a Google também precisa se preocupar em apresentar os resultados de uma maneira que ajude você a encontrar o que está procurando com mais facilidade ainda.

Analisar palavras

Compreender o significado da sua pesquisa é crucial para retornarmos boas respostas. Por isso, para encontrar páginas com informações relevantes, nosso primeiro passo é analisar o significado das palavras na consulta de pesquisa. Desenvolvemos modelos linguísticos para decifrar as sequências de palavras que precisamos procurar no índice.

Não iremos nos apegar a análise de significados ou busca por sinônimos. Nosso objetivo será identificar ocorrências de termos em arquivos TXT. Neste contexto, devemos criar um programa que permita anexar arquivos de texto e posteriormente operar funções de busca sobre tais arquivos.

Sendo assim o programa deverá possuir dois módulos:

  • Modo gerenciamento de arquivos;

  • Modo de buscas.


Desenvolvimento

Este repositório já contém um template com a estrutura de diretórios e arquivos, tanto de código quanto de teste criados. Há também o diretório statics que contém os arquivos necessários para realização de testes, caso julgue necessário, sinta-se à vontade para criar novos arquivos ou editar o conteúdo dos arquivos existentes. Veja abaixo:

.
├── statics
│ ├── arquivo_teste.txt
│ ├── novo_paradigma_globalizado.txt
│ └── novo_paradigma_globalizado-min.txt
├── tests
├── ting_file_management
│ ├── file_management.py
│ └── file_process.py
├── ting_word_searches
│ └── word_search.py
├── README.md
├── requirements.txt
└── setup.cfg

Apesar do projeto já possuir uma estrutura base, você quem deve implementar tanto as funções quanto os testes (extra). Novos arquivos podem ser criados conforme a necessidade.

Para executar os testes, lembre-se de primeiro criar e ativar o ambiente virtual, além de também instalar as dependências do projeto. Isso pode ser feito através dos comandos:

$ python3 -m venv .venv

$ source .venv/bin/activate

$ python3 -m pip install -r dev-requirements.txt

O arquivo requirements.txt contém todos as dependências que serão utilizadas no projeto, ele está agindo como se fosse um package.json de um projeto Node.js.


Instruções para entregar seu projeto:

ANTES DE COMEÇAR A DESENVOLVER:

Recomendações

  • ⚠ Para o desenvolvimento deste projeto recomendamos o uso da versão 3.8 ou 3.9 da linguagem Python. Para saber a versão que está configurada em seu dispositivo execute o comando python3 -V em seu terminal. Para mais detalhes relacionados a configuração do ambiente Python consulte o nosso guia de configuração de ambiente.
  1. Clone o repositório
  • git clone git@github.com:tryber/sd-013-c-project-ting.git.
  • Entre na pasta do repositório que você acabou de clonar:
    • sd-013-c-project-ting
  1. Crie o ambiente virtual para o projeto
  • python3 -m venv .venv && source .venv/bin/activate
  1. Instale as dependências
  • python3 -m pip install -r dev-requirements.txt
  1. Crie uma branch a partir da branch main
  • Verifique que você está na branch main
    • Exemplo: git branch
  • Se não estiver, mude para a branch main
    • Exemplo: git checkout main
  • Agora crie uma branch à qual você vai submeter os commits do seu projeto
    • Você deve criar uma branch no seguinte formato: nome-github-nome-do-projeto
    • Exemplo: git checkout -b exemplo-project-ting
  1. Adicione as mudanças ao stage do Git e faça um commit
  • Verifique que as mudanças ainda não estão no stage
    • Exemplo: git status (deve aparecer listada a pasta exemplo em vermelho)
  • Adicione o novo arquivo ao stage do Git
    • Exemplo:
      • git add . (adicionando todas as mudanças - que estavam em vermelho - ao stage do Git)
      • git status (deve aparecer listado o arquivo exemplo/README.md em verde)
  • Faça o commit inicial
    • Exemplo:
      • git commit -m 'iniciando o projeto ting' (fazendo o primeiro commit)
      • git status (deve aparecer uma mensagem tipo nothing to commit )
  1. Adicione a sua branch com o novo commit ao repositório remoto
  • Usando o exemplo anterior: git push -u origin exemplo-project-name
  1. Crie um novo Pull Request (PR)
  • Vá até a página de Pull Requests do repositório no GitHub
  • Clique no botão verde "New pull request"
  • Clique na caixa de seleção "Compare" e escolha a sua branch com atenção
  • Clique no botão verde "Create pull request"
  • Adicione uma descrição para o Pull Request e clique no botão verde "Create pull request"
  • Não se preocupe em preencher mais nada por enquanto!
  • Volte até a página de Pull Requests do repositório e confira que o seu Pull Request está criado

Testes

Com as dependências já instaladas, para executar os testes basta usar o comando:

$ python3 -m pytest

Se quiser saber mais sobre a instalação de dependências com pip, veja esse artigo: https://medium.com/python-pandemonium/better-python-dependency-and-package-management-b5d8ea29dff1

Para verificar se você está seguindo o guia de estilo do Python corretamente, execute o comando:

$ python3 -m flake8

Requisitos obrigatórios:

Pacote ting_file_management

1 - Implemente uma fila para armazenar os arquivos que serão lidos.

Preencha a classe Queue, presente no arquivo queue.py utilizando as estruturas vistas no módulo.

A fila (Queue) deve ser uma estrutura FIFO, ou seja, o primeiro item a entrar, deve ser o primeiro a sair. Utilize seus conhecimentos de estruturas de dados para otimizar as operações implementadas.

Devemos implementar os métodos de inserção (enqueue), remoção (dequeue) e busca (search).

Vamos expor o tamanho da nossa fila através do método __len__ que, após implementeado, permite o uso de len(instancia_da_fila) para se obter o tamanho da fila.

Na busca, caso um índice inválido seja passado, uma exceção do tipo IndexError deve ser lançada. Para uma fila com N elementos, índices válidos são inteiros entre 0 e N-1.

As seguintes verificações serão feitas:
  • 1.1 - Será validado que o método enqueue deve adicionar um elemento à fila, modificando seu tamanho.

  • 1.2 - Será validado que o método dequeue deve remover o elemento a mais tempo na fila, modificando seu tamanho.

  • 1.3 - Será validado que o método search deve retornar um valor da fila a partir de um índice válido.

  • 1.4 - Será validado que o método search deve lançar a exceção IndexError quando o índice for inválido.

2 - Implemente uma função txt_importer dentro do módulo file_management capaz de importar notícias a partir de um arquivo TXT, utilizando "\n" como separador. Todas as mensagens de erro devem ir para a stderr.

Exemplo simples de um arquivo txt a ser importado:

Acima de tudo,
é fundamental ressaltar que a adoção de políticas descentralizadoras nos obriga
à análise do levantamento das variáveis envolvidas.
  • Caso o arquivo TXT não exista, deve ser exibida a mensagem: "Arquivo {path_file} não encontrado";

  • Caso a extensão do arquivo seja diferente de .txt, deve ser exibida uma mensagem: "Formato inválido" na stderr;

  • A função deve retornar uma lista contendo as linhas do arquivo.

As seguintes verificações serão feitas:
  • 2.1 - Será validado que ao executar o método txt_importer deve retornar uma lista contendo as linhas do arquivo;

  • 2.2 - Será validado que ao executar o método txt_importer com um arquivo TXT que não exista, deve ser exibida a mensagem: Arquivo {path_file} não encontrado na stderr;

  • 2.3 - Será validado que ao executar o método txt_importer com uma extensão diferente de .txt, deve ser exibida uma mensagem: Formato inválido na stderr.

3 - Implemente uma função process dentro do módulo file_process capaz de ler o arquivo carregado na função anterior e efetuar o preprocessamento do conteúdo.

Exemplo de retorno:

{
    "nome_do_arquivo": "arquivo_teste.txt", # Caminho do arquivo recém adicionado
    "qtd_linhas": 3,                        # Quantidade de linhas existentes no arquivo
    "linhas_do_arquivo": [...]              # linhas retornadas pela função do requisito 2
}
  • A função irá receber como parâmetro a fila que implementamos no requisito 1 e o caminho do arquivo.

  • A instância da fila recebida por parâmetro deve ser utilizada para registrar o processamento dos arquivos.

  • Deve-se ignorar arquivos que já tenham sido processados anteriormente (ou seja, que tenham o mesmo caminho).

  • O exemplo de saída acima deve ser emitido após cada nova inserção válida, via stdout;

As seguintes verificações serão feitas:
  • 3.1 - Será validado que ao executar a função process com um arquivo já existente na fila a execução deverá ignorá-lo;

  • 3.2 - Será validado que ao executar a função process com sucesso deverá retornar mensagem via stdout.

4 - Implemente uma função remove dentro do módulo file_process capaz de remover o primeiro arquivo processado

  • A função irá receber como parâmetro a fila que implementamos no requisito 1.

  • Caso não hajam arquivos na fila, a função deve apenas emitir a mensagem Não há elementos via stdout;

  • Em caso de sucesso de remoção, deve ser emitida a mensagem Arquivo {path_file} removido com sucesso via stdout.

As seguintes verificações serão feitas:
  • 4.1 - Será validado que ao executar a função remove com sucesso deverá exibir mensagem correta via stdout.

  • 4.2 - Será validado que ao executar a função remove um arquivo inexistente deverá exibir a mensagem correta via stdout.

5 - Implemente uma função file_metadata dentro do módulo file_process capaz de apresentar as informações superficiais de um arquivo processado.

  • Baseado na posição informada, deve ser apresentado as informações relacionadas ao arquivo, parecido com o apresentado abaixo;

  • Em caso da posição não existir, deve ser exibida a mensagem de erro Posição inválida via stderr.

  • A função irá receber como parâmetro a fila que implementamos no requisito 1 e o índice a ser buscado.

Exemplo de mensagem com sucesso:

{
    "nome_do_arquivo": "arquivo_teste.txt",
    "qtd_linhas": 3,
    "linhas_do_arquivo": [...]
}
As seguintes verificações serão feitas:
  • 5.1 - Será validado que ao executar a função file_metadata com sucesso deverá exibir a mensagem correta via stdout.

  • 5.2 - Será validado que ao executar a função file_metadata com posição inválida deverá exibir a mensagem correta via stderr.

Pacote ting_word_searches

6 - Implemente uma função exists_word dentro do módulo word_search, que valide a existência da palavra em todos os arquivos processados. Para cada palavra encontrada, deve-se listar sua linha conforme apresentação abaixo.

  • A busca deve ser case insensitive e deve retornar uma lista no formato:
[
  {
    "palavra": "de",
    "arquivo": "arquivo_teste.txt",
    "ocorrencias": [
      {
        "linha": 1
      },
      {
        "linha": 2
      }
    ]
  }
]
  • Caso a palavra não seja encontrada em nenhum arquivo, deve-se retornar uma lista vazia.

  • A fila não deve ser modificada durante a busca. Ela deve permanecer com os mesmos arquivos processados antes e depois da busca!

As seguintes verificações serão feitas:
  • 6.1 - Será validado que ao executar a função exists_word com sucesso deverá retornar a mensagem correta.

  • 6.2 - Será validado que ao executar a função exists_word com palavra inexistente deverá retornar uma lista vazia.

7 - Implemente uma função search_by_word dentro do módulo word_search, que busque a palavra em todos os arquivos processados. Para cada palavra encontrada, deve-se listar sua linha, o conteúdo e o arquivo da ocorrência.

  • A busca deve ser case insensitive e deve retornar uma lista no formato:
[
  {
    "palavra": "de",
    "arquivo": "arquivo_teste.txt",
    "ocorrencias": [
      {
        "linha": 1,
        "conteudo": "Acima de tudo,"
      },
      {
        "linha": 2,
        "conteudo": "é fundamental ressaltar que a adoção de políticas descentralizadoras nos obriga"
      }
    ]
  }
]
  • Caso a palavra não seja encontrada em nenhum arquivo, deve-se retornar uma lista vazia.

  • A fila não deve ser modificada durante a busca. Ela deve permanecer com os mesmos arquivos processados antes e depois da busca!

As seguintes verificações serão feitas:
  • 7.1 - Será validado que ao executar a função search_by_word com sucesso deverá retornar a mensagem.

  • 7.2 - Será validado que ao executar a função search_by_word com palavra inexistente deverá retornar uma lista vazia.