terça-feira, 8 de maio de 2012

Linux salva o dia

A mulher amada foi viajar com um notebook (um HP-530) da empresa que, infelizmente, tem um Windows XP cheio de restrições. Não sendo possível instalar o Skype nele, saí à procura de um Linux para resolver o problema de comunicação.

Há muitos Linux que rodam direto de um CD ou DVD, mas são raros os que incluem o Skype. Encontrei uma variação sueca do Ubuntu 12.04 chamada ExLight. Ele funcionou muito bem com a webcam da Genius (uma FaceCam 1000) e com o Wifi (Intel PRO/Wireless 3945ABG).

O boot é demorado se o micro não estiver ligado por cabo a uma rede que devolva logo um IP por DHCP, mas ainda é mais rápido que iniciar o Windows. Esse Linux é tão obscuro que sequer consta do DistroWatch, mas resolveu tão bem o problema em questão que não hesito em indicá-lo.

segunda-feira, 30 de abril de 2012

Mapas de indicadores do RS

Na última terça-feira, dia 24/04, foram lançados os mapas de indicadores do TCE-RS. Eu trabalhei neles por um bom tempo e gostei de vê-los anunciados pela mídia do estado. Vou gostar ainda mais se meus compatriotas gaudérios os usarem para cobrar melhores resultados de seus prefeitos e suas câmaras municipais.

Os mapas foram escritos principalmente em Javascript (porque usam o Google Maps como base) e em PL/SQL (para gerar os dados). Não há muito no meio (deixei vários programadores Java sem emprego), exceto um script em Perl. O PL/SQL gera JSON, cujo resultado é armazenado em arquivos pelo script em Perl (porque algumas consultas são muito lentas e, de qualquer forma, porque eu não queria nenhuma carga extra desnecessária para o banco). O dia seguinte ao lançamento teve o maior número de acessos (6.487) e não teve nenhuma conseqüência sobre os servidores de aplicação e o banco justamente porque foram servidos apenas arquivos estáticos.



A principal dificuldade foi a de tirar um desempenho aceitável do Internet Explorer. O Javascript do IE é o pior por larga margem. Um Firefox 3 num Pentium Core Duo ainda é melhor que um IE9 num i7 de 4 núcleos. O garagalo principal está no código que desenha os 496 municípios; no IE ele demora tanto que o navegador acaba abrindo um alerta de que o script está demorando demais. A única forma de evitar esse problema foi dividir o trabalho no tempo com o setTimeout(). Os municípios são desenhados em grupos de 50 no IE e todos juntos nos outros navegadores.

As coordenadas foram comprimidas através de facilidades da própria API do Google Maps. A minha tentativa de comprimi-las tinha me levado de 1,5MB a 530KB, porque aproveitei o fato de que todas têm números negativos (exclui todos os sinais) e que as diferenças entre coordenadas consecutivas são pequenas (guardei apenas as diferenças sem o separador decimal). Mas a API do Google Maps é mais esperta e o arquivo final tem apenas 298KB.

Além da API do Google Maps, usei os plugins blockUI e Sparkline (para desenhar os gráficos) do jQuery. As consultas ganharam muito com o uso das funções analíticas do Oracle (que o Postgresql também oferece), já que com elas posso calcular médias e somas de vários anos distintos de uma só vez.

Em resumo, foi um excelente exercício de duas tecnologias muito diferentes: PL/SQL e Javascript. A primeira me permitiu escrever consultas muito mais legíveis e concisas; a segunda me permitiu jogar para o cliente toda a computação que restou fazer e assim aliviar a pressão dos servidores.

sábado, 28 de abril de 2012

Mobilidade cerceada

O tempo que levo para voltar do trabalho para casa tem me feito pensar sobre como é estúpido o sistema de transporte que estamos fomentando. Frequentemente, levo mais de 1h para percorrer os cerca de 9km entre meu trabalho e minha casa.

O maior problema é a quantidade de automóveis e o fato de que a maioria leva uma ou duas pessoas. Além disso, os autos estão ficando cada vez maiores. É irracional utilizar um veículo de uma tonelada e meia para carregar uma pessoa com menos de 100kg, mas esses gigantes estão se disseminando. Alguns precisam de duas vagas nos estacionamentos.

Como o país está numa fase de crescimento rápido e as pessoas encontram-se com dinheiro e a possibilidade de comprar carros enormes pela primeira vez, antecipo que vamos ter que aturar esse deslumbramento por um bom tempo ainda. Além disso, esse comportamento infantil adentra o reino do antissocial, porque os proprietários, além de não quererem dividir as ruas com ciclistas, pleiteiam para si cada vez mais investimentos de infraestrutura. Ciclovias são inúteis, reclamam, mas viadutos multi-milionários são indispensáveis.

Eu reservo-me o luxo de usar táxi-lotação, que são um pouco mais caros. Raramente uso ônibus, porque andam lotados e muitos não têm ar-condicionado. Penso que eles não melhoram, porque são vistos como negócio, não como utilidade pública. É muito fácil calcular despesas e lucros, ao passo que bem-estar ainda não sabemos quantificar.

Conferindo o orçamento da prefeitura de Porto Alegre em 2011, vejo que há milhões dotados para obras viárias: duplicação da Avenida Edvaldo Pereira Filho (R$32 milhões); duplicação da Avenida Voluntários da Pátria (R$9 milhões); prolongamento da Avenida Severo Dullius (R$8 milhões); implantação da Avenida Tronco (R$21 milhões); etc. Quando procuro por obras para pessoas, encontro pouco: construção de calçadão na Vila Assunção (R$245 mil dotados, mas nada pago); mobilidade e acessabilidade no centro (R$790 mil dotados, mas apenas R$290 mil pagos); obras viárias na área socioambiental (R$800 mil dotados, nada pago).

Esse excesso de ênfase no automóvel está tornando a vida cada vez mais complicada para todos. Estamos num círculo vicioso em que o transporte coletivo ruim incentiva o uso do carro e isso torna a mobilidade urbana ainda pior. Mas meus compatriotas estão ainda tão enamorados de seus brinquedinhos caros que não enxergam o efeito negativo que eles têm sobre suas vidas. Logo, o assunto que nos toma horas todos os dias não existe no debate político.

segunda-feira, 9 de abril de 2012

Juntando linhas

Tenho uma tabela de permissões que tem a seguinte forma:

CREATE TABLE PERMISSOES (
  OBJETO VARCHAR2(100),
  USUARIO VARCHAR2(100)
)
Eu preciso de um relatório que enumere todos os usuários para cada objeto, colocando todos os autorizados numa só linha. A minha solução, um pouco complicada, foi juntar as facilidades de consultas hierárquicas do Oracle com um pouco de funções analíticas.

O cerne da consulta é o seguinte SELECT:

select objeto, 
       row_number() over (partition by objeto order by usuario) ordem,
       row_number() over (partition by objeto order by usuario desc) medro,
       usuario
from permissoes
order by 1, 2, 3 desc
Isso produz uma lista de todos os objetos com os respectivos usuários numerados alfabeticamente tanto crescentemente como decrescentemente. Considere as seguintes linhas:

OBJETOUSUARIO
COFREHeráclito
COFREXenofonte
COMPUTADORHeródoto
COMPUTADORHeráclito
COMPUTADORPlatão

A consulta produzirá o resultado abaixo:

OBJETOORDEMMEDROUSUARIO
COFRE12Heráclito
COFRE21Xenofonte
COMPUTADOR13Heráclito
COMPUTADOR22Heródoto
COMPUTADOR31Platão

Envolvendo essa consulta com um SELECT hierárquico, podemos agregar os helenos.

  select objeto, substr(sys_connect_by_path(usuario, ','),2) autorizados 
  from (
    select objeto, 
           row_number() over (partition by objeto order by usuario) ordem,
           row_number() over (partition by objeto order by usuario desc) medro,
           usuario
    from permissoes
  )
  where medro=1
  connect by prior ordem=ordem-1 and prior objeto=objeto
  start with ordem=1
Então, uso a coluna ORDEM para simular uma hierarquia e a coluna MEDRO para eliminar todas as linhas exceto a última (que possui todos os usuarios relacionados a um objeto).

O resultado é o seguinte:

OBJETOAUTORIZADOS
COFREHeráclito,Xenofonte
COMPUTADORHeráclito,Heródoto,Platão

A função sys_connect_by_path() aglutina toda a hierarquia e neste caso indiquei uma vírgula como separador. No entanto, ela coloca uma vírgula também no início e para resolver isso adicionei a função substr().

segunda-feira, 2 de abril de 2012

Neofobia

Um amigo apareceu com um tablet daqueles chineses bem ordinários que não tem nome e muito menos manual. O aparelho roda Android e a tela deve ser das piores, porque é difícil de usar. O amigo perguntou (e eu já antecipava a pergunta) se seria possível instalar o Windows, porque era muito difícil configurar a rede sem fio no Android (não é).

O interessante dessa interação é que esse cidadão também não sabe configurar muita coisa no Windows. De fato, ele sabe fazer muito pouco no Windows além de iniciar o IE. Então, eu fiquei curioso: que problema haveria em ficar com o Android?

Eu já presenciei várias instâncias desse problema com pessoas que querem usar o micro para navegar e jogar paciência, mas que fazem questão absoluta de fazer isso com o Windows. O que me deixa mais perplexo é que a mudança do XP para o Windows 7 foi completamente indolor (aparentemente) enquanto eu ainda me atrapalho com o Explorer novo.

Que amor é esse ao Windows? Deve ser o prazer de ter que formatar o HD e reinstalá-lo todo ano!

terça-feira, 27 de março de 2012

Hipercontagem

Há um bom tempo venho colecionando as moedas comemorativas de um real. São elas a dos 50 anos da Declaração dos Direitos Humanos, a dos 40 anos do Banco Central e a do centenário de Juscelino Kubitschek.

MoedaEmissãoNa minha coleção
50 anos da Declaração dos Direitos Humanos600 mil2
40 anos da Banco Central40 milhões9
Centernário de JK50 milhões12

Provavelmente por eu as estar colecionando há vários anos, a distribuição delas na minha niqueleira é parecida com as proporções das emissões. A tabela abaixo mostra as proporções esperadas e as encontradas.

MoedaProporção do totalNa minha coleção
50 anos da Declaração dos Direitos Humanos0,6%8%
40 anos da Banco Central44%39%
Centernário de JK55%52%

Essas emissões especiais representam 4,4% do total de 2.024.376.000 da segunda família de moedas de um real (incluindo as comemorativas). Com isso, estimo que para juntar essas 23 moedas tenham passado quase 500 moedas de um real pela minha niqueleira. Claro, isso se as outras moedas comemorativas não tenham sido guardadas por malucos tentando estragar as estatísticas alheias.

segunda-feira, 27 de fevereiro de 2012

Transformando colunas em linhas III

Uma forma mais simples de transformar colunas em linhas é usar a função decode (do Oracle). Considere a seguinte tabela:

 CREATE TABLE PESSOAS (
    NOME VARCHAR2(200),
    NOME_PAI VARCHAR2(200),
    NOME_MAE VARCHAR2(200)
  )
Se for necessário produzir uma lista com todos os nomes, pode-se usar o decode da seguinte maneira:

select decode(n, 1, nome, 2, nome_pai, 3, nome_mae) 
from pessoas, 
     (select rownum n from pessoas where rownum<4)
A consulta com rownum serve apenas para produzir três linhas com os números 1, 2 e 3. Essa pequena tabela multiplica a tabela de pessoas por 3. O decode() então indica uma coluna diferente para cada valor de n. Assim, colocamos cada valor de coluna numa linha separada.