Olá, sou Igor Suzuki, tenho 24 anos e sou aluno de Banco de Dados da FATEC de São José dos Campos.
Meu conhecimento na programação iniciou-se em 2016 quando cursei meu técnico de Automação Industrial e aprendi a programar arduínos em C. Após terminar o curso, trabalhei como técnico de TI, me aproximando ainda mais da área da tecnologia. Em 2021, ingressei na FATEC para me especializar e dedicar-me à área de desenvolvimento, e obtive grandes ganhos de conhecimento, desenvolvendo hard e soft skills primordiais para minha migração profissional para a área de desenvolvimento de software.
Atualmente, trabalho como Analista Programador na empresa IACIT e tenho maior domínio de tecnologias como Java, Banco de Dados Relacional e ReactJS.
Visualizador de dados COVID-19
Carcará Analysis
Interno - FATEC
O desafio foi desenvolver um projeto com o objetivo de analisar os dados oficiais da COVID-19 no Estado de São Paulo e entregá-los ao usuário de forma clara e contextualizada, através de visualizações gráficas ou não-gráficas.
A solução foi um sistema web em Python através do Flask, que a partir dos CSVs disponilizados pelo governo contendo dados estatísticos da COVID, mostrava para o usuário gráficos de diferentes tipos, como barras e setores, que continham estatísticas sobre o vírus e também demais insights relevantes que eram calculados através dos dados já existentes.
A aplicação foi desenvolvida predominantemente em Python devido à sua sintaxe clara e simplificada, além de uma vasta quantidade de bibliotecas e frameworks que suportam diversas áreas de desenvolvimento, incluindo análise de dados, que facilitou o processo de criação do primeiro projeto.
Para ajudar com a manipulação dos dados foi utilizado o Pandas, que é uma biblioteca que oferece estruturas de dados de alto desempenho, além de ferramentas de análise de dados. Ela foi usada para a leitura dos dados que eram obtidos através de CSVs. O Pandas também possui integração com a biblioteca NumPy, o que proporcionou um desempenho eficiente para as operações numéricas.
Para facilitar a visualização dos dados estatísticos, foi utilizado Plotly, uma biblioteca gráfica interativa para Python. Ela é usada para criar visualizações de dados interativas e dinâmicas, além de oferecer suporte a uma variedade de tipos de gráficos, desde gráficos simples até visualizações mais complexas e personalizadas. No caso desse projeto, ela foi utilizada para criar gráficos de barra e setores, para demonstrar os dados da COVID.
Cálculos estatísticos para plotagem de gráficos
Nesse projeto, realizei o desenvolvimento dos cálculos para plotagem de gráficos com as estatísticas personalizadas de diferentes dados. Através dos cálculos, foi possível extrair informações complementares além das que os dados forneciam originalmente
# GRÁFICO TOTAL DE CASOS (Taxa de Incidência)
pop = 44000000 #população do estado de SP
casos = covidsp[covidsp['Data'] == data]['Casos por dia'].values[0]
inc = casos / (pop-casos) * 100000
print('Incidência de casos: %.f' %inc, 'a cada 100 mil habitantes')
# GRÁFICO TOTAL DE ÓBITOS (Taxa de Letalidade)
obtotal = covidsp[covidsp['Data'] == data]['Total de óbitos'].values[0]
casostotal = covidsp[covidsp['Data'] == data]['Total de casos'].values[0]
let = (obtotal/casostotal) * 100
print('Taxa de letalidade no Estado: %.1f' %let, '%')
No exemplo de código acima, eu utilizei os dados de casos por dia e a população do estado de SP para calcular a incidência de casos a cada 100 mil habitantes. No segundo cálculo, através do número de óbitos total e de casos total, realizei o cálculo para mostrar a porcentagem de letalidade da doença.
Cálculos estatísticos para comparação de informações
Realizei também o desenvolvimento dos cálculos para amostragem de informações de comparação. Através dos cálculos, foi possível comparar os dados de diferentes períodos e ter noção da evolução da COVID.
# OCUPAÇÃO DOS LEITOS DE UTI E ENFERMARIA NO ESTADO (%) (Variação nos últimos 7 dias)
ocup = leitos[leitos['Data'] == data]['Ocupação dos leitos de UTI e Enfermaria (%)'].values[0]
ocup7 = leitos[leitos['Data'] == (data - dt.timedelta(days=7))]['Ocupação dos leitos de UTI e Enfermaria (%)'].values[0]
x = (ocup*100) / ocup7-100
print('Ocupação de leitos {0}%. Comparação com 7 dias atrás: {1:.2f}'.format(ocup, x), '%')
# NOVAS INTERNAÇÕES POR DIA NO ESTADO (Variação nos últimos 7 dias)
inter = leitos[leitos['Data'] == data]['Novos casos de internações (UTI e Enfermaria)'].values[0]
inter7 = leitos[leitos['Data'] == (data - dt.timedelta(days=7))]['Novos casos de internações (UTI e Enfermaria)'].values[0]
x = (inter*100) / inter7-100
print('Novas internações: {0}. Comparação com 7 dias atrás: {1:.2f}'.format(inter, x), '%')
No trecho de código acima, utilizei os números de ocupação de leitos e de novas internações em determinada data, para realizar o cálculo da diferença em porcentagem com os números dos mesmos dados de 7 dias atrás.
Linguagem Python
- Lógica, variáveis e tipos de dados: sei fazer com autonomia
- Funções: sei fazer com autonomia
- Listas e dicionários: sei fazer com ajuda
- Manipulação de entrada e saída de arquivos: sei fazer com ajuda
Plotagem de gráficos
- Popular e construir gráficos: sei fazer com ajuda
- Plotagem de diferentes estilos de gráficos: sei fazer com ajuda
- Manipulação e personalização de dados estatísticos: sei fazer com ajuda
- Comunicação eficaz: Com as aulas em sua totalidade no regime online, precisei evoluir minha comunicação com os integrantes do grupo para melhor o entendimento e compreensão entre a equipe.
- Aprendizado contínuo: A partir da necessidade do aprendizado sobre desenvolvimento de software, sendo o meu primeiro semestre, precisei estudar bastante para entender a base necessária para programar em Python.
Sistema de cadastro de clientes
O desafio foi criar uma plataforma para criação e ativação de clientes para posterior uso da empresa. O projeto devia contar com telas de cadastro que inserem informações no banco de dados para posterior exibição na tela de consulta dos clientes.
A solução foi um aplicativo desktop em Java através de interface GUI, na qual eram dispostos componentes swing para formar etapas de um cadastro, os dados preenchidos nesses componentes eram salvos no banco de dados conforme o usuário avançava nas etapas do formulário.
A aplicação foi desenvolvida em Java, linguagem orientada a objetos, a qual juntamente com o framework Swing foi possível criar elementos visuais para utilização em um aplicativo desktop.
O Swing fornece componentes gráficos, como botões, caixas de texto, tabelas, entre outros, que podem ser usados para construir interfaces de usuário interativas. Essa característica foi útil nesse projeto pois facilitou o desenvolvimento da parte visual da aplicação.
Para armazenamento das informações, foi utilizado o PostgreSQL, um banco relacional no qual guardamos os dados de usuários e clientes. Foi escolhido o Postgres por conta de sua interface dedutiva, e funcionalidades expostas de forma facilitada, que contribuíram na conexão, manuseio e gerenciamento do banco de dados.
Visualização de clientes cadastrados
Neste projeto realizei o desenvolvimento dos métodos de crud dos clientes. Dentre eles, realizei o método de listagem dos clientes para visualizar quais empresas estão cadastradas no banco de dados da plataforma.
public void mostrarCliente(String cnpj) {
try {
Connection conexion = conectar();
st = conexion.createStatement();
String sql ="select * from cliente where cnpj_cliente='" + cnpj+ "';";
rs = st.executeQuery(sql);
variables empresa = new variables();
if (rs.next()) {
empresa.setCnpj(rs.getString("cnpj_cliente"));
empresa.setNome_empresa(rs.getString("nome_empresa"));
empresa.setObjetivo_neg(rs.getString("objetivo_negocio"));
var.add(empresa);
}
else {
JOptionPane.showMessageDialog(null, "Registro não encontrado", "Sem registro", JOptionPane.INFORMATION_MESSAGE);
}
st.close();
conexion.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Erro no Programa " + e, "Erro no sistema", JOptionPane.ERROR_MESSAGE);
}
No exemplo de código acima, é realizada uma conexão com o banco e realizada uma query de consulta dos clientes, procurando pelo CNPJ. Com base nos dados obtidos pela consulta, são setados nos campos de informação da empresa as informações referentes ao CNPJ pesquisado. Caso não seja encontrado um registro, mostra uma mensagem de "Registro não encontrado" em uma janela JOptionPanel
Cadastro de clientes
Desenvolvi o método para cadastrar as informações da empresa que é cadastrada na plataforma, com seus respectivo armazenamento no banco de dados.
public void inserir(String cnpj, String nome_empresa, String objetivo_neg, String entregavel_min, String entregaveis_possi,
String solucao, String produto, String funcionalidade, String core) {
try {
Connection conexion = conectar();
st = conexion.createStatement();
String sql = "insert into escopo(cnpj,nome_empresa,objetivo_neg,entregavel_min,entregaveis_possi,
solucao,produto,funcionalidade,core) values('" + cnpj + "','" + nome_empresa + "','"+entregavel_min+"',
'"+entregaveis_possi+"','"+solucao+"','"+produto+"','"+funcionalidade+"','"+core+"');";
st.execute(sql);
st.close();
conexion.close();
JOptionPane.showMessageDialog(null, "Salvo com sucesso", "Mensagem", JOptionPane.INFORMATION_MESSAGE);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Erro ao Salvar " + e, "Mensagem", JOptionPane.ERROR_MESSAGE);
}
}
No trecho de código acima, é aberta uma conexão com o banco, realizada uma query de inserção no banco de dados, a qual recebe os dados da empresa, itera na query de inserção e executa para armazenar as informações no banco. Após esse processo é encerrada a conexão com o banco e se ocorrer algum erro é mostrado uma janela com a mensagem de erro para o usuário.
Linguagem Java
- Orientação a objetos: sei fazer com ajuda
- Funções em Java: sei fazer com ajuda
- Integração com banco de dados: sei fazer com ajuda
- Tratamento de erros: sei fazer com ajuda
Banco de dados
- Consultas personalizadas com SQL: sei fazer com ajuda
- Gerenciamento de conexões: sei fazer com ajuda
Swing Framework
- Desenvolvimento através de componentes Swing: sei fazer com autonomia
- Gerenciamento de componentes GUI: sei fazer com ajuda
- Desenvolvimento de aplicação desktop: sei fazer com ajuda
- Criatividade: Com o primeiro contato com uma empresa real, precisei de criatividade para conseguir desenvolver uma solução que cumprisse com os requisitos impostos.
- Aprendizado contínuo: A partir do requisito de desenvolver em Java e ter o primeiro contato com a linguagem no semestre em questão, precisei estudar para aprender sobre os princípios de orientação à objetos.
Visualizador de dados meteorológicos
O desafio consistia no desenvolvimento de um sistema no qual seja possível importar, pesquisar e gerar relatórios de dados meteorológicos. Além disso, alocação dos dados disponibilizados no site do Instituto Nacional de Meteorologia (INMET) para um banco de dados, para integrar com o sistema desenvolvido.
A solução foi uma aplicação com interface web, que dispõe de um mecanismo de filtro no qual é possível filtrar os registros por datas, regiões, estados, localidades e tipo de dado, para posteriormente expor as informações em formato de gráficos e com a possibilidade de exportar um relatório com base na consulta realizada.
O back-end da aplicação foi desenvolvido predominantemente em Java, uma linguagem orientada a objetos, na qual juntamente com a tecnologia de Spring foi possível criar endpoints para interfaces web.
O Spring é um framework que dispõe de recursos para criação de aplicações web escritas em Java e que traz mais agilidade para o desenvolvimento, visto que facilita as configurações iniciais do projeto com a injeção de dependências, as quais servem tanto para preparar o ambiente, quanto para otimizar a utilização de ferramentas e bibliotecas durante o desenvolvimento do projeto.
O banco de dados utilizado foi o PostgreSQL, um banco relacional no qual alocamos todos os dados meteorológicos, dados de estações e regiões. A escolha do Postgres se deu por conta de sua versatilidade, interface simplificada, e funcionalidades expostas de forma dedutiva, que facilitaram a usabilidade e gerenciamento do banco de dados. A sua alta eficiência e desempenho contribuiram para armazenar com tranquilidade os milhões de dados meteorológicos importados.
Chart.js é uma biblioteca do JavaScript que possibilita a exposição de dados em forma de gráficos em páginas web, ela foi essencial para a interface do projeto. Com ela, pudemos mostrar de forma interativa os dados meteorológicos devidamente filtrados e escolhidos pelo usuário da aplicação. Nela também é possível personalizar as propriedades de design, o que possibilitou a exposição de gráficos personalizados de acordo com cada tipo de dado.
Criação e personalização dos endpoints back-end
Nesse projeto realizei o desenvolvimento dos métodos em back-end que realizavam as consultas dos dados meteorológicos no banco de dados. Criei os endpoints principais de consultas gerais, e também os endpoints personalizados baseados nos filtros. De acordo com os filtros selecionados, eu validava os parâmetros recebidos e adaptava os endpoints com consultas personalizadas no banco de dados para retornar os resultados pretendidos.
@GetMapping(value = "/precipitacao/range/{estacao}/{data1}/{data2}")
public List<Precipitacao> listarRangePrecipitacao(@PathVariable("estacao") String codigo, @PathVariable("data1") String precData, @PathVariable("data2") String precData1){
Query query = entityManager.createNativeQuery("select * from precipitacao where prec_data between '"+precData+"' and '"+precData1+"' and fk_estacao_cod_wmo = '"+codigo+"'");
List<Object[]> rows = query.getResultList();
List<Precipitacao> list = new ArrayList<>();
for (Object[] obj : rows) {
list.add(new Precipitacao(
(Integer) obj[0],
(Date) obj[1],
(Date)obj[2],
(BigDecimal) obj[3],
(String) obj[4])
);
}
return list;
}
No exemplo de código acima, o endpoint de precipitação recebe os parâmetros personalizados de acordo com a estação e datas escolhidas pelo usuário, realiza a pesquisa no banco de dados com as variáveis e coloca o resultado dentro de uma lista de arrays de objetos. Através de um laço, cada objeto do tipo precipitação retornado pela consulta na query é adicionado na lista.
Desenvolvimento do dashboard
Contribuí no desenvolvimento da interface do front-end, onde implementei a utilização da biblioteca chart.js para construir os gráficos baseados nos dados meteorológicos requisitados. Realizei métodos em JavaScript, que consultavam os JSON's dos endpoints do back-end, e gerava os gráficos a partir dos dados captados. Também implementei inputs na página web para receber os critérios de filtragem e passar os parâmetros para o back-end realizar as consultas.
if(dado[0]=="temperatura"){
$(document).ready(function(){
$.getJSON("/temperatura/range/"+dado[1]+"/"+dado[2]+"/"+dado[3],function(data){
if(dado[1]!=null){
document.getElementById("selectRegiao").innerHTML = "";
$("#selectRegiao").append(inventory.find(procurarEstacao).nome_estacao+" - |"+dado[1]+"|");
document.getElementById("selectEstado").innerHTML = "";
$("#selectEstado").append(inventory.find(procurarEstacao).estado);
$(document).ready(function(){
$.getJSON("/estados",function(regiao){
function procurarEstado(estado) {
return estado.nome_estado === inventory.find(procurarEstacao).estado;
}
document.getElementById("selectRegiao").innerHTML = "";
$("#selectRegiao").append(regiao.find(procurarEstado).regiao);
});
});
}
...
No trecho de código acima se o usuário busca pelo dado de temperatura, é realizado uma busca do JSON do endpoint formado pela URL personalizada de acordo com os parâmetros passados de região, estado e estação.
Geração de relatório
Implementei a função de gerar um PDF do gráfico gerado, contendo as informações meteorológicas filtradas de acordo com a pesquisa do usuário. O pdf gerado contém os dados pesquisados e o gráfico equivalente
Spring Framework
- Desenvolvimento de aplicações web: sei fazer com ajuda
- Arquitetura REST: sei fazer com autonomia
- Integração com banco de dados: sei fazer com autonomia
- Injeção de dependências: sei fazer com autonomia
- Desenvolvimento de código através de interfaces: sei fazer com ajuda
Banco de dados
- Consultas personalizadas com SQL: sei fazer com autonomia
- Geração de scripts: sei fazer com autonomia
- Export e import de backup: sei fazer com autonomia
Programação
- Funções em JavaScript: sei fazer com ajuda
- Manipulação de variáveis com JavaScript: sei fazer com autonomia
- Programação orientada a objetos: sei fazer com autonomia
- Consumo de API Rest: sei fazer com autonomia
- Gerenciamento de usuários: sei fazer com ajuda
- Consumo de recursos de bootstrap: sei fazer com ajuda
- Resolução de problemas: A partir da proposta de solução do projeto, necessitei de habilidades na resolução de problemas para contornar obstáculos durante o desenvolvimento.
- Flexibilidade: Como desenvolvi no front-end e também no back-end desse projeto, precisei desenvolver minha flexibilidade para conseguir conciliar o desenvolvimento em ambas as stacks.
- Autoconhecimento: Neste projeto necessitei me conhecer melhor, reconhecer meus limites e entender que existem coisas ao meu alcance, e coisas que não dependem somente de mim, entender que a pressa não adianta de nada se não houver qualidade no que se está fazendo. Me conhecer melhor foi um aprendizado essencial para a minha vida.
Aircraft Configuration Control: Gerenciador de componentes instalados em aeronaves
O desafio era a criação de uma plataforma em que o usuário consulte itens instalados nas aeronaves. O sistema inclui a verificação e edição de itens instalados ou aplicáveis a determinados "chassis" conforme base de dados fornecida.
A solução foi um sistema que possuía todas as lógicas de formação de todos os itens armazenadas no banco de dados, dessa forma, a partir do chassi consultado, a lógica de composição dos itens era consultada no banco e os itens que eram compatíveis com o chassi em questão eram mostrados na tela para o usuário. Para melhor usabilidade do sistema, foi utilizada hospedagem em nuvem, que permitiu o acesso do sistema tanto pelo computador, como pelo celular ou qualquer outro dispositivo com acesso ao navegador com internet.
O back-end da aplicação foi desenvolvido em Java juntamente com o framework Spring, onde foi realizada a lógica das regras de negócio para determinação de quais itens eram considerados instalados, instaláveis ou não instaláveis de acordo com os chassis que fossem pesquisados. Através do Spring Data foi possível realizar consultas de forma mais eficiente no banco de dados para tratamento das lógicas e condições no back-end.
Para armazenamento dos dados, foi utilizado o Oracle Autonomous Database, um banco relacional em nuvem. Foi escolhido devido a possibilidade de consultar o banco através da internet, proporcionando uma melhor acessibilidade, praticidade e flexibilidade. Além do mais, também proporcionou maior segurança, tanto no controle de acesso ao banco, quanto na consistência dos dados, pois eram gerados backups automáticos que protegiam contra a perda de dados e facilitavam a recuperação em caso de falhas de operação.
O front-end do sistema foi desenvolvido em Vue.js, um framework JavaScript que conta com uma arquitetura estruturada por meio da criação de componentes reusáveis. Isso facilitou o desenvolvimento da plataforma, tendo em vista que certas partes visuais da interface tinham certa semelhança.
Para hospedar a aplicação em um servidor, foi utilizada uma instância da AWS, que é uma das principais plataformas provedora de serviços de infraestrutura para aplicações online baseado em Cloud. Com ela foi possível hospedar a aplicação em nuvem, que permitiu o acesso ao sistema pelo endereço do servidor AWS, possibilitando o acesso por outros dispositivos, como celulares, tablets e outros dispositivos com acesso à internet.
Gerenciamento de permissões de usuários
Realizei o gerenciamento de permissões dos usuários de acordo com as roles que forem definidas na criação dos mesmos. Essas permissões diferenciam quais conteúdos do sistema cada nível de usuário terá acesso.
@Service
public class CreateRoleUserService {
@Autowired
UsuarioRepository userRepository;
public User execute(CreateUserRoleDTO createUserRoleDTO) {
Optional<User> userExists = userRepository.findById(createUserRoleDTO.getIdUser());
List<Role> roles = new ArrayList<>();
if (userExists.isEmpty()) {
throw new Error("User does not exists!");
}
roles = createUserRoleDTO.getIdsRoles().stream().map(role -> {
return new Role(role);
}).collect(Collectors.toList());
User user = userExists.get();
user.setRoles(roles);
userRepository.save(user);
return user;
}
}
No exemplo de código acima, na criação de permissões de um usuário, é passado uma DTO (Data Transfer Object) contendo as roles definidas para aquele perfil. Para cada role informada é realizada a atribuição e cadastro no usuário, através do setRole e save do mesmo.
Geração de relatório PDF
Contribuí no desenvolvimento da interface do front-end, onde implementei a utilização da biblioteca pdfMake para construir um relatório contendo os itens instalados no chassi pesquisado.
const gerarPDF = () => {
const docDefinition = {
header: {
text: `Chassi: ${chassi.value} - Embraer`,
style: 'header',
},
content: [
{
style: 'table',
table: {
headerRows: 1,
widths: ['*', '*'],
body: [
[
{ text: 'Item', style: 'tableHeader' },
{ text: 'Installed', style: 'tableHeader' },
],
...itens.value.map((item) => [
item.nome,
{
text: item.status === '✔' ? 'Aplicable' : 'Not Aplicable',
style: item.status === '✔' ? 'aplicable' : 'notAplicable',
}
[...]
pdfMake.createPdf(docDefinition).download('Embraer.pdf');
};
No trecho de código acima foi utilizada a biblioteca do pdfMake, biblioteca para gerar e exportar documentos PDF. No corpo do docoumento foram atribuídas as informações que serão expostas: o item, e se ele está instalado. E no final é chamado o método de createPdf para exportar o documento.
Hospedagem da aplicação em nuvem
Realizei a instanciação e configuração de um servidor em nuvem na AWS para disponibilizar a aplicação de forma pública. Configurei as aplicações back-end e front-end para realizarem a comunicação através do servidor, habilitei as portas necessárias e configurei o ambiente para rodar ambas as aplicações publicamente.
Spring Framework
- Integração do banco com Spring Data: sei fazer com autonomia
- Arquitetura REST: sei fazer com autonomia
- Implementação de Spring Security: sei fazer com ajuda
Banco de dados
- Segurança do banco de dados: sei fazer com autonomia
- Hospedagem de banco em nuvem: sei fazer com ajuda
- Gerenciamento de usuários do banco: sei fazer com ajuda
Hospedagem em nuvem
- Configuração de Windows Server: sei fazer com ajuda
- Permissionamento de portas do servidor: sei fazer com autonomia
- Gerenciamento de firewall: sei fazer com ajuda
- Gerenciamento de recursos: sei fazer com ajuda
- Pensamento crítico: Com a complexidade do projeto, necessitei desenvolver meu pensamento crítico para saber qual melhor caminho seguir e priorizar o que era mais importante para desenvolver uma solução para a regra de negócio mais complexa do projeto.
- Adaptabilidade: A partir da decisão de hospedar o sistema em nuvem e um dos requisitos ser a utilização do framework Vue.js, precisei me adaptar com novos ambientes e tecnologias com as quais nunca tive contato, o próprio Vue, e o sistema operacional Linux.
- Trabalho em equipe: Nesse projeto foi essencial a harmonia entre a equipe, pois com as novas tecnologias foi necessário que todos aprendessem algo novo, de forma a conseguir repassar para os colegas de que forma seria implementado no projeto. Através da boa comunicação e trabalho em equipe conseguimos conciliar o desenvolvimento de maneira mais eficiente.
Cloud Kitchen: Gerenciador de restaurante
O desafio abrange o desenvolvimento de um sistema web para gerência de um restaurante, com controle de estoque e fornecedores, visualização do desempenho de funcionários e pratos, além de gráficos para facilitar a visualização dos insights relevantes para o dono do estabelecimento.
A solução foi uma plataforma web, separada em diferentes seções, contendo insights em formas de gráficos, tabelas e cards para visualização de informações sobre estoque, vendas, pratos e funcionários.
O back-end foi desenvolvido em Java com framework Spring para disponibilizar uma API com arquitetura REST contendo o mapeamento das rotas. Foram desenvolvidos endpoints CRUD que interagem com dados de pratos, funcionários e estoque para consumo do frontend.
O banco de dados foi alocado em nuvem com o Autonomous Database da Oracle, que permitiu o consumo dos dados de qualquer ambiente com internet. Seu acesso restrito por wallet e backups automáticos foi um fator relevante para a escolha desse banco de dados.
Com o framework do Vue.js foi possível componentizar os elementos do frontend para reutilizá-los em locais diferentes. Suas propriedades de condicional com v-if e looping com v-for proporcionaram uma maior facilidade na exibição dos dados utilizando condições e iterações em componentes.
Cadastro de alertas de estoque
Realizei o consumo da API do backend para cadastrar alertas para avisos de estoque baixo ou validade próxima.
<script>
import axios from 'axios';
export default {
name: 'alerta',
data() {
return {
formData: {
nomeAlerta: "",
descricao: "",
entidade: "",
condicaoDisparo: "",
valorParametro: "",
acao: "",
destinatarios: ""
},
};
},
methods: {
submitForm() {
const jsonData = JSON.stringify(this.formData);
axios.post('http://localhost:8081/alerta', jsonData, {
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
console.log('Resposta do servidor:', response.data);
this.formSubmitted = true;
alert("Alerta criado");
})
.catch(error => {
console.error('Erro na solicitação:', error);
alert("Erro ao criar alerta");
});
}
}
};
</script>
No exemplo de código acima, é enviado um conteúdo de formulário em formato de JSON em uma requisição HTTP do tipo POST para o endpoint da API que cadastra alertas no banco de dados. Após isso, é retornado se o cadastro do alerta obteve sucesso ou não.
Exibição de quadro de funcionários
Realizei a exibição dos funcionários escalados em determinado dia conforme dados consumidos da API do backend.
<template>
<div>
<p class="funcio">{{ title }}</p>
<table class="tabela">
<thead>
<tr>
<th>COLABORADORES ESCALADOS</th>
<th>FUNÇÃO</th>
</tr>
</thead>
<tbody>
<tr v-for="(funcao, nome) in funcionarios" :key="nome">
<td>{{ nome }}</td>
<td>{{ funcao }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
import axios from 'axios';
export default {
...
methods: {
async fetchData(date) {
const formattedDate = this.formatDate(this.date);
try {
const response = await axios.get(`http://localhost:8081/diario/${formattedDate}`);
this.funcionarios = response.data.funcionarios || {};
} catch (error) {
console.error('Erro ao buscar dados:', error);
}
}
...
No exemplo de código acima, uma tabela com nome e função dos funcionários é montada com um v-for de uma lista, que contém dados de resposta obtidos de uma requisição HTTP, do tipo GET, para um endpoint de obter os funcionários escalados em um determinado dia, que é passado como parâmetro.
Plotagem de gráficos de desempenho de pratos
Realizei a plotagem de gráficos com os pratos, sobremesas e bebidas mais e menos vendidos de acordo com os dados do banco de dados.
<template>
<div class="container">
<div class="component-title2">Mais Vendidos</div>
<div class="row">
<div class="column">
<P class="desc-grafico">Principais mais vendidos</P>
<bar-chart :data="maisVendidos.principal"></bar-chart>
</div>
<div class="column">
<P class="desc-grafico">Sobremesas mais vendidas</P>
<bar-chart :data="maisVendidos.sobremesa"></bar-chart>
</div>
<div class="column">
<P class="desc-grafico">Bebidas mais vendidas</P>
<bar-chart :data="maisVendidos.bebida"></bar-chart>
</div>
</div>
<div class="component-title3">Menos Vendidos</div>
<div class="row">
<div class="column">
<P class="desc-grafico">Principais menos vendidos</P>
<bar-chart :data="menosVendidos.principal"></bar-chart>
</div>
<div class="column">
<P class="desc-grafico">Sobremesas menos vendidas</P>
<bar-chart :data="menosVendidos.sobremesa"></bar-chart>
</div>
<div class="column">
<P class="desc-grafico">Bebidas menos vendidas</P>
<bar-chart :data="menosVendidos.bebida"></bar-chart>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
import BarChart from './BarChart.vue';
export default {
name: 'pratos',
components: {
'bar-chart': BarChart,
},
data() {
return {
maisVendidos: { principal: [], sobremesa: [], bebida: [] },
menosVendidos: { principal: [], sobremesa: [], bebida: [] }
};
},
mounted() {
this.fetchData();
},
methods: {
fetchData() {
axios.get('http://localhost:8081/pratos/mais-vendidos')
.then(response => {
this.maisVendidos = response.data;
})
.catch(error => {
console.error('Erro ao buscar pratos mais vendidos: ', error);
});
axios.get('http://localhost:8081/pratos/menos-vendidos')
.then(response => {
this.menosVendidos = response.data;
})
.catch(error => {
console.error('Erro ao buscar pratos menos vendidos: ', error);
});
}
No exemplo de código acima, são plotados 6 gráficos de barra, com os pratos principais, sobremesas e bebidas mais e menos vendidos. Cada gráfico recebia seus dados de acordo com as listas resgatadas do banco de dados, em endpoints do tipo GET para consultar os pratos com melhores e piores desempenhos.
Vue.js
- Condicionais com v-if: sei fazer com ajuda
- Looping com v-for: sei fazer com ajuda
- Desenvolvimento com componentes: sei fazer com autonomia
DevOps
- Gitflow Workflow: sei fazer com autonomia
- Deploy com Github Actions: sei fazer com ajuda
- Testes automatizados: sei fazer com autonomia
- Gestão de tempo: Sendo o responsável pelo frontend da aplicação, precisei gerir bem meu próprio tempo pois as telas dependiam exclusivamente de mim, então uma boa gestão de tempo foi essencial para não gerar atrasos nem pendências nas entregas.
- Criatividade: Para desenvolver telas exclusivas do zero, necessitei de criatividade para criar o layout dos painéis e decidir o que seria mostrado, e onde seria exibido.
- Responsabilidade: Como único desenvolvedor alocado no frontend, necessitei assumir a responsabilidade pelo meu próprio trabalho, cumprir prazos e entregar resultados com valor. Responsabilidade foi essencial para cumprir com minhas devidas atribuições.
Sistema de análise de sentimentos
O desafio consiste em desenvolver um sistema capaz de compreender os sentimentos de clientes através de avaliações online obtidas pelo consumo de um produto ou serviço, para interpretar, em diferentes contextos, as necessidades de seus clientes.
A solução foi uma plataforma web que, com dados obtidos de avaliações de hotéis, analisava e previa os sentimentos dos clientes através de modelos de machine learning, separando em diferentes categorias e segmentos, possibilitando uma visão mais clara e abrangente do desempenho dos hotéis através de visualização geográfica, e insights de diferentes contextos, com filtros por cidades, datas, hotéis e características específicas dos hóspedes.
O Python, além de ser usado para o desenvolvimento da API back-end, também foi utilizado em conjunto com a biblioteca scikit-learn para o treinamento dos modelos de machine learning. Essa biblioteca contém uma série de modelos e ferramentas para auxiliar tanto na preparação de dados, quanto no treinamento dos modelos de aprendizado de máquina, e foi fundamental para o desenvolvimento e aperfeiçoamento do nosso modelo de classificação de sentimentos.
Para o gerenciamento de usuários e outras funcionalidades que envolviam os conceitos de LGPD, foi utilizado Spring Boot para o desenvolvimento de um módulo específico para tratar a parte de gerenciamento de acesso. O fácil manuseio e familiaridade com o Java foi decisivo na escolha dessas ferramentas para tratar e implementar os conceitos da LGPD no projeto.
O banco de dados não relacional MongoDB foi escolhido para armazenar os dados que passaram pelo nosso modelo de classificação de sentimentos. Como o MongoDB possui um schema flexível, foi a escolha ideal para armazenar os registros como "documentos", pois os dados não vinham somente com a classificação, mas também com outras informações contidas na base de dados original.
Para armazenar os dados referentes ao gerenciamento de acesso, foi utilizado o banco MySQL, por ser um banco relacional de fácil manuseio, para garantir a integridade e relacionamento dos dados dos usuários com os termos aceitos, informações de assinatura e demais logs que eram necessários.
Para o front-end foi utilizado o Vue.js pela familiaridade com o framework, que permitiu desenvolver com maior facilidade os dashboards e gráficos. Como as telas do sistema continham muitos elementos de insights com o mesmo modelo visual, mudando somente o conteúdo dos dados, a componentização fornecida pelo Vue facilitou o desenvolvimento.
Tratamento da base de dados
Realizei o tratamento da base de dados de avaliações de hotéis, para otimizar tanto o manuseio quanto o treinamento com ML posteriormente.
data = pd.read_csv(r'C:\Hotel_Reviews.csv', low_memory=False,delimiter=',', encoding='iso-8859-1', decimal='.')
df.loc[:, 'Positive_Review'] = data.Positive_Review.apply(lambda x: x.replace('No Positive', ''))
df.loc[:, 'Negative_Review'] = data.Negative_Review.apply(lambda x: x.replace('No Negative', ''))
df.sample(5)
def calculate_total_review(row):
if row['Reviewer_Score'] < 6:
return row['Negative_Review']
else:
return row['Positive_Review']
df.loc[:,'Total_Review'] = df.apply(calculate_total_review, axis=1)
df.loc[:,'review_type'] = df["Reviewer_Score"].apply(
lambda x: "negative" if x < 6 else "positive"
)
positive_reviews = df_reviews[df_reviews.review_type == "positive"]
negative_reviews = df_reviews[df_reviews.review_type == "negative"]
min_reviews = min(len(positive_reviews), len(negative_reviews))
positive_df = positive_reviews.sample(n=min_reviews, random_state=42)
negative_df = negative_reviews.sample(n=min_reviews, random_state=42)
df_review_resampled = pd.concat([positive_df, negative_df], ignore_index=True)
No exemplo de código acima, é realizada a importação de um arquivo CSV contendo as avaliações de hotéis, no qual eu realizei alguns tratamentos como: replace de dados redundantes, uma condição para identificar o tipo de avaliação de acordo com a nota fornecida pelo avaliador (se foi uma avaliação negativa eu considero o que tem no campo de comentários negativos, e se for uma avaliação positiva, considero o que tem no campo de comentários positivos), e também faço um equilíbrio na quantidade de dados para o treinamento não ficar desbalanceado.
Treinamento de modelos de Machine Learning
Realizei o treinamento com diferentes modelos de Machine Learning, buscando uma classificação de sentimentos cada vez mais assertiva.
y = df['review_type']
y = y.map({'positive': 1, 'negative': 0})
X_train_count, X_test_count, y_train, y_test = train_test_split(text_vect_count, y, test_size=0.2, random_state=42)
X_train_tfidf, X_test_tfidf, _, _ = train_test_split(text_vect_tfidf, y, test_size=0.2, random_state=42)
def train_and_evaluate_model(model, X_train, X_test, y_train, y_test, model_name):
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(f"### {model_name} ###")
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")
cm = confusion_matrix(y_test, y_pred)
disp = ConfusionMatrixDisplay(confusion_matrix=cm)
disp.plot()
plt.title(f"Confusion Matrix - {model_name}")
plt.show()
print(classification_report(y_test, y_pred))
with open(f'{model_name.lower()}_model.pkl', 'wb') as f:
pickle.dump(model, f)
gbc = GradientBoostingClassifier(n_estimators=200, learning_rate=0.1, max_depth=5, random_state=42)
train_and_evaluate_model(gbc, X_train_count, X_test_count, y_train, y_test, "Gradient Boosting")
lgbm = lgb.LGBMClassifier(n_estimators=1000, learning_rate=0.05, num_leaves=31, max_depth=7, random_state=42)
train_and_evaluate_model(lgbm, X_train_tfidf, X_test_tfidf, y_train, y_test, "LightGBM")
catboost = CatBoostClassifier(iterations=1000, learning_rate=0.05, depth=6, verbose=100, random_seed=42)
train_and_evaluate_model(catboost, X_train_tfidf, X_test_tfidf, y_train, y_test, "CatBoost")
xgb = XGBClassifier(n_estimators=600, objective='binary:logistic', learning_rate=0.05, max_depth=5, min_child_weight=3, random_state=42)
train_and_evaluate_model(xgb, X_train_hash, X_test_hash, y_train, y_test, "XGBoost")
No exemplo de código acima, após a importação de um dataframe, os dados foram divididos entre treino e teste e foi declarada uma função para auxiliar no treinamento de diferentes modelos de Machine Learning, realizando o treinamento, teste, exibição de resultados e salvamento do modelo. Neste código foram treinados os modelos GradientBoosting, LightGMB, CatBoost e XGBoost, que são somente alguns modelos entre os vários testados durante o desenvolvimento.
Classificação de diferentes idiomas e detecção de sarcasmo
Implementei as funcionalidades de classificação de diferentes idiomas através de uma biblioteca de tradução, e detecção de sarcarmos com um modelo BERT pré treinado.
def translate_to_english(text):
translator = GoogleTranslator(source='auto', target='en')
return translator.translate(text)
tokenizer = AutoTokenizer.from_pretrained('nikesh66/Sarcasm-Detection-using-BERT')
sarcasm_model = AutoModelForSequenceClassification.from_pretrained('nikesh66/Sarcasm-Detection-using-BERT')
def detect_sarcasm(text):
inputs = tokenizer(text, return_tensors='pt', truncation=True, padding=True, max_length=512)
outputs = sarcasm_model(**inputs)
logits = outputs.logits
probabilities = torch.softmax(logits, dim=-1).tolist()[0]
sarcasm_probability = probabilities[1]
return sarcasm_probability
def predict_text(input_text):
translated_text = translate_to_english(input_text)
sarcasm_probability = detect_sarcasm(translated_text)
if sarcasm_probability > 0.6:
sentiment = {
'sentiment': f'Sarcastic ({sarcasm_probability * 100:.2f}%)'
}
else:
predicted_sentiment = predict_sentiment(input_text)
sentiment = {
'sentiment': predicted_sentiment
}
return sentiment
No código acima, é declarada uma função para traduzir textos, que recebe um texto e detecta de forma automática qual seu idioma e traduz para inglês. Também há uma função que detecta sarcasmos utilizando um modelo BERT pré treinado especificamente para detectar sarcasmos, e as duas funções são utilizadas para o tratamento do texto na função de classificação, a qual traduz o texto de entrada para inglês, verifica a probabilidade de sarcasmo e depois realiza a classificação normalmente com o modelo desenvolvido por mim.
Python
- Tratamento de dados: sei fazer com autonomia
- Criação de endpoints com flask: sei fazer com autonomia
- Desenvolvimento com Jupyter Notebook: sei fazer com autonomia
Aprendizado de Máquina
- Preparação de dados para treinamento: sei fazer com autonomia
- Treino e teste de diferentes modelos de machine learning: sei fazer com ajuda
- Interpretação de resultados e matriz de confusão: sei fazer com autonomia
- Uso de algoritmos para classificação de sentimentos: sei fazer com ajuda
Banco de Dados Não-Relacional
- Criação e uso do MongoDB: sei fazer com autonomia
- Conexão do MongoDB com Python: sei fazer com autonomia
- Salvamento e busca de documentos: sei fazer com autonomia
- Adaptabilidade: Com novas tecnologias necessárias (machine learning e banco de dados não relacional), necessitei me adaptar com uma linguagem que não tinha familiaridade e também aprender a utilizar novas bibliotecas, ferramentas e frameworks.
- Aprendizado contínuo: Pelo fato de ser meu primeiro contato com aprendizado de máquina, necessitei aprender do zero como era o processo para a criação de um modelo. Inicialmente consegui desenvolver um modelo básico, porém para evoluir cada vez mais, necessitei de um aprendizado contínuo de novos modelos, novas bibliotecas e novos conceitos para melhoria da performance do classificador.
- Resolução de problemas: Durante o desenvolvimento do classificador de sentimentos, me deparei com muitos problemas que não reconhecia o motivo nem a solução, devido à falta de familiaridade com a área de machine learning. Com isso, foram necessárias intensas pesquisas e testes de diferentes cenários para conseguir contornar ou solucionar os problemas no decorrer do projeto.