Projeto job insights - Projeto avaliativo da Trybe do Bloco 32: Introdução à Python

Overview

Termos e acordos

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

Boas vindas ao repositório do projeto Job Insights!

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.


Sumário


Habilidades

  • Utilizar o terminal interativo do Python.
  • Utilizar estruturas condicionais e de repetição.
  • Utilizar funções built-in do Python.
  • Utilizar tratamento de exceções.
  • Realizar a manipulação de arquivos.
  • Escrever funções.
  • Escrever testes com Pytest.
  • Escrever seus próprios módulos e importá-los em outros códigos.

Entregáveis

Para entregar o seu projeto você deverá criar um Pull Request neste repositório. Este Pull Request deverá conter o diretório src e o diretório tests com seus arquivos, que conterão seu código Python e seus testes, respectivamente.

🚨 É importante que as funções e arquivos pedidos tenham o nome correto!

O avaliador utiliza o nome do arquivo e da função para testà-la. Você pode adicionar outros arquivos se julgar necessário. Qualquer dúvida, procure a monitoria.

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


O que deverá ser desenvolvido

Neste projeto você implementará análises a partir de um conjunto de dados sobre empregos. Suas implementações serão incorporadas a um aplicativo Web desenvolvido com Flask (um framework web muito popular na comunidade Python). Você também terá a oportunidade de escrever testes para a implementação de uma análise de dados. Por fim, como bônus, você terá o desafio de escrever uma rota e view para um recurso novo usando Flask!

Os dados foram extraídos do site Glassdoor e obtidos através do Kaggle, uma plataforma disponiblizando conjuntos de dados para cientistas de dados.


Estrutura

Este repositório já contém um template com a estrutura de diretórios e arquivos:

.
├── README.md
├── dev-requirements.txt
├── feedback.jsonc
├── requirements.txt
├── src
│   ├── app.py
│   ├── insights.py
│   ├── jobs.csv
│   ├── jobs.py
│   ├── more_insights.py
│   ├── routes_and_views.py
│   ├── sorting.py
│   └── templates
│       ├── base.jinja2
│       ├── includes
│       │   └── nav.jinja2
│       ├── index.jinja2
│       ├── job.jinja2
│       └── list_jobs.jinja2
├── tests
│   ├── __init__.py
│   ├── mocks
│   │   ├── job_1.html
│   │   ├── jobs.csv
│   │   ├── jobs_with_industries.csv
│   │   ├── jobs_with_salaries.csv
│   │   └── jobs_with_types.csv
│   ├── sorting
│   │   ├── conftest.py
│   │   ├── mocks.py
│   │   └── test_sorting.py
│   ├── test_feedback.py
│   ├── test_flask_app.py
│   ├── test_insights.py
│   ├── test_jobs.py
│   ├── test_more_insights.py
│   └── test_routes_and_views.py

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.

Instruções para entregar seu projeto

Data de Entrega

  • Serão 2 dias de projeto.
  • Data de entrega para avaliação final do projeto: 10/12/2021 - 14:00h.

Antes de começar a desenvolver

  1. Clone o repositório
  • git clone https://github.com/tryber/sd-010-a-project-job-insights.git.
  • Entre na pasta do repositório que você acabou de clonar:
    • cd sd-010-a-project-job-insights
  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-job-insights
  1. Adicione as mudanças ao stage do Git e faça um commit
  • Verifique que 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 job-insights' (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

Durante o desenvolvimento

  • PULL REQUESTS COM ISSUES NO LINTER NÃO SERÃO AVALIADAS, ATENTE-SE PARA RESOLVÊ-LAS ANTES DE FINALIZAR 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 (para enviar o commit para o repositório remoto após o passo anterior)
    5. 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)

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 AVALIADAS. ATENTE-SE PARA RESOLVÊ-LAS ANTES DE FINALIZAR O DESENVOLVIMENTO! ⚠️


Testes

Para executar os testes certifique-se de que os seguintes passos foram realizados;

  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. Quando precisar desativar o ambiente virtual, execute o comando "deactivate". Lembre-se de ativar 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.

Com esta preparação feita, podemos executar os testes:

Executar os testes

$ python3 -m pytest

O arquivo pyproject.toml já configura corretamente o pytest. Entretanto, caso você tenha problemas com isso 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 quiser saber mais sobre a instalação de dependências com pip, veja esse artigo.

Além dos testes com o Pytest, você pode (e vai ser bem bacana) rodar a aplicação flask para visualizar no navegador o resultado do desenvolvimento das funções. Para isso, digite o comando flask run, e acesse o site gerado pelo Flask em http://localhost:5000. No começo do desenvolvimento, você verá que muitas coisas não funcionam, mas conforme você for implementando os requisitos, perceberá que a aplicação web começa a utilizar suas implementações e passa a ganhar vida.


Requisitos

Requisitos obrigatórios

1 - Implemente a função read

local: src/jobs.py

Para começarmos a processar os dados, devemos antes carregá-los em nossa aplicação. Esta função será responsável por abrir o arquivo CSV e retornar os dados no formato de uma lista de dicionários.

  • A função deve receber um path (uma string com o caminho para um arquivo).
  • A função deve abrir o arquivo e ler seus conteúdos.
  • A função deve tratar o arquivo como CSV.
  • A função deve retornar uma lista de dicionários, onde as chaves são os cabeçalhos de cada coluna e os valores correspondem a cada linha.

✍️ Teste manual: abra um terminal Python importando estas funções através do comando python3 -i src/jobs.py e invoque a função utilizando diferentes paths.

🤖 O que será verificado pelo avaliador:

  • A função abre o arquivo passado como parâmetro
  • A função retorna uma lista de dicionários
  • A função retorna a quantidade correta de itens na lista
  • Nos dicionários retornados pela função, as chaves correspondem aos cabeçalhos do arquivo
2 - Implemente a função get_unique_job_types

local: src/insights.py

Agora que temos como carregar os dados, podemos começar a extrair informação deles. Primeiro, vamos identificar quais tipos de empregos existem.

  • A função deve receber o path do arquivo csv com os dados.
  • A função deve invocar a função jobs.read com o path recebido para obter os dados.
  • A função deve retornar uma lista de valores únicos presentes na coluna job_type.

🤖 O que será verificado pelo avaliador:

  • A função carrega os dados do arquivo recebido como parâmetro
  • A função retorna a quantidade correta de valores
  • A função retorna os valores corretos
  • A função desconsidera valores vazios
3 - Implemente a função get_unique_industries

local: src/insights.py

Da mesma forma, agora iremos identificar quais indústrias estão representadas nesse conjunto de dados.

  • A função deve obter os dados da mesma forma que o requisito 2.
  • A função deve retornar uma lista de valores únicos presentes na coluna industry.
  • A função desconsidera valores vazios

🤖 O que será verificado pelo avaliador:

  • A função carrega os dados do arquivo recebido como parâmetro
  • A função retorna a quantidade correta de valores
  • A função retorna os valores corretos
4 - Implemente a função get_max_salary

local: src/insights.py

Os dados apresentam faixas salariais para cada emprego exibido. Vamos agora encontrar o maior valor de todas as faixas.

  • A função deve obter os dados da mesma forma que o requisito 2.
  • A função deve ignorar os valores ausentes.
  • A função deve retornar um valor inteiro com o maior salário presente na coluna max_salary.

🤖 O que será verificado pelo avaliador:

  • A função carrega os dados do arquivo recebido como parâmetro
  • A função retorna o valor correto
5 - Implemente a função get_min_salary

local: src/insights.py

Os dados apresentam faixas salariais para cada emprego exibido. Vamos agora encontrar o menor valor de todas as faixas.

  • A função deve obter os dados da mesma forma que o requisito 2.
  • A função deve ignorar os valores ausentes.
  • A função deve retornar um valor inteiro com o menor salário presente na coluna min_salary.

🤖 O que será verificado pelo avaliador:

  • A função carrega os dados do arquivo recebido como parâmetro
  • A função retorna o valor correto
6 - Implemente a função filter_by_job_type

local: src/insights.py

Os empregos estão listados em um aplicativo web. Para permitir que a pessoa usuária possa filtrar os empregos por tipo de emprego, vamos precisar implementar esse filtro.

  • A função deve receber uma lista de dicionários jobs como primeiro parâmetro.
  • A função deve receber uma string job_type como segundo parâmetro.
  • A função deve retornar uma lista com todos os empregos onde a coluna job_type corresponde ao parâmetro job_type.

🤖 O que será verificado pelo avaliador:

  • A função retorna a quantidade correta de valores
  • A função retorna os valores corretos
  • A função retorna os valores na ordem correta
  • A função retorna uma lista vazia para job_types ausentes nos jobs recebidos
7 - Implemente a função filter_by_industry

local: src/insights.py

Do mesmo modo, o aplicativo precisa permitir uma filtragem por indústria. Vamos precisar implementar esse filtro também.

  • A função deve receber uma lista de dicionários jobs como primeiro parâmetro.
  • A função deve receber uma string industry como segundo parâmetro.
  • A função deve retornar uma lista de dicionários com todos os empregos onde a coluna industry corresponde ao parâmetro industry.

🤖 O que será verificado pelo avaliador:

  • A função retorna a quantidade correta de valores
  • A função retorna os valores corretos
  • A função retorna os valores na ordem correta
  • A função retorna uma lista vazia para job_types ausentes nos jobs recebidos
8 - Implemente a função matches_salary_range

local: src/insights.py

O aplicativo vai precisar filtrar os empregos por salário também. Como uma função auxiliar, implemente matches_salary_range para conferir que o salário procurado está dentro da faixa salarial daquele emprego. Vamos aproveitar também para conferir se a faixa salarial faz sentido -- isto é, se o valor mínimo é menor que o valor máximo.

  • A função deve receber um dicionário job como primeiro parâmetro, com as chaves min_salary e max_salary.
  • A função deve receber um inteiro salary como segundo parâmetro.
  • A função deve lançar um erro ValueError nos seguintes casos:
    • alguma das chaves min_salary ou max_salary estão ausentes no dicionário;
    • alguma das chaves min_salary ou max_salary tem valores não-numéricos;
    • o valor de min_salary é maior que o valor de max_salary;
    • o parâmetro salary tem valores não-numéricos;
  • A função deve retornar True se o salário procurado estiver dentro da faixa salarial ou False se não estiver.

🤖 O que será verificado pelo avaliador:

  • A função retorna o booleano correto
  • A função lança um ValueError se o valor de min_salary for maior que o valor de max_salary
  • A função lança um ValueError se as chaves min_salary ou max_salary tiverem valores não numéricos
  • A função lança um ValueError se o parâmetro salary tiver valor não numérico
  • A função lança um ValueError se as chaves min_salary ou max_salary estiverem ausentes no dicionário
9 - Implemente a função filter_by_salary_range

local: src/insights.py

Agora vamos implementar o filtro propriamente dito. Para esta filtragem, podemos usar a função auxiliar implementada no requisito anterior -- tomando o cuidado de descartar os empregos que apresentarem faixas salariais inválidas.

  • A função deve receber uma lista de dicionários jobs como primeiro parâmetro.
  • A função deve receber um inteiro salary como segundo parâmetro.
  • A função deve ignorar os empregos com valores inválidos para min_salary ou max_salary.
  • A função deve retornar uma lista com todos os empregos onde o salário salary estiver entre os valores da coluna min_salary e max_salary.

🤖 O que será verificado pelo avaliador:

  • A função retorna a quantidade correta de valores
  • A função retorna os valores corretos
  • A função retorna os valores na ordem correta
  • Empregos onde as chaves min_salary ou max_salary tiverem valores não numéricos devem ser ignorados
  • Empregos onde o valor de min_salary for maior que o valor de max_salary devem ser ignorados
10 - Implemente um teste para a função sort_by

local: tests/sorting/test_sorting.py

Por fim, espera-se que a pessoa usuária possa escolher um critério de ordenação para exibir os empregos. Já temos uma implementação para essa ordenação em src/sorting.py, mas queremos ter certeza de que ela funciona e, principalmente, que não deixará de funcionar conforme vamos implementando novos recursos. Precisamos então escrever um teste!

Esse teste deve se chamar test_sort_by_criteria e garantir que a função funciona segundo esta especificação:

  • A função sort_by recebe dois parâmetros:
    • jobs uma lista de dicionários com os detalhes de cada emprego;
    • criteria uma string com uma chave para ser usada como critério de ordenação.
  • O parâmetro criteria deve ter um destes valores: min_salary, max_salary, date_posted
  • A ordenação para min_salary deve ser crescente, mas para max_salary ou date_posted devem ser decrescentes.
  • Os empregos que não apresentarem um valor válido no campo escolhido para ordenação devem aparecer no final da lista.

📌 O teste da Trybe espera que o seu teste falhe em alguns casos. Nesse caso, o teste terá a saída XFAIL (ao invés de PASS ou FAIL), e isso significa que o requisito foi atendido ✔️

🤖 O que será verificado pelo avaliador:

  • O teste rejeita implementações que aceitam critérios não especificados.
  • O teste rejeita implementações que não ordenam corretamente.
  • O teste rejeita implementações que não ordenam em ordem crescente quando o critério é min_salary.
  • O teste aprova implementações corretas.

Requisitos bônus

11 - Implemente a página de um job

local: src/routes_and_views.py

Para fechar com chave de ouro, que tal testar o quanto você aprendeu de Flask apenas vendo como fizemos as páginas de index e de jobs, e tentar criar uma página que irá exibir todas as informações de um job em específico?

  • A função deve ser decorada com a rota /job/ .
  • A função deve receber um parâmetro index.
  • A função deve chamar a read para ter uma lista com todos os jobs.
  • A função deve chamar a get_job, declarada no arquivo src/more_insights.py, para selecionar um job específico pelo index.
  • A função deve renderizar o template job.jinja2, passando um parâmetro job contendo o job retornado pela get_job.

✍️ Teste manual: após criar a view, cheque se, na página que lista os jobs, aparecem links para jobs específicos nos números que identificam cada job. Ao clicar em um destes links, você deve ser levado a uma página que lista todas as informações do job.

🤖 O que será verificado pelo avaliador:

  • A rota /job/ existe.
  • A view job existe no arquivo src/routes_and_views.py, e recebe o parâmetro index (e somente ele).
  • A página de cada um dos jobs deve retornar o status code 200.
  • A página de um job específico (escolhido previamente) deve retornar o HTML exato esperado.

Depois de terminar o desenvolvimento

Para "entregar" seu projeto, siga os passos a seguir:

  • 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-010-a

Se ainda houver alguma dúvida sobre como entregar seu projeto, aqui tem um video explicativo.

Lembre-se que garantir que todas as issues comentadas pelo Lint estão resolvidas!


Revisando um pull request

À medida que você e as outras pessoas que estudam na Trybe forem entregando os projetos, vocês receberão um alerta via Slack para também fazer a revisão dos Pull Requests dos seus colegas. Fiquem atentos às mensagens do "Pull Reminders" no Slack!

Use o material que você já viu sobre Code Review para te ajudar a revisar os projetos que chegaram para você.


Avisos Finais

Ao finalizar e submeter o projeto, não se esqueça de avaliar sua experiência preenchendo ou o formulário ou o arquivo feedback.jsonc na raiz do projeto. Escolha um dos dois. Leva menos de 3 minutos!

Link: FORMULÁRIO DE AVALIAÇÃO DE PROJETO

O avaliador automático não necessariamente avalia seu projeto na ordem em que os requisitos aparecem no readme. Isso acontece para deixar o processo de avaliação mais rápido. Então, não se assuste se isso acontecer, ok?


You might also like...
PyDy, short for Python Dynamics, is a tool kit written in the Python
PyDy, short for Python Dynamics, is a tool kit written in the Python

PyDy, short for Python Dynamics, is a tool kit written in the Python programming language that utilizes an array of scientific programs to enable the study of multibody dynamics. The goal is to have a modular framework and eventually a physics abstraction layer which utilizes a variety of backends that can provide the user with their desired workflow

A Python script made for the Python Discord Pixels event.

Python Discord Pixels A Python script made for the Python Discord Pixels event. Usage Create an image.png RGBA image with your pattern. Transparent pi

this is a basic python project that I made using python

this is a basic python project that I made using python. This project is only for practice because my python skills are still newbie.

Analisador de strings feito em Python // String parser made in Python

Este é um analisador feito em Python, neste programa, estou estudando funções e a sua junção com "if's" e dados colocados pelo usuário. Neste código,

Python with braces. Because Python is awesome, but whitespace is awful.

Bython Python with braces. Because Python is awesome, but whitespace is awful. Bython is a Python preprosessor which translates curly brackets into in

PSP (Python Starter Package) is meant for those who want to start coding in python but are new to the coding scene.

Python Starter Package PSP (Python Starter Package) is meant for those who want to start coding in python, but are new to the coding scene. We include

Py-Parser est un parser de code python en python encore en plien dévlopement.

PY - PARSER Py-Parser est un parser de code python en python encore en plien dévlopement. Une fois achevé, il servira a de nombreux projets comme glad

Simple, high-school-leveled sequence library written in Python / 간단한 고등학교 수준 수열 라이브러리 (Python)
A community based economy bot with python works only with python 3.7.8 as web3 requires cytoolz

A community based economy bot with python works only with python 3.7.8 as web3 requires cytoolz has some issues building with python 3.10

Owner
Lucas Muffato
Engenheiro e desenvolvedor.
Lucas Muffato
Job Guy Backend

جاب‌گای چیست؟ اونجا وضعیت چطوریه؟ یه سوال به همین کلیت و ابهام معمولا وقتی برای یه شرکت رزومه می‌فرستیم این سوال کلی و بزرگ برای همه پیش میاد.اونجا وض

Jobguy.work 217 Dec 25, 2022
Allow you to create you own custom decentralize job management system.

ants Allow you to create you own custom decentralize job management system. Install $> git clone https://github.com/hvuhsg/ants.git Run monitor exampl

null 1 Feb 15, 2022
App to get data from popular polish pages with job offers

Job board parser I written simple app to get me data from popular pages with job offers, because I wanted to knew immidietly if there is some new offe

null 0 Jan 4, 2022
Custom SLURM wrapper scripts to make finding job histories and system resource usage more easily accessible

SLURM Wrappers Executables job-history A simple wrapper for grabbing data for completed and running jobs. nodes-busy Developed for the HPC systems at

Sara 2 Dec 13, 2021
NUM Alert - A work focus aid created for the Hack the Job hackathon

Contributors: Uladzislau Kaparykha, Amanda Hahn, Nicholas Waller Hackathon Team Name: N.U.M General Purpose: The general purpose of this program is to

Amanda Hahn 1 Jan 10, 2022
Projeto-menu - This project is designed to learn more about control mechanisms in Python programming

Projeto-menu - This project is designed to learn more about control mechanisms in Python programming

Henrik Ricarte 2 Mar 1, 2022
Projeto de Jogo de dados em Python 3 onde é definido o lado a ser apostado e número de jogadas, pontuando os acertos e exibindo se ganhou ou perdeu.

Jogo de DadoX Projeto de script que simula um Jogo de dados em Python 3 onde é definido o lado a ser apostado (1, 2, 3, 4, 5 e 6) ou se vai ser um núm

Estênio Mariano 1 Jul 10, 2021
Projeto para ajudar no aprendizado da linguagem Pyhon

Economize Este projeto tem o intuito de criar desáfios para a codificação em Python, fazendo com que haja um maior entendimento da linguagem em seu to

Lucas Cunha Rodrigues 1 Dec 16, 2021
Repositório do Projeto de Jogo da Resília Educação.

Jogo da Segurança das Indústrias Acme Descrição Este jogo faz parte do projeto de entrega do primeiro módulo da Resilia Educação, referente ao curso d

Márcio Estevam da Silva 2 Apr 28, 2022
Todos os exercícios do Curso de Python, do canal Curso em Vídeo, resolvidos em Python, Javascript, Java, C++, C# e mais...

Exercícios - CeV Oferecido por Linguagens utilizadas atualmente O que vai encontrar aqui? ?? Esse repositório é dedicado a armazenar todos os enunciad

Coding in Community 43 Nov 10, 2022