segunda-feira, 13 de julho de 2020

TypeScript #2: Melhorias no projeto EColeta

Pessoal, hoje vou comentar sobre o projeto que desenvolvi no post anterior sobre a criação de um marketplace de coleta de resíduos.No post anterior expliquei um pouco sobre a criação do backend desenvolvendo uma API (link) para ser consumida tanto Web como Mobile.
Neste post vou comentar sobre as novas funcionalidades desenvolvidas por mim dentro desse projeto, mostrando que com os conhecimentos obtidos da semana Next Level Week, foram desenvolvidas novas features:
  • Pesquisa de pontos de coleta (onde o usuário poderá pesquisar quais são os pontos disponíveis na sua cidade/cidade vizinha, e obter as informações sobre endereço do local);
  • Entrega de resíduos (onde o usuário poderá informar que entregou algum ítem de coleta em um determinado ponto de uma cidade).
A análise da feature de pesquisa foi:

O cliente informa o estado e cidade, e o sistema realiza uma pesquisa retornado todos os pontos localizados da localidade informada, atualizando o maps (LeafLeat), anexando o marcador nos pontos encontrados.
Logo abaixo, será retornado a imagem do ponto, junto com as suas informações do nome, email e telefone, para que o cliente consiga localizar/entrar em contato com o ponto que deseja entregar o ítem.

Para começar, eu comecei criando um arquivo .tsx (Nesse projeto foi usado TypeScrpit), onde será o index da Pesquisa do ponto de coleta. 

A primeira questão interessante que serviu como aprendizado nesse projeto foi que utilizamos a API do IBGE para nos retornarmos os estados e cidades do Brasil, assim evitamos possíveis inconsistências de informações como cidade/estado inexistente, e o cliente final ganha agilidade no processo de preenchimento do formulário, seja para pesquisa ou para cadastro.
Quando o cliente informa o estado é acionado o evento onChange, para obter o estado informado e pesquisar a cidade conforme o trecho de código abaixo:

<div className="field">
      <label htmlFor="uf">UF:</label>
        <select name="uf" id="uf" onChange={handleSelectUF}>
       <option value="0">Selecione uma UF</option>
           {ufs.map(uf=>(
             <option key={ufvalue={uf}>{uf}</option>
            ))}
         </select>
</div>

<div className="field">
        <label htmlFor="cidade">Cidade:</label>
          <select 
          name="cidade" 
          id="cidade" 
          value={selectedCity}
          onChange={handleSelectCidade}>
        <option value="0">Selecione uma Cidade</option>
               {cidades.map(cidade=>(
                   <option key={cidadevalue={cidade}>{cidade}</option>
                ))}
            </select>
           </div>
</div>
       <span>Foram localizados 
{quantidadeLocalizados < 1 ? '0' : quantidadeLocalizados} ponto(s)</span>                            
  <button type='submit'>Pesquisar</button>

E foi utilizado o useEffect para realizar as requisições para a API do IBGE, conforme o trecho de código abaixo:

    useEffect(()=>{
       axios.get<IBGEUFReponse[]>
('https://servicodados.ibge.gov.br/api/v1/localidades/estados')
       .then(response =>{
           const ufInitials = response.data.map(uf=> uf.sigla);
            setUFs(ufInitials);
           
       })
       
    }, [])
    //Carrega as cidades sempre que a UF mudar
    useEffect(()=>{
       if(selectedUF==='0'return;

       axios.get<IBGECidadeReponse[]>
(`https://servicodados.ibge.gov.br/api/v1/localidades/estados/
${selectedUF}/municipios`)
       .then(response =>{
           const cidades = response.data.map(cidade=> cidade.nome);
            setCidades(cidades);
           
       })

    }, [selectedUF]);

Após clicar no botão Pesquisar e for encontrado algum ponto com a localidade informada, o sistema populará o maps com a localidade (longitude,latitude) salvas no banco, usando o useEffect abaixo:
    
    useEffect(()=>{
        coordenadas.map(coordenada =>(
            setInitialPosition([coordenada.latitude, coordenada.longitude])
        ))
      
    }, [coordenadas])


Para mostrar as informações dos pontos localizados foi definida uma lista e dentro dela, será lido a lista de pontos, usando a função map, conforme o trecho de código abaixo:

<ul className='pontosLocalizados'>
        {pontos.map(ponto=> (
             <li key={ponto.id}>
              <img src={ponto.image} alt={ponto.name} 
className='pontosLocalizados'/>
             <br></br>

      <p className='pontosLocalizados'><b>{ponto.name}</b><br></br>
               {ponto.email}<br></br>
               {ponto.whatsapp}<br></br>
                                    
               </p>
              </li>
            ))}
</ul>


Desenvolvendo esses passos, consegui cumprir o que foi solicitado na análise comentada acima. Irei detalhar sobre a feature Entrega de resíduos no próximo post. Para mais detalhes do código, o repositório está disponível em:

Github: https://github.com/hiranneri/ecoleta-rocketseat
Linkedin: https://linkedin.com/in/hiranneri 

quarta-feira, 17 de junho de 2020

API Rest usando TypeScript

Olá pessoal, estou reativando o meu blog para falarmos sobre tecnologia e desenvolvimento, muitos assuntos foram obtidos durante esse tempo, e decidi que seria a melhor hora para voltar a falar sobre o que eu estudo/aprendo.

Neste post de retorno, gostaria de falar sobre Javascript, mas específico usando ele no back-end para criação de uma API REST.
Nesses meses e semanas de quarentena, decidi escolher uma stack de desenvolvimento para me aprofundar e desenvolver alguns projetos, venho estudado alguns tutoriais, vídeos aulas, e na primeira semana de junho, participei do evento gratuito da Rocketseat chamado: Next Level Week (NLW), que foi proposto um desafio de criar uma aplicação em uma semana, usando TypeScript, Knex e SQLite para a criação da API, e o sistema no Front-End e Mobile.

Neste projeto, o intuito inicial, foi a criação de um marketplace para coleta de resíduos, onde o usuário poderá cadastrar pontos de coleta e informar quais os tipos de resíduos que o ponto recebe.

Tendo ciência sobre o projeto, podemos iniciar com o gerenciador de pacotes:

NPM:

npm init            ou

YARN:

yarn init -y


Após o rodar o comando no terminal será criado o arquivo package.json
Recomendável realizar a instalação do TypeScript, podendo usar o comando:

yarn add -D typescript


Após a instalação do Typescript, podemos adicionar o Express (servidor)

yarn add express


Após as primeiras instalações, podemos estruturar as pastas do projeto, criando a pasta:

/src


Podemos criar o arquivo server.ts, como estamos trabalhando com TypeScript a extensão do arquivo é “.ts

Após a criação, iremos importar o Express:

import express from 'express';

const app = express();  -> Criação do app

app.use(express.json()); -> Esta linha serve para que o express entenda a

que as requisições em formato JSON.


Para utilizarmos as funções do Express, junto com o TypeScript, podemos instalar o pacote das tipagens, assim quando digitamos por exemplo “app.”, o VSCode (ou outra IDE de desenvolvimento), conseguirá identificar quais são as funções disponíveis do express().

Para instalar o pacote de tipagens usando:

NPM:

npm i @types/express            ou

YARN:

yarn add @types/express -D


Após instalar, já podemos ver a função listen, que escutará a porta “3333”, conforme código abaixo:

app.listen(3333); -> Execução do app na porta 3333

Após definido a porta de comunicação do servidor, já podemos criar as nossas rotas da aplicação

Rotas: Quando acessamos algum endereço por exemplo: localhost:3333/users, essa url seria uma rota, no exemplo abaixo a rota seria apenas "/", mais conhecido como rota raiz.


app.get('/', (request,response=> {

    
    /* Ação quando o usuário acessar a rota definida no primeiro 
    parâmetro, após o verbo HTTP GET. */
    
    return response.json( {message: "Olá Mundo"});
});

Caso precisamos que a API retorne todos os usuários, podemos fazer uma rota semelhante a essa:

Para atender a rota:  localhost:3333/users

app.get('/users', (request,response=> {
    
    /* Irei criar um objeto JSON apenas para exemplificar, 
    mas no cenário real, esse objeto seria retornado através 
    de uma pesquisa no banco. */
    
    return response.json( {
        'Gabriel',
        'Fernando',
        'José',
        'Joaquim'
    });
});

Caso precisamos que a API cadastre um usuário, podemos fazer uma rota semelhante a essa:

app.post('/users', (request,response=> {
    
    /* Quando acesso request.body, ele retornará os dados (corpo) 
    da requisição, que nesse caso seria o usuário informado 
    para ser cadastrado. */

    const {nomesobrenome,idadecidade= request.body; 

    /* Tendo esses dados em um objeto, podemos definir como salvar
    esses dados em algum banco e até realizarmos as validações, 
    após esse processo, podemos retornar o usuário salvo. */

    const usuarioCadastrado = {nome,sobrenome,idade,cidade};
    
    return response.json (usuarioCadastrado);
});

Existem mais conceitos que foram usados e que irei citar em novas publicações como o Knex e SQLite e etc., e também pretendo complementar esse projeto com novas funcionalidades. 
O código completo da API já está no meu github.

Sigam-me nas redes sociais:


segunda-feira, 10 de julho de 2017

Clean Code: Um livro necessário

Olá novamente, neste post irei falar sobre código limpo, um assunto que assim como testes, é de extrema importância, para qualquer desenvolvedor trabalhando em qualquer linguagem. Desde a última postagem estou lendo um livro que é muito falado na comunidade de desenvolvimento, chamado: Clean Code do Robert C. Martin.
 
As primeiras afirmações citadas no livro, me fez dar continuidade na minha leitura, e acredito que o fato de você ter clicado no link e está lendo esse post devem ser por esses dois motivos:


    - Há duas razões pelas quais você está lendo esse livro:
    1- Você é um programador;
    2 - Você deseja se tornar um programador melhor;


Se realmente forem esses os motivos por você está aqui, continue lendo esse post. 😅

Uma breve bibliografia do Robert Martin:
Robert C Martin, mais conhecido como Uncle Bob, é um profisional de software desde 1970, e consultor internacional desde 1990. Desde 70's ele já trabalhou em centenas de projetos. E em 2001, ele deu inicio a manifesto ágil, a partir das técnicas de programação Extreme. Ele também é membro do World Software Craftsmanship Movement - Clean Code. Ele já escreveu vários livros como: Programação Agile, Programação Extrema, UML, Programação Orientada a Objetos, Programação C ++. 


A razão por me basear neste livro, é porque durante a leitura, ele não fala sobre o que pode ser feito, dando recomendações, mas o que ele fez, comprovando que obteve sucesso. 

O que é Clean code (código limpo)?

  • É ser eficiente;
  • Simples;
  • Direto ao ponto;
  • Mínimas dependências;
  • Sem duplicação;
  • Fácil manutenção;
  • Padrões definidos;
  • Fácil leitura e entendimento;
  • Ser coberto por testes;
  • Elegante.
Já ouviu falar na síndrome das janelas?
Deixo um link para você entender que essa síndrome, tem tudo a ver com o assunto.
(http://justificando.cartacapital.com.br/2015/05/26/a-desordem-gera-desordem-conheca-a-teoria-das-janelas-quebradas/)


"Qualquer um consegue escrever código que um computador entende. Bons programadores escrevem código que humanos entendem". 
Martin Fowler.

Muitas vezes, não temos muito tempo para desenvolvermos uma feature, por n motivos, que já foram citados no meu post anterior falando sobre testes. (http://devhiranneri.blogspot.com.br/2017/06/testes-uma-pratica-necessaria.html)

Quando nós desenvolvemos um código ruim, feio, a nossa primeira intenção é tirar a culpa. Mas afinal, de quem é a culpa?
 

NOSSA!

OK, Agora que já entendemos o que é um código limpo, como eu consigo mensurar a qualidade de um código? Como eu consigo atingir os requisitos de um código limpo citados acima? 
É isso que veremos agora, que são alguns capítulos abordados pelo livro.

1 - Os nomes
 

Uma prática muito comum no desenvolvimento é querer simplificar o nome das variáveis, funções, nome de arquivos e etc. E isso uma má prática, pois somente você, ou no máximo a equipe de desenvolvimento saberá o que ela é, para o que serve. Caso entre novos(as) devs. na equipe, será um retrabalho para passar o todo o contexto, todos os significados do que pode ser aquela variável e etc. (que deveria ser simples, já que está se contratando um dev.).

Então use nomes que expressam alguma intenção:


int d;

int distanciaPecorridaEmKM;

A primeira variável (d), não consigo saber o real sentido dela, já a segunda (distanciaPecorridaEmKM), fica muito mais claro e objetivo.

2 - Funções 
NÃO IMPLEMENTE FUNÇÕES ENORMES, SEPARE-AS!

Seja pequeno!

 

Você terá mais facilidade de entender o que cada função faz, deixando-as menores, fazendo apenas 1 coisa.
 

Exemplo:
 

Tenho uma função de efetuarPedido(), nessa função deixe somente a implementação de efetuar um pedido, e não efetuar pedido, dar baixa no estoque, enviar mensagem ao usuário, tudo isso em uma função. Caso ocorra algum erro, você saberá exatamente onde refatorar o código desenvolvido.
Uma dica dada, é observar os níveis de endentação do código, se você perceber que está com muitos níveis, é bem provável que a função está fazendo mais de uma coisa.
 

Repetindo: AS FUNÇÕES DEVEM FAZER UMA COISA E DEVEM FAZÊ-LA BEM.

Só para complementar, argumentos booleanos, em geral, não são bons e o número ideal de argumentos para uma função é 0(zero). 

Depois vem um mônade(1), seguido de díade(2). Sempre que possível devem-se evitar três parâmetros. Para mais de três deve-se ter um motivo muito especial (políade) - mesmo assim não devem ser usados.

3 - DRY (Don't repeat yourself) - Não se repita 
Comentários não ajudam um código sujo. Como foi dito acima, caso o programador (ser humano, conhecedor da sintaxe da linguagem) não conseguiu enteder o código, então não será um comentário que ele entenderá.


Os comentários são aceitáveis quando:
  • Explicarem sobre a licença, direitos de uso de uma lib, por exemplo.
  • Comentários que explique a regra de negócio;
  • Comentários informativos.
O DRY não termina por aqui, ainda tem mais um conceito importante, que em breve vou comentar sobre ele.


4- Classes 
Devemos sempre seguir a convenção padrão do Java. Uma classe deve começar com uma lista de variáveis. As constantes estáticas públicas, se houver, devem vir primeiro. 
Então variáveis ​​estáticas privadas, seguidas por variáveis ​​de instância privadas. Raramente há uma boa razão para ter uma variável pública.
As funções públicas devem seguir a lista de variáveis. As funções utilitárias deverão ser privadas, assim ajuda o programa a ler como um artigo de jornal.


AS CLASSES DEVEM SER PEQUENAS. 


Assim como foi dito nas funções, que elas devem ser pequenas e realizar uma coisa de maneira correta, para a classe contamos quantas responsabilidades ela excerce.
O nome de uma classe deve descrever quais as responsabilidades que ela cumpre. 


No decorrer do livro ainda existem muitos assuntos que são tratados, como Responsabilidade Única, Exceção, Concorrência e etc...

Confesso que a leitura desse livro pude aprender muita coisa sobre desenvolvimento, as quais implementava de maneira incorreta, apenas fazendo com o que a máquina entendesse o meu código, e acredito que assim como você, estamos sempre em crescimento e melhorando o nosso trabalho, e os meus projetos serão mais bem pensados e avaliados. Vale a pena ler, e aprender ainda mais.

Siga-me nas redes sociais:
Twitter: devhiranneri
Github: github.com/hiranneri
Linkedin: linkedin.com/in/hiranneri 


Muito Obrigado e até a próxima! :)

Referências:
Livro Clean Code: https://www.amazon.com.br/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882

https://pt.slideshare.net/rodrigokono/boas-prticas-tcnica-para-um-cdigo-limpo-clean-code

https://vidadeprogramador.com.br/

quinta-feira, 22 de junho de 2017

Testes: Uma prática necessária

Dando uma breve pausa nos posts sobre lógica, hoje falo sobre testes, uma prática de desenvolvimento muito importante na construção de um sistema.
Nos dias atuais implementar o teste de software no ciclo de vida do sistema é de extrema importância, porém ainda existem muitas barreiras, por conta de recursos humanos, disponibilidade de tempo, e até recursos financeiros reduzidos.
Agora pare e pense, para ser construído um navio, avião, carro. Será que cada peça não precisa ser passada por constantes testes?
Será que um avião é simplesmente montado e já está autorizado e apto para voar com dezenas ou centenas de pessoas dentro?
No mundo do desenvolvimento, é comum estudar o problema (fazendo levantamento dos requisitos), pensar na solução e em seguida implementá-la, e depois fazer vários testes manuais na procura de algum erro e corrigindo aos poucos. Só que esse processo, principalmente na fase de testes finais tende a levar muito tempo, gera-se uma grande quantidade de erros no sistema, e afeta a manutenibilidade. E é por isso e por outras problemáticas que é necessário ter uma ou mais fases de teste.
Existem vários tipos de testes como: Testes Unitários, Teste de carga, Testes de Performance e entre outros:

Teste Unitário - O teste unitário irá testar a menor parte do sistema, que seriam os métodos. Irá avaliar se tal método atende ao que ele diz o que faz e qual o seu retorno (independente de seus parâmetros).




(Teste manual simples para inserir um cliente) 


Nesse caso, após a execução do script seria necessário olhar no console se a lista retornada condiz com o que esperamos.

A principio resolvemos parte da problemática em não testar o método utilizando-se de métodos manuais, mas será que esse(s) teste(s) manterão a sua qualidade durante muito tempo? E se fosse repetido todos os dias? Com certeza, alguma regra iria mudar e com isso o teste manual perderia a sua confiabilidade. Para que isso não ocorra, no mundo Java, existe um framework de testes unitários que trabalha com testes automatizados.

JUnit 


JUnit é um framework de testes que fornece uma API para construir os testes unitários automatizados e ajuda na visualização dos resultados. É possível verificar se cada método, está sendo executado da forma esperada.


Abaixo tem o passo a passo de como utilizar o JUnit na IDE Eclipse e um exemplo de teste (happy path) com a ferramenta.

1 - Clique em File, New, Other, Pesquise Por JUnit Test Case e clique em Next. 













2- Digite o nome da classe de teste (Recomendado ser o nome da classe a qual você quer testar + a palavra 'Test'), após no campo Class under test, clique em Browser e pesquise o nome da classe, a qual você irá testar, após clique em Next.

3- Escolha os métodos que você quer testar e depois clique em Finish.


4- Nesse passo, a classe já foi criada e já implementei o teste, no caso como eu escolhi o método inserir(), então desenvolvi o cenário, ação e a validação (utilizando o método assertEquals() da classe Assert).


5- Ao executar a classe ClienteDAOTest, o Eclipse mostra a tela do JUnit, informando quantos testes foram executados, e se houve algum erro ou alguma falha:


Testes de Performance.

O teste de perfomance consiste em verificar o quanto a aplicação se mantém durante um determinado tempo. Falando em testes de performances, existem alguns como: carga, stress e etc.

Teste de Carga

O teste de carga, irá verificar o quanto a aplicação comporta, porém o número de usuários, ou transações é aumentado gradativamente.
 

Teste de Stress

O teste de Stress, irá verificar o quanto a aplicação comporta, porém com um número x de usuários, fazendo n transações ao mesmo tempo.
 

JMeter. 
Para realizar esses testes, temos uma aplicação open source desenvolvida em Java que mensura o nível de performance, trabalhando com protocolos HTTP e HTTPS, Webservices (SOAP e REST), JDBC e etc.
(http://jmeter.apache.org/)
Nas próximas publicações, irei mostrar como utilizar o JMeter para realizar esses testes. Fique ligado!

Como vimos,é importante adotar a prática de desenvolvimento junto com testes, para que tenhamos produtividade, e que o nosso trabalho tenha mais qualidade. Os próximos posts práticos utilizaremos a metodoogia TDD - Desenvolvimento Orientado a Testes. 


Siga-me nas redes sociais:
Twitter: @devhiranneri
Github:github.com/hiranneri
Linkedin: linkedin.com/in/hiranneri


Obrigado pela leitura e até a próxima :)

segunda-feira, 19 de junho de 2017

#3: Desafios de Lógica: Remover elementos repetidos

Olá novamente, neste post, darei prosseguimento na série de posts sobre lógica, e agora vamos complementar o exercício anterior:

- Precisamos ordernar os elementos de um array e remover os elementos repetidos.


Para ordernar os elementos iremos utilizar a mesma resolução do problema anterior utilizando algoritmo bolha para ordenação.

Após solicitar um número x de nomes para o usuário e orderná-los, iremos remover eventuais elementos repetidos neste array.
A principio é necessário a criação:

String nomesSemRepeticao[] = new String[nomes.length];
int quantidadeDeElementosUnicos = 0;

 

Logo abaixo do algoritmo eu explico como foi pensado. 

for( int i = 0 ; i < original.length ; i++ ) {
                boolean existe = false;
                for( int j = 0 ; j < quantidadeDeElementosUnicos ; j++ ) {
                   
                    if( elementosSemRepeticao[ j ] .equals( original[ i ] )) {
                        existe = true;
                        break;
                    }
                }
               
                if( !existe ) {
                    elementosSemRepeticao[ quantidadeDeElementosUnicos++ ] = original[ i ];
                }
               
            }
         for(String nomes:elementosSemRepeticao){
             System.out.println(nomes);
         }

Explicação:
 

Foi criado um novo array que conterá somente elementos não repetidos, com o tamanho igual ao o array que armazenou os nomes digitados.

Foi criada a variável quantidadeDeElementosUnicos para termos ciência em qual índice o valor está sendo adicionado no array de elementos unicos.
 

A seguir foi criado uma estrutura de repetição para pecorrermos o array nomes[]. Na linha abaixo foi criada uma variável booleana para sabermos se foi encontrado algum valor repetido.

O segundo for só poderá ser executado na segunda iteração, pois j (j=0) não será menor do que quantidadeDeElementosUnicos(=0), sendo assim, cairá no segundo if, e caso o valor inverso da variável existe for igual a true, o primeiro elemento é adicionado no array.

Na segunda iteração, o j valerá 0 e quantidadeDeElementosUnicos será iterado valendo 1, assim os próximos elementos serão avaliados e se o valor do array de quantidadeDeElementosUnicos[] for igual ao valor do array nome[], então a variável existe será true, e o break da linha abaixo irá parar a condição, e a execução irá para o segundo if. (Nestas iterações, quando é encontrado um valor igual, o elemento não é adicionado, porque como a variável existe é igual a true, o valor inverso de true não executará o if que adiciona o elemento).

Após todas as iterações ocorrerem e somente os elementos forem adicionados, no final tem um for each que apresenta os valores em ordem alfabética e sem repetição.

Assim concluímos mais um desafio!

O código para resolução deste problema foi localizado no:
 https://pt.stackoverflow.com/questions/14339/eliminar-valores-repetidos-array-java


Siga-me nas redes sociais:
Twitter: @devhiranneri
Github:github.com/hiranneri
Linkedin: linkedin.com/in/hiranneri


Obrigado pela leitura e até a próxima :)

segunda-feira, 22 de maio de 2017

#2: Desafios de Lógica: Ordenação de nomes

Olá novamente, continuando com a série de Estrutura de Dados, hoje vou falar sobre ordenação.

Problema: Precisa-se que ordene um array de 20 nomes em ordem alfabética.

Resolução:
 Primeiro temos que criar um array de 20 posições para
resolução do problema:

 String nomes[] = new String [20];

Após isso, vamos solicitar ao usuário que informe os 20 nomes.
Como já expliquei essa parte de solicitar ao usuário utilizando a classe Scanner,  não vou entrar em mais detalhes nela. (Caso você queira entender um pouco melhor,  tem no meu post sobre Conversão de minutos para horas e minutos  (https://goo.gl/nQ0QEX)

Scanner sc = new Scanner(System.in);
for(int i=0;i<nomes.length;i++){
   System.out.println("Digite o nome");
   nomes[i] = sc.next();
}
//Somente para mostrar, que foi salvo os nomes
for(String valores:nomes){
  System.out.println(valores);
}

//Agora, independente da ordem que o usuário informou precisamos ordenar,
//e utilizaremos o algoritmo BubbleSort (ou conhecido também como:  Algoritmo Bolha)

* for (int i = 0; i < nomes.length - 1; i++) 
                for (int j = i + 1; j < nomes.length; j++) 
                    if (nomes[i].compareTo(nomes[j]) > 0) { 
                        String temporario = nomes[i]; 
                        nomes[i] = nomes[j]; 
                        nomes[j] = temporario; 
                    }

for(String nomesOrdenados:nome){
     System.out.println(nomesOrdenados);
}

* O algoritmo bolha, irá verificar de dois em dois se os elementos são maiores  ou menores entre eles, caso o primeiro elemento seja maior que o segundo  (o método compareTo irá retornar um número positivo (maior que 0(zero))).

Para a comparação entre os dois elementos, eu utilizo dois for's encadeados,  sendo que o segundo, irá iteirar + 1 com o índice do primeiro for, para que  consiga ler o próximo elemento.

nomes.lenght-1 - É para que o índice da variável j não passe do maior número  do array, e não lance uma exceção ArrayIndexOutOfBoundsException.

Assim independente da ordem que o usuário for passar os nomes, o algoritmo irá  verificar caractere por caractere e ordenando de forma alfabética.

Este código e outros estão disponíveis no meu github, caso queira analisar, basta clicar no link abaixo:

Projeto Ordenação - Bolha

Até + ;)
devhiranneri.eti.br

quarta-feira, 3 de maio de 2017

#1: Lógica - Conversão de minutos para hora e minutos

Olá novamente, durante esse tempo estava planejando alguns assuntos para postar aqui no meu blog que estarei estudando e transmitindo conhecimento:
A partir desse post vou falar sobre lógica de programação, resolvendo alguns problemas comuns do dia a dia do desenvolvimento. Para esta postagem vou falar sobre Conversão de minutos para horas e minutos.

O problema: (Conversão de minutos para horas e minutos)

O usuário irá digitar seja no console ou em alguma interface, o valor em minutos e o sistema deverá retornar o valor em horas e minutos.

Resolução:
Vamos pensar...















A principio teremos que criar três variáveis (horas,minutos,valorEmMinutosInformado):

int horas = 0,minutos=0,valorEmMinutosInformado=0; 
//Em JAVA, existe a possibilidade da declaração 
de variáveis em uma linha, caso as mesmas sejam 
do mesmo tipo, int.
E uma variável do tipo boolean para controlar a futura iterações, 
caso o usuário informe um valor incorreto.
boolean statusDoValor=true; 
Após a criação das variáveis iremos instanciar um objeto da classe Scanner para 
obtermos o valor passado pelo usuário.
Scanner sc = new Scanner(System.in); //No construtor da classe Scanner, existe um parâmetro que "obriga" para quem for instanciar o objeto deverá passar uma instância de InputStream,
ou outras como: Readable, File e etc. Você pode conferir na própria
documentação em:
https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html#constructor.detail
Essa linha serve para avisar ao usuário que já é possível informar o valor.
System.out.println("Digite o valor em minutos"); 
A estrutura de repetição do while servirá para no caso do usuário informar qualquer valor diferente de um número válido (e.x: número por extenso), irá ser lançado uma exceção, e a execução será abortada, e para que o usuário não necessite executar o código novamente, colocamos o código dentro do try..catch (Tratador de exceções).
 
while(statusDoValor){
try{

Essa linha abaixo irá ler o valor passado e atribuir a váriável 
valorEmMinutosInformado.

  valorEmMinutosInformado = sc.nextInt();

Vou precisar fazer uma "cópia" do valor em valorEmMinutosInformado para a variável minutos, para que no final eu consiga informar o tempo que o usuário passou via console.

  minutos=valorEmMinutosInformado;

A cada 60 minutos que equivale a 1 hora, a variável horas é incrementada e a variável minutos é reduzida de 60 em 60, até o valor dela ser menor que 60, ou seja, menor que 1 hora.


while(minutos>=60){
  horas++;
  minutos-=60;
}
  statusDoValor=false;
}catch(InputMismatchException e){
     System.out.println("Valor informado está incorreto. Digite novamente");
    valorErrado=true;
sc.next();

 
 }
}

System.out.println(valorEmMinutosInformado+" minutos equivale a "
+horas+" horas e "+minutos+"minutos");
 
}

Obs: Não se esqueçam dos imports para não apresentar erro de compilação.
" import java.util.Scanner;
import java.util.InputMismatchException; "
Esse foi um de uma série de 5 posts sobre lógica de programação. Em breve vou postar o segundo. Caso você queira contribuir com esse código ou outros, tenho ele no meu github. É só clicar no link abaixo: Projeto de Lógica de programação

Até mais...