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 an, escrevarange(1, n + 1). Metade dos erros aqui é uma volta a mais ou a menos; - a indentação: o que está dentro do
foracontece a cada volta; o que está na margem acontece uma vez, no fim. Umprintno lugar errado não dá erro — só mente.
A Parte A é no papel, como sempre. Rastreie antes de rodar.
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?
| 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.
A3. Rastreie o acumulador. Complete a tabela e diga o valor final.
| 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ê:
- imprimir os 30 dias do mês;
- perguntar a senha até a pessoa acertar;
- somar as 12 faturas do ano;
- descobrir em quantos meses a poupança chega a R$ 1000;
- 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ê?
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:
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:
# 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.
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:
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:
# 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.
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:
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.
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:
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:
# 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.
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:
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:
# 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.
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:
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