domingo, 5 de dezembro de 2010

Começando com testes em Python

Olá pessoal, depois de muito tempo sem tempo (e idéias) para postar, eu finalmente tive uma boa idéia. Você ai, que programa em C ou até mesmo já em Python, como você testa seus programas? Fica conferindo a saída do terminal pra ver se está como deveria? E quando o seu programa se torna difícil de testar visualmente? É um problema né? Apresento a você a SOLUÇÃO para os seus problemas: testes automatizados.

Como eu faço isso tio?


É simples! Usando bibliotecas próprias para testes, criamos nossos testes baseados em como o programa deve funcionar. Eles podem ser escritos depois do próprio código ou antes. A prática de escrever testes ANTES é extremamente útil. Com ela você já define como será a interface, a nível de código, das suas classes e funções, e precisa codificar somente o suficiente para passar nos testes criados.

Falar é fácil né? Faz ai, quero ver!


Então tá. Mostrarei um exemplo em Python, por ser simples, mas existem bibliotecas de testes para Java, C, C#, Ruby, etc... basta procurar. O intuito aqui não é comparar as ferramentas de testes de linguagens, mas sim mostrar como testes automatizados podem facilitar (muito) a sua vida. Suponhamos que temos o seguinte código a ser testado:

[python]

class Calculadora(object):

@staticmethod

def soma(num1, num2):

return num1 + num2

[/python]

Podemos escrever os testes da seguinte maneira:

[python]

import unittest # biblioteca responsável pela suíte de testes

from should_dsl import * # biblioteca que disponibiliza matchers mais legíveis

from calculadora import Calculadora # importando a nossa classe a ser testada

class CalculadoraTest(unittest.TestCase):

def testa_soma(self):

calculadora.soma(1,1) |should| equal_to(2)

if __name__ == '__main__':

unittest.main()

[/python]

Para rodar os testes é só executar o arquivo que os contém. Não é LINDO? Este é um caso muito simples, mas existem casos de programas complexos que seria completamente inviável ficar testando no "olho". Os testes automatizados te dão um feedback instantâneo (dependendo do que está testando e da quantidade de testes feitos) da aplicação. Em pouquíssimo tempo você sabe se aquela modificação que você acabou de fazer funciona ou não, com o simples uso de 1 comando e sem dor de cabeça.

Python é lindo! Do que eu preciso para criar aplicações com testes no meu PC? *-*


Primeiramente, precisa do Python instalado, claro. A biblioteca unittest já está incluída por padrão juntamente com o interpretador. Para instalar a biblioteca should_dsl é só executar:

 [sudo] pip install should_dsl 


Ou, se você o easy_install:

 [sudo] easy_install should_dsl 


Agora você já pode começar a parar de ficar imprimindo coisas na tela para "testar" e começar a fazer isso de verdade! Quando você começar a usar, nunca mais vai querer parar! É viciante e ajuda demais.

Gostei, onde encontro mais informação sobre testes em Python?



Na própria documentação do UnitTest: http://docs.python.org/library/unittest.html
No tutorial DiveIntoPython: http://diveintopython.org/unit_testing/

E no Google. :D

Bom, por enquanto é só isso amigos... até a próxima!

quarta-feira, 29 de setembro de 2010

Compilando o Python 2.6 com zlib e sqlite no Debian 5

Olá pessoal, faz um tempinho que eu havia decidido fazer um post sobre isso e acabei esquecendo, mas hoje me lembrei e não me perguntem a razão. Eu tive uma grande dor de cabeça quando tive que compilar o Python 2.6 no Debian 5 com a zlib e suporte a sqlite3. Agora ensinarei a vocês para que não passem pelo mesmo que eu passei.

Primeiramente instale os pacotes de desenvolvimento que serão necessários para que tudo seja compilado sem problemas:

 sudo apt-get install build-essential linux-headers-`uname -r` build-essential libncursesw5-dev libreadline5-dev libssl-dev libgdbm-dev libbz2-dev libc6-dev libsqlite3-dev libdb-dev tk-dev


Agora seu sistema já está apto a compilar o Python 2.6 com zlib e sqlite3. Baixe o código fonte do Python 2.6, extraia-o e na pasta dele execute o seguinte comando para configurar:

 ./configure USE="sqlite" –with-zlib=/usr/include


Depois para compilar:

 make 


E finalmente, para instalar:

 sudo make install 


Qualquer dúvida ou sugestão é só comentar minha gente! :D

sábado, 25 de setembro de 2010

Proriedades de Objetos e Metaprogramação em Ruby

Olá pessoal. Hoje mais cedo, um amigo (Pedro Henrique) me veio perguntar criar propriedades para objetos em Ruby e então eu decidi fazer esse post para ajudar a galera que ta começando com a linguagem. Criar propriedades em Ruby não é muito complicado, mas para a primeira vez exige um pouco de pesquisa.

Vamos começar então. Primeiramente espero que você saiba definir uma classe (olha lá hein!). Criaremos uma classe Pessoa que deve receber um nome no momento da criação, por exemplo.

[ruby]

class Pessoa

def initialize(nome)
@nome = nome
end

end

[/ruby]

A partir dessa classe, se você criar um objeto Pessoa com qualquer nome e tentar acessar a propriedade nome você terá um NoMethodError. Existem duas maneiras de criar essa propriedade nome. Vamos começar pela mais bruta (setter e getter). Se quando você chamou a propriedade nome o Ruby disse que o método não existe, vamos criá-lo:

[ruby]

class Pessoa

def initialize(nome)
@nome = nome
end

def nome
@nome
end

end

[/ruby]

Desta maneira você já conseguirá criar um objeto da classe Pessoa e acessar sua propriedade nome. Porém ao tentar mudá-la, novamente, será lançado NoMethodError para a função "nome=". Então vamos criá-la.

[ruby]

class Pessoa

def initialize(nome)
@nome = nome
end

def nome
@nome
end

def nome=(novo_nome)
@nome = novo_nome
end

end

[/ruby]

Ótimo! Agora podemos acessar e modificar a propriedade nome dos objetos criados a partir da classe Pessoa. Mas essa maneira de fazer isso é bem feia e trabalhosa. Existe um "açucar sintático" que torna a criação de propriedades bem mais simples. São as funções attr_reader, attr_write e attr_accessor. A classe Pessoa poderia ser reescrita, com o mesmo funcionamento, da seguinte maneira:

[ruby]

class Pessoa

attr_accessor :nome

def initialize(nome)
@nome = nome
end

end

[/ruby]

A linha 3 do código tem um funcionamento interessante. Ela transforma o símbolo passado como parâmetro para string, chama a função define_method, que define um método na classe onde ela é chamada. Ela passa então, via bloco de código, instance_variable_get, que por sua vez, recebe uma string como parâmetro e retorna o valor da variável com esse nome na instância da classe onde a função foi chamada. E para permitir a mudança as coisas não mudam muito, porém o método passa para o bloco de código uma variável, que seria o novo valor, e chama a função instance_variable_set que além da variável a ser mudada recebe o seu novo valor. Cabuloso, não?

Quanto aos outros dois métodos "mágicos": o attr_reader, como seu nome diz, cria um método de acesso à propriedade e o attr_writer cria um método de escrita.

Ai vai uma implementação dos 3 para você entender melhor como funciona:

[ruby]

def new_attr_reader(attr)
define_method("#{attr}") { instance_variable_get("@#{attr}") }
end

def new_attr_writer(attr)
define_method("#{attr}=") { |new_value| instance_variable_set("@#{attr}", new_value) }
end

def new_attr_accessor(attr)
new_attr_reader(attr)
new_attr_writer(attr)
end

[/ruby]

Isso nos mostra um pouco (?) do poder da metaprogramação em Ruby, que nos permite modificar classes em runtime e adicionar a elas: métodos, propriedades, variáveis... tudo que você pode imaginar! É código que modifica código. Praticamente 80% da facilidade, graça e poder do Ruby On Rails só pode existir graças a essa poderosa ferramenta que vale a pena ser estudada com paciência e atenção.

Bom, agora vocês já devem estar experts nisso (ou não). Até a próxima pessoal... e qualquer problema ou dúvida é só comentar! :D

domingo, 5 de setembro de 2010

ForkInCampos: O começo

Bom, alguns de vocês (pessoas que eu conheço fisicamente) já devem estar sabendo disso, outros não. Nessa sexta-feira passada (03/09) estava eu trabalhando normalmente quando Tarsis Azevedo, após ver um tweet do Israel sobre ForkInRio e reclamar que não tinhamos Fork em Campos dos Goytacazes, resolve me chamar para junto com ele organizar um Fork pra gente. Como eu so muito doido (e ele também) demos um jeito nisso rapidinho... e nasceu o ForkInCampos!

O que é ForkInCampos? O que é um Fork?


Calma gente, uma pergunta de cada vez. Primeiro explicarei brevemente o que é um Fork.

Fork é uma reunião de pessoas determinadas a aprender algo em comum, que assim como o Coding Dojo, prega não só o aprendizado mas também o compartilhamento do mesmo. Foi idealizado pelo pessoal do #horaextra inicialmente com o ForkInRio.

De maneira mais expressiva, o Fork é mais uma opção para encontrar seus amigos, conhecer gente nova, aprender coisas novas e ainda se divertir. Não existe pressão alguma, pessoas te cobrando... é aprendizado na essência! Apesar deste ter uma dinâmica que alguns achem meio individualista no começo, no fim verão que é bem interessante e proveitoso.

Mas eu não vou explicar aqui TUDO sobre um Fork. Para isso eu e Tarsis criamos um documento no Google Docs explicando o máximo possível sobre Fork's e sua dinâmica.

Fodaaaaa!!111!1!! Quero participar, #comofas?


Se você tem interesse em participar, é simples! Basta participar do grupo de discussão do ForkInCampos. E enviar um email ou ficar atento aos já enviados. Caso você queira iniciar um Fork sobre qualquer assunto de seu interesse basta contatar o grupo propondo o assunto. Logo os interessados irão responder e assim vocês poderão combinar local de encontro, exercícios, compartilhar material de estudo, etc. Simples assim! Tudo fácil e acessível a todos, basta que haja comunicação que tudo se resolve.

Por que diabos vocês resolveram fazer isso cara? :/


Resolvemos fazer isso porque podemos ver através dos Coding Dojo's que não exista uma maneira melhor de adquirir conhecimento do que conversando com outras pessoas. Juntos podemos aprender muito mais... cada um colaborando com o pouco que sabe para termos um conhecimento cada vez mais completo sobre o mais números de coisas possíveis.

Qualquer dúvida ou sugestão é só deixar um comentário gente, até a próxima! :D

sexta-feira, 20 de agosto de 2010

Instalando e configurando virtualenv(wrapper)

Python Logo


Se você programa em Python, principalmente em projetos que tem várias dependências, já deve ter pensando duas vezes antes de instalar vários pacotes Python no seu sistema. Imagine como seria bom se você pudesse ter um interpretador de Python separado para cada projeto seu, com as devidas dependências deles instaladas e o Python do seu sistema limpinho, só com o que ele realmente precisa ter.



VirtualEnv


Pare de imaginar coisas, isso EXISTE! E se chama virtualenv. A instalação é simples. Antes de tudo, caso não tenha o pip instalado, instale-o com:
 sudo easy_install pip

E depois, o virtualenv propriamente dito:
 sudo pip install virtualenv

Agora você já pode criar e ativar ambientes Python virtuais usando a sintaxe:
virtualenv --no-site-packages nomedoambiente

source nomedoambiente/bin/activate

O primeiro comando cria um ambiente virtual numa pasta chamada "nomedoambiente" totalmente independente do Python do sistema e o segundo ativa o mesmo. Para desativar é só usar:
deactivate



VirtualEnvWrapper


O único problema do virtualenv, pelo menos na minha opinião, é a localização dos ambientes e a maneira como eles são ativados. É muito chato ter que ficar lembrando disso toda hora. E existe uma solução pra isso, chamada virtualenvwrapper. Ele organizar seus ambientes virtuais em uma única pasta e você pode ativar qualquer um deles apesar usando o comando: workon nomedoambiente. A instalação dele também é simples como a do virtualenv.
sudo pip install virtualenvwrapper

Porém, você precisará definir em qual pasta vão ficar os ambientes virtuais criados com ele. Além de carregá-lo sempre que abrir o terminal. Para isso, execute:
 echo source /usr/local/bin/virtualenvwrapper.sh >> ~/.bashrc

 echo export WORKON_HOME=~/.pythonenvs >> ~/.bashrc

Obs.: Lembre-se de criar o diretório .pythonenvs na home do seu usuário.

Agora é só fechar e abrir o terminal novamente e você já poderá criar um ambiente virtual usando o comando:
 mkvirtualenv teste

Você também poderá copiar e deletar um ambiente usando, respectivamente:
 cpvirtualenv teste teste_copia

 rmvirtualenv teste_copia

E para instalar bibliotecas nos ambientes virtuais é só usar normalmente o pip (sem sudo).

Agora você pode ter um interpretador para cada projeto totalmente independente do seu Python global e com suas próprias bibliotecas.



VirtualEnvWrapper.Project (bônus)


Como se manipular ambientes virtuais com o virtualenvwrapper não fosse absurdamente fácil, existe um plugin para ele chamado virtualenvwrapper.project que além de manipular os Pythons virtuais também manipula projetos e liga eles com os ambientes virtuais. Os projetos ficam organizados em uma pasta definida no script e executando o comando "workon" com um projeto criado nele (usando o comando "mkproject") ativa automaticamente o ambiente virtual e a pasta do projeto criado.

A instalação é NOVAMENTE muito simples e parecida com a do virtualenvwrapper:
sudo pip install virtualenvwrapper.project

echo export PROJECT_HOME=$HOME/Devel >> ~/.bashrc

Substitua "$HOME/Devel" para a pasta onde você queira que fiquem os projetos e lembre-se de criá-la antes de usar o virtualenvwrapper.project. E lembre-se de reiniciar o terminal também.

Criei novos projetos com o comando:
mkproject nomedoprojeto

Uma pasta com o nome "nomedoprojeto" será criada, assim como um ambiente virtual com o mesmo nome. Quando você usar o comando "workon nomedoprojeto" além de ativar o novo interpretador, o seu diretório corrente mudará automaticamente para a pasta do projeto, que está dentro da pasta definida logo acima.

O virtualenvwrapper.project só tem um pequeno problema: ainda não existe um comando para deletar um projeto inteiro. Eu mesmo farei isso assim que tiver tempo. \o/

Qualquer problema ou sugestão é só comentar!

Obrigado pessoal e até a próxima. :D

segunda-feira, 9 de agosto de 2010

[DICA] Repositórios do Google para Linux

Google Logo


Venho trazer uma dica rápida para todos meus amigos (ou não) leitores que usam Linux: repositórios de aplicações do Google. Não é o repositório do Google Chrome, mas sim do Picasa 3 For Linux e do Google Desktop Linux. O Picasa todos nós já conhecemos, eu acho né? Mas o que me chamou a atenção foi o Google Desktop Linux. É como se o Google usasse seu algoritmo para indexar arquivos do nosso computador, gmail etc... E junta tudo em uma caixa de busca rápida que você acessa direto do Desktop. É genial!

Seguem as instruções para você instalar o repositório da Google no seu Linux, qualquer que seja:
 wget https://dl-ssl.google.com/linux/google-repo-setup.sh

 bash google-repo-setup.sh

Depois disso você já pode instalar os dois programas usando:
 sudo apt-get install picasa google-desktop-linux

Até a próxima pessoal! Qualquer dúvida ou problema é só postar ai. (:

domingo, 8 de agosto de 2010

Aula/Dojo na UENF!

Coding Dojo Symbol


Bom pessoal, venho aqui falar da grande iniciativa do pessoal de alunos sexto período de Ciência da Computação e Informática (Hugo Maia, Eduardo Hertz e Max) a pedirem à coordenadora do curso para ministrarem as aulas de Laboratório de Programação e além disso, em forma de Dojo. Eles desenvolvem em Ruby on Rails para a própria faculdade e são adeptos do agilismo, além de participar de grupos como o DojoRio.

Eu não pude permanecer durante muito tempo na aula deles, pois tinha aula de Estruturas de Dados 2 no mesmo horário, mas vou fazer um pequeno relato sobre a aula.

Quando os alunos entraram na sala e viram o pessoal do sexto período eles estranharam, porque a matéria seria ministrada pela coordenadora do curso. Então ele explicou que os veteranos iriam ministrar aulas de programação em forma de Coding Dojo para essa matéria. Terminada a explicação sobre a matéria, eles começaram com uma apresentação muito boa sobre o Dojo, de maneira geral, pro pessoal pegar a alma do negócio.

Ao fim da apresentação eles já foram convocados a meter a mão na massa! O problema do Fizz Buzz foi escolhido por ser bom para um primeiro Dojo e a linguagem foi Ruby. Achei a escolha da linguagem perfeita: Ruby é simples e expressivo o suficiente para deixar de longe as dores de cabeça de uma linguagem acadêmica/científica, como Pascal ou C, e permitir que a pessoa que esteja programando preste mais atenção no problema.

Primeiro os próprios "professores" participaram no Dojo, para ensinarem, na prática, a dinâmica aos alunos. Dai em diante eles foram chamando os alunos a participarem. No início todos tinham um pouco de vergonha e medo de não saber a sintaxe da linguagem, apesar disso, quando o primeiro foi participar, viu que é simples. Afinal, todos estão na aula/dojo para aprender. Hugo, Eduardo e Max precisavam estar participando as vezes para colocar os alunos nos trilhos e para programar  nas partes que envolviam questões de orientação a objetos (essa é uma matéria do quarto período), mas a participação deles deve diminuir conforme as aulas forem passando.

Um ponto interessante é que a pontuação da matéria é baseada em presença e participação. Não que seja com a intenção de "enfiar" o Dojo e algumas técnicas de agilismo na cabeça dos alunos, mas sim mostrar a eles um conceito novo e faze-los ter conhecimento sobre ele para depois julgar como queiram.

Estive matutando durante a aula/dojo e cheguei a conclusão que esse tipo de aula é muito importante! Os alunos aprenderão a desenvolver algoritmos de uma maneira bem interessante e produtiva, uma nova linguagem (Ruby), novos e promissores métodos de desenvolvimento. E além disso estarão aprendendo coisas que verão em matérias seguintes sem saber, facilitando para eles quando chegarem a tal matéria.