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:

  1. Começamos com i = 1
  2. Perguntamos: "i é menor ou igual a 10?"
  3. Se sim, exibimos o valor de i e incrementamos i
  4. Voltamos para a pergunta
  5. 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:

  1. Cria a variável i e a faz valer 0 → executa o bloco
  2. Muda i para 1 → executa o bloco de novo
  3. Muda i para 2 → executa o bloco de novo
  4. Muda i para 3 → executa o bloco de novo
  5. Muda i para 4 → executa o bloco de novo
  6. 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:

  1. Criar a variável i antes do laço
  2. Incrementar i dentro do laço (senão fica infinito!)
  3. 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:

  1. comando começa vazio
  2. Entra no while (porque "" != "sair" é verdadeiro)
  3. Exibe o menu e pede entrada
  4. Se o usuário digitar "somar", executa a soma
  5. Volta ao início do while
  6. Pergunta outra vez
  7. Se o usuário digitar "sair", a condição comando != "sair" vira falsa
  8. 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 try e except, 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 com if.


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:

  1. O computador escolhe um número secreto entre 1 e 100
  2. O usuário tem máximo 7 tentativas para adivinhar
  3. A cada tentativa errada, o programa diz se o número secreto é maior ou menor
  4. Se o usuário adivinhar, exiba uma mensagem de parabéns com quantas tentativas levou
  5. 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:

Python