Archive for the ‘codigo’ Category

Não sejamos tão radicais…

junho 16th, 2010

Uma das coisa que me incomodam bastante no meio de informática é que muitos de nós são um tanto radicais. Canso de escutar pessoas dizerem que somente a tecnologia delas  – que elas usam – é a melhor. Em minha humilde opinião, comentários a parte (já escrevi, inclusive, sobre isso), não existe o ideal e a tecnologia mais adequada para o problema.

Como disse antes não quero me ater a discussão do porque não existe uma tecnologia legal e se devemos conhecer mais de uma pois isso, já amplamente abordado inclusive por mim.  Quero apenas rebater um poucos os fanáticos.

Atualmente temos uma clara evolução do uso de duas tecnologias principalmente: Python e Ruby. O Ruby quase exclusivamente impulsionado pelo Rails ( framework de desenvolvimento altamente produtivo de aplicativos web) e python pelo seu poder ( o famoso battery include) e também por alguns de seus frameworks ( Django, Web2Py, Zope, Plone, etc)

Uma coisa que me incomoda um pouco na galera é que por muitas vezes, o pessoal que está chegando agora, vem tomando logo formas de pensar radicais. Um exemplo disso é o discurso mais do que batido que Java é mal.

Gente, sinceramente, Java não é mal. Muito pelo contrário, foi uma grande porta, primeiro passo, para todo esse boom que temos visto. Java, embora não seja  opensource, sempre fomentou o software livre e acabou por criar uma comunidade forte em seu entorno. Essas mesmas comunidades  que são veneradas por  muitos dos que negam o java,  surgiram desse movimento graças ao Java.

O grande problema, da linguagem,  que ela parou no tempo. O que por um bom tempo, sobre somente alguns pontos de vista, ajudou a protegê-la foi o mesmo que a engessou-la. Se ela tivesse se aberto para modificação, mesmo que gradualmente, possivelmente  ainda estaria sendo usada e adorada como antes.

É certo que criar um aplicação em rails é muito mais produtivo do que criá-la em Java ( mesmo com todos os frameworks existentes).  O mesmo vale para o Python em até outros casos.  Então por que estou, aparentemente, defendendo-a? Simples, pois quero mostrar que ainda existe vida após a morte nesse nosso mundo de TI.

Java , para “competir”  com essa galera tem “renascido” com outras formas que permitem sermos mais produtivos.  Um exemplo que gosto muito é o Groovy. O Groovy, senão me engano, foi criado por 2002 ou 2003 como uma linguagem alternativa para rodar dentro da JVM (java virtual machine). Graças ao seu sucesso foi implementada a um especificação para tornar a JVM capaz de entender outras linguagens.

Groovy é um Java melhorada e evoluído para os moldes desses novos paradigmas trazidos por Ruby, Python, etc.  Trouxe uma produtividade maior. Hoje é possível fazer uma aplicação nos moldes de Rails em “Java” /groovy usando o framework Grails.

Outra faceta desse mesmo ponto de vista tem sido o JRuby. JRuby é uma implementação do interpretador do Ruby para a JVM. Assim é possível executar código escrito em Ruby a partir da JVM.

A coisa não para por aí. Basta uma simples busca no google para vermos outros exemplos desse renascimento em outras formas do Java.

E ainda tem a pŕopria linguagem que não para de evoluir e ainda tem o seu espaço. Acredito sinceramente, que existem alguns problemas (requisitos)  os quais a melhor solução seja implementar a solução em Java.

Bom com certeza ainda terão aqueles que dirão que suas linguagens tem as melhores ferramentas. Concordo plenamente. Para mim, falando por exemplo de testes – TDD e BDD,  cucumber, rspec, mocka, should-dsl, lettuce, entre outras são estado da arte. Porém, já encontrei coisas em “Java” (entenda aqui conseguir testar código java, pois tem ferramenta em Groovy por exemplo) que pelo menos chegam perto disso.

Bem a princípio era isso que gostaria de dizer, até a próxima pessoal.

Fazendo upload de arquivo com WebDriver

maio 6th, 2010

A um tempo atrás alguém postou um comentário aqui no blog perguntando como ele poderia testar a questão do upload de arquivo usando o Selenium.

Bem, pedindo ajuda para o grande sábio Google, encontrei a página (clique aqui) com um trecho de código que reproduzo parte abaixo mostrando como fazer.

Pelo jeito ele somente irá funcionar para o IE pois os demais browser não aceitam que você digite no campo de file. (Me corrijam se eu estiver errado).

Espero que ajude:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package org.openqa.selenium;

import static org.openqa.selenium.Ignore.Driver.CHROME;
import static org.openqa.selenium.Ignore.Driver.IPHONE;
import static org.openqa.selenium.Ignore.Driver.SELENESE;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;

/**
 * Demonstrates how to use WebDriver with a file input element.
 *
 * @author jmleyba@gmail.com (Jason Leyba)
 */

@Ignore(value = IPHONE, reason = "File uploads not allowed on the iPhone")
public class UploadTest extends AbstractDriverTestCase {

  private static final String LOREM_IPSUM_TEXT = "lorem ipsum dolor sit amet";
  private static final String FILE_HTML = "<div>" + LOREM_IPSUM_TEXT + "</div>";

  private File testFile;

  @Override
  protected void setUp() throws Exception {
    super.setUp();
    testFile = createTmpFile(FILE_HTML);
  }

  @JavascriptEnabled
  @Ignore(value = {CHROME, SELENESE},
          reason = "Chrome: File input elements are not supported yet")
  public void testFileUploading() throws Exception {
    driver.get(uploadPage);
    driver.findElement(By.id("upload")).sendKeys(testFile.getAbsolutePath());
    driver.findElement(By.id("go")).submit();

    driver.switchTo().frame("upload_target");

    WebElement body = driver.findElement(By.xpath("//body"));
    assertEquals("Page source is: " + driver.getPageSource(),
        LOREM_IPSUM_TEXT, body.getText());
  }

  private File createTmpFile(String content) throws IOException {
    File f = File.createTempFile("webdriver", "tmp");
    f.deleteOnExit();

    OutputStream out = new FileOutputStream(f);
    PrintWriter pw = new PrintWriter(out);
    pw.write(content);
    pw.flush();
    pw.close();
    out.close();

    return f;
  }
}

Pyccuracy – Uma boa ferramenta de teste. Coloque-a na sua maleta

março 12th, 2010

Ultimamente, no meu emprego atual, tenho a oportunidade de usar um excelente framework de testes de aceitação brasileiríssimo que é o pycurracy . Ele é uma ferramenta feita em python que permite que você escreva suas histórias de aceitação em linguagem natural. Isso significa dizer, que você pode escreve o seu teste em português.

Não preciso dizer o quanto isso traz de vantagem. Só para citar, uma das mais imediatas, pelo menos para mim, é a questão da documentação.  Quem já está na estrada um tempo, sabe como é uma verdadeira luta manter documentações atualizadas do produto.  Tudo sempre começa bem, mas com o passar do tempo, sempre surgem outras tarefas mais urgentes e os “casos de uso”  ou histórias acabam ficando não condizentes com a realidade da aplicação.  Para muitos, isso pode soar como preciosismo porém imagine um contexto de um projeto open source… sem uma documentação bem feita, colaborar pode ficar bem difícil.

Um outro aspecto também é que desenvolvedores “não são muito amigos” de escrever documentos. Esta aí uma tarefa que vejo poucos colegas fazerem com prazer. Se puderem evitar, a grande maioria em minha humilde opinião,  evitarão fazê-lo.

Ferramentas como o pyccuracy, vem unir o “útil ao agradável”: vem possibilitar escrever testes, programando, e como resultado indireto obter uma excelente fonte para consultas.  Por permitir escrever os cenários  em linguagem natural (inglês e português) acabamos por ter um documento descrevendo o funcionamento esperado… as nossas histórias.

O pyccurace é todo feito em python usando o Selenium .  Para maiores detalhes recomendo uma visita a página do projeto.

A única coisa que tenho a dizer sobre ele é que bem que poderia ter uma implementação que usasse o WebDriver ao invés do Selenium RC. Acredito que ficaria bem mais rápido. Mas, até agora só temos versões estáveis do WebDriver para Java. A versão python está bem timida ainda.

Entendendo os decoradores em Python – Parte 1

dezembro 4th, 2009

A um certo tempo atrás me deparei com alguns códigos que usavam o recurso de decorator.  Dali, curioso com tal coisa, resolvi pesquisar para entender melhor como funcionam, para que servem, e quais seriam bons cenários para usá-lo.  Para minha surpresa, achei pouco material sobre, a maioria conteúdos que tratavam do assunto de forma superficial, outros que abordavam a coisa mais prática e/ou associada a um problema único,  alguns tantos falavam de forma extremamente complexa e sem muito nexo, etc. Para piorar,  quase nenhum dos artigos eram em português o que, se não tiver fluência total no inglês,  fica bastante complicado captar alguma essência (textos mal escritos, vocabulário difícil, e outras coisas).

Bem, desses todos, achei um excelente texto de uma fonte altamente confiável: Bruce Eckel, no site Artima.  O artigo aborda justamente de forma abrangente o assunto, decorator do python, e dando o enfoque que procurava (funcionamento, porque usar, como usar, quando usar) .  Então, como forma de dar minha retribuição a comunidade, segue uma versão do texto dele (não me ative a traduzir, parte irei reproduzir, outras colocarei minha visão).

Primeira coisa que considero interessante, que o próprio original cita,  é que necessitamos desfazer alguns conceitos erróneos sobre Decoradores. Muita gente quando escuta decorators logo remete seu pensamento aos padrões de projeto, mais precisamente, o padrão Decorator.  Esse padrão é feito para possibilidade de forma simples adicionar  recursos, detalhes, adornos a uma classe, inclusive em tempo de execução. Aqui eles tem mais uma carinha de Macros, do que decoradores.

O objetivo das macros é de permitir alterar os elementos de uma linguagem. Isto é exatamente oque os decoradores em Python fazem – eles modificam  funções e classes inteiras (existem decorators para classes) .  Isso é porque eles usualmente provem um caminho alternativo ao uso de metaclass.

A grande parte das linguagens que suportam tal recurso (auto-modificação)  falham no quesito complexidade :  elas são tanto restritivas e requerem, em alguns casos, uma linguagem diferente. Python se faz a pergunta: porque não fazê-lo em python mesmo? Porque não permitir escrever macros ou decoradores na própria linguagem permitindo uma interação maior ? Esse é exatamente a proposta dos decoradores.

Porque usar Decorators?

Decorators permitem que se altere a execução de um método ou classe. Para que os conhecem, lembra bastante o AOP (Aspect Oriented Programming – programação orientada a aspecto) .  A diferença que não precisamos muitas coisas ou grandes conhecimentos, oque torna muito interessante e legal, mesmo que para iniciantes.

Um exemplo de uso, didático,  é escrever algo que permita fazer algo antes e depois da execução de uma função.

1
2
3
@meuDecorator
def funcaoQualquer():
print "Ola Mundo"

A clásula acima @, define a chamada ao meu decorator que irá fazer algo, quando este método for chamado. Algo semelhante a uma proxy.

Documentar é preciso e faz bem

setembro 26th, 2009

Esses dias li um e-mail numa lista de discussão que participo onde a pessoa perguntava como ela deveria fazer para documentar um projeto que ele desenvolveu sozinho. Ainda segundo ele, a ideia é de permitir que num futuro próximo um novo desenvolvedor possa trabalhar no sistema sem traumas e com uma curva de aprendizado rápida.

Antes de tentar responder a pergunta, acredito seja necessário entender a diferença entre análise e documentação.  Muitas pessoas que trabalham com  criação de softwares, acabam confundindo documentar com analisar.  Essa dúvida é normal pois muitas “ferramentas” e “métodos” também se apresentam como opção de documentação, ou o contrário : coisas que deveriam ser usadas para documentar são usadas para fazer análise ( e até acabam com uma má fama sem terem culpa disso – puro mal uso). Um exemplo disso, no meu ponto de vista, é o uml : Muitos usam a UML com o propósito de analisar e modelar. Ela até foi criada com esse intuito pois, quando foi concebida  era bastante custoso codificar e alterar o código feito (lembre-se dos cartões perfurados, cobols da vida, etc) mas hoje isso já não é válido (com linguagens modernas, codificar é rápido e alterá-lo mais ainda). Voltando, UML, no meu ponto de vista, é muito mais documentativa do que modelagem.  Seus diagramas tem um ótimo apelo de representar graficamente um sistema e como diz um ditado: “Uma imagem vale por mil palavras”.

Um outro mito a ser desfeito, insisto, no meu ponto de vista, é de que documentar não agrega valor. Por mais que ninguém diga isso, por mais que ninguém escreva isso, por mais que ninguém assuma isso, muitos de nós considera o ato de documentar como uma atividade secundária, e com isso, delegamos para que outros façam ou, em piores casos, nem o fazemos. A questão que ninguém escreve um sistema para si e, na maioria dos casos, não fazemos isso sozinhos.  Outro ponto é que, possivelmente, não ficaremos para o resto de nossa vidas com aquele projeto, passaremos para outros desafios e aquele sistema deverá ser cuidado por outro pessoa que não necessariamente participou da equipe que o desenvolveu. Tal fato, implica em ter que forma esse pessoa de forma que ela possa dar continuidade ao aplicativo sem comprometer a qualidade dele (estou assumindo que seja aqueles projetos onde temos testes automatizados, linguagens bem expressivas, etc). Logo, tendo todo esse contexto em mente, fica fácil mostrar que documentar, no mínimo, é evitar dores de cabeça futuras.

Mas, enfim, como documentar?

A pergunta poderia ser redigida da seguinte forma para ter mais sentido para nós : Como podemos documentar sem que isso seja uma atividade secundária e agregue mais valor ao sistema? .  A maioria das linguagens modernas oferecem recursos, bastante interessantes, que podem responder essas perguntas. Em Java, nós temos o recurso básico do JavaDoc (comentários em formato especiais que são colocados no código fonte. Depois, através de ferramenta exportamos para um html), em .NET (csharp) temos algo parecido, e por ai segue. Embora isso já seja algo que ajude, considero insuficiente como documentação pois, quem irá ler não terá uma visão do funcionamento ou do comportamento do sistema.

Nesse contexto de comportamento e funcionamento que entram a ajuda primordial dos teste automatizados. Um efeito secundário dos testes automatizados (tanto os teste unitários quando os testes de comportamento) é de, se bem escritos e de grande abrangência,  eles acabam sendo uma boa fonte de consulta para o entendimento da aplicação.  Existe, inclusive, frameworks de teste de comportamento (Behavior Tests) que permitem que se escrevam de forma literal facilitando ainda mais o seu uso como documentação, como por exemplo o Cucumber (Ruby), Pyccuracy ( espero ter escrito certo – Python), etc.

Por fim, eu pessoalmente, acredito que um bom diário de bordo também ajuda bastante. Um diário de bordo, consiste, em algo parecido com um blog ( pode até ser um blog), em que vou escrevendo o dia a dia do desenvolvimento tentando retratar as decisões não técnicas e situações vencidas pela equipe de forma que a pessoa que irá trabalhar com o sistema no futuro tenha também uma visão do por que de certas escolhas, do sentimento da equipe naquele momento, etc.

Uma experiência a compartilhar

setembro 9th, 2009

Por um motivo que prometo explicar depois, tive que criar uma api para fazer o mapeamento de objeto-relacional para um sistema em Csharp que estamos desenvolvendo.  Como não gosto de reinventar a roda, parti para ver como os frameworks mais usados fazem isso e procurei fazer uma implementação light do que eu vi. Para título de curiosidade me baseiei em Hibernate,  Linq, etc.

O primeiro passo foi determinarmos com o faríamos a questão do mapeamento : para tanto resolvi partir do que hoje é feito pelo hibernate. Dentro do hibernate, simplificando muito o seu funcionamento, você tem um configuração que diz qual campo faz referencia a qual atributo (ou propriedade), qual tabela, as relações, etc.  O hibernate então ao receber o objeto para persistir, por exemplo, pega este dados, monta a query (insert,delete, update, select) e faz a operação. Como disse antes a idéia foi fazer algo light, sendo assim, optamos apenas por mapear os campos, tabela e objetos e não sua relações (com isso eliminamos muita complexidade). Sendo assim, nosso objetos deveriam apenas “saber” qual tabela e colunas a serem mapeadas.

O segundo desafio foi definirmos como iríamos fazer esse mapeamento :  usaríamos um xml, um arquivo de propriedades, base de registro, e por ai seguimos. Após muita discussão vimos que o usuário de nossa api de persistencia seria um outro programador, por isso, teríamos que fazer algo que facilitasse a vida deste cara. Foi aí que decidimos usar Atributos (o mesmo que anotações em Java). Para minha surpresa, criar atributos customizados em Csharp é algo realmente simples (veja o post que escrevi sobre com dicas de como fazer – clique aqui)

Sei que minhas próximas palavras vão soar estranhas para quem não curte codificar como eu, mas :  Não é que a coisa ficou bonita ! A implementação ficou fácil e tudo concentrado na classe sem necessidade de xmls, arquivos externos, problemas de atualização de base de registro, etc.

O meio do caminho – a transformação dos dados dos objetos para relacional e vice versa – foi toda feita com a api de Reflection do .NET. Ela é bastante poderosa, porém com inúmeras diferenças para quem já está acostumado com o Java.  Mas insisto, ela é bem poderosa e interessante.

Ao usar Reflection e rodar nossos testes (isso mesmo estamos desenvolvendo com o TDD – desenvolvimento orientados por teste, escrevemos os testes antes e depois vamos implementando), vimos que ocorria um erro de conversão:  O sistema dizia que não era capaz de converter um valor System.Decimal para System.Int32.

Cabe uma explicação ai: em .NET, ao acessar uma base de dados, para percorres o resultado de uma query você tem um objeto DataReader. Esse objeto é como um mapa dos valores da linha.  Para ele, os valores numéricos ficam mapeados como Decimal e por isso o erro.

A solução achei graças ao Google : basta usar a seguinte linha de código e todos os meus problema sumiram:

1
info.SetValue(obj,System.Convert.ChangeType(objReader[column.name],info.PropertyType),null);

O segredo da linha acima é de usar System.Convert.ChangeType . Ele se encarregará de fazer a conversão correta. Como argumento este metodo tem : valor a ser convertido, tipo para qual será convertido o valor.
Bem essa foi a minha aventura das últimas semanas. Achei legal compartilhar pelas dificuldades e de como fizemos para chegar a solução final.

Usando Expressões Regulares

abril 4th, 2009

Copiando os demais blogs e inaugurando minha coluna de pergunta e respostas, gostaria de começar por um email enviado para a lista do riojug. No email, a pessoa dizia que precisa retirar todos os traços, ”- “, de seu texto que não tivessem “sentido” : traços sozinhos, traços que não fossem de ligação, etc. Ele inclusive mandou um exemplo esclarecedor

- guarde-o – senão guardarei-o eu — Joãozinho-”;

No texto acima os traços a serem substituídos seriam : o primeiro, o traço antes do senão, os 3 traços seguidos e o traço do fim.
Para resolver isso poderiamos partir para várias soluções; uma mais elegantes que as outras, e vice-versa:

  • Varrer caracter a caracter e verificar: ler como um array de char e ficar verificando se o anterior é espaço, traço, etc…. Em pseudo codigo seria
  • 1
    2
    3
    4
    5
    6
    7
    char letras[] = <string em questão>
    letras.each{|i,l|
    if i = 0 then
        if l='-' then replace
    else
        if l='-'- and (letras[i-1]=' '  or letras[i-1]='-' or letras[i-1]=':')............ // e continua
    }

    so de ler e tentar fazer já dá medo…. e olhem que eu já vi coisas assim implementadas !!!

  • Usar expressões regulares.
  • Expressões regulares são uma forma de representar conjuntos de caracteres que estão sobre um certa regra. São como dicas que damos a quem procura, para que ele ache o que queremos. como analogia poderiamos imaginar que alguém nos pede para chamarmos uma outra pessoa. Para isso elas nos dá indicativos de como encontrá-la : alta, magra ou gorda, perto de um homem ou mulher, proxima a porta, etc… Transpondo isso para textos, expressoes regulares seriam como esta dicas.
    Expressões Regulares foram criadas pelo ano de 1943 por dois neurologistas. Anos mais tarde, um matemático, modelou algebricamente isso, dando o “ponta pé inicial”. Em 1968, graças ao unix, encontrou sua veia computacional, por meio do editor. Era chamado pelo comando ed. Este ed tinha o comando de contexto g, que aceitava expressões regulares e um comando p, e sua sintaxe ficava g/RE/p (“Global Regular Expression Print”), que deu origem ao aplicativo grep, que por sua vez originou o egrep.[fonte: guia de expressões regulares - aurélio marinho Vargas, Editora novatec]
    Bem vamos ao código

    1
    String.replaceAll("[^[:alnum:]][-][^[:alnum:]|[-]$|[-][[:punct:]]|^[-]")

    Lindo não ?!?!? Uma linha …..
    Quem se interessar pelo assunto pode ler o livro on line do Aurelio Marinho, Novatec, que é uma fonte riquissima para isso. (clique aqui)