Prosseguindo à parte mais teórica dos posts, loops são bastante usados em programação para realizar tarefas repetitivas, para iterar entre elementos. Iteração é a capacidade de rodar uma expressão repetidas vezes.
Em Python, temos duas principais formas de realizar um loop que são por meio das estruturas "for" e "while".
Imaginem uma lista de alunos de uma sala de aula. Precisamos criar um programa que faz a chamada desses alunos:
lista_de_alunos = [aluno1, aluno2, aluno3, aluno4, aluno5, aluno6...aluno35]
print(aluno1)
print(aluno2)
print(aluno3)
print(aluno4)
print(aluno5)
...
print(aluno35)
Bastante sacal chamar os alunos de um por um. Podemos usar um laço para resolver esse problema pra gente. Começando pelo laço for:
O equivalente em português para a estrutura de um "for loop" seria algo como:
lista_de_alunos = ['Alberto', 'Bernardo', 'Carla', 'Deniro']
para cada aluno na lista_de_alunos:
chame o nome do aluno
Acima, temos uma lista de alunos, que é um elemento iterável em programação. Iteráveis são estruturas que podem ser percorridas elemento a elemento. No nosso caso acima, chamamos os alunos, um por um, e fizemos a chamada dos nomes deles.
Em Python, a estrutura acima fica assim:
for aluno in lista_de_alunos:
print(aluno)
Basicamente a mesma estrutura, mas em inglês. Chamamos cada aluno por meio da variável "aluno" e printamos o seu nome na tela. Então, um programa que teria a quantidade de linhas igual à quantidade de alunos mais uma linha para a lista de alunos, resumimos o programa para duas linhas.
Dessa forma, podemos fazer o que quisermos com cada elemento da lista. Mas para sair da abstração e vindo mais para o mundo real, lembram do tópico de redimensionamento de imagens? O processamento de várias imagens foi feito uma a uma por meio de um for loop:
for image in files:
img = Image.open(image)
width, height = img.size
new_width, new_height = width/2, height/2
img = img.resize((round(new_width), round(new_height)), Image.ANTIALIAS)
img.save(image, format='png')
Ou no tópico passado, onde criamos a respeitável Blastter.com:
# Aqui a sintaxe muda um pouco pois estamos inserindo um código Python dentro de uma página HTML usando a sintaxe de um framework e não a do Python em si, mas a ideia é a mesma
{% for acao in carteira %}
<p>{{ acao }}</p>
{% endfor %}
Portanto, laços for são bastante úteis para realizarmos tarefas repetitivas.
Além do "for", podemos usar o equivalente em inglês à palavra "enquanto", que seria o laço "while".
Laços "while" são mais usados quando há uma condição específica de parada. Voltando ao nosso exemplo dos alunos:
lista_de_alunos = [aluno1, aluno2, aluno3, aluno4, aluno5, aluno6...aluno35]
enquanto houver alunos na lista de chamada:
chame o nome do aluno
Transcrevendo pra código Python:
lista_de_alunos = ['Aline', 'Berenice', 'Cirineu', 'Diolinda', 'Egberto']
quantidade_alunos = len(lista_de_alunos) # relembrando o len(), ele retorna a quantidade de itens de um iterável
n = 0
while n < quantidade_alunos:
print(lista_de_alunos[n])
n += 1
Resultado:
Aline
Berenice
Cirineu
Diolinda
Egberto
Explicando em miúdos:
n é uma variável inteira que foi inicializada com o valor 0.
O interpretador avaliou a expressão
while n < quantidade_alunos:
Ora, 0 é menor que a quantidade de alunos, que é 5. Então essa expressão (n < quantidade_alunos) retorna um booleano True. Já que a expressão é verdade, o bloco de código abaixo é executado, então temos printado na tela o aluno do índice "n", no caso 0 (lista_de_alunos[0] == 'Aline') e somamos um à variável "n". Fim do bloco de código, o interpretador avalia novamente a expressão "while". Agora temos que n == 1, e 1 < 5, então o bloco de código é executado até a condição não ser mais verdade.
Caso não adicionemos a soma de mais um à variável n, teremos problemas em nosso código:
lista_de_alunos = ['Aline', 'Berenice', 'Cirineu', 'Diolinda', 'Egberto']
quantidade_alunos = len(lista_de_alunos) # relembrando o len(), ele retorna a quantidade de itens de um iterável
n = 0
while n < quantidade_alunos:
print(lista_de_alunos[n])
# Omitindo a soma de n += 1
Resultado:
Aline
Aline
Aline
Aline
Aline
Aline
Aline
Aline
Aline
Aline
Aline
Aline
Aline
Aline
...
Aline
Aline
Traceback (most recent call last):
File "c:/.../teste.py", line 5, in <module>
print(lista_de_alunos[n])
KeyboardInterrupt
Ou seja, meu programa imprimiu o aluno da primeira posição indefinidas vezes. Criamos um loop eterno, um loop que nunca pode ser interrompido, a não ser que interrompamos fechando o programa, que foi o que eu fiz criando a exceção KeyboardInterrupt.
Laços while também podem ser interrompidos por meio da palavra reservada break:
x = 30
while x != 0:
print(x)
x -= 1
if x == 15:
break
print('Decidi interromper o programa pela metade')
Resultado:
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
Decidi interromper o programa pela metade
O break também pode ser usado em um "for loop".
O while é mais usados quando a condição de parada é variável. Num programa que criei no trabalho, que recebe dados de um aparelho, criei um laço while para receber dados enquanto o aparelho estiver funcionando. Quando o usuário dá STOP no aparelho, o laço é quebrado. Não vou explicar o código, foi mais pra exemplificar a utilidade de um laço while:
while True:
try:
object = serial_object_creator(time)
time = timer_for_closing_port(object)
if torque_validator(object):
if not object:
print('Torque máximo atingido ou erro no aparelho')
else:
readings_printer(object)
registers = values_storager(object)
else:
final_menu()
except KeyboardInterrupt:
print('Programa interrompido por atalho de teclado')
break
except IndexError: # This exception finishes the loop.
print('Foi pressionado ' + Fore.RED + 'STOP'
+ Style.RESET_ALL + ' no aparelho')
registers = dict(OrderedDict(sorted(registers.items())))
break
Caso alguém tenha curiosidade em ver o código completo:
https://github.com/ThiagoDiasV/Viscotester/Podemos usar também por exemplo no caso do desafio passado, o de criar um jogo de pedra papel ou tesoura. Criamos um loop while infinito e adicionamos ao final do jogo uma pergunta para o usuário para ele responder se quer continuar jogando. O laço while só é interrompido quando o usuário não quer mais jogar:
# ...
# Lógica do jogo pedra, papel ou tesoura
while True:
# Jogo
pergunta = input('Você quer continuar jogando?')
if pergunta == 'não':
break