Pular para conteúdo

Lista 08 · Repetição com for

A Lista 07 foi sobre laços que param quando uma condição muda. Esta é sobre os laços em que você já sabe quantas voltas serão — e nesses o for faz o trabalho de contador sozinho.

Duas coisas valem mais do que todas as outras nesta lista:

  • a regra do range: o primeiro número entra, o segundo não. Para ir de 1 a n, escreva range(1, n + 1). Metade dos erros aqui é uma volta a mais ou a menos;
  • a indentação: o que está dentro do for acontece a cada volta; o que está na margem acontece uma vez, no fim. Um print no lugar errado não dá erro — só mente.

A Parte A é no papel, como sempre. Rastreie antes de rodar.

Abrir o OnlineGDB

Como esta lista funciona

Cada exercício abaixo é um arquivo só. Copie o código inteiro, cole no OnlineGDB, escreva a sua solução no lugar do # TODO e aperte ▶ Run.

Nos exercícios que mostram como deve ficar, compare a sua saída com a publicada aqui, linha por linha. Espaço a mais, acento faltando e letra maiúscula contam: o computador não relaxa em nenhum deles.

Parte A · no papel

Faça esta parte antes de ligar o computador

Escreva a resposta no caderno, depois rode para conferir. Prever e errar ensina; rodar primeiro e ler a saída, não.

No papel, antes do computador.

A1. Rastreie. O que este laço imprime, linha por linha?

for i in range(4):
    print(i, i * 2)
Volta i imprime
1
2
3
4

A2. Quantas voltas? Sem rodar, diga quantas voltas cada laço dá e qual é o primeiro e o último valor da variável.

range(3)        range(1, 4)      range(0, 10)
range(5, 6)     range(1, 1)      range(1, 31)

A3. Rastreie o acumulador. Complete a tabela e diga o valor final.

total = 0
for n in range(1, 6):
    total = total + n * n
print(total)
Volta n n * n total no fim da volta
1 1 1 1
2
3
4
5

A4. Acumulador e contador no mesmo laço. Rastreie as duas variáveis.

soma = 0
grandes = 0
for gb in range(1, 6):
    soma = soma + gb
    if gb > 3:
        grandes = grandes + 1
print(soma, grandes)
Volta gb gb > 3 soma grandes
1 1 False 1 0
2
3
4
5

Por que soma cresce em toda volta e grandes não?

A5. A indentação muda tudo. Os dois programas abaixo diferem em uma linha de indentação. O que cada um imprime?

# (a)                        # (b)
total = 0                    total = 0
for n in range(1, 4):        for n in range(1, 4):
    total = total + n            total = total + n
    print(total)             print(total)

A6. for ou while? Para cada problema, diga qual laço usar e por quê:

  1. imprimir os 30 dias do mês;
  2. perguntar a senha até a pessoa acertar;
  3. somar as 12 faturas do ano;
  4. descobrir em quantos meses a poupança chega a R$ 1000;
  5. imprimir a tabuada do 9.

A7. O laço que não deu volta nenhuma. Este programa imprime só 0 e mais nada. Por quê?

total = 0
n = 5
for i in range(n, 1):
    total = total + i
print(total)

Parte B · no computador

Exercício 01

Escreva um programa que pergunte um número inteiro n e mostre a soma de todos os números pares de 1 até n.

Use for com range(1, n + 1) e um if dentro do laço. Lembre do capítulo 4: numero % 2 == 0 é o teste de "é par".

Use exatamente estes textos, para a sua sessão bater com a publicada:

Ate que numero somar:
Soma dos pares: ...

A sessão publicada usa 7, que é ímpar: o laço tem de ir até o 7 e parar de somar no 6. Mas o caso que quebra é o 1: o laço dá uma volta, o if dá falso e a resposta é 0. Se o seu programa imprimir 1 aí, o if não está filtrando nada.

Teste também estes, à mão, trocando o valor digitado — o 1 em primeiro lugar:

n digitado Soma dos pares
1 0
2 2
7 12
10 30
100 2550

Como deve ficar. Rodando o programa e digitando 7, a tela tem de ficar assim:

Ate que numero somar: 7
Soma dos pares: 12
# Exercício 01 — a soma dos pares até n.
# TODO: pergunte o numero (e converta para int).
# TODO: acumulador em 0, ANTES do for.
# TODO: for sobre range(1, n + 1), com um if que testa se e par.
# TODO: depois do laco, mostre a soma dos pares.

Baixar ex01.py

Exercício 02

Escreva um programa que pergunte um início, um fim e um divisor, e mostre quantos números entre o início e o fim (os dois incluídos) são múltiplos do divisor.

É o padrão contador: uma variável que nasce em zero antes do laço e ganha + 1 só quando o if dá certo.

Use exatamente estes textos, para a sua sessão bater com a publicada:

Inicio:
Fim:
Divisor:
Multiplos: ...

Os dois incluídos

range(inicio, fim) para antes de fim. Para incluir o fim, o laço tem de ir até fim + 1. Na sessão publicada, início e fim são o mesmo número (5, 5, divisor 5): a resposta certa é 1. Quem esquece o + 1 responde 0 — e o programa não reclama.

Teste também estes, à mão, trocando os valores digitados:

Início Fim Divisor Múltiplos
5 5 5 1
1 10 3 3
1 100 10 10
1 10 11 0
1 20 2 10
10 1 2 0

Como deve ficar. Rodando o programa e digitando 5, 5, 5, a tela tem de ficar assim:

Inicio: 5
Fim: 5
Divisor: 5
Multiplos: 1
# Exercício 02 — contar múltiplos num intervalo.
# TODO: pergunte o inicio, o fim e o divisor (converta para int).
# TODO: contador em 0, ANTES do for.
# TODO: percorra de inicio ate fim INCLUSIVE e teste o resto da divisao.
# TODO: depois do laco, mostre quantos multiplos foram encontrados.

Baixar ex02.py

Exercício 03

Um cliente anotou quanto consumiu de dados em cada dia — e cada dia foi diferente. Escreva um programa que pergunte a franquia e quantos dias foram, depois pergunte o consumo de cada dia, um de cada vez, e mostre quantos GB sobram no fim, com duas casas decimais.

A franquia nunca fica negativa: quando o consumo passa do que havia, o que sobra é 0.

Use for com range(1, dias + 1), e use a variável do laço na pergunta, para o cliente saber de que dia se trata. Dentro do laço, leia o consumo do dia, desconte-o e, com um if, impeça que a sobra fique negativa.

Use exatamente estes textos, para a sua sessão bater com a publicada:

Franquia em GB:
Dias:
Consumo do dia 1 em GB:
...
Sobra: ... GB

A franquia que acabou no meio

Na sessão publicada a franquia é 10 GB e são 5 dias, com consumos de 3, 2.5, 4, 1 e 2 GB: acaba no quarto dia, e a resposta é 0.00 — nunca -2.50. É o if dentro do laço que garante isso.

Teste também estes, à mão, trocando os valores digitados:

Franquia Dias Consumo de cada dia Sobra
10 5 3, 2.5, 4, 1, 2 0.00
20 3 1.4, 2.1, 0.5 16.00
15 4 2, 2, 2, 2 7.00
5 2 8, 1 0.00
20 0 — 20.00

Com 0 dias o laço não dá nenhuma volta, não pergunta consumo nenhum, e a franquia sobra inteira.

Como deve ficar. Rodando o programa e digitando 10, 5, 3, 2.5, 4, 1, 2, a tela tem de ficar assim:

Franquia em GB: 10
Dias: 5
Consumo do dia 1 em GB: 3
Consumo do dia 2 em GB: 2.5
Consumo do dia 3 em GB: 4
Consumo do dia 4 em GB: 1
Consumo do dia 5 em GB: 2
Sobra: 0.00 GB
# Exercício 03 — o que sobra da franquia depois de alguns dias.
# TODO: pergunte a franquia (float) e quantos dias (int).
# TODO: comece a sobra valendo a franquia inteira, ANTES do for.
# TODO: uma volta por dia: pergunte o consumo DAQUELE dia, desconte e,
#       se ficar negativo, zere.
# TODO: depois do laco, mostre a sobra com duas casas decimais.

Baixar ex03.py

Exercício 04

Quando a internet cai, o modem não fica tentando reconectar sem parar: ele espera 1 segundo antes da primeira tentativa e dobra a espera a cada tentativa seguinte — 1, 2, 4, 8, 16...

Escreva um programa que pergunte quantas tentativas o modem fez e mostre quantos segundos o cliente esperou no total.

São duas variáveis antes do laço: o total acumulado e a espera da vez. A segunda dobra a cada volta.

Use exatamente estes textos, para a sua sessão bater com a publicada:

Tentativas:
Espera total: ... s

A sessão publicada usa 5 tentativas, que é onde a duplicação aparece inteira: 1 + 2 + 4 + 8 + 16. Mas o caso que quebra é o 0: o laço dá zero voltas e a resposta é 0, não 1. Se o seu programa imprimir 1 aí, a espera da vez está sendo somada fora do laço.

Teste também estes, à mão, trocando o valor digitado — o 0 em primeiro lugar:

Tentativas Espera total
0 0
1 1
2 3
3 7
5 31
10 1023

Como deve ficar. Rodando o programa e digitando 5, a tela tem de ficar assim:

Tentativas: 5
Espera total: 31 s
# Exercício 04 — a espera acumulada das retentativas do modem.
# TODO: pergunte quantas tentativas (converta para int).
# TODO: total em 0 e espera em 1, ANTES do for.
# TODO: uma volta por tentativa: some a espera ao total e dobre a espera.
# TODO: depois do laco, mostre a espera total.

Baixar ex04.py

Exercício 05

Escreva um programa que pergunte um número inteiro n maior ou igual a 2 e mostre o maior divisor de n que seja menor que o próprio n.

Este é o padrão extremo: guarde um candidato e troque-o sempre que achar um melhor. Comece o candidato em 1, que divide qualquer número — assim ele nunca começa com um valor que não existe.

Percorra de 1 até n - 1 e teste com %.

Use exatamente estes textos, para a sua sessão bater com a publicada:

Numero:
Maior divisor: ...

O número primo

Na sessão publicada o número é 7, que é primo: nenhum candidato substitui o inicial, e a resposta é 1. Se você começar o candidato em 0 — ou não começar com nada —, é aqui que o programa responde errado, ou quebra.

Teste também estes, à mão, trocando o valor digitado:

n digitado Maior divisor
7 1
2 1
10 5
12 6
97 1
100 50

Como deve ficar. Rodando o programa e digitando 7, a tela tem de ficar assim:

Numero: 7
Maior divisor: 1
# Exercício 05 — o maior divisor próprio de n.
# TODO: pergunte o numero (e converta para int).
# TODO: comece o candidato em 1, ANTES do for.
# TODO: percorra de 1 ate n - 1 e, se dividir n sem resto, guarde o
#       candidato novo.
# TODO: depois do laco, mostre o maior divisor encontrado.

Baixar ex05.py

Exercício 06

Escreva um programa que pergunte um número inteiro e imprima a tabuada dele, de 1 a 10, uma linha por vez, neste formato:

7 x 1 = 7
7 x 2 = 14

Use for com range(1, 11) — são dez voltas, e você sabe disso antes de começar. O convite da pergunta deve ser exatamente Numero:.

A linha de fora

Só o print da tabuada fica dentro do laço. Se a leitura do número ficar indentada junto, o programa vai perguntar dez vezes.

Como deve ficar. Rodando o programa e digitando 7, a tela tem de ficar assim:

Numero: 7
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70
# Exercício 06 — a tabuada.
# TODO: pergunte o numero (e converta para int).
# TODO: com um for sobre range(1, 11), imprima uma linha por multiplicacao.

Baixar ex06.py