"O maior dos erros é a pressa antes do tempo, e a lentidão ante a oportunidade"
- Provérbio árabe
Do (excelente) livro "Do Fortran à Internet: no rastro da trilogia Educação, Pesquisa e Desenvolvimento", de Tércio Pacitti.
Páginas
Wednesday, March 18, 2009
Saturday, March 14, 2009
Escreva menos, use Python
Ontem vivenciei uma situação em que tivemos que manter um código legado para inserir mais uma pequena funcionalidade.
Uma "regra" aqui é não se desviar do que você tem que fazer (que possui mais valor de negócio) para cuidar de outras coisas. Outra "regra" é não deixar débito técnico.
A grande dificuldade é encontrar o balanço adequado entre esses dois objetivos, e ainda assim implementar sua nova funcionalidade.
Bem, livre de qualquer "regra", vou aproveitar esse post para introduzir 3 recursos do Python que nem sempre são lembrados, e que nos permitem economizar linhas de código, escrevendo de forma clara e concisa o que queremos fazer.
Vamos partir do seguinte código legado:
É um esboço de uma View do Django. Como podem ver, espera-se que a view seja requisitada via HTTP POST, com a passagem de diversos parâmetros, que ficam armazenados no dicionário Python
Então o código que temos é uma sequência de
Podemos imaginar que temos um formulário numa página que, ao ser submetido, exibe as informações preenchidas para confirmação.
Agora temos que adicionar mais um campo ao cadastro. Digamos que nosso cliente pediu para guardar também o campo "idade". Por simetria, acabaria acontecendo o seguinte:
Pra que mudar o que já funciona? Bem, vamos então ao primeiro dos tópicos.
Usar o
Mas o que esse método faz? Ele retorna o valor de dict['key'] se o dicionário tem a chave 'key', senão retorna
Ficaria assim:
Além de economizar linhas, temos um código menos redundante e seguindo o princípio de "It's better to beg forgiveness than to ask permission".
Vamos refatorar o resto do código:
Assim, caso um dos campos não venha no POST, será atribuído o valor
Notem que, assim como antes, existe bastante duplicação de código (por razões práticas, fiz um exemplo com poucas chaves do dicionário, mas o caso que me deparei eram mais que dez...).
Agora então é a hora de introduzir os outros dois conceitos, o
O primeiro transforma uma string em lista através de um separador. Exemplo:
Isso pode ser usado para declararmos uma lista sem precisar de muitas aspas e vírgulas... basta colocar todos os itens da lista em uma string e usar o
O outro faz o mesmo que
Com essas mudanças, nosso código ganha uma tremenda compressão, sem perder legibilidade:
Uma "regra" aqui é não se desviar do que você tem que fazer (que possui mais valor de negócio) para cuidar de outras coisas. Outra "regra" é não deixar débito técnico.
A grande dificuldade é encontrar o balanço adequado entre esses dois objetivos, e ainda assim implementar sua nova funcionalidade.
Bem, livre de qualquer "regra", vou aproveitar esse post para introduzir 3 recursos do Python que nem sempre são lembrados, e que nos permitem economizar linhas de código, escrevendo de forma clara e concisa o que queremos fazer.
Vamos partir do seguinte código legado:
#...
from django.shortcuts import render_to_response
from model import Cadastro
#...
def tratar_cadastro(request):
post = request.POST
#...
cadastro = Cadastro()
#...
if post.has_key('nome'):
cadastro.nome = post['nome']
if post.has_key('endereco'):
cadastro.endereco = post['endereco']
if post.has_key('telefone'):
cadastro.telefone = post['telefone']
if post.has_key('email'):
cadastro.email = post['email']
return render_to_response('cadastro/index.html', {"cadastro": cadastro})
É um esboço de uma View do Django. Como podem ver, espera-se que a view seja requisitada via HTTP POST, com a passagem de diversos parâmetros, que ficam armazenados no dicionário Python
request.POST
. Esse papo de cadastro, nome, telefone, etc é só para ilustrar.Então o código que temos é uma sequência de
if
's que setam atributos de uma instância de Cadastro
que é posteriormente passada para o template.Podemos imaginar que temos um formulário numa página que, ao ser submetido, exibe as informações preenchidas para confirmação.
Agora temos que adicionar mais um campo ao cadastro. Digamos que nosso cliente pediu para guardar também o campo "idade". Por simetria, acabaria acontecendo o seguinte:
#...
from django.shortcuts import render_to_response
from model import Cadastro
#...
def tratar_cadastro(request):
post = request.POST
#...
cadastro = Cadastro()
#...
if post.has_key('nome'):
cadastro.nome = post['nome']
if post.has_key('idade'):
cadastro.idade = post['idade']
if post.has_key('endereco'):
cadastro.endereco = post['endereco']
if post.has_key('telefone'):
cadastro.telefone = post['telefone']
if post.has_key('email'):
cadastro.email = post['email']
return render_to_response('cadastro/index.html', {"cadastro": cadastro})
Pra que mudar o que já funciona? Bem, vamos então ao primeiro dos tópicos.
Usar o
dict.has_key
é ruim e desnecessário. Esse método é deprecated no Python 2.6 e já foi removido da linguagem no Python 3.0, em favor da forma chave in dicionario
. No lugar dele e do if
deveríamos usar o dict.get
.Mas o que esse método faz? Ele retorna o valor de dict['key'] se o dicionário tem a chave 'key', senão retorna
None
ou outro valor padrão que o programador especificar.Ficaria assim:
#...
from django.shortcuts import render_to_response
from model import Cadastro
#...
def tratar_cadastro(request):
post = request.POST
#...
cadastro = Cadastro()
#...
if post.has_key('nome'):
cadastro.nome = post['nome']
cadastro.idade = post.get('idade', u'Campo não preenchido')
if post.has_key('endereco'):
cadastro.endereco = post['endereco']
if post.has_key('telefone'):
cadastro.telefone = post['telefone']
if post.has_key('email'):
cadastro.email = post['email']
return render_to_response('cadastro/index.html', {"cadastro": cadastro})
Além de economizar linhas, temos um código menos redundante e seguindo o princípio de "It's better to beg forgiveness than to ask permission".
Vamos refatorar o resto do código:
#...
from django.shortcuts import render_to_response
from model import Cadastro
#...
def tratar_cadastro(request):
post = request.POST
#...
cadastro = Cadastro()
#...
cadastro.nome = post.get('nome')
cadastro.idade = post.get('idade')
cadastro.endereco = post.get('endereco')
cadastro.telefone = post.get('telefone')
cadastro.email = post.get('email')
return render_to_response('cadastro/index.html', {"cadastro": cadastro})
Assim, caso um dos campos não venha no POST, será atribuído o valor
None
ao atributo do objeto cadastro
.Notem que, assim como antes, existe bastante duplicação de código (por razões práticas, fiz um exemplo com poucas chaves do dicionário, mas o caso que me deparei eram mais que dez...).
Agora então é a hora de introduzir os outros dois conceitos, o
split
e o setattr
.O primeiro transforma uma string em lista através de um separador. Exemplo:
>>> print "um, dois, tres".split(", ")
['um', 'dois', 'tres']
Isso pode ser usado para declararmos uma lista sem precisar de muitas aspas e vírgulas... basta colocar todos os itens da lista em uma string e usar o
split
.O outro faz o mesmo que
objeto.atributo = valor
, porém atributo
pode ser algo dinâmico, definido em tempo de execução.Com essas mudanças, nosso código ganha uma tremenda compressão, sem perder legibilidade:
#...
from django.shortcuts import render_to_response
from model import Cadastro
#...
def tratar_cadastro(request):
post = request.POST
#...
cadastro = Cadastro()
#...
for attr in 'nome idade endereco telefone email'.split():
setattr(cadastro, attr, post.get(attr))
return render_to_response('cadastro/index.html', {"cadastro": cadastro})
Wednesday, March 11, 2009
Psicologia Junguiana
Recebi isto hoje por email e acho que parece bastante com minha 'rotina' corrente.
Apesar da ralação, tem sido muito bom. Não me contento com molezinha :P
Apesar da ralação, tem sido muito bom. Não me contento com molezinha :P
Exigências da vida moderna (quem agüenta tudo isso??)
Dizem que todos os dias você deve comer uma maçã por causa do ferro.
E uma banana pelo potássio.
E também uma laranja pela vitamina C.
Uma xícara de chá verde sem açúcar para prevenir a diabetes.
Todos os dias deve-se tomar ao menos dois litros de água.
E uriná-los, o que consome o dobro do tempo.
Todos os dias deve-se tomar um Yakult pelos lactobacilos (que ninguém sabe bem o que é, mas que aos bilhões, ajudam a digestão).
Cada dia uma Aspirina, previne infarto.
Uma taça de vinho tinto também.
Uma de vinho branco estabiliza o sistema nervoso...
Um copo de cerveja, para... não lembro bem para o que, mas faz bem.
O benefício adicional é que se você tomar tudo isso ao mesmo tempo e tiver um derrame, nem vai perceber.
Todos os dias deve-se comer fibra.
Muita, muitíssima fibra.
Fibra suficiente para fazer um pulôver.
Você deve fazer entre quatro e seis refeições leves diariamente.
E nunca se esqueça de mastigar pelo menos cem vezes cada garfada.
Só para comer, serão cerca de cinco horas do dia.
E não esqueça de escovar os dentes depois de comer.
Ou seja, você tem que escovar os dentes depois da maçã, da banana, da laranja, das seis refeições e enquanto tiver dentes, passar fio dental, massagear a gengiva, escovar a língua e bochechar com Plax.
Melhor, inclusive, ampliar o banheiro e aproveitar para colocar um equipamento de som, porque entre a água, a fibra e os dentes, você vai passar ali várias horas por dia.
Há que se dormir oito horas por noite e trabalhar outras oito por dia, mais as cinco comendo são vinte e uma.
Sobram três, desde que você não pegue trânsito.
As estatísticas comprovam que assistimos três horas de TV por dia.
Menos você, porque todos os dias você vai caminhar ao menos meia hora (por experiência própria, após quinze minutos dê meia volta e comece a voltar, ou a meia hora vira uma).
E você deve cuidar das amizades, porque são como uma planta: devem ser regadas diariamente, o que me faz pensar em quem vai cuidar delas quando eu estiver viajando.
Deve-se estar bem informado também, lendo dois ou três jornais por dia para comparar as informações.
Ah! E o sexo.
Todos os dias, tomando o cuidado de não se cair na rotina.
Há que ser criativo, inovador para renovar a sedução.
Isso leva tempo e nem estou falando de sexo tântrico.
Também precisa sobrar tempo para varrer, passar, lavar roupa, pratos e espero que você não tenha um bichinho de estimação.
Na minha conta são 29 horas por dia.
A única solução que me ocorre é fazer várias dessas coisas ao mesmo tempo!!!
Tomar banho frio com a boca aberta, assim você toma água e escova os dentes. Chame os amigos e seus pais.
Beba o vinho, coma a maçã e dê a banana na boca da sua mulher.
Ainda bem que somos crescidinhos, senão ainda teria um Danoninho e se sobrarem 5 minutos, uma colherada de leite de magnésio.
Agora tenho que ir.
É o meio do dia, e depois da cerveja, do vinho e da maçã, tenho que ir ao banheiro.
E já que vou, levo um jornal...
Tchau....
Se sobrar um tempinho, me manda um e-mail.Luís Fernando Veríssimo
Friday, March 6, 2009
Como abrir o gnome-terminal com múltiplas abas
Para abrir o gnome-terminal com diversas abas, cada uma em um diretório, podemos usar o comando:
gnome-terminal \
--tab --working-directory=/home/user/project1 \
Outros dois parâmetros interessantes são " --command='comando a ser executado' " e " --title='titulo da aba' ", porém nenhum dos dois funcionou satisfatoriamente pra mim.
gnome-terminal \
--tab --working-directory=/home/user/project1 \
--tab --working-directory=/home/user/another_dir \
--tab --working-directory=/home/user/project1/src/main \
--tab --working-directory=/home/user
--tab --working-directory=/home/user/project1/src/main \
--tab --working-directory=/home/user
Outros dois parâmetros interessantes são " --command='comando a ser executado' " e " --title='titulo da aba' ", porém nenhum dos dois funcionou satisfatoriamente pra mim.
Wednesday, March 4, 2009
Mozilla Bespin: web text editor and collaboration tool
Hoje eu conheci o Bespin, graças a meu amigo Flávio Amieiro.
Depois do Coding Dojo Rio de hoje, movimentação na lista e uma possível integração com o pessoal da SEA Tecnologia de Brasília, o Flávio citou o Bespin como ferramenta para fazermos um dojo remoto colaborativo.
Comecei vendo um introdução nesse vídeo:
Introducing Bespin from Dion Almaer on Vimeo.
Basicamente é mais um experimento/projeto em estado alfa de desenvolvimento da equipe do Mozilla Labs. É um editor de código-fonte, atualmente com suporte a sintaxe colorida em Javascript, CSS e HTML.
O Bespin é escrito em Java, Python, e bastante Javascript, HTML e CSS.
Tem suporte experimental a edição colaborativa.
Esta é a interface de "dashboard", com um navegador de arquivos no estilo do Mac OS X.
Na parte de baixo eu dei o comando "help" para receber uma lista dos comandos disponíveis.

Esta é a interface de edição mais a área de colaboração, que no momento parece estar desativada.

Tem um demo do projeto rodando em:
http://bespin.mozilla.com/
Você pode se registrar ou usar um login genérico daqui:
http://www.bugmenot.com/view/bespin.mozilla.com
O código-fonte do Bespin é aberto, e está em um repositório do Mercurial:
http://hg.mozilla.org/labs/bespin/
Vale a pena dar uma olhada neste e outros projetos do Mozilla Labs, a exemplo do Ubiquity e do Prism.
Depois do Coding Dojo Rio de hoje, movimentação na lista e uma possível integração com o pessoal da SEA Tecnologia de Brasília, o Flávio citou o Bespin como ferramenta para fazermos um dojo remoto colaborativo.
Comecei vendo um introdução nesse vídeo:
Introducing Bespin from Dion Almaer on Vimeo.
Basicamente é mais um experimento/projeto em estado alfa de desenvolvimento da equipe do Mozilla Labs. É um editor de código-fonte, atualmente com suporte a sintaxe colorida em Javascript, CSS e HTML.
O Bespin é escrito em Java, Python, e bastante Javascript, HTML e CSS.
Tem suporte experimental a edição colaborativa.
Esta é a interface de "dashboard", com um navegador de arquivos no estilo do Mac OS X.
Na parte de baixo eu dei o comando "help" para receber uma lista dos comandos disponíveis.

Esta é a interface de edição mais a área de colaboração, que no momento parece estar desativada.

Tem um demo do projeto rodando em:
http://bespin.mozilla.com/
Você pode se registrar ou usar um login genérico daqui:
http://www.bugmenot.com/view/bespin.mozilla.com
O código-fonte do Bespin é aberto, e está em um repositório do Mercurial:
http://hg.mozilla.org/labs/bespin/
Vale a pena dar uma olhada neste e outros projetos do Mozilla Labs, a exemplo do Ubiquity e do Prism.
Subscribe to:
Posts (Atom)