27 de julho de 2012

Programador precisa ser bom em redação


Tenho visto que a característica que mais diferencia bons e maus programadores, no dia-a-dia, não é ser bom em lógica, nem aprender rápido. É ter a capacidade de transformar um raciocínio abstrato em código que funcione e seja entendido por outras pessoas.

Em outras palavras, é ter clareza de propósito, uma linha de raciocínio. É saber se expressar.

Programadores assim, normalmente, são bons palestrantes e escrevem em blogs. Quem os assiste ou os lê, entende o que eles querem dizer.

Mas existe o outro lado da moeda. Recentemente me envolvi num projeto já iniciado em Django e me deparei com a seguinte engrenagem, ao entrar numa URL p/ listar e filtrar uma relação de clientes:
  1. Uma função da view é chamada.
  2. Ela retorna um template HTML, que vamos chamar de HTML-A.
  3. Ele extende o template HTML-B e insere um outro template, o HTML-C.
  4. O HTML-A tem código javascript, bem como o HTML-B e o HTML-C também.
  5. No javascript do HTML-C, existe uma chamada Ajax para uma função de um controller de uma outra aplicação.
  6. Essa função do controller faz um certo trabalho, inclui dados que serão retornados ao HTML-C e passa o bastão para uma outra função.
  7. Essa nova, por sua vez, também trabalha, adiciona dados de retorno e encadeia uma chamada a uma outra.
  8. Essa última formata os dados e retorna, desfazendo a pilha, até voltar e popular o grid do HTML-C do item 2.
Complexo? Um pouco. Mas a confusão mesmo começou quando tentei juntar os pedaços e fazer uma manutenção na rotina. Acompanhe comigo:
  • Os títulos das colunas que aparecem no grid, bem como todas as configurações dele (altura, largura, etc.) estão no item 1 da lista acima. Ou seja, na view!
  • Os filtros são montados no item 6.
  • Os dados são efetivamente lidos no item 7.
  • Os mesmos dados são formatados, conforme o chamador, no item 8.
  • Nesses dados retornados, existem trechos de HTML hardcoded no item 8!
  • Esse HTML hardcoded é uma tag (um link) que aponta para uma URL definida na view do item 1.
  • A função do item 7 é importada de outra aplicação.
  • A do item 8 também.
Entendeu?

Bem, algumas pessoas podem dizer que isso é reutilização de código. É... é como se você estivesse reutilizando um trecho de bula de remédio, juntando com parte da Divina Comédia e do Hino à Bandeira e finalizando com o texto de uma questão da prova de matemática!

Ou seja, não faz o menor sentido. Tem muita coisa fora do lugar.

Eu disse que os nomes das funções e dos id's nem sempre retratam o que eles fazem? Isso pode parecer normal, mas quando não se tem nem uma letra dizendo aonde as coisas se encaixam, vê-se o caos.

Daí, eu fico pensando em como seria uma redação escrita por quem desenvolveu uma coisa assim. Alguém entenderia?

O Zen do Python define algumas diretrizes interessantes para programadores. Duas delas fazem o maior sentido nesse contexto:
  • "Complexo é melhor do que complicado".
  • "Se a implementação é difícil de explicar, é uma má ideia".
Com isso, reforço a minha tese que a melhor técnica para programar bem é redação e a primeira linguagem a se aprender é Português. A segunda, Inglês.

O resto, vem com o tempo e com a prática.

20 de abril de 2012

Usar o terminator ao invés do gnome-terminal

Existe um jeito de mudar o emulador padrão de terminal, no Ubuntu 12.04 Precise Pangolin, do gnome-terminal para o terminator.

Eu já tinha feito essa configuração visualmente no Lucid Lynx, mas agora isso não é mais possível. O Unity não mostra a opção nas preferred applications que fica na seção shortcuts do aplicativo keyboard.

Então, vamos recorrer à poderosa linha de comando. Digite isso: gsettings set org.gnome.desktop.default-applications.terminal exec /usr/bin/terminator

Assim, você substitui o gnome-terminal pelo terminator. Agora, o atalho Control+Alt+T vai abrir o terminator, ao invés do gnome-terminal.

Se você quiser que abra em tela cheia, troque a parte depois do exec por "/usr/bin/terminator -m". Sim, inclusive com as aspas.

19 de março de 2012

Encurtar URL pelo shell

Para quem gosta do shell do Linux, aí vai um encurtador de URL via linha de comando usando o serviço is.gd:
#!/bin/bash
# URL shortener using bash
U=$(python -c "import urllib; print urllib.quote('''$1''')") # urlencode long url
SHORT="`curl --data-urlencode --get is.gd/create.php?format=simple\&url=\"$U\" 2>/dev/null`"
echo -n $SHORT
Note o urlencode em Python. É para que os parâmetros da url longa não sejam confundidos com os parâmetros do próprio is.gd

Para complementar esse script, troque a última linha por:
echo -n $SHORT | xsel -i -b
Ela vai jogar a url já encurtada direto para o seu clipboard. Aí, é só colar aonde for necessário.

5 de março de 2012

Branch no prompt do shell

Uma das coisas que me incomodam quando uso git ou mercurial, é saber em qual branch estou trabalhando no momento.

Eu tenho alguns projetos no git e outros no mercurial. Aqui, mais uma fonte de confusão. Qual controle de versão eu uso em determinado projeto?

Para evitar ficar dando git branch ou hg branch toda hora, eis uma solução. Coloque isso no seu arquivo .bash_aliases:
function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(git \1) /'
}

function parse_hg_branch {
  hg branch 2> /dev/null | sed -e 's/\(.*\)/(hg \1) /'
}

export PS1="\[\e[36m\]>\W \[\e[0m\]\$(parse_hg_branch)\$(parse_git_branch)\$\[\e]2;\w\a\] "

O resultado é mostrado na imagem abaixo:



Qual o segredo para isso funcionar? Pipelining, sed e um pouquinho de regex.

Atenção: a última linha do código mostrado acima modifica seu prompt do shell. Por isso, atenção ao mexer com ele.

26 de janeiro de 2012

Como dar cd num shell script e ter efeito no prompt

Como todo desenvolvedor, eu tenho vários diretórios com programas fonte. Alguns deles são mais ou menos assim:
/home/usuario/src/web2py/applications/estoque
/home/usuario/src/web2py/applications/clinica
/home/usuario/src/web2py/applications/twitter
/home/usuario/src/web2py/applications/livraria
Toda vez que eu quero ir até o diretório da aplicação clínica, tenho que digitar cd ~/src/web2py/applications/clinica.

Nada prático, né? Então, surgiu a grande ideia de fazer um script para dar o cd automaticamente, mas esbarrei numa característica do shell: toda vez que um script é executado, um novo subprocesso é disparado e o cd que meu script fez não tem efeito no prompt.

Vamos supor que meu script seja ~/bin/meucd. Uma alternativa é executá-lo usando o source, assim: source meucd clinica. Ainda fica grande. Mas o source pode ser abreviado com um ponto ("."). Agora, o inconveniente é sempre lembrar de digitar o tal ponto antes do meucd.

A solução que encontrei foi combinar dois recursos do shell: alias e scripts. Eu fiz assim:
1) Editei meu ~/.bash_aliases (ou ~/.bashrc para quem não usa Debian-like)
2) Adicionei o seguinte comando ao final dele: alias meucd='source ~/bin/meucd'

Fechei o terminal e abri-o novamente para carregar o .bash_aliases alterado.

Agora eu já posso digitar meucd clinica.

15 de janeiro de 2012

Ramdisk no Linux

Outro dia eu conversava com o @Dodilei sobre como seria a velocidade de um aplicativo web montado na memória de um sistema Linux.

Imagine um sistema com velocidade de memória e não de disco, para servir aplicativos, arquivos, bancos de dados, etc.!

Hoje lembrei do assunto e  encontrei uns links. Segue o resumo.

Se você usa Ubuntu, já tem um ramdisk e talvez nem saiba disso. Entre em /dev/shm e você já estará nele. Simples assim.

Mas se você usa outra distro ou se quiser montar seu ramdisk de forma independente (o que eu recomendo):

mkdir -p /tmp/ram
sudo mount -t ramfs -o size=512M ramfs /tmp/ram/


Importante: nunca monte seu ramdisk a ponto de consumir mais memória do que o sistema operacional precisa. Isso pode travar seu computador.

13 de janeiro de 2012

O que é sucesso num projeto de software?

Faço minhas as palavras do Miguel Honório, no artigo Definindo sucesso em projetos de software.

Tomei a liberdade de reproduzir aqui o gráfico que ele usou para demonstrar o panorama dos projetos de software nos útimos 18 anos:

Desde 1994, tivemos, em média, 29,33% dos projetos entregues no prazo previsto inicialmente, com o custo previsto inicialmente e com o mesmo escopo inicial. São quase 20 anos e ainda não conseguimos acertar nem a metade do que estimamos.

Isso é muito ruim. Péssimo!

Mas, por que? Será que apenas 30% dos clientes do planeta conhecem realmente seu negócio? Certamente não. Será que menos de 30% dos profissionais de TI do mundo todo sabem realmente desenvolver software? Novamente, claro que não.

Quantas vezes, ao apresentarmos uma nova tela para o cliente, não ouvimos: "é... tá legal... mas faltou um campinho aqui pra escrever uma observação." Se trabalhamos com estimativas (de tempo, custo e escopo) rígidas, sabemos que esse pequeno ajuste vai acarretar dedicação de tempo. E, como não gostamos de trabalhar de graça, também acarretará custo. Mas se o cliente precisa mesmo desse novo recurso, não pode ser sacrificado. Mesmo que ele tenha esquecido de dizer isso antes. E o desgaste de cobrar por uma coisinha simples não vale a pena. Então, normalmente atendemos ao pedido, que invariavelmente, vai acumulando para um monte de pequenas solicitações, que formam uma semana de trabalho gratuito. Aí achamos que o cliente é aproveitador e que não conhece o próprio negócio. Ruim, né?

Bem, essa é a visão do desenvolvedor. E a visão do cliente, qual seria?

Ao longo dos anos, tenho conversado com clientes a respeito do que eles pensam sobre nós, desenvolvedores. A opinião deles não é lá muito confortante. Eles nos acham topetudos, enrolões, pouco comprometidos, incompetentes. E dizem que nós falamos outro idioma, que muitas vezes não conseguem entender. Alguns acham que falamos difícil para podermos cobrar mais caro. Ou seja, somos um mal necessário.

Mas, se o cliente toca o negócio dele, significa que ele conhece, certo? Se viramos noites trabalhando e entregamos software, significa que somos comprometidos e que conhecemos as ferramentas, certo?

Então, qual o problema? O método de trabalho. Nós, desenvolvedores, não temos como saber, de antemão, as dificuldades que teremos durante o desenvolvimento do sistema. Os clientes, também, não conseguem pensar em todas as nuances de legislação, regras, campos de tela... antes de ver alguma coisa funcionando.

Pessoas insistem em ler documentos e ver diagramas, ao invés de terem software funcionando. O tempo gasto na elaboração desses artefatos poderia ser muito bem empregado no desenvolvimento das funcionalidades. Muitas delas levariam menos tempo para serem desenvolvidas do que a própria documentação detalhada, preparada antecipadamente.

E, por que, então, continuamos desenvolvendo software dessa maneira? Por tradição. E pela falsa impressão de previsibilidade. Mas, vamos encarar a questão de frente: não temos poder para prever o futuro. Ninguém tem. Por isso, parece que os clientes gostam do me engana que eu gosto, ou não estão de fato comprometidos com seu próprio negócio, ou sempre buscam alguém para culpar em caso de algum problema. Até parece que eles não sabem que temos a tradicional "gordurinha" no prazo e no custo. Gente, trabalhar software assim não é racional.

Tá, mas qual seria a solução para contratar desenvolvimento de software sem as estimativas iniciais? Para isso não tem solução, porque tudo que vamos fazer no mundo dos negócios, precisa de uma estimativa. Só que estimativa é o que o próprio nome diz: estimativa. Não é certeza.

Como desenvolvedores, temos a obrigação de estimarmos um prazo, com base no que o cliente diz. Ele, por sua vez, precisa saber que mudanças virão tão rápido quanto a primeira entrega de software. E que, se mudou o que precisa ser feito (escopo), também mudou o dia de entregar (prazo) e o quanto ele vai pagar por isso (custo). Para mais ou para menos.

Minha sugestão é: que tal contratar o desenvolvedor por mês? Se o cliente sentir que ele está enrolando, contrata outro logo no primeiro mês. Se o ritmo estiver bom, continua. Afinal de contas não é isso mesmo que vendemos, nossas horas de trabalho?

É muito normal vermos projetos 99% prontos. Incomum é vermos um cliente realmente satisfeito com os sistemas da empresa.

Leia o post do Miguel e faça o download do livro que ele recomenda. Leitura simples e bem prática, onde aprendi bastante quando estava ajudando a traduzí-lo.