Páginas

Tuesday, October 25, 2011

Tuesday, October 4, 2011

O que é Coding Dojo?


O que é Coding Dojo?

Um Coding Dojo é um encontro no qual pessoas se juntam para trabalhar em um desafio de programação. O objetivo é a prática deliberada de programação como forma de melhorar habilidades pessoais e se divertir em grupo.

Premissa: o aprendizado é um processo contínuo e requer prática. Prática coletiva traz novos desafios e potencializa o aprendizado e a disseminação de conhecimento.

Características: o ambiente é colaborativo e divertido, adequado para testar novas ideias. Participantes com qualquer nível de conhecimento são bem-vindos.

Requisitos técnicos/físicos: sala com um computador e um projetor. Quadro branco ou flip-chart, post-its e comida são itens que ajudam ao longo do encontro.

O Coding Dojo é um espaço semanal na agenda para treinar boas práticas de programação, como Test-Driven Development (TDD), programação em par, código coletivo, passos de bebê, design incremental, entre outras práticas ligadas ao desenvolvimento Ágil de software.

A maioria das boas práticas do Dojo são derivadas da metodologia de desenvolvimento Ágil Extreme Programming. Mas o Dojo vai muito além quando consideramos os aspectos sociais, que envolvem convívio social, apresentação de ideias em voz alta para um público e trabalho em grupo para atingir um objetivo comum.

E o Coding Dojo Rio?

O Coding Dojo Rio iniciou seus encontros semanais em dezembro de 2008. Tudo começou em setembro daquele ano no encontro da comunidade brasileira de Python, o PyCon Brasil 2008, realizado no Rio de Janeiro.

Tuesday, September 20, 2011

Somos nossos conectomas

Resumo dos vídeos “Sebastian Seung, I am my connectome, TED Talk, 2010” e “Jeff Hawkins, MIT150 Symposium Brains, Minds and Machines, 2011”

Introdução

Um conectoma é um mapa detalhado das conexões neurais do cérebro. O termo é inspirado no termo “genoma”, e refere-se aos esforços científicos para capturar, mapear e entender a organização das relações neurais no cérebro.
O conectoma humano tem um milhão de vezes mais conexões que a quantidade de letras do seu genoma. Não se sabe ao certo quais informações podemos obter desses dados, mas especula-se que nossas memórias possam estar codificadas nas conexões de nossos neurônios. Outros aspectos como personalidade, intelecto, podem estar lá codificados.
Sebastian Seung fez uma apresentação de divulgação científica, explicando alguns conceitos, citando estudos passados e atuais, e tentando mostrar a importância e relevância do tema. No fim ele chega discutir a viabilidade de se estender a vida através da criogenia.
Seung reforça a ideia de auto-percepção do ser. Ele sustenta que “Eu sou mais que meus genes”, e que “Eu sou meu conectoma”. As interações neurais viriam a explicar o que os nossos genes não são capazes de explicar.
Um fato que achei particularmente interessante é que, similar ao estudo de genomas, existem muitos desafios científicos envolvidos. Encontrar conectomas implica resolver outros problemas, incluindo obtenção e processamento de imagens, como colorir um grafo gigante, escaneamento em três dimensões, habilidade de fazer zoom in/out em objetos 3d de alta resolução, processamento de enorme quantidade de dados, etc.
Pensando em redes complexas, considerar os genes isoladamente seria como olhar e entender cada nó da rede em sua individualidade. Mas já vimos que as redes codificam nas ligações entre os nós informações e características que não podem ser explicadas tomando como base as características individuais dos nós.

Thursday, September 15, 2011

Perl, Ruby, Python & Racket: time matters

Estava aqui pensando em duas coisas:

  1. Qual o comportamento de diversas linguagens de programação quando fazemos um "import" ou "require", e o que acontece se um mesmo arquivo for requirido várias vezes na árvore de dependências.
  2. Qual o tempo que leva para executar um script mínimo.
A motivação vem da diferença que dá usar #lang racket x #lang racket/base em Racket. Quando usamos a linguagem completa, temos todas as baterias em nossas mãos, e como penalização carregamos um monte de código pra memória sem que este seja efetivamente necessário. A segunda opção é mais leve, tem apenas definido elementos mais centrais da linguagem, ideal para usar quando estamos criando nossas bibliotecas.

Há uns anos atrás já havia feito experimentos similares (provavelmente não documentados) com Python. Agora fiz pequenos scripts em Python, Racket, Ruby e Perl para comparar. Atenção não leve em consideração os números deste post como "benchmarks" ou classificadores/qualificadores de uma ou outra linguagem.

O procedimento experimental

Para reproduzir este experimento, crie 4 diretórios:
mkdir t{python,ruby,racket,perl}
(Não entendeu a linha acima? Veja meu post sobre o uso de chaves no Bash)

Em cada um, crie 3 arquivos, "a", "b" e "c", com a extensão da respectiva linguagem.
O resultado final fica assim:

./tperl
├── a.pl
├── b.pl
└── c.pl
./tracket
├── a.rkt
├── b.rkt
└── c.rkt
./truby
├── a.rb
├── b.rb
└── c.rb
./tpython
├── a.py
├── b.py
└── c.py

Cada arquivo contém:
tpython/a.py
::::::::::::::
print "a"

tpython/b.py
::::::::::::::
import a
print "b"

tpython/c.py
::::::::::::::
import a, b
print "c"

Para as outras linguagens é similar, veja:

c.pl (Perl)

require "a.pl";
require "b.pl";
print "c\n";
c.rkt (Racket)
#lang racket/base
(require "a.rkt" "b.rkt")
(displayln "c")
c.rb (Ruby)
require 'a.rb'
require 'b.rb'
puts 'c'

Resultado 1

Todas as 4 linguagens parecem ser consistentes em:
  1. executar todo o código do corpo de um arquivo importado (incluindo efeitos-colaterais)
  2. não re-executar código já importado anteriormente (mesmo que por dependência indireta)
Ou seja, o resultado visual da execução de todos os exemplos é:

a
b
c

Resultado 2

Entretanto, o tempo de execução é bem diferente. Usando o time, os melhores resultados encontrados após muitas execuções num Core2Duo 2.2GHz com Ubuntu 10.10 64bits:

time perl c.pl
real 0m0.007s
user 0m0.000s
sys 0m0.000s

time ruby c.rb
real 0m0.010s
user 0m0.000s
sys 0m0.000s

time python c.py
real 0m0.015s
user 0m0.010s
sys 0m0.000s

time racket c.rkt
real 0m0.084s
user 0m0.060s
sys 0m0.020s

Se compilarmos o código Racket usando o "raco make", temos:

raco make c.rkt
time racket c.rkt

real 0m0.053s
user 0m0.030s
sys 0m0.020s


Conclusão
  • Racket e Python permitem fazer importação de vários módulos num único comando, enquanto que Ruby e Perl não. (Sim, existe o gem require_all pro Ruby, e certamente existe algo similar pro Perl no milagroso CPAN -- mas pelo que sei não existe solução "built-in" na linguagem)


  • Meus amigos Perl Monges devem ficar felizes porque Perl despontou como o mais rápido, né  Breno, Diogo, Samir, Ronald, e cia?
  • Meus amigos adeptos do Ruby vão ficar felizes e dizer que Ruby é mais rápido do que Python :P
  • Meus amigos Pythonistas, pé no chão, vão concordar que Python é rápido o suficiente e é mais divertido que Ruby (e que a conclusão acima, dos rubistas, não pode ser considerada já que meus resultados não provam nada...)
  • Meus amigos que ainda estão conhecendo Racket podem fazer caretas, normal... não tô nem aí :)
    Não me importo em "pagar o preço" para programar numa linguagem mais poderosa e bonita.

Obs: como as diferentes linguagens usam diferentes terminologias, perdoem o uso nem sempre preciso de "módulo", "arquivo", "importar", "requerer", etc. Espero não causar ambiguidade para o leitor.

Wednesday, September 14, 2011

Grep e Less com cores!

Esta é uma nota mental.

egrep -r --include="*.rkt" "[a-z-]+#" . --color=always | less -R

Para usar o Grep com cores, geralmente temos um alias grep='grep --color=auto' no nosso ~/.bashrc.

Mas acontece que muitas das vezes o resultado é grande é fazemos um pipe pro less. Como triste consequência perdemos as cores...
Para forçar o grep (egrep, fgrep, ...) a exibir cores use o --color=always, assim ele manda o output pro less com cores.
A opção -R do less faz com que ele interprete os caracteres de escape de cores do terminal.

grep "alguma coisa" /caminho/da/busca --color=always | less -R

Nota: pode ser usado também com o more:

grep "alguma coisa" /caminho/da/busca --color=always | more

[Update]
Como meu amigo Breno Oliveira sugeriu, uma alternativa interessante ao grep é o ack.
http://betterthangrep.com/

Usando o ack o comando fica:

ack "regexp perl" [caminho] --color | less -R