Categorias
Introdução à Programação para Bioinformática com Perl

Laços de repetição

Capítulo 5

Este conteúdo faz parte do livro “Introdução à Programação para Bioinformática com Perl“. Você pode adquirir a versão impressa desse livro aqui ou a versão para Kindle aqui. Para nos citar, consulte este link.

Laços de repetição, também conhecidos como laços de iteração ou simplesmente loops, são comandos que permitem iteração de código, ou seja, que comandos presentes no bloco sejam repetidos diversas vezes. Através de laços de repetição é possível criar programas que percorram arrays, analisando individualmente cada elemento, e até mesmo criar trechos de código que sejam repetidos até que certa condição estabelecida seja cumprida.

Perl possui basicamente quatro tipos de laço de repetição: while, do… while, for e foreach.

While

O laço while (na tradução literal para a língua portuguesa “enquanto”) determina que enquanto uma determinada condição for válida, o bloco de código será executado. O laço while testa a condição antes de executar o código, assim sendo, caso a condição seja inválida no primeiro teste o bloco nem é executado.

# Contador $i
my $i = 0;

while($i < 10){
	print "$i "; # 0 1 2 3 4 5 6 7 8 9 
	$i++;
}

Aqui inserimos o conceito de contador. Um contador auxilia na determinação de quantas vezes um laço de iteração deve ser executado. Chamamos nosso contador de $i (“i” de iteração). Nesse exemplo, iniciamos nosso contador com valor zero, a seguir o laço while repete todo o bloco de código enquanto $i for menor do que 10. A cada iteração imprimimos o valor de $i e ao final do código incrementamos $i em um elemento. Assim, o código se repete até $i ser igual a 10. Uma vez que isso ocorre, o código é interrompido antes do bloco ser executado. Por isso é impresso de 0 a 9. Se a incrementação não for feita o programa ficará executando eternamente. Chamamos isso de loop infinito.

Do… while

O laço do… while (na tradução literal para a língua portuguesa “faça… enquanto”), assim como o laço while, determina que enquanto uma determinada condição for válida o bloco de código será executado. Entretanto, do… while testa a condição após executar o código, assim sendo, mesmo que a condição seja considerada inválida no primeiro teste o bloco será executado pelo menos uma vez.

# Contador $i
my $i = 0;

do{
	print "$i "; # 0 1 2 3 4 5 6 7 8 9
	$i++;
}while($i < 10);

For

O comando for (na tradução literal para a língua portuguesa “para”) permite que uma variável contadora seja testada e incrementada a cada iteração, sendo essas informações definidas na chamada do comando. O comando for recebe como entrada uma variável contadora, a condição e o valor de incrementação.

# Iteracao for
for(my $i = 0; $i < 10; $i++){
	print $i; # 0123456789
}

Uma outra forma de usarmos o laço for é declarando uma variável, seguida por dois valores da iteração (primeiro e último) entre parênteses separados por dois pontos finais. Perl incrementará o valor em um elemento a cada rodada.

Foreach

O comando foreach (na tradução literal para a língua portuguesa “para cada”), diferente do comando while, realiza iterações sobre coleções. Sendo assim, a cada “volta” do laço, a variável definida na chamada do foreach assume o valor de um dos elementos da coleção. A execução do comando é finalizada quando chega ao fim da coleção ou através de um comando de interrupção, como veremos em breve. 

my @aminoacidos = ("Alanina","Cisteina","Aspartato");
my $a;

foreach $a(@aminoacidos){
	print $a."\n";
}
# Alanina
# Cisteina
# Aspartato

O comando foreach recebe um array como parâmetro e aplica, a cada iteração, um elemento a uma variável pré-definida. Nesse exemplo, cada elemento do array @aminoacidos é aplicado a variável $a a cada repetição. O número de repetições depende da quantidade de elementos do array (no caso três).

Podemos ainda iterar sobre hashes usando foreach. Entretanto, é necessário um outro laço para percorrer arrays presentes dentro da hash. Veja:

my $chave;
my $i;
my %aminoacidos = (
	polares => ["Aspartato","Glutamato"],
	apolares => ["Alanina","Cisteina"]	
);	

foreach $chave(keys %aminoacidos){
	for $i( 0 .. $#{ $aminoacidos{$chave} }){
		print "chave: $chave\n";
		print "valor: $aminoacidos{$chave}[$i] \n\n";
	}
}
#chave: polares
#valor: Aspartato 
#chave: polares
#valor: Glutamato 
#chave: apolares
#valor: Alanina 
#chave: apolares
#valor: Cisteina

Observe que o laço foreach percorre a lista de chaves da hash %aminoacidos. Cada chave é armazenada em uma variável em “foreach $chave(keys %aminoacidos){”. Note que não será necessário percorrer os valores com um laço, uma vez que a própria chave é responsável por ser o índice de busca na hash.

Dentro da hash %aminoacidos existem valores que armazenam arrays. Assim sendo, é necessário que um novo laço percorra cada elemento do array. Para isso foi utilizado o laço for.

Observe que no trecho “for $a( 0 .. $#{ $aminoacidos{$chave} }){”, utilizamos uma nova forma para contar a quantidade de elementos dentro do array: “$#{ nome_de_um_array }”. Dessa forma, o laço for percorre de 0 até o tamanho do array, e armazena o valor na variável contadora $i.

A variável $i é utilizada como índice na linha “print “chave: $chave\nvalor: $aminoacidos{$chave}[$i] \n\n”;”. Observe que para imprimir um elemento dentro de um array gravado em uma hash é necessário declarar a hash com o caractere “$” seguido pela chave, que no caso estava armazenada na variável $chave, e por fim seguido por colchetes e pela variável contadora “[$i]”.

Observe que a primeira iteração é executada duas vezes: uma para cada chave (polares e apolares). Para cada iteração do primeiro for, há duas iterações em cada array (“Aspartato” e “Glutamato” para chave polares, e “Alanina” e “Cisteina” para a chave apolares). Assim, o comando print foi executado oito vezes (duas chaves vezes dois arrays vezes dois elementos em cada array).

Cláusulas last e next

Caso desejemos alterar o fluxo de execução de um laço de repetição, podemos utilizar a cláusula last, para interromper a execução, ou next, para prosseguir para a próxima iteração. Veja:

my $i;

for $i (1 .. 10){
	if($i > 5){
		last;
	}
	print $i; #12345
}

A cláusula last é o que mais se aproxima das cláusulas break presentes em outras linguagens, como Python por exemplo. O comando last define que aquela execução do laço é a última. Observe agora o comando last utilizado junto ao laço while.

my $i = 0;

while($i < 10){
	print $i; #012345
	$i++;
	if ($i > 5){ 
		last;
	}
}

A cláusula next prossegue para próxima execução do laço desprezando todos os comandos do bloco declarados abaixo. No exemplo a seguir usaremos um comando condicional if para verificar se o valor de $i é um numeral ímpar. Se for, o comando next salta para próxima execução do laço, desprezando o comando print logo abaixo, que imprimirá apenas os valores pares.

my $i = 0;

while($i < 10){
	$i++;
	if ($i % 2 == 1){ 
		next;
	}
	print $i; # 246810
}

Qual o melhor laço de repetição?

Laços de repetição devem ser utilizados de acordo com a ocasião. Recomendamos utilizar o laço while sempre que não soubermos a quantidade de vezes que o bloco se repetirá. O laço do… while pode ser utilizado no mesmo caso, entretanto do… while deve ser utilizado caso queremos que o código seja executado pelo menos uma vez. O laço for deve ser utilizado sempre que soubermos a quantidade exata de iterações que deverão ser feitas. O laço foreach deve ser utilizado para iterar sobre arrays.

Muitas vezes o uso de diferentes laços pode apresentar os mesmos resultados. Logo, o programador tem a liberdade de utilizar aquele que tiver maior confiança e facilidade.

Construindo uma calculadora usando laços de repetição

Nos capítulos anteriores aprendemos a utilizar operadores numéricos para construir uma calculadora. No exemplo a seguir, faremos algumas modificações no script criado anteriormente para que a calculadora faça mais do que uma operação. Para isso, vamos criar uma variável chamada $SAIR, inicialmente com o valor 0. Em seguida vamos inserir todo o resto do código dentro de um laço de repetição while, que repetirá o bloco enquanto $SAIR for igual a 0. Ao final do código enviaremos ao usuário uma mensagem perguntando se deseja fazer outro cálculo, ou se deseja encerrar o script. Caso o usuário deseje encerrar o script, a variável $SAIR recebe o valor 1, e o laço não se repetirá.

use warnings;
use strict;

# Calculadora
my $SAIR = 0;
my $num1;
my $num2;
my $operador;
my $operacao;
my $opcao;

while($SAIR == 0){
	print "CALCULADORA";
	print "\n\n";
	print "Digite o primeiro numero: ";
	chomp($num1 = <STDIN>);
	print "\n";
	print "Digite a operacao desejada: 
	1 para soma 
	2 para subracao 
	3 para divisao 
	4 para multiplicacao: ";
	chomp($operador = <STDIN>);
	print "\n";
	print "Digite o segundo numero: ";
	chomp($num2 = <STDIN>);

	# Determinando qual o operador foi utilizado
	if ($operador == 1){
		$operacao = $num1 + $num2;
	}
	elsif ($operador == 2){
		$operacao = $num1 - $num2;
	}
	elsif ($operador == 3){
		$operacao = $num1 / $num2;
	}
	elsif ($operador == 4){
		$operacao = $num1 * $num2;
	}
	else {
		system("clear"); 
#use system("cls") para S.O. Windows
		print "Operador invalido. Digite 1, 2, 3 ou 4. Tente novamente.\n\n§";
		next;
	}

	print "\n";
	print "Resultado: ";
	print $operacao;
	print "\n";

	# Questiona se o usuario deseja sair 
# ou fazer outra conta
	print "Deseja sair? (S/s) SIM ou (N/n) NAO: ";
	chomp($opcao = <STDIN>);

	if(($opcao eq "S")or($opcao eq "s")){
		$SAIR = 1;
	}

	system("clear"); #use system("cls") para S.O. Win-dows

}

Curiosamente utilizamos a função system para fazer a limpeza da tela. A função system permite que funções nativas do sistema operacional sejam executadas pelo Perl. No caso, usamos system para executar o comando “clear”, que em sistemas operacionais Linux e Mac limpa a tela. Caso utilize sistema operacional Windows, utilize o comando “cls”.

Quer aprender mais? Conheça nossos cursos profissionalizantes à partir de R$19,99:

Nota do autor
Prefácio

Capítulo 1
Introdução ao Perl

Capítulo 2
Comandos condicionais

Capítulo 3
Strings

Capítulo 4
Arrays

Capítulo 5
Laços de repetição

Capítulo 6
Manipulando arquivos

Capítulo 7
Sub-rotinas

Capítulo 8
“O guia de sobrevivência para expressões regulares em Perl”

Capítulo 9
Introdução ao BioPerl

Capítulo 10
Sequências

Capítulo 11
BLAST

Capítulo 12
Estruturas de proteínas

Capítulo 13
Hierarquia do BioPerl

Epílogo
Referências bibliográficas
Sobre os autores

Por favor, nos cite:

MARIANO, DIEGO CÉSAR BATISTA; de MELO-MINARDI, R. C. . Introdução à Programação para Bioinformática com Perl. 1. ed. North Charleston, SC (EUA): CreateSpace Independent Publishing Platform, 2016. v. 2. 200p .

Por Diego Mariano

Doutor em Bioinformática pela Universidade Federal de Minas Gerais com atuação na área de ciência de dados e aprendizado de máquina aplicados ao aperfeiçoamento de enzimas usadas na produção de biocombustíveis. Mestre em Bioinformática, também pela UFMG, atuando na área de desenvolvimento de sistemas Web para montagem de genomas. Atualmente realiza estágio pós-doutoral no Departamento de Ciência da Computação da UFMG com foco em desenvolvimento de sistemas Web para Bioinformática, análise exploratória e visualização de dados. Tem conhecimentos nas linguagens: PHP, JavaScript, Python, R, Perl, HTML, CSS e SQL.