Raspagem dos dados do TCE-PB
4 de Dezembro de 2010, 0:00 - sem comentários aindaEsta é minha proposta conjunta com o Fernando Brito para as Microbolsas Hacker do pessoal do Transparência Hacker.
Quem somos nós?
Eu, o Vítor, sou quase (espero) bacharel em Computação. Estou no último período do curso na UFPB, faltando só defender a monografia. Acompanho a lista do thacker desde a cópia do Blog do Planalto, mas nunca participei ativamente. Fiz alguns pequenos hacks e nada mais.
O Fernando é graduando em Estatística, mas amanhã vai prestar vestibular para Computação. Entrou na lista do thacker também há algum tempo e está desenvolvendo um hack que lista os devedores da previdência social.
O que vocês vão fazer?
O Tribunal de Contas da Paraíba disponibiliza os dados de todos os municípios (e do governo) do estado em http://sagres.tce.pb.gov.br. Os dados estão relativamente bem organizados, mas falta uma API e visualizações mais amigáveis, gráficos, etc..
Estão disponíveis receita, despesas, empenhos, licitações, folha de pessoal, obras, veículos entre outros. A maioria dessas informações até que estão bem detalhadas, mas outras apresentam certas inconsistências que certamente serão repassadas ao orgão responsável.
Queremos raspar esses dados e disponibilizá-los em uma API. Após isto, iremos criar uma página semelhante ao http://cmsp.topical.com.br/, com gráficos que facilitem seu entendimento e que possibilitem cidadãos comuns obterem mais informações sobre a prestação de contas de orgãos de municípios e do estado da Paraíba.
Qual o retorno para a comunidade THacker?
Estamos documentando todo o processo e achamos que o know-how adquirido irá ajudar e encorajar outras equipes que desejem fazer algo semelhante em estados diferentes do nosso.
Além disso iremos disponibilizar todo o código fonte do projeto. A parte do código que raspa os dados do site do TCE-PB é bem específica para o nosso caso, mas o site e as visualizações com certeza ajudarão outros projetos.
O resultado final poderá ser usado como case de sucesso e será mais um argumento ao nosso favor, mostrando o poder e a necessidade da adoção de políticas de dados abertos.
Quando concluído, o projeto irá também chamar um pouco mais da atenção da mídia e principalmente dos hackers do Nordeste. Diferentemente do eixo Rio-São Paulo, aqui existe uma grande falta de interesse pelo tema e há uma enorme escassez de comunidades que lidem com o movimento de dados abertos.
Nós organizamos uma instância do Open Data Day aqui na Paraíba justamente com este objetivo: agregar pessoas, até conseguimos espaço para uma entrevista na associada local da Globo (http://jpb2.cabobranco.tv.br/index.php?ev=1&d=2010-12-04). Todavia sabemos que ainda há muito mais a ser feito e que essa pode ser justamente a oportunidade que estava nos faltando.
Bingo do Zé
3 de Novembro de 2010, 0:00 - sem comentários aindaAgora que as eleições passaram (e Ricardo Coutinho venceu), resolvi parar um pouco e escrever sobre o Bingo do Zé.
Como tudo começou
O @pizzariaze @alexandrend lançou
no dia 17 15 de outubro uma cartela com algumas pérolas do candidato
Zé Maranhão. A ideia era que você imprimisse e fosse marcando ao assistir aos
debates.
Achei genial. Teve uma boa repercussão no Twitter e, no dia seguinte, Alan Kelon, um professor da UFPB e amigo, lançou um desafio na lista de estudantes de Computação da federal: fazer uma aplicação web com a ideia do bingo. Fiquei com isto na cabeça.
Naquele dia estava com insônia. Já eram mais de 2 da manhã e não tinha sono algum. Então Samara, minha namorada, me liga. Também estava lesando no computador. Contei pra ela sobre o bingo e, depois de rirmos bastante, veio a proposta: bora fazer agora? ;)
Ela disse sim :D
Primeira versão
Três horas da manhã de uma terça-feira, estávamos eu e ela com o notebook na cama e um modem 3G. Primeiro passo: procurar algo já pronto. Rapidamente encontrei este post que mostrava como fazer um bingo “padrão” com JavaScript, JQuery e CSS.
Perfeito! Só precisaria modificar pra usar frases ao invés de números e estilizá-lo. Depois de pouco mais de uma hora chegamos a isso:
Alguns detalhes técnicos
Houve duas sacadas que acho interessante falar. Se você não for de computação ou não estiver interessado em saber como funciona o bingo, aguarde pela parte 2 deste post.
Gerando uma URL única para cada cartela
Fiz algumas funções pra compartilhar o bingo no twitter. Uma delas é que, quando você fecha uma linha ou coluna (exceto a central) ou a cartela toda, você pode enviar uma mensagem do tipo “Fiz 2 colunas no #BingoDoZe!”. Mas, pra ficar mais interessante, queria adicionar o link da sua cartela nesse tweet. Mas como?
O sistema é feito todo só com JavaScript. Não consigo (facilmente) usar um banco de dados. Primeiro pensei em reescrevê-lo em Ruby ou PHP, mas fiquei com preguiça. Pensei mais um pouco, fiquei olhando o código para ver se surgia alguma ideia, então me veio a luz. Antes de tudo, deixe-me explicar como funciona o código.
Eu tenho um array com as pérolas. Para gerar a cartela, eu o embaralho e coloco os 25 primeiros termos e nos campos do bingo. A solução que encontrei para gerar sempre a mesma é adicionar uma semente ao algoritmo do Math.random().
function fillCards(seed){
Math.seedrandom(seed);
var shuffle = function() { return 0.5 - Math.random(); };
var termos_shuffled = termos.sort(shuffle);
for(var i = 0; i <= 24; i++){
// Pula a imagem de Maranhão
if (i == 12)
continue;
$('#cell'+i).html(termos_shuffled[i]);
}
}
Uma linguagem de programação gera números (pseudo-)aleatórios a partir de diversos cálculos em cima de um valor inicial. Se você puder definir qual é esse valor, então a função sempre retornará os mesmos resultados. O que faz isso é a linha 2, Math.seedrandom(seed).
Infelizmente, não tem como fazer isso nativamente em JavaScript. Mas basta adicionar o seedrandom.js, criado pelo David Bau e disponibilizado no seu blog. Funcionou perfeitamente.
Como seed usei um hash na URL, na forma http://labs.vitorbaptista.com/bingodoze/#367660 (neste caso, o seed é #367660). Ao entrar em http://labs.vitorbaptista.com/bingodoze, se já houver um hash, usa ele como seed. Caso contrário, gera um aleatoriamente.
Salvando que campos foram marcados
Depois do passo anterior os jogadores conseguem compartilhar suas cartelas. Mas quem acessar meu link vai encontrá-la vazia. Como persistir os campos marcados?
Seguindo a ideia de adicionar os dados à URL, tive a ideia de codificar o que foi marcado em um inteiro. Bem simples: tenho um número com 25 bits, cada um representando uma célula. Os que estiverem em 1, estão ativos; em 0, desativos.
Para isso, há duas funções principais: cartelaToMask() e maskToCartela(mask). A primeira retorna um inteiro que representa a cartela, e a segunda faz o caminho inverso, recebendo um inteiro e preenchendo a cartela. Vejamos:
function cartelaToMask() {
var mask = 0;
for (var i = 0; i <= 24; i++) {
if ($('#cell'+i).hasClass('ativo'))
mask |= masks[i];
}
return mask;
}
Bem simples. Há o inteiro mask inicializado com 0 e, para cada célula, checo se ela tem a classe CSS “ativo”. Se sim, eu coloco o bit correspondente em 1. No final, retorno o mask.
O array masks usado no algoritmo possui as potências de 2 já calculadas. Ou seja, masks[0] == 1, masks[1] == 2, masks[2] == 4, e por aí vai. É uma solução muito deselegante. O ideal seria gerar esses valores provavelmente usando bit shifting.
function maskToCartela(mask) {
for (var i = 0; i <= 24; i++) {
if (mask & masks[i])
$('#cell'+i).addClass('ativo');
}
}
O caminho contrário é bem parecido. Eu faço um laço de 0 até 24 pegando o bit correspondente (mask & masks[i]). Se ele estiver ativo, adiciono a classe “ativo” à célula. Pronto.GG
Esse inteiro é codificado em hexadecimal e adicionado a URL. Assim temos algo como http://labs.vitorbaptista.com/bingodoze/#367660-1d50170, onde #367660 é a semente e 1d50170 é a máscara.
Se você faz computação e teve problemas em entender a lógica dos operadores bit-a-bit usados nesse código, dê uma lida aqui. É simples e pode ser bem útil.
Eu pretendia só falar das estatísticas do Bingo do Zé, mas acabei me empolgando e falando demais. Vou deixá-las para a parte 2 deste post. Se você estiver curioso, pode ir vendo as estatísticas de tweets em http://summarizr.labs.eduserv.org.uk/?keyword=bingodoze
Bingo do Zé – Parte 1
3 de Novembro de 2010, 0:00 - sem comentários aindaAgora que as eleições passaram (e Ricardo Coutinho venceu), resolvi parar um pouco e escrever sobre o Bingo do Zé.
Como tudo começou
O @pizzariaze lançou no dia 17 de outubro uma cartela com algumas pérolas do candidato Zé Maranhão. A ideia era que você imprimisse e fosse marcando ao assistir aos debates.
Achei genial. Teve uma boa repercussão no Twitter e, no dia seguinte, Alan Kelon, um professor da UFPB e amigo, lançou um desafio na lista de estudantes de Computação da federal: fazer uma aplicação web com a ideia do bingo. Fiquei com isto na cabeça.
Naquele dia estava com insônia. Já eram mais de 2 da manhã e não tinha sono algum. Então Samara, minha namorada, me liga. Também estava lesando no computador. Contei pra ela sobre o bingo e, depois de rirmos bastante, veio a proposta: bora fazer agora?
Ela disse sim
Primeira versão
Três horas da manhã de uma terça-feira, estávamos eu e ela com o notebook na cama e um modem 3G. Primeiro passo: procurar algo já pronto. Rapidamente encontrei este post que mostrava como fazer um bingo “padrão” com JavaScript, JQuery e CSS.
Perfeito! Só precisaria modificar pra usar frases ao invés de números e estilizá-lo. Depois de pouco mais de uma hora chegamos a isso:
Alguns detalhes técnicos
Houve duas sacadas que acho interessante falar. Se você não for de computação ou não estiver interessado em saber como funciona o bingo, aguarde pela parte 2 deste post.
Gerando uma URL única para cada cartela
Fiz algumas funções pra compartilhar o bingo no twitter. Uma delas é que, quando você fecha uma linha ou coluna (exceto a central) ou a cartela toda, você pode enviar uma mensagem do tipo “Fiz 2 colunas no #BingoDoZe!”. Mas, pra ficar mais interessante, queria adicionar o link da sua cartela nesse tweet. Mas como?
O sistema é feito todo só com JavaScript. Não consigo (facilmente) usar um banco de dados. Primeiro pensei em reescrevê-lo em Ruby ou PHP, mas fiquei com preguiça. Pensei mais um pouco, fiquei olhando o código para ver se surgia alguma ideia, então me veio a luz. Antes de tudo, deixe-me explicar como funciona o código.
Eu tenho um array com as pérolas. Para gerar a cartela, eu o embaralho e coloco os 25 primeiros termos e nos campos do bingo. A solução que encontrei para gerar sempre a mesma é adicionar uma semente ao algoritmo do Math.random().
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function fillCards(seed){ Math.seedrandom(seed); var shuffle = function() { return 0.5 - Math.random(); }; var termos_shuffled = termos.sort(shuffle); for(var i = 0; i <= 24; i++){ // Pula a imagem de Maranhão if (i == 12) continue; $('#cell'+i).html(termos_shuffled[i]); } } |
Uma linguagem de programação gera números (pseudo-)aleatórios a partir de diversos cálculos em cima de um valor inicial. Se você puder definir qual é esse valor, então a função sempre retornará os mesmos resultados. O que faz isso é a linha 2, Math.seedrandom(seed).
Infelizmente, não tem como fazer isso nativamente em JavaScript. Mas basta adicionar o seedrandom.js, criado pelo David Bau e disponibilizado no seu blog. Funcionou perfeitamente.
Como seed usei um hash na URL, na forma http://labs.vitorbaptista.com/bingodoze/#367660 (neste caso, o seed é #367660). Ao entrar em http://labs.vitorbaptista.com/bingodoze, se já houver um hash, usa ele como seed. Caso contrário, gera um aleatoriamente.
Salvando que campos foram marcados
Depois do passo anterior os jogadores conseguem compartilhar suas cartelas. Mas quem acessar meu link vai encontrá-la vazia. Como persistir os campos marcados?
Seguindo a ideia de adicionar os dados à URL, tive a ideia de codificar o que foi marcado em um inteiro. Bem simples: tenho um número com 25 bits, cada um representando uma célula. Os que estiverem em 1, estão ativos; em 0, desativos.
Para isso, há duas funções principais: cartelaToMask() e maskToCartela(mask). A primeira retorna um inteiro que representa a cartela, e a segunda faz o caminho inverso, recebendo um inteiro e preenchendo a cartela. Vejamos:
1 2 3 4 5 6 7 8 9 10 |
function cartelaToMask() { var mask = 0; for (var i = 0; i <= 24; i++) { if ($('#cell'+i).hasClass('ativo')) mask |= masks[i]; } return mask; } |
Bem simples. Há o inteiro mask inicializado com 0 e, para cada célula, checo se ela tem a classe CSS “ativo”. Se sim, eu coloco o bit correspondente em 1. No final, retorno o mask.
O array masks usado no algoritmo possui as potências de 2 já calculadas. Ou seja, masks[0] == 1, masks[1] == 2, masks[2] == 4, e por aí vai. É uma solução muito deselegante. O ideal seria gerar esses valores provavelmente usando bit shifting.
1 2 3 4 5 6 |
function maskToCartela(mask) { for (var i = 0; i <= 24; i++) { if (mask & masks[i]) $('#cell'+i).addClass('ativo'); } } |
O caminho contrário é bem parecido. Eu faço um laço de 0 até 24 pegando o bit correspondente (mask & masks[i]). Se ele estiver ativo, adiciono a classe “ativo” à célula. Pronto.
Esse inteiro é codificado em hexadecimal e adicionado a URL. Assim temos algo como http://labs.vitorbaptista.com/bingodoze/#367660-1d50170, onde #367660 é a semente e 1d50170 é a máscara.
Se você faz computação e teve problemas em entender a lógica dos operadores bit-a-bit usados nesse código, dê uma lida aqui. É simples e pode ser bem útil.
Eu pretendia só falar das estatísticas do Bingo do Zé, mas acabei me empolgando e falando demais. Vou deixá-las para a parte 2 deste post. Se você estiver curioso, pode ir vendo as estatísticas de tweets em http://summarizr.labs.eduserv.org.uk/?keyword=bingodoze
Gastos dos deputados paraibanos com Telefonia, Combustíveis e Lubrificantes
3 de Outubro de 2010, 0:00 - sem comentários aindaHoje, conversando com o Fernando Brito, ele me mostrou um site muito interessante: o da Câmara dos Deputados. Mais especificamente, a parte de Cota para Exercício da Atividade Parlamentar (mais detalhes). Nele, podemos ver onde os deputados estão gastando dinheiro, em um nível de detalhamento muito grande. Podemos ver quanto foi gasto, pra quem foi pago, quando e a categoria.
Por curiosidade, fui ver os gastos do Efraim Filho (DEM). Daí que me deparo com:
Como assim? R$ 4.125,06 em combustível?! R$ 2.850,84 de telefone?! Em um mês?!?! Como ele conseguiu? Fui ver de outros deputados e me deparei com números parecidos. Aparentemente, é normal gastar alguns milhares de reais por mês comprando gasolina e pagando a conta de telefone.
Para variar, lá vou eu fazer o scrapping dessa página. Duas horas depois, consegui montar estas tabelas:
Deputado | Combust. e Lubrific. | Telefonia |
---|---|---|
ARMANDO ABÍLIO (PTB) | R$ 3.924,46 | R$ 2.876,46 |
DAMIÃO FELICIANO (PDT) | R$ 3.424,78 | R$ 1.144,66 |
EFRAIM FILHO (DEM) | R$ 2.950,66 | R$ 1.006,01 |
LUIZ COUTO (PT) | R$ 1.271,95 | R$ 1.406,68 |
MAJOR FÁBIO (DEM) | R$ 2.043,00 | R$ 827,82 |
MANOEL JUNIOR (PMDB) | R$ 4.235,14 | R$ 2.128,04 |
MARCONDES GADELHA (PSC) | R$ 2.942,35 | R$ 1.893,33 |
RÔMULO GOUVEIA (PSDB) | R$ 3.135,14 | R$ 1.636,98 |
RONALDO CUNHA LIMA (PSDB) | R$ 734,13 | — |
VITAL DO RÊGO FILHO (PMDB) | R$ 2.870,52 | R$ 2.045,92 |
WALTER BRITO NETO (PRB) | R$ 1.124,44 | — |
WELLINGTON ROBERTO (PR) | R$ 3.700 | R$ 1.271,12 |
WILSON BRAGA (PMDB) | R$ 4.212,07 | R$ 1.562,76 |
WILSON SANTIAGO (PMDB) | R$ 3.911,33 | R$ 2.339,48 |
Estes dados refletem a média de gastos entre 01/2007 até 09/2010, 45 meses. Se pegarmos quem gastou mais com combustível, Manoel Júnior, que ficou com uma média de R$ 4.235,14, e multiplicarmos isso por 45 meses, são R$ 190.581,30. Vamos considerar que ele usou 70% dinheiro pra comprar gasolina e o resto pra lubrificantes, e que tenha pago, em média, R$ 3 por litro. São 44.468,97 litros. Digamos que ele tenha um carro que consome bastante, fazendo 5 km/l. Daria pra rodar 222.344,85 km.
Para comparação, a costa brasileira tem 7.408 km. Com essa quantidade de combustível, ele poderia ter ido do cabo Orange até o arroio Chuí mais de 30 vezes. Dá mais ou menos uma vez a cada mês e meio, durante aos 3 anos e 9 meses os quais temos acesso aos dados.
Mas, pela pouca pesquisa que fiz até agora, esses gastos são normais. Ele não gasta muito mais do que os outros deputados. Isso me faz chegar a conclusão que ou há algo de muito estranho nesses gastos, ou há algo que eu não saiba. Quem sabe esse combustível não é para carro, mas para seus jatinhos particulares?
Alguém sabe quanto consome um Legacy?
P.S.: Quem quiser ver os dados que consegui extrair e, quem sabe, descobrir outras coisas, é só clicar aqui. Ele é um banco de dados sqlite3. Por enquanto só tem os deputados paraibanos, mas estou baixando todos os outros e publicarei aqui.
Descobrindo qual é a operadora de um telefone
2 de Outubro de 2010, 0:00 - Um comentárioDesde março de 2009, há no Brasil a portabilidade numérica para telefones fixos e celulares. Isto quer dizer que podemos trocar de operadora de telefonia sem trocar de número. Assim, se outra empresa oferecer um plano mais vantajoso, podemos migrar para ela sem precisar avisar a todos nossos contatos que trocamos de número.
Mas isso também gera um problema: antes, cada operadora tinha uma faixa de números. Na Paraíba, a gente sabia que um celular era da Oi se começasse com 88, da Claro se fosse com 93, etc. Com a portabilidade não dá mais pra saber assim, é preciso consultar o número no site da ABR Telecom.
Até aí tudo bem. Mas eu tenho quase 500 contatos no meu celular, toda vez que eu quiser saber se posso ligar para um número sem ter que pagar minutos extra (tenho bônus pra Oi), vou ter que consultar nessa página? Preciso de uma maneira melhor.
Eu tenho um celular com Android, o Nexus One. De cara, pensei em fazer um aplicativo que consultasse os dados da ABR Telecom e me mostrasse qual é a operadora de cada contato, quem sabe com um ícone ao lado da foto. Não deve ser muito complexo. Mas, quando fui ver, me deparei com o primeiro problema: o CAPTCHA.
CAPTCHA são aquelas letras distorcidas que a gente tem que digitar em alguns sites. Ele serve para evitar que uma pessoa automatize uma determinada tarefa, como tentar logar em um site, criar contas no orkut. Desta forma, ele evita que alguém crie um programa para testar todas as possibilidades de sua senha no GMail, por exemplo. Idealmente, as letras são muito difíceis de um computador detectar, mas fáceis para um humano.
O site da ABR Telecom tem um CAPTCHA. Do jeito que ele está, eu não consigo fazer um programa para checar a operadora dos meus 500 contatos. A não ser que eu consiga quebrar esse CAPTCHA. Hum…
Foi isso que eu fiz (explico em outro post). Não foi difícil, eles usam um CAPTCHA muito simples. Daí nasceu o http://qualeaoperadora.de, um site que tem a mesma funcionalidade que o ABR Telecom (inclusive usa ele por baixo dos panos), mas sem o CAPTCHA. Assim, você pode criar novos softwares e sites usando as informações do meu. Isto está bem na moda, e se chama mashup.
Eu não parei por aí. Além de você poder acessar as informações digitando no site, ou adicionando diretamente o telefone na URL (como em http://qualeaoperadora.de/6132160000), você também pode pegar em dois formatos diferentes: YAML e JSONP. Para o primeiro, basta adicionar .yml ao final (http://qualeaoperadora.de/6132160000.yml); para o segundo, adicione .json (http://qualeaoperadora.de/6132160000.json). Se quiser especificar a função pra callback, também pode fazer http://qualeaoperadora.de/6132160000.json?callback=minhaFuncao. Em JSONP, eu também retorno uma URL para o logotipo da operadora e a UF do Estado.
Ainda não fiz o software para buscar isso no meu Android, nem sei se vou fazer. Mas, com esse site, você mesmo pode fazê-lo. Esteja à vontade, mashups são divertidas. Se fizer algo, não deixe de me avisar
Ah! Se você quiser dar uma olhada no código do http://qualeaoperadora.de, ele é livre e está disponível em http://www.gitorious.com/vitorbaptista/qualeaoperadora-de