quinta-feira, 19 de junho de 2008

Erlang é dificil (parte 2)

Agora vamos usar as funções específicas para manipular listas.

-module(tut).
-export([generate/1]).

%%
%% Funcao generate(X)
%% Quando X for 0, retorna [0]
%% Quando X > 0, retorna [X,X-1,...,0]
%% Caso contrario retorna [0,1,2,...,abs(X)]
%%
generate(0) -> [0];
generate(L) when integer(L), L > 0 ->
lists:seq(0,L); % cria uma lista de 0 até L
generate(L) when integer(L) ->
% vamos reverter a lista?
lists:reverse(generate(-L)).


Muito mais simples, certo? Veja o teste:

$ erl
Erlang (BEAM) emulator version 5.5.5 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.5.5 (abort with ^G)
1> c(tut).
{ok,tut}
2> tut:generate(5) ++ tut:generate(-5).
[0,1,2,3,4,5,5,4,3,2,1,0]
3>


O operador ++ une 2 listas :)

quarta-feira, 18 de junho de 2008

Erlang é dificil?

Erlang é realmente dificil?

-module(tut).
-export([generate/1]).

%%
%% Funcao generate(X)
%% Quando X for 0, retorna [0]
%% Quando X > 0, retorna [X,X-1,...,0]
%% Caso contrario retorna [0,1,2,...,abs(X)]
%%
generate(0) -> [0];
generate(L) when integer(L) -> gera_lista(L).

gera_lista(L) when L > 0 -> gera_lista_direita(L);
gera_lista(L) -> gera_lista_inversa(-L).

gera_lista_direita(L) -> gera_lista_direita(L,[]).

gera_lista_direita(-1,Z) -> Z;
gera_lista_direita( L,Z) ->
%io:format("chamando: gera_lista_direita(~p,Z)~n",[L]),
gera_lista_direita(L - 1,[L | Z]).

gera_lista_inversa(L) -> gera_lista_inversa(L,[]).

gera_lista_inversa(-1,Z) -> Z;
gera_lista_inversa( L,Z) -> gera_lista_inversa(L,0,Z).

gera_lista_inversa(-1,_,Z) -> gera_lista_inversa(-1,Z);
gera_lista_inversa( L,A,Z) ->
%io:format("chamando: h(~p,~p,Z)~n",[L,A]),
h(L - 1, A + 1,[A | Z]).


Ok, dessa forma é dificil. Erlang é uma linguagem funcional, ou seja, suas funções seguem um raciocínio matemático e não imperativo. Vc sente o problema quando quer resolver algo iterativo ou utilizar variaveis de qualquer forma.

Fiz uma pequena função chamada generate, do modulo tut (de tutorial, uma vez que estou seguindo um). Ela é muito simples, se vc informar 0, ela gera uma lista simples contendo 0. Se vc passar um numero positivo ela gera uma lista de 0 até o número, inclusive. Se o numero for negativo, ele assume que vc quer fazer fazer a lista de forma inversa.

Veja só:
$ erlc tut.erl   # compilando o modulo
$ erl
Erlang (BEAM) emulator version 5.5.5 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.5.5 (abort with ^G)
1> c(tut). # carregando o modulo
{ok,tut}
2> tut:generate(0). # invocando modulo:funcao(parametros).
[0]
3> tut:generate(10).
[0,1,2,3,4,5,6,7,8,9,10]
4> tut:generate(-10).
[10,9,8,7,6,5,4,3,2,1,0]
5>


A função generate chama a função gera_lista se o parametro passado for um número inteiro.
A função gera_lista chama a função para gerar a lista direita ou inversa, de acordo com o valor do parâmetro.

Veja só a simplicidade:

gera_lista_direita(L) -> gera_lista_direita(L,[]).

gera_lista_direita(-1,Z) -> Z;
gera_lista_direita( L,Z) ->
%io:format("chamando: gera_lista_direita(~p,Z)~n",[L]),
gera_lista_direita(L - 1,[L | Z]).


quando eu chamo gera_lista_direita(10) eu estou, na verdade, chamado a função gera_lista_direita(10,[]), onde eu fico usando uma lista como acumulador.

A operação [L | X] pode ser lida como [ elemento | lista ] , ou seja, eu adiciono um elemento em uma lista. gera_lista_direita(10,[]) vai chamar, então, gera_lista_direita(9,[10]), e depois gera_lista_direita(8,[9, 10]), e assim recursivamente até gera_lista_direita(-1,Z), quando eu retorno a lista. Fica claro se removerem os comentários (%) da frente dos io:format, que é a forma de fazer PPADD (Passei Por Aqui Driven Development) em Erlang.

Erlang precisa de MUITA pratica, principalmente de quem nunca programou em uma linguagem funcional e fica tentado a fazer coisas 'não ortodoxas' ;-)

Ah sim, o google é seu amigo:

http://www.dei.isep.ipp.pt/~paf/orgcdocs/Intro_Erlang.pdf

Tabela do Brasileirão 2008 com links + sed

O sed é um processador de texto muito versátil.

O links é um browser modo texto com features tão interessantes quanto do antigo lynx.

Ano passado eu postei como imprimir a tabela do brasileirão com um one liner interessante. Agora eu resolvi beber de outra fonte:

#!/bin/bash
TIME=Internacional
COLOR=$(echo -ne '\e[31;1m&\e[m')
URL=http://globoesporte.globo.com/Esportes/Futebol/Classificacao/0,,ESP0-9827,00.html
links --dump ${URL} | sed -r 's/\[[0-9]*\]//;/(^[0-9]|J jogos)/!d' | sed "s/${TIME}/${COLOR}/
1a-----Libertadores----------
4a-----Pre-Libertadores------
5a-----Sul-Americana---------
13a---------------------------
17a-----Rebaixado-------------"


O resultado não é tão bom quanto o do ano passado, é verdade, mas não deixa de ser uma alternativa

sexta-feira, 13 de junho de 2008

Gerenciando Inovações

No ramo da tecnologia da informação, vulgo informática, saber gerenciar inovações é uma arte. Não tenho outras palavras para descrever o fato de vc olhar para uma ideia como o gmail, youtube, icq, orkut ou geocities e dizer "isso tem futuro". Mas não é bem assim.

A história de cada inovação bem sucedida é extremamente complexa: são opiniões diversas, conflitos internos, apostas, brigas e muito trabalho para transformar uma ideia em algo que marque de verdade. Com certeza nada naquilo que temos hoje é o que foi imaginado de primeira, afinal os conceitos evoluem. Com certeza aquele chefe chato que barrava todas as ideias contribuiu, mesmo que indiretamente, para o sucesso da ideia.

Ai tem um ponto interessante: quem não conhece aquele chefe que barra todas as ideias inovadoras? Estes são o outro extremo da coisa! A informática muda muito, as pessoas que tem computador hoje são diferentes das que tinham no passado e assim por diante, é dificil vc inovar sem se arriscar muito: é ai que entra o medo.

Em todos os ramos existe inovação, o que diferencia é a velocidade com a qual as coisas andam. Alguns ramos seguem as mesmas ideias por décadas ou séculos, enquanto outros ramos a escala é de semanas. É dificil não ter medo, afinal ou vc inova ou vc faz coisas loucas, inconsequentes, que podem destruir todo um trabalho de uma vida.

O segredo é saber o que vc quer. Empresas de tamanho médio inovam com algum pé atrás, apostando em formulas consagradas e alguma novidade para quebrar o clima. Empresas grandes não podem se dar ao luxo de inovar sob pena de perder o fio da meada portanto podem comprar as empresas pequenas que, inovando, podem gerar lucro para gigantescas corporações multinacionais. E este é apenas um cenário de muitos que acontecem por ai. Temos empresas que sabem vender o convencional como se fosse inovação, e vice-versa.

A questão é: como lidar com inovações quando as mesmas podem ser o próximo microsoft bob ou o Iphone? Acho que cada um tem a sua formula: seja inovando ou comprando inovações por chegar a um tamanho que não é possivel não ser burocrata, cada um enfrenta essas novas tendências como acha melhor, trabalhando num ramo muito recente, onde as regras estão sendo escritas por bilhões de pessoas.

A resposta não é algo vago como: dilheiro dá em árvores ou todos tem potencial para ser algo mágico, etc, etc. É necessário entender as inovações que surgiram nos ultimos 10 anos (flash, ajax, orkut, celular, busca por palavras chave, etc) e reconhecer que existem milhões/bilhões de pessoas que contribuem para isso e elas são extremamente intelectualmente ativas. Uma face disso são os projetos open source como Linux, Hibernate e Ruby on Rails que competem de igual para igual com gigantescas corporações.

Resumindo: eu não sei lidar com inovações, mas elas chegam até mim via centenas de privilegiados que bebem da fonte. De alguma forma eu participo delas, mas não sei gerar nenhuma, tampouco saberia gerenciar, mas sei respeitar que o assunto é complexo e, principalmente, causa medo.

Medo de prejuizos. Principalmente se alguem lembrar muito, ou pouco.

quarta-feira, 28 de maio de 2008

Pesquisando nos Grupos do Yahoo

Meu amigo MrBits me deu essa grande ideia:

#!/bin/bash
QTDE=20
CHARSET=UTF-8
GROUP=shell-script

while getopts g:c:q: OPTION ; do
case $OPTION in
g) GROUP=$OPTARG ;;
c) CHARSET=$OPTARG ;;
q) QTDE=$OPTARG ;;
esac
done

shift $(($OPTIND -1))

SEARCH="$@"

if [ -z "$SEARCH" ]; then
echo "Usage: $(basename $0) [-q qtde] [-g grupo] [-c charset] search"
exit 1
fi

BASEURL="http://br.groups.yahoo.com/group"
URL="${BASEURL}/${GROUP}/msearch?submit=OK&charset=${CHARSET}&cnt=${QTDE}&query=${SEARCH// /+}"
SEDCMD="/message/!d;/${GROUP}/!d;/.*[0-9]/!d;s#/group#${BASEURL}#g;s/<[^>]*span>//g;s/$/<br \/>/"

LYNXOPT="-dump -force_html -assume_charset=${CHARSET}"
lynx $LYNXOPT <( curl -b /tmp/cookie$$ -sL "${URL}" | sed "${SEDCMD}" )


Vejamos em uso:
$ ./find.sh              
Usage: find.sh [-q qtde] [-g grupo] [-c charset] search

$ ./find.sh -q 10 getopts # procurando por getopts limitando a 10 registros
[1]Re: [shell-script] Script de busca de mensagens
[2]Re: [shell-script] Re: script iterativo / passo a passo
[3]Re: [shell-script] Script de Backup
[4]Re: [shell-script] Script de Backup
[5]Re: [shell-script] Script de Backup
[6]Re: [shell-script] Script de Backup
[7]Re: [shell-script] Echo e executa: superecho
[8]Re: [shell-script] testar se parametro $1 foi passado
[9]Re: [shell-script] Echo e executa: superecho
[10]Re: [shell-script] testar se parametro $1 foi passado

References

1. http://br.groups.yahoo.com/group/shell-script/message/26373
2. http://br.groups.yahoo.com/group/shell-script/message/26204
3. http://br.groups.yahoo.com/group/shell-script/message/26078
4. http://br.groups.yahoo.com/group/shell-script/message/26076
5. http://br.groups.yahoo.com/group/shell-script/message/26075
6. http://br.groups.yahoo.com/group/shell-script/message/26072
7. http://br.groups.yahoo.com/group/shell-script/message/25742
8. http://br.groups.yahoo.com/group/shell-script/message/25720
9. http://br.groups.yahoo.com/group/shell-script/message/25719
10. http://br.groups.yahoo.com/group/shell-script/message/25718


Divertido, não? o default é procurar no grupo shell-script do yahoo, mas ele pode investigar em qualquer um.

Valeu Mr.Bits!!

terça-feira, 27 de maio de 2008

Francisco Ayala: Ciencia e Religiao

Interessante conclusão do Francisco J. Ayala:

Considere que pelo menos 20% das gravidezes notoriamente terminam em aborto espontâneo. Se isso resulta de anatomia divinamente inspirada Deus é o médico que mais realiza abortos.


Vale a pena ler o resto aqui

O começo:
Ex-padre defende que Deus e teoria evolutiva de Darwin são compatíveis

Para um professor universitário, Francisco J. Ayala passa muito tempo na estrada.
Biólogo e geneticista evolutivo na Universidade da Califórnia em Irvine, ele freqüentemente fala em universidades, igrejas e qualquer outro lugar, geralmente em defesa da teoria da evolução e contra argumentos do criacionismo e seu primo ideológico, o design inteligente.

quarta-feira, 21 de maio de 2008

Hello World orientado a objetos

Hoje em dia é raro um desenvolvedor conhecer bem apenas uma linguagem. Em nome da multidisciplinaridade, decidi mostrar algums exemplos do mesmo programa: uma classe HelloWord com um construtor que recebe uma mensagem ("ola mundo") e um método show() que imprime essa mensagem.

Vejamos um exemplo em C++

#include <iostream>
#include <string>
using namespace std;

class HelloWorld{
string mensagem;
public:
HelloWorld(string mensagem) { // construtor!
this->mensagem = mensagem;
}

void show() { // metodo show
cout << "mensagem: " << this->mensagem << endl;
}
};
int main()
{
HelloWorld obj("ola mundo");
obj.show();
return(0);
}


Agora o mesmo código em Java:

package Hello;

public class HelloWorld{
private String mensagem;
public HelloWorld(String mensagem){
this.mensagem = mensagem;
}
public void show() {
System.out.println("mensagem: " + mensagem);
}
public static void main(String [] args){
HelloWorld obj = new HelloWorld("ola mundo");
obj.show();
}
}


Agora, percebam a simplicidade do Ruby:
class HelloWorld
def initialize(mensagem)
@mensagem = mensagem
end
def show
puts "mensagem: #{@mensagem}"
end
end

obj = HelloWorld.new "ola mundo"
obj.show


Agora em Perl (sim, Perl!)
package HelloWorld;

sub new
{
my ($class, $mensagem) = @_;
my $self = { mensagem => $mensagem };
bless $self, $class; # abençoando a variavel!
return $self;
}

sub show
{
my $self = shift; # sim, ela vem como argumento!
print "mensagem: " . $self->{mensagem} . "\n";
}

my $obj = new HelloWorld("ola mundo");
$obj->show(); # parece artificial, não?

1;


PHP também é:
<?php

Class HelloWorld{
var $mensagem = "";
function HelloWorld($mensagem){
$this->mensagem = $mensagem;
}
function show(){
echo "mensagem : " . $this->mensagem . "<br/>";
}
}

$obj = new HelloWorld("ola mundo");
$obj->show();
?>


Por fim, vamos criar um tipo usando JavaScript
function HelloWorld(mensagem){
this.mensagem = mensagem;
this.show = function(){
alert("mensagem: " + this.mensagem);
}
}

var obj = new HelloWorld("ola mundo");
obj.show();


Edit: Python, atendendo a diversos pedidos
class HelloWorld:
def __init__(self, arg):
self.message = arg

def show(self):
print "mensagem: ", self.message

hello = HelloWorld("Ola Mundo")
hello.show()


A diferença entre uma linguagem e outra está (entre outras coisas) na sintaxe: em Perl eu tenho que criar os mecanismos na mão (com bless e receber $self) mas em Java e Ruby é tudo muito natural. Em Javascript eu não tenho uma construtor propriamente dito (muito menos classes) mas uma função (e crio um objeto dando um new nessa função).

Vou abordar o tema "herança" no proximo post, espero que seja útil :)

sexta-feira, 2 de maio de 2008

CRDS - Conselho Regional de Desenvolvedores de Software

Num futuro não muito distante, o carlinhos está desenvolvendo um pequeno sistema de contas a pagar para a Padaria do Manoel. Entretando o seu local de trabalho recebe uma visita de um fiscal do CRDS!

- Pronto
- Sr Carlos Silva?
- É ele.
- Meu nome é Teobaldo, sou fiscal do Conselho Regional de Desenvolvedores de Software. Fiquei sabendo que nesse recindo está sendo desenvolvido um "software".
- Exato! To desenvolvendo um...
- Antes de mais nada, qual a sua formação?
- Sou formado em ciências da computação pela faculdade VIVA VIVER, do Acre, na modalidade EAD. Meu trabalho de conclusão foi "um sistema escrito em java para a web 2.0".
- Puxa, ultimamente só tem dado essa faculdade.
- Po, ela custa 49,99 por mês...
- É claro. Continuando, onde está a ART desse sistema?
- Bom, é um sistema pequeno, com menos de mil linhas, precisa ART?
- Claro, e vc pode imprimir o boleto pelo site da CRDS, não tem desculpas.
- Ok. Eu pagarei...
- E onde está a documentação do sistema? Cadê o levantamento de requisitos, análise de impacto, análise de riscos, análise...
- EI! O meu sistema foi feito utilizando metodologias ágeis! É uma mistura de SCRUM com XP proporcionando um contrato de escopo aberto onde eu tento atender as necessidades do cliente, evitando burocracia, trabalhando em sprints de 15 dias...
- Ok, mas o CRDS exige essa documentação no template .doc que vc pode baixar do site
- Mas q .doc ?? Ta maluco, eu uso openoffice no meu linux.
- Linux ?? Vc desenvolve em um sistema operacional não homologado pela CRDS? Se ainda fosse Ubuntu...
- Mas Ubuntu é linux.
- Chega, se não tem documentação, como vc sabe que o sistema funciona?
- Eu uso testes unitários!
- Humm... teste precisa de um profissional habilitado em testes.
- Mas eu uso JUNIT, veja!
- Ei... q java esquisito é esse com esses @ e esses "maior e menor"?
- Isso se chama Annotations e Generics! Ta desde o Java 1.5
- Desculpe mas o CRDS só permite o uso de Java 1.4.2 que é a versão homologada para o Windows E Ubuntu.
- E se eu estivesse usando MacOS ?
- MacOS não foi homologado pelo CRDS ainda.
- Mas java é multiplataforma!
- Certo certo... e o modelo ER?
- Eu uso Hibernate para Abstrair o modelo ER..
- Hibernate ? Ok, terei que embargar o seu sistema...

TDD com Perl

É possivel fazer Test Driven Development com Perl? Mas claro :)

Artigo interessante sobre Test::More:
http://www.testingreflections.com/node/view/5333

Tutorial bem sucinto:
http://www.wgz.org/chromatic/perl/IntroTestMore.pdf

Excelente apresentação:
http://wellington.pm.org/archive/200606/tdd/

Pra descontrair...