Translate

domingo, 27 de abril de 2014

Configurando Memória Virtual SWAP no Ubuntu

Quando nosso Sistema Operacional utiliza uma grande porcentagem de memória RAM, para não travar, ele lança mão da Memória Virtual.

Explicando este termo resumidamente, "Memória Virtual" é quando o sistema operacional armazena em disco (acesso mais lento), dados que deveriam ser colocados na memória RAM, e isto não pôde ser feito, porque a mesma já estava muito cheia. 

O fato da memória RAM estar muito cheia pode ser sinal de que seu sistema precisa ser fisicamente atualizado, adicionar mais 'pentes' de memória RAM pode ajudar.

Quando a memória virtual é alocada pelo sistema operacional, o computador se torna mais lento, pois como já disse anteriormente, o acesso aos dados no disco é muito mais lento do que o acesso à memória. 

No Ubuntu, por padrão a memória virtual é acionada quando atinge-se 40% de memória RAM utilizada (60% de memória RAM livre); isto pode tornar o sistema lento rapidamente, no caso do uso mais extremo. 

Para checar como seu Sistema Operacional está usando o recurso de swap (memória virtual) e também a memória em si, execute o comando na janela do Terminal (shell)

free -m

O resultado deve ser algo parecido com a tela abaixo: 

free -m
             total       used       free     shared    buffers   cached
Mem:          3848       3644        204        263         19      515
-/+ buffers/cache:       3108        740

Swap:         4940        619       4320


Note que meu Sistema operacional, está consumindo 619 MB de memória virtual!

Podemos mudar isto, ajustando o ponto de utilização da memória RAM em que o sistema operacional começará a alocar dados também em Memória Virtual.

Para saber como este ponto está configurado atualmente, digite o seguinte comando :

cat /proc/sys/vm/swappiness 

O SO deve retornar o valor atualmente configurado para swap:

60

O valor a ser alterado é bastante subjetivo, para alterá-lo somente durante a sessão atual como forma de teste, execute o comando: 

sudo sysctl vm.swappiness=30

Verifique que o valor está alterado, chamando novamente:

cat /proc/sys/vm/swappiness 

Para alterá-lo efetivamente no Sistema Operacional, edite com permissão sudo o arquivo /etc/sysctl.conf  e adicione ao final do arquivo a linha: 

vm.swappiness = "VALOR_ESCOLHIDO_ENTRE 0 e 100"

Abaixo exemplo:

sudo gedit /etc/sysctl.conf

Adicionei a este arquivo a linha abaixo, no meu caso o valor de 30, que quer dizer que quando estiver com 70% da RAM ocupada, meu SO irá começar a utilizar Memória Virtual.

vm.swappiness = 30

sábado, 26 de abril de 2014

Enviando E-Mail com Java usando JavaMail e GMail

Eventualmente podemos nos defrontar com a necessidade de que nossas aplicações JAVA enviem E-mails, seja para gerar alertas, seja para rápida comunicação, etc. 

A JavaMail API permite esta implementação de maneira bastante simplificada. 

Juntamente com esta possibilidade, temos uma gigante e poderosa ferramenta de e-mail, gratuita, o Gmail do Google, que nos permite criar uma conta gratuita a fim de integrarmos a mesma à nossa aplicação. 

Os servidores do Gmail, necessitam de uma autenticação um pouco diferenciada (SSL), o que pode se tornar um fator complicador na implementação desta funcionalidade. 

Descrevo neste post uma Classe JAVA que é capaz de enviar emails usando texto simples, ou conteúdo HTML, para uma mensagem mais rebuscada. 

Além disso, realiza a validação e autenticação frente os servidores do Google, de forma a permitir a utilização da mesma com uma conta do Gmail

Você ainda pode compilar um .jar da mesma e utilizar seus métodos públicos de envio de e-mail, incorporando facilmente esta funcionalidade a qualquer outra aplicação, sem precisar escrever tudo novamente.


Baixando a JavaMail API

Para começarmos, devemos baixar e adicionar ao nosso classpath (importar o .jar dependendo da IDE) o arquivo java.mail.jar . 


Código Fonte

Abaixo código fonte completo e comentado. O método main()  pode ser usado para executar diretamente a classe no console e enviar mensagens.

Não esqueça de alterar o código com os endereços de remetente e destinatário. 

Para chamá-la através de outras aplicações, simplesmente instancie o construtor EnviaEmail(String, String); com o nome de usuário (cadastrado no Gmail) e senha.




package br.com.devfacil.email.view;

import java.util.Properties;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

/**
 * Classe Utilitária que contém métodos para envio de Email através de conta do
 * Gmail
 */
public class EnviaEmail {

    /**
     * Construtor sem parametros, ao ser chamado já instancia as configuraççoes
     * de email do Gmail na JVM
     *
     */
    public EnviaEmail(String userNameGmail, String senhaGmail) {

        this.username = userNameGmail;
        this.senha = senhaGmail;

        ajustaParametros();

    }

    /**
     * Variavel local para Sessao
     */
    Session session = null;

    String username = null;
    String senha = null;

    /**
     * Metodo 'main()' para teste e execução
     *
     */
    public static void main(String[] args) {

        /**
         * Mensagem de teste para envio de email Html
         */
        String mensagemHtmlTeste = "<html>\n"
                + "<body>\n"
                + "<h1> Mensagem para voc&ecirc;</h1>\n"
                + "<h2> conte&uacute;do da Mensagem:</h2>\n"
                + "<p>Mensagem enviada atrav&eacute;s de Aplica&ccedil;&atilde;o "
                + "que estudei no blog <a href=\"http://www.devfacil.blogspot.com.br\"><b>DevFacil!</b></a></p>\n"
                + "</body>\n"
                + "</html>";

        try {
            EnviaEmail ee = new EnviaEmail("eu@gmail.com", "123456");

            /**
             * Envia mensagem de e-mail com conteúdo html
             */
            ee.enviarEmailHtml("eu@gmail.com", "seu@amigo.com", "Estou aprendendo a Enviar Email através do JAVA!", mensagemHtmlTeste);
            
            /**
             * Envia mensagem de e-mail simples, somente com texto
             */
            ee.enviarEmailHtml("eu@gmail.com", "seu@amigo.com", "Estou aprendendo a Enviar Email através do JAVA!", "Mensagem Somente Texto");

        } catch (Exception ex) {

            System.out.println(ex.getMessage());

        }

    }

    /**
     * Metodo para envio de mensagem com texto simples
     */
    public void enviarEmail(String remetente, String destinatario, String assunto, String conteudo) throws Exception {

        try {

            Message message = new MimeMessage(session);

            //Configura o Remetente da mensagem
            message.setFrom(new InternetAddress(remetente));

            //Configura o Destinatário da mensagem
            Address[] toUser = InternetAddress
                    .parse(destinatario);

            //Configura o Assunto da mensagem
            message.setRecipients(Message.RecipientType.TO, toUser);
            message.setSubject(assunto);

            //Configura o Conteudo da mensagem
            message.setText(conteudo);

            /**
             * Envia a mensagem criada
             */
            Transport.send(message);

            System.out.println("Email enviado com Sucesso; ");

        } catch (MessagingException e) {
            throw new Exception("Erro ao enviar email! \n" + e.getMessage());
        }

    }

    /**
     * Metodo para envio de mensagem padrao HTML ja formatado
     */
    public void enviarEmailHtml(String remetente, String destinatario, String assunto, String conteudoHtml) throws Exception {
        try {

            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(remetente));

            Address[] toUser = InternetAddress
                    .parse(destinatario);

            message.setRecipients(Message.RecipientType.TO, toUser);
            message.setSubject(assunto);

            Multipart multipart = new MimeMultipart("related");
            BodyPart htmlPart = new MimeBodyPart();
            htmlPart.setContent(conteudoHtml, "text/html");

            multipart.addBodyPart(htmlPart);

            message.setContent(multipart);

            /**
             * Método para enviar a mensagem criada
             */
            Transport.send(message);

            System.out.println("Email enviado com Sucesso; ");

        } catch (MessagingException e) {
            throw new Exception("Erro ao enviar email! \n" + e.getMessage());
        }

    }

    /**
     * Configura aa propriedades da JVM com parametros do servidor Gmail
     *
     * Modificador de acesso 'private' pois não é necessário que este método
     * seja chamado de outras classes
     */
    private void ajustaParametros() {

        Properties props = new Properties();

        /**
         * Conexão com servidor Gmail
         */
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.port", "465");

        /**
         * Associa autenticação a sessao de correio
         */
        session = Session.getDefaultInstance(props,
                new javax.mail.Authenticator() {
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, senha);
                    }
                });

    }

}

quinta-feira, 24 de abril de 2014

Jogo Simon com Arduino

No Brasil conhecido como 'Genius', sucesso na década de 80. 

Jogo simples, com memória de melhor jogada e contagem de pontos. 

Vídeo demonstrativo abaixo:







Pressione qualquer tecla e mantenha pressionada até que o computador faça a jogada. Repita a jogada o quanto puder. A jogada mais extensa é gravada na EEPROM e  exibida como recorde no LCD. 

Para Limpar a memoria, pressione as chaves 0 e 4 (as das extremidades) e, mantendo-as pressionadas, reinicie o Arduino, ate ouvir um beep e  aparecer a mensagem de limpeza da memoria. 

Abaixo o código, com métodos de som (utilizando buzzer). 



Led's ligados às saídas A0 ~ A3 (constantes no código 14 aé 17)  e chaves ligadas às entradas 6 ~ 9 (constantes no código 6 até 9); 


Abaixo, diagrama de ligação: 




Código Fonte:



/*

Jogo Simon para Arduino

Para iniciar, pressione e matenha pressionada qualquer tecla. 

Para recomeçar pressione RESET

Para Limpar a memoria, pressione e mantenha pressionada as teclas
1 e 4, ate ouvir o beep.


*/


//Adiciona biblioteca para Cristal Liquido
#include <LiquidCrystal.h>

//Adiciona biblioteca para EEPROM
#include <EEPROM.h>


//Configura pinos ligados ao display LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//Quantidade de jogadas maxima
const int JOGADAS_SIZE = 100;


//Velocidade dos leds durante exibicao inicial
const int DELAY_APRESENTACAO = 150;
//
//Teclas
const int key1 = 6; 
const int key2 = 7;
const int key3 = 8;
const int key4 = 9; 
//
//Leds
const int led1 = A0; //14
const int led2 = A1; //15
const int led3 = A2; //16
const int led4 = A3; //17
//
//Pino ligado ao Buzzer
const int pin10 = 10;
//
//Tons emitidos pelo buzzer
const int som1 = 50;
const int som2 = 100;
const int som3 = 150;
const int som4 = 200;
//
//Vetor de jogadas do computador
int cpu[JOGADAS_SIZE]; //quantidade de jogadas
int tempoNivel = 250;  //velocidade do jogo
//Variave de controle da jogada atual
int jogadaAtual = 0;
//Recorde
int recorde = 0; 
//
boolean resultado = true; 
//  -led in 17 key 4  //ligacao das teclas e saidas (led e teclas)
//  -led in 16 key 3
//  -led in 15 key 1
//  -led in 14 key 1

//

void setup(){


  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(key1, INPUT);
  pinMode(key2, INPUT);
  pinMode(key3, INPUT);
  pinMode(key4, INPUT);
  //
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  //
  pinMode(10, OUTPUT);

  limpaMemoria();

  //
  // como a entrada analogica 5 nao esta conectada
  // o ruido vai fazer com que o metodo
  // randomSeed(), que inicializa o gerador
  // de numeros pseudo-aleatorios da funcao random()
  randomSeed(analogRead(5)); 


  carregaRecorde();

  preencheVetor();
  escreveVetor();

  apresenta();

}

void loop(){

  escreveLcd();
  jogadaCpu(); 

  resultado= lerTeclado(); 

  if(resultado == false){

    lcd.setCursor(0, 1);
    lcd.print("Voce Falhou"); 

    checaRecorde();

    errou();

  }
  else{
    
    delay(1000);
    
  };

}

void limpaMemoria(){

  if(digitalRead(key1)
    && digitalRead(key4)){

    digitalWrite(pin10, HIGH);
    delay(50);
    digitalWrite(pin10,LOW);
    lcd.clear();
    lcd.print("Limpando Memor..");

    for (int i = 0; i < 512; i++)
      EEPROM.write(i, 0);

    digitalWrite(pin10, HIGH);
    lcd.clear();
    lcd.print("Memoria Limpa!");
    delay(2000);
    digitalWrite(pin10,LOW);
  }


}

void carregaRecorde(){

  recorde = EEPROM.read(0);
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("Recorde: "); 
  lcd.setCursor(11, 1);
  lcd.print(recorde); 
}

void checaRecorde(){

  if(jogadaAtual > recorde){

    recorde = jogadaAtual; 
    EEPROM.write(0, recorde);

    lcd.clear(); 
    lcd.setCursor(0,0);
    lcd.print("Novo Recorde");

    lcd.setCursor(14,0);
    lcd.print(recorde);

  }

}

void somOn(int s){

  switch(s){

  case 14:
    analogWrite(pin10, som1);
    break;


  case 15:
    analogWrite(pin10, som2);
    break;


  case 16:
    analogWrite(pin10, som3);
    break;



  case 17:
    analogWrite(pin10, som4);
    break;
  }

}

void somOff(){

  analogWrite(pin10, 0); 

}

void jogadaCpu(){

  for(int j = 0; j<=jogadaAtual; j++){
    somOff();
    digitalWrite(cpu[j], LOW);
    delay(tempoNivel);     
    digitalWrite(cpu[j], HIGH);
    somOn(cpu[j]);
    delay(tempoNivel); 
    digitalWrite(cpu[j], LOW);
    somOff();
  }

}

void preencheVetor(){

  for(int x = 0; x < JOGADAS_SIZE; x++){

    cpu[x] = random(14,18);

  }

}

void escreveVetor(){

  for(int x = 0; x < JOGADAS_SIZE; x++){

    Serial.print(cpu[x]);
    Serial.print(" - ");
  }
  Serial.print("\n");

}

void errou(){

  analogWrite(pin10, 50);
  delay(500);
  analogWrite(pin10, 40);

  delay(500);            
  analogWrite(pin10, 30);
  delay(500);
  analogWrite(pin10, 20);
  delay(1000);
  somOff();

  while(true){
    delay(DELAY_APRESENTACAO);
    digitalWrite(14, HIGH);
    digitalWrite(15, HIGH);
    digitalWrite(16, HIGH);
    digitalWrite(17, HIGH);
    delay(DELAY_APRESENTACAO);  

    digitalWrite(14, LOW);
    digitalWrite(15, LOW);
    digitalWrite(16, LOW);
    digitalWrite(17, LOW);
    delay(DELAY_APRESENTACAO);
  }

}

void apresenta(){


  while(true){

    if(digitalRead(key1)
      ||digitalRead(key2)
      ||digitalRead(key3)
      ||digitalRead(key4)){
      delay(150);
      if(!digitalRead(key1)
        ||!digitalRead(key2)
        ||!digitalRead(key3)
        ||!digitalRead(key4)){
        return;
      }
    }
    delay(DELAY_APRESENTACAO * 2);
    for(int i = 14; i<=17; i++){
      digitalWrite(i, HIGH);
      delay(DELAY_APRESENTACAO);
    } 

    for(int i = 14; i<=17; i++){
      digitalWrite(i, LOW);
      delay(DELAY_APRESENTACAO);
    } 

    delay(DELAY_APRESENTACAO * 2);

    for(int i = 17; i>=14; i--){
      digitalWrite(i, HIGH);
      delay(DELAY_APRESENTACAO);
    } 

    for(int i = 17; i>=14; i--){
      digitalWrite(i, LOW);
      delay(DELAY_APRESENTACAO);
    } 
    delay(DELAY_APRESENTACAO * 2);
  }
}

boolean lerTeclado(){

  int index = 0;
  int jogadaPlayer = 0; 
  boolean jogou = false;

  do{
    do{
      jogou = false;

      while(digitalRead(key1)){
        delay(150);
        digitalWrite(14,HIGH); 
        somOn(14);
        if(!digitalRead(key1)){

          delay(150); 
          digitalWrite(14,LOW); 
          somOff();
          jogadaPlayer = 14;
          jogou = true;

          Serial.print(jogadaPlayer) ; 
          Serial.print("-"); 

        }
      }


      while(digitalRead(key2)){
        delay(150);
        digitalWrite(15,HIGH); 
        somOn(15);
        if(!digitalRead(key2)){

          delay(150); 
          digitalWrite(15,LOW);
          somOff();
          jogadaPlayer = 15;
          jogou = true;

          Serial.print(jogadaPlayer) ; 
          Serial.print("-"); 

        }
      }
      while(digitalRead(key3)){ 
        delay(150);
        digitalWrite(16,HIGH); 
        somOn(16);
        if(!digitalRead(key3)){

          delay(150); 
          digitalWrite(16,LOW);
          somOff();
          jogadaPlayer = 16;
          jogou = true;

          Serial.print(jogadaPlayer) ; 
          Serial.print("-"); 

        }
      }
      while(digitalRead(key4)){
        delay(150);
        digitalWrite(17,HIGH); 
        somOn(17);
        if(!digitalRead(key4)){

          delay(150); 
          digitalWrite(17,LOW);
          somOff();
          jogadaPlayer = 17;
          jogou = true;

          Serial.print(jogadaPlayer) ; 
          Serial.print("-"); 

        }
      }
    }
    while(jogadaPlayer == 0); 
    if(cpu[index] != jogadaPlayer){
      Serial.print(cpu[index]);
      Serial.print(jogadaPlayer);
      return false; 

    }

    jogadaPlayer = 0; 
    index++;
  }
  while(index<=jogadaAtual); 
  jogadaAtual++;
  Serial.print("\n");

  tempoNivel = tempoNivel-10; //torna o jogo mais rapido

  return true; 
}

void escreveLcd(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Pontos: ");
  lcd.setCursor(13,0);
  lcd.print(jogadaAtual);

}

Bom divertimento!

quarta-feira, 23 de abril de 2014

Wrapper e Primitivos, quando utilizar?

Os tipos de uma varável em JAVA (uma linguagem fortemente "tipada") são fundamentais no código e devem ser escolhidos com cautela, analisando sempre o que cada variável deve representar, seja para a lógica de negócio da aplicação, seja para variáveis de controle de fluxo do código. 

Os tipos primitivos, já são de conhecimento da maioria dos programadores e são exibidos na tabela abaixo: 



As classes Wrapper nada mais são (em linhas gerais) do que uma Classe, que "representa um primitivo", desta forma, uma variável de um tipo Wrapper pode ser null e pode ser instanciada (na memória) ou não (quando possui valor nulo). 

É fácil localizarmos as Classes Wrapper, que possuem os mesmos nomes dos tipos primitivos, somente com a primeira letra maiúscula. 

O Java nos oferece Classes Wrapper para todos os tipos primitivos. Assim sendo, todas linhas de código abaixo são válidas. 

        Byte b = null; 
        Short s = null; 
        Integer i = null; 
        Long l = null; 
        Float f = null; 
        Double d = null;
        Character c = null; 
        Boolean bol = null;


Além de possuir diversos métodos para trabalharmos com os primitivos que ela representa, ela nos oferece dois construtores, um recebendo como parametro um valor do tipo primitivo que ela representa 
Integer inteiro = new Integer(10); 
 
e outra recebendo uma String que é convertida para o valor primitivo que a classe Wrapper representa, 

Integer inteiroStr = new Integer("10"); 
 
Uma das necessidades de se utilizar um Wrapper, ao invés de um primitivo, é construtores de classes de algumas API (Collections por exemplo) não suportam tipos primitivos.  O código abaixo, por exemplo, não compila:


    List<int> lista = new ArrayList<int>();

O correto, seria utilizar Wrapper:


    List<Integer> lista = new ArrayList<Integer>();

Autoboxing

Um objeto Integer pode receber um primitivo diretamente, através do Autoboxing:

  Integer i = 15; 


Ou ainda:

    int inteiroPrimitivo = 15; 
        
    Integer k = inteiroPrimitivo; 
        

Ou ainda, nossa lista de Integer pode receber diretamente um valor primitivo, ou usando o construtor recebendo uma String como parâmetro:

    List<int> lista = new ArrayList<int>();

    lista.add(15);
    lista.add(new Integer("40"));


Unboxing

Abaixo, exemplos de Unboxing explícitos e implícitos (automáticos):

 

        int i = 10;

        Integer inteiroWrapper = new Integer(i);  // Boxing Explicito
        int k = inteiroWrapper.intValue();        // Unboxing Explicito

        inteiroWrapper = i; // Boxing Automatico
        k = inteiroWrapper; // Unboxig Automatico


Resumindo, o procedimento de Boxing converte um valor primitivo numa referência do seu correspondente Wrapper (Integer), já no procedimento de Unboxing, a referencia é transformada no tipo primitivo correspondente. 

Abaixo exemplos de outras conversões: 

 
        boolean boolValor = true;
        byte b = 2;
        short s = 2;
        char c = '2';
        int i = 2;

        // Boxing
        Boolean boolReferencia = boolValor;
        Byte bReferencia = 88;
        Short sReferencia = 2;
        Character cReferencia = '2';
        Integer iReferencia = 2;
       // Integer iRef1 = s; // ATENÇÂO!! tipos short não podem ser associados a Integer

        // Unboxing
        boolean boolVal1 = boolReferencia;
        byte b1 = bReferencia;
        short s1 = sReferencia;
        char c1 = cReferencia;
        int i1 = iReferencia;

terça-feira, 15 de abril de 2014

Sistemas Embarcados - Arduino

Palestra UNIFEG (15/03/2014) - Sistemas Embarcados, Arduino


Aproveitando o blog, para postar a apresentação da palestra ministrada no Centro Universitário Fundação Educacional de Ensino de Guaxupé/MG (UNIFEG), sobre Sistemas Embarcados com ênfase na Plataforma Arduino.
Texto bastante básico e explicativo, para que os alunos tivessem o primeiro contato com a plataforma.


segunda-feira, 14 de abril de 2014

Alterando senha SUDO Linux

Este é daqueles comandos que as vezes nos esquecemos e nos fazem falta. 

Para alterar a senha sudo em ambiente Linux abra a janela do Terminal e execute o seguinte comando: 


~$ sudo passwd seu_nome_de_usuario_aqui

Ser á solicitada a nova senha:


Enter new UNIX password: 

Digite e será solicitado que repita a senha:


Retype new UNIX password:

Ao redigitar é exibida a mensagem abaixo e a senha sudo está atualizada!
passwd: password updated successfully

domingo, 13 de abril de 2014

Tutorial Integração Spring Framework e Quartz

Artigo


Agendando Tarefas Utilizando Quartz e Spring Framework


Ano passado, fui convidado pela equipe da Easy Java Magazine a escrever este artigo, que trata sobre como integrar as bibliotecas do agendador de tarefas Quartz em aplicações que utilizem o Spring Framework.

Abaixo o link direto para a página da matéria que saiu na revista Easy Java Magazine #25:


Ler Artigo no Site da Revista


sábado, 12 de abril de 2014

Algoritmo Ordenação Bubble Sort


As linguagens de programações atuais, esbanjam praticidade quando o assunto é ordenação de listas. 

Com pouquíssimas linhas como mostrado aqui em posts anteriores, podemos ordenar nossas listas. 

Para quem gosta de brincar com algoritmos, vamos desenvolver neste pequeno tutorial o Algoritmo Bubble Sort, bastante conhecido. 

É interessante se conhecer a forma de aplicar tais algoritmos, pois não é em todas linguagens que temos tanta praticidade para ordenar listas. 

Conhecer um algoritmo de ordenação, como o Bubble Sort, por exemplo, é uma boa ideia quando se trabalha programando para dispositivos com capacidades computacionais reduzidas como microcontroladores. 

Conhecendo o Algoritmo Bubble Sort

No vídeo abaixo, um grupo de dança demonstra de forma muito bem humorada o funcionamento do Algoritmo Bubble Sort:


O algoritmo consiste basicamente em ordenar um vetor de n posições, a partir de pequenas partes do mesmo.

O algoritmo varre o vetor, ordenando os pares. Como demonstra a figura abaixo:
Após concluir a ordenação por pares, pode ocorrer do vetor ainda não estar ordenado conforme se deseja. Assim sendo o algoritmo deve ser executado de forma recursiva até que a ordenação do vetor se complete. 

Mais informações podem ser encontradas no Site da Wikipedia.

Bubble Sort com JAVA

Abaixo, descrevemos um código que carrega um vetor carregado com números aleatoriamente. 

 /**
         * Preenche o vetor com numeros aleatórios
         */
        for (int i = 0; i < vetor.length; i++) {

            vetor[i] = (int) (Math.random() * 100);

        }
Após executa um método que exibe o vetor (ainda fora de ordem) na tela. 
   /**
    * Metodo que recebe um vetor e exibe o mesmo na tela
    */
    private void exibeVetor(int[] v) {

        System.out.println("\n");

        for (int i = 0; i < v.length; i++) {

            System.out.print(v[i] + " ");

        }
    }
Agora é hora da mágica! O método abaixo ordena o vetor, verificando os valores contidos nos índices e comparando-os com os valores do próximo índice. Caso o valor do índice atual for menor do que do índice posterior, ele inverte a posição dos mesmos, com o auxilio de uma variável de controle. 
     /**
     * Metodo responsavel por varrer o vetor e ordenar os pares
     */
    private void ordenaBubbleSort(int[] v) {

        for (int i = 0; i < v.length; i++) {

            /**
             * Caso o índice atual do vetor for o ultimo, não precisa ordenar
             */
            if (i != v.length - 1) {

                /**
                 * Verifica se os valores não estão em ordem crescente
                 */
                if (!(v[i] <= v[i + 1])) {

                    /**
                     * atribui o valor do indice a uma variavel temporaria
                     */
                    int valorTemp = v[i];

                    /**
                     * coloca o valor do proximo indice no indice atual
                     */
                    v[i] = v[i + 1];

                    /**
                     * atribui o valor da variavel temporaria no proximo indice
                     */
                    v[i + 1] = valorTemp;
                }
            }
        }

        if (!isVetorOrdenado(v)) {

            ordenaBubbleSort(v);

        }
    }
O método abaixo verifica se o vetor esta em ordem.
 /**
     * Metodo que verifica se o vetor está em ordem
     * Retorna 'true' se estiver atualizado
     */
    private boolean isVetorOrdenado(int[] v) {

        for (int i = 0; i < v.length; i++) {
            /**
             * Caso o índice atual do vetor for o ultimo, não precisa ordenar
             */
            if (i != v.length - 1) {
                /**
                 * Verifica se o indice atual e o próximo estão ordenados;
                 *
                 * Caso estejam, checa os proximos indices
                 */
                if (!(v[i] <= v[i + 1])) {

                    return false;

                }
            }

        }
        return true;
    }
Finalmente, acrescentamos o trecho abaixo, no final do método ordenaBubbleSort(), de forma a definir se é ou não necessária a recursão.
     if (!isVetorOrdenado(v)) {

            ordenaBubbleSort(v);

        }

Após, evocamos finalmente o método exibeVetor() para mostrá-lo na tela. 

Abaixo a classe completa, já com o método main();



package bubblesort;

public class BubbleSort {

    /**
     * Constante com o tamanho do vetor a ser criado
     */
    public static final int TAMANHO_VETOR = 11;

    public static void main(String[] args) {

        BubbleSort bubbleSort = new BubbleSort();

        int[] vetor = new int[TAMANHO_VETOR];

        /**
         * Preenche o vetor com numeros aleatórios
         */
        for (int i = 0; i < vetor.length; i++) {

            vetor[i] = (int) (Math.random() * 100);

        }

        bubbleSort.exibeVetor(vetor);

        bubbleSort.ordenaBubbleSort(vetor);

        bubbleSort.exibeVetor(vetor);


    }

    /**
     * Metodo responsavel por varrer o vetor e ordenar os pares
     */
    private void ordenaBubbleSort(int[] v) {

        for (int i = 0; i < v.length; i++) {

            /**
             * Caso o índice atual do vetor for o ultimo, não precisa ordenar
             */
            if (i != v.length - 1) {

                /**
                 * Verifica se os valores não estão em ordem crescente
                 */
                if (!(v[i] <= v[i + 1])) {

                    /**
                     * atribui o valor do indice a uma variavel temporaria
                     */
                    int valorTemp = v[i];

                    /**
                     * coloca o valor do proximo indice no indice atual
                     */
                    v[i] = v[i + 1];

                    /**
                     * atribui o valor da variavel temporaria no proximo indice
                     */
                    v[i + 1] = valorTemp;
                }
            }
        }

        if (!isVetorOrdenado(v)) {

            ordenaBubbleSort(v);

        }
    }

    /**
     * Metodo que verifica se o vetor está em ordem
     * Retorna 'true' se estiver atualizado
     */
    private boolean isVetorOrdenado(int[] v) {

        for (int i = 0; i < v.length; i++) {
            /**
             * Caso o índice atual do vetor for o ultimo, não precisa ordenar
             */
            if (i != v.length - 1) {
                /**
                 * Verifica se o indice atual e o próximo estão ordenados;
                 *
                 * Caso estejam, checa os proximos indices
                 */
                if (!(v[i] <= v[i + 1])) {

                    return false;

                }
            }

        }
        return true;
    }
   /**
    * Metodo que recebe um vetor e exibe o mesmo na tela
    */
    private void exibeVetor(int[] v) {

        System.out.println("\n");

        for (int i = 0; i < v.length; i++) {

            System.out.print(v[i] + " ");

        }
    }
}

Java - Ordenando Listas de Objetos (Object Sort) II - Utilizando Comparator

Nos post anterior falamos de como ordenar objetos em uma lista a partir de um atributo do mesmo. 

Mas e se quisermos permitir diversas formas de se ordenar um objeto?

Para tal, utilizamos a interface Comparator.

Aproveitaremos a mesma classe Pessoa já criada no post anterior  e implementaremos classes internas à mesma. 

Vamos criar modos para ordenar por Sobrenome e por Nome. 

Abaixo a classe interna (inner class) para ordenação por Nome, que deverá ser inserida dentro da classe Pessoa:


  
    /**
     * Classe interna que ordena Pessoa pelo atributo Nome
     */
    public static class OrdenarPorNome implements Comparator<Pessoa>{

        @Override
        public int compare(Pessoa o1, Pessoa o2) {
            
         return o1.getNome().compareTo(o2.getNome());
         
        }
        
    }

Vamos aproveitar e criar outra classe interna (inner class) para ordenação por Sobrenome, que também deverá ser inserida dentro da classe Pessoa:
    /**
     * Classe interna que ordena Pessoa pelo atributo Sobrenome
     */
    public static class OrdenarPorSobrenome implements Comparator<Pessoa>{

        @Override
        public int compare(Pessoa o1, Pessoa o2) {
            
         return o1.getSobreNome().compareTo(o2.getSobreNome());
         
        }
        
    }

Assim, a classe Pessoa deve ficar da seguinte forma, já com a adição das classes internas: 



package br.com.devfacil.model;

import java.util.Comparator;

public class Pessoa implements Comparable<Pessoa> {

    private String nome;
    private String sobreNome;
    private Integer idade;

    public Pessoa(String nome, String sobreNome, Integer idade) {
        this.nome = nome;
        this.sobreNome = sobreNome;
        this.idade = idade;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getSobreNome() {
        return sobreNome;
    }

    public void setSobreNome(String sobreNome) {
        this.sobreNome = sobreNome;
    }

    public Integer getIdade() {
        return idade;
    }

    public void setIdade(Integer idade) {
        this.idade = idade;
    }

    @Override
    public int compareTo(Pessoa pessoaComparacao) {

        int idadeComparacao = ((Pessoa) pessoaComparacao).getIdade();

        /**
         * Ordena as idades de forma Descrescente
         */
        return idadeComparacao - this.idade;
    }

    
    /**
     * Classe interna que ordena Pessoa pelo atributo Nome
     */
    public static class OrdenarPorNome implements Comparator<Pessoa>{

        @Override
        public int compare(Pessoa o1, Pessoa o2) {
            
         return o1.getNome().compareTo(o2.getNome());
         
        }
        
    }
    
    /**
     * Classe interna que ordena Pessoa pelo atributo Sobrenome
     */
    public static class OrdenarPorSobrenome implements Comparator<Pessoa>{

        @Override
        public int compare(Pessoa o1, Pessoa o2) {
            
         return o1.getSobreNome().compareTo(o2.getSobreNome());
         
        }
        
    }
    
}

Vamos modificar agora a classe principal, e a chamada do método Collections.sort() já descrita no post anterior , desta vez, vamos incluir a chamada para as classes internas, como parâmetro do método, conforme o trecho abaixo: 
 

        /**
         *  Ordena por nome
         */
        Collections.sort(listaPessoas, new Pessoa.OrdenarPorNome());


Abaixo, a classe principal do post anterior, já com a adição da chamada para ordenação por nome e sobrenome: 



 
package br.com.devfacil.view;

import br.com.devfacil.model.Pessoa;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class SortListMain {

    public static void main(String[] args) {

        /**
         * Cria lista de Pessoas
         */
        List<Pessoa> listaPessoas = new ArrayList<Pessoa>();

        /**
         * Atribui 'Nome', 'Sobrenome' e 'Idade' fazendo uso do contrutor com
         * parametros de Pessoa(String nome, String sobreNome, Integer idade);
         */
        listaPessoas.add(new Pessoa("Ana", "Dias", 40));
        listaPessoas.add(new Pessoa("Pedro", "Serafim", 30));
        listaPessoas.add(new Pessoa("Maria", "Cavalcante", 58));
        listaPessoas.add(new Pessoa("Beatriz", "Silva", 27));

        /**
         *  Ordena por nome
         */
        Collections.sort(listaPessoas, new Pessoa.OrdenarPorNome());

        System.out.println("\n Lista Ordenada por Nome:");
        for (Pessoa p : listaPessoas) {

            System.out.println("Nome: " + p.getNome() + ", Sobrenome: " + p.getSobreNome() + ", Idade: " + p.getIdade());

        }
        
        /**
         *  Ordena por Sobrenome
         */
        Collections.sort(listaPessoas, new Pessoa.OrdenarPorSobrenome());
        
          System.out.println("\n Lista Ordenada por Sobrenome:");
        for (Pessoa p : listaPessoas) {

            System.out.println("Nome: " + p.getNome() + ", Sobrenome: " + p.getSobreNome() + ", Idade: " + p.getIdade());

        }
    }
}

A saída exibida deverá ser esta:

 


 Lista Ordenada por Nome:
Nome: Ana, Sobrenome: Dias, Idade: 40
Nome: Beatriz, Sobrenome: Silva, Idade: 27
Nome: Maria, Sobrenome: Cavalcante, Idade: 58
Nome: Pedro, Sobrenome: Serafim, Idade: 30

 Lista Ordenada por Sobrenome:
Nome: Maria, Sobrenome: Cavalcante, Idade: 58
Nome: Ana, Sobrenome: Dias, Idade: 40
Nome: Pedro, Sobrenome: Serafim, Idade: 30
Nome: Beatriz, Sobrenome: Silva, Idade: 27

sexta-feira, 11 de abril de 2014

Java - Ordenando Listas de Objetos (Object Sort)

No post anterior, falamos de ordenação de listas, e ordenamos alfabeticamente uma lista de nomes. 

A ordenação alfabética é simples e intuitiva para qualquer leitor, porém, e quando queremos ordenar objetos, que nós mesmos criamos dentro do código? 

Quando queremos ordenar esta lista de objetos, segundo regras criadas por nós mesmos?

Neste breve tutorial, vamos exemplificar o uso da interface Comparable e do metodo compareTo()

Começaremos criando a classe Pessoa possuindo como atributos, Nome, Sobrenome e Idade:



package br.com.devfacil.model;

public class Pessoa {

    private String nome;
    private String sobreNome;
    private Integer idade;

    public Pessoa(String nome, String sobreNome, Integer idade) {
        this.nome = nome;
        this.sobreNome = sobreNome;
        this.idade = idade;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getSobreNome() {
        return sobreNome;
    }

    public void setSobreNome(String sobreNome) {
        this.sobreNome = sobreNome;
    }

    public Integer getIdade() {
        return idade;
    }

    public void setIdade(Integer idade) {
        this.idade = idade;
    }

}

Feito isto criaremos nossa classe principal, com o metodo main(), que criará uma lista de Pessoa,  a preencherá e a ordenará, como no exemplo do post anterior




package br.com.devfacil.view;

import br.com.devfacil.model.Pessoa;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class SortListMain {

    public static void main(String[] args) {

        /**
         * Cria lista de Pessoas
         */
        List<Pessoa> listaPessoas = new ArrayList<Pessoa>();

        /**
         * Atribui 'Nome', 'Sobrenome' e 'Idade' fazendo uso do contrutor com
         * parametros de Pessoa(String nome, String sobreNome, Integer idade);
         */
        listaPessoas.add(new Pessoa("João", "da Silva", 41));
        listaPessoas.add(new Pessoa("Ana", "Dias", 40));
        listaPessoas.add(new Pessoa("Pedro", "Serafim", 30));
        listaPessoas.add(new Pessoa("Maria", "Cavalcante", 58));
        listaPessoas.add(new Pessoa("Beatriz", "Silva", 27));

        Collections.sort(listaPessoas);

        for (Pessoa p : listaPessoas) {

            System.out.println("Nome: " + p.getNome() + ", Sobrenome: " + p.getSobreNome() + ", Idade: " + p.getIdade());

        }
    }
}
Note que na linha que tenta ordenar a lista Collections.sort(listaPessoas); o Java retorna um erro, falando, em linhas gerais, que não consegue ordenar uma lista de objetos do tipo Pessoa, porque não conhece os parâmetros de comparação necessários para ordenar os objetos; em outras palavras, a JVM não sabe se deve ordenar as pessoas da lista por nome, por sobrenome ou pela idade. 

Para solucionar este problema, nossa classe Pessoa deve implementar a interface Comparable, ou seja, 'ser comparável', e sobrescrever o metodo compareTo() da mesma, de modo que este possa determinar o que se deve levar em consideração para ordenar uma lista de pessoas. 

A nova classe Pessoa implementando Comparable é mostrada abaixo: 



package br.com.devfacil.model;

public class Pessoa implements Comparable<Pessoa>{

    private String nome;
    private String sobreNome;
    private Integer idade;

    public Pessoa(String nome, String sobreNome, Integer idade) {
        this.nome = nome;
        this.sobreNome = sobreNome;
        this.idade = idade;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getSobreNome() {
        return sobreNome;
    }

    public void setSobreNome(String sobreNome) {
        this.sobreNome = sobreNome;
    }

    public Integer getIdade() {
        return idade;
    }

    public void setIdade(Integer idade) {
        this.idade = idade;
    }

    @Override
    public int compareTo(Pessoa pessoaComparacao) {
        
      int idadeComparacao = ((Pessoa) pessoaComparacao).getIdade();
      
      /**
       * Ordena as idades de forma Crescente
       */
      return this.idade - idadeComparacao; 
    }

}
Note que o método compareTo() recebe um objeto pessoa e compara o atributo idade, dos objetos.  

Ao executar o metodo main() da classe principal novamente, o erro desaparece, e a saída do programa é a seguinte: 


Nome: Beatriz, Sobrenome: Silva, Idade: 27
Nome: Pedro, Sobrenome: Serafim, Idade: 30
Nome: Ana, Sobrenome: Dias, Idade: 40
Nome: João, Sobrenome: da Silva, Idade: 41
Nome: Maria, Sobrenome: Cavalcante, Idade: 58

As pessoas da lista estão ordenadas com a idade em valores crescentes.

Como exemplo, podemos alterar o metodo compareTo() do objeto Pessoa, de modo a obtermos a ordenação em forma decrescente: 


 @Override
    public int compareTo(Pessoa pessoaComparacao) {

        int idadeComparacao = ((Pessoa) pessoaComparacao).getIdade();

        /**
         * Ordena as idades de forma Descrescente
         */
        return idadeComparacao - this.idade;
    }

O resultado apresentado na tela é este: 



Nome: Maria, Sobrenome: Cavalcante, Idade: 58
Nome: João, Sobrenome: da Silva, Idade: 41
Nome: Ana, Sobrenome: Dias, Idade: 40
Nome: Pedro, Sobrenome: Serafim, Idade: 30
Nome: Beatriz, Sobrenome: Silva, Idade: 27

quinta-feira, 10 de abril de 2014

Java - Ordenando Listas

Trabalhar com listas e vetores (arrays) é vital para qualquer linguagem de programação. 

A linguagem Java possui a poderosíssima API Collections, que nos ajuda a trabalhar com listas, e entre outras funcionalidades bastante interessantes, nos permite ordená-las. 


Ordenando uma lista Simples


Começaremos com um exemplo básico: Uma lista de nomes, cujos valores são adicionados aleatoriamente;


   /**
         * Lista de String's contendo nomes
         */
        List<String> listaNomes = new ArrayList<String>();

        listaNomes.add("Joaquim");
        listaNomes.add("Pedro");
        listaNomes.add("Ana");
        listaNomes.add("Bianca");
        listaNomes.add("Maria");
        listaNomes.add("João");

        /**
         * FOR avançado: para cada String dentro de 'listaNomes' associamos a
         * variável 'nome' e a exibimos na tela
         *
         * Exibe lista na ordem de adição
         */
        for (String nome : listaNomes) {

            System.out.println(nome);

        }
A saída obtida ao executarmos este código, é a seguinte: 
Joaquim
Pedro
Ana
Bianca
Maria
João

Usando o metodo estático sort() de java.util.Collections podemos facilmente ordenar esta lista de nomes. O código abaixo é exatamente igual ao anterior, porem adicionamos  a chamada Collections.sort(listaNomes) : 


     /**
         * Lista de String's contendo nomes
         */
        List<String> listaNomes = new ArrayList<String>();

        listaNomes.add("Joaquim");
        listaNomes.add("Pedro");
        listaNomes.add("Ana");
        listaNomes.add("Bianca");
        listaNomes.add("Maria");
        listaNomes.add("João");

        /**
         * Chamada ao metodo sort()
         * Ordena a lista em ordem alfabética;
         */
        Collections.sort(listaNomes);

        for (String nome : listaNomes) {

            System.out.println(nome);

        }

Ordenando um Vetor (Array)


Em JAVA, os vetores (arrays) também podem ser ordenados de forma bem semelhante:
 

   String[] arrayNomes = new String[]{"Joaquim", "Pedro", "Ana", "Bianca", "Maria", "João"};
        
        /**
         * Exibe a lista de nomes 
         * na ordem que está colocada no vetor
         */
        for (int i = 0; i < arrayNomes.length; i++) {
            
            System.out.println(arrayNomes[i]);
            
        }
        
        System.out.println("\n");
        
        /**
         * Ordena os nomes do vetor
         */
        Arrays.sort(arrayNomes);
        
        
        /**
         * Exibe a lista de nomes 
         * já ordenada
         */
        for (int i = 0; i < arrayNomes.length; i++) {
            
            System.out.println(arrayNomes[i]);
            
        }

terça-feira, 8 de abril de 2014

Ajustando Papel de Parede no Ubuntu 13.10 desconfigurado

Utilizo a versao 13.10 do Ubuntu, com gnome 3.8. 

Ao tentar ajustar o papel de parete (wallpaper) por um de maior resolução, notei que a imagem se apresenta toda desconfigurada, com escala desproporcional à tela. 

Depois de muito tentar e pesquisar na web aqui vai a solução: 

Solução 1: 

- Na janela terminal, execute a seguinte linha de comando: 


sudo gsettings set org.gnome.desktop.background picture-options "scaled"


Onde a opção "scaled" pode ser substituida por: 

wallpaper, centered, stretched, scaled, zoom, spanned. 

Solução 2: 

- Certifique se que tens instalado dconf-editor executando o seguinte comando: 


sudo apt-get install dconf-editor


Feito isto, execute o dconf-editor (que nada mais é que uma interface gráfica para ajustes de configurações gerais de seu ambiente Ubuntu) através do seguinte comando na janela do terminal: 


dconf-editor


Nesta janela, navegue até  org > gnome > desktop > background




Dê duplo clique em picture-options, e escolha a opção que melhor se adapte à sua necessidade: wallpaper, centered, stretched, scaled, zoom, spanned, através do menu pop-up que surge. 

É isso. 



segunda-feira, 7 de abril de 2014

Manipulando Strings em JAVA usando StringBuilder

Quando precisamos trabalhar com objetos do tipo String uma excelente dica é utilizar os métodos da classe java.lang.StringBuilder. 

A documentação oficial da classe StringBuilder pode ser encontrada AQUI.

As classses StringBuilder e StringBuffer possuem os mesmos métodos e características, apenas com a diferença que a primeira não é segura para Threads. 

Abaixo, código simples de concatenação de String de forma dinâmica, melhor prática em relação à concatenação de String utilizando o operador "+=" 



    
        StringBuilder sb = new StringBuilder();


        sb.append("Teste");
        sb.append(" ");
        sb.append("Somente");

        
        /**
         * Retorna o valor concatenado 
         * através do metodo toString()
         */
        System.out.println(sb.toString());


Note que ao final, recuperamos o valor utilizando o metodo toString() da classe StringBuilder

    


       Teste Somente


Abaixo, outro exemplo de utilização de outros métodos da classe StringBuilder; acrescentando a linha: 


    
 sb.reverse();
Obtemos o texto invertido:
  

       etnemoS etseT

domingo, 6 de abril de 2014

Leitura de Arquivos Texto com JAVA

Para realizar a leitura de arquivo texto em disco, (indiferente à extensão) podemos utilizar o método abaixo descrito.

O método lerArquivo() é capaz de verificar a existência do arquivo, e retornar uma String com o conteúdo do arquivo lido. 

O código abaixo realiza a leitura de arquivos em disco: 





    public String lerArquivo() throws Exception {

        File arquivo;
        FileInputStream fis = null;
        String saida = null;
        try {

            arquivo = new File("exemplo.txt");

            /**
             * Verifica se o arquivo existe, caso contrário, lança exceção
             */
            if (!arquivo.exists()) {

                throw new Exception("Arquivo não existe.");

            }

            fis = new FileInputStream(arquivo);

            int ln;

            /**
             * Para cada linha lida do Arquivo, concatena à variáel 'saida'
             */
            while ((ln = fis.read()) != -1) {
                saida += (char) ln;
            }



        } catch (Exception ex) {

            throw new Exception("Erro ao ler arquivo. " + ex.getMessage());

        } finally {
            /**
             * Se o FileInputStream não estiver instanciado, 
             * não há necessidade de fechá-lo
             */
            if (fis != null) {
                fis.close();
                
            }
        }

        return saida;

    }

sábado, 5 de abril de 2014

Gerando Números Aleatórios com Math.random() em JAVA

Muitas vezes precisamos de valores aleatórios em nossas aplicações. 

Em JAVA, a poderosíssima classe java.lang.Math (mais informações AQUI) é capaz de realizar diversas operações com números e ainda nos disponibiliza o método random() que retorna um numero pseudo-aleatório em forma de um valor do tipo primitivo double com sinal positivo entre 0.0 e 1.0.

O Código abaixo demonstra a utilização do metodo random(): 
//
        
        double valorAleatorio = Math.random();
        
        
        //Exibe na Tela
        System.out.println(valorAleatorio);

//


Note que pelos valores serem entre 0.0 e 1.0, por vezes faz-se necessário convertê-los em um inteiro, usando o processo de cast como no código abaixo: 



//

        int valorInt = (int)(Math.random()*100);
        
        
        /**
         * Exibe na Tela
        */
        System.out.println(valorInt);
        

//
Atenção que torna-se necessário multiplicarmos por 100 (como no exemplo, para obtermos valores entre 0 e 100) pois senão obteríamos somente o valor 0. 

sexta-feira, 4 de abril de 2014

Display 7 segmentos com Arduino


Começaremos através deste artigo, nosso primeiro post com soluções para Arduino. 

Neste rápido tutorial, mostraremos como acionar um display de 7 segmentos utilizando a plataforma Arduino. 

Nosso projeto difere-se dos demais, pois utiliza o circuito integrado CD 4511 (datasheet disponível aqui).

O objetivo de se utilizar este CI, é economizar portas de saída do Arduino, pois com  o CD 4511, necessitamos apenas de 4 portas do Arduino, para acionar os 7 segmentos deste display.

Abaixo vídeo demonstrando o circuito em funcionamento:



Note que foi adicionado o efeito de fader para desvanecimento do digito. Para isso, apenas ligamos no pino 10  o anodo comum do display, e variamos a intensidade do brilho, baseado no tempo.

No código, geramos o BCD (para entrada do 4511) usando um array bidimensional onde colocamos todos os dígitos a serem exibidos (de 0 a 9) e  o valor a ser colocado nos 4 pinos de saída do Arduino (1 ou 0) . 

O código ainda exibe na saída serial, a tabela verdade do dígito exibido.

Abaixo o código: 





/*

 Display de 7 segmentos ligado atravs do circuito integrado
 CD 4511
 
 */



const int pinA = 6;   //LSB bit MENOS significativo
const int pinB = 7; 
const int pinC = 8; 
const int pinD = 9;   //MDB bit MAIS significativo

                       //  D C B A
byte digitos[10][4] ={   { 0,0,0,0 },  // = 0
                         { 0,0,0,1 },  // = 1
                         { 0,0,1,0 },  // = 2
                         { 0,0,1,1 },  // = 3
                         { 0,1,0,0 },  // = 4
                         { 0,1,0,1 },  // = 5
                         { 0,1,1,0 },  // = 6
                         { 0,1,1,1 },  // = 7
                         { 1,0,0,0 },  // = 8
                         { 1,0,0,1 }   // = 9
                         };

const int faderPin = 10;



void setup(){

  pinMode(pinA, OUTPUT);   
  pinMode(pinB, OUTPUT);   
  pinMode(pinC, OUTPUT);   
  pinMode(pinD, OUTPUT);  
  
  pinMode(faderPin, OUTPUT);  
  
  Serial.begin(9600);
}  

void loop(){

     
//  CONTAGEM CRESCENTE
//
    for (byte count = 0; count < 10; ++count) {
    
     imprimeBCD(count);
     fadeOut(); 
     delay(500); 
    
   
  }
 
 
  Serial.print("*****************\n\n");
  delay(2000);


}

void imprimeBCD(byte digit) {
  
  byte pin = 9; // pino do MSB bit mais significativo 
  
  Serial.print(digit);Serial.print(",\n ");
                Serial.print("D  C  B  A \n");
  for (byte segCount = 0; segCount < 4; ++segCount) {


    imprimeTabelaVerdade(pin,  digitos[digit][segCount]);
    
    digitalWrite(pin, digitos[digit][segCount]); //envia BCD para 4511
    --pin; // decrementa pino do bit

  }   
   fadeIn(); 


  Serial.print("\n\n");
  
}

void imprimeTabelaVerdade(int p, int estado){

  switch (p) {

  case 6: 

    Serial.print(" ");

    Serial.print(estado);
    Serial.print(" ");
    break;
  case 7: 
    Serial.print(" ");

    Serial.print(estado);
    Serial.print(" ");
    break;
  case 8: 

  
    Serial.print(" ");

    Serial.print(estado);
    Serial.print(" ");
    break;
  case 9: 

   
    Serial.print(" ");

    Serial.print(estado);  
    Serial.print(" ");  
    break;

  }
}


void fadeOut(){

  for(int i = 0; i < 255; ++i)
  {
    analogWrite(faderPin, i);
    delay(5);
  }
  
  digitalWrite(faderPin, HIGH); 

}


void fadeIn(){


   for(int i = 255; i > 0; --i)
  {
    analogWrite(faderPin, i);
    delay(5);
  }
  
    digitalWrite(faderPin, LOW); 
}


Gravação de Arquivos com JAVA

Demonstraremos neste breve tutorial como a tarefa de realizar a Leitura e Gravação de arquivos, utilizando JAVA é relativamente simples. 

Primeiramente veremos o método de gravação.

Este recebe como parâmetro uma String e realiza a gravação da mesma em um arquivo com a extensão .txt

Esta extensão é sugerida, porém não obrigatória. Sinta-se à vontade para colocar o nome do arquivo como preferir. 

O código abaixo, demonstra o método gravaArquivo()
 public void gravaArquivo(String entrada) throws IOException {

        FileOutputStream fos = null;

        try {

            /**
             * Executa Verificação para garantir que o valor de entrada não é nulo
             */
            if (entrada == null || entrada.trim().isEmpty()) {
                throw new IOException("Impossível gravar! Conteúdo Vazio ou nulo");
            }

            
            /**
             * Nome do arquivo a ser gravado.
             */
            File arquivo = new File("exemplo.txt");

            /**
             * O Construtor de FileOutputStream recebe como 
             * primeiro parametro, o conteudo a 
             * ser gravado no arquivo, e 
             * como segundo parametro um booleano, chamado 'append'
             * que determina se, caso o arquivo exista, 
             * o conteudo deva ser concatenado com o ja existente (true)
             * ou sobrescrito (false) 
             */
            fos = new FileOutputStream(arquivo, false);

            fos.write(entrada.trim().getBytes());

        } catch (IOException iex) {

            throw iex;

        } finally {

            fos.close();

        }


Formatando Datas em Java



Ainda falando sobre Datas. 

Muitas vezes precisamos formatar as datas a fim de facilitar a visualização do usuário. 

Utilizaremos neste exemplo a Classe java.text.SimpleDateFormat, que possui diversos métodos para o trabalho com valores de data. 

Basta passarmos um padrão determinado, no construtor de SimpleDateFormat (Ex. "dd/MM/yyyy") e aplicar o método format(), que retorna a String formatada de acordo com o padrão designado anteriormente.

O Código abaixo mostra um exemplo de utilização da Classe SimpleDateFormat, para formatação de Datas:


         /**
          * Captura data atual do Sistema
          *
        Date data = new Date(System.currentTimeMillis()); 
        
        
        /**
         *  Passa padrão "dd/MM/yyyy" para o construtor
         */
   SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy");

System.out.println(formato.format(data).toString());




A tabela abaixo, mostra padrões bastante utilizados com o SimpleDateFormat:

ValorDescriçãoSaída
yAno2014
MMês do AnoApril, 07, 7
dDia do Mês1-31
EDia da SemanaFriday, Sunday
aAM/PMAM, PM
HHora do Dia0-23
hHora AM/PM1-12
mMinutos0-60
sSegundos0-60


Para mais informações sobre os padrões válidos, visite a documentação Oficial JAVA.

quinta-feira, 3 de abril de 2014

Conversão java.util.Date para java.sql.Date

Trabalhar com Datas em JAVA, para o programador iniciante e até mesmo para programadores mais experientes, pode ser uma tarefa um tanto quanto confusa. 


Quando trabalhamos com persistência dos dados em banco, muitas vezes precisamos fazer a conversão entre as classes java.util.Date (quando ainda são atributos de determinado objeto) para java.sql.Date (para persistência ou retorno do Banco de Dados).


Basta utilizar o metodo getTime() da classe java.sql.Date e passar o retorno do mesmo, no construtor do objeto java.util.Date. 


O código abaixo realiza a conversão de  java.sql.Date para  java.util.Date:


   
//


    // Converte java.sql.Date para java.util.Date     

    /*
     *  data do tipo java.sql.Date,
     *  pegando data atual do sistema    
     */

    java.sql.Date dataSql = new java.sql.Date(System.currentTimeMillis());



    /*     
     *  cria novo objeto java.util.Date,
     *  usando o metodo getTime() do java.sql.Date
      */
    java.util.Date dataUtil = new java.util.Date(dataSql.getTime());

    //Exibe na tela
    System.out.println("java.util.Date: " + dataUtil.toString());
    System.out.println("java.sql.Date: " + dataSql.toString());


//
O contrário também é possível.

A classe java.util.Date também possui o método getTime() e o Construtor do objeto da classe java.sql.Date também recebe o retorno, do tipo Long.


O código abaixo realiza a conversão de  java.util.Date para  java.sql.Date:
   
//

    // Converte java.util.Date para java.sql.Date     

    /* 
     *  data do tipo java.util.Date,
     *  pegando data atual do sistema
     */

    java.util.Date dataUtil = new java.util.Date(System.currentTimeMillis());



    /*     
     *  cria novo objeto java.sql.Date,
     *  usando o metodo getTime() do java.util.Date
     */
    java.sql.Date dataSql = new java.sql.Date(dataUtil.getTime());

    //Exibe na tela
    System.out.println("java.util.Date: " + dataUtil.toString());
    System.out.println("java.sql.Date: " + dataSql.toString());


//
É isso.