04/03/2010

Como estimar prazos precisos e imprecisos

Ilustração de hartboy

Definir quanto tempo será necessário para finalizar uma tarefa ou o desenvolvimento de um software não é (ou pelo menos não deveria ser) algo trivial. Estimar prazos faz parte do nosso dia-a-dia como programadores.

O que muita gente não se dá conta é que a precisão com que um programador prevê a entrega de tarefas e projetos é um poderoso indicador do quão bom ele é.

Para informar de forma precisa o tempo necessário para a realização de algo em desenvolvimento de software é necessário que o programador possua uma certa experiência no assunto, tenha um bom domínio do negócio, seja rápido e produtivo.

Embora muitos de nós não apreciem essa difícil tarefa, estimar prazos é parte do nosso trabalho. Fazer isso bem pode ser a diferença entre um programador profissional e um amador.

Em um dia normal, estamos estimando prazos o tempo todo. Ao colocar a comida no micro-ondas você deve informar quantos minutos serão necessários para esquenta-la. Se você tem um horário fixo para acordar, deve analisar quantas horas de sono serão suficientes e então decidir quando deve ir para a cama.

O segredo não está no tempo, mas em quão precisa deve ser a sua estimativa. Se seu chefe pergunta que horas você entregará o relatório amanhã, ele quer ter uma ideia se será antes ou depois do almoço. Se ele lhe pergunta quanto tempo será necessário para resolver um bug critico e colocar o sistema de volta em produção ele precisa de uma precisão maior.

A escala de tempo é muito importante ao se estimar prazos. Por exemplo, você pode dizer “O projeto será entregue em 25 dias” ou pode dizer “O projeto será entregue em cerca de 5 semanas”. Embora ambas as frases indiquem o mesmo tempo, o efeito sob cada uma delas pode ser diferente. Ao dar a primeira resposta, seu cliente provavelmente anotará na agenda dele o dia exato em que você entregará o projeto. Por outro lado, a segunda resposta fará com que ele lhe procure a qualquer momento daqui a 4 ou 6 semanas.

O livro The Pragmatic Programmer dá uma importante dica que nos ajuda a escolher a escala de tempo apropriada ao estimar prazos. Veja a tabela:

1-15 dias -> dias
3-8 semanas -> semanas
8-30 semanas -> meses
30 + semanas -> pense bem antes de dar uma estimativa

Qual a vantagem disso? O fato é que quanto maior o tempo, mais difícil é a previsão, exigindo que você seja cada vez mais impreciso. Por exemplo, se sua estimativa é que serão necessários 125 dias para terminar um trabalho, é muito mais seguro dizer que precisará de “cerca de 6 meses” para finaliza-lo.

Todas as estimativas que fazemos são baseadas em nossas experiências passadas. Mas, o que fazer quando é necessário estimar algo que você nunca fez ou que não conhece? A resposta é simples: “não estime”. É melhor pedir para que alguém que já tenha feito algo semelhante lhe dê uma ideia do tempo necessário.

Além de considerar o grau de precisão, também é importante entender qual é o problema antes de começar a chutar um tempo. Quase sempre nossas estimativas dependem de outros fatores para darem certo: “Supondo que não haja trânsito dá para chegar aí em 20 minutos”.

Se possível é muito útil testar alguns aspectos do projeto antes de dizer quanto tempo será necessário para cumpri-lo. Se o sistema precisa ser carregado dentro do Facebook, seria muito bom poder gastar um tempo criando alguma coisa bem simples para esta plataforma afim de analisar o grau de complexidade, isto sem dúvida aumentará a precisão da estimativa.

É muito importante levar em consideração que a equipe, sua produtividade e o ambiente afetam diretamente sua estimativa.

Analisando todos estes fatores, a conclusão é que há apenas uma única resposta correta a se dar quando lhe é pedido para estimar um prazo: “Me dê algum tempo para pensar”. Você sempre terá resultados melhores se retardar a resposta e pensar um pouco mais.

01/03/2010

[Link] The Future Of CSS Typography, @font-face fonts

The quick fire fox jumps over the explorer
O Smashing Magazine (Inayaili de Leon) fez um excelente post sobre o que está disponível e o que vem por aí no CSS3 com relação a texto e formatação.

A especificação final do CSS3 ainda não está pronta e algumas coisas ainda devem mudar. Muito do que é mostrado ainda não é suportado por alguns dos browsers mais populares (principalmente o Internet Explorer). No entanto, se você é designer ou programador de interfaces já pode fazer alguns testes e ir adiantando o aprendizado. Destaque para o novo text-decoration e mais uma vez para o @font-face.

Um novo mercado

A possibilidade de incluir fontes em um site diferentes das que o usuário possui instaladas na máquina é um grande avanço para o design, sem dúvida. Mais do que isso, é o surgimento de um novo mercado. O Fontspring vende fontes compatíveis com @font-face além das fontes comuns para desktop. Mas, qual a diferença? Bom, a mais importante delas é com relação à licença, que deve permitir explicitamente o embeding. Isto vale também para outras formas de embeding/replacement, como o Cufón (usado aqui no TAS). Para funcionar no IE, a fonte (pelo menos por enquanto) deve ser convertida para o formato EOT, da Microsoft. A principal polêmica do embed de fontes é justamente quanto ao formato x pirataria. Até agora, os formatos de fonte para web são os mesmos do desktop, onde bastaria baixar o arquivo indicado no arquivo CSS para se ter o arquivo de fonte totalmente funcional em um outro computador. Ainda não se chegou a um consenso/acordo entre as type foundries, designers de tipos, fabricantes de browsers, etc., e o assunto ainda deve render.

Artigos Relacionados:

  1. [Link] Dive Into HTML5

21/02/2010

iPhone e Rails

O desenvolvimento de web apps para iPhone requer alguns cuidados especiais. Em nossas aplicações significa pensar em um layout para o gadget. Uma forma rápida de definir o layout para iPhone é através do código abaixo:

Para quem quer conhecer o desenvolvimento de web apps para iPhone, vale conhecer os projetos jQTouch e iWebKit. O jQTouch é um plugin do jQuery com uma série de recursos de animação semelhantes ao do aparelho e possui inclusive a funcionalidade de Geo Location. Já o iWebKit é um framework que não depende de nenhuma biblioteca e que possui também bons recursos para montagem de interfaces.

Posts relacionados:

From Solo to Full Chef

Yesterday I wrote about my exercises with Chef Solo. I’ve spent several hours experimenting different cookbooks, writing my own recipes, tweaking attributes, reverting snapshots of my virtual machine several times to execute everything again. That got me pretty excited as I was getting more and more confortable.

So, as the Solo exercise was great I decided to try the full blown client-server model. And, to my surprise, it was easier than I expected.

Now I’ve installed 2 Debian virtual machines, bare bone with the 1st CD-ROM and no optionals. I recommend that you already choose 2 different hostnames for each of them, such as “chefserver.localdomain” and “chefclient.localdomain”. Then I installed build-install and ssh from the apt repositories. Manually downloaded and installed Ruby Enterprise Edition .deb package.

Recently, Rubygems was updated to 1.3.6 to add Gemcutter features. So you need to manually update and then install chef’s gems:

1
2
gem update --system
gem install chef ohai --no-ri --no-rdoc

Just so you don’t need to switch between articles, I am going to repeat what I said in the previous article about downloading cookbooks:

1
2
3
4
5
wget http://github.com/akitaonrails/cookbooks/tarball/master
mkdir -p /srv/chef
cd /srv/chef
tar xvfz ~/akitaonrails-cookbooks-2b4edeb.tar.gz
mv akitaonrails-cookbooks-2b4edeb cookbooks

Again, beware of the “2b4edeb” hash ID as it will change whenever I push a new commit to Github. Now, do the following:

1
2
3
4
mkdir /etc/chef
touch /etc/chef/solo.rb
echo "file_cache_path  \"/tmp/chef-solo\"" >> /etc/chef/solo.rb
echo "cookbook_path    \"/srv/chef/cookbooks\"" >> /etc/chef/solo.rb

Consider that I am building up 2 virtual machines with the same configurations. If you followed my hostname suggestion above, I recommend adding the “chefclient.localdomain” IP in your chefserver /etc/hosts file and vice-versa, so that each machine can reach each other through their full domain names. This is only necessary because I will not bother installing a DNS server, but in a production setting, of course you will need a DNS server to resolve names.

Now, for the chefserver machine, edit /etc/chef/server.json with the following:

1
2
3
4
5
6
7
8
9
10
11
12
{
  "bootstrap": {
    "chef": {
      "url_type": "http",
      "init_style": "runit",
      "path": "/srv/chef",
      "serve_path": "/srv/chef",
      "server_fqdn": "chefserver.localdomain"
    }
  },
  "recipes": "bootstrap::server"
}

Pay attention to the server_fqdn attribute, it requires a Fully Qualified Domain Name, so “locahost” will not work, you need a full domain name. Now, in the chefclient machine, create and edit /etc/chef/client.json with the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "bootstrap": {
    "chef": {
      "url_type": "http",
      "init_style": "runit",
      "path": "/srv/chef",
      "serve_path": "/srv/chef",
      "server_fqdn": "chefserver.localdomain",
      "client_interval": 300,
      "client_splay": 10
    }
  },
  "recipes": "bootstrap::client"
}

Again, pay attention to the server_fqdn as it should point to a reachable Chef Server in the network, hence why I said to add the server domain name to the client’s hosts file.

One caveat: Up until this version, there is a small bug with the newest JSON 1.2 gem. You need to manually remove it and downgrade to the previous version:

1
2
3
gem install json json_pure -v 1.1.9 --no-ri --no-rdoc
gem uninstall json json_pure -v 1.2.0
ohai hostname

The last command should print out your hostname without any errors.

Now, time to install the chefserver and the chefclient machines. This is a good opportunity to Take a Snapshot so you can revert back in case anything goes wrong. In the chefserver machine, run this command:

1
chef-solo -c /etc/chef/solo.rb -j /etc/chef/server.json

And obviously enough, run this command in the chefclient machine:

1
chef-solo -c /etc/chef/solo.rb -j /etc/chef/client.json

The client side should be fast, the server side should take a while. The recipes are robust enough and you should not have any problems.

Once it’s finished, edit the /etc/chef/server.rb file. Uncomment the last two lines and add your open ID provider and open ID so you can log in.

1
2
authorized_openid_providers   [ "https://debian.localdomain", "myopenid.com", "akitaonrails.com" ]
authorized_openid_identifiers [ "www.akitaonrails.com" ]

In the same file you will find a line similar to this:

1
validation_token   "ALC8rmTryYO1nAK6bdX2"

Copy this line, edit the /etc/chef/client.rb in the chefclient machine and paste that line there. This is not really necessary but for our controlled exercise purpose, it should make things easier. Read the Securing Chef Server documentation for more information.

Now, you open your web browser and go to http://chefserver.localdomain:4000 (considering that you registered the chefserver in your desktop hosts file too).

The way chefclient is configured makes it call back home to the chefserver every 1200 seconds (20 min) with a splay of 20 seconds. The splay thing is so that if you have dozens of nodes, they don’t try to hit the server all at the same time, causing a denial of service attack in the server (thundering herd problem). The splay randomly distributes the reconnections within a 5 min range, so each node will call back within 20:00 and 20:20 since the last reconnection. In the client.json above I overrided these options to have it call back every 5 min (300 sec) with a smaller splay of 10 sec as I only have 1 node in my exercise. You should increase this interval if you have many nodes.

When it connects back, it will validate itself with the server. So if you go to the “Registration” page in the admin app, you should see the Node already registered. Now you can go to the “Nodes” tab and Edit your client node.

You will be presented to a list of available recipes and a Run List box. You can drag and drop individual recipes in the top thin grey bar at the top of the Run List box (that’s the droppable area). Below you will find a JSON attributes editor. You can use “Add Child” to add new nodes to configure the recipes you added just like you did manually with the previous when you edited the dna.json file.

When you save the node configuration, next time the client reconnects with the server, it will push the recipes and run what you configure. You will also notice that there is a Roles box in the same page. Instead of dragging and dropping dozens of individual recipes, you can group them in a Role, such as “web server” ou “load balancer” and so forth. Read the Roles documentation.

Now that you have a server, you can add as many node machines as you want. The default recipe installs the Chef Server over Mongrel but there are procedures for Thin, Passenger and more. Another detail: the chef-client runs as a daemon on the node machines. It will consume around ~30 MB of RAM. Depending on your usage this can be too much or it can be nothing. If you have a cheap VPS server with 360 Mb of RAM, this client alone consumes almost 10% of the available RAM. If you have a big iron server with 16 GB of RAM, the extra 30 MB of the client weights absolutely nothing. But keep in mind that the client is not cheap.

One complain I hear a lot from some people is the concern between CF Engine and Puppet/Chef on dependencies and weight. Because CF Engine is made in C it depends on almost nothing whereas Puppet/Chef depends on a full Ruby and Gems installation to bootstrap. Another thing is that the CF Engine client is very lightweight, but a puppet or chef client will consume at least 30MB, which is not cheap.

Again, this is convenience vs flexibility vs performance, there’s always a trade-off. That’s why you need to study these tools and the scenarios you intend to use them to better evaluate what and how to use. There is no free lunch. Chef is a light enough, very flexible configuration management tool, the installation process was easier than I thought and the recipe DSL is very expressive. I definitely intend to use it more.


18/02/2010

Configurações do OS: prosa, verso e taquigrafia.

Uma das grandes máximas do design de interfaces é aquela de que quanto mais invisível, mais eficaz ela é. Dispensar manuais e treinamentos também é um outro bom indício de uma interface bem construída. No caso de um sistema operacional, onde você tem usuários com diferentes graus de familiariadade com computadores e o utilizam também para finalidades tão distintas, parece muito complicado construir uma interface tão abrangente. Vou tentar comentar neste post as diferenças no projeto de interface entre os principais sistemas operacionais e gerenciadores de janelas.

Wizards

Wizard - Windows XP

O Windows carrega no colo o usuário iniciante na maioria das situações. A cada novo ajuste, uma sequência de passos dentro de um wizard vão explicando o que o usuário deve fazer. São parágrafos e mais parágrafos, com orientações e possíveis caminhos. Parece ótimo: deixa o usuário mais seguro, facilita o tratamento de erros, não desfavorece o usuário médio – que ignora os textos – etc. Por outro lado, dificulta a tradução de textos e mais textos em todas as línguas a cada versão. Para o usuário avançado, que talvez precise executar a mesma tarefa num dia, é mais que desconfortavel. Tentar explicar em prosa ou limitar configurações que podem ser usadas para inúmeros fins também não é uma saída das mais inteligentes. Qual a diferença entre a rede doméstica e a rede de pequena empresa? Qual a diferença entre a instalação rápida, completa ou personalizada? Qual a necessidade de um texto enorme sobre o que está sendo feito seguido de um campo “Máscara de Sub-Rede” logo abaixo? Isto realmente é familiar ao usuário? Caberia um wizard em um caso como esse?

Painel de Controle

Usei o Windows desde a versão 3.1. Desde aquele tempo, havia um painel de controle para definições gerais do sistema. Fontes, dispositivos, tela, etc. Alguns poucos ícones. De lá pra cá, o sistema foi se tornando mais complexo. O número funcionalidades do sistema operacional cresceu, surgiram diversos tipos de dispositivos e possibilidades de trabalho. Com o sistema, o número de ícones no Painel de Controle se multiplicou: o que não é exatamente muito bom. Janelas de configuração já existentes em outras versões do Windows foram mantidas e funções afins foram sendo postas em itens separados. Chegamos hoje ao cúmulo de ter meia dúzia de itens relacionados a rede, além de uma barra mutante do lado esquerdo. Para onde ir?

Tentando simplificar e reduzir o caos, desde o Windows XP (ou seria o 2000?) há uma versão resumida (com os itens mais comuns) e uma ‘avançada’ do Painel de Controle. Esta é realmente a melhor saída?

Em verso

A Apple é uma empresa conhecida por tomar decisões pelos seus usuários, muitas vezes radicais. Provavelmente “Macintosh sem possibilidade de upgrade”, “retirada do drive de disquete”, “somente porta USB”, “retirada do drive de dvd”, “sem 3G” e “monotarefa” façam algum sentido pra você. A verdade é que o Mac OS, principalmente a partir da versão 10, também é um sistema extremamente opinativo, objetivo, direto.

Windows 3.1

Windows 3.1

Windows 7

Windows 7

Mac OS X

Mac OS X


Dentro do mesmo ambiente há telas e configurações comuns a usuários iniciantes e avançados. Seu uso é confortável para ambas as personas. Isto se dá por conta das telas enxutas e organizadas, suficientemente didáticas e bem suportadas por tópicos de ajuda. Manter uma tela única e mutante para todos os itens do painel de controle também reduz consideravelmente a frustração caso o usuário se engane e abra um item que não contém o que ele procura (por exemplo, abrir ‘teclado’ ao invés de ‘idiomas/texto’ para trocar o layout de teclado). É simples voltar e usar outro item. Exceto em algumas poucas situações, não há ‘modo Avançado’ nas configurações normais. Itens mais específicos e que são procurados somente por usuários avançados estão fora das preferências do sistema, na forma de aplicativos da pasta Utilitários.

O Terminal

Taquigrafia ou estenografia (do grego taqui = rápido e grafia = escrita) é um termo geral que define todo método abreviado ou simbólico de escrita, com o objetivo de melhorar a velocidade da escrita ou a brevidade, em comparação a um método padrão de escrita. Fonte: Wikipedia

A comparação com a taquigrafia ou mesmo com LIBRAS é apenas uma brincadeira, mas não há nada mais eficiente, preciso e rápido para um usuário avançado do que o terminal: nenhuma interface ultra revolucionária ou esquema de janelas existente. Difícil competir com um ifconfig na hora de configurar uma rede, meia dúzia de arquivos de texto para configurar usuários, grupos e permissões e alguns scripts para algumas tarefas rotineiras. A distância entre pensamento e a execução é mínima. A linguagem e a dispersão são reduzidas ao máximo, enquanto o foco é total. A vantagem ainda é maior quando a necessidade é de executar tarefas repetidas ou estar no controle de várias máquinas ao mesmo tempo.

E então? Para tarefas muito especificas e avançadas uma interface não serve pra nada? Ela é apenas uma muleta for the rest of us? É quase uma pegadinha: O esquema WIMP talvez não seja a melhor maneira de se resolver a interface de determinados tipos de tarefa. Na verdade, talvez não seja a melhor maneira de resolver interface nenhuma – só não teriam inventado nada melhor ou nada que tivesse adoção por parte dos grandes players. Um exemplo semelhante é o teclado QWERTY vs. DVORAK. O terminal, por sua vez, é um tipo de interface, com todos os seus méritos, defeitos e especificidades.

$ love
-sh: love: not found
$ happiness
-sh: happiness: not found
$ peace
-sh: peace: not found
$ kill
-sh: you need to specify whom to kill

Artigos Relacionados:

  1. A explosão das formas de interação
  2. Livres das plataformas