Codemountain, Paulo Suzart's Blog

Clojure e seus “Incantos”

with 3 comments

Ta bom, eu sei que é encantos, mas resolvi escrever “Incantos” por postar aqui muito rapidamente sobre uma lib clojure chamada Incanter.

Durante a construção do JTornado, resolvi fazer um exemplo de utilização em clojure. A sensação que eu tive foi a mesma que você vai ter quando olhar o código abaixo. Algo do tipo: “c@#, esse negócio é impossível!”. Me senti exatamente como Brenton Ashworth se sentiu ao descrever seus primeiros contatos com a linguagem em uma entrevista a Fogus.

Mas não aceitei o desaforo de me sentir assim e encarei o aprendizado da linguagem com mais seriedade. Para a minha supresa, a linguagem é tão concisa e tras consigo uma ideologia tão profunda, que tudo é naturalmente compreendido. Imediatamente fiz uma conexão Os ensinamentos do Budha, principalmente no tocante a impermanência de todas as coisas.

Ok, não vamos gastar as poucas linhas que pretendo escrever.🙂 Mas a ideia trazida por Rich Hickey é – guardadas as proporções – muitíssimo semelhante.

Por algum motivo achei um post do Michael Kohl (que inclusive me deu  boas dicas de como melhorar a primeira versão deste exemplo), onde ele usa o Incanter para analisar – inclusive graficamente –  a utilização de linguagens de programação em projetos hospedados no GitHub. Aquilo me saltou aos olhos de imediato.

Vamos chamar o Incanter de uma poderosa construção em clojure que integra elegantemente diversas libs java (veja a descrição no site) matemáticas, estatísticas e de plotagem. O resultado não poderia ter sido melhor. E nada como um bom motivo (ainda que você force a barra um pouco :p) pra usar algo que você quer aprender.

Na pós-graduação, a professora de Gestão de Pessoas passou um questionário para que pudéssemos visualizar nosso Estilo Motivacional. O teste se chama LEMO e visa detectar se você é uma pessoa de estilo Ação, Participação, Conciliação ou Manutenção. Sem entrar em detalhes, o teste consiste em anotar as respostas do questionário e efetuar somas simples por quesito, o resultado é categorizado em estilos dentro de uma situação normal de trabalho e numa situação de pressão.

Ok, não precisava desenvolver nada pra calcular, a professora até entregou uma planilha com tudo arrumado, era só preencher. Mas se eu preenchesse não seria eu. E aí vem:

(ns lemo
 (:use (incanter core io charts stats)))

(def lemo (read-dataset "lemo.txt"
 :header true
 :delim \;))

(defn bar [data title]
 (bar-chart ["p" "a" "m" "c"]
 data
 :title title
 : x-label "Motivational Style"
 :y-label "Degree"))

(defn line [n p]
 (doto (line-chart ["Normal" "Pressure"]
 [(sd n) (sd p)]
 :title "Standard Deviation"
 :y-label "Deviation"
 : x-label "Condition")

 (add-subtitle "From Normal to Pressure Conditions")))

(let [[norm press] (->> lemo
 to-matrix
 (partition-all 9)
 (map trans)
 (map #(map sum %)))]
 (view (bar norm "Normal Conditions"))
 (view (bar press "Under Pressure"))
 (view (line norm press)))

;;lemo test can be loaded from http://gist.github.com/526089

Susto? Provavelmente sim. Onde está o método main? Qual é o nome da classe? Bom, esquece tudo isso! Clojure nem é orientada a objeto, embora tudo nela seja um. #WIN.

O código acima basicamente lê um txt onde coloquei todas as minhas respostas (linha 4 a 6). No script observe um um binding (usando let) para duas variáveis de nomes norm e press cujos valores são o primeiro e segundo ítem da lista retornada de uma série de aplicação de funções:

  • to-matrix: deve ser intuitivo, estou convertendo meu data-set em uma matriz
  • (partition-all 9) : como optei por colocar todas as respostas juntas (em condições normais e de pressão), apenas organizei os dados por estilo, que corresponde as questões a,b,c e d. Então tenho 9 questões para uma e 9 para outra condição.
  • (map trans): a função anterior particionou minha matrix em 2, uso a função nativa map, para gerar a matriz transposta de cada uma delas.
  • (map #(map sum %)): A função anterior gerou uma transposta para cada matriz, ou seja, 2 matrizes, por isso o map outra vez, mas ao invez de aplica trans eu aplico uma função anônima #(map sum %). Esta função diz: para cada linha da matriz (map) aplique a função de soma (sum). Ah! Cada linha da matriz será passada como primeiro argumento (%) para a função anônima.

Sem atribuições, sem mutações, nada.

Isso é permitido devido à função ->>, que executa  uma espécie de folding das funções listadas, aplicando na próxima função – como último parâmetro – o resultado da execução anterior. A gente já faz muito isso em programação funcional, e chama-se fold (dobrar). Mas, mais frequentimente “dobramos” listas de números, Strings, etc. Por que não dobrar uma sequencia de funções?

Pronto! Agora é só pegar os dados e brincar de gráficos.

Para mostrar os resultados, criei duas funções, a bar e a line (definidas por defn). A função bar recebe a primeira lista de valores (norm) – que corresponde a meu Estilo Motivacional em Situação Normal – e retorna um gráfico em barras:

Naturalmente, a segunda lista de valores de (press), mostra meu Estilo Motivacional em situações de Pressão. Mais uma vez usei bar para gerar o gráfico:

Por fim, e tão sem necessidade quanto calcular e gerar gráficos (a não ser a própria diversão e aprendizado), observei que em situação de pressão meus estilos tendem a se equilibrar. Quanto? Para saber o quão distante estão meus estilos nas duas condições, gerei um terceiro gráfico onde uso Desvio Padrão, a função sd do Incanter.stats. Note que em situação normal, meu estilo Conciliador é mais baixo, o que gera um desvio de aproximadamente 4.5 pontos. Com o equilibrio, passo a ter um desvio de pouco mais de 1.5 pontos. O gráfico a seguir mostra que mudando de condição, há um decrescimento no desvio.

Como foi possível notar, meu Estilo Motivacional predominante é o Manutenção. Isso significa (também) que sou capaz de fazer algo como este post só por diversão e a troco de algumas horas pensando e estudando.

Sugestão para executar o script em sua máquina: Cljr vai ajudar a instalar e rodar tudo redondinho inclusive com o claspath configurado. Lembre de executar um:

> cljr install incanter

É preciso executar o lemo.cljr no mesmo diretório que o lemo.txt. A versão utilizada no post é a {:major 1, :minor 2, :incremental 0, :qualifier “beta1”}.

Espero que tenha sido divertido, você encontra o original dos fontes em um dos meus Gists: Este. E lá você pode ver a evolução da coisa. Comecei brincando de calcular e terminei neste post (que decidi fazer hoje mesmo).

Antes que esqueça, o Incanter se inspirou no R, que é uma linguagem  funcional para construção de computações estatísticas provinda do S. R possui forte semelhança com APL, que tem uma implementação feita pelo próprio criador da, chamada J. Ambas Sensacionais!

Até a próxima e não esqueça de me seguir no twitter: @paulosuzart.

Nota: no código, note que :y-label tem os dois pontos juntos à letra y, o que é não possível com a letra x, por isso ao espaço entre o : e o x. O wordpress resolveu colocar um emoticon ao detectar esta sequencia.

Written by paulosuzart

agosto 19, 2010 às 10:17 pm

Publicado em clojure

Tagged with ,

3 Respostas

Subscribe to comments with RSS.

  1. Nice post!

    One small comment though: R is not from the APL language family, it’s a free implementation of a language called S that appeared in the mid-70s. It internally uses matrices though, which definitely is a similarity to APL’s/J’s use of matrices.

    Will I see you at my Clojure course btw?🙂

    citizen428

    agosto 20, 2010 at 6:55 am

    • Thanks for better info about R. It’s really similar to J. Will fix it. About the course, I`m trying to get some friends too.
      Thank you.

      paulosuzart

      agosto 20, 2010 at 11:36 am

  2. Gostei do post mano, até deu vontade de estudar clojure, ja vou instalando aki😀. Esse incanter eh muito bom mesmo, tive umas ideias loucas para ele.

    Abraços.

    Abraao

    agosto 20, 2010 at 2:30 pm


Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: