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

Para realizar o projeto, atente-se a cada passo descrito a seguir, 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 deste repositório, utilizando uma branch específica e um Pull Request para colocar seus códigos.

Termos e acordos

Ao iniciar este projeto, você concorda com as diretrizes do Código de Conduta e do Manual da Pessoa Estudante da Trybe.

Entregáveis

🤷🏽‍♀️ Como entregar

Para entregar o seu projeto você deverá criar um Pull Request neste repositório.

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

👨‍💻 O que deverá ser desenvolvido

Neste projeto você deverá implementar um programa que simule um algoritmo de indexação de documentos similar ao do Google. Seu programa deverá ser capaz de identificar ocorrências de termos em arquivos TXT.

Para isso, o programa desenvolvido por você deverá ter dois módulos:

  • Módulo de gerenciamento de arquivos que permite anexar arquivos de texto (formato TXT) e;
  • Módulo de buscas que permite operar funções de busca sobre os arquivos anexados.

👀 Neste projeto não iremos focar na análise de significados ou busca por sinônimos.

🚵 Habilidades exercitadas:

  • Manipular Pilhas;

  • Manipular Deque;

  • Manipular Nó & Listas Ligadas e;

  • Manipular Listas Duplamente Ligadas.

🗓 Data de Entrega
  • Este projeto é individual;
  • Serão 2 dias de projeto;
  • Data para entrega no prazo regular: 13/12/2022 14:00.

Orientações

⚠ Antes de começar a desenvolver
  1. Clone o repositório
  • Use o comando: git clone git@github.com:tryber/sd-019-c-project-ting.git
  • Entre na pasta do repositório que você acabou de clonar:
    • cd sd-019-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 joaozinho-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 joaozinho 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 joaozinho/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 joaozinho-ting
  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
  • Coloque um título para a sua Pull Request
    • Exemplo: "Cria tela de busca"
  • 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
⌨️ 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 origin 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)
🧱 Estrutura do Projeto
Este repositório já contém um template com a estrutura de diretórios e arquivos, tanto de código quanto de teste criados. Veja abaixo:
Legenda:
🔸Arquivos que não podem ser alterados
🔹Arquivos a serem alterados para realizar os requisitos.
.
├──🔸dev-requirements.txt
├──🔸pyproject.toml
├──🔸README.md
├──🔸requirements.txt
├──🔸setup.cfg
├──🔸setup.py
├──statics
│   ├──🔸arquivo_teste.csv
│   ├──🔸arquivo_teste.txt
│   ├──🔸nome_pedro.txt
│   ├──🔸novo_paradigma_globalizado-min.txt
│   └──🔸novo_paradigma_globalizado.txt
├──tests
│   ├──🔸__init__.py
│   ├──🔸test_file_mangement.py
│   ├──🔸test_file_process.py
│   ├──🔸test_queue.py
│   └──🔸test_word_search.py
├──ting_file_management
│   ├──🔹file_management.py
│   ├──🔹file_process.py
│   ├──🔸__init__.py
│   └──🔹queue.py
├──ting_word_searches
│   ├──🔸__init__.py
│   └──🔹word_search.py
└──🔸trybe.yml

Na estrutura deste template, você deve implementar as funções necessárias. Novos arquivos e funções podem ser criados conforme a necessidade da sua implementação, porém não remova arquivos já existentes.

🎛 Linter

Para garantir a qualidade do código, vamos utilizar neste projeto o linter Flake8. Assim o código estará alinhado com as boas práticas de desenvolvimento, sendo mais legível e de fácil manutenção! Para rodá-lo localmente no projeto, execute o comandos abaixo:

python3 -m flake8

⚠️ PULL REQUESTS COM ISSUES DE LINTER NÃO SERÃO AVALIADOS. ATENTE-SE PARA RESOLVER TODAS AS ISSUES ANTES DE FINALIZAR O DESENVOLVIMENTO! ⚠️

🏕️ Ambiente Virtual
O Python oferece um recurso chamado ambiente virtual que permite sua máquina rodar, sem conflitos, diferentes tipos de projetos com diferentes versões de bibliotecas. Para utilizar este recurso siga os passos a seguir:
  1. criar o ambiente virtual
$ python3 -m venv .venv
  1. ativar o ambiente virtual
$ source .venv/bin/activate
  1. instalar as dependências no ambiente virtual
$ python3 -m pip install -r dev-requirements.txt

Com o seu ambiente virtual ativo as dependências serão instaladas neste ambiente.

👀 Caso precise desativar o ambiente virtual execute o comando "deactivate".

⚠️ Lembre-se de ativar o ambiente virtual novamente quando voltar a trabalhar no projeto.

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

🛠 Testes

👀 Para executar os testes certifique-se de que você está com o ambiente virtual ativado.

Executar os testes

$ python3 -m pytest

O arquivo pyproject.toml já configura corretamente o pytest. Entretanto, caso você tenha problemas com isso e queira explicitamente uma saída completa, o comando é:

python3 -m pytest -s -vv

Caso precise executar apenas um arquivo de testes basta executar o comando:

python3 -m pytest tests/nomedoarquivo.py

Caso precise executar apenas uma função de testes basta executar o comando:

python3 -m pytest -k nome_da_func_de_tests

Se desejar que os testes parem de ser executados quando acontecer o primeiro erro, use o parâmetro -x

python3 -m pytest -x tests/nomedoarquivo.py

Para executar um teste específico de um arquivo, basta executar o comando:

python3 -m pytest tests/nomedoarquivo.py::test_nome_do_teste

Se quiser saber mais sobre a instalação de dependências com pip, veja esse artigo.

🤝 Depois de terminar o desenvolvimento (opcional)

Para sinalizar que o seu projeto está pronto para o "Code Review", 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-019-c.

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.

🗣 Nos dê feedbacks sobre o projeto!

Ao finalizar e submeter o projeto, não se esqueça de avaliar sua experiência preenchendo o formulário. Leva menos de 3 minutos!

FORMULÁRIO DE AVALIAÇÃO DE PROJETO

🗂 Compartilhe seu portfólio!

Agora que você finalizou os requisitos, chegou a hora de mostrar ao mundo que você aprendeu algo novo! 🚀

Siga esse guia que preparamos com carinho para disponibilizar o projeto finalizado no seu GitHub pessoal.

Esse passo é super importante para ganhar mais visibilidade no mercado de trabalho, mas também é útil para manter um back-up do seu trabalho.

E você sabia que o LinkedIn é a principal rede social profissional e compartilhar o seu aprendizado lá é muito importante para quem deseja construir uma carreira de sucesso? Compartilhe esse projeto no seu LinkedIn, marque o perfil da Trybe (@trybe) e mostre para a sua rede toda a sua evolução.

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.

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

  • O tamanho da fila deverá ser exposto utilizando o método __len__ que permitirá, após implementado, o uso do comando len(instancia_da_fila) para se obter o tamanho da fila.

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

🤖 O que será verificado pelo avaliador
  • 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 e;

  • 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.

  • Caso o arquivo TXT não exista, deve ser exibida a mensagem Arquivo {path_file} não encontrado na stderr, em que {path_file} é o caminho do arquivo;

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

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

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.
🤖 O que será verificado pelo avaliador
  • 2.1 - Será validado que 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, em que {path_file} é o caminho do arquivo e;

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

3 - Implemente a função process no módulo file_process. Essa função deverá ser capaz de transformar o conteúdo da lista gerada pela função txt_importer em um dicionário que será armazenado dentro da Queue.

  • A função irá receber como parâmetro um objeto instanciado da fila implementada no requisito 1 e o caminho para um arquivo;

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

  • A função deve processar o arquivo passado por parâmetro (ou seja, gerar um dicionário com o formato e informações especificadas abaixo);

Exemplo da estrutura de saída:
{
    "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
}
  • Deve-se ignorar arquivos que já tenham sido processados anteriormente (ou seja, arquivos com o mesmo nome e caminho (nome_do_arquivo) não devem ser readicionados a fila);

  • Após cada nova inserção válida, a função deve mostrar via stdout os dados processados, conforme estrutura no exemplo abaixo.

🤖 O que será verificado pelo avaliador
  • 3.1 - Será validado que ao executar a função process com um arquivo já existente na fila a execução deverá ignorá-lo e;

  • 3.2 - Será validado que ao executar a função process com sucesso deverá mostrar dados 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 implementada no requisito 1.

  • Caso não existam 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, em que {path_file} é o caminho do arquivo.

🤖 O que será verificado pelo avaliador
  • 4.1 - Será validado que ao executar a função remove com sucesso deverá exibir mensagem correta via stdout e;

  • 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.

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

  • Caso a posição não exista, deve ser exibida a mensagem de erro Posição inválida via stderr;

  • Caso a posição seja válida, as informações relacionadas ao arquivo devem ser mostradas via stdout, seguindo o exemplo de estrutura abaixo.

Exemplo da estrutura de saída em caso de sucesso:
{
    "nome_do_arquivo": "arquivo_teste.txt",
    "qtd_linhas": 3,
    "linhas_do_arquivo": [...]
}
🤖 O que será verificado pelo avaliador
  • 5.1 - Será validado que ao executar a função file_metadata com sucesso deverá exibir a mensagem correta via stdout e;

  • 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 verifique a existência de uma palavra em todos os arquivos processados.

  • A função irá receber como parâmetros a palavra a ser buscada e a fila implementada no requisito 1;

  • A função deve retornar uma lista com as informações de cada arquivo e suas linhas em que a palavra foi encontrada, conforme exemplo da estrutura de retorno;

  • A busca deve ser case insensitive (não diferenciar maiúsculas e minúsculas);

  • 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.

Exemplo da estrutura de retorno:
[{
  "palavra": "de",
  "arquivo": "arquivo_teste.txt",
  "ocorrencias": [
    {
      "linha": 2
    },
    {
      "linha": 7
    }
  ]
}]
🤖 O que será verificado pelo avaliador
  • 6.1 - Será validado que ao executar a função exists_word com sucesso deverá retornar a estrutura correta;

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

  • 6.3 - Será validado que ao executar a função exists_word a fila original não deverá ser alterada.

7 - Implemente uma função search_by_word dentro do módulo word_search, que busque uma palavra em todos os arquivos processados.

  • Esta função deverá seguir os mesmos critérios do requisito seis, mas deverá incluir na saída o conteúdo das linhas encontradas, conforme exemplo da estrutura de retorno.

👀 De olho na dica: este requisito é uma ótima oportunidade para reforçar a prática de código limpo!

Exemplo da estrutura de retorno:
[{
  "palavra": "de",
  "arquivo": "arquivo_teste.txt",
  "ocorrencias": [
    {
      "linha": 3,
      "conteudo": "Acima de tudo,"
    },
    {
      "linha": 4,
      "conteudo": "é fundamental ressaltar que a adoção de políticas descentralizadoras nos obriga"
    }
  ]
}]
🤖 O que será verificado pelo avaliador
  • 7.1 - Será validado que ao executar a função search_by_word com sucesso deverá retornar a estrutura correta;

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

  • 7.3 - Será validado que ao executar a função search_by_word a fila original não deverá ser alterada.