Arquivo da categoria: Programação

Não é magia, é o módulo itertools da biblioteca padrão do Python

Não é magia, é o módulo itertools da biblioteca padrão do PythonQuem ouve falar que Python vem com baterias incluídas, geralmente não imagina que elas estão mais próximas de uma usina nuclear do que de um par de pilhas Rayovale (sim, existe!). Nunca me canso de ficar surpreso toda vez que lembro que existem módulos como o itertools, por exemplo. Passeando pela documentação, é fácil encontrar funcionalidades poderosas, pérolas que podem salvar o dia em alguns minutos quando o seu problema é um desses:

Percorrer os elementos de várias sequências de uma só vez

Com a função chain(), basta fazer:

>>> import itertools
>>> a = [100, 200, 300]
>>> b = ('Newton', 'Einstein', 'Hawking', 'Cooper')
>>> c = 'Python'
>>> for item in itertools.chain(a, b, c):
...     print item
...
100
200
300
Newton
Einstein
Hawking
Cooper
P
y
t
h
o
n

Calcular a soma acumulada a cada passo da iteração

Vamos supor que uma criança guarda parte de sua mesada num cofrinho todo mês. Com a função accumulate() (Python 3) é possível calcular o valor economizado mês a mês:

>>> import itertools
>>> cofrinho = [10, 12, 15, 5, 7, 0, 20, 13, 9, 0, 1, 16]
>>> for mes, valor_guardado in enumerate(list(itertools.accumulate(cofrinho)), start=1):
...    print(mes, '= R$', valor_guardado)
...
1 = R$ 10
2 = R$ 22
3 = R$ 37
4 = R$ 42
5 = R$ 49
6 = R$ 49
7 = R$ 69
8 = R$ 82
9 = R$ 91
10 = R$ 91
11 = R$ 92
12 = R$ 108

Na verdade essa é apenas a funcionalidade mais básica da função accumulate(). É possível passar qual a função que será usada no lugar da soma, permitindo fazer operações muito mais complexas envolvendo séries de elementos. Mais detalhes podem ser vistos na documentação oficial.

Encontrar todas as possíveis combinações entre os elementos de um conjunto

Lembra de análise combinatória na escola? Uma entre as funções do módulo itertools que poderiam nos ajudar na hora do aperto é a permutations(). Um problema clássico da análise combinatória é encontrar todos os anagramas de uma palavra:

>>> import itertools
>>> [''.join(anagrama) for anagrama in itertools.permutations('gato')]
['gato', 'gaot', 'gtao', 'gtoa', 'goat', 'gota', 'agto', 'agot', 'atgo', 'atog', 'aogt', 'aotg', 'tgao', 'tgoa', 'tago', 'taog', 'toga', 'toag', 'ogat', 'ogta', 'oagt', 'oatg', 'otga', 'otag']

Esse é só um aperitivo das possibilidades do módulo itertools. A documentação oficial traz, além da referência de todas as funções do módulo, uma seção só com receitas do que se pode construir a partir da combinação das funções. Vale dar uma olhada, pois nunca se sabe quando vai ser necessário usar algo parecido.

Referência

Comandos Python em uma linha

Comandos Python em uma linhaJá se vão mais de 15 anos desde que a última edição da saudosa revista Micro Sistemas foi publicada. Naquela época pré-internet, os curiosos que tentavam aprender como obrigar o computador a fazer exatamente o que eles queriam – vulgo programar – não tinham outra alternativa a não ser garimpar livros e revistas sobre o assunto. Uma das minhas seções preferidas da Micro Sistemas era a dos jogos one-liner em BASIC e suas variantes. Meu primeiro contato com programação foi justamente a tentativa de copiar aquele emaranhado mágico e incompreensível de letras e números que vinha publicado na revista e tentar fazer aquilo funcionar.

Hoje a informação é muito mais acessível e qualquer um pode aprender praticamente qualquer assunto, sobre qualquer ramo do conhecimento humano, desde que tenha disciplina para se dedicar o suficiente. Uma dentre as milhões de coisas bastante úteis de se aprender é o uso das opções de linha de comando do interpretador Python (finalmente cheguei onde queria!). Com elas é possível realizar vários tipos de tarefas em apenas 1 (uma) linha, direto do shell, sem sequer precisar editar um arquivo de código-fonte.

A opção -c <comando>

Executa o código Python passado como argumento em comando, que pode ser uma ou mais declarações separados por indicadores de nova linha, no caso o ponto-e-vírgula (;). Vale lembrar que, assim como no código Python normal, espaços em branco no começo de cada linha são significativos. Portanto, cuidado.

A opção -m <nome-do-módulo>

Procura no sys.path pelo nome-do-módulo e executa seu conteúdo como o módulo principal (__main__). Como o argumento é o nome de um módulo, você não deve passar a extensão (.py). O nome-do-módulo deveria ser um nome de módulo válido para o Python, mas pode ser que a implementação não force esse comportamento (ex.: pode permitir que você use um nome que contenha hífen).

Exemplos de uso

Com essas duas opções e um pouco de criatividade, é possível fazer coisas como:

Imprimir o caminho de busca por módulos Python formatado

Usando os módulos sys e pprint:

$ python -c 'import sys, pprint; pprint.pprint(sys.path)'

Iniciar um servidor HTTP

Este exemplo cria um servidor HTTP que serve o conteúdo do diretório corrente na porta 8081 usando o módulo SimpleHTTPServer :

$ python -m SimpleHTTPServer 8081

Obter lista dos releases disponíveis de um módulo do PyPI

Usando o módulo xmlrpclib:

$ python -c 'import xmlrpclib; print xmlrpclib.Server("http://pypi.python.org/pypi").package_releases("Django")'
['1.5', '1.4.5', '1.4.4', '1.4.3', '1.3.7', '1.3.6', '1.3.5', '1.2.7', '1.1.4', '1.0.4']

Medir o tempo de execução de um trecho de código

Usando o módulo timeit para descobrir qual implementação é mais rápida:

$ python -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 3: 35.3 usec per loop
$ python -m timeit '"-".join([str(n) for n in range(100)])'
10000 loops, best of 3: 30.2 usec per loop

Conhece alguma outra aplicação útil das opções de linha de comando do Python? Compartilhe nos comentários!

Referências

O que muda no Django 1.5

O que muda no Django 1.5No último dia 26 de fevereiro foi lançada a versão 1.5 do framework Django. Ainda não tive a oportunidade de instalar e testar todos os detalhes, mas de acordo com as informações das notas de versão, as principais novidades são as seguintes:

Modelo User configurável

A maior mudança nesta nova versão é a possibilidade de personalizar o modelo User do Django. Antes da versão 1.5, as aplicações que precisassem usar o framework de autenticação do Django eram forçadas a usar a sua definição de “usuário”. Agora é possível substituir o modelo User por outro escrito pelo desenvolvedor.

Algumas vantagens de poder criar seu próprio User são o fim da limitação de 30 caracteres para o atributo username e a possibilidade de criar mais atributos personalizados para o perfil do usuário, por exemplo.

Para facilitar a implementação, está disponível a classe AbstractBaseUser , que fornece a implementação do núcleo de um User customizado.

Também é necessário indicar para a aplicação qual a classe que representa o seu modelo User. Para isso, deve-se fornecer um valor para o atributo da configuração AUTH_USER_MODEL no settings.py. Por exemplo:

AUTH_USER_MODEL = 'myapp.MyUser'

Mais detalhes sobre a personalização do modelo User podem ser consultados na documentação oficial.

Suporte a Python 3

Outra novidade importante é o suporte a Python 3 (especificamente Python 3.2 e acima). Segundo os desenvolvedores, por enquanto este suporte deve ser considerado experimental, pois apesar de ter passado por testes automatizados extensivos, ainda não existiram muitas situações do “mundo real” para colocá-lo à prova. Além disso, alguns recursos não estão disponíveis para Python 3, tais como o backend para MySQL, o ImageField e o LiveServerTestCase. Isso se deve à dependência de componentes de software de terceiros (PIL, Selenium WebDriver etc.) que ainda não foram portados para Python 3.

Suporte a persistência de subconjuntos de campos de um modelo

Foi incluído o novo argumento update_fields no método Model.save(). Com ele é possível salvar apenas um subconjunto dos campos de um modelo. Esse recurso pode ser útil por motivos de desempenho ou para evitar sobrescrever mudanças concorrentes.

Instâncias de modelos relacionados passam a ficar em cache

O ORM do Django passa a evitar que uma nova consulta SQL seja disparada nos casos em que seja invocada uma instância de um modelo que possui relacionamento com outro que já foi recuperado do banco. Para exemplificar, na linha 3 do exemplo abaixo já não é mais necessária uma ida ao banco para recuperar first_choice.poll:

>>> first_poll = Poll.objects.all()[0]
>>> first_choice = first_poll.choice_set.all()[0]
>>> first_choice.poll is first_poll
True

Tag {% verbatim %}

Esta tag evita que o conteúdo do bloco seja renderizado. É útil nos casos em que, por exemplo, queremos evitar um trecho de código Javascript que conflita com a sintaxe do template seja renderizado.

{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}

Existem ainda muitas outras mudanças nessa nova versão do Django, incluindo algumas incompatibilidades com versões anteriores, para as quais vale a pena ficar atento antes de disponibilizar suas aplicações.

Referência: Django 1.5 release notes

Hack Design: aulas de design para programadores

Se você se considera um bom programador, mas todo mundo vive reclamando da deficiência estética de suas interfaces gráficas, seus problemas acabaram! Bom, pelo menos se você tiver interesse em acompanhar as lições de design para hackers do Hack Design, não vai ser por falta de informação de alta qualidade que a cara da sua aplicação vai desanimar os usuários.

O objetivo do projeto é tornar o assunto “design” mais acessível, mostrando como lidar com suas nuances e subjetividades. Para isso, alguns designers reconhecidos foram consultados para fazer uma curadoria dos livros, blogs, games, vídeos e tutoriais mais úteis para aprender os elementos fundamentais do design.

O projeto consiste em lições semanais que são enviadas por email aos assinantes. Cada lição é composta por uma ou mais indicações de recursos (filme, artigo, jogo etc.) sobre o tema da lição (tipografia, design para dispositivos móveis etc.). Mesmo quem preferir não assinar a newsletter, pode ter acesso livre a todas as lições já disponibilizadas.

A lição número 0, por exemplo, é assistir ao filme Objectified, que trata sobre como o design está presente em praticamente tudo o que nos rodeia.

Referência: Hack Design

Você também pode se interessar por:

Contando ocorrências de valores em Python

python-doc-iconUma operação bastante comum em várias aplicações é a contagem da frequência da ocorrência de valores em uma determinada lista. Para facilitar nossa vida, o Python traz em sua biblioteca padrão a classe Counter, que é parte do módulo collections.

O uso de Counter é bastante simples: para instanciar a classe, passamos uma sequência qualquer como argumento para seu construtor. Vamos supor que queremos saber quantas vezes cada caractere aparece na frase “o rato roeu a roupa do rei de roma”. Como uma string é uma sequência, podemos fazer:

>>> from collections import Counter
>>> c = Counter('o rato roeu a roupa do rei de roma')
>>> c
Counter({' ': 8, 'o': 6, 'r': 5, 'a': 4, 'e': 3, 'd': 2, 'u': 2, 'i': 1, 'm': 1, 'p': 1, 't': 1})

Como podemos ver, o caractere mais frequente é ‘ ‘ (espaço), com 8 ocorrências, seguido por ‘o’ com 6, depois por ‘r’ com 5 e assim por diante.

Counter é uma subclasse de dict, portanto podemos acessar seus elementos por meio de índices, do mesmo jeito que fazemos com dicionários. Isso é útil quando queremos saber qual a contagem específica de um determinado elemento. Por exemplo, para saber a frequência apenas da letra ‘r’, fazemos:

>>> c['r']
5

Entre outros métodos, a classe Counter oferece o most_common([n]) que, como seu nome descreve, retorna as n ocorrências mais frequentes da sequência. Então para saber, por exemplo, quais foram os dois times com mais títulos da NBA nos últimos dez anos, bastaria fazer:

>>> nba = ['San Antonio Spurs', 'Detroit Pistons', 'San Antonio Spurs', 'Miami Heat', 'San Antonio Spurs', 'Boston Celtics', 'Los Angeles Lakers', 'Los Angeles Lakers', 'Dallas Mavericks', 'Miami Heat']
>>> Counter(nba).most_common(2)
[('San Antonio Spurs', 3), ('Los Angeles Lakers', 2)]

Note que, em caso de elementos com o mesmo número de ocorrências (“Los Angeles Lakers” e “Miami Heat”, nesse exemplo), a ordenação é aleatória.

Plugins do Sublime Text para desenvolvimento WordPress

Plugins do Sublime Text para desenvolvimento WordPressDurante os últimos dois anos, o Sublime Text vem se estabelecendo como um dos editores de texto mais populares entre programadores, designers e usuários avançados em geral. Sua flexibilidade e riqueza de recursos o tornam uma ferramenta completa e versátil.

Como não poderia deixar de ser, logo surgiu uma infinidade de plugins e extensões do Sublime Text para o desenvolvimento na plataforma do WordPress, um CMS que dispensa maiores apresentações. Seguem uma lista com alguns plugins que podem facilitar bastante a vida dos desenvolvedores e integradores WordPress:

Sublime Text Snippet Library For WP

Traz atalhos para vários trechos de código (snippets), que economizam tempo na hora de lembrar e digitar.

Plugins do Sublime Text para desenvolvimento WordPressWordPress New Project Config

Na verdade este não chega a ser um plugin, mas sim um script que tem como objetivo poupar a chateação de todas as tarefas repetitivas que é preciso realizar toda vez que você inicia um novo projeto WordPress. Depois de fazer coisas como: perguntar o nome do novo projeto, criar uma pasta para o projeto, instalar o build mais recente do WordPress, apagar os temas padrão que não serão utilizados, entre outras tarefas, o script inicia o Sublime Text com o novo projeto pronto para começar o desenvolvimento.

Genesis

Outra coleção de snippets, desta vez mais voltada para o desenvolvimento de temas usando o framework Genesis

Search WordPress Codex

Este plugin permite realizar buscas na referência oficial do WordPress sem precisar sair do editor. Após instalado, basta dar um Ctrl + Shift + P e digitar WordPress Codex, ou clicar com o botão direito em qualquer função e selecionar WordPress Function Reference.

Sublime Text 2 WordPress

Este pacote de trechos de código traz os snippets para WordPress do bundle original para o TextMate.

Referência: WordPress Extensions for Sublime Text 2 (Speckyboy Design Magazine)

Check iO: desafios de programação em Python em forma de jogo de aventura

O que me motivou a dar uma olhada no Check iO foi a divulgação que que se tratava de um jogo de aventura no qual o jogador precisa resolver desafios de programação em Python. Apesar de esperar mais do elemento “jogo”, é um dos sites de desafios mais agradáveis de se utilizar que já experimentei. Os belos gráficos das ilustrações dão um clima especial à história que vai se desenrolando à medida que vamos resolvendo os desafios. Aliás, para o pessoal que curte coding dojo, o Check iO é uma ótima fonte de inspiração para escolher problemas.

Check iO: desafios de programação em Python em forma de jogo de aventura

Check iO: use Python para resolver problemas e progredir na aventura

A apresentação de cada desafio é um trecho da história da aventura, na qual os personagens precisam, por exemplo, resolver problemas na programação dos robôs e máquinas que são usados para se locomover entre as várias ilhas que compõem o mundo do game. Cada desafio vale um determinado número de pontos de acordo com o grau de dificuldade. Existe ainda um sistema de mentoria, no qual os jogadores podem escolher um mentor para orientá-los na resolução dos problemas. No geral, o site é mais um recurso muito útil no aprendizado e prática de programação, pois apresenta a resolução de problemas de forma lúdica e divertida.

Qual a melhor IDE para Python?

Há alguns dias, o post IDEs Are a Language Smell causou furor em pelo menos três listas de discussão das quais participo (sem contar em outros fóruns ao redor do mundo). Entre mortos, feridos e o fogo cruzado de acusações de arrogância, salvaram-se todos. O lado bom da polêmica foi que o pessoal da comunidade Python Brasil ficou motivado para atualizar a página do wiki sobre IDEs para Python. Aliás, não se passa uma semana sem que um iniciante faça essa pergunta – completamente legítima por sinal – na lista de discussão: Qual a melhor IDE para programar em Python?

Qual a melhor IDE para programar em Python?

Essa simples indagação costuma despertar a ira de algumas pessoas. Acredito que menos pela pergunta em si do que pela enxurrada de respostas nas quais cada um indica a sua IDE/editor favorito. Não clique aqui.

Na minha opinião, a melhor resposta para a maior parte desse tipo de pergunta “teimosa” e polêmica, em qualquer área do conhecimento humano, é o bom e velho…

— DEPENDE.

O que você realmente quer é usar “a melhor” IDE ou somente quer saber o que os programadores um pouco mais experientes usam? Python é sua primeira linguagem ou você vem de uma cultura de plataformas que têm IDEs oficiais de fato (Java = Eclipse) ou de direito (.Net = Visual Studio)? Qual o sistema operacional que você usa? Qual o tipo de aplicação que você pretende desenvolver: Scripts para linha de comando? Aplicações web? Aplicações com GUI para desktop?

Como podemos ver, existem muitas variáveis a serem levadas em consideração. Sem saber a resposta para cada uma dessas perguntas, é quase impossível que alguém venha com uma resposta única, definitiva e que vai te deixar feliz para sempre.

Minha resposta default

Não existe algo como “a melhor” IDE, acredite. Se existisse, todos estariam usando. Python é uma linguagem que se destaca por ser intuitiva, legível e de código fácil de manter. Por isso, um bom editor de textos  e o interpretador interativo devem ser o suficiente para a maior parte dos casos. Alguns editores de texto recomendados são:

Sublime Text Dicas

No entanto, se você já tem o hábito de usar IDE e tem certeza de que não quer experimentar um estilo mais simples de programar, tente as opções a seguir e escolha a que for mais confortável para você:

Lembre-se sempre de que é uma decisão pessoal. Todas as opções apresentadas tem vantagens e desvantagens. Somente você pode avaliar qual delas atende suas necessidades.

Criando plugins para Sublime Text

Criando plugins para Sublime Text

Conheci o Sublime Text há pouco mais de um ano, por indicação do pessoal da comunidade Python Brasil. Desde então, tenho usado este editor de texto como alternativa às IDEs pesadas, caras e com muitos recursos que acabam subutilizados.

Logo nos primeiros minutos de uso, os novos usuários podem notar que o Sublime Text se destaca por sua interface limpa e rápida. O editor dispõe de um interessante mini-mapa que permite visualizar o código “do alto”, facilitando a localização. Também é possível editar texto lado a lado em múltiplos painéis (mão na roda para escrever HTML e CSS, por exemplo). Os recursos de seleção e edição de textos são intuitivos e proporcionam alto ganho de agilidade. Experimente a busca e seleção de múltiplos trechos para entender do que estou falando.

Mesmo com todos estes recursos, onde o Sublime Text realmente brilha é na capacidade de estender suas funcionalidades por meio de plugins personalizados, de forma que os usuários possam incrementar o editor com novos recursos de acordo com suas necessidades. Os plugins são escritos em Python e existe todo um ecossistema de publicação e gerenciamento de pacotes de plugins.

Por que você deveria aprender a escrever plugins para o Sublime Text?

Uma vez convencido de que o Sublime Text é o editor certo para você, o próximo passo é saber como tirar dele o máximo de funcionalidade. Andrew Hunt e David Thomas, no seu clássico livro The Pragmatic Programmer, defendem que um programador deve usar um único editor para todas as suas tarefas e usá-lo bem. Além disso, um bom editor deve possuir três características fundamentais: ser configurável, ser extensível e ser programável. Sendo assim, é importante desenvolver a capacidade de prover o editor com os recursos que você precisará para que seu projeto ganhe em produtividade, evitando inconsistências e duplicação de esforços.

Por onde começar?

Após baixar e instalar o Sublime Text no seu sistema operacional (existem versões para Linux, Mac e Windows),  vamos escrever um plugin simples para inserir a data e hora atuais no final do texto.

Selecione o item de menu Tools > New plugin… O seguinte trecho de código será criado automaticamente numa nova aba do editor:

import sublime, sublime_plugin
class ExampleCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.view.insert(edit, 0, "Hello, World!")

O que este código Python faz é inserir a frase “Hello, World!” no início do texto. Para testá-lo, salve o arquivo  com o nome example.py na pasta Packages/User (crie caso não exista), que fica dentro do diretório de instalação do Sublime Text. Em seguida, abra uma nova aba vazia, digite um trecho de texto qualquer e depois abra o console do Sublime Text (View > Show console). No console, digite:

view.run_command('example')

Se tudo ocorrer como esperado, deve surgir a frase “Hello, World!” no editor, logo no início do texto.

Agora vamos fazer algumas pequenas modificações no código para que o plugin faça o que nós queremos. Para obter a data e hora atuais, precisaremos de recursos do módulo datetime do Python. Então, acrescentamos no início do nosso código a linha:

import datetime

Depois, substituímos a string “Hello, World!” no corpo do método run() pelo código que nos retorna a string formatada correspondente a data e hora atuais. A última linha fica assim:

self.view.insert(edit, 0, datetime.datetime.now().strftime('%d/%m/%y, %H:%M'))

Por fim, queremos que a data e hora sejam inseridas no final do texto e não no início. Para isso precisamos modificar o valor do segundo parâmetro passado para o método insert, que indica a posição em que a string deve ser inserida. Atualmente o valor é 0 (zero), que indica a primeira posição da tela.

Para informar o valor da última posição, devemos passar o tamanho do texto já existente. Esse valor é obtido chamando o método size() do objeto view. Dessa forma, a última linha passa a ser:

self.view.insert(edit, self.view.size(), datetime.datetime.now().strftime('%d/%m/%y, %H:%M'))

Execute o comando novamente através do console e a string com a data e hora deve aparecer ao final do texto. Está pronto o código do nosso primeiro plugin para Sublime Text.

Atribuindo uma tecla de atalho

Agora vamos associar uma combinação de teclas de atalho para executar o novo comando disponibilizado pelo plugin que acabamos de escrever. No Sublime Text, as combinações de teclas de atalho são configuradas em arquivos JSON. As combinações de teclas são específicas para cada sistema operacional, o que nos obriga a criar três novos arquivos se quisermos que nosso plugin funcione em qualquer plataforma: Default (Windows).sublime-keymap, Default (Linux).sublime-keymap e Default (OSX).sublime-keymap. Para fazer com que a data e hora sejam inseridas com a combinação de teclas Shift+Alt+D, o conteúdo de cada um dos arquivos deve ser:

[
	{
		"keys": ["shift+alt+d"], "command": "example"
	}
]

Os arquivos devem ser salvos na mesma pasta em que está localizado o example.py. Desse modo, ao pressionar a combinação de teclas que atribuímos, a data e hora atuais serão inseridas no final do texto que estivermos editando.

Exemplo de Código

Para fins de estudo, escrevi um pequeno plugin que serve para inserir docstrings em funções/métodos de um programa Python. O plugin AddPythonDocstrings é do tipo TextCommand e serve como exemplo de uso de algumas funções comuns na localização e manipulação de trechos do texto.

Esta foi uma rápida amostra das possibilidades dos plugins para Sublime Text. Para mais detalhes sobre como desenvolver plugins mais complexos, bem como para uma melhor compreensão da API de plugins, recomendo estudar a documentação indicada nas referências abaixo.

Referências

  1. Sublime Text API Reference
  2. How to Create a Sublime Text 2 Plugin
  3. Plugin Development Forum
  4. Sublime Text Unofficial Documentation

Como fazer consultas GQL pela chave da entidade no Google App Engine

Google App EngineA chave de cada entidade armazenada no datastore pode ser acessada por meio do seu atributo __key__. Este atributo, por sua vez, é uma instância da classe Key. Sendo assim, para realizar uma consulta pela chave da entidade, o parâmetro precisa ser um objeto da classe Key. Para criá-lo, basta chamar seu construtor, passando a string da chave como argumento. A seguir, um exemplo:

SELECT * FROM Pessoa WHERE __key__ = Key('agRmMWdwcgwLEgRSYWNlGMmWKww')