Depois das festas de Natal e Ano Novo, é hora de voltar ao trabalho!
Hoje vou escrever um pouco sobre o controle de fluxo. Para os leigos, o controle de fluxo consiste em dar uma sequência lógica ao programa, incluindo aí repetições de uma sequência de comandos e a chamada de funções para auxiliar na realização de uma tarefa.
Vou dar um exemplo simples: a sequência de Fibonacci.
Para os que ainda não a conhecem, tal sequência consiste em somar os dois números anteriores da sequência para obter o próximo valor. Os dois primeiros valores da sequência são 1 e 1. Sendo assim, a sequência segue como mostrado a seguir:
1, 1, 2, 3, 5, 8, 13, 21, ....
Como poderíamos escrever um programa que mostra os 10 primeiros números da sequência de Fibonacci? Temos algumas opções. A primeira seria calcularmos de cabeça os números e apenas imprimí-los:
>>> fibonacci = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> print 'Os 10 primeiros números da sequência de Fibonacci são:', fibonacci
É uma solução bem simples, mas também muito limitada. O que acontece se agora desejarmos mostrar os 100 primeiros números da sequência? E os 1000 primeiros? Ficaria algo impraticável utilizando este método. Para resolver situações como esta existem os chamados "loops" na programação. Em python existem basicamente 2 tipos de "loops": os "while" e os "for". Vamos ver como poderíamos escrever os 100 primeiros números de fibonacci utilizando primeiramente um "while" e em seguida um "for":
>>> a = 1
>>> b = 1
>>> print "Os 100 primeiros números de Fibonacci são:", a, b
>>> num = 2
>>> while num < 100:
... num += 1
... print a + b,
... a, b = b, a + b
...
Deixe-me explicar o que ocorre no trecho de código acima, linha a linha:
a = 1
Primeiro número da sequência de Fibonacci
b = 1
Segundo número da sequência
print 'Os... são:', a, b
Imprime a string inicial e em seguida os 2 primeiros números, armazenados nas variáveis "a" e "b". Note que, ao separarmos os valores a serem impressos com uma vírgula, estes serão impressos na mesma linha.
num = 2
Como já mostramos os 2 primeiros números, inicializamos esta variável com o valor 2, indicando que temos mais 98 números a exibir.
while num < 100:
Aqui está o comando de controle da repetição. A sequência de comandos abaixo será executada enquanto o valor armazenado na variável "num" seja menor que 100. Outro fator que devemos levar em consideração é qual a sequência de comandos que será repetida. Na linguagem Python, este bloco de comandos será indicado pela identação do código, ou seja, pelo número de espaços em branco antes do primeiro caractere. Note também que, após digitar a linha com o comando "while" e pressionar a tecla "enter" o interpretador mostrará uma linha com "...", indicando que ele espera por um bloco de código. Assim sendo, para digitar o bloco de código que será repetido no loop, pressione a tecla "tab" no começo de cada linha, indicando a identação exigida para o bloco.
num += 1
Aqui nós incrementamos o valor da variável "num" em 1. Este comando produz o mesmo efeito que o comando: "num = num + 1". Note que o sinal de igual aqui informa atribuição e não a comparação de valores. Sendo assim, tal comando poderia ser traduzido para o Português como: atribua a variável "num" o valor da variável "num" acrescido do valor 1. Esta linha é importante pois sem ela nós estaríamos entrando num "loop infinito", mas isto eu vou explicar mais à frente.
print a + b,
Nesta linha nós exibimos o próximo valor da sequência, que nada mais é que a soma dos dois valores anteriores, armazenados nas variáveis "a" e "b".
a, b = b, a + b
Esta linha é o coração do algoritmo. E mostra também uma das vantagens da linguagem Python. Neste caso estamos efetuando duas atribuições em um único comando, e evitando o uso de uma variável temporária para a troca de valores. O que ocorre é que, do lado esquerdo do sinal de atribuição temos as variáveis que receberão os valores, os quais são calculados do lado direito da atribuição. sendo assim, a variável "a" receberá o valor da variável "b", e a variável "b" receberá o valor resultado da soma das variáveis "a" e "b". Para o leitor que já não é programador eu espero duas reações distintas para este comando. Ou você irá entender de cara que a operação faz todo o sentido ou ficará perdido sem saber o que realmente está acontecendo...
Deixe-me explicar de outra forma. O que o ocorre no fim das contas é que a operação será efetuada em duas etapas. Na primeira etapa, os valores do lado direito da atribuição são calculados. Numa segunda etapa a atribuição e efetivada. Sendo assim, na primeira iteração do loop, quando os valores de "a" e "b" são 1, teremos a seguinte sequência:
a, b = b, a + b
a, b = 1, 1 + 1
a, b = 1, 2
a = 1
b = 2
Perceba, então, que ao final da iteração teremos o valor do 2º termo da sequência armazenado na variável "a" e o valor do 3º termo armazenado na variável "b", possibilitando o cálculo do 4º termo na próxima iteração do loop. Se você ainda está em dúvida quanto ao funcionamento desta atribuição, podemos rescrevê-la da seguinte forma:
c = a + b
a = b
b = c
Para uns a primeira forma, com as duas atribuições numa só linha fará mais sentido, e para outros a segunda forma, com a utilização de uma terceira variável para armazenar o valor do próximo termo temporariamente é mais clara. Eu pessoalmente prefiro a primeira forma, numa única linha.
Bom, e como ficaria o código utilizando um "for" ao invés de um "while"? Para responder esta pergunta primeiro tenho que explicar como funciona o "for" na linguagem Python. E a solução não poderia ser mais simples: o comando "for" consiste em efetuar um "loop" sobre uma sequência de elementos de uma lista ou tupla. Ou seja, a variável do "loop" assumirá, a cada iteração, o próximo valor da lista. Vejamos como ficaria então o código:
>>> a = 1
>>> b = 1
>>> print "Os 100 primeiros números de Fibonacci são:", a, b
>>> for k in range(98):
... print a + b,
... a, b = b, a + b
...
Perceba que o código é praticamente o mesmo. Apenas o "while" foi substituído pelo "for". Note ainda que não precisamos mais da linha "num += 1", pois o controle do loop é automático no "for". Outro fator que chama atenção é a utilização da função "range()". Esta função consiste simplesmente em construir uma lista, cujos valores serão os números inteiros a partir do zero até o valor passado como parâmetro menos 1:
>>> print range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Ou seja, range(98) resulta em uma lista com os valores 0, 1, 2, ..., 97. A lista terá então 98 elementos. Outro fator que devemos ressaltar é que, apesar de não termos utilizado a variável "k" no código, ela irá assumir, a cada iteração do loop o valor associado na lista retornada pela função "range()", ou seja, na primeira iteração ela terá o valor 0, na segunda iteração terá o valor 1, e assim por diante, até que na última iteração ela terá o valor 97. O loop "for" termina quando se esgotarem os elementos da lista a ser percorrida.
É isso! Espero que vocês tenham entendido o funcionamento das estruturas "while" e "for" para a repetição de blocos de comandos. Até o próximo post!