Páginas

Sunday, August 23, 2009

Windows Vista: filtrando visualização no Windows Explorer

Muitas vezes ficamos apenas reclamando dos Sistemas Operacionais, reclamamos do Windows, ele não presta, a Microsoft é má, isso e aquilo...
Bem, depois de ouvir cuidadosamente a palestra do Robert M. Lefkowitz na PyCon 2007, espero que você mude de idéia e comece a entender onde fica o software livre e o proprietário, pois ambos tem seu espaço. Então agora estou escrevendo a favor do Windows Vista, já que acabo de descobrir uma funcionalidade muito bacana, que parece ficar escondida na interface...

Programar no Windows não costuma ser uma tarefa tão divertida quanto ter um Linux bem arrumado, mas em ambos os casos eu sempre fico querendo esconder os arquivos .pyc e ver só o que interessa, os .py.
O que eu descobri é que com o Windows Explorer eu posso fazer isso e um pouco mais!

Aqui está um diretório com alguns arquivos Python e seus respectivos compilados, no modo de exibição "detalhes":

Colocando o mouse sobre qualquer coluna aparece uma seta no canto direito, como pode ser visto abaixo. Clique nesta seta para exibir um menu contextualizado com a coluna. Por exemplo, na coluna "Modificado em", é possível filtrar os arquivos por data. Tem até opções para filtrar os arquivos mais recentes, por semana, mês ou ano. Veja:

E você pode filtrar por nome, neste caso resolvi mostrar apenas os arquivos cujo nome começa com números (ocultando o __init__.py, que neste caso não é tão interessante):

E posso agrupar por tipo de arquivo, assim posso acessar separadamente, como se fossem dois "diretórios virtuais":

Note que desde a segunda tela eu já estava usando o filtro por "Tipo" para exibir apenas "Python file", resolvendo meu problema com os ".pyc" que só distraem!

Python: o print agora se chama raw_input

Opa! Ah? Que? O que que houve? Como assim?

Certo, nada mudou no Python... na verdade mudou, agora no Python 3.0 o raw_input virou input, que não deve ser confundido com o input presente nas versões pre-3.0.

A dica que deixo aqui é apenas um fato que percebi que tenho utilizado há algum tempo... talvez uma nova "técnica", mas que não dei muita bola até que comecei a falar sobre ela com amigos, e pensei que não faria mal relatar aqui.

Às vezes queremos colocar um print no meio do código, naquele processo de depuração (claro, você está fazendo TDD e dificilmente precisa fazer isso) e o que acontece é que, na maioria dos casos, temos que ficar caçando onde o output foi parar, quando você tem muita informação que surge no terminal.

Então, use o raw_input, que terá o mesmo efeito do print, porém o interpretador vai parar logo após exibir o que solicitou. Basta pressionar qualquer tecla para continuar a execução do script.

Outrar opção é parar com AssertionError, fazendo:

assert False, objeto_ou_valor_a_ser_inspecionado

Exemplo:
def get_tweets(user):
   from gluon.tools import fetch
   from gluon.contrib.simplejson import loads as sj_loads
   
   page = fetch('http://twitter.com/%s?format=json' % user)
   return sj_loads(page)['#timeline']

#print get_tweets('ilovetweeting')
raw_input(get_tweets('ilovetweeting'))

Saturday, August 22, 2009

Novo domínio e demais novidades

Olá!

A novidade mais recente é que agora o lifeatmymind.blogspot.com é blog.rodolfocarvalho.net!
Outra é que a partir do próximo mês vou residir em Lisboa, Portugal. Em busca de novas aventuras...

E isso quer dizer que globo.com agora entrou para a história, não estou mais desenvolvendo lá. Excelente experiência que tive nos últimos 8 meses, agora é partir para o desconhecido na Europa.

Dev in Rio 2009

Que Rock in Rio que nada... o evento de 2009 é o Dev in Rio!
Este evento é diferente de tudo que você já viu, e de todos os eventos que já paticipou. E o que me deixa tão confiante para dizer isso? Bem, o foco nas PESSOAS.

Este não é apenas um evento sobre tecnologias e máquinas, e sim um encontro de PESSOAS com um propósito. Ser diferente, a constante busca em fazer o melhor, vontade de mudar o mundo... se você procura pessoas que compatilham deste interesse, vá ao Dev in Rio 2009.

Os créditos vão para os meus amigos Guilherme Chapiewski e Henrique Bastos, dois dos grandes movimentadores de comunidade de software aqui no Rio de Janeiro, e para todos os outros envolvidos que estão tornando o Dev in Rio uma feliz realidade.

O evento será realizado no próximo mês, na segunda-feira dia 14 de Setembro de 2009. É o início da semana com o pé direito.
Infelizmente eu não vou poder participar, pois estarei iniciando outra coisa: minhas aulas em Lisboa!

Então, se não é Dev in Rio em 2009, será Rock in Rio Lisboa em 2010 e Dev in Rio 2010, já apostando na segunda edição!

Além de palestrantes nacionais e internacionais, vai ter uma arena rolando Dojo Rio durante o evento. Já se conscientizou que é imperdível?

Agora é só correr e fazer logo sua inscrição, pois as vagas são limitadas.

Friday, August 14, 2009

Filtros personalizados no admin do Django

Então ontem estava eu pensando na melhor forma de colocar meu próprio filtro naquela caixa lateral da interface padrão da aplicação 'admin' do Django.

Num ModelAdmin você normalmente pode especificar um nome de um campo que faça parte do seu Model, mas não pode fazer por exemplo um filtro por um valor computado.

Eu já tinha começado por uma abordagem bem rasteira de estender os templates padrão e colocar meu filtro logo abaixo dos outros filtros (guardado numa shelf do Bazaar :P). Mas eis que a melhor solução até agora foi a do Marinho Brandão e do Semente no DjangoSnippets.

Fiz algumas poucas alterações para pegar do banco apenas valores distintos, e apesar de ser um ponto que pode prejudicar o desempenho, gero a lista a cada requisição -- caso contrário, a lista só será recomputada quando o servidor for reiniciado. Talvez fosse mais interessante gerar um lista fixa de opções (implicando nenhum acesso ao banco), ou mesmo ao invés de consultar N linhas do banco e remover valores duplicados, poderia partir de uma lista fixa e chegar se o banco contém resultados para o valor da lista.

# meu_projeto/minha_app/admin/filterspecs.py
from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext as _


class AlphabeticFilterSpec(ChoicesFilterSpec):
"""
Adds filtering by first char (alphabetic style) of values in the admin
filter sidebar. Set the alphabetic filter in the model field attribute
'alphabetic_filter'.

my_model_field.alphabetic_filter = True

Based on http://www.djangosnippets.org/snippets/1051/
"""

def __init__(self, f, request, params, model, model_admin):
super(AlphabeticFilterSpec, self).__init__(f, request, params, model,
model_admin)
self.lookup_kwarg = '%s__istartswith' % f.name
self.lookup_val = request.GET.get(self.lookup_kwarg, None)
self.model = model

def choices(self, cl):
yield {'selected': self.lookup_val is None,
'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
'display': _('All')}

f = self.field
values_list = self.model.objects.distinct().values_list(f.name, flat=True)
# getting the first char of values
lookup_choices = sorted(set(val[0].lower() for val in values_list if val))

for val in lookup_choices:
yield {'selected': smart_unicode(val) == self.lookup_val,
'query_string': cl.get_query_string({self.lookup_kwarg: val}),
'display': val.upper()}


# registering the filter
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'alphabetic_filter', False),
AlphabeticFilterSpec))


E para ativar seu filtro para algum campo:

# meu_projeto/minha_app/models.py
# [...]

class Empresa(models.Model):
nome = models.CharField(max_length=64)
nome.alphabetic_filter = True
# [...]


# meu_projeto/minha_app/admin/__init__.py
# [...]
class EmpresaAdmin(admin.ModelAdmin):
list_display = ('nome', 'cnpj', 'inicio_convenio',
'_termino_convenio', 'natureza')
list_display_links = ('nome', 'cnpj')
list_filter = ('natureza', 'termino_convenio', 'inicio_convenio', 'nome')


# meu_projeto/urls.py
# Chama o código que registra o filtro personalizado
import sgtce.admin.filterspecs
# [...]

Wednesday, August 12, 2009

Web2py hack day



Na última sexta-feira realizamos um encontro em um dos laboratórios da Peta 5 na UFF.
O tema foi o framework desenvolvimento de aplicações web web2py, escrito em Python, e que conta com uma crescente comunidade -- boa parte dela aqui no Brasil.

Este post serve como uma continuação da história sobre o que estamos fazendo aqui no Rio.
Como conversamos depois do último dojo na quarta-feira passada, "estamos procurando por melhores formas de desenvolver software fazendo e ajudando outros a fazer o mesmo..." e por aí vai o Manifesto Ágil. Só que, para fugir da imagem enganosa estabelecida pelas buzzwords -- os conceitos deturpados de o que é fazer software, cunhamos o termo framps como a nossa palavra para descrever o que somos e fazemos.




Estão foi isso, tivemos o web2py hack day framps. Juntamos membros do Dojo Rio, PythOnRio, INPI, UFF, etc. Alguns computadores, disposição e as dicas e orientações do Álvaro Justen, e rapidinho fomos desenvolvendo nosso produto: o web2itter!

Se virem esse nome em qualquer outro lugar, não se enganem, fui eu quem inventei! Apesar do escopo amplo, o primeiro release foi apenas uma aplicação concorrente do Twitter, com a diferença de suportar muito mais requisições por segundo que o original.

Depois, só porque a UFF tinha que fechar as portas e porque nossos estômagos estavam vazios, paramos de programar e fomos para o Vestibular do Chopp encarar uma picanha... e algumas horas de bate-papo sobre os mais variados temas, incluindo a história do projeto GNU e o papel do Linus Torvalds e seu kernel, as opções de controle de versão de código-fonte: git, mercurial (hg) e bazaar (bzr), e mais um monte de coisas que sinceramente eu já nem lembro :P.

E pra isso tudo não poderiam faltar fotos! Vejam as fotos do I Web2py Hack Day Framps.

Saturday, August 8, 2009

If-else em uma linha de Python

Hoje aprendi mais uma forma [tosca] de fazer condicional com Python.

Depois do truque lógico do "condicao and valor_caso_verdadeiro or valor_caso_falso", o que descobri navegando na Internet hoje foi:

>>> x = 5
>>> ["menor que 10", "maior que 10"][x > 10]
'menor que 10'

Isso funciona porque o tipo bool (valor booleano) é um subclasse do tipo int, tipo requerido em indices de sequências.

>>> ["menor que 10", "maior que 10"]['not an integer']
TypeError: list indices must be integers

>>> issubclass(bool, int)
True

>>> ["menor que 10", "maior que 10"][True]
'maior que 10'


Mas é claro que isso é só um "acidente" e não deve ser usado normalmente. A partir do Python 2.5 temos a sintaxe:

valor_caso_verdadeiro if condicao else valor_caso_falso