Monday, March 26, 2012

Adeus @luciano, olá @ramalhoorg

Estou abandonando gradualmente minha conta @luciano no Twitter e começando a usar @ramalhoorg. A partir de 27/mar/2012, a conta @luciano vai publicar somente retweets do @ramalhoorg, e avisos periódicos para que as pessoas sigam a nova conta.

Para lembrar, é fácil: meu email pessoal termina com ramalho.org (e o Twitter não aceita ponto no nome).

PORQUE ESTOU MUDANDO O NOME

Parece ótimo ter um nome simples como @luciano no Twitter. O problema é que @luciano é um nome comum, e tem uns lucianos mais famosos do que eu, parece que um até apresenta um programa de auditório, imaginem só.

Muita gente não sabe que no Twitter o espaço em branco é importante. Se você manda um recado para "@luciano bla", o Sr. Bla nunca vai saber, e eu vou receber o recado. Eu recebo centenas de recados de outras pessoas todo dia no Twitter.

E a minha lista de menções é inútil: a maioria das vezes que @luciano aparece no Twitter, eu não sou a pessoa que queriam mencionar. Com isso eu muitas vezes não vejo mensagens que seriam para mim.

Então, meus amigos, por gentileza sigam o @ramalhoorg e esqueçam o @luciano, OK?

Tuesday, November 15, 2011

Curso Online: Python para quem sabe Python

Este mini-curso de 12h destina-se a pessoas que já estudaram ou até já usam Python no dia-a-dia, mas querem conhecer mais profundamente como a linguagem funciona, como o Django e outros frameworks conseguem fazer certas coisas que parecem mágica, e como aproveitar recursos de Python que não existem em outras linguagens.

Tópicos


  • pérolas sub-utilizadas da biblioteca padrão
  • sobrecarga de operadores: usos benéficos
  • iteráveis e iteradores, geradores
  • comando with e gerenciadores de contexto
  • programação funcional e decoradores de funções
  • acesso, criação, remoção dinâmica de atributos
  • propridades e descritores
  • tratamento de acessos não previstos (ex. como "method_missing" de Ruby)
  • criação dinâmica de classes e monkeypatching
  • metaclasses

Formato

  • Instrutor: Luciano Ramalho
  • Curso online, com aulas interativas
  • Carga horária total: 12h
  • Preço: R$ 250
  • Vagas limitadas

Datas e Horários

Uma das opções a seguir será escolhida pela maioria dos interessados:
  • Sábados, 10h-13h (dias: novembro 26, dezembro 3, 10 e 17)
  • 2ª e 4ª-feira, 17h30-19h30 (dias: novembro 28 e 30, dezembro 5, 7, 12, 14)
  • 3ª e 5ª-feira, 21h-23h (dias: novembro 29, dezembro 1, 6, 8, 13, 15)

Para se inscrever

INSCRIÇÕES ENCERRADAS, EM 2012 TEM MAIS!
Se você tem interesse em participar deste curso, preencha o formulário cujo link aparece abaixo. Lá você terá a oportunidade de escolher o horário mais conveniente, e propor outros temas a serem tratados. Verifique com cuidado seu e-mail: eu vou entrar em contato pessoalmente com cada interessado para dar mais informações e esclarecer eventuais dúvidas.
Formulário de pré-inscrição (sem compromisso)


PS. O nome deste mini-curso foi inspirado no título de um livro de PHP do Juliano Niederauer, publicado pela editora Novatec. Mandou bem, Juliano!

Monday, October 31, 2011

Academia Python: de 0 a 100 em 3½ meses

Quem me conhece sabe que eu adoro lecionar, e nos últimos anos tenho trabalhado como desenvolvedor de sistemas usando a elegante e poderosa linguagem Python, a minha favorita no momento.

Agora estou unindo essas duas paixões, lançando em parceria com a Globalcode a Academia Python, uma formação completa para programadores, que leva do básico ao avançado nesta linguagem, em 3 meses e meio de aulas, 2 vezes por semana.

Porque Python é especial

Python é uma linguagem muito simples para começar a aprender, mas ao mesmo tempo é largamente utilizada para inovação em uma grande variedade de empresas, como YouTube, Industrial Light & Magic, Globo.com e Dropbox.

Existem outras linguagens simples de aprender, mas elas costumam ter limitações práticas que atrapalham seu uso em ambientes profissionais, e existem outras linguagens usadas profissionalmente, mas nenhuma é tão fácil de aprender quanto Python.

Qual é o segredo deste mistério? As principais idéias de Python vêm da linguagem ABC, desenvolvida ao longo de 10 anos de pesquisa científica e testes com usuários para chegar a uma linguagem amigável e prática. Por exemplo, o laço for do Python é o mais simples possível:

>>> for letra in 'Python':
...     print letra
... 
P
y
t
h
o
n

Ao mesmo tempo, é uma linguagem que oferece recursos avançados e modernos de programação, como Orientação a Objetos com sobrecarga de operadores e meta-classes, iteradores, co-rotinas, meta-programação. O resultado é que Python vem sendo cada vez mais usada como primeira linguagem em cursos de computação ao redor do mundo (da FATEC ao MIT), e ao mesmo tempo é usada em grandes sites como Google, YouTube, Globo.com, nas principais empresas computação gráfica, como Industrial Light & Magic, The Foundry, e Autodesk. Python vem pré-instalada no Mac OSX e em praticamente qualquerLinux, e é fácil de instalar no Windows.

Porque fazer uma Academia na Globalcode

A Globalcode é uma empresa que tem tido muito sucesso oferecendo cursos sobre Java há 10 anos. Uma das fórmulas desse sucesso tem sido as Academias: formações completas com mais de 100 horas de aula (para comparar, uma disciplina típica de computação na USP tem 60 horas). Enquanto muitos cursos livres concentram conteúdo em turmas intensivas de curta duração, as Academias oferecem 8 horas de aula por semana, assim os alunos têm tempo para absorver, exercitar e aplicar o que foi visto no curso. A Academia Python tem 112 horas, o que dá 14 semanas (sem contar feriados). São três meses e meio de convívio entre alunos e o instrutor, uma vivência muito mais rica do que um curso rápido pode oferecer.

Como é a Academia Python

A estrutura da Academia Python reflete as próprias características da linguagem: começa com um módulo básico de 16 horas, acessível para qualquer pessoa que saiba programar em qualquer linguagem, mas chega ao quinto módulo abordando tópicos avançados como bancos de dados não-relacionais, programação assíncrona de alto desempenho e arquiteturas de sistemas distribuídos na nuvem (cloud computing).

Os módulos são:

  1. Introdução à linguagem Python: dominando a sintaxe, tipos de dados e funções básicas através de tarefas práticas de conversão de arquivos (16h)
  2. Orientação a Objetos e frameworks: exemplos em Django (framework Web) e Tkinter (desktop GUI) para demonstrar para que servem e como usar os conceitos de encapsulamento, herança e polimorfismo (24h)
  3. Desenvolvimento Web com Django e JQuery: como construir uma aplicação Web moderna usando Django, framework adotado pela Globo.com e JQuery, a biblioteca JavaScript mais importante do momento (32h)
  4. Django profissional: tópicos avançados de desenvolvimento Web com Django, incluindo testes automatizados, deployment com Apache e lighttpd, migração de modelos de dados e geração de relatórios em PDF, entre outros (20h)
  5. Cloud, NoSQL e novas arquiteturas: Google App Engine, MongoDB e programação assíncrona com para sites altamente escaláveis (20h)

Para saber mais

A primeira turna da Academia Python está prevista para começar dia 8 de novembro, com aulas 3ª e 5ª de 19h a 23h na Globalcode de São Paulo (metrô Paraíso). Mais detalhes, preços e matrícula na página da Academia Python na Globalcode.

Dia 1º de novembro vamos oferecer um mini-curso gratuito de Introdução à Programação Orientada a Objetos em Python na Globalcode de São Paulo (metrô Paraíso) e também via Webcast. Inscrições pelo site da Globalcode.

Saturday, June 18, 2011

Dorneles Treméa, o grande Déo

Hoje é aniversário do Déo: #dornelesday.

Tive o prazer de conhecer o Déo em 2002, no primeiro sprint de Zope do Brasil (talvez o primeiro sprint de todos os tempos no Brasil? Se não, foi um dos primeiros).

O Déo era um dos brilhantes imberbes que tinham criado a X3NG, uma das duas primeiras empresas especializadas em Python e Zope no Brasil. Eu era o barbudo que tinha criado, junto com outro imberbe, a outra empresa brasileira focada em Python e Zope na época, a Hiperlógica.

Nos próximos 5 anos assisti meio de longe a carreira meteórica do Déo, de pequeno empreendedor em Caxias do Sul a hacker internacional disputado pelas mais importantes empresas de Plone do mundo (ele trabalhou nas empresas dos dois líderes do projeto Plone). Ao pesquisar como se fazia alguma coisa com Plone, vira e mexe a gente era guiado pela inteligência e generosidade do Déo, na forma de muito código em repositórios, mensagens em listas, e dicas no IRC. Eu nunca fui grande frequentador do IRC, e sei que isso me privou de muito contato com o Déo. Felizmente a gente sempre se via nos eventos comunitários: FISL e PythonBrasil. Era uma alegria encontrar o Déo ao vivo, sempre sorridente, carinhoso com os amigos, grande contador de estórias. Agora estou me emocionando ao lembrar de sua voz e seu sotaque da serra gaúcha.

Em 2007, criamos a Associação Python Brasil, junto com vários amigos e colegas da comunidade. Com isso, aumentaram muito as oportunidades de encontrar o Déo virtualmente. Ele foi o nosso primeiro diretor administrativo, e fomos companheiros nas longas batalhas com a burocracia nacional até conseguirmos um CNPJ e uma conta bancária para finalmente concretizar a APyB. Não é mera coincidência que a sede jurídica da APyB seja em Caxias do Sul: sem o Déo, o que levou quase dois anos talvez levasse cinco (e até hoje não teríamos uma conta no banco!). Para mim uma das melhores coisas de participar da gestão da APyB era poder colaborar com o Déo. Todo mundo sabe que o Déo era o parceiro ideal para qualquer empreitada: ponta firme, positivo, safo no melhor sentido. Com ele não tinha tempo ruim, prazo curto demais e nem problema sem solução.

Foi também em 2007 que o Déo fez uma palestra inesquecível na PythonBrasil em Joinville. O tema era simplesmente "Empreendedorismo", e foi a melhor aula sobre o assunto que eu já vi. Um depoimento franco e cheio de humor, deixando claro o seguinte: não basta ser inteligente e ter conhecimento, é preciso muita persitência e garra para dar certo como empreendedor, e essas coisas o Déo também tinha de sobra. Se você pensa ou já pensou em ser empreendedor, corra e assista agora.

Esse post do blog do Déo em 2007 é uma boa amostra de quem foi esse cara.

Foi um choque para mim quando o Érico me contou que o Déo tinha sofrido um acidente de carro e não tinha resistido. Até hoje pensar nisso me dá um nó na garganta. Eu não convivi com o Déo nem 1% do que gostaria, mas o convívio que eu tive foi maravilhoso. Nesses 9 anos de contato em doses homeopáticas, o Déo deixou de ser imberbe, e este barbudo aqui aprendeu muito com ele.

Tenho certeza que o Dorneles nunca será esquecido. Ele tocou de forma muito intensa e muito positiva muita gente. Para mim, foi uma das pessoas mais inspiradoras com quem pude conviver. Um grande abraço, Déo.

Wednesday, March 30, 2011

Orientação a Objetos em Python no Garoa Hacker Clube

Hoje à noite, de 20h âs 22h30 no Garoa Hacker Clube em São Paulo [1] apresentarei a minha aula favorita de Python, "OO em Python".

[1] http://garoa.net.br/wiki/Garoa_Hacker_Clube:Sede

O objetivo desta aula é apresentar o essencial de como se usa orientação a objetos em Python, especialmente para aqueles que aprenderam OO em outras linguagens e por isso talvez não aproveitem da melhor forma as facilidades que Python oferece mas que não existem ou são diferentes nessas outras linguagens. Facilidades como:

  • polimormismo (toda lingagem OO faz, mas as dinâmicas levam às últimas consequencias)
  • sobrecarga de operadores (sim, é possível usar bem para fazer programas mais claros)
  • herança múltipla (não é coisa do demônio)
  • controle de atributos via properties e descritores (quem falou que em Python não em encapsulamento?)
  • atributos virtuais (similar ao methodmissing do Ruby, porém mais genérico)
e até, se der tempo...
  • metaclasses (porque afinal, toda classe é uma instância!)

Como todas as atividades do Garoa Hacker Clube, esta é aberta e gratuita. Basta chegar e sentar.

Não é preciso se inscrever.

PS. A atividade não será gravada e/ou transmitda pela Internet ao menos que algum voluntário grave e/ou transmita pela Internet.

Saturday, December 4, 2010

Por que bibliotecários usam bancos de dados esquisitos...

...e por que eles estão certos.

Este seria o tema da minha monografia de conclusão no curso de Biblioteconomia na ECA/USP, se o decôro acadêmico não demandasse algo mais sóbrio. Então o título ficou sendo:
O Modelo de Dados Semiestruturado em Bases Bibliográficas:
do CDS/ISIS ao Apache CouchDB
.

Hã?

Boa pergunta! É que, hoje, banco de dados é sinônimo de banco de dados relacional, com linguagem SQL e tal. Só que este é apenas um tipo de banco de dados. É o tipo dominante no mercado, mas apenas um tipo. Sempre existiram alternativas, e agora existem ainda mais bancos de dados não-relacionais, apelidados de NoSQL. O Google, o Facebook e a Amazon.com dependem de sistemas NoSQL para funcionar.

Há 25 anos a BIREME/OPAS/OMS, onde eu trabalho, usa o ISIS, um banco de dados NoSQL criado pela Unesco. O ISIS é um banco de dados orientado a documentos. Outros BD orientados a documentos modernos são o CouchDB e o MongoDB.

Os objetivos do meu TCC foram:


  • Analisar o ISIS a partir da teoria de bancos de dados semiestruturados, que é a base teórica dos BD orientados a documentos.

  • Migrar uma base de dados do ISIS para o CouchDB, documentando o processo e criando ferramentas de apoio.

Apresentarei a monografia dia 15/12, 10h, na ECA/USP, sala 247 (bloco principal, 2º andar). Apareça!

A banca será formada pelo orientador Marcos Mucheroni (biblioteconomia, ECA/USP) e por Fernando Modesto (biblioteconomia, ECA/USP) e João Eduardo Ferreira (computação, IME/USP).

Depois da apresentação colocarei aqui um link para o PDF da monografia, em acesso aberto.

Atualização: publiquei os arquivos PDF da monografia revisada e slides usados na defesa. O texto e os slides podem ser considerados Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Brazil. Se você usar parte deste material para algum trabalho ou atividade, por gentileza coloque um comentário aqui contando como usou, OK?

Tuesday, January 19, 2010

Django-Brasil ultrapassa Zope-PT

Conforme eu previa, em algum momento de 2009 a lista django-brasil ultrapassou em número de assinantes a lista zope-pt. Alguém sabe exatamente quando foi?

Na minha palestra-relâmpago na PyCon 2009 em Chicago eu mostrei números que indicavam que isso estava prestes a acontecer.

Então por esse critério o Django é hoje o mais popular framework Web da linguagem Python no Brasil.

Parabéns a todos que ajudaram isso a acontecer, como usuários, consultores, tradutores, autores, instrutores e evangelizadores!

A simplicidade, a praticidade e o poder do Django combinam com o jeito Python de programar. Assim como Python, Django faz bem para a auto-estima do principiante (como diz o Marco André).

Ao mesmo tempo, Python e Django vêm com pilhas incluídas (componentes prontos para usar), e não se limitam a soluções simples, pois oferecem ferramentas e extensibilidade para programadores experientes produzirem sistemas muito sofisticados, flexíveis e robustos.

O sucesso do Django foi a melhor coisa que aconteceu para o Python nos últimos anos.

Monday, January 18, 2010

Três perguntas sobre Python

Desde quando o Google e o Youtube usam Python?

Desde o início. Os algoritmos inovadores do Google foram criados em Python e em C, e até hoje Python é usada em todos os milhões de servidores do Google. O Youtube já era feito em Python antes de ser adquirido pelo Google. Veja a página About Google de 1998 e o depoimento de Peter Norvig, diretor de pesquisa do Google e co-autor do livro Inteligência Artificial: uma abordagem moderna. Ah sim: a primeira linguagem suportada no Google App Engine foi Python.

Porquê o MIT está usando Python?

O Massachussetts Institute of Technology, a mais famosa escola de engenharia do mundo, está usando Python em sua principal disciplina introdutória de computação. Python foi adotada porque possui bibliotecas muito versáteis (redes, robôs, computação gráfica, etc.) e permite explorar conceitos avançados de orientação a objetos e meta-programação, mas tem uma curva de aprendizagem suave. O livro-texto adotado pelo MIT já foi traduzido pela comunidade Python brasileira: Aprenda Computação com Python.

Existe emprego para programadores Python?

Sim. Hoje existem mais vagas para .Net, Java e PHP do que para Python, mas as vagas para programadores Python são mais atraentes. O motivo é que Python não é uma opção "default", mas é uma escolha consciente feita por empresas que se preocupam com qualidade e buscam inovação, e isso se reflete em melhores condições de trabalho, salários maiores e ambientes mais estimulantes para a pesquisa e a aprendizagem. O programador milionário Paul Graham blogou sobre isso: The Python Paradox.

Para quem tem um perfil mais empreendedor: vários programadores Python brasileiros atendem clientes no exterior, vivendo no Brasil e recebendo em dólar ou euros. Outros tantos foram convidados para trabalhar no exterior. A demanda de especialistas em Python é muito maior que a oferta, e isso cria grandes oportunidades profissionais.

Monday, November 9, 2009

Como usar bpython com Django

O bpython é um espetacular console interativo Python com auto-completar visual e help. Funciona no Linux, Mac OSX e Unixes em geral, mas não no Windows porque depende do módulo curses.

Os screenshots não fazem justiça ao programa, porque nele tudo é dinâmico, então você precisa mesmo experimentar para sacar. Além disso ele é mais bonito no Linux que no Mac OSX porque as linhas verticais aparecem contínuas.

Para quem usa Windows, o IPython também é legal, e vale muito a pena usá-lo com o Django.

Mas para quem pode usar o bpython eis como fazer.



Método 1: ler manualmente os settings do django

1) Inicie a sessão do bpython a partir do diretório principal do seu projeto Django (onde fica o arquivo settings.py).

2) Digite no prompt >>>

from django.core.management import setup_environ
import settings
setup_environ(settings)


A partir desse ponto, você pode interagir normalmente com os modelos e outros objetos da sua aplicação Django.



Metodo 2: rodar um script que lê os settings, e entrar em modo interativo


1) crie um arquivo (digamos, .dbpython.py) com o conteúdo:

from django.core.management import setup_environ
import settings
setup_environ(settings)
from minha_app.models import * # opcional


Note que a quarta linha é opcional, e você precisa alterar o nome da app, e repetir essa linha para cada app que quiser acessar com mais comodidade.

2) execute o script usando o bpython com a opção -i (que faz entrar em modo interativo, como no python normal):

$ bpython -i dbpython.py


3) Bônus: para não ter que digitar o comando acima toda vez, crie um script de shell:

#!/bin/sh
# este eh o arquivo dbp.sh
bpython -i dbpython.py


Depois torne este script executável:

$ chmod +x dbp.sh


Agora basta digitar:

$ ./dbp.sh


E pronto, as maravilhas do bpython!



Metodo 3: configurar um script de inicialização para o bpython

Este é o método documentado no site do bpython:

http://docs.bpython-interpreter.org/django.html

Eu estou usando o método 2 porque gostei de ter um script dbpython.py customizado para o meu projeto atual, assim eu faço os imports dos models das apps que estou desenvolvendo.

Claro que seria possível sem muito esforço alterar o dbpython.py para fazer os imports dos models automaticamente, lendo o atributo settings.INSTALLED_APPS, mas isso fica como um exercício para o leitor.

Agradeço ao meu colega de trabalho, Fabio Montefuscolo, pela dica que deu início a este post.

Wednesday, August 26, 2009

Construção civil e engenharia de software

A construção de uma casa nos EUA é muito diferente da construção de uma casa no Brasil. Aqui a casa comum é construída tijolo por tijolo, azulejo por azulejo, telha por telha. Numa economia mais desenvolvida, os custos de mão de obra tornam inviável esse modo de construção artesanal.

A casa típica da classe média americana não é propriamente construída, e sim montada. Apenas a construção da fundação se parece com o que se faz no Brasil. Sobre a fundação, a casa gringa é montada a partir de elementos estruturais, paredes, pisos e coberturas que chegam prontos ao local da construção, como um kit. As peças em sua maioria já vem até cortadas nos tamanhos e formatos certos. Os banheiros, que são a parte mais complicada de qualquer casa, costumam ser entregues prontos: chegam pré-montados em uma carreta e são colocados no lugar por um guindaste.

Em outras palavras, os americanos montam casas mais ou menos como se montam automóveis nos EUA, no Brasil ou em qualquer lugar. Na Ford por exemplo, desde os tempos do Modelo T, motores, painéis e bancos não são construídos na linha de montagem, mas apenas integrados. Ou seja, a prática da construção civil americana já é industrial, enquanto que a brasileira ainda é artesanal.

Na engenharia de software o sonho que vem impulsionando a adoção da Orientação a Objetos é o uso de componentes pré-montados, permitindo a redução do tempo de desenvolvimento e o aumento da qualidade. Quando as aplicações são feitas artesanalmente, a produtividade é muito baixa. Esse modelo só se sustenta quando a remuneração dos programadores também é baixa. Vira um ciclo vicioso: o cara ganha pouco porque trabalha mal, e trabalha mal porque ganha pouco. Como ganha pouco tem que trabalhar muito, e aí não tem tempo para estudar.

O uso de frameworks vai além: oferece um conjunto de componentes já integrado, e o papel do programador passa a ser implementar componentes específicos que se conectam de forma bem definida aos demais. O framework é como o kit estrutural de uma casa.

Usar um framework exige um investimento maior do tempo programador até ele entender como as partes se encaixam e atingir um bom nível de produtividade. Não dá para simplesmente sair programando do jeito que você quer, é preciso estudar antes, às vezes bastante, para entender como programar componentes que vão se encaixar num framework. Mas uma vez superada esta fase, é possível entrar em um ciclo virtuoso: você ganha bem porque produz bastante e com qualidade, e ganhando bem pode investir mais na própria formação e atualização.

Por sinal, uma das melhores formas que eu conheço de investir em mim mesmo é frequentar congressos de alta qualidade como a Python Brasil.

Sunday, August 2, 2009

Unibabel: bricando com Unicode

Este fim-de-semana eu comecei um novo projeto experimental, o Unibabel.

É uma interface Web para explorar a Unicode database que vem embutida na linguagem Python. Eu me divirto passeando entre as páginas e encontrando caracteres, ideogramas e símbolos elegantes, exóticos, familiares ou bizarros.

Veja por exemplo esta página de operadores matemáticos, e esta letra do alfabeto malaio. Link
Serve também como um exemplo bem básico de como fazer rodar uma aplicação Django no Google App Engine.

O código do Unibabel está publicado:

http://code.google.com/p/unibabel/source/browse/unibabel/views.py


Por enquanto o Unibabel não usa o datastore do Google, todos os dados vêm do módulo unicodedata do Python. Futuramente vou usar o datastore para permitir buscas por atributos dos caracteres (por exemplo, listar todos os caracteres numéricos, todos os símbolos, ou todas as variantes da letra 'A'...).

Se alguém quiser colaborar, fique à vontade para clonar o repositório e se fizer algo interessante me manda uma mensagem que eu posso incorporar a sua contribuição.

Tuesday, June 2, 2009

O diabo da acentuação (2)

Com a explosão da Internet, ficou sem sentido continuar usando sistemas de codificação de caracteres diferentes em cada parte do mundo. Mas para unificar, seria preciso uma codificação que não ia caber em um byte. Então a primeira tentativa foi usar dois bytes, o que permite códigos de \x0000 a \xFFFF, ou seja, 65536 caracteres distintos. Era o que propunham as primeiras versões do padrão Unicode. E assim várias linguagens, inclusive Java, adotaram uma representação interna de strings onde cada caractere equivale a dois bytes.

Outra idéia errada: 1 caractere == 2 bytes



Eu aprendi o que era Unicode estudando Java, e sempre achei normal que um caractere Unicode fosse representado por dois bytes em Java, numa codificação chamada UCS2. Até que em 2006 eu comecei a estudar a linguagem Ruby, e constatei que o suporte a Unicode em Ruby era mais primitivo que em Python. Fiquei surpreso porque o criador de Ruby, Yukihiro Matsumoto, é japonês, e a linguagem é muito popular no Japão.

Mas a propaganda aqui no ocidente é que o Unicode veio para resolver o problema das línguas orientais, então porque faltava um bom suporte em Ruby? Quem pesquisar um pouco o assunto vai descobrir que as primeiras versões do Unicode foram rejeitadas pelo chineses, japoneses e coreanos! Os principais motivos foram (1) a unificação de certos ideogramas que embora visualmente parecidos queriam dizer coisas diferentes e (2) a falta de uma especificação de como estender a codificação para além dos 2 bytes. O segundo ponto é interessante: quando se usa um alfabeto, uma nova palavra é apenas um novo arranjo das mesmas letras; mas em chinês, uma nova palavra pode ser um novo ideograma.

Para resolver este problema, é preciso abstrair um pouco mais...

Unicode é uma tabela de codepoints



O foco do padrão Unicode não é estabelecer uma relação entre caracteres e bytes, e sim uma relação entre caracteres e códigos numéricos chamados codepoints. Como estes codepoints serão representados na memória ou em um arquivo é uma questão secundária, até porque diferentes aplicações vão exigir diferentes representações: um formato bom para transmitir pode ser ruim para processar, por exemplo.

Na documentação do Unicode, os codepoints são identificados por números hexadecimais com o prefixo 'U+'. Veja uma pequena amostra de codepoints e caracteres:

U+6C23 氣 CJK UNIFIED IDEOGRAPH-6C23

U+06BF ڿ ARABIC LETTER TCHEH WITH DOT ABOVE

U+2620 ☠ SKULL AND CROSSBONES

U+0D0B ഋ MALAYALAM LETTER VOCALIC R

U+4DF1 ䷱ HEXAGRAM FOR THE CAULDRON

O texto eu caixa alta em cada linha acima é o atributo "name" do caractere, segundo a tabela Unicode. Além de letras de vários idiomas, o Unicode inclui também símbolos matemáticos, naipes do baralho e até hexagramas do I-Ching.

Vale a pena explorar o site oficial do Unicode, em particular as code charts (tabelas de código) onde os milhares de caracteres aparecem agrupados por idioma ou assunto.

O diabo da acentuação

Estamos no meio de uma imensa migração para Unicode, aquela terra prometida onde caracteres acentuados são cidadãos de primeira classe, e até o conceito da energia interior qi pode ser representado na forma original: 氣.

Enquanto não chegamos lá, reina a confusão na terra da acentuação. Em fóruns de programadores a gente vê muita gente perdida, procurando e oferecendo soluções baseadas mais em superstição e mitos do que em razão e fatos.

Este é o primeiro de uma série de posts para tentar esclarecer essa bagunça.

codificação: neste assunto, codicação não tem nada a ver com cifras ou código-fonte. Uma codificação é apenas uma forma de representar caracteres através de códigos numéricos, para armazenagem em computadores digitais.


A idéia errada: 1 caractere == 1 byte



A computação nasceu em países que falam inglês, um idioma onde se usam apenas as 26 letras de A a Z, sem acentos nem cedilhas [1]. Além disso, a memória das máquinas era muito limitada, então depois de alguma briga entre fabricantes americanos e usuários europeus se estabeleceu a idéia equivocada de que um byte corresponde a um caractere.

Essa idéia simplista gerou codificações como esta (clique na figura para ampliar):



Esta figura na verdade representa uma série de gambiarras, uma em cima da outra. Para começar, a faixa preta representa caracteres projetados para controlar um teletipo, um equipamento mais obsoleto até que um mimeógrafo. Por exemplo, o caractere '\x0C' [2], serve para avançar uma folha no papel e o '\x07' é o BELL, faz o teletipo tocar um sino para chamar a atenção do operador!

Apenas três destes caracteres de controle são largamente utilizados hoje: o HORIZONTAL TAB ('\x09'), o LINE FEED ('\x0a') e o CARRIAGE RETURN ('\x0d'). Os 32 caracteres de controle, bem como a faixa azul, formam o padrão ASCII (pronuncia-se ásqui, e não ásqui-2), totalizando 128 caracteres.

A faixa verde é a tabela ISO-8859-1, também conhecida como Latin-1, uma das várias tabelas de caracteres criadas na norma ISO-8859 para padronizar conjuntos de caracteres alfabéticos. Na tabela Latin-1 aparecem todos os caracteres usados nos idiomas da Europa ocidental. A mesma norma ISO inclui outras tabelas, como a ISO-8859-2 (Latin-2), para idiomas da Europa oriental (como Polonês, Tcheco e Húngaro) e a ISO-8859-5 que contém letras do alfabeto cirílico usado na Russia, Bulgaria, Sérvia etc. [3]

As duas fileiras vermelhas são um "puxadinho" feito pela Microsoft. A norma ISO-8859 reservava estas 32 posições para ainda mais caracteres de controle, que nunca "pegaram", então a Microsoft inventou um padrão chamado "CP-1252" [4] que é basicamente a combinação de ASCII com Latin-1 e mais 27 símbolos como o € (euro) o • (bullet) e as aspas assimétricas “assim” que tanto atrapalham a nossa vida de programadores.

Muitos aplicativos, especialmente no mundo Windows, alegam usar a codificação ISO-8859-1 mas na verdade usam CP-1252, violando a lei de Postel [5]. Isso causa alguma confusão porque se você tenta ler um arquivo CP-1252 como se fosse ISO-8859-1, seu programa não vai saber o que fazer com os €, •, “aspas” etc. Mas o inverso não causa problemas: você sempre pode ler um ISO-8859-1 como se fosse CP-1252, porque o primeiro é um sub-conjunto do segundo.

E o 氣?



Realmente não tem espaço naquela tabela para o caractere chinês do "qi" e os outros milhares de caracteres chineses, japoneses, coreanos, ou para dezenas de idiomas que não usam o alfabeto latino, como árabe, hebraico, tailandês e sânscrito. Essa constatação acabou com o princípio de que "1 byte == 1 caractere", e nos conduziu ao Unicode, tema do próximo post.




[1] na verdade, isso já é uma simplificação; qualquer dicionário de inglês tem a palavra façade (fachada), escrita assim mesmo, com cedilha; a palavra virou até um termo técnico em engenharia de software, pois é o nome de um dos padrões de projeto originais.


[2] \x0C é hexadecimal, em decimal seria 12


[3] a ISO-8859-1 (Latin-1) continua importante até hoje, mas a ISO-8859-5 "não pegou". Os russos preferem outros padrões, como KOI-7 ou KOI-8.


[4] conhecido também como "codepage 1252" ou oficialmente "Windows-1252"


[5] "Seja liberal no que aceita conservador no que envia". Procure "Postel Law" no Google e aprenda um princípio realmente importante e útil para a engenharia e para a vida em sociedade.

Monday, April 13, 2009

Python e o caminho do meio

A maneira como Python trata variáveis faz muito sentido, e exemplifica uma característica que eu gosto muito na linguagem: a opção pelo caminho do meio.

A maioria das linguagens segue um de dois caminhos extremos no tratamento de variáveis.

Um dos caminhos é aquele que exige que cada variável seja declarada, como ocorre em C, Pascal, Java etc. O curioso é que várias linguagens obrigam o programador a declarar uma variável, mas nem todas elas obrigam o programador a inicializar a variável antes de usá-la, o que gera bugs que às vezes são difíceis de achar.

Ou seja, tornar obrigatória a declaração da variável é algo que facilita a vida do compilador, mas não necessariamente resolve o problema do programador. Claro que os compiladores modernos reclamam quando encontram variáveis que nunca foram inicializadas em expressões, mas isso é um remendo.

O outro caminho, radical na direção oposta, é o das linguagens que não obrigam a declaração da variável e nem a sua inicialização. É uma tentativa equivocada de simplificar a vida do programador. Linguagens que seguem essa linha são JavaScript, PHP, Perl, Basic e outras chamadas "linguagens de scripting". Em algumas delas (Perl, VisualBasic) você pode mandar o interpretador reclamar quando encontra uma variável não declarada, mas esta opção não costuma ser o default. Em alguns casos a variável não inicializada tem um valor especial como "undefined" ou "null".

Nestas linguagens, a ocorrência de uma variável não inicializada em uma expressão geralmente faz com que ela seja avaliada com algum valor default, tipo 0 (zero) se for uma expressão numérica ou "" (string vazia) etc. Tudo isso faz com que ocorram bugs muito chatos de encontrar, porque se o nome de uma variável é soletrado incorretamente, o programador não é avisado e um valor sem sentido é introduzido no programa. Em projetos grandes, isso se torna um problema muito grave, e é um dos motivos pelos quais os adeptos de abordagens mais rigorosas consideram que as linguagens de scripting não são "sérias".

Python escolheu o caminho do meio, o mais sensato na minha opinião. Não é preciso declarar variáveis, até porque tal declaração não teria muita utilidade em uma linguagem de tipagem dinâmica onde o tipo está vinculado ao objeto, e não à variável. Mas Python exige que você inicialize uma variável antes de usá-la. Veja:

>>> b = a + 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined


Então isso obriga você a escrever:

>>> a = 3
>>> b = a + 1
>>> print a, b
3 4


Note que como toda variável precisa obrigatoriamente ser inicializada, isso é mais útil do que a exigência de que ela seja simplesmente declarada. Porque evita valores inválidos, e o momento da atribuição acaba funcionando como uma declaração também.

O modo como Python lida com identificadores, não só neste aspecto, mas também no seu sofisticado sistema de namespaces, evita conflitos de nomes e é um dos fatores que torna Python atraente para projetos de larga escala. Ruby adota a mesma filosofia de Python quanto à inicialização de variáveis, mas não tem o suporte a namespaces.

Este é apenas mais um exemplo de como Python é uma linguagem "simples e correta", como definiu meu amigo Geraldo Coen.

Thursday, April 2, 2009

Python vai migrar para Mercurial. Uebaaa!!!!

Perdõem a falta de objetividade no título, mas eu adorei esta decisão dos core developers da linguagem Python: entre os principais sistemas de controle de versão distribuídos, o Guido van Rossum optou pelo Mercurial, também conhecido como Hg, seu símbolo na tabela periódica.

No primeiro dia da conferência o Brett Cannon (perfil no Ohloh) fez uma palestra relâmpago explicando que os desenvolvedores do Python haviam decidido migrar do sistema de controle de versão atual, o Subversion, para um DVCS (sistema distribuído de controle de versões) e que ultimamente três sistemas tinham sido avaliados: Bazaar, Mercurial e Git.

Na mesma palestra-relâmpago, Brett disse que o Git havia sido descartado por ser o menos popular entre os principais desenvolvedores da linguagem Python e por não ser adequadamente suportado no Windows. Também pesou, mas não foi decisivo, o fato de que o Mercurial e o Bazaar são escritos em Python com partes em C, mas o Git é praticamente C puro com alguma coisa escrita em Perl. O vídeo da primeira sessão de palestras relâmpago, incluindo esta do Brett Cannon, já está no Blip.tv.

Chegando no Hg

Uma vez descartado o Git, foram apenas mais dois dias de suspense até que o Guido anunciou sua decisão favorável ao Hg, baseada principalmente nas preferências pessoais dos core developers que lhe enviaram e-mails ou twittaram sobre o tema. Segundo ele, o Git tem muitos fãs mas também um alto índice de rejeição, e o Hg tem ainda mais fãs que o Bazaar, com menos oposição. Então é isso, Mercurial na cabeça!

Gostei muito dessa escolha, porque passei bastante tempo tentando me acostumar com a idéia de usar um DVCS em vez do Subversion. Inicialmente brinquei com o Bazaar, mas só entendi realmente a idéia quando experimentei o Mercurial. Não sei se é a documentação dele que é melhor, ou seus comandos fazem mais sentido para mim, mas o fato é que com o manual do Mercurial a coisa toda finalmente fez sentido para mim.

Na verdade, eu vou mais longe, acho que aprender a usar o Mercurial é mais fácil que aprender a usar o Subversion, então se você ainda não usa um sistema de controle de versões, chegou a hora de começar!

Git e eu

Depois que eu já havia adotado o Mercurial eu resolvi aprender o Git porque estava na moda, e muita gente que eu respeito falava muito bem dele. Achei a documentação do Git horrenda, e suas mensagens de erro estão entre as piores que eu já vi. Ele foi desenvolvido pelo Linus e outros kernel hackers para uso próprio, e a documentação deixa claro que eles não se importam minimamente se meros mortais vão usar a ferramenta. Daí a comunidade Rails adotou o Git e com seu talento evangelista transformaram o Git em mais um ritual de sua religião.

Acontece que a maioria dos defensores do Git que eu conheço nunca experimentaram o Mercurial, e quase todas as vantagens do Git que eles apregoam por aí se aplicam perfeitamente ao Mercurial e até ao Bazaar.

Para mim as únicas vantagens objetivas do Git sobre o Mercurial são o desempenho e o Github.

A vantagem do desempenho é relativa, porque a gente não gerencia milhões de linhas de código como o Linus e os kernel hackers, então na prática isso significa que o Git faz em 0.01s algo que o Hg leva 0.1s para fazer.

Só que esta vantagem é anulada pelas armadilhas anti-usuário do Git. Cada vez que você perde 20 minutos tentando desfazer um erro lutando contra a interface hostil do Git, lá se vão 1200 segundos, ou seja, você acabou de perder a vantagem de desempenho equivalente a milhares de operações!

O Github é muito legal pelo seu componente social (virou uma espécie de Orkut de programadores), e continua sendo a melhor razão objetiva para usar o Git.

Agora com essa decisão da comunidade Python, o Bitbucket.org deve ficar mais popular, e funcionalmente ele é bem parecido com o Github.

Tentei muito gostar do Git, mas estou muito contente por poder deixá-lo de lado e voltar a me concentrar no Mercurial.

Na órbita de Mercurial

Vale notar que o Hg também foi adotado pelos core developers da linguagem Java e do projeto Mozilla (Firefox), então estamos na companhia de mega projetos (lista de usuários do Hg).

Com a adesão da comunidade Python ao Hg, vou migrar meus projetos relacionados a Python do Github para o Bitbucket.org. Nos vemos lá!

Wednesday, March 25, 2009

Django no mundo real

Esse foi o tema do primeiro tutorial que eu assisti na PyCon 2009 em Chicago. A conferência começa dia 27 mas nos dois dias antes estão rolando mais de 30 tutoriais.

Este tutorial na verdade foi uma palestra longa, não foi no estilo "mão na massa". Os apresentadores foram o Jacob Kaplan-Moss, um dos criadores do Django e co-autor do Django Book, e o James Bennett, autor do Practical Django Projects e release manager do Django.

Os caras são bons, claro, o Jacob e o Adrian são geniais por terem bolado um framework simples e integrado quando os concorrentes em Python eram todos complicados demais, desintegrados ou as duas coisas ao mesmo tempo. Mas na comunidade Python Brasil eu conheço várias pessoas que manjam mais de Python e de desenvolvimento Web que eles. Falta só um pouco mais de disposição para contribuir internacionalmente. Na verdade, a nossa galera de Plone já é reconhecida mundialmente, mas ainda temos condição de ocupar muito espaço fora do mundo Zope.

Apesar do comentário acima, aprendi bastante na palestra. O James especialmente tem muito o que dizer, se bem que quase tudo que ele falou eu já conhecia porque tem no livro que ele escreveu. Os slides estão online [1] e depois eu vou comentar com mais tempo a apresentação pois fiz umas anotações.

[1] http://jacobian.org/speaking/2009/real-world-django/

Tuesday, March 24, 2009

Metaprogramação 2: o caso do method_missing

Depois de um rigoroso regime de Java ou Delphi, as pessoas ficam maravilhadas ao encontrar na classe Object da linguagem Ruby o método method_missing.

Como fazer isto em Python? Bom, uma busca rápida no Google revela uma solução feita por um programador Ruby que recentemente adotou Python. Ele complicou demais a questão. Vou dar a minha solução mais pragmática.

Antes de mais nada, o que faz o method_missing?

Quando o interpretador Ruby encontra uma invocação de um método que não existe, digamos x.spam, ele faz uma segunda tentativa invocando x.method_missing(:spam) . Se a classe de x não implementa este method_missing, ela herda a implementação da classe Object (veja method_missing na documentação do Ruby), que apenas reporta um erro.

A graça é que você pode implementar method_missing nas suas classes, e fazer o que quiser. Uma aplicação comum é implementar métodos dinâmicos que fazem coisas diferentes dependendo do nome que foi invocado. Em Rails você vê coisas como Cliente.find_by_cpf, onde cpf é um atributo, e find_by_cpf é um método que não existe mas a invocação é tratada por um method_missing que faz uma busca por CPF.

Origem da idéia

Não sei se este mecanismo existia antes do Smalltalk, mas ele fazia parte do Smalltalk-80, lançado há quase 30 anos. Em Smalltalk o método se chamava doesNotUnderstand: e tem um artigo co-escrito pelo Ralph Johnson (da Gangue dos Quatro) que discute o uso dele em metaprogramação.

E em Python?

Python é diferente de Ruby porque a interface pública dos objetos em Python é formada por apenas por atributos, e um método é simplesmente um atributo invocável (callable). Em Ruby a interface pública dos objetos é formada só por métodos. Então o mecanismo análogo em Python lida com atributos não encontrados, e não com métodos. O nome poderia ser attribute_missing mas na verdade é __getattr__. Para entender o __getattr__, tem um exemplo simples no meu texto anterior.

O exemplo de method_missing documentação do Ruby pode ser implementando em Python de forma muito simples usando apenas __getattr__:


# coding: utf-8

'''
Instâncias de Romano têm atributos dinâmicos que devolvem o valor
inteiro correspondente ao numeral romano acessado::

>>> r = Romano()
>>> r.III
3
>>> r.mmix # caixa-baixa também funciona
2009

'''
# Inspirado pela documentação do método Object#method_missing da linguagem Ruby
# e aproveitando o módulo roman.py de Mark Pilgrim, publicado no livro
# Dive into Python: http://diveintopython.org/

from roman import fromRoman, InvalidRomanNumeralError

class Romano(object):
def __getattr__(self, s):
try:
return fromRoman(s.upper())
except InvalidRomanNumeralError:
raise AttributeError('Numeral romano invalido: %r' % s)

if __name__=='__main__':
import doctest
doctest.testmod()



Note que na solução pythônica, acessar r.x significa acessar um atributo cujo valor é calculado dinamicamente, e não acessar um método. Se o objetivo é acessar um método mesmo, basta que o __getattr__ retorne um objeto invocável. No próximo post, a solução para isso.

Monday, March 23, 2009

Metaprogramação em Python

Recentemente eu dei um curso de Python para uns programadores muito bons que curtem Ruby, e eles queriam saber sobre "metaprogramação" em Python.

Python tem uma longa e sólida tradição de metaprogramação, mas esse não é um termo que a gente usa muito na comunidade Python. Meus exemplos de metaprogramação sempre ficaram numa pasta chamada "introspecção". Realmente temos muito que aprender com a comunidade Ruby no quesito marketing. Metaprogramação é muito mais sexy.

Para ilustrar metaprogramação em Python, fiz este pequeno exemplo inspirado numa feature muito importante do Rails 3, que é a possibilidade de acessar itens usando ordinais como first, second etc. Dizem que o DHH implementou todos os ordinais até fortysecond, mas eu não testei.

A idéia fica bem clara num doctest:

'''
Os itens contidos em objetos da classe Lista podem ser acessados pelos
ordinais de 'primeiro' até 'decimo', ou por abreviaturas de três letras
destes ordinais:

>>> l = Lista([11, 22, 33, 44, 55])
>>> l.primeiro
11
>>> l.ter
33

'''
A implementação ficou assim:

from itertools import count

class Lista(list):

__ordinais = ('primeiro segundo terceiro quarto quinto sexto setimo'
' oitavo nono decimo').split()
__abrevs = [s[:3] for s in __ordinais]

def __getattr__(self, atrib):
atr = atrib[:3]
for i, ordinal, abrev in zip(count(), self.__ordinais, self.__abrevs):
if atrib == ordinal or atr == abrev:
return self[i]
else:
msg = "'%s' object has no attribute '%s'"
raise AttributeError(msg % (self.__class__.__name__, atrib))

@property
def ultimo(self):
return self[-1]

ult = ultimo


Vou comentar alguns lances que podem ser novidade para alguém.

Economia de aspas e vírgulas

Quando faço listas de identificadores tipo aquela dos __ordinais eu costumo colocar tudo numa única string e depois usar split, para economizar a digitação de um monte de aspas e vírgulas. Mas isso não é ineficiente? Não, porque aquela atribuição acontece só uma vez, quando o módulo é importado a primeira vez.

O que faz o __getattr__

O método especial __getattr__ é invocado quando um atributo inexistente é acessado. A obrigação dele é devolver um valor, ou levantar AttributeError. Existe também um __setattr__ e até um __delattr__. Tem também um __getattribute__ nas classes novas, mas este é mais difícil de usar corretamente.

Desde que Python ganhou o mecanismo de property, a gente usa menos estes métodos, mas eles ainda são essenciais.

Iterar com índices

O comando for em Python é mais fácil de usar que em outras linguagens, porque não obriga a lidar com o índice que em geral não interessa.

Mas às vezes a gente precisa do índice, e neste caso basta fazer
for i, item in enumerate(sequencia):
No for deste __getattr__ eu usei zip e count porque queria formar tuplas de três elementos: o índice, o ordinal e a abreviatura. Vale muito a pena estudar o que tem lá no módulo itertools: entender como usar aquelas funções vai te fazer pensar diferente.

Propriedade

Em Python uma property serve para implementar um atributo calculado, ou seja, um método que pode ser invocado usando a sintaxe de acesso a atributo (i.é. x.a em vez de x.a()).

Para definir uma propriedade apenas para leitura, usamos o decorador @property acima do método em questão.

E por último, ult = ultimo

Propriedades, funções e até classes em Python são objetos de primeira classe, ou seja, podem ser atribuidos a variáveis, passados como parâmetros e devolvidos como resultados de expressões. Isso significa que para criar uma propriedade ult, bastou atribuir ultimo a este identificador. Simples e elegante.

Este post mal arranhou o vasto e fascimante tema da metaprogramação em Python. Uma ótima referência para o tema é a palestra do Werneck na PyConBrasil 2007 em Joinville: "O que o Python faz quando você não está olhando".