Unidade 3 · a fila

A fila

while, for, range, listas, dicionários. Uma instrução, a manhã inteira no comprovante — sem copiar a linha.

Nesta unidade Repetir sem copiar a linha. Depois, a gaveta com vários nomes e a ficha nome/via. Envelopar isso numa função fica para a unidade 4.

Três vias do comprovante

Arquivo vias.py. A loja precisa de três cópias da palavra VIA no terminal — cliente, caixa, arquivo. O jeito ingênuo:

print("VIA")
print("VIA")
print("VIA")

Funciona. Para três linhas, ninguém vai à polícia. Agora pense no extremo: 50 vias, ou trocar VIA por COPIA em cinquenta lugares. Copiar-colar não escala. Mudar o texto vira caça ao tesouro. Loop = uma instrução, N execuções.

3.A · o extremo

Por que três print("VIA") é projeto frágil se a loja pedir 50 vias?

Imagine 500 linhas idênticas e um pedido para trocar a palavra.
O problema não é “três”. É o que acontece quando N cresce.
Solução: não escala; loop concentra a mudança.

while: perguntar de novo

while pergunta uma expressão booleana. Enquanto a resposta for True, o bloco indentado roda; depois o interpretador volta à pergunta. Você precisa de um contador — como dedos no ar.

i = 3
while i != 0:
    print("VIA")
    i = i - 1

Começa em 3. Enquanto não for 0, imprime e diminui. Quando chega a 0, a pergunta vira False e o programa segue.

início i ← 3 ┌─ i != 0 ? ──false──▶ para │ true │ print("VIA") │ i ← i - 1 └──────── volta à pergunta

Se o contador não mexe

Se você esquecer i = i - 1, i continua 3 para sempre. A pergunta nunca vira False. Isso é loop infinito — acidental. O terminal enche de VIA. Não precisa desligar o PC: Ctrl+C interrompe (cancel / KeyboardInterrupt).

3.B · eterno

i = 3 e while i != 0: print("VIA") sem alterar i. O que acontece?

A pergunta é i != 0. i permanece 3.
True para sempre = loop infinito. Ctrl+C no terminal.
Solução: imprime sem parar até você cancelar.
3.C · while que termina

Um while que imprime VIA e atualiza o contador (soma ou subtrai).

while pergunta; o bloco faz o trabalho E muda i.
i = i - 1 ou i += 1, conforme você conte para baixo ou para cima.
Modelo:
i = 3
while i != 0:
print("VIA")
i = i - 1

Outra aritmética, mesmo efeito

Quem prefere subir: i = 1 e while i <= 3, incrementando. Se você começar em 1 e subtrair, nunca chega em 3 — outro infinito, agora no negativo.

Convenção da área: contar a partir de 0 e ir até, mas não incluindo, o N que você quer. i = 0 e while i < 3 dá três voltas (0, 1, 2). Se deixar <=, vias demais: quatro. Off-by-one é o bug clássico desta aula.

Atalho de incremento

i = i + 1 lê da direita para a esquerda: soma, depois guarda. Tão comum que existe i += 1. O mesmo para -=, *=. Linguagens C/Java têm i++; Python não tem. Este é o máximo de sucinto.

3.D · +=

Escreva a forma curta de somar 1 em i.

Não é i++. É mais-igual.
i += 1
Solução: i += 1

for: o interpretador vira a engrenagem

while deixa a mecânica com você: inicializar, perguntar, incrementar. for percorre uma coleção. Lista usa colchetes:

for i in [0, 1, 2]:
    print("VIA")

Python põe 0 em i, executa o bloco, põe 1, executa, põe 2, executa, acaba a lista, para. Duas linhas. Escrever 0 até 999_999 na mão? Não. Por isso existe range.

range e variável que você ignora

range(n) entrega n valores começando em 0 e parando antes de n. range(3) ≈ 0, 1, 2. Para um milhão de vias: range(1_000_000) — o underscore no número é só leitura humana.

for _ in range(3):
    print("VIA")

Se você não usa o número, o nome _ sinaliza: “preciso da volta, não do valor”. Usar _ e imprimir o _ é criptografia barata — aí dê um nome de verdade.

3.E · for + range

Um for com range que imprime algo (três vias, por exemplo).

for _ in range(3):
print indentado.
Modelo:
for _ in range(3):
print("VIA")

Multiplicar texto

Python deixa "VIA" * 3 — cola a string três vezes. Para quebrar linha: "VIA\n" * 3. O print ainda acrescenta outro \n no fim, e sobra uma linha em branco. end="" corta essa extra.

print("VIA\n" * 3, end="")

É curto. Também é mais opaco que um for. Correto não é o mesmo que legível. Escolha o que o colega (você daqui a um mês) ainda entende.

3.F · linha extra

print("eco\\n" * 3) deixa uma linha em branco no fim. Por quê, e como cortar?

Cada VIA\n já desce uma linha. print desce de novo no final.
end="" (unidade 1) troca o final padrão.
Solução: print ainda emite \\n; use end="".

Insistir até a entrada prestar

Quantas vias? Precisa ser inteiro maior que zero. Um if n < 0 e outro input não basta: a pessoa pode errar dez vezes. Você não escreve dez if.

Paradigma comum: while True — loop eterno de propósito. Dentro, lê. Se ainda não presta, continue (volta à pergunta sem o resto do bloco). Se presta, break (sai do loop mais interno).

while True:
    n = int(input("Quantas vias? "))
    if n > 0:
        break

for _ in range(n):
    print("VIA")

Dá para inverter: if n < 0: continue e else: break. O if n > 0: break sozinho já aperta. Zero vias não interessa: a impressora não liga para comprovante vazio.

3.G · break

Um while True que lê um número e dá break quando for positivo.

while True: é infinito até o break.
n = int(input(...)); if n > 0: break
Modelo:
while True:
n = int(input("n? "))
if n > 0:
break

Vários valores na mesma gaveta

Lista: colchetes, vírgulas. Três inteiros ou três strings — o tipo dos itens é você quem escolhe. Indexar: itens[0] é o primeiro. Listas em Python são zero-indexadas. O segundo é [1]. Off-by-one de novo, agora com nome.

itens = ["pão", "leite", "ovos"]
print(itens[0])
print(itens[1])
print(itens[2])

Três prints manuais têm o mesmo cheiro das três vias. O próximo bloco elimina isso.

3.H · [0]

itens = ["pão", "leite", "ovos"]. O que é itens[0]?

O computador conta 0, 1, 2.
A posição zero é o primeiro da lista.
Solução: pão

Percorrer os valores

Não precisa de range se você quer o conteúdo, não o número da posição:

for item in itens:
    print(item)

Python inicializa item sozinho: pão, depois leite, depois ovos. Não declare antes. Chame a variável do que ela é — item, não _, porque desta vez você usa o valor. for s in itens é aceitável; for item in itens lê melhor.

3.I · for na lista

Percorra itens com for e imprima cada elemento.

for x in itens: — o nome da variável é você quem escolhe.
print(x) indentado.
Modelo: for item in itens:
print(item)

Quando você quer o número da posição

range(itens) não roda: range quer um inteiro. len(itens) devolve o comprimento (3). Aninhe: range(len(itens)) gera 0, 1, 2. Aí itens[i] usa o índice.

for i in range(len(itens)):
    print(i + 1, itens[i])

Somar 1 na hora de mostrar: o humano não precisa ver “pão em zeroth place”. Por baixo, o índice continua 0.

Associar uma coisa a outra

Lista é uma fila de valores. Dicionário associa chave a valor — palavra a definição, produto a preço. Chaves: chaves { } (as mesmas da f-string, outro emprego). Formato: "café": 8.5.

tabela = {
    "café": 8.5,
    "pão": 4.0,
    "suco": 9.0,
}
print(tabela["café"])

O índice não é 0, 1, 2 — é o nome do produto. Duas listas paralelas (nomes numa, preços noutra) “alinham na honra” e quebram quando a lista cresce. Dicionário é o par explícito.

for produto in tabela percorre as chaves, por desenho da linguagem. Para o preço: tabela[produto].

for produto in tabela:
    print(produto, tabela[produto], sep=", ")
3.J · lookup

Com o dicionário tabela acima, quanto vale tabela["café"]?

A chave é o texto à esquerda dos dois-pontos.
café está associado a 8.5.
Solução: 8.5

Uma ficha por pessoa

Quando cada aluno tem nome, turma e um campo que às vezes não existe, uma lista de dicionários padroniza as chaves:

alunos = [
    {"nome": "Bia", "turma": "A", "monitor": "sim"},
    {"nome": "Leo", "turma": "A", "monitor": "não"},
    {"nome": "Nico", "turma": "B", "monitor": None},
]

for aluno in alunos:
    print(aluno["nome"], aluno["turma"], aluno["monitor"], sep=", ")

None (N maiúsculo) é a ausência oficial de valor — melhor que string vazia, que misturaria “não preenchi” com “não se aplica”. O for aluno in alunos percorre a lista; cada aluno é um dicionário; aluno["nome"] abre essa ficha.

Dicionário grande continua rápido para busca por chave: essa é a promessa da estrutura. Ordenar, filtrar, persistir em arquivo — módulos seguintes.

Duas dimensões: linha, depois coluna

Um retângulo de hashes no terminal (prateleira, banner, grade de estoque) não é uma linha só. A impressora pensa: cima para baixo; em cada linha, esquerda para direita. Laço de fora = linhas. Laço de dentro = tijolos daquela linha. No fim da linha interna, print() vazio desce o cursor.

def print_retangulo(tamanho):
    for i in range(tamanho):          # cada linha
        for j in range(tamanho):      # cada célula
            print("#", end="")
        print()                     # desce depois da linha

Variáveis i e j por convenção. Não reutilize i no interno: bagunça a contagem. Depois de k, aninhar mais costuma ser sinal de decompor em função.

O laço interno some se você já sabe multiplicar string: print("#" * tamanho) dentro do laço das linhas. Ou uma função print_faixa(largura)abstração: print_retangulo não precisa saber como a faixa é feita, só que alguém imprime uma linha. Você troca a implementação interna e main não percebe, desde que o nome e os parâmetros continuem iguais.

def print_faixa(largura):
    print("#" * largura)

def print_retangulo(tamanho):
    for _ in range(tamanho):
        print_faixa(tamanho)

Coluna vertical: um for e um print("#") por volta — ou print("#\\n" * altura, end=""). O mesmo contrato, outras entranhas.

3.K · aninhado

Num quadrado impresso no terminal, o laço de fora e o de dentro fazem o quê?

Impressora: esquerda → direita numa linha, depois a linha de baixo.
end="" evita descer a cada hash.
Solução: fora = linha; dentro = célula; print() desce.

Oficina · carimbo e grade

Problema da unidade Escolha um (ou os dois): (1) perguntar um N positivo e imprimir VIA N vezes com for + range — sem copiar a linha N vezes; (2) imprimir um retângulo de # (por exemplo 4×4) com loop, não com quatro prints iguais. Arquivo sugerido: carimbo.py ou grade.py.
Oficina 3

Cole um programa com for ou while, range e print.

for _ in range(n): print("VIA")
Retângulo: for _ in range(4): print("#" * 4)
Não cole a mesma linha quatro vezes à mão.
Modelo:
n = 3
for _ in range(n):
    print("VIA")

for _ in range(4):
    print("#" * 4)