segunda-feira, 22 de dezembro de 2008

Novas Distribuições Linux

Diariamente eu leio noticias sobre novas distribuições, brasileiras ou internacionais.

Até que ponto isso é realmente necessário? Não seria melhor tentar focar em uma das excelentes distribuições que existem hoje em dia ou então tentar ajudar a manutenção de pacotes ou mesmo traduzir documentação?

Acho que produzir uma distribuição é um bom aprendizado, porém produzir algo que sera dificil de manter e atualizar pode ser bem penoso.

segunda-feira, 24 de novembro de 2008

Tirando o Mofo

Fiquei uns dias sem postar, hehe.

Tive pouco tempo livre, afinal além de pegar alguns projetos novos (e ter que aprender muito no processo) ainda tem a faculdade, que agora chega ao fim do semestre com algumas provas.

Nesse tempo também participei de alguns eventos legais, a começar pelo workshop de design patterns ministrado pelo Bruce Eckel (Thinking in Java, Thinking in C++). Foram 3 dias imerso em um mundo de orientação a objetos com exemplos em Java e Python. O Bruce é um cara muito bacana, tive a oportunidade de conversar bastante com ele e descobri que tinhamos algo em comum: uma graduação em física incompleta (chegamos a conclusão que não foi um tempo perdido pois aprendemos a resolver problemas, ou pelo menos demorar bastante tempo até desistir). Também tive a oportunidade de participar de um Coding Dojo onde resolvemos o problema da notação de trits (ao contrário, diga-se de passagem) usando Haskell. A ideia do Dojo é sensacional!

Também participei da PyConBrasil 2008. Foi um evento muito bom, excelente organização, sem falar que a sessão aberta com o Bruce sobre os rumos do Python foi o ponto forte, que surgiu totalmente do acaso. Python é uma linguagem muito interessante, com uma comunidade consideravel. Quem não usa python devido a indentação obrigatória do código usa um dos argumentos mais ridículos possiveis :)

Outro evento sensacional foi o workshop de Domain-Driven Design ministrado pelo Philip Calçado na Caelum/RJ. DDD é sobre comunicação, um ponto essencial no desenvolvimento de software nos dias de hoje. O Phillip foi responsavel, ainda que indiretamente, pela minha vinda a globo.com, porém só agora pudemos tomar aquele chopp e conversar sem ter 12 horas de diferença.

Sabado passado começou o curso on-line e intensivo de BDD on Rails com RSpec ministrado pelo Danilo Sato pela eGenial. Esta valendo a pena, pois parte daquela premissa que sempre defendi que temos que testar o nosso código e, para isso, existem varias abordagens e frameworks.

Estou preparando outros posts, devo atualizar este blog em breve.

sexta-feira, 24 de outubro de 2008

Fear, uncertainty and doubt

Fear, uncertainty and doubt (ou simplesmente FUD) não é algo novo. Volta e meia alguma instituição ou candidato a utiliza de forma a enfraquecer o(s) seu(s) adversário(s), geralmente os projetos open-source são vitimas frequentes.

Hoje, no Rio de Janeiro haverá o ultimo debate entre os candidatos a prefeito. Não sou de usar blog técnico como meio de propaganda politica porém não posso ficar de braços cruzados enquanto um candidato utiliza FUD, Boatos e Mentiras. Aqui e aqui vemos alguns exemplos extremamente baixos, que qualquer pessoa com um minimo de instrução deveria perceber. Até quando isso será permitido? E o TRE? E os panfletos apócrifos apreendidos?

Felizmente o outro candidato, cujo partido possui uma cor verde interessante, não responde na mesma moeda pois seria facil usar coisas desse tipo, mas que não acrescentam nada.

Realmente a melhor forma de se proteger do FUD é informando a população, cobrando das autoridades cabíveis e destacando o quão antiético é esse tipo de abordagem. Felizmente cada cidade tem o prefeito que merece.

terça-feira, 7 de outubro de 2008

Policia do RS usa MSN

Pelo que eu vejo nesse link, a Policia do RS está utilizando o MSN, que é um messenger bem comum hoje em dia, para receber chamados de socorro.

Com protocolos livres como o Jabber e clientes livres como o Pidgin, sera que uma alternativa mais barata e eficiente não poderia ser desenhada?

Da forma como é hoje, um serviço de segurança esta nas mãos de software/serviço e protocolo proprietário e fechado, e isso me preocupa como cidadão!

terça-feira, 2 de setembro de 2008

Chrome: o browser da google

As noticias apareceram em todas os sites especializados: o google estaria lançando hoje uma novidade chamada chrome, um browser baseado em Webkit disponivel por enquanto para Windows XP e Vista.

Até um gibi foi disponibilizado, então esperando até as 4 PM consegui fazer o download em uma maquina virtual e pude testa-lo um pouco.

A performance parece ser muito boa, apesar da virtualização. Não observei travamentos ou comportamentos estranhos (como os que ocorrem no Safari para Windows). O visual e as tabs são realmente práticas, com muita área para ver o site e icones intuitivos.

primeira_impressao

Bem interessante é o gerenciador de tarefas, (Controlar Pagina Atual > Desenvolvedor) onde podemos ver o consumo de cpu, memória e rede de cada aba (que rodam como processos independentes).

gerenciador_tarefas

E também temos acesso a informações de memória bem detalhadas (infelizmente estáticas, gostaria que houvesse algo como o top do unix, quem sabe no futuro...).
chrome_memory]

O histórico é limpo e muito bonito

chrome_historico

E um recurso que eu gostei bastante do novo Opera, mas com uma nova roupagem: ao abrir uma nova aba temos uma pagina com os favoritos e snapshots das paginas.

chrome_abas

Por fim, basta instalar com um clique o plugin flash para navegar no Youtube ou Globo Videos

chrome_globo_videos

Outras coisas que percebi: a pergunta para salvar as senhas dos sites é muito mais discreta, aparecendo acima do site após o login (não é aquele alert que surge do nada). O Gmail parece ter uma boa performance e o gtalk funcionou sem maiores problemas. Com 6 abas o consumo de memória foi de 144408k - e ainda podemos comparar com outros browsers abertos!

Sinto falta de usar '/' para fazer pesquisas na pagina (quem usa Vim entende disso) mas o Ctrl + F funciona bem. Para configurar o tamanho da fonte basta usar Ctrl + (mais) e Ctrl - (menos) para alterar o tamanho do texto, Ctrl 0 para voltar ao normal. E, a mais interessante, não há necessidade de um campo de texto para pesquisas rapidas ao google ou outro buscador: basta digitar os termos no lugar da url (bem intuitivo, aliás). O download de algum arquivo é simples e bonito também.

Bom, até então eu gostei, só aguardo a versão para Linux e quero por as mãos no tão falado codigo fonte logo-logo :)

Link para download: http://gears.google.com/chrome

Edit: o Chrome tem o mesmo problema que o Firefox tinha para gerenciar senhas: ele mostra a senha sem pudor algum:

Senhas

Poderia ter um recurso mais seguro como o da senha mestra do Firefox, parece que não pensaram (tanto) na nossa privacidade. Quem sabe no futuro isso não será corrigido?

sexta-feira, 29 de agosto de 2008

Despedida do Antonio

Esta foi a ultima semana do Antonio na globo.com. A despedida foi em grande estilo, com direito a galeria gourmet. Fica o exemplo e a saudade desse grande colega.

Em clima de festa com direito a montinho e tudo:


Fico feliz por ter surpreendido do Antonio nesses poucos meses que trabalhei com ele, agora os desafios são outros (aka Expurgo...)!

Toninho, boa sorte no Yahoo!

segunda-feira, 25 de agosto de 2008

SQL Injection - A fina arte de criar paginas realmente inseguras

Este post diz tudo:


Por mais que existam alertas sobre os perigos de SQL Injection, muita gente resolve ignorar e criar sistemas cujas consultas ao banco de dados são feitas através de concatenações de strings com os dados oriundos do usuário.

Uma das primeiras coisas que aprendi quando trabalhava como testador foi tentar este código em telas de login:

' or '1' ='1


Imagine que o impacto dessa belezinha em uma query como esta:

"SELECT USUARIO FROM TABELA WHERE USUARIO = '" + usuario + "' AND SENHA = '" + senha + "'"

temos, então:

SELECT USUARIO FROM TABELA WHERE USUARIO = 'qqCoisa' AND SENHA = '' or '1' ='1'


Consegui efetuar o login devido a extrema preguiça do desenvolvedor que nunca se interessou em estudar um pouco de segurança, muito menos sabe o que é um prepared statement. Isso no melhor dos casos, posso querer inserir um DROP TABLE da vida facilmente, pois o sistema está, literalmente, de pernas abertas.

Recentemente um colega testou esse tipo de ataque contra um site de uma instituição por curiosidade. Ele conseguiu obter um arquivo contento a senha e o IP do banco de dados e conseguiu acessa-lo, perceberam o perigo?

Sinceramente? Se eu vejo um site que cai nesse truque eu não sinto pena. Não vou zoar ou fazer algo maléfico, as vezes até tento avisar, mas não sei se vale a pena: ou o sistema custou muito barato ou custou muito caro, foi produzido por uma consultoria que lucou 1980% em cima do salario do estágiario e que, por mais documentos que tenham produzido não conseguiram fazer algo básico: um site seguro contra hackers que estudam pela Wikipedia.

Se o seu site não pode receber aspas simples, duplas ou %, tenha MUITO medo, pois alguem VAI fazer algo em breve...

segunda-feira, 11 de agosto de 2008

Closures em Java - Parte 2

Ainda sobre a Closures do java 7, agora será possivel fazer isso:

public class A {
public static void main(String args[]) {
@Shared int acumulador = 0;

{int => int } xxx = { int i => acumulador += i; i};

System.out.println(xxx.invoke(1));
System.out.println(xxx.invoke(2));
System.out.println(xxx.invoke(3));
System.out.println("o valor do acumulador eh " + acumulador );

}
}


Só eu estou achando divertido?

http://gafter.blogspot.com/2008/08/java-closures-prototype-feature.html

sexta-feira, 8 de agosto de 2008

Closures em Java

Olha o que vai ter no java 1.7

public class A {
public static void main(String args[]) {
exec( { int a, int b => a + b });
exec( { int a, int b => a * b });
exec( { int a, int b =>
System.out.println("closure " + a + ":" + b);
(a * a) + (b * b)
});
}
public static void exec({ int, int => int } closure){
System.out.println(closure.invoke(3,2));
}
}


$ java -Xbootclasspath/p:./closures-2008-08-04/lib/closures.jar   A
5
6
closure 3:2
13


Divertido :)

Fonte:
http://guj.com.br/posts/list/99477.java

Parsing de XML na linguagem ABC

A maior parte das linguagens de progração em uso pelo mundo tem pelo menos 1024 bibliotecas para trabalhar com arquivos XML. Me espanta saber que muitos querem "gravar e ler" arquivos nesse formato mas não fazem ideia do que é um XML!

Eis um bom começo:
http://www.w3schools.com/xml/default.asp

Acho que nenhuma linguagem tem mais variações sobre o mesmo tema que Java: http://guj.com.br/artigos.jsp#87031

Testable & Untestable Code

Leitura recomendada:

http://misko.hevery.com/2008/07/24/how-to-write-3v1l-untestable-code/
http://www.testingreflections.com/node/view/7221

quinta-feira, 7 de agosto de 2008

The Good, the Bad and the Ugly

Depois de ter visto algumas vezes "Era uma vez no Oeste" (com Charles Bronson tocando harmônica), finalmente pude conferir o clássico "Três Homens em Conflito" (The Good, the Bad and the Ugly) do mestre Sergio Leone.

Clint Eastwood, Eli Wallach e Lee Van Cleef estão perfeitos nessa história cheia de sangue, traições e a obcessão pela riqueza. As panorâmicas de Leone sobre o desertico velho oeste e a caracterização dos homens embrutecidos daquela época, onde a vida não valia mais do alguns dólares, são majestosas, com direito à mostrar parte da guerra civil americana.



Esqueçam aqueles filmes de indios e tiros falsos: são personagens densos, únicos, em um momento diferente da história, com momentos fantásticos (como a cena em que o "Feio" monta um revolver com as peças de outros). Sem falar no olhar mortal do "Olhos de Anjo" Lee Van Cleef, que passa uma frieza na espinha...

- "When you have to shoot, shoot. Don’t talk!"

Sem falar no maravilhoso tema de Ennio Morriconi, clássico absoluto. O estilo Western não é vazio como muitos pensam, basta saber apreciar.

Voltas às Aulas e o Java - parte 2

Existe o clássico problema de determinar se um aluno passou ou não de ano quando são informados as notas e o número de faltas.

Vejamos:
1) O número de faltas é acima do permitido?. Aqui entra um if dos bons com uma comparação numérica, quando um número é maior ou igual a outro.
2) A média é basicamente somar as X notas e dividir por X (se for média aritmética). Somar e dividir são operações matemáticas básicas.

Uma forma de fazer é:
if( numero_de_faltas > maximo_de_faltas_toleradas) {
// reprovado por faltas
} else if ( media_do_aluno < media_para_passar ){
// reprovado por nota
}
// se nem um nem outro, esta aprovado


O ruim dessa abordagem é que o aluno estar aprovado é uma condição "que sobra". Se passarmos a focar a aprovação do mesmo ficaria assim:

if( media_do_aluno >= media_para_passar && numero_de_faltas <= maximo_de_faltas_toleradas) {
// aprovado!
} else {
// reprovado!
}


É claro que eu posso que eu posso querer saber o motivo pelo qual o aluno foi reprovado:

if( media_do_aluno >= media_para_passar && numero_de_faltas <= maximo_de_faltas_toleradas) {
// aprovado!
} else if(numero_de_faltas > maximo_de_faltas_toleradas){
// reprovado pelo número de faltas: ignoro a média.
} else {
// aqui só sobra a reprovação por nota,
// basta fazer a tabela-verdade dessas expressões
}


Se o foco do professor for o algoritmo, isso é o que deveria ser analisado. Quem implementa corretamente um método que recebe X notas e um número de faltas e consegue responder a essas perguntas consegue descrever facilmente os casos de teste para verificar se a implementação corresponde ao que se espera.

Um programa que tenha algum tipo de interação (seja Swing ou console) ajuda a fazer um macarrão de código, mesclando o algoritmo com o controle de estado dos "menuzinhos". No fim vemos laços de repetição aonde não são necessários, calculo de média errado, etc.

Ok, não acho que um marinheiro de primeira viagem devesse começar por JUnit, mas uma com boa noção dos fundamentos da linguagem e evitando a interação desnecessária com o usuario (poderia ser usado até os parâmetros do main), acredito num melhor desempenho. O risco é o aluno acreditar que java é dificil ou que tudo se resume a getters/setters e gigantescos try/catch's onde as exceptions são varridas pra debaixo do tapete.

Eu colocaria TDD num segundo momento, mas ai sem perdão, ensinando o caboclo a fazer do jeito certo o quanto antes. O que é dificil se eles conseguem passar sem saber fazer aritmética básica.

quarta-feira, 6 de agosto de 2008

Algumas pessoas PRECISAM fazer programas interativos

Este código:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv){
int i;
double total =0;

for(i=1;i < argc;i++){
total = total + atof(argv[i]);
}

printf("A soma dos %d parametros eh %f\n",(argc - 1),total);

return 0;
}


É limpo, prático e scriptável. Não preciso fazer pergunta nenhuma nem tratar nada que o usuario informe: no maximo posso ver o número de parâmetros e reclamar. Basta saber como funciona o laço for e saber que argc é o número de parâmetros que eu passei para o programa e argv é um vetor de strings (que, em C puro, são vetores de chars) onde cada elemento é um parâmetro. O primeiro é sempre o nome do programa (a posição 0, que eu pulei).

$ gcc -Wall soma.c
$ ./a.out 1 2 3 4 5
A soma dos 5 parametros eh 15.000000


Eu compilo e pelo para que todos os warnings possiveis sejam mostrados. Novamente não tive nenhum problema e o código funciona bem. Nem um flush de stdin foi preciso. Se eu colocar uma palavra no meio, como abóbora, será ignorado.

Não é mais facil assim do que fazer milhões de menus? Nem precisa de system("pause") system("cls")!

Test Driven Development - parte 1.

Veja este código:

 public void testEhPar() throws Exception{
assertTrue("2 deve ser par",algoritmo.ehPar(2));
assertTrue("4 deve ser par",algoritmo.ehPar(4));
assertTrue("6 deve ser par",algoritmo.ehPar(6));

assertTrue("1 NAO deve ser par",!algoritmo.ehPar(1));
assertTrue("3 NAO deve ser par",!algoritmo.ehPar(3));
assertTrue("5 NAO deve ser par",!algoritmo.ehPar(5));
}


Dentro de uma classe de teste, usando o framework JUnit, a leitura dessas linhas é a seguinte:

Eu tenho um objeto chamado algortimo.
A chamada algoritmo.ehPar(2) deve retornar true, pois 2 é par, e este método informa se o parâmetro informado é, ou não, par.
O método assertTrue recebe dois parâmetros: uma mensagem informando o significado deste teste, e o resultado do mesmo.

Se o método estivesse com algum problema e retornasse false, isso:

assertTrue("2 deve ser par",algoritmo.ehPar(2));

seria o mesmo que

assertTrue("2 deve ser par",false);

Logo, o teste falha, pois 2 deve ser par.

Esta é uma forma programática de garantir o comportamento do código que eu desenvolvo: testando. Se o meu método só depende dos parâmetros informados, é muito simples verificar o seu funcionamento.

Desenvolvendo os testes antes de implementar o código, tendo apenas as assinaturas dos métodos (por isso recorri a uma interface aqui, lembra?), eu posso pensar nos comportamentos esperados e, então, vou desenvolvendo até que todos os testes estejam passando.

Não é nada fácil, funciona melhor quando o projeto que estás desenvolvendo está começando, porém os resultados são excelentes: veja o quanto de tempo estás economizando! Se tu pretendes determinar se um código teu está funcionando por programas que perguntam os valores, escrever

$ ant clean test


é muito mais rápido!

O problema surge quando queremos fazer algo complexo, pois a dificuldade de testar mostra problemas na arquitetura adotada, por exemplo. Quanto temos objetos que tem objetos, herança, polimorfismo, tecnicas mais avançadas podem ser usadas como usar Mocks de objetos (e prover os mecanismos para injetar estes Mocks).

No caso desse exemplo, esta é uma solução:
public boolean ehPar(int numero){
return numero % 2 == 0;
}


Muitos alunos desconhecem as operações de divisão e módulo entre inteiros. O 1, inteiro, dividido por 2, inteiro, não é 0.5, (em java), e sim 0, pois este é o resultado da divisão inteira. O resto da divisão, simbolizado por %, retorna 1. Dessa forma, o resto da divisão de um numero par por 2 é 0, caso contrario é um número inteiro. São operações básicas que precisam ser dominadas. Repare que eu fiz um código que funcione, não tentei nada mais maquiavélico que dê 0.0001 milissegundos mais rápido. Evite a otimização precoce.

Programar profissionalmente é uma tarefa de muita responsabilidade. Desenvolver testes para garantir a qualidade provê excelentes resultados a longo prazo.

Trocar de Emprego

Completando 6 meses de globo.com, refleti sobre a opção que fiz quando resolvi trocar de emprego. Vi essa semana muitas pessoas com duvidas de como ou quando fazer uma opção parecida, por isso resolvi colaborar.

A primeira coisa que devemos pensar é na nossa carreira. As vezes chegamos ao limite na empresa onde estamos, ou não há perspectivas, ou a situação está ruim, etc. São muitas as coisas que podem acontecer. Com um mercado com falta de mão-de-obra qualificada, muito profissional é assediado por empresas, prometendo as vezes salário maior, ou então surge uma oportunidade fora do estado. O que fazer?

Todas as oportunidades devem ser vistas de forma crítica. Analise o futuro, a distância, o ambiente de trabalho e, também, a remuneração. Eu sempre escolhi o trabalho à remuneração, mas trabalho que paguem abaixo do esperado eu simplesmente não considero. Escolher um emprego vendo apenas o salário engana: imagine ganhar 20% a mais em um emprego mais longe, onde vais perder mais tempo no trajeto, será que compensa? Ou então sair de um ambiente legal para uma confusão absoluta, onde domingo é dia útil de trabalho? Pois é.

Feito isso, temos que pensar em coisas práticas: todas as exigências são atendidas? Tem empresa que só se preocupa com diploma e certificações, mesmo que a sua bagagem supere todas expectativas. Se a empresa é em outra cidade ou estado, temos que analisar o custo de vida, mudança, lugar aonde morar (em grandes centros urbanos é sempre caótico, veja isso com muito cuidado).

O currículo precisa estar atualizado. Ja leu isto aqui? E isso?

Nas entrevistas seja sincero e tenha confiança: tu és um produto, tens que te vender. E, se mentir, babau, vão descobrir mais cedo ou mais tarde... Pra isso, podes estudar bastante algum assunto (eu vim lendo as apostilas da Caelum na viagem de carro que fiz de PoA ao RJ).

Por fim, planeje bem a transição: vale a pena sair com as portas abertas, caso ocorra algum problema. Seguindo estes passos é relativamente fácil optar por trocar, ou não, de emprego.

O importante é se sentir bem aonde estás trabalhando e colaborar para que o ambiente evolua, caso contrario podes ficar fazendo o mesmo trabalho, da mesma forma, por muito tempo: até que um estágiario possa ficar no seu lugar ;-)

Ps: como vai o seu inglês?

segunda-feira, 4 de agosto de 2008

Voltas às Aulas e o Java

Na época de volta às aulas nas faculdades percebe-se uma grande invasão de alunos desesperados em foruns de informática para resolverem os seus execícios. É facil reconhecer um aluno em pânico com o seu primeiro while ou algum exercício sobre Fibonacci: eles não tentam, simplesmente colam o enunciado do problema esperando a resposta pronta.

Entretanto tão bizarro quanto são os exercícios propostos: um programa que leia pergunte 2 numeros e retorne a soma, ou um programa para calcular alguma coisa que pergunte ao usuário... perai, pergunte? Um programa perguntando? Como?

Este é o típico programa 'interativo' com o usuário. Quando não usa a entrada padrão (algo completamente misterioso para boa parte dos alunos), usam algum recurso SWING. Mas sera que ninguem pensa o quão PREJUDICIAL são estes exercícios?

Normalmente o aluno se preocupa com a apresentação do mesmo, fazendo frescuras de menuzinhos, asteriscos pra lá e pra cá... e o algoritmo que é bom nada. Sinceramente: dane-se os menuzinhos. Sabem quantos programas com menuzinhos e que vão perguntar alguma coisa pro usuario vcs vão fazer na vida profissional de vcs? 0! Zero! Nenhum!

Existem muitas formas de interação com o usuario, hoje em dia vc pode ter interfaces web, por exemplo. Eu acho que, num primeiro momento, a única interação com o usuario deveria ser escrever na tela. Nada mais que isso se o camarada não sabe o que significa um NullPointerException.


Exemplo pratico:

- Prepare um diretório para trabalhar (suponho que vc vai usar linux, senão deve ser facil portar este exemplo para outros sistemas operacionais).
- Crie um diretorio lib e copie o junit-4.4.jar pra lá (use o google pra baixar esse arquivo, se vc não conseguir saia do curso de informática).
- Crie a estrutura abaixo, ainda no diretório de trabalho:
src/java
src/test
- Instale o aplicativo ant (de novo o google te ajuda, alias vc tem algum JDK instalado, certo??).
- Crie um arquivo chamado build.xml no diretorio de trabalho.
- Baixe o arquivo ant-junit.jar daqui [ http://www.java2s.com/Code/Jar/ANT/Downloadantjunitjar.htm ] e copie o .JAR para ~/.ant/lib (se não existe, crie).

Agora vem a proposta: baseado nessa interface:

public interface Algoritmo{
/* dado um numero, retorna true se for par */
boolean ehPar(int numero);
/* calcula o valor absoluto ou modulo de um numero, ex: -1 vira 1, 1 vira 1 */
int calculaModulo(int numero);
/* calcula algum termo da série de fibonacci: se 0, mostra o primeiro, se 1 mostra o segundo...*/
int calculaFibonacci(int elemento);
/* calcula o fatorial do numero indicado */
long calculaFatorial(int numero);
}


Vais criar uma classe chamada, digamos, SuaClasse que implementa esta interface (percebeu que tudo deve ficar em src/java não é?). Não pense na implementação dessa classe ainda.

No diretorio src/test vc vai salvar esta classe:

import junit.framework.TestCase;

public class AlgoritmoTeste extends TestCase{
Algoritmo algoritmo;
public void setUp(){
algoritmo = new SuaClasse();
}

public void tearDown(){
algoritmo = null;
}

public void testEhPar() throws Exception{
assertTrue("2 deve ser par",algoritmo.ehPar(2));
assertTrue("4 deve ser par",algoritmo.ehPar(4));
assertTrue("6 deve ser par",algoritmo.ehPar(6));

assertTrue("1 NAO deve ser par",!algoritmo.ehPar(1));
assertTrue("3 NAO deve ser par",!algoritmo.ehPar(3));
assertTrue("5 NAO deve ser par",!algoritmo.ehPar(5));
}

public void testCalculaModulo() throws Exception{
assertTrue("modulo de 3 deve ser 3",algoritmo.calculaModulo(3) == 3);
assertTrue("modulo de -3 deve ser 3",algoritmo.calculaModulo(-3) == 3);
assertTrue("modulo de 5 deve ser 5",algoritmo.calculaModulo(5) == 5);
assertTrue("modulo de -5 deve ser 5",algoritmo.calculaModulo(-5) == 5);
}

public void testCalculaFibonacci() throws Exception{
assertTrue("elemento 0 da serie fibonacci deve ser 0",algoritmo.calculaFibonacci(0) == 0);
assertTrue("elemento 1 da serie fibonacci deve ser 1",algoritmo.calculaFibonacci(1) == 1);
assertTrue("elemento 2 da serie fibonacci deve ser 1",algoritmo.calculaFibonacci(2) == 1);
assertTrue("elemento 3 da serie fibonacci deve ser 2",algoritmo.calculaFibonacci(3) == 2);
assertTrue("elemento 4 da serie fibonacci deve ser 3",algoritmo.calculaFibonacci(4) == 3);
assertTrue("elemento 5 da serie fibonacci deve ser 5",algoritmo.calculaFibonacci(5) == 5);
assertTrue("elemento 6 da serie fibonacci deve ser 8",algoritmo.calculaFibonacci(6) == 8);
assertTrue("elemento 7 da serie fibonacci deve ser 13",algoritmo.calculaFibonacci(7) == 13);
assertTrue("elemento 11 da serie fibonacci deve ser 89",algoritmo.calculaFibonacci(11) == 89);
assertTrue("elemento 13 da serie fibonacci deve ser 223",algoritmo.calculaFibonacci(13) == 233);
}

public void testCalculaFatorial() throws Exception{
assertTrue("Fatorial de 1 deve ser 1",algoritmo.calculaFatorial(1) == 1);
assertTrue("Fatorial de 2 deve ser 2",algoritmo.calculaFatorial(2) == 2);
assertTrue("Fatorial de 3 deve ser 6",algoritmo.calculaFatorial(3) == 6);
assertTrue("Fatorial de 4 deve ser 24",algoritmo.calculaFatorial(4) == 24);
assertTrue("Fatorial de 5 deve ser 120",algoritmo.calculaFatorial(5) == 120);
assertTrue("Fatorial de 6 deve ser 720",algoritmo.calculaFatorial(6) == 720);
assertTrue("Fatorial de 10 deve ser 3628800L",algoritmo.calculaFatorial(10) == 3628800L);
}
}


Uma ideia sobre o JUnit pode ser encontrada aqui: [ http://guj.com.br/java.tutorial.artigo.40.1.guj ], alias o guj, na sessão de tutoriais, explica varias coisas, é ótimo material de referência!

Ok, vc tem a interface que vc deve respeitar e um arquivo de teste. Vamos falar do arquivo de build do ant.

<project name="Meu Projeto" basedir="." default="dist">
<description>
Aprendendo a fazer um build.xml para o ant
</description>

<property name="lib" location="lib"/>
<property name="src" location="src/java"/>
<property name="test" location="src/test"/>

<property name="build" location="build"/>
<property name="dist" location="dist"/>

<path id="classpath.test">
<pathelement location="${test}" />
<pathelement location="${build}" />
<pathelement location="${lib}/junit-4.4.jar" />
</path>

<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>

<target name="compile" depends="init" description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>

<target name="dist" depends="compile" description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>

<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/lib/Algortimo-${DSTAMP}.jar" basedir="${build}"/>
</target>

<target name="clean" description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>

<target name="test" depends="compile">
<javac srcdir="${test}">
<classpath refid="classpath.test"/>
</javac>
<junit>
<classpath refid="classpath.test" />
<formatter type="brief" usefile="false" />
<test name="AlgoritmoTeste"/>
</junit>
</target>
</project>


A utilização desse arquivo é muito simples, não se amedronte pelo tamanho do arquivo, o formato xml do ant é bizarro e verboso, sou muito mais um Makefile, porém uma vez com ele feito basta ir adicionando coisas "com cuidado". Sem falar que tudo tem documentação oficial cheia de exemplos, só não aprende quem não quer.

$ ant
isso deve compilar a sua classe e gerar um jar (pode ser util no futuro).

$ ant clean
limpa os diretorios que vc acabou de criar com as suas paradas compiladas.

$ ant test
compila e executa os testes unítarios.

É claro que vc vai dizer, e agora??? Bom, veja isso:

public class SuaClasse implements Algoritmo{
public boolean ehPar(int numero){return false;}
public int calculaModulo(int numero){ return -1;}
public int calculaFibonacci(int elemento){return -1;}
public long calculaFatorial(int numero){return -1;}
}


Olha que legal! Uma classe que tem o minimo pra compilar! Agora vamos testar...

$ ant test
Buildfile: build.xml

init:
[mkdir] Created dir: /home/GLOBO.COM/peczenyj/test/junit/build

compile:
[javac] Compiling 2 source files to /home/GLOBO.COM/peczenyj/test/junit/build

test:
[javac] Compiling 1 source file
[junit] Testsuite: AlgoritmoTeste
[junit] Tests run: 4, Failures: 4, Errors: 0, Time elapsed: 0.005 sec
[junit]
[junit] Testcase: testEhPar(AlgoritmoTeste): FAILED
[junit] 2 deve ser par
[junit] junit.framework.AssertionFailedError: 2 deve ser par
[junit] at AlgoritmoTeste.testEhPar(Unknown Source)
[junit]
[junit]
[junit] Testcase: testCalculaModulo(AlgoritmoTeste): FAILED
[junit] modulo de 3 deve ser 3
[junit] junit.framework.AssertionFailedError: modulo de 3 deve ser 3
[junit] at AlgoritmoTeste.testCalculaModulo(Unknown Source)
[junit]
[junit]
[junit] Testcase: testCalculaFibonacci(AlgoritmoTeste): FAILED
[junit] elemento 0 da serie fibonacci deve ser 0
[junit] junit.framework.AssertionFailedError: elemento 0 da serie fibonacci deve ser 0
[junit] at AlgoritmoTeste.testCalculaFibonacci(Unknown Source)
[junit]
[junit]
[junit] Testcase: testCalculaFatorial(AlgoritmoTeste): FAILED
[junit] Fatorial de 1 deve ser 1
[junit] junit.framework.AssertionFailedError: Fatorial de 1 deve ser 1
[junit] at AlgoritmoTeste.testCalculaFatorial(Unknown Source)
[junit]
[junit]
[junit] Test AlgoritmoTeste FAILED

BUILD SUCCESSFUL
Total time: 1 second


Agora basta escrever codigo de verdade na SuaClasse e testar, estara pronto quando TUDO estiver passando. São 4 métodos básicos, sabendo lidar com variaveis locais, if e for, vc consegue muita coisa.

Se eu fosse professor eu daria exercícios assim: o projeto deveria compilar e todos os testes deveriam passar senão o aluno leva 0. A nota viria de acordo com o que eu espero, posso usar um EMMA e ver a cobertura de código, posso avaliar a presença de um Javadoc que preste, etc.

Enfim, eu seria um professor muito malvado }-)

Não perca a parte 2 aqui, e uma introdução ao TDD aqui.

terça-feira, 8 de julho de 2008

Tor: Um sistema anónimo de comunicação na Internet

Pelo veto ao projeto de cibercrimes - Em defesa da liberdade e do progresso do conhecimento na Internet Brasileira

http://www.petitiononline.com/veto2008/

Se esta lei for aprovada, podemos fazer uso do Tor para navegar tranquilamente.

Tor é um conjunto de ferramentas para um amplo grupo de organizações e particulares que desejam aumentar a sua segurança na Internet. Usar Tor pode ajudar a tornar anónima a navegação e publicação na Web, instant messaging, IRC, SSH, e outras aplicações que usem o protocolo TCP. Tor também disponibiliza uma plataforma para os programadores de software, criarem novas aplicações com funções de anonimato, segurança e privacidade já incorporadas.

Tor pretende defender contra a análise de tráfego, uma forma de vigilância que ameaça o anonimato pessoal e a privacidade, a confidencialidade dos negócios e relacionamentos, e a segurança de estados. As comunicações são enviadas através de uma rede distribuída de servidores chamados onion routers, protegendo-nos de sites Web que constroem perfis com os nossos interesses, pequenos espiões que lêem os nossos dados ou registam que sites visitámos.

A segurança do Tor aumenta à medida que a sua base de utilizadores aumenta e mais pessoas se oferecem para alojar servidores. Por favor considere oferecer o seu tempo ou oferecer a sua largura de banda. Convém lembrar que estamos a lidar com código em desenvolvimento — Não deve usar o Tor se precisa realmente de fortes garantias de anonimato.

Fonte: http://www.torproject.org/index.html.pt

quinta-feira, 3 de julho de 2008

Sudo

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...


Regulamentar a profissão dos outros é refresco

Na onda da campanha contra a regulamentação das profissões da área de informática

Eu, que trabalho como Analista de Sistemas e tenho Bacharelado em Física incompleto, tenho uma grande inveja do Phillip Calçado, que trabalha na Austrália, e postou recentemente sobre essa “lei”.

http://blog.fragmental.com.br/2008/03/21/ainda-bem-que-estou-aqui/

Cito a opinião da Sociedade Brasileira de Computação

1. Exercício da profissão de Informática deve ser livre e independer de diploma ou comprovação de educação formal.
2. Nenhum conselho de profissão pode criar qualquer impedimento ou restrição ao princípio acima.
3. A área deve ser Auto-Regulada.


Parece que os politicos querem saber mais de informática do que quem é da área (se bobear ninguem sabe o que é a ACM, devem achar que é um politico a pouco falecido). Fico com pena de algumas pessoas egoístas que pensam “tenho diploma, logo essa lei me favorece”. A nação brasileira frperde como um todo, retrocendendo décadas numa das atitudes mais lastimáveis de todos os tempos.

Parafraseando o Rodrigo Kumpera:

Para ser programador vamos precisar ter diploma, enquanto isso para fazer política basta assinar o nome. Regulamentar a profissão dos outros é refresco.


Segue a thread: http://br-linux.org/2008/campanha-contra-o-projeto-de-lei-6072007-de-regulamentacao-das-profissoes-da-area-de-informatica/

Código transparente, contas fechadas ?

Engraçado como começamos a falar em “Transparência de Contas” e aparece gente dizendo q queremos acabar com o FISL. Parece que a ideia é “Aceite o FISL como ele É ou tu és contra o software livre no Brasil (e provavelmente usa Windows em casa)”.

Mesmo que o FISL acabasse (o que não vai acontecer, e ninguem quer) existem dezenas de eventos acontecendo pelo Brasil afora (alguns com palestrantes internacionais até). O FLISOL aconteceu em diversas cidades simultaneamente, por exemplo. Esses eventos só tendem a crescer e se profissionalizar, criando todo um ecossistema de divulgação de conhecimento técnico.

“Código transparente, contas fechadas” é um lema perigoso que pode acabar com a reputação da comunidade de software livre brasileira.

sábado, 26 de abril de 2008

Manipulando logs com AWK e SED

Eis que a lista de shell script traz um bom desafio.

Galera, tenho o seguinte log.:

AAAA-------------campo_1-------------campo_2-----campo_3----campo_4----------
teste_1 371508787 371547453 38666 testetesteteste

BBBB-------------campo_1-------------campo_2-----campo_3----campo_4----------
teste_2 4625081503 4651313710 26232207 testetesteteste

Estou a tentar usar o awk com a seguinte função :
awk '$1~"teste_" {print $5";"$4}' teste > teste_.csv

a funcao busca realmente o que desejo:
$5 $4
testetesteteste 38666
testetesteteste 6232207

porem,, gostaria que seprasse da forma:

AAAA-------------
testetesteteste 38666
BBBB-------------
testetesteteste 26232207

Alguém tem uma dica de como fazer?


Ah... o bom e velho SED pode resolver isso

$ sed -rn '/(^[^-]+-+).*/{s//\1/;h};
/^teste_/{s/.* ([^ ]+) +([^ ]+$)/\2 \1/;x;p;g;p}' arquivo.log
AAAA-------------
testetesteteste 38666
BBBB-------------
testetesteteste 26232207


Ok, ok, ta muito complicado, mas veja só:

$ sed -rn '/^[^-]+-+/h;/^teste_/{x;p;g;p}' arquivo.log
AAAA-------------campo_1-------------campo_2-----campo_3----campo_4----------
teste_1 371508787 371547453 38666 testetesteteste
BBBB-------------campo_1-------------campo_2-----campo_3----campo_4----------
teste_2 4625081503 4651313710 26232207 testetesteteste


Vamos explicar
1) a opção -n serve para informar ao sed "imprima apenas quando eu mandar"
2) a opção -p serve para utilizar expressões regulares extendidas
(assim não preciso escapar o quantificador + , que significa "um ou
mais vezes", assim como os parentesis, para informar os grupos).

Eu fiz uma sacanagem. o comando h quarda o padrão num espaço chamado espaço reserva, tipo uma memória do sed, sobreescrevendo. Assim no espaço reserva eu tenho a ultima ocorrencia de uma linha do tipo, ^[^-]+-+ ,que traduzindo significa: tudo o que começa com um ou varios caracteres diferentes de -, seguidos de um ou varios - (no caso
do AAAA------------- ... ).

Agora, quando eu encontro uma linha que começa com teste_ eu:

x) troco essa linha com a linha que esta na memória (a atual
'teste_...' vai, outra volta).
p) imprimo a linha que veio (AAAA---------- ...)
g) pego a linha da memória (teste_...)
p) imprimo a linha cachorrona

Só que não fica como vc quer. Ai vc precisa fazer a sacanagem:

se uma linha NÃO tem o que eu quero, então eu a manipulo habilmente
até que ela chegue ao que eu quero


Eu poderia ter usado varias tecnicas mas... uma vez com sed, podemos continuar nele.

$ sed -rn '/(^[^-]+-+).*/{s//\1/;h};
/^teste_/{s/.* ([^ ]+) +([^ ]+$)/\2 \1/;x;p;g;p}' arquivo.log


eu transformei a primera ER em (minha_ER).* -- ou seja, criei um grupo para o que me interessa. basta fazer:

s/(minha_ER).*/\1/

para que toda a linha seja reduzida ao que a minha ER casa. em outras palavras, eu apaguei o resto da linha.

na outra eu fui mais sacana pois eu tenho 2 grupos e troco toda a linha pelos grupos, na ordem inversa. coisa de quem toma muito café e não tem escrupulos.

Vamos ver a versão AWK?

$ awk '/^[^-]+-+/{match($0,/^[^-]+-+/); x=substr($0,1,RLENGTH)}
/^teste_/{print x,"\n"$5,$4}' arquivo.log
AAAA-------------
testetesteteste 38666
BBBB-------------
testetesteteste 26232207


x, nesse caso, armazena aquele pedaço da linha anterior, que eu descobri o que é via match. match procura uma expressão regular numa string, nesse caso em $0, e seta um valor na variavel RLENGTH, que é onde a expressão acaba. basta pegar essa parte da string e guardar na variavel x, que sera lida depois.

Aqui fala um pouco dessas duas funções: http://people.cs.uu.nl/piet/docs/nawk/nawk_92.html

Eu poderia ter resolvido dessa forma também
$ awk '/^[^-]+-+/{sub(/-[^-]+.*$/,"-");x=$0}
/^teste_/{print x,"\n"$5,$4}' arquivo.log
AAAA-------------
testetesteteste 38666
BBBB-------------
testetesteteste 26232207


Entretanto aqui eu faço uma substituição grosseira do resto da linha que tem o AAAA------... por -, abusando do .* (e o fato dele ser guloso). Parece mais simples, mas está sujeito à falhas, embora não consigo pensar em nenhuma situação que seja possivem demonstrar.

AWK & SED são ferramentas sensacionais para esse tipo de problema ;-)

sexta-feira, 25 de abril de 2008

Sbado dia 26 de Abril tem FLISOL na PUC-Rio !!



Em 26 de abril, será realizado o FLISOL - Festival Latinoamericano de Instalação de Software Livre - evento de divulgação de Software Livre da América Latina. No Rio de Janeiro quem está organizando este evento é o SL-RJ. Segundo o coordenador Carlos Ferreira, “É uma ótima oportunidade para levar seus amigos para passar este dia tão importante, participando das palestras ou instalando legalmente seu computador”. O Local onde será realizado, é a PUC-Rio - Pontifícia Universidade Católica do Rio de Janeiro - Auditório do RDC, localizado na Rua Marquês de São Vicente, 225, Gávea - Rio de Janeiro, RJ - Brasil - 22453-900. Das 8:30 às 17:00.


Veja mais informações aqui:
http://installfest.info/FLISOL2008/Brasil/RioDeJaneiro

Software disponível

* Linux: Ubuntu
* Openoffice e Firefox.
* Para quem desejar, existe a opção de receber um cd da distribuição Linux Ubuntu versão 7.10, para isto basta levar um cd virgem.

Palestras

Veja aqui a grade de palestras completa.

Iremos disponibilizar uma máquina e uma pessoa para ficar durante todo o evento à disposição das pessoas interessadas em conhecer um determinado programa ou recurso, tirar dúvidas e/ou obter dicas.

Como ajudar?

Você pode ajudar o evento de diversas maneiras. A mais simples é divulgando-o para os seus amigos, na sua escola ou no seu trabalho.

Se você quiser, pode ser um instalador ou palestrante no InstallFest. Envie um e-mail para Carlos Ferreira ou Luiz Aldabalde falando um pouco sobre a sua experiência com GNU/Linux ou qualquer outra aplicação livre que seja instalada durante o evento.

Caso queira ajudar de qualquer outra forma, entre em contato conosco por e-mail. Toda a ajuda é bem vinda!

O que devo fazer para me preparar para o Install Fest?

ATENÇÂO: Maquinas do tipo Desktop(com gabinete) só poderão entrar no Campus da PUC-Rio até as 12:00 horas, após este horário somente laptops dentro de mochilas.

Checagem de Hardware: No Windows, vá até o Painel de Controle e escolha Sistema. Liste:

* Placa de rede (marca, modelo, configuração)
* Placa de vídeo (marca, modelo, configuração)
* Placa de Som (marca, modelo, configuração)
* CPU (Processador)
* Memória RAM
* Modem (marca, modelo, configuração)
* Espaço livre em disco (mínimo de 5.0 Gb)
* Componentes SCSI (se houver algum)

* Faça backup dos seus dados. Por precaução, você deve fazer uma cópia dos seus dados importantes no computador do seu amigo ou em CD-ROM.

* Particionamento do disco: se você souber como fazer, faça uma partição de no mínimo 5.0 Gb. Quanto maior for essa partição, mais utilidades do Linux poderão ser instaladas. Se você não souber fazer isso, nós faremos no dia do Install Fest. Apenas irá demorar mais tempo.

* Desfragmento do disco: Se você não souber fazer o particionamento, desfragmente o seu disco. Se você não souber fazer isso, ou não quiser, nós o faremos no dia do Install Fest. Apenas a sua instalação demorará mais que se você o tivesse feito antecipadamente. Para desfragmentar no Windows, primeiro desabilite todos os programas. Isso incluirá ICQ, navegadores, anti-vírus ou qualquer outra coisa que você estiver rodando. A seguir, clique em Iniciar, Programas, Acessórios, Desfragmentador de Disco. A seguir, clique em Iniciar na janela que aparecer nesse instante.

* Os custos de transporte do seu PC são de sua responsabilidade.

* Trazer para o Install Fest o Gabinete,Teclado, mouse e ainda, cabos de comunicação CPU-Periférico e cabos de força. Enfim, tudo o que é necessário para fazer seu computador funcionar. Se possível, traga também os manuais do seu hardware.

Apoio

CASA DO MOODLE http://www.casadomoodle.com

Responsáveis

Coordenador:
o Carlos Henrique Lucas Ferreira

Colaboradores:
o Luiz Guilherme Aldabalde
o Avalci Suzano
o Carlos Eduardo(Cadunico)
o Luis Felipe Costa
o Bruno Garcia
o Josir Gomes

domingo, 20 de abril de 2008

Sobre o FISL e tudo mais

Rapidamente, foi ótimo reencontrar os amigos de Porto Alegre. Os ultimos dias do FISL me cansaram demais, porém foi ótimo conversar pessoalmente com o Aurélio (alias o livro dele é ANIMAL! vale a pena adquirir!), rever o Julio Neves, a galera do Tchelinux, sem falar na galera que eu conheci no evento (que eu insistia em trocar o nome, procedência, etc). Um abraço especial pro Marcelo Martins, que deve estar em Torres agora.

Destaque para a palestra do Guilherme Chapiewski.

Devo me preparar melhor para os próximos eventos, tanto em Poa ano que vem quanto os próximos eventos (como o FLISOL dia 26 de Abril na PUC-RJ, sem falar no Hack'n Rio). To doido pra ir no Javauy 2008 mas acho que não vai rolar :( Estou cheio de ideias!

Peço desculpas a todos que não conseguiram me encontrar ou que não pude conversar direito! Forte Abraço!

domingo, 13 de abril de 2008

Um corretor ortográfico em gawk

Ano passado eu publiquei uma pequena nota sobre um pequeno corretor ortográfico feito em Python.

No artigo do Peter Norwig, ele explica o principio estatístico do algoritmo. No final, ele mostra varias implementações do algoritmo (em D, Java, Ruby e até Erlang).

Depois de muito pesquisar, decidi fazer uma versão em gawk. A primeira tinha 30 linhas e não funcionava muito bem, arrumando e testando cheguei a esta forma final com apenas 15 linhas.

Eu chamo de linha um statement completo do awk. Perceba que nenhuma linha dessas possui o separador de statement ; (ponto-e-virgula), exceto quando estou utilizando o for no estilo C.

# Usage: gawk -v word=something -f thisfile.awk [ big.txt [ big2.txt ... ]]
# Gawk version with 15 lines -- 04/13/2008
# Author: tiago (dot) peczenyj (at) gmail (dot) com
# Based on : http://norvig.com/spell-correct.html
function edits(w,max,candidates,list, i,j){
for(i=0;i< max ;++i) ++list[substr(w,0,i) substr(w,i+2)]
for(i=0;i< max-1;++i) ++list[substr(w,0,i) substr(w,i+2,1) substr(w,i+1,1) substr(w,i+3)]
for(i=0;i< max ;++i) for(j in alpha) ++list[substr(w,0,i) alpha[j] substr(w,i+2)]
for(i=0;i<= max ;++i) for(j in alpha) ++list[substr(w,0,i) alpha[j] substr(w,i+1)]
for(i in list) if(i in NWORDS) candidates[i] = NWORDS[i] }

function correct(word ,candidates,i,list,max,temp){
edits(word,length(word),candidates,list)
if (!asort(candidates,temp)) for(i in list) edits(i,length(i),candidates)
return (max = asorti(candidates)) ? candidates[max] : word }

BEGIN{ if (ARGC == 1) ARGV[ARGC++] = "big.txt" # http://norvig.com/big.txt
while(++i<=length(x="abcdefghijklmnopqrstuvwxyz")) alpha[i]=substr(x,i,1)
IGNORECASE=RS="[^"x"]+" }

{ ++NWORDS[tolower($1)] }

END{ print (word in NWORDS) ? word : "correct("word")=> " correct(tolower(word)) }


Veja o script em funcionamento:
$ time gawk -v word=somethink -f spelling.awk
correct(somethink)=> something

real 0m4.862s
user 0m4.702s
sys 0m0.093s

sábado, 5 de abril de 2008

Participe do Domingão do Faustão

Vou fazer uma propaganda descarada: o Domingão do Faustão lançou o quadro Dança da Galera!

Para participar, basta seguir as instruções aqui e enviar o seu vídeo!

2008 promete muitas novidades! Aguardem!

sexta-feira, 4 de abril de 2008

Venha Tomar um Chimarrão no Estande da Globo.com!

Acompanhando o post do Guilherme, dia 18 eu devo aparecer por Porto Alegre, para o FISL.

Venha Tomar um Chimarrão no Estande da Globo.com durante o FISL!

quarta-feira, 2 de abril de 2008

Programando em C para console - parte 1

(Depois de um fecundo primeiro de Abril... )

Cada vez mais eu me espanto com a quantidade de novatos que tentam fazer programas para o "modo console" que não fazem o menor sentido.

Programas com menuzinho (1 - saque , 2 - deposito, 3 - sair) ou do estilo "digite um numero (q para sair)" são totalmente contra-produtivos. O novato perde TEMPO fazendo um monte de código desnecessário quando esquece o que deveria fazer (o tal do algoritmo).

Veja um exemplo: um programa que receba uma quantidade variavel de números e que imprima a soma dos mesmos. IMHO a forma mais interessante para fazer isso é pegar os números como argumentos do programa principal. Vc cria um programa console absolutamente limpo e facil de scriptar, por exemplo.

Veja só:

#include <stdio.h>

int main(int argc, char *argv[]){
double soma = 0.0;

printf("A soma dos numeros eh %g\n",soma);

return 0;
}


Feito esse simples arquivo, vamos compilar
$ gcc -Wall soma.c
$ ./a.out 1 2 3 4 5
A soma dos numeros eh 0


Ai vc fala "po, ta errado!", mas claro, eu primeiro escrevi a base do meu programa. Perceba que eu compilei com a opção -Wall, que me informa todos os warnings que a compilação pode gerar (o que sempre é uma excelente pratica, eu procuro compilar sempre com 0 warnings).

Feito isso, vamos definir 2 coisas:
- O algoritmo da soma e
- Possiveis fluxos de excessão.

Vou partir do suposto que, se vc digitar alguma coisa que não seja um numero, eu vou ignorar e considerar como 0. Caso eu não informe nenhum numero ao programa, isso significa que estou faltando com alguma coisa, nesse caso vou informar uma mensagem elucidativa sobre o uso do programa.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
int i;
double soma = 0.0;

if(argc == 1){
fprintf(stderr,"Faltando Argumentos!\n");
fprintf(stderr,"Uso: %s x1 [ x2 .. xN ]\n",argv[0]);
return 1;
}

for(i=1;i<argc;i++)
soma += atof(argv[i]);

printf("A soma dos numeros eh %g\n",soma);

return 0;
}


Todos os argumentos que eu passo para o programa, incluindo o nome do mesmo, ficam no vetor argv, e o número de argumentos fica na variavel arcc. Dessa forma, o nome do programa é o argv[0] e, se eu não passar nenhum argumento adicional, argc será 1. A função atof converte a string para um número de ponto flutuante e retorna 0 se não for possivel converter.

Simples, não? Agora vamos executar:

$ ./a.out          
Faltando Argumentos!
Uso: ./a.out x1 [ x2 .. xN ]
$ echo $?
1
$ ./a.out 1 2 3 4 5
A soma dos numeros eh 15
$ echo $?
0


A mensagem de uso utiliza uma notação no manual de alguns programas do mundo unix: colocar os argumentos opcionais entre colchetes. Eu informo que preciso de pelo menos um argumento. Caso eu entre no fluxo de excessão, o meu main retorna um valor diferente de 0 para o sistema operacional que pode ser capturado pela variavel de ambiente $? (nesse caso estou em um linux utilizando o bash, em outros sistemas mais exotéricos como o Windows eu não imagino como vc poderia capturar essa informação, tampouco imagino se ela seria util).

Perceba que eu posso criar um script extremamente simples para utilizar esse programa, assim como testar o resultado é uma tarefa de um grep (ou diff). Eu poderia juntar um script de teste e um makefile nesse post mas estou esperando um exemplo um pouco mais interessante.

Eu criei um programa sucinto, facil de entender e muito util, sem ter que perguntar para o usuario nada. transformar esse programa num que calcula a média, por exemplo, é uma tarefa de colocar apenas uma linha (na verdade uma subtração e uma divisão) a mais. Espero que os programadores novatos se inspirem nessa forma de pensar e que utilizem os programas básicos do unix como o grep, cat, diff, cp, etc, para seus futuros trabalhos.

terça-feira, 1 de abril de 2008

Java 1.7 vai ter Ponteiros!!!

Sensacional.

Um dos recursos mais uteis do C finalmente conquistou o mundo java: a notação de ponteiros do Kernighan & Ritchie.

public class Example{
public static void main(String [] args){
int *x, y=0;
x = &y;
System.out.println("O valor de x eh " + *x);
}
}


Agora será possivel fazer, em java:

- Passar primitivos por referência.
- Usar malloc, realloc e free.
- Utilizar ponteiros void para converter uma URL em String, ou um Throwable em um List.
- Sem falar que as Strings terão um caracter a mais no fim: o famoso \0 (na verdade a classe String deve desaparecer no Java 1.8, sendo substituida pelo bom e velho array de char)

Parabéns Sun!

WhiteSpace Server Pages

E... para completar o dia:

<?WhiteSpace
Say hello.













































































































?>

Novas Tecnologias .Net

A Microsoft resolveu contra-atacar a proposta da SUN com o FSP que, de uma tacada só, 6 novas linguagens no mundo dot NET: vejam exemplos dos novissimos ABAP .Net, ASM .Net, BrainFuck .Net, JCL .Net e VHDL .Net.

Para a parte web, vc poderá utilizar qualquer uma destas linguagens. Todas serão compiladas para CLI pelo ISS. A nova tecnologia permite, inclusive, rodar um .BAT, veja os exemplos abaixo!

<?ABAP
REPORT ZHB00001.
WRITE: 'Hello world'.
?>


<?ASM
SECTION .data

msg db "Hello, world!",0xa ;
len equ $ - msg

SECTION .text
global main

main:
mov eax,4
mov ebx,1
mov ecx,msg
mov edx,len
int 0x80

mov eax,1
mov ebx,0
int 0x80
?>


<?BRAINFUCK
++++++++++[>+++++++>++++++++++>+++<<<-]>++.>+.+++++++
..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.
?>


<?MSDOS
@ECHO OFF
REM Hello World for DOS batch

ECHO Hello World!
?>


<?JCL
//HERIB JOB ,'HERIBERT OTTEN',PRTY=12
//* Hello World for MVS
//HALLO EXEC PGM=IEBGENER
//SYSPRINT DD SYSOUT=*
//SYSUT2 DD SYSOUT=T
//SYSUT1 DD *
Hello World!
/*
//
?>


<?VHDL
ENTITY helloworld IS
END helloworld;

ARCHITECTURE hw OF helloworld IS

BEGIN

ASSERT FALSE
REPORT "HELLO, WORLD!"
SEVERITY NOTE;

END hw;
?>


Essa microsoft...

FSP - Fortran Server Pages!

Sensacional.

A SUN está ressucitando uma das mais velozes linguagens de todos os tempos. Uma nova tecnologia web foi anunciada hoje: Fortran Server Pages!


<?FORTRAN
*
C Hello World in Fortran 77
C (lines must be 6 characters indented)
*
PROGRAM HELLOW
WRITE(UNIT=*, FMT=*) 'Hello World'
END
?>


A ideia é atingir um novo patamar em sistemas web.

Fonte: Google

sexta-feira, 28 de março de 2008

Hackeando um Hello World com sed

Fantástico o que o sed pode fazer!

$ cat a.c
main(){
puts("hello world");
}
$ gcc a.c
$ ./a.out
hello world
$ sed -i 's/hello world/_ola mundo_/'./a.out
$ ./a.out
_ola mundo_

quarta-feira, 12 de março de 2008

A internacionalização do Engodo (2)

Excelente artigo do Olavo de Carvalho:

A internacionalização do Engodo (2)

segunda-feira, 10 de março de 2008

sexta-feira, 7 de março de 2008

Projeto reconhece profissões de TI

Projeto reconhece profissões de TI, mas exclui criação de conselhos

Fonte: TI Inside

A Comissão de Ciência, Tecnologia, Inovação, Comunicação e Informática (CCT) do Senado aprovou, nesta quarta-feira (5/3), parecer favorável do senador Eduardo Azeredo (PSDB-MG) ao projeto de lei que regulamenta o exercício das profissões de analista de sistemas e técnico de informática. A proposta é de autoria do senador Expedito Júnior (PR-RO) e agora será encaminhada à Comissão de Assuntos Sociais (CAS), na qual receberá decisão terminativa.
(...)
De acordo com a proposta, a profissão de analista de sistemas somente poderá ser exercida por pessoas que possuam diploma de nível superior em análise de sistemas, ciência da computação ou processamento de dados.


Sem comentários...

quinta-feira, 6 de março de 2008

Sobre o "ensino" de Java hoje em dia.

Java é uma linguagem orientada a objetos que contem tipos primitivos e wrappers para estes tipos, é executada sobre uma maquina virtual, com suporte a herança simples mas possui interfaces, com mecanismos de sobreescrita e sobrecarga de métodos, com um sistema de tratamento de exceções que te obriga a tratar determinadas situações e por ai vai.

Ao meu ver o estudo da linguagem deveria focar o domínio do mecanismo de herança e a construção de classes, domínio dos métodos, tipos de retorno, escopos de variavel, conversão de tipos, domínio das estruturas condicionais, de loops e de tratamento de erros, domínio das operações matemáticas e lógicas e,principalmente, domínio da classe String (ok, domínio pode ser uma palavra forte, talvez uma boa noção fosse suficiente em algumas situações).

Com disso tudo, o aluno deveria primeiro trabalhar com argumentos de linha de comando (o que vc acha que o main recebe?), depois passar a estudar a leitura e escrita em arquivo texto e, por fim, leitura pela entrada padrão.

Pois leitura pela entrada padrão é o que vc menos vai fazer em Java. Ninguem faz programa com menuzinho em Java pra console no mercado. Temos coisas mais complexas pela frente e sem conhecer tudo aquilo que eu listei antes só é possivel fazer gambiarras (como as famosas class functions, gigantescos métodos que fazem centenas de coisas com nomes adequados do tipo createTree3).

Ensina-se Java ao contrário: primeiro o camarada programa como se fosse C, perdendo tempo em fazer menus e estruturas de controle pois o usuario pode ter dado um enter, tab, "ç" ou ter digitado algo inválido quando deveria aprender os fundamentos da linguagem. Cria-se vícios que pode ser custoso para remover (como encher o código de getters/setters sem necessidade). A prova disso é que invariavelmente temos comparação de Strings usando o operador == quando deveria ser utilizado os métodos adequados para isso (imagina o susto quando a galera descobre o equalsIgnoreCase).

Eu vejo muitos estudantes incapazes de compilar e executar uma classe (o famoso hello world) pois os mesmos nunca fizeram uso da linha de comando muito menos foram apresentados ao conceito de classpath. Vejo barbaridades típicas de quem não conhece (ou não sabe ler) o javadoc das classes básicas. Fico me perguntando quando esses jovens serão capazes de ler um "Effective Java", por exemplo.

Aqui tem um excelente começo.

Espero que os professores acordem para essa realidade e que os alunos percebam que estão sendo prejudicados e passem a estudar por sua conta os tópicos necessários para sair arrasando pro ai.

quarta-feira, 5 de março de 2008

Melhorando o “try()” do Ruby, a maneira “Groovy” [parte final]

class Omega
def a
self
end
def b
self
end
def c
self
end
def to_s
"Omega"
end
end

def da?
begin
yield() if block_given?
rescue => exc
nil
end
end

xyz = nil
a = da? { xyz.a.b.c }

xyz = Omega.new
b = da? { xyz.a.b.c }

puts "da? com nil -> '#{a}'"
puts "da? com Omega -> '#{b}'"


Executando:
da? com nil -> ''
da? com Omega -> 'Omega'


O que eu fiz? como a expressão xyz.a.b.c poderia retornar algum erro pois um dos métodos poderia returnar nil, bastaria executar em um bloco de código com a ajuda do método da? (péssimo nome, uma corruptela de "da para executar sem erro? se não, me retorna nil e era wilson...), que captura qualquer erro e some com ele.

Ruby é divertido. :)

ps: teste com

a = da? { xyz.a.b.c } || "nao deu..."

Melhorando o “try()” do Ruby, a maneira “Groovy” [parte 2]

Vou pedir perdão ao meu amigo Urubatan, que publicou um artigo de mesmo nome.

class Omega
def doIt
puts "ola"
self
end
end

class NullableClass
def method_missing(*x)
self
end
end

class Object
def existe?
self
end
end

class NilClass
def existe?
NullableClass.new
end
end

xyz = Omega.new
xyz . existe? . doIt . doIt

abc = nil
abc . existe? . doIt . doIt


Estou em duvida sobre o nome do metodo, por enquando fica existe? mesmo.

O que isso faz? Imagine que vc tem uma variavel ou atributo de classe que pode ser nil. Se for nil ela vai lançar um um erro em tempo de execução quando vc for tentar chamar algum método que a NilClass não possua (o que geralmente acontece, é semelhante ao NullPointerException do java).

Eu poderia resolver isso alterando o method_missing da NilClass, porém alguns scripts podem estar esperando erros desse tipo. Decidi então criar um método que, para qualquer objeto, retorna ele mesmo (self). Caso seja nil, ele vai retornar um NullableClass (outro nome infeliz, não tenho nenhuma ideia melhor) que simplesmente retorna ele para qq método requisitado.

IMHO pode ser o suficiente quando queremos fazer um teste simples: o objeto é nil? então não faz nada.

Se alguem achar isso util por favor me avise :)

Ah sim, a execução do script acima resulta em:
ola
ola

quarta-feira, 27 de fevereiro de 2008

Escher em Lego

Sensacional:

sexta-feira, 22 de fevereiro de 2008

Alterando Multiplos Arquivos (versão final?)

O site Dicas-L trouxe na ultima semana 2 formas de renomear multiplos arquivos (aqui e aqui)

#Forma 1
for o in $(ls -1 *.txt); do
mv $o $(echo $o | awk -F. '{print $1".htm"}');
done


#Forma 2
for i in `ls *.txt`; do
mv $i $(echo `basename $i .txt`.html)
done


São ambas formas interessantes, porém ao meu ver consomem muito recursos da maquina, sem falar que são um tanto... feios... (nada contra - o que importa é que funcione)

Vou utiliza-los como exemplo de como podemos tornar algo melhor e mais prático (se o tempo permitir).

Vamos dividir as paradas:

altera() { mv $1 $(echo `basename $1 .txt`.html) ; }

for i in `ls *.txt`; do
altera $i
done


Agora vamos tomar um cuidado: arquivos com espaço no nome

altera() { mv "$1" $(echo `basename "$1" .txt`.html) ; }

for i in `ls *.txt`; do
altera "${i}"
done


Bom, o for pode iterar sobre uma lista de argumentos. As mascaras de nome de arquivo são expandidos pelo shell durante a execução, logo...

for i in *.txt ; do
altera "${i}"
done


Agora, a rotina de alteração do nome do arquivo de destino é complicadissima, depende de um ou mais sub-processos. Isso poderia ser...

altera() { mv "$1" "${1%.txt}.html" ; }


Que, inserido no for...

for i in *.txt ; do
mv "${i}" "${i%.txt}.html"
done


Interessante, certo? Nenhum sub-processo, exceto o inumeros mv que serão executados. Existem outras formas de fazer a mesma coisa

ls *.txt | awk -F. -v OFS=. '{ O=$0; $NF="html" ;printf "\"%s\" \"%s\"\n",O,$0 }' | xargs -n 2 mv

ls *.txt | sed 's#^\(.\+\)\.[^.]\+$#"&" "\1.html"#g' | xargs -n 2 mv


(rodem as linhas acima sem o mv do xargs para entende-las -- é metaprogramação)

Agora... tudo isso é muito bonito mas... veja se o seu computador possui os comandos mmv ou rename (que facilitam Absurdamente a tarefa)

rename .txt .html *.txt

mmv "*.txt" "#1.html"


Simples, não?

Tudo depende do tempo que temos e das nossas necessidades. Mesmo que o rename/mmv sejam uteis, pode ser que a forma com awk / sed valha mais a pena pois o ls pode ser substituido por um find (ja pensou nisso?)

sábado, 2 de fevereiro de 2008

Building Didier Stevens' SpiderMonkey in Cygwin

Eu estava quebrando a cabeça até que encontrei este post.

O Paul Melson ensinou de forma facil a compilar o SpiderMonkey para Cygwin: agora posso criar scripts usando javascript standalone.

Vantagem: Nenhuma, coisa de nerd :)

quarta-feira, 30 de janeiro de 2008

Twitter.sh versão 2.0

O Bruno me deu uma ótima sugestão: um simples usage.

Entretanto ontem eu fiquei batendo cabeça com os inúmeros tac/tail's mas percebi q um sed resolvia a questão. Alias é possivel também passar uma lista de parâmetros também!

#!/bin/bash
TWIURL=http://m.twitter.com # utilizando versão 'mobile' do twitter
USAGEMSG="Usage: $(basename $0) <twitter-user> [user list...]"

[ -z "$1" ] && { echo "${USAGEMSG}" ; exit 1 ; }
for i in "$@" ; do
echo "==============================="
links -dump "${TWIURL}/${i}" | sed -r '1,3d;/^\ +Older [0-9]+/,$d'
done

Agora chega :)

terça-feira, 29 de janeiro de 2008

Twitter + shell script

Como acessar o twitter a partir de um shell script de apenas 2 linhas? Fácil

#!/bin/bash
links -dump http://m.twitter.com/${1} | tac | sed -n '/\*/,$p' | tac | tail +2


Basta informar o username a ser impresso:

$./twitter.sh pac_man
Twitter

pac_man pac_man fogo controlado agora. about 1 hour ago

Previous Updates
* minha cozinha pegou fogo. about 4 hours ago
* @gchapiewski To com a cuia, onde se compra a erva (mate)? about 9
hours ago
* @pcalcado alias XYZZY='echo -ne Zork!' about 16 hours ago
* XYZZY about 16 hours ago
* 4 horas pra montar um armario. Pelo menos jantei pizza. 08:36 PM
January 28, 2008
* Odeio fazer mudanc,a! Armario ainda nao ta pronto... 03:41 PM January
28, 2008
* Amanha chega a minha mudanc,a. Terei um pc finalmente. 07:41 PM
January 27, 2008
* Odeio limpar a areia dos gatos. 07:38 PM January 27, 2008
* E ainda tenho q desmontar uma geladeira :/ 12:30 PM January 27, 2008


Não consegui fazer com que o links entenda o conjunto de caracteres correto mas... quebra um galho. Depois vou fazer um que submeta um post :)