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.
Ao iniciar este projeto, você concorda com as diretrizes do Código de Conduta e do Manual da Pessoa Estudante da Trybe.
🤷🏽♀️ 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
No projeto passado você implementou algumas funções que faziam leitura e escrita de arquivos JSON
e CSV
, correto?
Neste projeto nós vamos fazer algo parecido, mas utilizando a Programação Orientada a Objetos! Você implementará um gerador de relatórios que recebe como entrada arquivos com dados de um estoque e gera, como saída, um relatório acerca destes dados.
Esses dados de estoque poderão ser obtidos de diversas fontes:
-
Através da importação de um arquivo
CSV
; -
Através da importação de um arquivo
JSON
; -
Através da importação de um arquivo
XML
.
Além disso, o relatório final possuirá duas versões: simples e completa.
🚵 Habilidades a serem trabalhadas:
- Aplicar conceitos de Orientação a Objetos em Python;
- Aplicar padrões de projeto;
- Leitura e escrita de arquivos (XML, CSV, JSON).
🗓 Data de Entrega
- Este projeto é individual;
- São
2
dias de projeto; - Data para entrega final do projeto:
23/06/2022 14:10
.
⚠ Antes de começar a desenvolver
- Clone o repositório
- Use o comando:
git clone git@github.com:tryber/sd-014-b-inventory-report.git
- Entre na pasta do repositório que você acabou de clonar:
cd sd-014-b-inventory-report
- Crie o ambiente virtual para o projeto
python3 -m venv .venv && source .venv/bin/activate
- Instale as dependências
python3 -m pip install -r dev-requirements.txt
- Crie uma branch a partir da branch
master
- Verifique que você está na branch
master
- Exemplo:
git branch
- Exemplo:
- Se não estiver, mude para a branch
master
- Exemplo:
git checkout master
- Exemplo:
- 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-inventory-report
- Você deve criar uma branch no seguinte formato:
- 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)
- Exemplo:
- 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)
- Exemplo:
- Faça o
commit
inicial- Exemplo:
git commit -m 'iniciando o projeto inventory-report'
(fazendo o primeiro commit)git status
(deve aparecer uma mensagem tipo nothing to commit )
- Exemplo:
- Adicione a sua branch com o novo
commit
ao repositório remoto
- Usando o exemplo anterior:
git push -u origin joaozinho-inventory-report
- 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:
git status
(para verificar o que está em vermelho - fora do stage - e o que está em verde - no stage)git add
(para adicionar arquivos ao stage do Git)git commit
(para criar um commit com os arquivos que estão no stage do Git)git push -u origin nome-da-branch
(para enviar o commit para o repositório remoto na primeira vez que fizer opush
de uma nova branch)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.
.
├── inventory_report
│ ├── data
│ │ ├── 🔸inventory.csv
│ │ ├── 🔸inventory.json
│ │ └── 🔸inventory.xml
│ ├── importer
│ │ ├── 🔹csv_importer.py
│ │ ├── 🔹importer.py
│ │ ├── 🔹json_importer.py
│ │ └── 🔹xml_importer.py
│ ├── inventory
│ │ ├── 🔹inventory_iterator.py
│ │ ├── 🔹inventory_refactor.py
│ │ └── 🔹inventory.py
│ │ └── 🔸product.py
│ ├── reports
│ │ ├── 🔸colored_report.py
│ │ ├── 🔹complete_report.py
│ │ └── 🔹simple_report.py
│ └── 🔹main.py
└── tests
│ ├── factories
│ │ ├── 🔸__init__.py
│ │ └── 🔸product_factory.py
│ ├── product
│ │ ├── 🔸__init__.py
│ │ ├── 🔸conftest.py
│ │ ├── 🔸mocks.py
│ │ └── 🔹test_product.py
│ ├── product_report
│ │ ├── 🔸__init__.py
│ │ ├── 🔸conftest.py
│ │ ├── 🔸mocks.py
│ │ └── 🔹test_product_report.py
│ ├── report_decorator
│ │ ├── 🔸__init__.py
│ │ ├── 🔸conftest.py
│ │ ├── 🔸mocks.py
│ │ └── 🔹test_report_decorator.py
│ ├── 🔸__init__.py
│ ├── 🔸marker.py
│ ├── 🔸test_complete_report.py
│ ├── 🔸test_importer.py
│ ├── 🔸test_inventory_refactor.py
│ ├── 🔸test_inventory.py
│ ├── 🔸test_main.py
│ └── 🔸test_simple_report.py
├── 🔹dev-requirements.txt
├── 🔸docker-compose.yml
├── 🔸Dockerfile
├── 🔸pyproject.toml
├── 🔸README.md
├── 🔸requirements.txt
├── 🔸setup.cfg
├── 🔸setup.py
└── 🔸trybe.yml
Apesar do projeto já possuir uma estrutura base, você perceberá que possui arquivos vazios, ou seja, neles você quem deve implementar as classes. 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
🏕️ Ambiente Virtual
O Python oferece um recurso chamado de ambiente virtual, onde permite sua máquina rodar sem conflitos, diferentes tipos de projetos com diferentes versões de bibliotecas.
- criar o ambiente virtual
$ python3 -m venv .venv
- ativar o ambiente virtual
$ source .venv/bin/activate
- 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
.
🛠 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/test_simple_report.py
Caso queria executar um teste especifico de um arquivo basta executar o comando:
python3 -m pytest -x tests/nomedoarquivo.py::test_nome_do_teste
Se quiser saber mais sobre a instalação de dependências com pip
, veja esse artigo.
🐳Docker
Caso queria executar os seus testes de projeto via `Docker-compose`, substituindo o ambiente virtual, execute o comando:docker-compose run --rm inventory pytest
🛼Executando o Projeto
Após implementar o requisito bônus, seu programa deverá ser executável via linha de comando com o comandopython3 -m inventory_report.main
:
-
O <argumento 1> deve receber o caminho de um arquivo a ser importado. O arquivo pode ser um
csv
,json
ouxml
. -
O <argumento 2> pode receber duas strings:
simples
oucompleto
, cada uma gerando o respectivo relatório.
🗃️ Arquivos com os dados de entrada
Três formatos de importação estão disponíveis no diretório
data
dentro do diretório inventory_report
. Confira o exemplo de formato eles:
Arquivos CSV Os arquivos CSV são separados por vírgula, como no exemplo abaixo:
id,nome_do_produto,nome_da_empresa,data_de_fabricacao,data_de_validade,numero_de_serie,instrucoes_de_armazenamento
1,cadeira,Target Corporation,2021-02-18,2025-09-17,CR25,empilhadas
2,mesa,"Galena Madeira, Inc.",2022-12-06,2026-12-25,FR29,desmontadas
3,abajur,Keen Iluminação,2019-12-22,2025-11-07,CZ09,em caixas
Arquivos JSON Os arquivos JSON seguem o seguinte modelo:
[
{
"id":1,
"nome_do_produto":"Borracha",
"nome_da_empresa":"Papelaria Solar",
"data_de_fabricacao":"2021-07-04",
"data_de_validade":"2029-02-09",
"numero_de_serie":"FR48",
"instrucoes_de_armazenamento":"Ao abrigo de luz solar"
}
]
Arquivos XML Os arquivos XML seguem o seguinte modelo:
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<record>
<id>1</id>
<nome_do_produto>Microfone</nome_do_produto>
<nome_da_empresa>Tecno Uau LTDA</nome_da_empresa>
<data_de_fabricacao>2021-10-27</data_de_fabricacao>
<data_de_validade>2032-08-31</data_de_validade>
<numero_de_serie>MT08</numero_de_serie>
<instrucoes_de_armazenamento>Longe de fonte de calor</instrucoes_de_armazenamento>
</record>
</dataset>
🤝 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 timetryber/students-sd-014-b
.
-
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!
🗂 Compartilhe seu portfólio!
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.
Crie o teste em: tests/product/test_product.py
Ao analisar o código do projeto, você encontrará a classe do objeto produto já implementada neste arquivo: inventory_report/inventory/product.py
, a classe Product.
Para termos confiança em continuar as implementações, precisamos que você implemente o teste, que certifique que o método __init__
da classe Product esta funcionando corretamente.
O nome deste teste deve ser test_cria_produto
, ele deve verificar o correto preenchimento dos seguintes atributos:
- id (int)
- nome_da_empresa (string)
- nome_do_produto (string)
- data_de_fabricacao (string)
- data_de_validade (string)
- numero_de_serie (string)
- instrucoes_de_armazenamento (string)
🤖 O que será verificado pelo avaliador
- 1 - Deve criar um novo produto com todos os atributos corretamente preenchidos.
📌Como seu teste é avaliado
O teste da Trybe irá avaliar se o seu teste está passando conforme seu objetivo, e confirmará se ele está falhando em alguns casos que deve falhar. Para estes testes que esperemos que falhe, o requisito será considerado atendindo quando a resposta do Pytest forXFAIL(Expected Fail)
, ao invés de PASS
ou FAIL
.
Crie o teste em: tests/product_report/test_product_report.py
Boa novidade, o primeiro relatório já implementamos neste arquivo inventory_report/inventory/product.py
. Formulamos uma frase construída com as informações do produto, que será muito útil para etiquetarmos o estoque.
Para desenvolver este relatório, utilizamos o recurso __repr__
do Python, que permite alterar a representatividade do objeto, para que sempre que usarmos um print nele, no lugar de endereço de memória, teremos uma String personalizada.
Dica: A reimplementação do __repr__
não faz o objeto retornar exatamente uma string
, fazer um cast
para string
, pode te ajudar.
Exemplo da frase:
O produto
farinha
fabricado em01-05-2021
porFarinini
com validade até02-06-2023
precisa ser armazenadoao abrigo de luz
.
Agora para mantermos uma boa cobertura de testes, precisamos que você implemente o teste.
O nome deste teste deve ser test_relatorio_produto
, ele deve instanciar um objeto Product
e verificar se acessá-lo a frase de retorno esta correta.
🤖 O que será verificado pelo avaliador
- 1 - Se seu código testa que o retorno padrão (
__repr__
) de um objetoProduct
deve ser um relatório sobre ele
📌Como seu teste é avaliado
O teste da Trybe irá avaliar se o seu teste está passando conforme seu objetivo, e confirmará se ele está falhando em alguns casos que deve falhar. Para estes testes que esperemos que falhe, o requisito será considerado atendindo quando a resposta do Pytest forXFAIL(Expected Fail)
, ao invés de PASS
ou FAIL
.
Crie a classe em: inventory_report/reports/simple_report.py
O relatório deve ser gerado através de um método de classe chamado generate
escrito dentro da classe SimpleReport
.
- Ao rodar os testes localmente, você terá um teste para cada validação de cada informação
- Deve ser possível executar o método
generate
sem instanciar um objeto deSimpleReport
- O método deve receber um parâmetro que representa uma
list
(estrutura de dados), onde cada posição contém umdict
(estrutura de dados).
Exemplo de formato de entrada
[
{
"id": 1,
"nome_do_produto": "CADEIRA",
"nome_da_empresa": "Forces of Nature",
"data_de_fabricacao": "2022-04-04",
"data_de_validade": "2023-02-09",
"numero_de_serie": "FR48",
"instrucoes_de_armazenamento": "Conservar em local fresco"
}
]
- O método deverá retornar uma
string
de saída com o seguinte formato:Data de fabricação mais antiga: YYYY-MM-DD Data de validade mais próxima: YYYY-MM-DD Empresa com mais produtos: NOME DA EMPRESA
- A data de validade mais próxima, somente considera itens que ainda não venceram.
Dica: O módulo datetime pode te ajudar.
🤖 O que será verificado pelo avaliador
-
3.1 - O método generate da classe SimpleReport deve retornar todas informações do relatório simples. Informações necessárias:
- a data de fabricação mais antiga
- a validade mais próxima
- a empresa com maior número de produtos
-
3.2 - O método generate da classe SimpleReport deve retornar o formato correto do relatório simples
📌 Atente-se a espaçamentos e quebras de linhas
Crie em: inventory_report/reports/complete_report.py
O relatório deve ser gerado através de um método generate
para a classe CompleteReport
.
Ele deverá receber dados numa lista contendo estruturas do tipo dict
e deverá retornar uma string formatada como um relatório.
-
A classe
CompleteReport
deve herdar o método (generate
) da classeSimpleReport
, de modo a especializar seu comportamento. -
O método deve receber de parâmetro uma lista de dicionários no seguinte formato:
[ { "id": 1, "nome_do_produto": "MESA", "nome_da_empresa": "Forces of Nature", "data_de_fabricacao": "2022-05-04", "data_de_validade": "2023-02-09", "numero_de_serie": "FR48", "instrucoes_de_armazenamento": "Conservar ao abrigo de luz" } ]
-
O método deverá retornar uma saída com o seguinte formato:
Data de fabricação mais antiga: YYYY-MM-DD
Data de validade mais próxima: YYYY-MM-DD
Empresa com mais produtos: NOME DA EMPRESA
Produtos estocados por empresa:
- Physicians Total Care, Inc.: QUANTIDADE
- Newton Laboratories, Inc.: QUANTIDADE
- Forces of Nature: QUANTIDADE
🤖 O que será verificado pelo avaliador
- 2.1 - O método generate da classe CompleteReport deve retornar todas informações do relatório completo no formato correto. Informações necessárias:
- a data de fabricação mais antiga
- a validade mais próxima
- a empresa com maior estoque
- a quantidade de produtos por empresa
Crie em: inventory_report/inventory/inventory.py
A importação do arquivo CSV deve ser realizada através do método import_data
que você deve criar em uma classe chamada Inventory
.
O método deve ser estático ou de classe, ou seja, deve ser possível chamá-lo sem instanciar um objeto da classe.
O método receberá como primeiro parâmetro uma string como caminho para o arquivo CSV
e como segundo parâmetro uma string que representa o tipo de relatório a ser gerado. Tipos:
"simples"
"completo"
De acordo com os parâmetros recebidos, deve recuperar os dados do arquivo e chamar o método de gerar relatório correspondente à entrada passada. Ou seja, o método da classe Inventory
deve chamar o método generate
da classe que vai gerar o relatório (SimpleReport
, CompleteReport
).
🤖 O que será verificado pelo avaliador
- 3 - Ao importar um arquivo CSV, deve retornar o relatórios simples ou o completo conforme solicitado.
Incremente em:
inventory_report/inventory/inventory.py
.
📌 Utilize o mesmo método do requisito anterior.
Altere o método import_data
para que ele também seja capaz de carregar arquivos JSON
.
Como no requisito anterior, o método ainda receberá como primeiro parâmetro uma string como caminho para o arquivo, e como segundo parâmetro uma string que representa o tipo de relatório a ser gerado. Tipos:
"simples"
"completo"
De acordo com os parâmetros recebidos, deve recuperar os dados do arquivo e chamar o método de gerar relatório correspondente à entrada passada. Ou seja, o método da classe Inventory
deve chamar o método generate
da classe que vai gerar o relatório (SimpleReport
, CompleteReport
).
🤖 O que será verificado pelo avaliador
- 4 - Ao importar um arquivo JSON, deve retornar o relatórios simples ou o completo conforme solicitado.
Incremente em:
inventory_report/inventory/inventory.py
.
📌 Utilize o mesmo método do requisito anterior.
Altere o método import_data
para que ele também seja capaz de carregar arquivos XML
.
Como no requisito anterior, o método ainda receberá como primeiro parâmetro uma string como caminho para o arquivo, e como segundo parâmetro uma string que representa o tipo de relatório a ser gerado. Tipos:
"simples"
"completo"
De acordo com os parâmetros recebidos, deve recuperar os dados do arquivo e chamar o método de gerar relatório correspondente à entrada passada. Ou seja, o método da classe Inventory
deve chamar o método generate
da classe que vai gerar o relatório (SimpleReport
, CompleteReport
).
🤖 O que será verificado pelo avaliador
- 5 - Ao importar um arquivo XML, deve retornar o relatórios simples ou o completo conforme solicitado.
Crie em: inventory_report/importer/importer.py
Como pôde observar até aqui, o método import_data
está com muitas responsabilidades, e, com o intuito de resolver isso, podemos dividir a sua complexidade para cada formato de arquivo.
O padrão de projeto Strategy
nos ajuda a isolar cada estratégia em um objeto, e por meio de uma Interface podemos padronizar a assinatura dos métodos, garantindo que todas elas possuam o comportamento similar.
-
Ao rodar os testes localmente, você terá um teste para cada validação de cada informação
-
Crie uma classe abstrata
Importer
para ser a interface da estratégia -
A Interface será uma classe abstrata
Importer
terá três classes de estratégias herdeiras:CsvImporter
,JsonImporter
eXmlImporter
. -
Crie as classes nos respectivos arquivos:
inventory_report/importer/csv_importer.py inventory_report/importer/json_importer.py inventory_report/importer/xml_importer.py
-
A classe abstrata deve definir a assinatura do método
import_data
a ser implementado por cada classe herdeira. Esse método deve ser estático ou de classe, e deve receber como parâmetro o nome do arquivo a ser importado. -
O método
import_data
definido por cada classe herdeira deve lançar uma exceção do tipoValueError
caso a extensão do arquivo passado por parâmetro seja inválida. Por exemplo, quando se passa um caminho de um arquivo com extensão.csv
para oJsonImporter
. A mensagem de erro da exceção deve ser "Arquivo inválido". -
O método deverá ler os dados do arquivo passado e retorná-los estruturados em uma lista de dicionários conforme exemplo abaixo:
[ { "id": 1, "nome_do_produto": "Cafe", "nome_da_empresa": "Cafes Nature", "data_de_fabricacao": "2020-07-04", "data_de_validade": "2023-02-09", "numero_de_serie": "FR48", "instrucoes_de_armazenamento": "instrucao" } ]
🤖 O que será verificado pelo avaliador
- 8 - As classes estratégicas
CsvImporter
,JsonImporter
eCsvImporter
devem cada uma:- herdar a classe
importer
- importar e retornar os dados para uma lista (
list
) de dicionários (dict
) - validar se ao enviar um arquivo com extensão incorreta deve gerar um erro
- herdar a classe
Crie o teste em: tests/report_decorator/test_report_decorator.py
Uma versão deste relatório será exibida em letreiros em Led, estes letreiros são coloridos, para isso, já implementamos o método responsável por retornar este relatório em cores.
Implementamos em : inventory_report/reports/colored_report.py
Em vez de criarmos uma classe que herda os relatórios originais, utilizamos o padrão Decorator
para receber o tipo do relatório por composição (SimpleReport
ou CompleteReport
) e, assim, colorir o retorno do método generate
, que recebe uma lista de produtos e retorna o relatório já colorido.
Para termos confiança que as cores sairão corretamente, precisamos que você implemente o teste, que certifique que o método generate de ColoredReport funciona corretamente.
Para que o Python consiga colorir as strings, é preciso que a string contenha o início do código da cor, e o reset da cor.
📌 Execute este print teste em um terminal interativo python3 -i
. O resultado das cores podem não ser exatos, por isso, atente-se aos códigos deste exemplo:
print("\033[36mAzul\033[0m \033[32mVerde\033[0m \033[31mVermelho\033[0m")
O nome deste teste deve ser test_decorar_relatorio
, ele deve verificar se o relatório está devidamente colorido. Representamos abaixo como deve ser a disposição das cores:
🟩Data de fabricação mais antiga:🟩 🟦10-05-2022🟦
🟩Data de validade mais próxima:🟩 🟦14-06-2021🟦
🟩Empresa com mais produtos:🟩 🟥Farinini🟥
🤖 O que será verificado pelo avaliador
- 9 - Deve retornar o relatório devidamente colorido.
- verde:
- "Data de fabricação mais antiga:"
- "Data de validade mais próxima:"
- "Empresa com mais produtos:"
- azul: As datas
- vermelho: Nome da empresa com mais produtos
- verde:
📌Como seu teste é avaliado
O teste da Trybe irá avaliar se o seu teste está passando conforme seu objetivo, e confirmará se ele está falhando em alguns casos que deve falhar. Para estes testes que esperemos que falhe, o requisito será considerado atendindo quando a resposta do Pytest forXFAIL(Expected Fail)
, ao invés de PASS
ou FAIL
.
Crie em: inventory_report/inventory/inventory_iterator.py
O estoque será mostrado por painéis de led. Para não sobrecarregarmos a memória destes painéis, queremos poder iterar pelos itens do estoque, um item por vez. Para isso, precisamos primeiro refatorar a forma com que importamos os dados, e então aplicar o Padrão Iterator.
-
A classe
Inventory
deverá ser refatorada (copiada) em outro arquivo chamadoinventory_report/inventory/inventory_refactor.py
. Nesse arquivo você irá refatorar a classeInventory
chamando-a deInventoryRefactor
. -
A classe
InventoryRefactor
deve utilizar as classes definidas no requisito 8 para lidar com a lógica de importação, via composição no métodoimport_data
. -
A classe
InventoryRefactor
deve receber por seu construtor a classe que será utilizada para lidar com a lógica de importação e armazenar em um atributo chamadoimporter
. -
A classe
InventoryRefactor
deve ter um método de instância que recebe um caminho para o arquivo a ser importado, e carrega seus dados. -
Ao importar os dados, os mesmos devem ser armazenados na instância, em adição aos itens já presentes naquela instância. O atributo de
InventoryRefactor
que armazena esses dados deve se chamardata
. -
Os atributos e os métodos devem ser públicos.
-
A classe
InventoryIterator
deverá implementar a interface de um iterator (Iterator
) com o método__next__
. Além disso, a classeInventoryRefactor
deve implementar o método__iter__
, que retornará este iterador. -
As classes
InventoryIterator
eInventoryRefactor
devem implementar corretamente a interface do padrão de projeto Iterator, de modo que seja possível iterar sobre os itens em estoque.
✍️ Teste manual
iterator = iter(inventory)
first_item = next(iterator)
🤖 O que será verificado pelo avaliador
-
10.1 - Será validado que a instancia de InventoryRefactor é iterável (Iterable)
-
10.2 - Será validado que é possível iterar o primeiro item da lista usando csv
-
10.3 - Será validado que é possível iterar o primeiro item da lista usando json
-
10.4 - Será validado que é possível iterar o primeiro item da lista usando xml
-
10.5 - Será validado que é possível receber duas fontes de dados sem sobrescrita
-
10.6 - Será validado que não é possível enviar arquivo inválido
Essa função deve, ao receber pela linha de comando o caminho de um arquivo e o tipo de relatório, devolver o relatório correto.
-
Deverá ser usado a classe
InventoryRefactor
para recuperar os dados e gerar o relatório. -
Ao chamar o comando no formato abaixo pelo terminal, deve ser impresso na tela o devido relatório no formato da saída dos requisitos
1
e2
:
inventory_report <caminho_do_arquivo_input> <tipo_de_relatório>
- Caso a chamada tenha menos de três argumentos (o nome
inventory_report
é considerado o primeiro argumento), exiba a mensagem de erro "Verifique os argumentos" nastderr
.
Dicas:
-
Você pode utilizar o
sys.argv
para receber a entrada de dados da pessoa usuária. -
Ao utilizar algo do módulo
sys
, faça a importação comimport sys
e utilizesys.xxxx
(onde xxxx é o que você quer utilizar). Não façafrom sys import xxxx
, pois isso pode fazer com que os testes não passem. -
Tome a precaução de não deixar um
print()
em seu código, pois ele irá conflitar com os testes.
✍️ Teste manual
No ambiente virtual onde seu projeto foi configurado, digite o comandopython3 -m inventory_report.main parametro_1 parametro_2
, assim você conseguirá interagir com o menu.
🤖 O que será verificado pelo avaliador
-
11.1 - Será validado se o menu importa um arquivo csv simples
-
11.2 - Será validado se o menu importa um arquivo csv completo
-
11.3 - Será validado se o menu importa um arquivo json simples
-
11.4 - Será validado se o menu importa um arquivo json completo
-
11.5 - Será validado se o menu importa um arquivo xml simples
-
11.6 - Será validado se o menu importa um arquivo xml completo
-
11.7 - Será validado se houverem argumentos faltantes será retornando um erro