quinta-feira, 8 de janeiro de 2009

Controle de Fluxo

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!

8 comentários:

Anônimo disse...

gostaria de parabeniza-lo pela iniciativa. muito bom mesmo!

obrigado!

isac jonatas.

Eduardo Rolim disse...

Excelente iniciativa !!!

Estevam disse...

Muito interessante, estou acompanhando e apesar de saber um pouco de programação estou achnado muito imteressantes os recursos do python.

Ricardo Pontes disse...
Este comentário foi removido pelo autor.
Anônimo disse...

Olá João Paulo,

Boa iniciativa!! Já trabalho com programação há um bom tempo, contudo, gosto de acompanhar iniciativas como esta pela internet, aproveitando para dar meus centavos de contribuição e claro, sempre me reciclar! Tenho uma observação e uma sugestão: nos primeiros posts você deixa uma mensagem que leva a entender que seu curso será voltado para pessoas que nunca tiveram contato com programação ( você explica o que é programação, por ex. ), contudo, os posts subsequentes apresentam "resumos" de uma quantidade de informação relativamente grande para leigos, o que acredito que para quem nunca programou fique um pouco difícil acompanhar o raciocínio. A minha sugestão é que ou "mude o foco" de seu blog, informando que o curso será voltado para quem já conhece um pouco de programação e deseja aprender uma nova linguagem, ou que dê um pouco mais de detalhes e caminhe um pouco mais devagar com o conteúdo! É apenas minha sugestão, caso ache pertinente, fico feliz em poder ajudar, caso contrário, viva a democracia :D rss! Só não pense que estou invalidando sua iniciativa, muito pelo contrário! :D

Parabéns mais uma vez por dedicar seu tempo para todos!

att,
Tiago

Rodrigo disse...

Seguindo a lista de parabenizações, deixo as minhas e também um pedido: já que o objetivo é mostrar a programação em Python para leigos, que tal um post sobre lógica, com problemas comuns em programação?
Ótima iniciativa. Sucesso ao blog, e que ele possa ajudar a todos nós.
[ ]s

João Paulo Farias disse...

Opa!

Fico feliz de ver que o pessoal tem gostado do blog. Para o Tiago e o Rodrigo: minha ideia é sim apresentar um tutorial para iniciantes em programação. Talvez eu tenha realmente entrado em assuntos que possa ter deixado os realmente iniciantes um tanto confusos, mas como mostro como as coisas funcionam, espero que estes entendam.

Vou tentar propor alguns problemas de lógica e ver como o pessoal reage.

No mais, obrigado a todos pelo incentivo.

Anônimo disse...

Mais postagens!!!!!!!!! pleaseeee!!!!