Latest posts.

O Processo Legislativo Animado: Chamada Para Designers

Um problema que vamos enfrentar com certeza no Meu Parlamento é o quão complicado é o Processo Legislativo. Existe um número enorme de trajetos diferentes que uma proposição pode percorrer, e não é nada trivial saber o que cada etapa significa. A Câmara dá uma explicada e tem bastante coisa para ler no Interlegis, mas nada que se possa chamar exatamente de intuitivo. Também não é nada fácil olhar a tramitação de uma proposição em particular e entender onde ela está, por onde ainda falta passar, etc.

Eu pensei em um jeito de resolver estes dois problemas.

A idéia

A idéia é fazer um diagrama de estados completo e interativo, mostrando os estados e transições pelos quais uma proposição pode passar.

Aprendendo o Processo

Nas transições, as arestas tem a espessura proporcional ao número de proposições que já fizeram essa transição (a la Charles Joseph Minard). Os dados viriam do Legisdados.

Passar o mouse por cima da aresta a destaca e mostra um balão com sua descrição.

Passar o mouse por cima de um estado o destaca e mostra sua descrição.

Clicando o botão Play (tem um botão Play), começamos com uma nova proposição no estado inicial. Um texto explicativo é exibido embaixo, como se fosse uma visita guiada, falando o que aquele estado significa e explicando o que pode acontecer com a proposição a partir dali (isto é, descrevendo as arestas). Neste ponto, o usuário escolhe e clica em uma das arestas, passando para o próximo estado.

Repetindo estes passos, o usuário tem uma simulação completa da tramitação de uma proposição, explicada do começo ao fim. A espessura das arestas indica o caminho mais frequente e pode ser usado como dica para o usuário explorar primeiro os casos mais comuns.

Podemos pegar algumas proposições reais que sejam particularmante representativas ou históricas e ilustrar da mesma forma, com texto específico para ela, o caminho que seguiu. [Em vez de deixar o usuário clicar nas arestas, fazemos apenas um playback, exibindo um botão de "avançar".] Dessa forma sedimentamos o aprendizado com um exemplo real.

Acompanhando proposições

Para acompanhar a tramitação de uma proposição específica, mostramos o diagrama de estados um pouco apagado, destacando a trajetória já percorrida pela proposição. Nos balões de informação das arestas e estados, podemos colocar informações específicas daquela proposição. Por exemplo, na aresta poderíamos ter: “enviado para a Comissão de Constituição de Justiça em 05/03/2009″; e no estado: “na Comissão de Constituição e Justiça – relator Deputado João da Silva”.

O balão de informação do estado “votação” poderia mostrar um gráfico bonitão do resultado, como os do Congresso Aberto.

E podemos disponibilizar a mesma função de playback que descrevi acima: começamos na apresentação do texto, e cada click no botão de “avançar” vai para o estado seguinte, mostrando informação sobre a aresta tomada e o estado atingido.

Podemos também dar um leve destaque para os caminhos que a proposição ainda pode vir a percorrer.

A chamada

Eu sou um zero à esquerda para coisas gráficas. Eu posso programar a lógica do negócio, integrar aos dados, etc., mas não consigo nem fazer um mockup para ilustrar a minha idéia.

Então se você é um designer gráfico (especialmente se entende de animações em browser, com flash ou javascript) e quer dar uma mãozinha à democracia, entre no grupo de discussão do Meu Parlamento e diga alô :)

Talvez já haja coisas mais ou menos prontas que a gente possa reaproveitar. Eu encontrei este software que aparentemente transforma fluxogramas em animações flash, mas é proprietário, e não deve ser muito extensível. O ideal seria uma biblioteca, framework, alguma coisa assim que desse pra gente programar e adaptar.

Sugestões e críticas sobre a conceituação do negócio também são bem-vindas, tanto nos comentários quanto no grupo.

E se você resolver implementar a idéia por conta própria, pelo amor de deus libere o programa sob uma licença livre e mande o link :)

  • Share/Bookmark

Wish: RSS Tab Creator

I wish there were a Firefox extension that did this:

  1. you enter a list of RSS feeds;
  2. it keeps track of which items you haven’t read yet;
  3. you click a button or menu item and BAM!, it opens one tab for each unread item, showing the original page, not the RSS text content.
  • Share/Bookmark

The Holy Grail of Kickass API Documentation

Disclaimer: this is a bunch of vaporware.

Read/Write Asymmetry

It’s been a while since people solved the problem of making API documentation easily readable, while keeping it closely tied to the code: keep it in comments in the source code and export it to HTML.

One problem that still remains is that developers suck at writing documentation. They have no need for it (it’s just a waste of time: they already know how that stuff works), and they often don’t use the API they develop themselves, or at least not in all possible use cases, so they end up not knowing very well which information is most valuable to the users.

Users, on the other hand, know it all too well. They know a hack around that quirky behavior; they inadvertently found that undocumented feature (or was it a bug?); they have collectively field-tested it in a hundred times as many use cases as the author had originally foreseen; and they know what needs to be known.

They write about it too! You can see countless blog posts, forum answers, even comments appended to the documentation itself taking up where it left off. It just happens that this stuff never makes its way back into the official docs because it’s too much of a hassle!

If you’re just a user of some library, you usually have it installed in some far-away system directory, outside of source control, and read-only. Making a change to the documentation means finding where the repository is hosted, checking it out locally, finding where in the code that bloody method is implemented, making a change and sending a patch (where to, again?). That’s not your job right?

So why don’t we just make it all a wiki huh? Easy as pie. No funky markup in comment blocks, no generation step, it’s all HTML. You’re reading it, you spot something wrong or incomplete, edit it right there and you’re back to reading before you can say “back to reading.” And where is the code now? Well, somewhere completely dissociated from the documentation. You’re not even sure which version you’re reading about.

So what we really want is API documentation that:

  • comes directly from the source code;
  • is easily editable as a wiki;
  • and goes back to the source code.

There and Back Again

Rdoc.info takes any arbitrary repository and generates API documentation for you. So far it only works for Ruby repositories on Github, but it’s the only one I know so it’s the one I’ll talk about. The idea is applicable to anything that does the same type of auto-generation though.

That’s really cool then! Our first requirement is covered.

The second requirement is making a wiki, so I think we can borrow from about five million solutions.

Now HOW?! How do you turn that stuff back into source code again?!

chmod +w RDoc

Documentation on rdoc.info is generated per repository, per user, so you can decide, for each repository, if its documentation should be wiki-editable or not (if you made it this far I assume you really want it really bad). In that case, all you have to do is create a public branch called “docs”, and rdoc.info starts tracking that instead of the master branch, generating a wiki from it. Now you just tell everyone to come and edit!

Gathering edits

Rdoc.info forks your repository and commits every wiki edit to that fork. It’s quite simple: it just replaces the comment block next to a method/class/whatever with the edited version. On every commit, you receive a pull request.

Displaying

On the website, rdoc.info shows the latest wiki-edited docs by default, with a read-only “canonical” tab showing the last official version that was pushed before the recent edits.

Merging back

When you receive the pull request from rdoc.info, you merge rdoc.info’s branch back into yours, resolving possible conflicts and integrating the changes.

Edit History

What if you push to your “docs” branch when there are wiki commits that you haven’t integrated? Rdocs.info can’t try a normal merge, as there might be conflicts, and the whole thing has to be automatic. If it just does a “reset hard”, it’ll lose previous edits. So it does a merge, but with a no-hostages approach: automatically resolve every conflict by choosing your changes. It will count as a normal edit in the wiki, with the previous version still in the history.

Reverting to a particular version from the wiki interface is the same thing: the contents (only the doc comments, not the code) of the chosen version are commited on top of the current commit, and can be diffed with it.

Attribution, Statistics, Reputation

If the user making the edit is logged in, the commit can have her as the author, and statistics can be kept on who helped out the most and that kind of stuff. Methods with the least content can be marked as “stubs”, and editing those can be worth more points.

More into metadata territory, the developer could also possibly benefit from indirect usage statistics (through clicks and searches), and people up/downvoting individual methods, maybe even commenting on their design (whether they should be split in two; if the parameters or return values make sense, etc.).

You want it too?

From the few services I know which host API docs, I think the most likely to implement something like this are either rdoc.info or ApiDock. So write them and ask for it! (hey, I told you it was vaporware.)

Update: Apparently, something like this has been tried already by DocBox as a Google Summer of Code project. The code on Github is from last year and the website pointed at by RubyFlow seems to be down. Anyone with more info on this?

  • Share/Bookmark

Democracia Líquida no Brasil: Uma Realidade Possível (a curto prazo!)

English version here

O que é?

Democracia Líquida é um método de tomada de decisão em grupo que funciona mais ou menos como uma “democracia direta para pessoas que sabem que não são especialistas em um assunto, mas conhecem pessoas em que elas confiam e que sabem mais sobre esse assunto do que elas”.

É muito mais democrático do que a Democracia Representativa (a que temos hoje no Brasil, com deputados, senadores, vereadores), e muito mais factível do que a Democracia Direta, onde todo mundo vota em tudo. Como na democracia direta, a pergunta pode ser respondida por todo mundo mas, no caso da Democracia Líquida, a resposta pode ser “eu voto o que o fulano votar”. Cada pessoa pode escolher “assessores” para determinados assuntos, como os deputados fazem hoje.

Por exemplo, você não sabe nada sobre a matriz energética do Brasil e suas necessidades, mas tem um amigo engenheiro elétrico que sabe muito disso e que tem opiniões parecidas com as suas, então ele vira seu “assessor” em matérias de Energia: a não ser que você vote diretamente, o voto dele passa a valer um a mais. Ele, em determinadas questões, pode não estar completamente seguro sobre o assunto específico: ele é engenheiro elétrico, estão votando exploração do petróleo. Mas ele conhece um geólogo que entende e tem os mesmos valores que ele, então delega seu voto. O voto do geólogo passa a valer dois a mais (o seu e o do engenheiro elétrico).

Nos assuntos que te interessam mais e sobre os quais você entende melhor, você vota diretamente.

Se você simplesmente não se interessa por nada e não quer gastar seu tempo com isso, é só delegar tudo. Fica igual a nós todos hoje, com alguém votando tudo por nós sem nossa intervenção, com a exceção que, neste caso, quem vai votar por você serão pessoas que você conhece e com quem pode conversar pessoalmente se precisar, e você não precisa esperar 4 anos se quiser trocá-las.

Importante:

Não existe mandato. Se estiver insatisfeito, você pode trocar de assessor a qualquer momento.

Importantíssimo:

Você sempre pode votar diretamente. Não importa se você delegou seu voto para um determinado assunto. Se você for e votar diretamente, a delegação não conta naquela votação: seu voto vale 1 (mais o número de pessoas que delegaram pra você) e o do seu assessor passa a valer esta quantidade a menos. Como você pode ver o que o seu assessor vai votar antes que ele vote de fato, se você discordar é só ir lá e votar você mesmo.

Como faz?

Dissolvemos câmara dos deputados, senado, assembléias legislativas estaduais e câmaras de vereadores, criamos um site de elaboração e votação de leis e instituimos que este será o único meio pelo qual estas duas coisas serão feitas, certo?

Calma. Ninguém vai pegar em armas, ninguém vai dissolver nada. Como eu disse, esta é uma revolução factível, não um sonho distante e utópico.

Uma maneira que alguns suecos inventaram de fazer isso foi criar um partido (o Demoex) e eleger um “vereador-laranja” que vota na câmara o que for tirado pelos membros do partido através de um sistema online de democracia líquida. Tudo bem, eles começaram só com uma cadeira, mas já conseguiram resultados bem legais. A idéia é muito boa e parece que já foi tentada no Brasil (não consegui achar muita informação). Mas eu tenho uma idéia diferente que não envolve eleger ninguém.

Meu Parlamento

Criamos o tal site com o sistema de democracia líquida, pegamos as pautas da Câmara Federal antes de cada plenário e jogamos lá. Discutimos, delegamos, votamos. Somos nosso próprio parlamento paralelo, cada um de nós um deputado. Simples assim.

Que diferença faz?, você pergunta. Só eu e você? Não muita. Agora imagine 10% da população brasileira (ou mesmo só de São Paulo) usando isso. Os deputados começariam a dar atenção. Começaríamos a ter influência. Eu consigo imaginar um deputado, na véspera de uma sessão do plenário, consultando o site pra ver o que eu e você votamos. Agora imagine 30%. Depois 50%. Só um louco nos ignoraria. Sem que tenhamos eleito nenhum “laranja” nós mesmos, todos os deputados, aos poucos, entrariam na discussão e passariam a ser voluntariamente nossos laranjas. Afinal de contas quem, depois de ver uma parcela gigante do eleitorado votar de um jeito no site, votaria de maneira contrária no plenário?

Ah, claro: depois que eles votarem, comparamos as escolhas deles com as nossas. “73% dos cinco milhões de usuários do Meu Parlamento votaram contra a lei do Azeredo; 340 dos 513 deputados da Câmara votaram a favor. Estes são os deputados que votaram a favor: Fulano, Ciclano, Beltrano”.

E, depois que você tiver um certo número de votações registradas no site, podemos fazer comparações personalizadas. Você vai ao perfil do Fulano (deputado federal, talvez o que você elegeu na última eleição) e lá está: em 70% das votações, Fulano votou diferente de você. Hm… será que você vai votar nele na próxima eleição? Talvez você queira consultar a lista de todos os deputados, ordenada por quão parecido com você eles votaram. Escolher um representante por quanto ele te representou e não pela campanha, quem diria hein?

Mas está faltando alguma coisa pra isso ser um parlamento de verdade. Até agora, nós estamos apenas votando nos projetos de lei elaborados pelos deputados. Por que não criarmos nossos próprios?

Se a proposta do Túlio Vianna virar lei, poderemos elaborar colaborativamente projetos de lei no próprio site (wiki?), debatê-los e encaminhá-los à Câmara para votação. Precisaríamos de mais ou menos 1 milhão de apoiadores. Veja que não é tanta gente quanto parece. O Orkut tem mais de 30 milhões de usuários no Brasil (você poderia inclusive pedir pros seus amigos no Orkut assinarem). Como qualquer outro projeto em votação na Câmara, ele passaria antes por nós, e já iria para o plenário com o peso dos nossos votos.

E mesmo se a proposta do Túlio Vianna não passar, tudo o que precisamos é de mais ou menos um milhão de assinaturas reais, em papel. A elaboração e a discussão ainda podem ser feitas no site. Depois disso, cada pessoa interessada imprime o texto do abaixo-assinado, assina embaixo e manda pelo correio para a ONG que vai gerenciar o Meu Parlamento. A ONG recolhe as assinaturas e encaminha o projeto de lei à Câmara. Pronto.

Cortando o atravessador

Podemos elaborar leis nós mesmos e mandá-las para a Câmara. Podemos influenciar a Câmara para que vote o que nós votarmos. Somos um Parlamento completo.

Quando tivermos este tipo de controle, iremos nos perguntar: pra que temos mesmo uma Câmara? Pra que gastamos esta quantidade monstruosa de dinheiro pagando deputados, assessores, secretários, faxineiros, motoristas, etc.? É, realmente não faz muito sentido. Vamos manter o Meu Parlamento e cortar o resto.

Por que vai funcionar?

Como eu disse, isto não é uma utopia. Ok, a parte de cortar o atravessador talvez seja. Mas votar leis como qualquer deputado — e ter o nosso voto ouvido — e criar nossas próprias leis são coisas que dependem de muito pouco: software (livre, claro) e usuários.

Haverá, claro, a necessidade de um empenho grande de algumas pessoas para que o site seja criado: programadores, designers, gente disposta a testar e dar feedback.

Também será grande o esforço para que o site tenha uma adoção significativa. Precisaremos de comunicadores para divulgar a idéia e atrair novos usuários. Precisaremos de jornalistas, comentadores políticos e cidadãos engajados para alimentar a discussão no site e dar-lhe vida.

Talvez dê muito trabalho participar e fique difícil convencer novas pessoas a se cadastrarem, certo?

Errado. Como em todo site de conteúdo gerado por usuários, quem desenvolve e divulga o site e quem gera a maior parte do conteúdo é uma fração minúscula do número total de usuários (pense no YouTube). A maioria interage muito pouco, contribui quase nada e ainda consegue tirar proveito. E, mesmo assim, constroem-se comunidades vibrantes e ricas.

O cidadão mais desinteressado e preguiçoso precisará fazer muito pouco, então não será tão difícil convencê-lo a se envolver. “É só criar um login e escolher uns amigos pra votarem por você”. Ele receberá um email de vez em quando falando “olha, tem essas coisas sendo votadas, você se interessa?” e o deletará. E depois outro dizendo “tal amigo seu votou a favor disso por você, outro amigo votou contra aquilo” e também o deletará. Mas ele estará, pelo menos de uma maneira passiva e vaga, informado sobre o que anda acontecendo, o que já é mais do que temos hoje. Nestes emails, alguma coisa talvez lhe salte os olhos. O amigo que vota por ele pode ligar e conversar sobre o que está sendo discutido (coisa que deputado algum jamais faria). Mesmo com o mínimo de esforço ainda há mais democracia.

Como chegar lá?

Não precisamos fazer tudo de uma vez. O site pode começar muito simples e ir agregando funcionalidades aos poucos.

O primeiro passo é criar um simples sistema de acompanhamento de deputados, algo parecido com o Twitter. Você vai até o “perfil” de um deputado e escolhe “seguir” seus votos (e *apenas* os votos), seja por email, RSS ou qualquer outro jeito. Toda vez que ele vota alguma coisa você recebe uma notificação: “Fulano votou X na votação sobre Y”. Colocamos no site o texto do que foi votado para debate, algo parecido com isso.O desenvolvimento desta parte já está em andamento.

Em seguida, adicionamos um sistema simples de votação direta pós-fato (inicialmente, é mais fácil lidar com votações que já ocorreram do que com a pauta antes das sessões). Você recebe “Fulano votou X na votação Y, o que você teria votado?“. Clica no link, vai até o site e vota. Com isso já dá pra fazer as comparações citadas acima do seu histórico de votações com o dos políticos.

O bom de fazer as coisas nessa ordem é que o site vai ficando incrementalmente mais útil. Ele não precisa de uma massa gigante de usuários logo no começo pra fazer algum sentido. Mesmo se você for o único usuário, já se beneficia de informação sobre os políticos, suas atividades e o quanto eles te representam.

Depois disso, aos poucos, vamos introduzindo outras funcionalidades: votação sobre a pauta antes da sessão no plenário, sistema de escolha de assessores e delegação de votos, sistema de elaboração colaborativa de projetos de lei, etc.

Começamos primeiro com a Câmara Federal porque é o órgão legislativo que mais disponibiliza eletronicamente informações sobre sessões, votos e deputados. Na maioria das assembléias estaduais e câmaras de vereadores, esta informação está em atas de papel, e só consegue ver quem tem a paciência de ir até lá. À medida que estas começarem a ser disponibilizadas online também, passarão a ser incluídas no site.

Como eu ajudo?

Como dá pra ver, tem muita coisa a ser feita. Precisamos de desenvolvedores, designers, comunicadores, lobistas (pra convencer as assembléias e câmaras municipais a disponibilizarem seus dados na internet), testadores, críticos, captadores de recursos, advogados, enfim, não importa o que você faça, tem como você ajudar.

Eu criei um grupo de discussão para começar a agregar os interessados. Cadastre-se em: http://groups.google.com/group/parlamento-aberto.

Referências

Conteúdo:

http://campaigns.wikia.com/wiki/Liquid_Democracy (en)
http://en.wikipedia.org/wiki/Proxy_voting#Delegated_voting (en)
http://en.wikipedia.org/wiki/Delegative_Democracy (en)
http://www.brynosaurus.com/deleg/deleg.pdf (en)
http://p2pfoundation.net/Decision-Making_Tools (en)
http://pt.wikipedia.org/wiki/Demoex_-_democracia_experimental (pt)
http://www.opencongress.org/ (en)
http://legistalker.org/ (en)
http://www.democracia.com.br/ (pt)

Discussão (veja também os comentários):

http://tuliovianna.wordpress.com/2009/07/19/democracia-digital-direta-ja/ (pt)
http://www.trezentos.blog.br/?p=2193 (pt)

Perguntas?

Não deu pra cobrir tudo acima, senão o texto ficaria longo demais. Mas, por favor, usem os comentários. Existem várias questões que ainda precisam ser debatidas (segurança, anonimidade, exclusão digital, etc.) e eu ficarei feliz em responder às perguntas.

Update: parece que já tem algo do gênero sendo desenvolvido em http://www.democracia.com.br/. Tem acompanhamento e votação direta, mas não consegui me cadastrar nem acessar o blog. Ainda está ativo?

Update 2009-11-25: troquei “Parlamento Aberto” por “Meu Parlamento”, o novo nome.

  • Share/Bookmark

Brincando com políticos e inteligência artificial

A idéia desta análise veio do André Lima (@andlima) e será executada por mim como um projeto de pesquisa orientado pelo Prof. Siome K. Goldenstein.

Resumo

A quantidade de informação disponível eletronicamente sobre a atuação dos nossos representantes eleitos tem aumentado drasticamente em tempos recentes e, apesar de ainda longe do ideal, já permite análises interessantes.

“Informação”, aqui, refere-se não a notícias ou opiniões, mas a dados crus e objetivos como: contribuições de campanha, fluxos orçamentários, movimentações partidárias, processos na justiça, históricos de votação em plenário, etc. Para os fins deste artigo, vamos nos focar no último.

A idéia básica é, olhando apenas os históricos de votação dos deputados:

  • fazer um agrupamento automático por similaridade;
  • comparar este agrupamento automático com o real (por partidos);
  • estabelecer as votações ou projetos de lei mais relevantes.

Modelagem

No site da Câmara dos Deputados há muita informação sobre o processo legislativo. Em particular, o site lista:

  • Deputados;
  • Votações (projetos de lei, entre outros);
  • Votos (sim/não/abstenção/ausência).

Com estas informações, podemos modelar um deputado como sendo um vetor de votos, onde cada dimensão corresponde a uma votação, e o valor da dimensão, ao voto. Ex.:

Deputado1: <sim,não,não,sim,aus,abs>
Deputado2: <não,não,não,sim,sim,aus>

Sabemos a que votação cada voto corresponde pela posição no vetor.

Tendo isso em mãos, podemos criar uma medida de distância entre dois deputados, dada pelo número de votações em que os dois votaram diferente. Intuitivamente, quanto mais eles discordarem, mais “distantes” estarão ideologicamente. No exemplo acima, Deputado 1 e Deputado2 discordam na primeira, na penúltima e na última votação. Portanto, tem distância 3.

Agrupamento

Vetores e uma medida de distância são a entrada de vários algoritmos de agrupamento (clustering, em inglês), subárea da Inteligência Artificial conhecida como Aprendizado de Máquina (Machine Learning, em inglês). As saídas em que estamos interessados são o número de grupos encontrado e a distribuição dos deputados em grupos.

Uma maneira intuitiva de imaginar, grosso modo, como o número de grupos é obtido é a seguinte: se todos os políticos tiverem votado exatamente a mesma coisa em todas as votações, precisamos apenas de 1 grupo (eles concordam em tudo). Se eles tiverem votado exatamente a mesma coisa em todas as votações exceto em uma, onde metade votou “sim” e a outra “não”, precisamos de 2 grupos, e assim por diante.

O número de grupos é um resultado interessante em si porque, de certa forma, pode ser interpretado como a quantidade de “variação ideológica” entre os deputados. Uma crítica frequente ao sistema político brasileiro é o fato de haver dezenas de partidos sem muita definição da diferença entre eles (ao contrário do sistema estadunidense, polarizado em dois partidos principais). O número de grupos encontrado pelo algoritmo refletiria o número de pólos ideológicos reais, definidos puramente pelas opiniões dos deputados expressas em seus votos.

A composição dos grupos é também interessante, pois podemos ver não só que políticos foram parar em que grupos mas, melhor ainda, que partidos foram parar em que grupos. Talvez haja pouca surpresa aqui, mas seria curioso se pessoas de partidos supostamente opostos ideologicamente acabassem no mesmo grupo, ou se um pedaço de um partido estivesse em um grupo e outro pedaço em outro, revelando uma divisão partidária.

Relevância dos projetos de lei

Fazendo algo semelhante a uma Análise de Componentes Principais (PCA – Principal Component Analysis, em inglês), podemos obter um conjunto pequeno das votações que foram mais relevantes em distinguir um político do outro. Retomando o exemplo acima, se todos tivessem votado exatamente a mesma coisa exceto em uma votação, onde metade votou “sim” e metade “não”, concluiríamos que esta uma votação é muito mais relevante do que as outras porque, para qualquer político, bastaria saber o que ele votou nesta uma votação para determinarmos a que grupo ele pertence. O resultado real claramente não será tão óbvio, mas através deste procedimento poderíamos obter, por exemplo, as 10 votações ou projetos de lei mais relevantes.

Aplicações

A aplicação mais imediata seria, a partir da análise de relevância, criar um questionário online com as leis mais importantes, determinando a que grupo o usuário pertence e que deputados de seu estado se encontram nele (e quais não se encontram). Outras aplicações, diretas ou indiretas, das idéias básicas apresentadas aqui são muitas e muito importantes, e as apresentarei melhor em outro post.

  • Share/Bookmark

Code Review + Google Wave = Code Wave !

Doing some exploratory thinking about the possibilities opened by Google Wave, I came up with this very early idea of something that could turn out to be pretty interesting. In explaining it, I’ll assume you’ve watched that huge 1h20min video they have about it (it’s worth every minute, but there’s an abridged — 10min — version).

Motivation

People have been doing code review through email for ages. It’s the easiest, dead-simple way of doing it. Just add a post-receive-hook to your repository and make it email a diff of every new commit to a mailing list. People answer to that email, inlining comments where needed. Great, you say. But… It’s not 2.0. Bummer.

You know what is 2.0? Review Board. Very pretty web interface, AJAX, all that goodness (seriously, it’s awesome, I’m even working on it myself). But… It’s not Email.

You know what is Email and 2.0? You’re absolutely right! Google Wave*! :)

So how do we tie it to the code?

Code Wave

The idea so far includes developing four separate pieces of software — one wave robot, two gadgets and one stand-alone web application which will use the embed API — , but the basic idea is to map every commit and every file to its own wave. Think of it as a code browser on steroids.

The Robot

The robot handles creating, linking and updating the repository content, access control and custom markup.

It creates one “absolute” wave for each version of each file and directory, plus one “relative” (HEAD) wave for each, which gets updated with every new commit. This way, one can look at a particular version of a file using the absolute wave, but also use the Playback functionality on the relative wave to watch it evolve as new changes are committed. Since waves can be linked to one another, besides being able to make directory listings, we can also have a header on each wave, linking to the usual previous/next/head commits. This is the “code browser” part.

When new commits arrive, they each also get their own wave, with the commit message, diff content and a link to each file changed. As with any wave, people can comment inline on any part they want, even chat about it, effectively doing (possibly live!) code review. The conversation history will be kept (and “playbackable”) in the wave, and people who are participants will be notified of the changes and can also come and chip in.

The robot also handles access control. Apparently waves, at least so far, don’t allow one to say “nobody can edit the content, only add comments.” If I’m right about that, the robot will need to watch and overwrite any changes to the content itself (the content must always reflect the repository), leaving only comments. On the web interface (which we’ll talk about in a sec), people can decide to “watch” certain (or all) files or directories, being notified about changes in them (much like in Review Board). The robot accomplishes this by adding these people to the commit waves where these files/directories are changed, so the wave pops up in their inboxes. The original committer always gets added, so she gets notified about any comments on her changes.

Another cool thing to have is special markup, so the robot watches for stuff like revision numbers/sha1s and turns them into links to the appropriate wave. It can also be configured through the web interface to turn ticket numbers and the like into links.

The Web Interface

It serves two main purposes: store settings and provide a way to browse the repository and comments.

Settings to be stored are repository path, privacy levels, groups of users, change watchers, robot behavior, etc.

Since waves can be embedded into normal web pages, this is also a nice way to make all that content (files, diffs and reviews) available online without needing a wave client. We could even think about indexing everything and making it searchable.

Gadget Number One

Syntax highlighting, plain and simple. Highlight code, skip (wave) comments, allow raw copying, etc. Could also be used to fold and unfold comment threads, so you could have a look at the diffs without the cruft. Maybe we could borrow some things from Bespin?

Gadget Number Two

Link helper. Like the Google button, that lets you search for something and drag results into the wave, this helper would allow you to refer to other files in the repository, searching them by name/path and dragging them in. Not sure how useful this really is, just thought it was a nifty idea.

The Future

Emacs Client

Imagine this: you’re there, nurturing your code on emacs (you are using emacs right?), and you spot something funky. It shouldn’t be there, or there’s a better way to do it, or you have a question about it. You put your cursor over the funky line, hit Control+Meta+Shift+whatever and what happens? Your trusty emacs takes the “git blame” for that line (or the equivalent in your SCM of choice), asks the web app for the wave URL associated with the commit sha1, splits your window in half and shows you said wave (do you have any doubt there will be an emacs wave client?) with the cursor right on the corresponding line in the diff, ready for you to hit M-x add-wave-reply and send your comments the committer’s way. It also might just be that someone already had the same issue, and you’ll see a threaded conversation there with the answer.

Editing

Right now we’ve only mentioned writing on commit waves (code review), but file waves were read-only. I haven’t thought out the details for this yet, but maybe there can be something like embedding Bespin on Google Wave, or the other way around, so that people can do real-time collaborative code editing (while also chatting through inline comments) and then mutually decide to commit. The file wave could wrap the file’s content in a header with a commit command.

The Present

So, how far are we into this project? Well, nowhere, really. It’s just a recent idea I had, and I don’t even have a Google Wave Sandbox account yet (hint, hint if you’re a googler). So if you liked it, feel free to go ahead and implement it. Many of the parts I described can be done independently (like the emacs wave client), so you don’t have to take on everything at once. And if you ever get around to building this (under a free license, of course) and making tons of money, please send me a couple beers :)

Also, this is a very rough draft, so suggestions or any kind of feedback is appreciated.

* For a non-ludicrous version of this comparison, take a look at: http://smartbear.com/white-paper.php?content=docs/articles%2FFour-Kinds-Of-Review.html

  • Share/Bookmark

Ideas matter

So I’m starting to get a kind of reputation for producing a lot of vaporware. According to wikipedia,

“most vaporware would not be considered a hoax since the makers have a genuine intention to create their product, even if it ultimately never materializes.”

Every once in a while I email friends with a cool idea I had, but it seems that I can produce ideas faster than code implementing them. That can be a cause of frustration if you think you’re the only person who can implement your ideas. And I usually don’t blog about them because it’s better to come out announcing something that actually exists.

I’m leaving that pride behind. I’ll just post ideas as they come. Since they’re not likely to get implemented by me anyway, at least there’s a slightly higher chance that someone else will like the idea, take it for themselves and run with it.

It’s kind of what organizations in the Google Summer of Code do. They post ideas, students come by, look at them, some decide to implement their own, some pick one from the list. This is the start of my own list of ideas. Maybe someday I’ll also have money to pay people to implement them like Google does.

I’ll take comfort in the fact that wikipedia also states that

“products with unspecified release dates (…) are not normally labelled vaporware.”

  • Share/Bookmark

Graphing delayed_job statistics with Munin

Queue Size

Number of jobs that haven't been run yet or that failed and are going to be retried

Number of jobs that haven't been run yet or that failed and are going to be retried

Graphs make people happy. No denying that. So here’s a treat for you. Assuming you’re using Munin to monitor all sorts of stuff in your servers (Munin’s web interface is ugly but it’s really cool!), and using delayed_job as a queue, take this file:
http://github.com/obvio171/delayed_job/blob/423dc31b9ed6f2bee6e4c780e85d7d9a546e0a60/contrib/delayed_jobs_queue_size.rb

just drop it (or link to it) inside your /etc/munin/plugins/ on the servers that run jobs and that’s it! It’ll break!

Not what you were expecting huh? Ok, you have to do a little more work. First, you have to tell the plugin how to connect to your database. The easiest way, if you’re running Rails, is to set the environment variable DATABASE_YML to the path where that file is. Make sure the user who runs the plugin has access to that file. By default it’s the user munin, but you can specify a different one (cf. http://munin.projects.linpro.no/wiki/plugin-conf.d — this won’t link properly due to a bug in wordpress).

If you have some different setup, you can edit the plugin and pass a hash with username, password, etc. to Grapher.new. Don’t be scared! The code is really simple, take a look!

Also, if you’re running vanilla delayed_job (that is, from tobi’s repo), this plugin uses a table column that you don’t have, finished_at (we’ll come back to this column later). Just remove that extra AND finished_at IS NULL. Now it works! That’s how big your queue is right there, on that graph!

So why would you want that extra column again? Here’s something to wet your appetite:

Average Run Time

How long it's taking your jobs to run

How long it's taking your jobs to run

Now, you can’t get that with vanilla delayed_job. Why not? Because it deletes finished jobs, so there’s no way of telling how long they took to run*.

How do you solve that?

Step 1: Run this migration:

Step 2: Use my branch of delayed_job (hey, gotta sell my fish). It adds the appropriate behavior related to those extra columns.

Step 3: Add the line Delayed::Job.destroy_successful_jobs = false to your environment.rb or, better yet, to some initializer.

Now your jobs stay there after they complete successfully so you can poke at them and gather statistics. Specifically, they keep the time when they first started, when they last started (these are different if there was more than 1 attempt) and when they finished successfully.

With that in hands, you can now add this one other plugin:
http://github.com/obvio171/delayed_job/blob/423dc31b9ed6f2bee6e4c780e85d7d9a546e0a60/contrib/delayed_jobs_run_time.rb

Follow the same instructions as with the first one, and you have the graph above with each point representing the average running time of jobs that got finished in the last 5 minutes. Sweet huh?

There’s more!

It’s a graphing spree! Know what else you can do with those statistics you’re gathering? From the README:

“This is useful for gathering statistics like how long a job took:
* to be picked up by the first worker: first_started_at – created_at
* in one successful run (the last one that didn’t fail): finished_at – last_started_at
* in failed retries: last_started_at – first_started_at”

Now these you’ll have to do yourself. I haven’t written them. But if you look at my plugins, they’re really simple, and it should be very easy for you to change them to output these other graphs. If you get around to doing that, please be nice and put them in that contrib folder. There’s certainly people who’ll find use for them!

Wait, so I’ll have these finished jobs lying around FOREVER?

If you don’t do anything, yep. But you can clean up with these handy rake tasks:
jobs:clear:all
jobs:clear:finished
jobs:clear:failed
Put them in a cron job somewhere and you’ll be fine.

* This is not entirely true. Delayed_job logs how long each job took on its last run. So you could parse the log and graph it. I don’t like parsing logs, and if you have more than one worker you’ll have to aggregate the different logs somehow, it’s just a big mess. Also, it only gives you how long it took to run, doesn’t give you when it started and finished, so you can’t graph that other stuff I mentioned at the end. My plugin, for example, has slightly different semantics, and tells you how long the job took IN TOTAL to run, counting retries. You can’t do that by parsing the log. I could’ve added the extra data to the log itself but, as I said, I hate parsing logs, and delayed_job already let you keep failed jobs around, so I thought it wouldn’t be too inconsistent to leave successful ones there too.

  • Share/Bookmark

Second steps with CouchDB: Playing with hierarchical data

So I jumped on the bandwagon and joined all the cool kids in scorning relational databases and playing with CouchDB (for a sort of long and excellent wrap up on this versus that, read this). I installed it, read through a lot of docs, thought I understood it pretty well and immediately started searching the tubes for what Ruby framework/library/gizmo would best allow me to get kickstarted with using it on a new project.

Turns out that was a bit premature, as my brain couldn’t really handle trying to model the domain of my intended application onto this totally new way of thinking so abruptly. It’s like when you’re a native Portuguese speaker and you’re drunk, trying to make yourself pass as speaking Spanish and you keep spilling out the German you’ve been learning for the past two years. I’m sure everyone can relate to that.

Time to take a step back.

The best way I found to get more familiar with this new type of database was to get rid of all the mental cruft I had around it. So I forgot about my app, its data model and the web framework and went on to play with the database alone.

I had seen this blog post about how to store hierarchical data in CouchDB and decided to play with the example data and views the guy provided (big thanks to Paul Bonser!). [Note: If you can follow that, you don't need to read this, as it's basically an expanded version of one of his examples.]

This is the data:


{
  "docs": [
    {"_id":"Food", "path":["Food"]},
    {"_id":"Fruit", "path":["Food","Fruit"]},
    {"_id":"Red", "path":["Food","Fruit","Red"]},
    {"_id":"Cherry", "path":["Food","Fruit","Red","Cherry"]},
    {"_id":"Tomato", "path":["Food","Fruit","Red","Tomato"]},
    {"_id":"Yellow", "path":["Food","Fruit","Yellow"]},
    {"_id":"Banana", "path":["Food","Fruit","Yellow","Banana"]},
    {"_id":"Meat", "path":["Food","Meat"]},
    {"_id":"Beef", "path":["Food","Meat","Beef"]},
    {"_id":"Pork", "path":["Food","Meat","Pork"]}
  ]
}

Which corresponds to this tree:
Tree

To create a database and import this data, save that snippet as a file somewhere (I’ll use /tmp/data.json). CouchDB talks to the world in HTTP. We’re gonna use curl for that so you really see what’s going on. Web browsers are for wimps.

Usually CouchDB runs locally on 127.0.0.1, port 5984. To create a new database all you need to do is PUT to that address with the name you want your DB to have in the URL and no payload. We’ll save that URL in a variable because we’re gonna use it a lot.


DB="http://127.0.0.1:5984/hierarchical_data"
curl -v -X PUT $DB

Here -v means verbose, and -X lets you choose the HTTP method.

We have our database, now we import the data using the bulk document API. We specify the payload (data) with -d and feed it as a string from the file by prefixing its path with a @ (that’s one bash trick I didn’t know about!):


curl -v -d @/tmp/data.json -X POST $DB/_bulk_docs

And this is the view I was interested in (it lists all descendants of a node, including itself):


{
  "language": "javascript",
  "views": {
    "descendants": {
      "map": "
        function(doc) {
            for (var i in doc.path) {
                emit(doc.path[i], doc)
            }
        }"
    }
  }
}

This thing about views going through all objects in your database took a little time to sink in with me. Initially I thought the query took place in the view, that I would somehow pass the node from which I wanted the descendants as the doc argument to that function. That’s not how it works. The query actually takes place in the view parameters, and the view function itself only flattens everything out into a convenient array so you can query it better.

This view I just mentioned, for example, doesn’t actually give you the elements in a sub-tree. It goes through each object (document) in the database and adds it to the array of results once for each of its ancestors.

To see if for yourself, save it in a file somewhere (/tmp/view.json in my case) and add it to the database. We do that by creating a special design document:


curl -v -d @/tmp/view.json -X PUT $DB/_design/tree

Now, to run it, just execute:


curl -v -X GET $DB/_design/tree/_view/descendants

Or see it in the browser: http://localhost:5984/hierarchical_data/_design/tree/_view/descendants

This is what you get:


{"total_rows":29,"offset":0,"rows":[
{"id":"Banana","key":"Banana","value":""},
{"id":"Beef","key":"Beef","value":""},
{"id":"Cherry","key":"Cherry","value":""},
{"id":"Banana","key":"Food","value":""},
{"id":"Beef","key":"Food","value":""},
{"id":"Cherry","key":"Food","value":""},
{"id":"Food","key":"Food","value":""},
{"id":"Fruit","key":"Food","value":""},
{"id":"Meat","key":"Food","value":""},
{"id":"Pork","key":"Food","value":""},
{"id":"Red","key":"Food","value":""},
{"id":"Tomato","key":"Food","value":""},
{"id":"Yellow","key":"Food","value":""},
{"id":"Banana","key":"Fruit","value":""},
{"id":"Cherry","key":"Fruit","value":""},
{"id":"Fruit","key":"Fruit","value":""},
{"id":"Red","key":"Fruit","value":""},
{"id":"Tomato","key":"Fruit","value":""},
{"id":"Yellow","key":"Fruit","value":""},
{"id":"Beef","key":"Meat","value":""},
{"id":"Meat","key":"Meat","value":""},
{"id":"Pork","key":"Meat","value":""},
{"id":"Pork","key":"Pork","value":""},
{"id":"Cherry","key":"Red","value":""},
{"id":"Red","key":"Red","value":""},
{"id":"Tomato","key":"Red","value":""},
{"id":"Tomato","key":"Tomato","value":""},
{"id":"Banana","key":"Yellow","value":""},
{"id":"Yellow","key":"Yellow","value":""}
]}

As you can see, there was no view parameter in that call, and this looks nothing like a list of descendants. Each emit call is responsible for one line of the output, which contains the id of the doc object, a key and a value. [I replaced doc as the value in the original emit call with '' to make it more readable.]. Note that lines do not appear in the order they were emitted (otherwise you’d see lines with the same id grouped together). CouchDB automatically sorts them by key. Another thing you’ll notice is that all the lines whose keys have the same element are also a descendant of that element. Convenient, huh?

Now, to get the descendants of one particular node, just query the view with that node’s name in the key:


curl -v -X GET 'http://localhost:5984/hierarchical_data/_design/tree/_view/descendants?key="Fruit"'

Or, again, use the browser: http://localhost:5984/hierarchical_data/_design/tree/_view/descendants?key=%22Fruit%22

And bingo!


{"total_rows":29,"offset":13,"rows":[
{"id":"Banana","key":"Fruit","value":""},
{"id":"Cherry","key":"Fruit","value":""},
{"id":"Fruit","key":"Fruit","value":""},
{"id":"Red","key":"Fruit","value":""},
{"id":"Tomato","key":"Fruit","value":""},
{"id":"Yellow","key":"Fruit","value":""}
]}
  • Share/Bookmark

Untangling licensing options to achieve better collaboration on free web software

The ‘loophole’

Lots of people write frameworks and plugins and libraries intended for use on the Web. A lot of that is FOSS. But, as everybody knows, free software licenses like the GPL lose their “virality” when used for the web, since you’re not giving away any software (which would then force you to make the code available), you’re just providing a service. As long as you don’t give away the software, you can keep your modifications nice and cozy inside your server, without anybody knowing about it, and it’s still all legal.

Less Sharing

Occasionally I’ve made small contributions to such software projects and I might eventually release some of my own. But you know, I like Linus’ tit-for-tat attitude, and I’d like to get back improvements from people who are using my web-related stuff.

Sure, a lot of people contribute back, as you can see on GitHub, even if they don’t have to. Some folks are just that nice. But, and I’m taking a wild guess here, there’s a large hidden part of users who make modifications and don’t give them back simply because it’s extra work making it look nice, maybe conforming to the project’s coding standards, removing private, company-specific stuff, etc., and the employer only cares that it works, not that it’s shared back. So a lot of potential hacking freedom mojo is lost due to time/budget constraints or just pure laziness.

A solution?

Apparently I’m not alone in thinking this, as the FSF wrote the Afferos General Public License (AGPL) specifically to cover this area, which was previously overlooked. Now you have to give back modifications on AGPLed code, whether you give away the code or just provide a service with it over a network. Great! Now I can make a Rails plugin and get back some contributions!

Small problem though: like the GPL, the AGPL is viral, and so the installation of a mere plugin would require the whole app to be open-sourced as well. Fat chance.

The same problem existed in the desktop world, so they came up with the LGPL, which lets you use the library in proprietary software, but forces you to give back changes you made to the library itself. Sadly, there’s no “ALGPL” equivalent for us web folks. So what now? Are we doomed to have our FOSS mojo drained forever into the gutters of licensing loopholes?!

No!

The solution!

While not as good as making an ALGPL, the clever FSF guys put a nice little linking exception in both GPLv3 and AGPLv3, allowing you to use software licensed under any of them together. What does that mean?

It means that now you, application developer, can take my AGPL plugin/library and use it on your app, which is GPL, and give me back only changes you make to my stuff.

Wait a minute! So you’re saying I have to license my code as GPL?! Kind of, yes. But since you don’t give out your code anyway, to the outside world it’s completely unknowable if it is indeed GPL or not. You just stick a LICENSE file in there with the GPL text and that’s it. Nobody has to know about it, and you don’t have to do a thing (and I won’t even check if the file is actually there). For the web, GPL == proprietary.

Sounds convoluted? Nah. It’s actually quite simple. Summarizing:

  1. Put the GPL text in a hidden file in your web app;
  2. Install my plugin/library;
  3. Change it around, make it better;
  4. Give me the changes.

That’s it. Since other people will also be giving me their improvements, you will also benefit, all of that while keeping your application nice and proprietary. Good, eh?

  • Share/Bookmark