https://github.com/0bvim/milenio_challenge
Share objects, container and tests
https://github.com/0bvim/milenio_challenge
Last synced: 4 months ago
JSON representation
Share objects, container and tests
- Host: GitHub
- URL: https://github.com/0bvim/milenio_challenge
- Owner: 0bvim
- Created: 2024-07-16T01:40:02.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-07-16T23:03:23.000Z (almost 2 years ago)
- Last Synced: 2025-06-01T12:10:53.094Z (about 1 year ago)
- Language: C++
- Size: 240 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Processador de CSV
Este desafio visa avaliar suas habilidades técnicas e capacidade de solucionar problemas reais, desenvolvendo uma biblioteca compartilhada ou _shared object_ (.so) que será utilizada por uma aplicação em C.
## Objetivo
Implementar uma biblioteca que processe arquivos CSV, aplicando filtros e selecionando colunas conforme especificado. A solução deve ser capaz de integrar com a interface definida em C abaixo.
```c
/**
* Process the CSV data by applying filters and selecting columns.
*
* @param csv The CSV data to be processed.
* @param selectedColumns The columns to be selected from the CSV data.
* @param rowFilterDefinitions The filters to be applied to the CSV data.
*
* @return void
*/
void processCsv(const char[], const char[], const char[]);
/**
* Process the CSV file by applying filters and selecting columns.
*
* @param csvFilePath The path to the CSV file to be processed.
* @param selectedColumns The columns to be selected from the CSV data.
* @param rowFilterDefinitions The filters to be applied to the CSV data.
*
* @return void
*/
void processCsvFile(const char[], const char[], const char[]);
```
processCsv
- csv: String com os dados do CSV, onde cada linha representa um registro e as colunas são separadas por vírgulas.
- Exemplo: `"header1,header2,header3\n1,2,3\n4,5,6"`
- selectedColumns: Uma string onde os nomes das colunas a serem selecionadas são separados por vírgulas.
- Exemplo: `"header1,header3"`
- rowFilterDefinitions: Uma string onde cada filtro é definido em uma nova linha, no formato `header(comparador)valor`.
- Exemplo: `"header1>1\nheader2=2\nheader3<6"`
processCsvFile
- csvFilePath: String com o caminho do arquivo CSV.
- Exemplo: `"path/to/csv_file.csv"`
- selectedColumns: Uma string onde os nomes das colunas a serem selecionadas são separados por vírgulas.
- Exemplo: `"header1,header3"`
- rowFilterDefinitions: Uma string onde cada filtro é definido em uma nova linha, no formato `header(comparador)valor`.
- Exemplo: `"header1>1\nheader2=2\nheader3<6"`
Exemplo:
```c
const char csv[] = "header1,header2,header3\n1,2,3\n4,5,6\n7,8,9";
processCsv(csv, "header1,header3", "header1>1\nheader3<8");
// output
// header1,header3
// 4,6
const char csv_file[] = "path/to/csv_file.csv";
processCsvFile(csv_file, "header1,header3", "header1>1\nheader3<8");
// output
// header1,header3
// 4,6
```
## Funcionalidades Obrigatórias e Requisitos
O candidato deve focar nos requisitos obrigatórios, pois o descumprimento de qualquer um deles acarreta na desclassificação do processo seletivo.
Para os exemplos abaixo, considere sempre o seguinte CSV:
```csv
header1,header2,header3
1,2,3
4,5,6
7,8,9
```
- **O CSV processado deve ser escrito no stdout**
- **A primeira linha do CSV sempre será um header**
- **O CSV processado deverá incluir o header do CSV considerando a seleção de coluna**
- **A sua implementação deve tratar CSVs com quantidades arbitrárias de caractéres**
- **A sua implementação deve tratar CSVs onde as colunas tem quantidades arbitrárias de caractéres**
- **Uma string de seleção de colunas vazia é equivalente a selecionar todas as colunas**
- **No mínimo, o candidato deve implementar filtros para maior (>), menor (<) e igual (=)**
- **As strings de seleção de colunas e filtro sempre terão a mesma ordem que aparecem no CSV**
Exemplo:
- `"header1,header3"` ou `"header1=4\nheader3>3"` → OK
- `"header3,header1"` ou `"header3>3\nheader1=4"` → NÃO OK
- **Vírgulas sempre delimitam uma coluna, aspas não têm nenhuma interpretação especial**
Exemplo: No CSV abaixo, o nome da primeira coluna é `'hea"der1'`
```csv
hea"der1,header2,header3
1,2,3
```
- **Apenas linhas que condizem com todos os filtros devem ser selecionadas**
Exemplo: Aplicando os filtros `"header1=4\nheader2>3"` e selecionando as colunas header1 e header3. Somente a linha 4,5,6 `(header1 = 4 AND header2 > 3)` deve ser selecionada, pois todas as condições dos filtros devem ser atendidas. Output do filtro abaixo:
```csv
header1,header3
4,6
```
- **Nunca serão fornecidos filtros inválidos ou colunas inexistentes**
Exemplo:
- Coluna inexistente: `"header4"`
- Filtro inválido: `"header1#2"`
- **Nunca será fornecido mais de 1 filtro por coluna**
Exemplo: Se o filtro for `"header1=2"`, não haverá outro filtro para `"header1"` na mesma operação.
- **O CSV de entrada terá no máximo 256 colunas**
- **O nome de cada coluna é único**
- **Os comparadores nos filtros devem seguir a ordem lexicográfica conforme a implementação da [strcmp](https://www.man7.org/linux/man-pages/man3/strcmp.3.html) da stdlibc**
- **A arquitetura alvo é x86_64**
- **Não é permitida a execução de processos externos. Seu código não deve usar chamadas de sistema para executar outros programas**
- **Não é permitido o uso de bibliotecas externas para converter o CSV em estruturas de dados intermediárias (libs de lexers e tokenizers podem ser utilizadas)**
## Funcionalidades Bônus
Se o candidato terminar todos os pontos obrigatórios e ainda dispor de tempo livre, a seguir estão algumas funcionalidades bônus que contarão como critério de desempate.
Para todos os exemplos abaixo, considere sempre o seguinte CSV:
```csv
header1,header2,header3
1,2,3
4,5,6
7,8,9
```
1) **Desenvolver testes unitários**
2) **As colunas que aparecem na string de colunas selecionadas podem estar em ordem arbitrária**
Exemplo: Se a string de colunas selecionadas é `"header3,header1"`, sua implementação deve selecionar as colunas nesta ordem.
```csv
header1,header2,header3
1,2,3
4,5,6
7,8,9
```
E a string de colunas selecionadas: `"header3,header1"`, o resultado deve ser:
```csv
header1, header3
1,3
4,6
7,9
```
3) **As colunas na string de filtros podem aparecer em ordem arbitrária**
Se os filtros são fornecidos como `"header2>3\nheader1=4"`, sua implementação deve aplicar esses filtros corretamente, independentemente da ordem, conforme output abaixo:
```csv
header1,header2,header3
4,5,6
```
4) **Colunas que não existem podem aparecer na seleção de colunas e nos filtros**
Se a string de colunas selecionadas inclui `"header4"` e o CSV não tem um header header4, ou se os filtros incluem `"header5=10"` e o CSV não tem um header header5, sua implementação deve tratar esses casos adequadamente, escrevendo no stderr com a mensagem `"Header 'header4' not found in CSV file/string"` ou `"Header 'header5' not found in CSV file/string"`, respectivamente, encerrando a execução.
5) **Tratamento de erro para filtros inválidos**
Se for fornecido um filtro inexistente ou inválido, como `header1#2`, sua implementação deve tratar esses casos escrevendo no stderr com a mensagem `"Invalid filter: 'header1#2'"`.
6) **Aceitar mais de 1 filtro por header**
Permitir que múltiplos filtros sejam aplicados a um mesmo header, como `"header1=1\nheader1=4\nheader2>3\nheader3>4"`, e tratar esses filtros de forma adequada. Para essa implementação, o candidato deverá implementar a lógica OR para filtros no mesmo header.
O filtro de exemplo será considerado como: `(header1=1 OR header1=4) AND header2>3 AND header3>4`, resultando no output abaixo:
```csv
header1,header2,header3
4,5,6
```
7) **Implementar os operadores diferente (!=), Maior ou igual que (>=), e Menor ou igual que (<=)**
Permitir que filtros utilizem operadores de diferença, maior ou igual, e menor ou igual, como `"header1!=2\nheader2>=5\nheader3<=6"`, e tratar esses filtros de forma adequada resultando no output abaixo:
```csv
header1,header2,header3
4,5,6
```
---