Este é um blog sobre tecnologia e desenvolvimento, e eu tenho sido muito criterioso em evitar posts sobre outros assuntos. Mas dessa vez eu não me aguentei. Hoje li esses posts:

Se você ainda não os leu, por favor, leia agora. Depois você volta aqui e continua a ler o meu.

Não levou a sério? Cara, vai lá, lê os dois posts, você vai perder um minutinho só em cada um. Vale a pena.

Leu? Bom queria falar de 3 assuntos: carros, bicicletas e trabalho.

O primeiro texto é sobre carros. Os outros dois sairão nos próximos domingos.

Tenho um sedã popular. Comprei novo, há três anos. Está na hora de trocar. Não amo meu carro, embora goste muito do conforto e comodidade que ele traz a minha família. Já me disseram para trocar meu carro por um “melhor”, mas “melhor”, nesse caso, significa mais caro, mais imponente ou maior. Nenhum desses três adjetivos significa melhor para mim. Não é raro que eu deixe o carro na garagem e vá de transporte público a alguma reunião. Não é raro também, ver nas pessoas cara de espanto ao saber que eu cheguei até ali sem um carro. “Está tudo bem? Quer uma carona? O que houve com seu carro?” São as reações mais comuns.

Por quê? Claro, por uma série de motivos, incluindo o fato de que tem muita gente que realmente te julga pelo carro em que você anda. Mas há um outro motivo, que talvez seja mais doloroso: não ter um carro, em São Paulo, é muito ruim. Dependendo do seu caminho, andar de transporte público é desumano.

Fiz uma experiência simples. Escolhi quatro shopping centers, cada um em uma zona da cidade, e tracei as rotas no Google Maps da minha casa até lá agora:

Lugar de carro de transporte público
Zona Oeste 0:23 1:25
Zona Leste 0:30 1:20
Zona Norte 0:23 1:20
Zona Sul 0:33 1:10

Está certo, é domingo. Se seu trajeto puder ser feito de Metrô e for hora do rush, o carro perde feio. Dependendo do trajeto, é melhor até ir andando a pé pela rua do que de carro. Você olhou bem para a tabela acima? Se eu for a um shopping agora com minha família, de carro, em qualquer lugar da cidade vou gastar cerca de uma hora em deslocamento, ida e volta. Se formos de transporte público, levarei duas horas e meia, se der sorte.

Qual o resultado disso? Simples, quem puder vai andar de carro, sempre que puder. O jovem de classe baixa arruma o primeiro emprego e começa a se planejar para comprar um carro, para se livrar do ônibus, mesmo que o carro custe mais de um ano de salário. São Paulo tem 11 milhões de habitantes e 6 milhões de carros. Não cabem 6 milhões de carros nas ruas.

A matemática é simples. São Paulo tem cerca de 14 mil quilômetros de ruas e avenidas. Se todos os 6 milhões de veículos da cidade forem colocados em fila, encostados um no outro, a fila terá quase 27 mil quilômetros. Mesmo a cidade tendo centenas de avenidas com várias pistas, é fácil ver o que acontece.

A solução não é fazer mais avenidas. Nosso modelo de cidade feliz não pode ser um lugar onde todos tenham bons carros e possam dirigi-los livremente. Não porque eu ache que pessoas de determinada classe social, cor da pele, religião ou time de futebol não mereçam ter um bonito SUV de oito lugares. Simplesmente não cabe, não há espaço para isso. Nós precisamos de outro modelo de felicidade. Precisamos de uma cidade em que sair de carro seja apenas uma das boas opções.

Enquanto continuarmos achando que quem tem um carro é mais importante do que quem anda à pé, deixando de dar preferência ao mais frágil no trânsito, xingando o sujeito que teve a coragem de fazer alguma coisa ao deixar o carro em casa e sair de bicicleta, buzinando para o motorista que parou antes de uma esquina para o pedestre passar, vamos estar transmitindo uma mensagem a toda a sociedade: importante é quem tem carro. Nossas crianças estão ouvindo a mensagem. Nossos governantes também.

Isso tem muito a ver com você, que não sairia de casa sem carro nem que estivesse em Londres. Não estou dizendo que você precisa deixar de andar de carro, que isso é crime. O que estou dizendo é que, se você não quer ser obrigado a deixar o carro em casa, você precisa parar de pensar em avenidas e viadutos, e começar a pensar em tornar a cidade boa para todos. Ao votar, ao escrever, ao conversar, você deveria fazer o que estiver ao seu alcance para que São Paulo tenha transporte público excepcional, e que andar a pé, de bicicleta, de moto ou de Pogobol seja maravilhoso. É o único jeito de cabermos todos aqui.

Hoje estava brincando com Requests e tive essa ideia maluca:

import requests
import re

def Ed(text):
params=dict(server=’0.0.0.0:8085′,charset_post=’utf-8′,
charset=’utf-8′,pure=1,js=0,tst=1,msg=text)
return re.sub(‘<[^>]*>’,”,re.sub(r’\n+$’,”,
requests.get(‘http://www.ed.conpet.gov.br/mod_perl/bot_gateway.cgi’,
params=params).text))

def SeteZoom(text):
params=dict(server=’127.0.0.1:8088′,pure=1,js=0,tst=1,msg=text)
return re.sub(r’\n+$’,”,
requests.get(‘http://bot.insite.com.br/cgi-bin/bot_gateway.cgi’,
params=params).text)

msg=’Oi!’
while True:
print ‘SeteZoom: %s’ % msg
msg=Ed(msg)
print ‘Ed: %s’ % msg
msg=SeteZoom(msg)

Teste aí, o resultado às vezes é mais inteligente que muito chat entre seres humanos por aí…

O módulo webbrowser permite abrir uma URL no navegador do usuário. Só isso, simples assim. Por exemplo:

import webbrowser
webbrowser.open("http://visie.com.br")

E o site da Visie será aberto no navegador do usuário. Muito útil se você está fazendo um programa para desktop ou mesmo um script para o terminal. No caso de scripts para terminal, se o usuário estiver rodando o script sob uma interface gráfica o site será aberto no navegador padrão dele, já se estiver rodando via ssh ou num outro terminal sem interface gráfica, será usado um navegador de CLI (como o Lynx) se estiver disponível.

Teste aí:

sudo apt-get install cowsay

Depois rode:

cowsay Funciona...

O cowsay também pode receber texto na entrada padrão:

date|cowsay

Isso permite usos razoavelmente criativos:

lynx --dump http://news.google.com.br | grep "^\[" | grep -v "»" \
| sed -e "s/.*\]//g" | sort -R | head -n 1|cowsay

Você pode colocar seu Ubuntu para te dar uma dica de Linux toda vez que você abre o terminal, assim:

sudo apt-get install fortunes-ubuntu-server

Depois edite o arquivo ~/.bashrc e inclua no final:

fortune|cowsay

E pronto! Cada vez que você abrir um terminal vai receber uma dica de Ubuntu.

Nosso presente de natal para os desenvolvedores do Brasil: API gratuita de consulta de CEP.

A Visie é parceira de tecnologia da Aviso Brasil. Nós fornecemos tecnologia para o Correio Control, e como parte do negócio, precisamos ter a base de endereços sempre atualizada e sincronizada com o Diretório Nacional de Endereços.

Vimos que muita gente oferece aquele cômodo recurso de auto completar o endereço pelo CEP, mas usando bases de dados desatualizadas. Existem até uns serviços pagos que oferecem esses dados.

Por isso, decidimos oferecer um serviço gratuito de consulta de endereços pelo CEP, para que você possa usar em sua aplicação. Os resultados podem ser retornados usando o modelo JSONp, de modo que o próprio navegador do usuário requisite diretamente o endereço de nossos servidores.

Aproveite!

Em tempo: se você faz software que de alguma maneira envia e controla encomendas, você precisa conhecer o Correio Control. É um software de baixo custo para usuários corporativos dos Correios que oferece o controle de faixas de registro, geração de etiquetas e AR, monitoramento e rastreamento estendido, solicitação automatizada de pedidos de informação e indenização, relatórios de status e muito mais.

 

Veja:

>>> class Class:
...   def um(self):
...     return 1
... 
>>> c=Class()
>>> c.um()
1
>>> def dois(self):
...   return 2
... 
>>> Class.dois=dois
>>> c.dois()
2
>>> Class.tres=lambda self:3
>>> c.tres()
3
>>> Class.um=lambda self:'Um modificado.'
>>> c.um()
'Um modificado.'

As classes em Python são completamente dinâmicas. Você pode acrescentar métodos quando quiser e isso se refletirá em todos os objetos criados com aquela classe (mais ou menos como o que você faz em Javascript com prototype.)

Python é uma linguagem open-source, com uma extensa biblioteca. E os módulos da biblioteca são escritos em Python. Alguns módulos, como pickle e StringIO, tem versões em C mais rápidas (cPickle e cStringIO) mas as versões em Python são mantidas para que você possa ler os fontes.

Veja como descobrir onde estão os fontes de um módulo qualquer:

>>> import glob
>>> glob.__file__
'/usr/lib/python2.7/glob.pyc'

O nome do arquivo tem a extensão pyc. É um compilado. Tire o último “c” e você terá o caminho do arquivo com o código fonte. Dê uma lida no conteúdo do glob.py, por exemplo, e você deve achar muito simples mas bastante interessante.

Se você está aprendendo Python agora, sempre que for resolver uma tarefa sobre determinado assunto, dê uma olhada no código dos módulos relacionados aquele assunto. Você vai ver como a comunidade Python tem abordado problemas semelhantes aos seus e com certeza vai aprender muito.

Há muitas situações em que uma função faz cálculos e operações para obter valores e, ao final, deve montar uma string com esses valores. Nesta situação, muita gente monta um dicionário com os valores e usa string formatting para gerar a string a ser retornada. Por exemplo:

# -*- encoding: utf-8 -*-
import string,random

template='''Sugestões para %(nome)s:
 - login: %(login)s
 - email: %(email)s
 - site: www.%(domain)s.com
 - senha: %(passwd)s
'''

def sugere_logins(nome):
    login=nome.split(' ')[0].lower()
    domain=nome.split(' ')[-1].lower()
    email=login+'@'+domain+'.com'
    chars=string.letters+string.digits
    passwd=''.join(random.sample(chars,10))
    dados={'login':login,
           'email':email,
           'nome':nome,
           'domain':domain,
           'passwd':passwd}
    print template % dados

Você pode substituir todo o trecho em que monta o dicionário, usando o resultado da função locals(). A função locals() retorna um dicionário com todas as variáveis locais. No exemplo acima, isso ficaria assim:

# -*- encoding: utf-8 -*-
import string,random

template='''Sugestões para %(nome)s:
 - login: %(login)s
 - email: %(email)s
 - site: www.%(domain)s.com
 - senha: %(passwd)s
'''

def sugere_logins(nome):
    login=nome.split(' ')[0].lower()
    domain=nome.split(' ')[-1].lower()
    email=login+'@'+domain+'.com'
    chars=string.letters+string.digits
    passwd=''.join(random.sample(chars,10))
    print template % locals()

Uso muito esse truque ao trabalhar com web2py, fazendo com que os controllers, ao invés de retornar um dicionário montado por mim, retornem locals().

Dizem que Delfim Neto dizia que números, quando bem torturados, são capazes de confessar qualquer coisa. Eu concordo. Sempre que você ouvir números impressionantes gaste algum tempo pensando, aplique um pouco de matemática básica e duvide um pouco do que você ouviu.

Vi no Facebook hoje o pessoal compartilhando esse artigo:

Paulistas compram mais carros por hora do que roraimenses o mês todo

O artigo destaca o fato de que “São Paulo vendeu em agosto o dobro do segundo colocado e 212 vezes mais do que Roraima, o último do ranking”, dando a impressão ao leitor de que isso é reflexo de uma tremenda desigualdade social.

Acontece que a população de São Paulo é maior que o dobro que a de Minas Gerais, segundo colocado no ranking de venda de carros. Assim, per-capita, o mineiro comprou quase a mesma quantidade de carro que o paulista em agosto.

Veja, para cada dez mil habitantes em São Paulo foram vendidos 28 veículos, e em Minas 26. E quanto a Roraima? Bem, as diferenças sociais são gritantes. Mas o artigo coloca as coisas assim:

São Paulo vende por hora 621 unidades, mais do que Roraima vende por mês: 538.

Olhando assim, parece que o paulista ganha dezenas de vezes mais dinheiro que o roraimense. Mas em Roraima, para cada dez mil habitantes, foram vendidos 11 carros. Ainda uma desigualdade, claro, mas não de dezenas de vezes, não é?

Em tempo: antes que os comentários enveredem por esse assunto, eu concordo que nossas cidades precisam de menos carros e mais bicicletas/metrôs/corredores de ônibus/trabalho remoto. Mas o fato de isso ser uma boa causa não nos dá o direito de fazer esses absurdos com os números, não é?

A dica de hoje não é muito útil. Pelo menos eu nunca usei para nada realmente sério. Mas é bem divertida:

>>> t='All your base are belong to us.'
>>> t.encode('rot-13')
'Nyy lbhe onfr ner orybat gb hf.'

Rot-13 é um encoding comum do Python. Você pode escrever código em rot-13 também, se indicar o encoding do arquivo num cabeçalho:

# -*- encoding: rot-13 -*-
vzcbeg fgevat
sbe v va enatr(20):
    cevag fgevat.nfpvv_ybjrepnfr[:v]

Salve o conteúdo acima no arquivo rot13.py e você poderá executar:

$ python rot13.py

Divertido, não?

O pacote cclive, para download de vídeos do YouTube na linha de comando, é uma reescrita do clive mais eficiente, com menor consumo de memória e menos dependências. Para instalar:

$ sudo apt-get install cclive

E para usar:

$ cclive http://www.youtube.com/watch?v=8fvTxv46ano

Isso vai baixar o vídeo na pasta atual. Simples e indolor. Mas qual a vantagem de usar a linha de comando em relação a uma extensão no navegador, onde você não precisa digitar comandos? Com a linha de comando é possível automatizar as tarefas. Criei um script que recebe um nome de usuário do YouTube e baixa os últimos 15 vídeos publicados. Chamei o arquivo de massclive. Veja o código fonte:

mkdir -p $1

lynx --dump http://www.youtube.com/user/$1/feed | \
  grep youtube.com/watch | \
  sed -e "s/.* //" | \
  sed -e "s/&.*//" | \
  sort -u | \
  while read url
  do
    cclive -c --output-dir $1 $url
  done

E você pode usar assim:

$ ./massclive maninthearenatv

Essa é bem legal. Temos três listas:

>>> a=[1,2,3]
>>> b=[4,5,6]
>>> c=['a','b','c']

Veja:

>>> zip(a,b,c)
[(1, 4, 'a'), (2, 5, 'b'), (3, 6, 'c')]

Simples e útil, não? E se as listas tiverem tamanhos diferentes?

>>> c=['a','b']
>>> zip(a,b,c)
[(1, 4, 'a'), (2, 5, 'b')]

O resultado será truncado para o tamanho da menor lista. Se você quiser, pode obter um comportamento diferente com map, assim:

>>> map(None,a,b,c)
[(1, 4, 'a'), (2, 5, 'b'), (3, 6, None)]

Veja um truque que eu costumava usar bastante com zip:

>>> colors=['Azul','Vermelho','Amarelo','Verde','Branco']
>>> for i in zip(range(len(colors)),colors):
...   print '%i. %s' % i
... 
0. Azul
1. Vermelho
2. Amarelo
3. Verde
4. Branco

Até que eu descobri enumerate():

>>> for i in enumerate(colors):
...   print '%i. %s' % i
... 
0. Azul
1. Vermelho
2. Amarelo
3. Verde
4. Branco

O pacote libtext-lorem-perl contém um gerador de Lorem Ipsum para o seu terminal. Eu tinha até feito um script para isso antes de saber da existência desse pacote. Para instalar:

$ sudo apt-get install libtext-lorem-perl

E para usar:

$ lorem

Para gerar vários parágrafos, use a opção -p informando quantos parágrafos você quer:

$ lorem -p12

Você também pode usar -w para indicar quantas palavras o lorem deve gerar, ou -s para indicar quantas sentenças. Olha o que dá para fazer:

echo "<section>
 <h1>`lorem -w 3`</h1>
 <h2>`lorem -s 1`</h2>
 <p>`lorem`</p>
 <p>`lorem`</p>
 <p>`lorem`</p>
</section>"

Boa parte das APIs do HTML5 já estão disponíveis hoje para a maioria dos navegadores e, com um pouco de conhecimento e uma pitada de javascript, é possível desenvolver hoje aplicações com geoposicionamento, funcionamento offline, conexão em tempo real com o servidor, gráficos vetoriais e todo um novo conjunto de recursos de interface.

Por que esperar?

O HTML5 foi construído de maneira modular. Não é preciso esperar que toda a documentação esteja escrita para começar a trabalhar com ele. Você pode usar agora mesmo o que já está pronto.

Pensando nisso, preparamos este Workshop sobre as APIs do HTML5 e como construir a nova geração de aplicações web. Veja o programa.

Python tem duas funções muito interessantes: any e all. A função any recebe uma lista (ou outro objeto interável) e retorna True se algum dos elementos for avaliado como True. Já all só retorna True se todos os elementos forem avaliados como True. Veja:

>>> everybody=[1,2,3,4]
>>> anybody=[0,1,0,2]
>>> nobody=[0,0,0,0]
>>> any(everybody)
True
>>> any(nobody)
False
>>> any(anybody)
True
>>> all(everybody)
True
>>> all(nobody)
False
>>> all(anybody)
False

Sem segredos, certo? Mas essas duas funções junto com os generators permite uma sintaxe muito interessante:

>>> v=[10,12,25,14]
>>> any(n>20 for n in v)
True
>>> all(n>20 for n in v)
False

Veja um exemplo disso num código real:

if all(v<100 for v in values):
    msg='Para usar seu cupom de desconto, pelo menos '+
        'um dos produtos deve custar mais de R$ 100,00.'

E numa classe real:

class Form:
    # ...
    def validates(self):
        return not any(field.error for field in self.fields)

O módulo gzip nos permite ler e escrever em arquivos .gz sem nenhum trabalho. Veja:

>>> import gzip
>>> f=gzip.open('teste.txt.gz','w')
>>> f.write('Hello!\n')
7
>>> f.close()
>>> 
$ gunzip teste.txt.gz 
$ cat teste.txt 
Hello!
$ gzip teste.txt 
$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import gzip
>>> print gzip.open('teste.txt.gz').read()
Hello!