Pular para conteúdo

Lista 07 · Repetição com while

Esta lista é sobre uma única ideia: voltar e fazer de novo. Todo exercício aqui tem um laço, e todo laço tem as mesmas três peças — a variável que existe antes, a condição que decide se continua, e a linha que faz a variável avançar.

Faça a Parte A no papel, antes de abrir o OnlineGDB. Rastrear um laço volta a volta é a habilidade que a prova cobra, e é a única forma de entender um laço que não faz o que você esperava.

Dois avisos antes de rodar qualquer coisa:

  • Se o programa não parar, você escreveu um laço infinito. Não é defeito da máquina: falta a linha que muda a variável do teste. Botão Stop vermelho no OnlineGDB, e leia o bloco de novo.
  • Se o total sair igual à última parcela, o acumulador está sendo zerado dentro do laço. Esse não trava, não reclama e entrega o número errado — é o erro mais importante da unidade.

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.

Estes são para fazer no papel, sem computador. Depois rode e confira a sua previsão — se a sua tabela bater com a tela, você entendeu o laço.

A1. Rastreie. Complete a tabela, uma linha por volta, e diga o que o programa imprime.

contador = 1
while contador <= 4:
    print(contador)
    contador = contador + 2
Volta contador no teste o teste dá imprime contador no fim
1
2
…

Quantas voltas o laço deu? Com que valor contador fica ao final?

A2. Rastreie o acumulador. Qual é o valor de total impresso?

total = 0
n = 1
while n <= 4:
    total = total + n * 10
    n = n + 1
print(total)
Volta total no início n total no fim
1 0 1
2
3
4

A3. O erro que não dá erro. Este programa deveria somar 1 + 2 + 3 + 4 + 5. Ele imprime outro número, e não dá erro nenhum.

n = 1
while n <= 5:
    total = 0
    total = total + n
    n = n + 1
print(total)
  1. Rastreie e diga o que ele imprime.
  2. Explique, numa frase, por quê.
  3. Conserte movendo uma única linha.

A4. Laço infinito. Um destes três nunca termina. Qual, e por quê?

# (a)
x = 10
while x > 0:
    print(x)
    x = x - 2

# (b)
x = 10
while x > 0:
    print(x)
    x = x + 2

# (c)
x = 10
while x > 0:
    x = x - 1
print(x)

A5. < ou <=? Quantas linhas cada um imprime?

i = 1                 i = 1
while i < 3:          while i <= 3:
    print(i)              print(i)
    i = i + 1             i = i + 1

A6. A sentinela. O programa abaixo deveria somar valores até a pessoa digitar 0. Ele trava para sempre. O que falta?

total = 0
valor = float(input("Valor (0 encerra): "))
while valor != 0:
    total = total + valor
print(total)

A7. Ordene o algoritmo. As linhas estão fora de ordem. Reescreva-as na ordem que faz o programa somar os números de 1 a 100.

print(total)
n = n + 1
n = 1
total = total + n
while n <= 100:
total = 0

(Duas delas precisam ficar indentadas. Diga quais.)

Parte B · no computador

Exercício 01

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

Use um while. É o padrão acumulador do capítulo: a variável do total nasce em zero antes do laço.

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

Ate que numero somar:
Soma: ...

A sessão publicada usa 10, que dá dez voltas. Mas o caso que quebra é o 0: não há o que somar, o laço dá zero voltas e a resposta é 0. Se o seu programa imprimir 1 aí, o acumulador começou no lugar errado — ou o avanço veio antes da soma.

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

n digitado Soma
0 0
1 1
5 15
10 55
100 5050

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

Ate que numero somar: 10
Soma: 55
# Exercício 01 — a soma de 1 até n.
# TODO: pergunte o numero (e converta para int).
# TODO: crie o acumulador do total, comecando em 0, ANTES do laco.
# TODO: crie o contador comecando em 1, escreva o while e nao esqueca do avanco.
# TODO: depois do laco, mostre a soma.

Baixar ex01.py

Exercício 02

Escreva um programa que pergunte um número inteiro maior ou igual a zero e mostre quantos algarismos ele tem.

Use um while e o operador // do capítulo 4: dividir por 10 joga fora o último algarismo (137 // 10 dá 13). Conte quantas vezes dá para fazer isso até sobrar zero.

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

Numero:
Algarismos: ...

Cuidado com o zero

0 tem um algarismo, mas o laço não daria nenhuma volta com ele — o programa responderia 0, sem travar e sem reclamar. Trate esse caso à parte, com um if, antes do laço. É por isso que o 0 é o valor da sessão publicada.

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

Número digitado Algarismos
0 1
7 1
42 2
137 3
1000 4
987654321 9

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

Numero: 0
Algarismos: 1
# Exercício 02 — quantos algarismos tem o número.
# TODO: pergunte o numero (e converta para int).
# TODO: trate o caso do 0 separadamente, com um if — ele tem 1 algarismo.
# TODO: senao, enquanto sobrar numero, jogue fora o ultimo algarismo com // 10
#       e conte mais um.
# TODO: mostre a quantidade de algarismos.

Baixar ex02.py

Exercício 03

Um cliente começou a assistir uma série pelo celular, e a cada dia ele assiste um pouco mais: o consumo de dados cresce sempre a mesma quantidade de um dia para o outro. Escreva um programa que pergunte a franquia, o consumo do primeiro dia e o aumento diário, e mostre quantos dias completos ele consegue usar sem estourar a franquia.

Com 1 GB no primeiro dia e aumento de 0,2 GB, os dias gastam 1,0 — 1,2 — 1,4 — 1,6 … GB. Não há divisão que responda isso: cada dia é diferente do anterior, e é o laço que vai somando um de cada vez.

É o padrão do capítulo: um acumulador para o que já foi gasto e um contador para os dias. Mas aqui a condição tem de perguntar "ainda cabe mais um dia?" — e não "já estourou?" —, ou a resposta conta um dia que o cliente não conseguiu completar.

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

Franquia em GB:
Consumo no primeiro dia em GB:
Aumento por dia em GB:
Dias completos: ...

Quando não dá nem para o primeiro dia

Com franquia de 5 GB e consumo de 10 GB no primeiro dia, a resposta é 0 — o laço dá zero voltas, e isso está certo. É esse o caso da sessão publicada. Um programa que responde 1 aí desconta um dia que o cliente nunca teve.

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

Franquia Consumo no 1º dia Aumento/dia Dias completos
5 10 1 0
20 1 0.2 10
10 1 1 4
30 1 0.5 9
20 1.4 0 14
10 2 0 5

Repare nas duas últimas linhas: com aumento 0 o consumo é sempre o mesmo, e aí uma divisão resolveria (20 // 1.4 dá 14). É o aumento que torna o laço necessário.

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

Franquia em GB: 5
Consumo no primeiro dia em GB: 10
Aumento por dia em GB: 1
Dias completos: 0
# Exercício 03 — quantos dias a franquia aguenta, com o consumo crescendo.
# TODO: pergunte a franquia, o consumo do primeiro dia e o aumento por dia (float).
# TODO: acumulador do que ja foi usado e contador de dias, ANTES do laco.
# TODO: continue enquanto couber MAIS UM dia dentro da franquia.
# TODO: dentro do laco, depois de contar o dia, aumente o consumo do dia seguinte.
# TODO: depois do laco, mostre os dias completos.

Baixar ex03.py

Exercício 04

Escreva um programa que pergunte um número inteiro maior ou igual a zero e mostre a soma dos algarismos dele — para 137, a resposta é 11 (1 + 3 + 7).

Dois operadores do capítulo 4 resolvem isto: % 10 devolve o último algarismo e // 10 joga o último algarismo fora. Repita até não sobrar nada.

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

Numero:
Soma dos algarismos: ...

Os zeros no meio do caminho

Em 1000 a resposta é 1: três voltas somam zero e não mudam nada, mas o laço precisa dar essas voltas até sobrar nada. É esse o valor da sessão publicada. Se o seu programa parar no primeiro zero, ele responde errado sem dar erro nenhum.

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

Número digitado Soma dos algarismos
1000 1
0 0
7 7
137 11
4321 10
999999 54

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

Numero: 1000
Soma dos algarismos: 1
# Exercício 04 — a soma dos algarismos.
# TODO: pergunte o numero (e converta para int).
# TODO: acumulador em 0, ANTES do laco.
# TODO: enquanto sobrar numero: pegue o ultimo algarismo com % 10, some,
#       e descarte-o com // 10.
# TODO: depois do laco, mostre a soma dos algarismos.

Baixar ex04.py

Exercício 05

Você está juntando dinheiro para trocar de celular, numa conta que rende um tanto por cento ao mês. Escreva um programa que pergunte o saldo que você já tem, quanto consegue guardar por mês, o rendimento mensal e a meta, e mostre quantos meses faltam para o saldo alcançar ou passar a meta.

A cada mês, nesta ordem: o saldo rende e depois recebe o depósito.

saldo = saldo + saldo * rendimento / 100 + deposito_mensal

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

Saldo atual:
Deposito por mes:
Rendimento ao mes (%):
Meta:
Meses: ...

A sessão publicada começa do zero, guarda 100 por mês com rendimento de 2% e mira 1200: são 11 meses. Sem o rendimento seriam 12, e aí uma divisão (1200 / 100) resolveria. Com o rendimento, cada mês soma um valor diferente do anterior, porque o saldo que rende é cada vez maior — e só o laço dá conta disso.

Mas o caso que quebra é o da meta já alcançada: com saldo 500 e meta 500 a resposta é 0, porque a condição já é falsa de saída e o laço dá zero voltas. Isso está certo, e é o primeiro que você tem de testar à mão.

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

Saldo Depósito/mês Rendimento (%) Meta Meses
500 100 1 500 0
0 100 2 1200 11
0 100 0 1200 12
0 200 5 3000 12
0 200 0 3000 15
1000 0 1 1100 10
200 100 0 500 3

A linha com depósito 0 termina porque o rendimento sozinho já faz o saldo crescer.

Saldo zero e depósito zero não termina nunca

Se o saldo começar em 0 e o depósito for 0, não há nada para render nem para somar: o saldo fica parado abaixo da meta e o laço não para. Botão Stop vermelho no OnlineGDB.

Como deve ficar. Rodando o programa e digitando 0, 100, 2, 1200, a tela tem de ficar assim:

Saldo atual: 0
Deposito por mes: 100
Rendimento ao mes (%): 2
Meta: 1200
Meses: 11
# Exercício 05 — meses até alcançar a meta, com o dinheiro rendendo.
# TODO: pergunte o saldo atual, o deposito mensal, o rendimento (%) e a meta (float).
# TODO: um contador de meses, ANTES do laco.
# TODO: enquanto o saldo for MENOR que a meta: o saldo rende, recebe o deposito,
#       e conta-se um mes.
# TODO: depois do laco, mostre quantos meses foram.

Baixar ex05.py

Exercício 06

Escreva um programa que pergunte, um de cada vez, quanto o cliente consumiu de dados em cada dia, em GB. Quando ele digitar 0, o programa para de perguntar e mostra:

  • quantos dias foram informados;
  • o consumo total, com uma casa decimal;
  • a média por dia, com duas casas decimais.

O 0 é a sentinela: ele encerra o laço e não entra na conta.

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

Consumo do dia em GB (0 encerra):
Dias informados: ...
Consumo total: ... GB
Media por dia: ... GB

Os dois input()

Um antes do while, para a condição ter o que testar na primeira volta, e outro no fim do bloco, para a próxima volta ter um valor novo. Faltando o segundo, o programa nunca termina.

Pode supor que o cliente informa pelo menos um dia antes de digitar 0.

Como deve ficar. Rodando o programa e digitando 1.4, 2.0, 0.6, 3.0, 0, a tela tem de ficar assim:

Consumo do dia em GB (0 encerra): 1.4
Consumo do dia em GB (0 encerra): 2.0
Consumo do dia em GB (0 encerra): 0.6
Consumo do dia em GB (0 encerra): 3.0
Consumo do dia em GB (0 encerra): 0
Dias informados: 4
Consumo total: 7.0 GB
Media por dia: 1.75 GB
# Exercício 06 — consumo diário com sentinela.
# TODO: crie o acumulador do total e o contador de dias, ANTES do laco.
# TODO: leia o primeiro consumo antes do while.
# TODO: enquanto o valor lido nao for 0, some, conte e leia o proximo.
# TODO: depois do laco, mostre os dias, o total e a media.

Baixar ex06.py