Boas vindas ao repositório do projeto TING(Trybe is not Google)!

Você já usa o GitHub diariamente para desenvolver os exercícios, certo? Agora, para desenvolver os projetos, você deverá seguir as instruções a seguir. Fique atento a cada passo, e se tiver qualquer dúvida, nos envie por Slack! #vqv 🚀

Aqui você vai encontrar os detalhes de como estruturar o desenvolvimento do seu projeto a partir desse repositório, utilizando uma branch específica e um Pull Request para colocar seus códigos.


Instruções para entregar seu projeto:

ANTES DE COMEÇAR A DESENVOLVER:

  1. Clone o repositório
  • git clone https://github.com/tryber/sd-04-ting.git.
  • Entre na pasta do repositório que você acabou de clonar:
    • sd-04-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-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

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 e testes

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. 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 - Deve haver 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__.

Na busca, caso um índice inválido seja passado, uma exceção do tipo IndexError deve ser lançada.

As seguintes verificações serão feitas:
  • O método enqueue deve adicionar um valor a fila, modificando seu tamanho.

  • O método dequeue deve remover o elemento a mais tempo na fila, modificando seu tamanho.

  • O método search deve buscar um valor na lista à partir de um índice.

  • O método search deve lançar uma exceção quando o índice for inválido.

2 - Deve haver 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";

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

As seguintes verificações serão feitas:
  • Executar o método txt_importer deve retornar uma estrutura contendo as linhas do arquivo;

  • 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";

  • Executar o método txt_importer com uma extensão diferente de .txt, deve ser exibida uma mensagem: "Formato inválido".

3 - Deve haver 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", # Nome 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.

  • Por padrão deve-se ignorar arquivos com o mesmo nome;

  • Não deve haver limites de linhas a serem analisadas;

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

  • O conteúdo processado deve ser adicionado a uma fila.

As seguintes verificações serão feitas:
  • Executar a função process com o mesmo nome a execução deverá ser ignorada;

  • Executar a função process com sucesso deverá retornar mensagem via stdout.

4 - Deve haver 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.

  • Por padrão deve-se ignorar a operação caso não hajam arquivos e emitir a mensagem Não há elementos;

  • Em caso de sucesso de remoção, deve ser emitido a mensagem: "Arquivo {path_file} removido com sucesso".

As seguintes verificações serão feitas:
  • Executar a função remove com sucesso deverá retornar mensagem via stdout.

  • Executar a função remove um arquivo inexistente deverá retornar a mensagem Não há elementos.

5 - Deve haver uma função file_metadata dentro do módulo file_process capaz de apresentar as informações superficiais dos arquivos processados.

  • 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 uma mensagem de erro: "Posição inválida" na stderr.

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

Exemplo de retorno:

{
    "nome_do_arquivo": "arquivo_teste.txt",
    "qtd_linhas": 3,
    "linhas_do_arquivo": [...]
}
As seguintes verificações serão feitas:
  • Executar a função file_metadata com sucesso deverá retornar mensagem via stdout.

  • Executar a função file_metadata com posição inválida deverá retornar a mensagem Posição inválida.

Pacote ting_word_searches

6 - Deve haver 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.
As seguintes verificações serão feitas:
  • Executar a função exists_word com sucesso deverá retornar a mensagem.

  • Executar a função exists_word com palavra inexistente deverá retornar uma lista vazia.

7 - Deve haver 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.
As seguintes verificações serão feitas:
  • Executar a função search_by_word com sucesso deverá retornar a mensagem.

  • Executar a função search_by_word com palavra inexistente deverá retornar uma lista vazia.


DURANTE O DESENVOLVIMENTO

  • Faça commits das alterações que você fizer no código regularmente

  • Lembre-se de sempre após um (ou alguns) commits atualizar o repositório remoto

  • Os comandos que você utilizará com mais frequência são:

    1. git status (para verificar o que está em vermelho - fora do stage - e o que está em verde - no stage)
    2. git add (para adicionar arquivos ao stage do Git)
    3. git commit (para criar um commit com os arquivos que estão no stage do Git)
    4. git push -u nome-da-branch (para enviar o commit para o repositório remoto na primeira vez que fizer o push de uma nova branch)
    5. git push (para enviar o commit para o repositório remoto após o passo anterior)

DEPOIS DE TERMINAR O DESENVOLVIMENTO (OPCIONAL)

Para sinalizar que o seu projeto está pronto para o "Code Review" dos seus colegas, faça o seguinte:

  • Vá até a página DO SEU Pull Request, adicione a label de "code-review" e marque seus colegas:

    • No menu à direita, clique no link "Labels" e escolha a label code-review;

    • No menu à direita, clique no link "Assignees" e escolha o seu usuário;

    • No menu à direita, clique no link "Reviewers" e digite students, selecione o time tryber/students-sd-04.

Caso tenha alguma dúvida, aqui tem um video explicativo.


REVISANDO UM PULL REQUEST

Use o conteúdo sobre Code Review para te ajudar a revisar os Pull Requests.

#VQV 🚀