segunda-feira, 30 de dezembro de 2013

Construindo interfaces gráficas com PySide - MainWindow

Fala pessoal, hoje vamos aprender como construir uma janela principal utilizando o toolkit gráfico PySide.

PySide é uma versão do PyQt com uma licença diferente, para mais informações vide a documentação oficial.

Motivação

Muitas vezes estamos programando alguns scripts Python, mas pela ausência de GUI nao conseguimos mostrar aos nossos pais os programas que fazemos (brincadeira pessoal).

A motivação aqui, é o fato que programas que possuem uma interface, tornam-se mais amigável  e conseguem alcansar um número  maior de usuários e também conseguem facilitar a execução de tarefas dentro do software.

Mostre o código

Agora é a hora legal, onde o Guilherme para de falar e exibe o código, vamos lá? Veja como é o código e confira a explicacao logo em seguida:

Na primeira linha fazemos a importação dos módulos QtGui e QtCore. Logo após criamos uma classe, que herda de QMainWindow.

Dentro da classe temos apenas 3 linhas, a primeira linha declara o construtor da classe ( __init__() ). Na segunda linha temos a chamada ao construtor da classe pai, nesse caso temos uma chamada ao construtor da classe QMainWindow. Na 3 e ultima linha da classe, chamamos o método serWindowTitle, ele tem um parâmetro do tipo str (string). Esse método altera o título da nossa janela.

Feito isso já temos uma janela escrita em PySide, porém, falta ainda um método para criar uma instância da janela, e iniciar a nossa app. Nas ultima linhas definimos o método main (um velho amigo). Na primeira linha do main temos a importação do módulo sys, logo após criamos uma aplicação. Depois criamos uma instância da classe janela, chamamos o método show() para exibi-la, e por fim mandamos a aplicação executar. 

Se você preferir, não precisamos criar o método main e nem importar o módulo sys ... Veja como ficaria:

O resultado final deve ser uma janela parecida com a que temos na imagem a seguir:



Bom é isso ai pessoal, até a próxima!! Bons estudos :)

sexta-feira, 30 de agosto de 2013

Algoritmo produtor / consumidor - Python

Olá pessoal, na aula de SOP (Sistemas Operacionais) da minha faculdade meu professor pediu para que escrevêssemos um algoritmo para simular dois processos (A e B), onde o processo A era um produtor de valores e o processo B era um consumidor de valores.

Também era desejado que os dois processos pudessem operar de forma igual mesmo se os dois possuíssem velocidades diferentes. Exemplo:

[1 caso] Se o processo A (produtor) for mais veloz que o processo B (consumidor) ele deve produzir um número máximo N e logo em seguida dormir. O processo A será ativado novamente quando a lista estiver sem nenhum valor para ser consumido.

[2 caso] Se o processor B (consumidor) for mais veloz que o processo A (produtor) ele deve consumir todo o vetor de valores len(N) e logo em seguida dormir. O processo B (consumidor) será ativado novamente quando a lista estiver preenchida com valores para serem consumidos.

Para fazer esse tarefa usei a linguagem Python, e segue abaixo a minha implementação:
#! /usr/bin/python
# coding:utf-8

from random import randint
from time import sleep
import sys
import os

lista = [] #cria uma lista de valores com nenhum valor inserido
dormir_c = False #flag para desativar/ativar processo B (consumidor)
dormir_p = False #flag para desativar/ativar processo A (produtor)
length_max = int(sys.argv[1]) #tamanho max do vetor

#Processo A (produtor), produz valores para a lista
def produtor():
 global lista, length_max, dormir_c, dormir_p

 if not dormir_p: #verifica se processo está ativo
  while len(lista) < length_max: #verifica se a lista não atingiu seu tamanho máximo
   lista.append(randint(0, 1000)) #adiciona um valor inteiro entre 0 e 1000 à lista
   print 'Olá Sr. Programador eu sou o produtor, olha como está a lista de valores ' + str(lista)
  else:
   print 'Fiz o meu serviço olha como eu deixei a lista cheinha >>> ' + str(lista)
   print 'Agora eu vou tirar uma soneca. [Produtor está tirando uma soneca acorde ele quando a lista estiver vazia] \n'
   dormir_p = True #desativa o processo A
   dormir_c = False #ativa o processo B
   consumidor() #chama o consumidor

#Processo B (consumidor), consome valores da lista      
def consumidor():
 global lista, length_max, dormir_c, dormir_p

 if not dormir_c: #verifica se processo está ativo
  if lista: #verifica se a lista contem valores
   del lista[0] #remove o valor que se encontra no inicio da lista
   print 'Olá Sr. Programador eu sou o consumidor, olha como está a lista de valores' + str(lista)
  else:
   print 'Fiz o meu serviço olha como eu deixei a lista limpinha >>> ' + str(lista)
   print 'Agora eu vou tirar uma soneca. [Consumidor está tirando uma soneca, acorde ele quando a lista possuir valores] \n'
   dormir_c = True #desativa o processo B
   dormir_p = False #ativa o processo A
   produtor() #chama o produtor

while True: #loop infinito
 #inicia a brincadeira
 produtor() 
 consumidor()
 sleep(5) #trava a tela a cada iteração para podermos ver os processos em execução
 print '-----------------------------------------------------------------------------------------------------------------------------------'

Para executar o script, você deve informar o número máximo de itens que a lista pode conter. Esse parâmetro deve ser informado por linha de comando. Desse modo para executarmos nosso script temos que fazer:

user@server$ python algoritmo.py  N

Onde N é um número inteiro aleatório. Quando quiser encerrar a execução basta pressionar Ctrl+C. Espero que gostem do material e até a próxima!

sexta-feira, 23 de agosto de 2013

Atualizando o Firefox no Slackware - Slackware [14]

Olá pessoal, cansado do Firefox 15 que a instalação do Slackware 14 traz por padrão? Hoje vou mostrar como atualizar o seu Firefox para a versão mais atual (no momento em que escrevi esse post estava na versão 23). Vamos laá então.

Atualizando o Firefox

Bom primeiramente você deve baixar a versão do Firefox que deseja instalar em sua máquina diretamente pelo site do fornecedor https://www.mozilla.org/pt-BR/firefox/fx/.

Página de download do navegador mozilla firefox.

Após o termino do download vá até o diretório e descompacte o pacote baixado. Abaixo fiz uma pequena demonstração de como utilizar a linha de comando nesse caso. Veja:

root@user:# su -
root@user:# wget http://https://www.mozilla.org/pt-BR/firefox/fx/ firefox-23.0.1.tar.bz2
root@user:# tar -jxvf firefox-23.0.1.tar.bz2
root@user:# mv firefox firefox-23
root@user:# mv firefox /usr/lib/
root@user:# rm /usr/bin/firefox
root@user:# cd /usr/bin
root@user:# ln -s /usr/lib/firefox-23/firefox firefox
root@user:# rm -r /usr/lib/firefox-15.0.1/

Pronto pessoal, lembrando que tudo isso pode ser feito utilizando a interface gráfica. Basta que você abra o navegador de arquivos pela linha de comando logado como root. Se tudo deu certo a tela de entrada do firefox deve ser esta:
Agora você já sabe como fazer para ter sempre o firefox mais atual em seu sistema operacional :). Até a próxima pessoal o/

sexta-feira, 16 de agosto de 2013

Liberar som para usuário sem privilégios de root [Slackware 14]

Fala pessoal, hoje vou mostrar como liberar o som para usuário comum no Slackware 14. Eu resolvi mudar de SO e apostei minhas fichas no SO do Patrick (criador da distro), como sei que essa distro tem fama por ser leve e muito prática adotei ela como sistema padrão. Nessa transição de SO (Xubuntu p/ Slackware) tive muitas percas e ganhos. Abaixo fiz uma pequena lista delas:

Percas 
  • Central de programas
  • Facilidade para instalação de pacotes via terminal
  • Não ter que compilar pacotes em todas as instalações
Ganhos
  • Velocidade e desempenho
  • Pacotes default completos
  • Estabilidade de SO
Mas como nem tudo são rosas eu tive/tenho vira e mexe um problema aqui e outro acolá. 
Bom chega de conversa vamos fazer o seu som responder ai para que você possa escutar suas músicas e assistir aos seus vídeos. Abra o seu terminal e entre como root:

>> su -
>> [informe sua senha...]

Agora vamos adicionar o seu usuário ao grupo audio, assim ele terá acesso a todos os dispositivos de áudio:

>> usermod -G audio $seu_usuario

Pronto, faça um logoff ou reboot e tudo estará funfando jovem!
Até a próxima pessoal <o/

quarta-feira, 7 de agosto de 2013

Estrutura de dados usando C - Pilha

Olá pessoal, como disse no post biblioteca de estrutura de dados estou criando uma biblioteca para facilitar a vida de programadores que desejam utilizar linguagem C para trabalhar com estrutura de dados, assim como de professores e alunos em sala de aula.

Nesse post irei mostrar como usar a stack.h. Essa biblioteca serve para manipular estrutura de dados do tipo pilha, vamos lá?!

Adicionando a biblioteca em seu arquivo C

Meu objetivo não é dizer o que é uma pilha e nem como ela funciona na memória de seu computador (já estou trabalhando em um post para isso). Hoje vamos aprender como facilitar a sua vida na criação e manipulação de uma pilha.

Primeiramente é necessário que você tenha o código fonte da biblioteca que pode ser obtido no no meu repósitorio de código, feito isso salve em um local de seu HD para que possamos utilizá-lo.

Agora crie um arquivo C para que possamos trabalhar =). Importante: crie o arquivo C no mesmo local onde você salvou o código da biblioteca.

Para adicionar a biblioteca a seu arquivo C use o include passando o caminho em que a mesma se encontra. No nosso caso o arquivo C e o código fonte da biblioteca estão no mesmo local. Veja:
#include "stdio.h" #include "stdlib.h" #include "stack.h"

Declarando uma variável do tipo Pilha e criando uma Pilha

Para declarar uma variável do tipo pilha devemos declarar um ponteiro do tipo Stack, e posteriormente para criar uma pilha na memória devemos chamar a função new( ) que retorna a pilha criada. Veja:

/* Declarando variável do tipo Stack */ Stack* pilha; /* Criando uma Pilha */ pilha = new();
Fácil não é? Pronto com isso temos uma pilha alocada em nossa memória, porém, ela ainda está vazia. Vamos ver como fazemos para inserir valores nessa pilha.

Inserindo e removendo valores da pilha

Até a versão atual da biblioteca (1.0 beta) as estruturas de dados trabalham unicamente com o tipo de dado float. Para inserir valores na pilha temos a função push(Stack*, float), e para remover valores temos a função pop(Stack*). Veja:

/* Adicionando valores a pilha */ push(pilha, 10); push(pilha, 20); push(pilha, 30); /* Removendo valores da pilha */ float item_removido = pop(pilha); printf("%f, foi o item removido \n\n", item_removido);
E ai pessoal está fácil? Nem parece linguagem C? kkkk. Ainda temos mais duas funções que devemos saber trabalhar, digamos que você tenha que listar os valores contidos na pilha ... e agora? Calma pequeno gafanhoto eu também fiz essa função ... ufaa ^_^. E a ultima função é talvez uma das mais importantes, ela será a responsável por liberar o espaço de memória ocupado por sua pilha. Vamos ver como utilizá-las!

Listando valores contidos na pilha, e destruindo a pilha

Algo muito importante quando estamos trabalhando com pilhas é listar os valores que estão contidos na pilha, para fazer isso podemos usar a função show(Satck*), antes de encerrar a nossa aplicação devemos limpar a memória para evitarmos que a mesma fica ocupada com os dados que foram utilizados durante a execução de nosso código. Para destruir a pilha temos a função clean(Stack*). Veja:

/* Exibindo os valores presentes na pilha */ printf("Itens da pilha:\n"); show(pilha); /* Limpando a memória */ clean(pilha);
Pronto pessoal, agora podemos fazer qualquer aplicação C utilizando Pilhas =). Em breve está chegando a versão 2.0, fique ligado no blog. Segue o código completo:

#include "stdio.h" #include "stdlib.h" #include "stack.h" /* Sabemos que para usar a ED de Pilha devemos usar o tipo Stack. * Uma vez que haja uma variável do tipo Stack podemos usar os recursos da stack.h =) */ int main() { /* Declarando variável do tipo Stack */ Stack* pilha; /* Criando uma Pilha */ pilha = new(); /* Adicionando valores a pilha */ push(pilha, 10); push(pilha, 20); push(pilha, 30); /* Removendo valores da pilha */ float item_removido = pop(pilha); printf("%f, foi o item removido \n\n", item_removido); /* Exibindo os valores presentes na pilha */ printf("Itens da pilha:\n"); show(pilha); /* Limpando a memória */ clean(pilha); return 0; }
Bom pessoal e aqui termina mais um post! Se você gostou recomende e assine o nosso feed de noticias para ficar a par das novidades =). Até a próxima!

domingo, 4 de agosto de 2013

Biblioteca de estrutura de dados - Linguagem C

Olá pessoal, no meu tempo livre venho trabalhando em algo que pode ajudar muitos estudantes de programação a entenderem alguns conceitos de estruturas de dados sem quebrarem tanto a cabeça (como eu quebrei kkk).

Eu resolvi criar uma biblioteca (escrita em linguagem ANSI C), para facilitar o uso DA linguagem no ensino aprendizagem da disciplina de estruturas de dados. Como estou programando a biblioteca em meu tempo livre (que não é muito) ela está em sua versão BETA e ainda incompleta.

Na versão atual (versão 1.0) temos incluídos os arquivos headers para trabalharmos com as estruturas de: Pilha, Lista Encadeada, Lista Circular, Lista Duplamente Encadeada, Árvores Binárias e Gráfos (BETA).

Nessa primeira versão cada estrutura pode trabalhar com tipos de dados de pontos flutuantes, porém, já estou trabalhando para que as mesmas trabalhem com qualquer tipo de dados (int, float e char).

O código fonte estará disponível no Github para quem quiser usá-lo =). Abaixo colocarei os links com o How-To para usar a biblioteca com cada uma das estruturas de dados.

Isso é tudo pessoal, e até a próxima. =)

OBS: OS LINKS ESTÃO CEGOS POR ENQUANTO.

Pilhas 
Listas encadeadas 
Listas circulares 
Listas duplamente encadeadas 
Árvores binárias 
Grafos (BETA) 
Link do projeto (Github) 

sexta-feira, 19 de julho de 2013

Python - Ler parâmetros informados por linha de comando

Olá pessoal, hoje vou ensinar como ler parâmetros passados por linha de comando utilizando a linguagem de programação Python.

Muitas vezes quando estamos fazendo algum script para executar uma determinada rotina temos que informar alguns parâmetros de configuração.

Para informar parametros no atraves da linha de comando basta escrevelos após o comando de interpretação assim:

#python aula.py guilherme carvalho python

Quando fazemos isso dizemos para rodar o arquivo aula.py e passamos 3 parametros para esse arquivo que são: guilherme, carvalho e python. Esses argumentos são recebidos como uma lista e podemos usalos dentro de nosso codigo.
Para usá-los devemos importar o modulo sys e informar qual a posição do parâmetro que desejamos recuperar.

import sys fname,lname,lang = sys.args[1], sys.args[2], sys.args[3] print 'My name is ' + fname + lname + ". I'm love " + lang


Você pode utilizar todos os métodos de estrutura lista uma vez que sys.argv é uma lista de parâmetros. Outra informação importante é que o primeiro parâmetro é sempre o nome completo do arquivo sendo executado. Bom pessoal espero que tenham curtido! Até o próximo post.

domingo, 2 de junho de 2013

Funções em Python - Variáveis por referência ou valor?

Olá pessoal, hoje vamos aprender um pouco mais de Python e entender como essa linguagem trabalha com variáveis em chamadas de funções.

Quando estamos escrevendo um programa estruturado certamente iremos construir algumas funções para solucionar algum problema. Em muitas linguagens de programação temos a opção de passar valores por refência ou por valor.

Quando passamos valores por referência estamos na verdade passando o endereço de memória onde a variável original aponta, então quem recebe esse endereço tem o que chamamos de acesso direto e toda alteração feita localmente reflete a variável original uma vez que o endereço apontado pela variável local é o mesmo da original.

Quando passamos por valor a variável local recebe uma "cópia" do valor que a variável original armazena, e toda a mudança que a variável local recebe NÃO é refletida na variável original pois a variável local é apenas uma cópia de seu valor.

Em Python não fazemos essa divisão em valor ou referencia. Em Python tudo é objeto, e quando eu digo tudo é tudo mesmo: 1, 10, 45, 543,  *lista, *tuplas, *dicionários, etc.

Então como fazer essa divisão em Python? Ora, muito simples. Dizemos que temos objetos que são mutáveis e objetos que são imutáveis. Objetos mutáveis como o próprio nome diz são objetos que podem mudar no decorrer da interpretação do código e objetos imutáveis são aqueles que não mudam no decorrer do código. Exemplo de objetos imutáveis: 1, 20, 123. O objeto 1 quando iniciamos o programa é 1 e no final dele continua sendo 1.

Agora objetos que são mutáveis temos: *listas, *dicionário, etc. Uma lista pode começar fazia, e no final da interpretação terminar com 10 elementos.

* Estruturas de dados da linguagem Python.

Persistir mudanças em variáveis externas

E agora vem a pergunta: Como fazer uma variável externa recuperar o valor que foi dado à ela dentro de uma função?.

A primeira coisa a ver nesse caso é se a variável a ser passada é mutável ou imutável. Caso ela seja mutável não é preciso fazer nada, toda a mudança que ela receber na função vai ser refletida a variável original .
def adicionarItem(item, lista): lista.append(item) lista = list() adicionarItem(5, lista) adicionarItem(10, lista) print(lista)
Veja que criamos uma lista, onde valores são inseridos e ao final exibimos e comprovamos que os valores foram inseridos na lista. Agora se a variável for imutável devemos retornar o valor calculado dentro da função para a variável externa, fazendo com que ela receba esse valor. Exemplo:
def incrementar(a): a += 1 return a a = 5 a = incrementar(a) print(a)
Temos uma função cujo o seu propósito é incrementar um ao valor original da variável passada. Criamos uma variável com o valor 5 e logo em seguida estamos chamando a função e atribuindo o valor de retorno a nossa variável. Ao final estamos imprimindo o valor calculado pela nossa função. Nesse caso nada de errado aconteceu e o valor 6 foi mostrado como já era previsto. Mas e se não tivéssemos atribuído esse retorno a variável, será que o resultado seria o mesmo? Vamos testar:
def incrementar(a): a += 1 return a a = 5 incrementar(a) print(a)
Opa agora o resultado que foi mostrado na tela foi o número 5 :s!!! Isso não era para estar acontecendo! Na verdade era, em Python temos uma tabela de objetos onde cada objeto tem um ID. Então quando criamos uma variável ela é uma etiqueta para esse ID que por sua vez faz uma referencia a memória. Então quando a variável é criada ela está etiquetando o ID do Objeto 5, é criada uma outra variável só que localmente e essa aponta para ID 6. Como a variável local não é retornada ela morre ou melhor deixa de existir assim que a função acaba de ser interpretada. Bom pessoal por hoje é só espero que tenham gostado. Bons estudos!!!

Estruturas em C - struct (só o básico)

Olá pessoal, hoje vamos falar de struct (Estruturas). As estruturas existem em linguagem C para agrupar dados de diferentes tipos. Podemos definir estruturas como tipo de dados  que armazenam dados de tipos desiguais.

Nota: Podemos imaginar estruturas como sendo matrizes, porém, ela seria uma matriz turbinada que pode armazenar mais de um tipo de dado.

Criando uma estrutura

Para criar uma estrutura usamos a palavra-chave struct. Quando fazemos isso estamos definindo para o compilador um novo tipo de dado. Exemplo:

struct Relogio { int horas; int minutos; int segundos; };
A definição de uma estrutura não cria nenhuma variável, somente informa ao compilador as características de um novo tipo de dado. A palavra struct indica que um novo tipo de dados está sendo definido e Relogio será a sua entiqueta.

Outra coisa importante a dizer é que nesse exemplo definimos a struct como sendo global, ou seja, ela está acessível em qualquer parte do código. Podemos definir nossa struct dentro de uma função, com isso ela só poderá ser utilizada dentro dessa função pois seu escopo será local e não mais global. Exemplo:

#include <stdio.h>  int main(void) { struct Relogio { int horas; int minutos; int segundos; }; struct Relogio r; printf("\n O ponteiro hora está parado em qual número? \n >>> "); scanf("%d", &r.horas); printf("\n O ponteiro minuto está parado em qual número? \n >>> "); scanf("%d", &r.minutos); printf("\n O ponteiro de segundo está parado em qual número? \n >>> "); scanf("%d", &r.segundos); /* Não estou considerando se a hora é inválida! */ printf("\n Hora lida \n >>> %d:%d:%d", r.horas, r.minutos, r.segundos); return 0; }
No exemplo acima Relogio só pode ser acessado dentro da função principal (main). Por fim dessa introdução ao assunto gostaria de deixar uma definição sobre estruturas:
Uma estrutura é um tipo de dado cujo formato é definido pelo programador.

typedef + struct

Em C temos um recurso para dar novos nomes a tipos de dados que já existem (typedef). Com ele podemos então nomear as nossas estruturas. Podemos utilizar ele de 3 distintas formas, porém, para ser mas breve o possível vou adotar apenas uma forma e levar até o fim desse post.

typedef struct { int horas; int minutos; int segundos; } Relogio; Relogio rolex; /*Declara uma variavel do tipo Relogio*/
Para acessar os membros contidos em nossa struct utilizamos o operador "." (ponto final).
rolex.horas = 1;
Para acessar os membros de uma struct devemos utilizar o operador ponto. Esse operador conecta o nome de uma variável estrutura ao membro dela.

Estruturas aninhadas

Podemos ter uma estrutura que contém outra estrutura. Quando isso ocorre damos o nome de estruturas aninhadas. Para criar uma estrutura aninhada devemos criar todas as estruturas que agregam/compõem outras estruturas afim de suprir essa hierarquia montada:

typedef struct { int notas[3]; } Boletim; typedef struct { char nome[30]; Boletim boletim; } Aluno;
No exemplo acima temos duas estruturas: Boletim e Aluno. A estrutura Boletim possui apenas um membro já a estrutura Aluno possui dois membros, inclusive um de seus membros é do tipo Boletim. Então devido essa dependência devemos definir primeiramente Boletim e depois Aluno.
Para utilizar estruturas contidas em outras estruturas a ideia é a mesma. Devemos acessar os níveis hierárquicos utilizando o operador ponto e depois fazer a atribuição do valor, ou recuperar o mesmo. Exemplo:

typedef struct { int notas[3]; } Boletim; typedef struct { char nome[30]; Boletim boletim; } Aluno; Aluno Guilherme; int main(void) { Guilherme.boletim.notas[i]=10; return 0; }
Pessoal escrevi só o basicão, caso você goste e se interessou pelo assunto deixe seu comentário pedindo uma segunda parte mais avançada que eu farei ... lembre-se só farei se a demanda for alta por isso ajude ai compartilhando. Bons estudos!

domingo, 21 de abril de 2013

Manipulando arquivos XML em Python

Fala pessoal hoje vamos aprender como escrever e ler arquivos XML utilizando a linguagem de programação Python.

Na maioria da vezes temos que salvar informações que os usuários ou sistemas geram. Podemos salvar essas informações de várias formas , seja em um banco de dados, em arquivos de texto, na nuvem, etc. Eu diria que a mais tradicional de todas elas seria salvar em um bom banco de dados como (MySQL, PostgreSQL, Oracle) mas em determinadas aplicações o seu uso é desnecessário ou até mesmo inaplicável. Quando isso ocorre devemos então salvar as informações em arquivos de texto, porém, os arquivos de texto não são lá muito elegantes e legíveis.

Eis então que surge os arquivos XML que podemos definir a grosso modo como sendo arquivos de texto estruturados. O XML é muito utilizado hoje para garantir que dois sistemas possam se interagir normalmente. Um bom exemplo seria o sistema de emissão de nota fiscal online onde a troca de informações entre o sistema proprietário e o sistema da receita federal é toda feita através de arquivos no formato XML.

Escrevendo em formato XML

Para escrever em formato XML utilizando Python podemos utilizar a biblioteca ElementTree que já vem nos pacotes de instalação do interpretador Python.

Para utilizar essa biblioteca primeiramente devemos importa-la :
from xml.etree.ElementTree import Element, ElementTree
Feito isso já podemos utilizar todos os recursos de nossa biblioteca. Todo arquivo XML possui o que podemos chamar de Nó Pai ou simplesmente de root e a partir dele vários desmenbramentos que podem ou não ter filhos e assim sucessivamente. Para criar um root fazemos:
root = Element('Agenda')
Agora a partir do root criamos os sub-nos ou filhos de root:

pessoa = Element('Pessoa') cliente = Element('Cliente', nome='Guilherme', idade='19', peso='71', altura='1.63')
Acima criamos dois filhos de agenda, um chamado pessoa e o outro chamado cliente. Como podemos ver pessoa não possui nenhum atributo enquanto o cliente possui 4 atributos: nome, idade, peso, altura. Quando uma tag não possui atributos dizemos que ela é vazia esse é o caso da tag pessoa.

Ainda temos que dar o comando de escrita, ou seja, o comando que vai criar o nosso arquivo XML. Senão fizermos isso ao final da execução programa não teremos um arquivo gerado. Para gerar/escrever um arquivo XML devemos fazer:

root.append(pessoa) root.append(cliente) ElementTree(root).write('agenda.xml');
Perceba que o comando append foi utilizado em root, isso indica que na estrutura root estamos adicionando duas outras estruturas filhas chamadas sucessivamente de pessoa e cliente. Logo após utilizamos o comando write onde passamos o nome do arquivo que será gerado, caso o arquivo exista o mesmo será atualizado caso contrário um novo arquivo será gerado com o nome que foi passado como argumento.

O nosso arquivo XML tem essa seguinte estrutura:

<Agenda> <Pessoa /> <Cliente altura="1.63" idade="19" nome="Guilherme" peso="71" /> </Agenda>

Lendo arquivos no formato XML

Como já sabemos um arquivo XML tem um Nó (node, raíz). Através desse nó principal podemos descobrir e listar os demais nós presentes em nossa estrutura. Vimos que cada nó contido no root nomeamos de filhos ou sub-nós.

Vejamos como abrir um arquivo XML utilizando o ElementTree:

tree = ElementTree(file='agenda.xml')
Após abrir o arquivo devemos então recuperar o elemento root para então recuperar os seus filhos. Para recuperar o elemento root de um arquivo XML fazemos:
r = tree.getroot()
Agora sabemos que r contém o nó root da nossa árvore XML. Portanto para recuperar os outros nós basta percorrer todos os filhos de root. Para percorrer os filhos de um nó utilizamos:
pessoa = r.find('Pessoa') cliente = r.find('Cliente')
Pronto agora os nós estão armazenados em variáveis possibilitando assim a manipulação. Você pode imprimir tags ou atributos utilizando essa biblioteca, veja como é simples:
print (cliente.tag, cliente.attrib)
Muito simples trabalhar com a linguagem Python não é mesmo? Abaixo segue o código completo para que você possa analisar parte a parte. Um abraço a todos e bons estudos!!! from xml.etree.ElementTree import Element, ElementTree """ Escrevendo os dados em formato XML e gerando o arquivo """ # Criando o nó superior "root" root = Element('Agenda') pessoa = Element('Pessoa') cliente = Element('Cliente', nome='Guilherme', idade='19', peso='71', altura='1.63') root.append(pessoa) root.append(cliente) ElementTree(root).write('agenda.xml'); """ Lendo o arquivo XML que foi persistido pela primeira parte do código """ tree = ElementTree(file='agenda.xml') r = tree.getroot() # Lista os elementos abaixo do root print (r.getchildren()) # Encontra a pessoa pessoa = r.find('Pessoa') # Encontra o cliente cliente = r.find('Cliente') print (cliente.tag, cliente.attrib)

terça-feira, 16 de abril de 2013

Erros comuns que acontecem com iReport




Olá pessoal, hoje vou falar de uma experiência desagradável que tive na minha vida. Vou falar do polêmico iReport. 

O iReport é uma ferramenta para construção de relatórios em vários formatos, tais como: HTML, XLS e PDF. O iReport pode ser utilizado com a linguagem de programação Java ou PHP.

Sem dúvidas o iRepot é uma excelente ferramenta no que se diz respeito à criação de relatórios, porém, seu uso pode acarretar uma experiência não muito agradável. Recentemente utilizei o iReport em um projeto onde tive que criar desde relatórios simples a relatórios mais elaborados. Tive vários probleminhas que tive que descobrir com ajuda de alguns gurus Java e outros que tive que descobrir na raça mesmo.

Por esse motivo fiz um compilado dos problemas que tive na hora de gerar meus relatórios.

  1. Versões diferentes
  2. Fontes diferentes
  3. Gerar .jar 

Versões diferentes

O iReport possui várias versões e nenhuma delas são compatíveis entre si. Se você construir um relatório utilizando a versão 3 e no seu projeto você está utilizando a biblioteca da versão 4 o relatório não irá rodar. O que é no minimo estranho já que sua biblioteca é de uma versão superior a do seu relatório. 

Mas o maior problema não é quando o relatório não roda, o problema começa quando você debuga para achar o erro. Quando você debuga o seu projeto o mesmo diz que não tem nenhum erro e passa normalmente o código, deixando o programador muito confuso já que erros não foram detectados e mesmo assim o seu relatório não abre.

Então se você está desenvolvendo aplicações com iReport e seu relatório não está abrindo fique atento provavelmente a versão do iReport que você incluiu no diretório libs de seu projeto não é a mesma versão do iReport em que o arquivo foi desenhado. 

Fontes diferentes

Parece brincadeira de mal gosto mas é isso mesmo, se seu relatório contem fontes que não estejam instaladas no sistema operacional do cliente ele se quer irá abrir ou muito menos dar uma mensagem de erro. Isso acontece também pelo fato do iReport ser na minha opinião um pouco "ingenuo", ora se a fonte não está instalada no cliente apresente uma fonte padrão da mesma família da fonte não instalada, por exemplo: sans-serif, serif, courier, etc.

Uma dica de quem já quebrou a cabeça com isso. Use somente fontes que você tenha certeza que estejam instaladas no cliente, ou use fontes que sejam genéricas como: sans-serif, serif, etc.

Gerar .jar

Esse é um problema muito frequente em qualquer tipo de aplicação, mas quando você utiliza o iReport ele pode ficar um pouco mais chatinho de resolver. O jar é o executável de um programa Java então todos os arquivos de seu programa estão contidos no jar. Caso você não inclua os arquivos em seu .jar o mesmo não irá executar na máquina cliente ... mesmo se você instalar o iReport na máquina do cliente.

Parece coisa de boçal essa dica mas programadores .NET irão gostar,  pois o Crystal Reports você não libera ele com a aplicação você deve instalá-lo na máquina do cliente.

Bom pessoal por hoje é só e nos vemos no próximo post. Bons estudos!!!

domingo, 14 de abril de 2013

Número arbitrário de argumentos em funções

Fala pessoal, hoje vou mostrar como trabalhar com números de argumentos arbitrários em funções.  Muitas vezes temos que fazer um código onde não sabemos quantos argumentos serão passados quando o código estiver em execução.

Em Python podemos receber tipos arbitrários de funções de duas formas. A primeira seria usando tupla e a segunda usando dicionario.

Relembrando conceitos

Tuplas são listas de dados imutáveis. Quando o programa está em execução não podemos modificar os valores contidos nos índices da tupla, ou seja, se no inicio do programa a posição 1 da tupla armazena o dado 'programado' até o final do programa a posição 1 irá armazenar esse dado.

Dicionários são listas de dados que combinam par de chave valor, ou seja, invés de associarmos indices com dados no dicionário adicionamos chaves com dados. Por exemplo:

programador = 'Guilherme'
(chave)         (dado)

E para recuperarmos o dado devemos informar o nome da chave.

Simples não é mesmo? Bom vamos voltar para a ideia central do post.

Trabalhando com N parâmetros na chamada da função

Bom primeiramente vamos imaginar o seguinte cenário: "Elabore um programa que realize a somatória de N números inteiros e exiba o valor calculado". 

Sabemos que vamos trabalhar com muitos parâmetros, porém, não nos foi informado quantos. Sabemos também que são números inteiros ou seja entre dicionários e tuplas qual devemos escolher? Se você falou tuplas acertou.

Para identificar que um parâmetro é uma tupla basta  adicionar * antes de seu nome. Veja:

def funcao (*args):     pass
Com isso definimos uma tupla com o nome de args. Para chamar essa função basta colocar o seu nome e adicionar os números que deseja somar:

funcao (1,2,3,4,5,6,7,8,9,10)

E para compilar você deve colocar o comando python e logo após o nome do seu arquivo. Veja:

>> python arquivo.py

O que apareceu na sua tela? Exatamente nada rsrsrs!! Calma pequeno gafanhoto isso aconteceu porque não implementamos a somatória dos números. Vamos fazer isso então.

Para percorrer todos os valores de uma tupla podemos usar o comando for, que serve para percorrer um tipo de dado que seja Iterator. E por definição uma tupla é iterável. Para somar todos os dados da tupla devemos fazer:
soma = 0 for nro in args:     soma += nro return soma
Agora podemos chamar a função e imprimir o seu retorno:

print ( funcao(1,2,3,4,5,6,7,8,9,10)) >> 55
Viu como foi simples? Então o que fizemos foi o seguinte. Montamos uma estrutura for e varremos essa estrutura pegando os itens um a um e adicionamos os seus valores na variável local chamada soma. Ao final da função retornamos o valor de soma.
Veja o código completo:

arquivo.py

def funcao(*args): soma = 0 for nro in args: soma += nro return soma print (funcao(1,2,3,4,5,6,7,8,9,10))

Agora vamos trocar de cenário: "Elabora um programa que simule uma agenda telefonica. Onde o usuário deve informar o nome e o número do contato."

Bom acho que isso não podemos resolver com tuplas correto? Bem ainda nos resta o dicionário será que ele pode nos ajudar? Se você respondeu sim ... você acertou!

Para identificar que um parâmetro é um dicionário devemos adicionar ** antes de seu nome. Veja:

def funcao (**kwargs):     pass
Com isso definimos um dicionário com o nome de kwargs. Para chamar essa função basta colocar o seu nome e adicionar os nomes e seus respectivos números (contatos):

funcao(PHP=88888888, Python=77777777, Java=21212121, C=28826718)
Como você já sabe, se executarmos o nosso arquivo nada irá ocorrer pois nada foi implementado não é mesmo? Bom então lets programar pequeno gafanhoto.

Já sabemos que o for consegue percorrer objetos que sejam iteráveis, e adivinha só ... o dicionário é iterável o///. Então o nosso código ficará assim:
arquivo.py
def funcao(**kwargs): print ('Name \t Number ') for contato in kwargs: print ("\n{}\t{}".format(contato, kwargs[contato])) funcao(PHP=88888888, Python=77777777, Java=21212121, C=28826718)
Nossa muito fácil né pessoal nem parece que em poucas linhas de código já montamos uma agenda telefônica '-'. Sério pessoal, podemos pegar esse código e mandar ele salvar em um arquivo .txt e Ulalá teremos uma agenda *-*.

Porém você deve estar muito emocionado agora, sim eu sei que está kkk. Mas e se precisarmos de uma tupla, um dicionário e mais 3 parâmetros em uma mesma função será que isso é possível?

SIM É PLENAMENTE POSSÍVEL =). VEJA:

def funcao (arg1, arg2, arg3, *args, **kwargs):     pass
Cabe aqui uma dica. A tupla deve ficar antes do dicionário e o dicionário deve ser sempre o ultimo argumento.

Pessoal o post terminou :'( ... Bons estudos e até a próxima!!!

terça-feira, 9 de abril de 2013

Trabalhando com vários arquivos *.java

Fala pessoal, hoje vou mostrar como trabalhar com mais de um arquivo (.java) em seus projetos.

Introdução

Quando estamos aprendendo a programar geralmente escrevemos nossos códigos em um único arquivo. Isso é feito para que o aluno não se perca no decorrer de seu aprendizado e trabalhar com um único arquivo é muito mais simples do que trabalhar com vários.
Quando estamos programando no paradigma orientado a objetos muitas vezes (senão sempre) precisamos de mais que um arquivo. Programas grandes costumam possuir vários arquivos onde uma parte do código chama outro parte de código de um arquivo diferente.
Bom visto que para grandes programas temos que usar mais de um arquivo vamos então aprender como programar utilizando mais de um arquivo ... bora lá pé de pano?

Brincando com os arquivos

Vamos imaginar que temos o seguinte problema: Precisamos desenvolver um sistema para uma loja de jóias, essa loja deseja realizar o cadastro de produtos e clientes. Vamos deixar só isso por enquanto pequeno gafanhoto depois retomamos e brincamos mais ;-)

De acordo com o texto acima eu sei que vou ter no mínimo 3 arquivos não é mesmo? O primeiro arquivo seria para escrever código de manipulação de clientes, o segundo de produtos e o terceiro arquivo seria a minha classe principal.

Mais a questão é: "E se eu quiser fazer tudo no mesmo arquivo?". Na tem problema algum em codificar um programa inteiro em um único arquivo, vejamos por exemplo como criar as 3 classes de nosso programa em um único arquivo:


public class TestJoalheria { public static void main() { // CÓDIGO OCULTO } } public class Cliente { // CÓDIGO OCULTO } public class Produto { // CÓDIGO OCULTO }
Esse seria o nosso arquivo único com todas as classes que nosso sistema possui. Veja que não tem problema algum em ter todo o código em um único arquivo. A desvantagem em ter tudo programado em apenas um único arquivo seria a complexidade que o código ganharia. Imagine ter que procurar um erro em um arquivo que tenha 50 classes e o total de linhas seja igual à 100.000 linhas?!

Já que tratar tudo em um arquivo é algo muito complexo, imagine agora se o mesmo programa de 100.000 linhas estivesse divido em 50 arquivos diferentes. É muito mais fácil procurar um erro em um arquivo que você sabe que o erro está ali e esse arquivo tem agora 2000 linhas ... conseguiu enxergar a vantagem pequeno gafanhoto?

Bom vamos ver como ficou o código da Joalheria em vários arquivos? DICA: INCREMENTE FUNCIONALIDADES A MAIS NO SOFTWARE, SEI LÁ CONSTRUA UMA INTERFACE GRÁFICA ... OU DEIXE UM COMENTÁRIO DIZENDO O QUE GOSTARIA QUE EU MODIFICASSE NO CÓDIGO PARA TE AJUDAR MELHOR. BONS ESTUDOS. 

Cliente.java
public class Cliente { private String nome; private int idade; private String endereco; private String telefone; public Cliente(String nome, int idade, String endereco, String telefone) { this.nome = nome; this.idade = idade; this.endereco = endereco; this.telefone = telefone; } public String getNome() { return nome; } public int getIdade() { return idade; } public String getEndereco() { return endereco; } public String getTelefone() { return telefone; } }

Produto.java public class Produto { private String descricao; private float preco; private int estoque; public Produto(String descricao, float preco, int estoque) { this.descricao = descricao; this.preco = preco; this.estoque = estoque; } public String getDescricao() { return descricao; } public float getPreco() { return preco; } public int getEstoque() { return estoque; } }

Joalheria.java import java.util.List; import java.util.ArrayList; public class Joalheria { private List clientesCadastrados; private List produtosCadastrados; public Joalheria() { clientesCadastrados = new ArrayList<>(); produtosCadastrados = new ArrayList<>(); } public boolean adicionarCliente(Cliente cliente) { if (cliente != null) { clientesCadastrados.add(cliente); return true; } return false; } public boolean adicionarProduto(Produto produto) { if (produto != null) { produtosCadastrados.add(produto); return true; } return false; } public List getClientesCadastrados() { return clientesCadastrados; } public List getProdutosCadastrados() { return produtosCadastrados; } public int qtdeClientesCadastrados() { return clientesCadastrados.size(); } public int qtdeProdutosCadastrados() { return produtosCadastrados.size(); } }

TestJoalheria.java import javax.swing.JOptionPane; public class TestaJoalheria { Joalheria joalheria = new Joalheria(); private boolean cadastrarCliente(String nome, int idade, String endereco, String telefone) { return joalheria.adicionarCliente(new Cliente(nome, idade, endereco, telefone)); } private boolean cadastrarProduto(String descricao, float preco, int estoque) { return joalheria.adicionarProduto(new Produto(descricao, preco, estoque)); } private void imprimirClientes() { int qtde = joalheria.qtdeClientesCadastrados(); if (qtde > 0) { System.err.println("Número de clientes cadastrados na base de dados: " + qtde); for (Cliente c : joalheria.getClientesCadastrados()) { System.out.println("Nome: " + c.getNome()); System.out.println("Idade: " + c.getIdade()); System.out.println("Endereço: " + c.getEndereco()); System.out.println("Telefone: " + c.getTelefone()); System.out.println("------------------------------------"); } } else { System.err.println("Nenhum cliente encontrado!"); } } private void imprimirProdutos() { int qtde = joalheria.qtdeProdutosCadastrados(); if (qtde > 0) { System.err.println("Número de produtos cadastrados na base de dados: " + qtde); for (Produto p : joalheria.getProdutosCadastrados()) { System.out.println("Descrição: " + p.getDescricao()); System.out.println("Preço: " + p.getPreco()); System.out.println("Estoque: " + p.getEstoque()); System.out.println("------------------------------------"); } } else { System.err.println("Nenhum produto encontrado!"); } } // Esse cara nada mais é que o método que dá o ponta pé inicial public static void main(String[] args) { int opcao; TestaJoalheria test = new TestaJoalheria(); do { opcao = Integer.parseInt(JOptionPane.showInputDialog("Informe o que deseja cadastrar: \n1-Produtos\n2-Clientes\n\n0-Sair")); if (opcao == 1) { String descricao = JOptionPane.showInputDialog("Entre com a descrição do produto"); float preco = Float.parseFloat(JOptionPane.showInputDialog("Entre com o preço")); int estoque = Integer.parseInt(JOptionPane.showInputDialog("Entre com a quantidade em estoque")); if (!test.cadastrarProduto(descricao, preco, estoque)) { JOptionPane.showMessageDialog(null, "Erro ao cadastrar produto!"); } else { JOptionPane.showMessageDialog(null, "Produto cadasrtrado com sucesso!"); } } else if (opcao == 2) { String nome = JOptionPane.showInputDialog("Entre com o nome"); int idade = Integer.parseInt(JOptionPane.showInputDialog("Entre com a idade")); String endereco = JOptionPane.showInputDialog("Entre com o endereço"); String telefone = JOptionPane.showInputDialog("Entre com o telefone"); if (!test.cadastrarCliente(nome, idade, endereco, telefone)) { JOptionPane.showMessageDialog(null, "Erro ao cadastrar cliente!"); } else { JOptionPane.showMessageDialog(null, "Cliente cadasrtrado com sucesso!"); } } else { JOptionPane.showMessageDialog(null, "Sistema finalizado!!!"); } } while(opcao != 0); test.imprimirProdutos(); test.imprimirClientes(); } }

terça-feira, 26 de março de 2013

Encapsular campos em Python 3.x

Encapsulamento de dados é um recurso presente em linguagens que seguem o paradigma orientado a objetos. Esse recurso tem como objetivo restrigir o acesso direto a informação, ou seja, ele protege informações que não devem ser alteradas em qualquer parte do programa. Com isso podemos entender que quem está de fora apenas sabe que o serviço é realizado mas não sabe como o serviço é implementado.

Certamente quando começamos a programar orientado a objetos não vemos os benefícios que o encapsulamento de dados nos proporciona, pois, a primeira vista ele só serve para gerar mais linhas de código.

Hoje vou falar como encapsular dados na linguagem de programação Python versão 3.x. Se você já programou em alguma linguagem .Net (Visual Basic, C#) não sentirá grandes mudanças, porém, se você é um programador Java sentirá uma certa estranheza quando ler o código.

Bom sem mais demora vamos conhecer mais um pouquinho da linguagem Python e sua implementação diferente em POO.

Protegendo minhas variáveis dos Noobs

Na minha opinião o encapsulamento de dados existe, porém, não garante a total segurança do seu código. Antes de você me chamar de louco vou explicar, se você é um programador Java e ficou muito ofendido com o que eu disse ... me desculpe essa não foi a intenssão! Mas Sr.Programador Java, seu código não está seguro só porque o Sr. usa o modificador de acesso private em suas variáveis de instância, se alguém quiser saber quais são as variáveis presentes em determinadas classes de seu sistema ele pode fazer isso utilizando a própria API do Java a nossa querida Reflection. Logicamente que trabalhar com essa API não é algo trivial, porém, pense duas vezes antes de desafiar um nerd dizendo que seu código está 100% seguro.

Em Python a história também não é diferente, se alguém quiser saber quais variáveis sua classe tem essa pessoa vai acabar descobrindo de um jeito ou de outro. Por isso que a ideia principal de Python é que tudo seja public e somente o necessário, seja private. Muitas vezes quando estamos aprendendo POO o pessoal costuma dizer: "Grande parte das vezes sua classe terá atributos de instância privado e métodos públicos". Mais nem sempre é assim, podemos realmente ter variáveis em nossas classes que não precisam serem private.

Bom, se você está certo que precisa ter variáveis private em sua classe e não quer que ela seja acessível fora da classe onde ela foi especificada, então você terá que informar primeiramente que ela será private, para que o interpretador Python saiba disso. Para dizer que um atributo de instância é private em python utilizamos dois underline antes do nome da variável. Exemplo:

class Gato:
    __raca = None
    ...

Com isso dizemos ao interpretador que o atributo raça é privado. Agora temos que construir dois métodos, um para setar (setter) e outro para recuperar (getter) o valor do atributo. No python 3.x foi introduzida uma sintaxe muito elegante para realizar esse serviço. Veja:

class Gato:
    def __init__(self):
        __raca = None

    @property
    def raca(self):
        return __raca

    @raca.setter
    def raca(self, value):
        self.__raca = value

Viu como é simples? Bom o que fizemos foi definir dois métodos (em python pode-se falar função da classe), onde no primeiro definimos o getter e o segundo o definimos o setter. Observe que os dois métodos tem o mesmo nome, mas possuem anotações diferentes. A primeira anotação @property indica o método é um getter e a segunda anotação @raca.setter indica que o método é um setter,  perceba que a segunda anotação é bem diferente da primeira, nela devemos informar o nome do atributo seguido de ponto e a palavra setter.

Podemos definir que um atributo seja apenas read-only. Para fazer isso basta excluir o método setter. Veja:

class Gato:
    def __init__(self):
        __raca = None

    @property
    def raca(self):
        return __raca

Agora observe como fica natural o acesso aos atributos:

if __name__ == '__main__':
    mimo = Gato()
    megui = Gato()

    mimo.raca = 'angorá turco'
    mimo.idade = 2

    megui.raca = 'siames'
    megui.idade = 1

    print('Megui é da raça {}, e tem {} ano(s) de idade.'.format(megui.raca, megui.idade))
    print('Mimo é da raça {}, e tem {} ano(s) de idade.'.format(mimo.raca, mimo.idade))

Pessoal o post se encerra por aqui! Espero que tenham gostado de aprender um pouco mais sobre Python e veja vocês em um próximo post, até lá e BONS ESTUDOS!

terça-feira, 19 de março de 2013

MinhaString & MinhaData

Fala pessoal, se você acompanha o blog e quando lê esses posts que não explicam absolutamente nada e que apenas possuem códigos e enunciados saiba que eles fazem parte das listas de exercícios da faculdade que eu curso (Instituto Federal de Educação, Ciência e Tecnologia de São Paulo - campus Araraquara). Bom hoje vou postar mais um  desses exercícios, porém, leia o código copie e execute ai na sua máquina, aproveite para brincar e descobrir o que ele faz ... isso te dará um conhecimento extra que muitas vezes deixamos escapar em uma explicação mais formal. Beleza?!

Enunciados:


A classe MinhaData está muito simples, implemente as seguintes melhorias:
  • Não permitir que uma data inválida seja instanciada. Caso tente-se instanciar uma data inválida instancie 01/01/1900.
  • Implemente um construtor que aceite várias ordens de argumentos parainstanciar uma data. Por exemplo, o mesmo construtor deve receber osseguintes dados: (1, 2, 1900) ou (1900, 2, 1) e instanciar a data 01/02/1900.
  • Implementar um método que retorne a data por extenso.
  • Implementar um método que retorne a quantidade de dias entre a data instanciada e uma data passada como argumento.
A classe MinhaString:
  • Sabe-se que em Java ou mesmo em C não existe um tipo primitivo para armazenar uma String. Implemente a classe MinhaString que permita manipular um conjunto de até 256 caracteres. Implemente todas as funcionalidades que acharem interessante para esta classe, como por exemplo: converter para maiúsculo, inverter o texto, comparar dois textos.

MinhaData.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package logica;

/**
 *
 * @author guilherme
 */
public class MinhaData {
    private int dia;
    private int mes;
    private int ano;

    public MinhaData(int param1, int param2, int param3, String mascara) {
        organizaValores(mascara, param1, param2, param3);
    }

    private void confereData(int dia, int mes, int ano) {
        boolean dataValida = true;
     
         /* Verifica ano */
        if(ano < 0) {
            dataValida = false;
        } else {
            this.ano = ano;
        }
     
        if(mes < 0 || mes > 12) {
            dataValida = false;
        } else {
            this.mes = mes;
        }
     
        /* Verifica se o dia é válido */
        if(dia > 1 && dia < 31) { //verifica se o dia não é negaivo
            if(mes == 2) {
                if(dia < 28 || (dia == 29 && anoBissexto(this.ano))) {
                    this.dia = dia;
                } else {
                    dataValida = false;
                }
            } else if(mes == 1 || mes == 3 || mes == 5 || mes == 7 || mes == 8
                    || mes == 10 || mes == 12) {
                    this.dia = dia;
            } else {
                if(dia > 30) {
                    dataValida = false;
                }
                this.dia = dia;
            }
        } else {
            dataValida = false;
        }
     
        /* Se a data não for válida então aplica-se a data padrão */
        if(!dataValida) {
            this.dia = 1;
            this.mes = 1;
            this.ano = 1990;
        }
     
    }
 
    private boolean anoBissexto(int ano) {
        if(ano % 4 == 0 && (ano % 100 != 0 || ano % 400 == 0)) {
            return true;
        }
        return false;
    }
 
    public String imprimeData(String padrao) {
        switch(padrao.toLowerCase()) {
            case "pt-br":
                return dia + "/" + mes + "/" + ano;
            case "us":
                return ano + "-" + mes + "-" + dia;
            default:
                return null;
        }
    }

    private void organizaValores(String mascara, int param1, int param2, int param3) {
        switch(mascara) {
            case "ymd":
                confereData(param3, param2, param1);
                break;
            case "ydm":
                confereData(param3, param1, param2);
                break;
            case "myd":
                confereData(param2, param3, param1);
                break;
            case "mdy":
                confereData(param2, param1, param3);
                break;
            case "dmy":
                confereData(param1, param2, param3);
                break;
            case "dym":
                confereData(param1, param3, param2);
                break;
            default:
                confereData(0, 0, 0);
                System.out.println("Esse formato não existe!");
        }
    }

    public String dataPorExtenso() {
        String[] meses = {"janeiro", "fevereiro", "março", "abril", "maio", "junho"
        ,"julho", "agosto", "setembro", "outubro", "novembro", "dezembro"};
     
        return String.valueOf(dia) + " de " + meses[mes - 1] + " de " + String.valueOf(ano);
    }
 
    public double qtdeDeDias(MinhaData data1, MinhaData data2) {
     
        int[] nroDiasMes = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int dias = 0;
 
        for(int i=0; i<data1.ano; i++) {
            if(anoBissexto(i)) {
                dias += 366;
            } else {
                dias += 365;
            }
        }
     
        for(int i=0; i<data1.mes; i++) {
            dias += nroDiasMes[i];
        }
     
        for(int i=0; i<data1.dia; i++) {
            dias += 1;
        }
     
        for(int i=0; i<data2.ano; i++) {
            if(anoBissexto(i)) {
                dias -= 366;
            } else {
                dias -= 365;
            }
        }
     
        for(int i=0; i<data2.mes; i++) {
            dias -= nroDiasMes[i];
        }
     
        for(int i=0; i<data2.dia; i++) {
            dias -= 1;
        }
     
     
        return Math.abs(dias);
    }

}


MinhaString.java
package logica;

/**
 *
 * @author guilherme
 */
public class MinhaString {
    char[] str;

    public MinhaString(char[] str) {
        this.str = str;
    }
   
    public int tamanho(char[] str) {
        int tamanho = 0;
        for(char c : str) {
            ++tamanho;
        }
        return tamanho;
    }
 
    public char[] concatena(char[] str) {
        int tam = tamanho(str) + tamanho(this.str);
        char[] aux = new char[tam];
     
        for(int i = 0; i < tamanho(this.str); i++) {
            aux[i] = this.str[i];
        }
     
        for(int i = tamanho(this.str), j = 0; i < tam; i++, j++) {
            aux[i] = str[j];
        }
     
        this.str = aux;
     
        return this.str;
    }
 
    public char[] maiuscula() {
        char[] aux = str;
        for(int i=0; i < tamanho(aux); i++) {
            if(str[i] > 96 && str[i] < 123) {
                str[i] -=32;
            }
        }
        return this.str;
    }
 
    public char[] minuscula() {
        char[] aux = str;
        for(int i=0; i < tamanho(aux); i++) {
            if(str[i] > 64 && str[i] < 91) {
                str[i] +=32;
            }
        }
        return this.str;
    }
 
    public char[] inverte() {
        int tam = tamanho(str);
        char[] x = espelha(str);
        for(int i=tam-1, j=0; i > -1; i--, j++) {
            str[j] = x[i];
        }
        return this.str;
    }
 
    public char[] trocarCaracter(char caracterAntigo, char caracterNovo) {
        char[] aux = espelha(str);
        for(int i=0; i<tamanho(aux); i++) {
            if(str[i] == caracterAntigo) {
                str[i] = caracterNovo;
            }
        }
        return str;
    }
 
    public char[] subString(int x, int y) {
        int tam = tamanho(str);
        if( (x >= 0 && x <= tam) && (y >= 0 && y <= tam) ) {
         
            char[] aux = new char[y - x];
         
            for(int i=x, j=0; i<y; i++, j++) {
                aux[j] = this.str[i];
            }
         
            return aux;
        }
        return this.str;
    }
 
    public int comparar(char[] str1, char[] str2) {
        /*
         *  0  são iguais
         *  1  maior
         * -1  menor
         */
     
        int t1 = tamanho(str1);
        int t2 = tamanho(str2);
     
        if(t1 > t2) {return 1;} else if(t2 > t1) {return -1;}
        else {
            for(int i=0; i<t1; i++) {
                if(str1[i] > str2[i]) {
                    return 1;
                } else if(str2[i] > str1[i]) {
                    return -1;
                }
            }
            return 0;
        }
    }
 
    public void valueOf(char[] str) {
        for (char c : str) {
            System.out.print(c);
        }
    }
 
    private char[] espelha(char[] str) {
        int tam = tamanho(str);
        char[] x = new char[tam];
        for(int i=0; i<tamanho(str); i++) {
            x[i] = str[i];
        }
        return x;
    }
 
}
Bom pessoal postei para ajudar e não para copiar, a intenção é evolução e não regressão beleza!? Bons estudos!

MinhaData versão Python

Fala pessoal, estava de boa aqui em casa e resolvi programar um pouco em Python. Implementei a classe MinhaData que originalmente foi escrita em Java.
Quando executei descobri um agravante, o código em Java estava cortando o resultado quando as datas passadas eram muito distantes. Já em Python não tive esse problema e a execução do código também se mostrou mais rápida ... o que o Java fazia em x minutos Python fazia em x/2.
Vamos ver como ficou? Segue o código ai:

MinhaData.py
#-*- encoding: utf-8 -*- import timeit class MinhaData(): def __init__(self, dia, mes, ano): self.dia = dia self.mes = mes self.ano = ano def isBissexto(self, ano): if ano % 4 == 0 and (ano % 100 != 0 or ano % 400 == 0): return True return False def calcDias(self, d1, d2): return abs(self.qtdeDias(d1) - self.qtdeDias(d2)) def qtdeDias(self, data): nroDiasMes = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] dias = 0 for dia in range(1, data.dia+1): dias += 1 for mes in range(data.mes): dias += nroDiasMes[mes] for ano in range(1, data.ano+1): if self.isBissexto(ano): dias += 366 else: dias += 365 return dias if __name__ == '__main__': d1 = MinhaData(21,03,2013) d2 = MinhaData(21,03,1994) print('Intervalo de',d1.calcDias(d1, d2), 'dia(s)')

Pessoal estou preparando um post juntamente com o Guilherme Bueno onde comparamos o desempenho das linguagens de programação: Java, C/C++ e Python executando um mesmo algoritmo ... aguadem. Bons estudos!!!

terça-feira, 12 de março de 2013

Realizando leitura com System.in.read

Fala pessoal, hoje vou mostrar como realizar a leitura do teclado utilizando System.in.read(). Então teremos hoje mais um post dedicado aos programadores Java e ao pessoal que gosta de Java. Gostaria de alertar que a partir do Java 5 a leitura do teclado é feita com a classe Scanner do pacote java.util.Scanner.

Realizando leitura do teclado sem utilizar a classe Scanner

Como dito anteriormente nas versões anteriores da Java 5 a leitura do teclado exigia um certo esforço do programador. Antigamente o programador utilizava o método System.in.read() que retorna um InputStream bufferizado. Então o programador pegava este buffer retornado e convertia-o para caracter para que ele pudesse converte-lo para os demais formatos.

Exemplos práticos

Vou utilizar dois problemas apresentados na aula de POO do IFSP campus Araraquara curso ADS para ilustrar como é feita a leitura utilizando a classe System.in.read().
  1. Construa um programa Java que leia o ano de nascimento do usuário e calcule a idade do mesmo;
  2. Construa um programa Java que leia uma sigla para sexo (M/F) e depois apresente no console o sexo lido;
    Atenção: A leitura do teclado deve ser realizada com o método System.in.read();

SysRead2.java
import java.io.IOException; public class SysRead2 { public static void main(String[] args) throws IOException { byte[] aux = new byte[4]; System.out.println("Informe seu ano de nascimento: "); System.in.read(aux); int anoNascimento = Integer.parseInt(new String(aux, "UTF-8")); System.out.println("Idade: " + (2013 - anoNascimento)); } }

SysRead3.java
import java.io.*; public class SysRead3 { public static void main(String[] args) throws IOException { byte sexo; System.out.println("Informe o sexo M/F: "); sexo = (byte) System.in.read(); System.out.println("Sexo digitado: " + (char)sexo); } }

Dúvidas e sugestões deixem comentários, Bons estudos.

domingo, 3 de março de 2013

Porque não utilizar o DefaultTableModel

Olá pessoal, hoje vamos falar de TableModel e porque não devemos utilizar o DefaultTableModel em sua JTable.
Para que o leitor compreenda o assunto tratado é necessário que o mesmo tenha conhecimento dos princípios básicos de POO e que conheça o funcionamento do toolkit para construções gráficas swing.

Nem sempre o modelo pronto é o mais fácil

Muitas vezes quando estamos trabalhando com JTable não nos preocupamos em implementar o modelo da Table e simplemente utilizamos o modelo padrão (DefaultTableModel). O DefaultTableModel é um modelo padrão utilizado para que o programador possa adaptá-lo a suas necessidades. Mas nem sempre adaptar esse TableModel padrão é uma boa escolha, na maioria das vezes o DefaultTableModel deixará o desempenho da aplicação comprometido assim como a segurança da mesma.

A situação pode ficar ainda pior, vamos supor que você tenha feito um software a 3 anos atrás e nesse software você persistio as informações com JDBC, porém, agora você deseja migrar para um ORM de sua proferencia, por exemplo Hibernate. Você terá que percorrer linha por linha da JTable e mapear as informações para objetos e depois montar um List para então poder salvar os dados contidos em sua JTable.

Por esse e outros motivos a melhor solução seria a implementação de um TableModel para cada JTable de sua aplicação e abolir de vez o uso do DefaultTableModel.

Implementando um TableModel simples

Sempre quando procuramos ajuda na Internet o pessoal escracha o DefaultTableModel e manda a pessoa implementar um TableModel e se quer diz como a pessoa deve fazer.

Veja a implementação de um TableModel para sua JTable:


public class TableModelOrdemServico extends AbstractTableModel { private String[] colunas = new String[]{"Descrição", "Qtde"};//aqui vc coloca os nomes que iram aparecer na coluna de sua JTable, o número de colunas é igual ao número de elementos que contem no Array private Class[] classeColuna = new Class[]{String.class, Integer.class};//aqui vc coloca o tipo de dado que cada coluna armazena. Os tipos suportados são: Integer, Double, String e Object. private List linhas;//Cada elemento do List representa uma linha da JTable, então quando um novo elemento é adicionado na tabela ele também é adicionado no List. public TableModelOrdemServico() { linhas = new ArrayList<>(); } public TableModelOrdemServico(List listaDeItensDeVenda) { this(); linhas.addAll(listaDeItensDeVenda); } @Override public String getColumnName(int columnIndex) {//Retorna o nome da coluna return colunas[columnIndex]; } @Override public int getColumnCount() {//Retorna o número de colunas que seu modelo tem. Repare que o número de colunas é igual ou tamanho do Array. return colunas.length; } @Override public int getRowCount() {//Retorna o número de linhas que o modelo da tabela tem. Repare que o número de elementos corresponde ao número de linhas do modelo return linhas.size(); } @Override public boolean isCellEditable(int rowIndex, int columnIndex) {//Retorna qual célula da tabela é editável, nesse exemplo nenhuma célula é editável return true; } @Override public Class getColumnClass(int columnIndex) {//Retorna a classe da coluna selecionada return classeColuna[columnIndex]; } @Override public Object getValueAt(int rowIndex, int columnIndex) {//Retorna o valor contido da célula OrdemServico o = linhas.get(rowIndex); switch(columnIndex) { case 0: return o.getDescricao(); case 1: return o.getQtde(); default: return null; } } @Override public void setValueAt(Object obj, int rowIndex, int columnIndex) {//Modifica/Atualiza o valor contido na célula. OrdemServico o = linhas.get(rowIndex); switch(columnIndex) { case 0: o.setDescricao(obj.toString()); break; case 1: o.setQtde(Integer.parseInt(obj.toString())); break; case 2: o.setQtde(Integer.parseInt(obj.toString())); break; } fireTableDataChanged(); } //Os métodos listados acima devem ser reescritos em cada classe que extenda AbstractTableModel (se vc não entende o que a palavra extends representa em Java leia sobre Herança aqui no Blog temos um POST explicando sobre o assunto). //Você ainda pode implementar quantos métodos forem necessários para sua aplicação

Espero que tenham gostado e até a próxima pessoal.

domingo, 27 de janeiro de 2013

Programando em Java - parte 15

Métodos e classes finais (final)

Você deve estar se lembrando do modificador final que é utilizado em variáveis quando desejamos que o valor seja o mesmo durante toda a execução do programa (constantes). Além de poder ser utilizado em variáveis podemos utilizar esse cara em métodos e classes.

Métodos

Métodos final não podem ser sobrescritos nas subclasses que implementam sua superclasse. Uma declaração do método final nunca pode mudar, sendo assim todas as subclasses utilizam a mesma implementação do método.

final void parar() { //lógica para parar o que você quiser }

Classes

Uma classe final não pode ser estendida. Esta é uma medida de segurança da linguagem Java que impede a criação de subclasses mal-intencionadas afim de driblar a segurança do sistema.

public final class Autor { //essa classe não pode ser superclasse }
Chegamos ao final de mais um assunto, espero que tenham gostado de aprender sobre classes e métodos finais. Até a próxima.

Programando em Java - parte 14

Classes abstratas

Já vimos que em Java podemos criar classes genéricas e estende-las criando classes mais especificas (herança). Também vimos que podemos modificar os comportamentos da classe padrão em cada classe especifica (polimorfismo). Na maioria das vezes a função da classe genérica é apenas fornecer um "modelo" para que as classe filhas implementem, sendo assim não seria necessária a instanciação dessa classe genérica.

Em Java podemos criar classes que não podem ser instanciadas. Dizemos que temos dois tipos de classe: concretas (podem ser instanciadas) e não concretas (não podem ser instanciadas). Para criar uma classe abstrata em Java utilizamos a palavra reservada abstract.

Uma classe abstrata pode conter métodos abstratos e métodos não abstratos, porém, uma classe que não é abstrata não pode conter nenhum método abstrato. Métodos abstratos não fornecem implementações.

A classe concreta que implementar a superclasse abstrata deve implementar os métodos abstratos da mesma. Construtores e métodos estáticos (static) não devem ser abstratos. O construtor não é herdado, portanto nunca seria sobrescrito. Métodos estáticos não podem ser reescritos portanto não faz sentido que o mesmo seja abstrato.

Exemplo:

Criação da classe abstrata Transporte.
public abstract class Transporte { String cor, int ano; abstract void parar(); }
Criação da classe Moto.
public class Moto extends Transporte { String cor, int ano; @Override void parar() { //lógica para parar a moto } }
Criação da classe Navio.
public class Navio extends Transporte { String cor, int ano; @Override void parar() { //lógica para parar o navio } }
Com isso garantimos que todas as classes que implementarem a classe Transporte implementaram o método parar. Bom com isso encerramos mais um conteúdo, até a próxima pessoal.

sexta-feira, 25 de janeiro de 2013

Python 3 - Leitura de dados com input()

Introdução

Olá pessoal, ultimamente venho estudando a linguagem de programação Python. Quando iniciei meus estudos o Python estava em sua versão 2.7. Nessa versão criei toda a minha base que tenho hoje de Python, porém, o Python foi atualizado para a versão 3. Nessa versão algumas funções foram modificadas consequentemente o modo de utilizá-las também. Hoje foi falar da função de capturar entradas do teclado.

Python 2

Na versão anterior (usada em vários sistemas) para se capturar entradas do teclado era necessário utilizar a função raw_input(). A função raw_input() retorna uma string que pode ser convertida em qualquer tipo númerico de Python. Exemplo:

nome = raw_input('Entre com o nome : ') idade = int(raw_input('Entre com a idade : ')
A primeira linha retorna uma string com o nome que o usuário digitou. A segunda linha retorna uma string com a idade digita e logo em seguida a função int() converte essa string para um valor número inteiro.

Python 3

Na versão 3 do Python a função raw_input() mudou de nome e passou a se chamar apenas input(). A ideia original na versão 3 do Python era que as funções input e raw_input() deixassem de existir. Se isso acontecesse uma simples ação de ler dados do teclado seria algo assim:

import sys print ('Entre com o nome : ') nome = sys.stdin.readline()
Muito mais trabalhoso não é mesmo!!! Portanto a escolha foi substituir raw_input() por input(). Veja como ficaria:

nome = input('Entre com o nome : ') idade = int(input('Entre com a idade : ')
Bom é isso ai galera, se você gosta de Python, Java e programação em geral continue acompanhando o blog. Deixe o seu comentário!!! Abs.

Métodos - Parâmetros com tamanho indefinido

Introdução

Olá pessoal, muitas vezes estamos construindo uma aplicação em que não sabemos exatamente quantos parâmetros de um mesmo tipo o método vai ter em sua chamada (quando ele for acionado). Para solucionarmos este problema poderiamos declarar um vetor do tipo que desejado e passá-lo como parâmetro, porém, em Java temos uma forma mais elegante de se passar um número de parâmetros indefinido para os métodos. Vejamos como podemos faze-lo.

Passando um número indefinido de parâmetros

Como dito anteriormente a linguagem Java suporta a passagem de um número indefinido de parâmetros. Para fazer isso basta utilizar três pontos ( ... ) após a declaração do tipo da variável e logo após dos três pontos colocar o nome da variável. Quando isso é o compilador cria um array contendo os valores que foram passados por parâmetro. Exemplo:

public class App { static void tabuadaDo2(int ... num) { for(int n : num) { System.out.println(n + " x 2 = " + n*2); } } public static void main(String[] args) { tabuadaDo2(2,3,4,5,6,7,8,9,10);//podemos chamar passando os valores 1 à 1 tabuadaDo2(new int[]{1,2,3,4,5,6,7,8,9,10}); } }

Só é permitida a inclusão de uma parametro indefinido por método, pois, o parametro indefinido deve estar no fim do método (ultimo a ser declarado).  Exemplo;

public class App { static void tabuadaDo2(int ... num, double ... numeros) {//não compila for(int n : num) { System.out.println(n + " x 2 = " + n*2); } } public static void main(String[] args) { tabuadaDo2(2,3,4,5,6,7,8,9,10);//podemos chamar passando os valores 1 à 1 int[] list = {2,3,4,5,6,7,8,9,10}; tabuadaDo2(list); } }

É importante ressaltar que apenas variaveis indefinidas tem que serem unicas! Portanto um parametro indefinido pode fazer parte de um metodo que tenha mais de uma variavel de parametro. Exemplo:

public class App { static void tabuadaDo2(double numeros, int ... num) { for(int n : num) { System.out.println(n + " * " + numeros + " = " + n*numeros); } } public static void main(String[] args) { tabuadaDo2(2,3,4,5,6,7,8,9,10);//podemos chamar passando os valores 1 à 1 tabuadaDo2(new int[]{9,73,4,67,1,0}); } }

Espero que tenham gostado pessoal, qualquer coisa deixem um comentário. Até mais!!!

Novidade!!! Agora vamos ter canal no Youtube =D

Fala pessoal tudo beleza, estou sumido a correria está forte por aqui. Estou querendo dar um start em um projeto antigo que vem desde o temp...