Capítulo 4 — Estruturas de repetição
Você já imaginou tentar desenhar um polígono com 36 lados usando o Turtle, sem poder repetir nada? Teria que escrever o mesmo código t.forward() e t.left() trinta e seis vezes! Isso seria gigantesco, cansativo e impossível de manter. E se depois você quisesse desenhar um com 50 lados? Começaria tudo novamente?
Bem, existe um jeito bem melhor de fazer isso: estruturas de repetição (ou laços). Elas permitem que você execute o mesmo bloco de código várias vezes, mudando apenas o que precisa mudar. É como dizer ao Python: "faz isso 36 vezes, cada vez com um valor diferente para a variável de controle". E de repente, uma tarefa impossível fica super viável.
Neste capítulo, vamos aprender as duas estruturas de repetição mais usadas: o for (quando você sabe quantas vezes vai repetir) e o while (quando você repete até uma condição mudar). Vamos também ver como controlar melhor o que acontece dentro do laço com break e continue. Bora?
1. Por que repetir? Motivação
O problema
Imagine que você quer desenhar um polígono regular de 36 lados. Cada lado mede 100 pixels. Para um polígono regular, cada ângulo externo é 360 / 36 = 10 graus. Então o padrão é sempre o mesmo:
t.forward(100)
t.left(10)
Repetir isso 36 vezes sem um laço? Veja só:
# VAMOS MORRER ESCREVENDO ISSO
import turtle
t = turtle.Turtle()
t.forward(100)
t.left(10)
t.forward(100)
t.left(10)
t.forward(100)
t.left(10)
# ... (mais 33 vezes!)
# ... (total de 72 linhas!)
turtle.done()
Eca! Qual é a chance de não cometer erros copiando isso 36 vezes? Zero.
A solução
Com um laço for, você faz assim:
import turtle
t = turtle.Turtle()
for i in range(36):
t.forward(100)
t.left(10)
turtle.done()
Pronto! Apenas 4 linhas. O computador encarrega-se de repetir as instruções 36 vezes. Muito melhor, não é?
2. Fluxogramas com repetição
Antes de aprender a sintaxe do for e while, vamos ver como representar loops em fluxogramas. É importante entender o que está acontecendo, não só como escrever.
Símbolo de repetição
Em um fluxograma, a repetição é representada por um losango especial (parecido com o que usamos para decisões, mas com interpretação diferente). A seta sai do losango e volta para cima, formando um círculo — isso mostra que o código vai repetir.
Exemplo: contar de 1 a 10
Aqui está um fluxograma de um programa que conta de 1 a 10:
flowchart TD
A([Início]) --> B[i = 1]
B --> C{i <= 10?}
C -->|Não| D[/Exiba: Fim/]
C -->|Sim| E[/Exiba: i/]
E --> F[i = i + 1]
F --> C
D --> G([Fim])
Vamos rastrear esse fluxograma:
- Começamos com
i = 1 - Perguntamos: "i é menor ou igual a 10?"
- Se sim, exibimos o valor de
ie incrementamosi - Voltamos para a pergunta
- Se não, exibimos "Fim" e terminamos
A seta que sai do "não" vai direto para o fim, enquanto o "sim" continua fazendo as ações e volta para a pergunta. É exatamente assim que um while funciona!
3. O laço for
O for é usado quando você sabe de antemão quantas vezes vai repetir. Ele é controlado por uma variável (geralmente chamada i) que muda a cada iteração. Vamos começar com a sintaxe e depois explorar todos os seus usos.
Sintaxe básica do for com range()
for variável in range(n):
# código que será repetido n vezes
O range(n) é uma função que gera uma sequência de números de 0 até n-1. Quando você escreve for i in range(5), o Python:
- Cria a variável
ie a faz valer 0 → executa o bloco - Muda
ipara 1 → executa o bloco de novo - Muda
ipara 2 → executa o bloco de novo - Muda
ipara 3 → executa o bloco de novo - Muda
ipara 4 → executa o bloco de novo - Termina (porque 5 não está no range de 0 a 4)
Vamos ver isso na prática:
for i in range(5):
print(f"Contagem: {i}")
Saída:
Contagem: 0
Contagem: 1
Contagem: 2
Contagem: 3
Contagem: 4
Repare que começou em zero, não em 1! Essa é uma convenção de programação — vamos falar mais sobre isso daqui a pouco.
As três formas do range()
O range() tem três formas diferentes, cada uma útil para uma situação:
Forma 1: range(n) — começa em 0 e vai até n-1
for i in range(3):
print(i)
# Saída: 0, 1, 2
Forma 2: range(inicio, fim) — começa em inicio e vai até fim-1
for i in range(5, 10):
print(i)
# Saída: 5, 6, 7, 8, 9
Forma 3: range(inicio, fim, passo) — começa em inicio, vai até fim-1, mas pulando de passo em passo
for i in range(0, 10, 2):
print(i)
# Saída: 0, 2, 4, 6, 8
for i in range(10, 0, -1):
print(i)
# Saída: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
Repare que com passo negativo (-1), conseguimos fazer contagem regressiva!
Nota para o professor: muitos alunos estranham começar em 0. Isso é uma convenção de praticamente todas as linguagens de programação modernas, e é importante que os alunos se acostumem. Pode ajudar explicar que é como indexação de arrays — a primeira posição é 0, a segunda é 1, etc.
Exemplo 1: Tabuada
Vamos criar um programa que exiba a tabuada de um número:
numero = int(input("Digite um número para a tabuada: "))
print(f"\nTabuada de {numero}:")
for i in range(1, 11):
resultado = numero * i
print(f"{numero} × {i} = {resultado}")
Se o usuário digitar 7, a saída será:
Tabuada de 7:
7 × 1 = 7
7 × 2 = 14
7 × 3 = 21
7 × 4 = 28
7 × 5 = 35
7 × 6 = 42
7 × 7 = 49
7 × 8 = 56
7 × 9 = 63
7 × 10 = 70
Repare que usamos range(1, 11) para começar em 1 e ir até 10. Se usássemos range(10), começaria em 0 e a tabuada mostraria 7 × 0 = 0, que é chato.
Exemplo 2: Contagem regressiva
print("Contagem para o foguete:")
for i in range(10, 0, -1):
print(i)
print("Decolagem! 🚀")
Saída:
Contagem para o foguete:
10
9
8
7
6
5
4
3
2
1
Decolagem! 🚀
A linha print("Decolagem!") está fora do for (sem indentação extra), então só executa uma vez, ao final do laço.
Iterando sobre strings (introdução)
Aqui está algo bacana: você também pode usar for para percorrer os caracteres de uma string!
palavra = "Python"
for letra in palavra:
print(letra)
Saída:
P
y
t
h
o
n
O for vai pegando cada letra uma por uma. Essa técnica é super útil para analisar textos caractere por caractere. Vamos explorar isso melhor no Capítulo 6 (Listas e strings), mas é bom saber que dá para fazer desde agora.
4. O laço while
O while (que significa "enquanto") é um pouco diferente do for. Você o usa quando não sabe exatamente quantas vezes vai repetir, mas tem uma condição que deve ser verdadeira para continuar repetindo.
Sintaxe
while condição:
# código que será repetido enquanto a condição for True
A lógica é: "enquanto a condição for verdadeira, faz isso. Quando a condição virar falsa, sai do laço."
Exemplo 1: Contar até 5
Vamos comparar for e while fazendo a mesma coisa:
# Com for (você sabe exatamente quantas vezes)
for i in range(5):
print(i)
# Com while (você testa uma condição a cada volta)
i = 0
while i < 5:
print(i)
i = i + 1
As duas formas produzem a mesma saída. Mas note que com while, você precisa:
- Criar a variável
iantes do laço - Incrementar
identro do laço (senão fica infinito!) - Testar uma condição que, em algum momento, vai virar falsa
Cuidado: Laços infinitos!
Este é o erro mais fácil de cometer com while:
# PERIGO! Isso é um laço infinito!
i = 0
while i < 5:
print("Oi")
# Oops, esqueci de incrementar i!
# i nunca vai aumentar, então i < 5 é sempre True
Se você rodasse isso, o programa ficaria imprimindo "Oi" para sempre até você apertar Ctrl+C para parar. A condição i < 5 nunca vira falsa porque i não muda!
Por isso, sempre lembre-se de mudar a variável que controla o while dentro do laço.
Exemplo 2: Menu que repete até o usuário digitar "sair"
Aqui está um uso clássico de while — um menu que fica repetindo até o usuário escolher sair:
comando = ""
while comando != "sair":
print("\n=== Menu ===")
print("1. Somar dois números")
print("2. Multiplicar dois números")
print("3. Sair")
comando = input("\nO que você quer fazer? ").lower()
if comando == "1" or comando == "somar":
a = int(input("Primeiro número: "))
b = int(input("Segundo número: "))
print(f"Resultado: {a + b}")
elif comando == "2" or comando == "multiplicar":
a = int(input("Primeiro número: "))
b = int(input("Segundo número: "))
print(f"Resultado: {a * b}")
elif comando == "3" or comando == "sair":
print("Até logo!")
else:
print("Comando não entendi. Tente novamente.")
Vamos rastrear como isso funciona:
comandocomeça vazio- Entra no
while(porque"" != "sair"é verdadeiro) - Exibe o menu e pede entrada
- Se o usuário digitar "somar", executa a soma
- Volta ao início do
while - Pergunta outra vez
- Se o usuário digitar "sair", a condição
comando != "sair"vira falsa - Sai do laço
O while é ideal aqui porque não sabemos quantas vezes o usuário vai pedir uma operação — pode ser 1 vez, pode ser 100 vezes.
5. Controle de laço: break e continue
Às vezes você quer sair do laço antes da hora ou pular uma iteração e ir direto para a próxima. Para isso, existem break e continue.
break: Saindo do laço
O break interrompe o laço imediatamente e continua o programa depois do laço. Muito útil quando encontra uma condição especial.
for i in range(10):
if i == 5:
print("Encontrei o 5! Saindo...")
break
print(i)
print("Laço terminado!")
Saída:
0
1
2
3
4
Encontrei o 5! Saindo...
Laço terminado!
Repare que não imprimiu 5, 6, 7, 8, 9. O break interrompeu o laço no momento que i == 5.
continue: Pulando para a próxima iteração
O continue pula o resto do bloco do laço naquela iteração e vai direto para a próxima.
for i in range(10):
if i == 5:
print(f"Pulando o número {i}...")
continue
print(i)
print("Laço terminado!")
Saída:
0
1
2
3
4
Pulando o número 5...
6
7
8
9
Laço terminado!
Desta vez, o 5 foi pulado — mas o laço continuou com 6, 7, 8, 9. Nenhum código depois do continue (naquele laço) foi executado para i = 5, mas o laço não parou por completo.
Exemplo prático: Validar entrada até conseguir um número válido
while True: # laço que rodaria infinitamente...
entrada = input("Digite um número positivo: ")
try:
numero = int(entrada)
if numero <= 0:
print("O número precisa ser positivo!")
continue # volta para o input
print(f"Obrigado! Você digitou {numero}")
break # sai do laço
except ValueError:
print("Isso não é um número! Tente novamente.")
continue
Este código usa while True (um laço que seria infinito sem break) e sai só quando recebe um número positivo válido. O continue faz voltar para o input quando há erro, e o break faz sair quando tudo está certo.
Nota: neste exemplo, usamos
tryeexcept, que é tratamento de erros. Não vamos detalhar isso agora (é para capítulos mais adiante), mas é bom saber que existe. Para agora, use simples verificações comif.
6. Acumuladores e contadores
Dois padrões muito comuns em laços são somar valores (acumulador) e contar quantas vezes algo acontece (contador). Vamos ver os dois.
Padrão 1: Acumulador (somando valores)
soma = 0
for i in range(1, 6): # i vai de 1 a 5
soma = soma + i
print(f"Soma de 1 a 5: {soma}")
Saída:
Soma de 1 a 5: 15
Vamos rastrear:
Antes do laço: soma = 0
i = 1: soma = 0 + 1 = 1
i = 2: soma = 1 + 2 = 3
i = 3: soma = 3 + 3 = 6
i = 4: soma = 6 + 4 = 10
i = 5: soma = 10 + 5 = 15
Fim do laço: soma = 15
A variável soma acumula valores ao longo do laço. É por isso que ela começa em 0 (a identidade da adição) e vai sendo incrementada.
Padrão 2: Contador (contando ocorrências)
contador = 0
numeros = [3, 7, 3, 9, 3, 2, 3] # vamos aprender listas no cap 6
for numero in numeros:
if numero == 3:
contador = contador + 1
print(f"O número 3 aparece {contador} vezes")
Saída:
O número 3 aparece 4 vezes
Aqui, o contador começa em 0 e aumenta 1 a cada vez que encontramos o número 3. Note que não somamos o número em si — apenas contamos ocorrências.
Exemplo: Calculadora que soma múltiplos números
soma = 0
quantidade = 0
print("Digite números (digite -1 para parar):")
while True:
numero = int(input("Número: "))
if numero == -1:
break
soma = soma + numero
quantidade = quantidade + 1
if quantidade > 0:
media = soma / quantidade
print(f"\nVocê digitou {quantidade} números")
print(f"Soma: {soma}")
print(f"Média: {media:.2f}")
else:
print("Você não digitou nenhum número!")
Se o usuário digitar: 10, 20, 30, -1
Saída:
Você digitou 3 números
Soma: 60
Média: 20.00
Neste programa, usamos tanto acumulador (soma) quanto contador (quantidade). Depois, calculamos a média dividindo a soma pela quantidade.
7. Prática com Turtle e repetição
Agora vamos juntar laços com o Turtle para criar desenhos bacanas! O professor vai demonstrar cada um dos exemplos a seguir.
7.1. Polígono regular de N lados
Este programa pergunta ao usuário quantos lados quer e desenha o polígono:
import turtle
t = turtle.Turtle()
t.speed(10)
numero_lados = int(input("Quantos lados o polígono tem? "))
angulo_externo = 360 / numero_lados
for i in range(numero_lados):
t.forward(100)
t.left(angulo_externo)
turtle.done()
Teste com 3 (triângulo), 4 (quadrado), 6 (hexágono), 8 (octógono). A beleza aqui é que o código é sempre o mesmo — muda só o número de lados!
7.2. Espiral quadrada
Este cria uma espiral aumentando o comprimento a cada lado:
import turtle
t = turtle.Turtle()
t.speed(10)
distancia = 10
for i in range(50):
t.forward(distancia)
t.left(90)
distancia = distancia + 5
turtle.done()
A variável distancia começa pequena e aumenta a cada volta. Depois do primeiro lado, aumenta 5; depois do segundo, aumenta mais 5; e assim vai, criando uma espiral.
7.3. Estrela de 5 pontas
import turtle
t = turtle.Turtle()
t.speed(10)
for i in range(5):
t.forward(200)
t.right(144) # ângulo externo de uma estrela de 5 pontas
turtle.done()
Quando você desenha uma estrela de 5 pontas, a tartaruga vira 144° a cada ponta. Isso é uma propriedade matemática das estrelas!
7.4. Mosaico de formas: laços aninhados
Às vezes você quer um laço dentro de outro laço. Aqui vamos desenhar 3 linhas de 3 quadrados cada:
import turtle
t = turtle.Turtle()
t.speed(5)
for linha in range(3):
for coluna in range(3):
# Desenha um quadrado
for lado in range(4):
t.forward(50)
t.left(90)
# Move para o próximo quadrado na mesma linha
t.penup()
t.forward(60)
t.pendown()
# Move para a próxima linha
t.penup()
t.backward(60 * 3) # volta ao início da linha
t.left(90)
t.forward(60)
t.right(90)
t.pendown()
turtle.done()
Este exemplo tem laços aninhados (um dentro do outro). O laço de fora controla as linhas, o do meio controla as colunas, e o de dentro desenha cada quadrado. Essa é uma técnica poderosa para criar grades e padrões!
7.5. Círculos concêntricos com cores alternadas
import turtle
t = turtle.Turtle()
t.speed(0)
cores = ["red", "blue", "green", "yellow", "purple"]
raio = 150
for i in range(5):
t.color(cores[i])
t.circle(raio)
raio = raio - 30
turtle.done()
Aqui usamos cores[i] para pegar cores de uma lista. Não vamos aprender listas até o cap 6, mas neste caso é bem intuitivo: cores[0] é "red", cores[1] é "blue", etc. A cada volta, mudamos de cor e diminuímos o raio.
8. Exercícios
Agora é praticar! Leia cada exercício com cuidado e tente fazer sozinho. Se travar, releia o capítulo ou desenhe um fluxograma para entender melhor o que está acontecendo.
a) Escreva um programa que peça um número ao usuário e exiba a tabuada desse número de 1 a 10. Use for e range().
b) Crie um programa que calcule o fatorial de um número. O fatorial de 5 é 5 × 4 × 3 × 2 × 1 = 120. Use um acumulador (como a soma, mas multiplicando). Leia o número do usuário e use for.
c) Com o Turtle, peça ao usuário para digitar quantos lados quer num polígono regular (entre 3 e 12). Desenhe o polígono. Dica: lembre-se de calcular o ângulo externo como 360 / número_de_lados.
d) Escreva um programa que funcione como um menu: exiba as opções (somar, subtrair, multiplicar, sair) e repita enquanto o usuário não escolher "sair". Use while para isso.
e) Crie um programa que peça números ao usuário até ele digitar -1. Ao final, exiba: quantidade de números digitados, soma de todos eles e média. Use while, acumulador e contador.
f) Com o Turtle, desenhe uma espiral circular: comece com um círculo pequeno e vá aumentando o raio a cada volta. Use for para repetir e aumente o raio a cada iteração.
g) Implemente o jogo FizzBuzz simplificado: imprima os números de 1 a 30, mas: quando é múltiplo de 3, escreva "Fizz" em vez do número; quando é múltiplo de 5, escreva "Buzz"; quando é múltiplo de ambos, escreva "FizzBuzz". Use o operador % para verificar resto.
h) Com o Turtle, desenhe uma fileira de 5 triângulos coloridos. Use um laço for para repetir 5 vezes: desenhe um triângulo, mude para uma cor aleatória (ou de uma lista pré-definida), e mova para a direita.
i) Crie um jogo de adivinhação: o computador escolhe um número entre 1 e 50, o usuário tenta adivinhar, e tem até 10 tentativas. A cada tentativa errada, diga se o número secreto é maior ou menor que o palpite. Conte as tentativas com uma variável. Use while.
j) Com o Turtle, desenhe um grid 4×4 de quadrados, como um tabuleiro de xadrez. Use laços aninhados: o de fora para as linhas, o de dentro para as colunas. Cada quadrado tem 30 pixels de lado.
9. Desafio de capítulo: Jogo de adivinhação com feedback
Crie um jogo mais completo de adivinhação com estas regras:
- O computador escolhe um número secreto entre 1 e 100
- O usuário tem máximo 7 tentativas para adivinhar
- A cada tentativa errada, o programa diz se o número secreto é maior ou menor
- Se o usuário adivinhar, exiba uma mensagem de parabéns com quantas tentativas levou
- Se o usuário gastar as 7 tentativas sem acertar, revele o número secreto
Exemplo de execução:
Pensei em um número entre 1 e 100. Você tem 7 tentativas!
Tentativa 1: Qual é o número? 50
Muito alto!
Tentativa 2: Qual é o número? 25
Muito baixo!
Tentativa 3: Qual é o número? 35
Muito alto!
Tentativa 4: Qual é o número? 30
Acertou! Você levou 4 tentativas. Parabéns! 🎉
Ou:
Tentativa 7: Qual é o número? 45
Muito alto!
Não foi dessa vez! O número era 42. Tente novamente!
Template para começar:
import random
numero_secreto = random.randint(1, 100)
tentativa = 0
acertou = False
print("Pensei em um número entre 1 e 100. Você tem 7 tentativas!")
print()
while tentativa < 7 and not acertou:
tentativa = tentativa + 1
palpite = int(input(f"Tentativa {tentativa}: Qual é o número? "))
if palpite == numero_secreto:
print(f"Acertou! Você levou {tentativa} tentativas. Parabéns! 🎉")
acertou = True
elif palpite < numero_secreto:
print("Muito baixo!")
else:
print("Muito alto!")
print()
if not acertou:
print(f"Não foi dessa vez! O número era {numero_secreto}. Tente novamente!")
Desafios extras para ir além:
- Adicione um marcador de "quentes" e "frios": se o usuário está a menos de 10 de distância do número, diga "Você está quente!"; se estiver a mais de 50, diga "Você está muito frio!"
- Permita que o usuário jogue múltiplas rodadas antes de encerrar
- Mantenha um "ranking" de quantas tentativas cada rodada levou, e exiba ao final qual foi a melhor e pior performance