Ja saps decidir amb if i repetir amb for i while, però els teus bucles encara són rígids: recorren la seqüència completa tant sí com no. En aquesta lliçó aprendràs a prendre el control fi de l'execució: break per sortir d'un bucle tan bon punt trobes el que busques, continue per saltar-te elements, pass com a marcador de posició, la poc coneguda clàusula else dels bucles, el patró while True per a menús que es repeteixen fins que l'usuari decideix sortir, i la moderna sentència match/case de Python 3.10. Amb totes elles construirem el primer menú interactiu de Papyrus, l'esquelet sobre el qual creixerà l'aplicació de l'Anna durant la resta del curs.

Contingut

  1. break: sortir del bucle abans d'hora
  2. continue: saltar a la iteració següent
  3. pass: la instrucció que no fa res
  4. La clàusula else en bucles
  5. Bucles infinits controlats: while True + break
  6. match/case: selecció per patrons (Python 3.10+)
  7. Projecte: el menú interactiu de Papyrus

break: sortir del bucle abans d'hora

La sentència break ("trencar") acaba el bucle immediatament: Python salta a la primera instrucció després del bucle, sense completar la volta actual ni fer les restants.

El cas d'ús per excel·lència és la cerca: en Lluís pregunta si Papyrus té Hamlet. Tan bon punt el trobem, no té sentit continuar mirant la resta del catàleg.

cataleg = ["L'Odissea", "Hamlet", "El Quixot"]
cercat = "Hamlet"

for titol in cataleg:
    print(f"Comprovant '{titol}'...")
    if titol == cercat:
        print(f"Trobat! '{cercat}' es al cataleg.")
        break

print("Cerca acabada.")

Sortida:

Comprovant 'L'Odissea'...
Comprovant 'Hamlet'...
Trobat! 'Hamlet' es al cataleg.
Cerca acabada.

Fixa-t'hi: El Quixot no es comprova mai. Amb un catàleg de 3 llibres tant és, però amb 30 000 la diferència és enorme.

Detalls importants de break:

  • Només es pot usar dins d'un bucle (for o while); a fora produeix SyntaxError.
  • En bucles imbricats, break surt només del bucle més intern que el conté, no de tots.
  • Gairebé sempre apareix dins d'un if: "si passa això, deixa d'iterar".

continue: saltar a la iteració següent

Mentre break abandona el bucle, continue ("continuar") abandona només la volta actual: salta directament a la iteració següent, sense executar la resta del bloc.

L'Anna vol imprimir la llista de llibres vendibles, saltant-se els esgotats:

cataleg = ["L'Odissea", "Hamlet", "El Quixot", "Faust"]
estocs = [4, 6, 8, 0]

print("Llibres disponibles per a la venda:")
for i, titol in enumerate(cataleg):
    if estocs[i] == 0:
        continue    # esgotat: passem al seguent sense imprimir res
    print(f"- {titol} ({estocs[i]} u.)")

Sortida:

Llibres disponibles per a la venda:
- L'Odissea (4 u.)
- Hamlet (6 u.)
- El Quixot (8 u.)

Faust (acabat d'arribar al catàleg, però amb estoc 0) se salta netament. El patró if condicio_de_descart: continue al començament del bloc s'anomena de vegades "clàusula de guarda" i té un gran avantatge de llegibilitat: el cas "normal" del bucle queda sense indentació extra, en lloc d'embolicar-ho tot amb un if gegant.

Comparativa ràpida de les dues sentències:

Sentència Què interromp El bucle... Ús típic
break El bucle sencer Acaba ja "Trobat, deixo de cercar"
continue Només la volta actual Segueix amb la següent "Aquest element no m'interessa, següent"
flowchart TD
    A[Següent element] --> B{descartar?}
    B -- "continue" --> A
    B -- No --> C[Processar element]
    C --> D{objectiu complert?}
    D -- "break" --> E[Sortir del bucle]
    D -- No --> A

pass: la instrucció que no fa res

pass és exactament això: una sentència buida. Existeix perquè la sintaxi de Python exigeix que tot bloc indentat contingui almenys una instrucció; quan encara no saps què posar-hi (o deliberadament no vols fer res), pass omple el buit sense efectes.

opcio = "3"

if opcio == "1":
    print("Mostrant cataleg...")
elif opcio == "2":
    pass    # TODO: cerca de llibres, la implementarem mes avall
else:
    print("Opcio no reconeguda.")

Sense el pass, aquest elif amb el cos buit donaria IndentationError. Els seus usos habituals:

  • Esquelets: escriure primer l'estructura del programa (branques, bucles, i en el futur funcions i classes) i omplir els blocs a poc a poc.
  • Ignorar casos a propòsit, deixant constància explícita que no és un oblit.

No confonguis pass amb continue: dins d'un bucle, pass no salta res (l'execució segueix a la línia següent); simplement "no fa res" i el flux continua amb normalitat.

La clàusula else en bucles

Aquí arriba una peculiaritat molt de Python: els bucles for i while poden portar un bloc else. El seu significat sorprèn al principi: l'else s'executa si el bucle ha acabat de manera natural, sense break.

Per a què serveix? Per al patró de cerca que hem vist abans: què passa si el llibre no hi és? Sense else necessitaríem una variable "bandera" (flag):

# Versio amb bandera (funciona, pero fa mes soroll)
cataleg = ["L'Odissea", "Hamlet", "El Quixot"]
cercat = "Faust"
trobat = False

for titol in cataleg:
    if titol == cercat:
        trobat = True
        break

if trobat:
    print(f"'{cercat}' es al cataleg.")
else:
    print(f"'{cercat}' no hi es. Anna pot demanar-lo al distribuidor.")

Amb l'else del bucle, la bandera desapareix:

# Versio amb for/else (idiomatica en Python)
cataleg = ["L'Odissea", "Hamlet", "El Quixot"]
cercat = "Faust"

for titol in cataleg:
    if titol == cercat:
        print(f"'{cercat}' es al cataleg.")
        break
else:
    print(f"'{cercat}' no hi es. Anna pot demanar-lo al distribuidor.")

Sortida:

'Faust' no hi es. Anna pot demanar-lo al distribuidor.

Com llegir-lo sense confondre's: pensa en l'else del bucle com un "si no hi ha hagut break" (alguns l'anomenen la clàusula nobreak). El flux exacte:

  • El bucle recorre tots els elements sense que s'executi cap break → en acabar, s'executa l'else.
  • S'executa un break en qualsevol volta → l'else se salta.

Dues advertències:

  • L'else va alineat amb el for/while, no amb cap if interior. Un descuit d'indentació canvia el significat del tot.
  • És una construcció poc coneguda fins i tot entre programadors amb experiència; usa-la per a cerques (el seu cas estrella) i acompanya-la d'un comentari si creus que qui llegeixi el codi pot no conèixer-la.

També funciona amb while: l'else s'executa quan la condició es torna falsa (sortida natural), però no si en surts amb break.

Bucles infinits controlats: while True + break

A la lliçó anterior el bucle infinit era un error a evitar. Però hi ha una versió deliberada i controlada que és un patró fonamental: while True amb un break interior. S'usa quan el programa ha de repetir alguna cosa indefinidament fins que l'usuari decideixi parar — exactament el que fa qualsevol menú, caixer automàtic o aplicació interactiva.

while True:
    resposta = input("Escriu 'sortir' per acabar: ")
    if resposta == "sortir":
        print("Fins aviat!")
        break
    print(f"Has escrit: {resposta}")

Com que True sempre és cert, el bucle no acaba mai per la seva condició: l'única sortida és el break. Això no és un bucle infinit accidental, perquè la sortida existeix i és clara; la clau és garantir que el break és assolible.

Aquest patró també resol del tot la validació d'entrades que vam deixar a mitges a fitxa_llibre.py:

while True:
    text = input("Estoc inicial del llibre: ")
    if text.isdigit():           # la cadena conte nomes digits?
        estoc = int(text)
        break
    print("Entrada no valida. Escriu un nombre enter, per exemple: 4")

print(f"Estoc registrat: {estoc}")

isdigit() és un mètode de les cadenes que retorna True si tots els seus caràcters són dígits (el veurem juntament amb la resta de mètodes de str al mòdul 4; de moment, usa'l tal qual). El bucle insisteix fins a rebre un nombre vàlid, i només llavors converteix i surt. Comparada amb el while resposta != ... de la lliçó anterior, aquesta forma evita duplicar l'input() o inicialitzar variables artificials: per això és la preferida en Python.

match/case: selecció per patrons (Python 3.10+)

Quan un programa ha de reaccionar de manera diferent segons el valor concret d'una variable (l'opció d'un menú, un codi d'estat, un tipus de client), una cadena d'if/elif funciona, però des de Python 3.10 hi ha una alternativa més expressiva: la sentència match.

opcio = "2"

match opcio:
    case "1":
        print("Mostrant el cataleg complet...")
    case "2":
        print("Cercador de llibres...")
    case "3":
        print("Sortint de Papyrus. Fins dema, Anna!")
    case _:
        print("Opcio no valida.")

Com funciona:

  • match expressio: avalua l'expressió una vegada.
  • Cada case patro: es compara en ordre; el primer que encaixa executa el seu bloc i la sentència acaba (no hi ha "caiguda" al cas següent, a diferència del switch d'altres llenguatges: aquí no necessites cap break).
  • case _: és el comodí: encaixa amb qualsevol cosa, i actua com l'else final. Ha d'anar en darrer lloc.
  • Si cap cas no encaixa i no hi ha comodí, simplement no s'executa res (sense error).

A més dels valors literals, els patrons bàsics permeten dues coses molt útils:

Alternatives amb | (o barra vertical): un mateix cas per a diversos valors.

resposta = input("Confirmar la venda? (s/n): ")

match resposta:
    case "s" | "S" | "si" | "Si":
        print("Venda confirmada.")
    case "n" | "N" | "no":
        print("Venda descartada.")
    case _:
        print("Resposta no reconeguda.")

Condició extra amb if (anomenada guarda): el cas només encaixa si a més es compleix la condició.

estoc = 2

match estoc:
    case 0:
        print("Esgotat.")
    case n if n <= 3:
        print(f"Estoc baix: en queden {n}.")
    case n:
        print(f"Estoc correcte: {n} unitats.")

En case n if n <= 3:, el patró n és un patró de captura: encaixa amb qualsevol valor i el guarda a la variable n, però la guarda if n <= 3 filtra quan s'accepta. És una porta d'entrada als patrons estructurals més avançats de match (desempaquetar llistes, diccionaris o objectes), que agafaran sentit quan coneguis aquestes estructures als mòduls 4 i 5.

match o if/elif? Guia ràpida:

Situació Recomanació
Comparar una mateixa variable contra valors concrets (menús, codis) match guanya en claredat
Condicions heterogènies (estoc > 0 and es_soci, rangs, diverses dades) if/elif
El teu codi ha de funcionar en Python < 3.10 if/elif obligatòriament

Projecte: el menú interactiu de Papyrus

Ajuntem totes les peces de la lliçó en un script nou per al projecte: menu.py, dins de la carpeta papyrus (amb el .venv activat, com sempre). És el primer programa de Papyrus que conversa amb l'Anna: es repeteix fins que ella decideix sortir.

NOM_BOTIGA = "Papyrus"
cataleg = ["L'Odissea", "Hamlet", "El Quixot"]
preus = [12.50, 9.95, 15.90]
estocs = [4, 6, 8]

print(f"Benvinguda a la gestio de {NOM_BOTIGA}")

while True:
    print()
    print("1. Veure cataleg")
    print("2. Cercar un llibre")
    print("3. Sortir")
    opcio = input("Tria una opcio (1-3): ")

    match opcio:
        case "1":
            print(f"\n{'Titol':<12} {'Preu':>8} {'Estoc':>6}")
            print("-" * 28)
            for i, titol in enumerate(cataleg):
                print(f"{titol:<12} {preus[i]:>6.2f} € {estocs[i]:>6}")
        case "2":
            cercat = input("Titol a cercar: ")
            if not cercat:
                print("No has escrit res.")
                continue
            for i, titol in enumerate(cataleg):
                if titol.lower() == cercat.lower():
                    print(f"'{titol}': {preus[i]:.2f} €, estoc {estocs[i]}.")
                    break
            else:
                print(f"'{cercat}' no es al cataleg.")
        case "3":
            print(f"Tancant {NOM_BOTIGA}. Fins dema, Anna!")
            break
        case _:
            print("Opcio no valida. Tria 1, 2 o 3.")

Repassa com hi col·labora cada eina:

  1. while True manté el menú viu: després de cada operació, es torna a mostrar.
  2. match opcio despatxa cada opció amb un cas net, i case _ captura els errors de tecleig.
  3. A la cerca, continue fa de guarda si l'Anna prem Intro sense escriure (truthiness de la cadena buida, com a la lliçó 02-01): torna al menú sense executar la cerca.
  4. for/break/else: el break talla tan bon punt hi ha coincidència i l'else del bucle cobreix el cas "no trobat" sense variables bandera. (lower() passa el text a minúscules perquè la cerca no distingeixi majúscules; més sobre mètodes de cadenes al mòdul 4.)
  5. break al case "3" és l'única sortida del while True: fixa't que trenca el bucle exterior perquè match no és cap bucle — break i continue travessen la sentència match i actuen sobre el bucle que la conté.

Una sessió d'exemple:

Benvinguda a la gestio de Papyrus

1. Veure cataleg
2. Cercar un llibre
3. Sortir
Tria una opcio (1-3): 2
Titol a cercar: hamlet
'Hamlet': 9.95 €, estoc 6.

1. Veure cataleg
2. Cercar un llibre
3. Sortir
Tria una opcio (1-3): 3
Tancant Papyrus. Fins dema, Anna!

Aquest menú és deliberadament senzill: al mòdul 3 el reorganitzarem amb funcions (una per opció) i al mòdul 6 farà que el catàleg sobrevisqui entre sessions guardant-lo en fitxers. L'esquelet, però, ja no canviarà: while True + match + break és el patró estàndard de les aplicacions de consola.

Errors Comuns i Consells

  • Esperar que break surti de tots els bucles imbricats: només surt del més intern. Si necessites sortir de diversos nivells, sol ser senyal que aquest codi mereix ser una funció (mòdul 3), on return surt de tot de cop.
  • Malinterpretar l'else del bucle com a "si el bucle no s'ha executat cap vegada": fals. Amb una seqüència buida, el bucle acaba sense break... i l'else que s'executa. Recorda: else = "no hi ha hagut break".
  • Usar break o continue fora d'un bucle (per exemple, dins d'un if solt o esperant que tallin un match): SyntaxError. Només tenen sentit dins de for/while.
  • Abusar de continue: diverses guardes seguides a l'inici del bucle són llegibles; continues repartits per mig bloc fan el flux difícil de seguir. Si et passa, replanteja les condicions.
  • Oblidar el break de sortida en un while True: llavors sí que tens un bucle infinit de debò. En escriure while True:, escriu el case/if de sortida amb el seu break abans d'omplir la resta.
  • Escriure case "1" | "2": quan cada valor necessita lògica diferent: l'alternativa | és per a casos que comparteixen bloc. Si els blocs difereixen, són casos separats.
  • Usar match amb Python antic: en versions anteriors a la 3.10 dona SyntaxError. Comprova la teva versió amb python --version; si mantens codi per a versions velles, usa if/elif.
  • Consell: pass és útil mentre construeixes, però no hauria d'arribar a la versió final de l'script llevat que ignorar el cas sigui una decisió conscient — i llavors, comenta-ho.

Exercicis

Exercici 1: primera venda esgotada

Donades vendes_pendents = [2, 1, 3, 2, 4] (unitats demanades per diversos clients, en ordre) i un estoc = 6 de Hamlet, recorre les comandes amb un for: serveix cada comanda restant de l'estoc i imprimeix Comanda de N u. servida (en queden M). Si una comanda no es pot servir completa, imprimeix Estoc insuficient per a la comanda de N u. i deixa de processar comandes en aquell moment. Si totes s'han servit, imprimeix al final Totes les comandes servides (pista: for/else).

Exercici 2: informe saltant els descatalogats

Donades les llistes titols = ["L'Odissea", "Hamlet", "El Quixot", "Faust"] i estats = ["actiu", "actiu", "descatalogat", "actiu"], imprimeix un informe numerat (començant per 1) només dels llibres actius, usant continue per saltar els descatalogats. La numeració ha de ser consecutiva per als mostrats (1, 2, 3), no la posició original.

Exercici 3: caixer de Papyrus amb match

Escriu un while True que demani a l'Anna un codi d'operació i reaccioni amb match:

  • "v" o "venda" → demana un import i suma'l a un acumulador caixa (parteix de caixa = 0.0).
  • "d" o "devolucio" → demana un import i resta'l de caixa.
  • "t" → imprimeix el total actual amb dos decimals.
  • "x" → imprimeix el total final i surt.
  • Qualsevol altra cosa → missatge d'error.

Solucions

Solució 1:

vendes_pendents = [2, 1, 3, 2, 4]
estoc = 6

for comanda in vendes_pendents:
    if comanda > estoc:
        print(f"Estoc insuficient per a la comanda de {comanda} u.")
        break
    estoc -= comanda
    print(f"Comanda de {comanda} u. servida (en queden {estoc})")
else:
    print("Totes les comandes servides")

Amb estoc 6, se serveixen les comandes de 2 i 1 (en queden 3), la de 3 (en queden 0) i la de 2 ja no es pot servir: break. Com que hi ha hagut break, l'else no s'executa — exactament el que volem. Prova de canviar estoc = 12 i veuràs el missatge final.

Solució 2:

titols = ["L'Odissea", "Hamlet", "El Quixot", "Faust"]
estats = ["actiu", "actiu", "descatalogat", "actiu"]

numero = 0
for i, titol in enumerate(titols):
    if estats[i] == "descatalogat":
        continue
    numero += 1
    print(f"{numero}. {titol}")

La clau és portar un comptador propi (numero) que només s'incrementa després de la guarda amb continue: així els descatalogats no consumeixen número i la llista mostrada queda 1. L'Odissea, 2. Hamlet, 3. Faust.

Solució 3:

caixa = 0.0

while True:
    codi = input("Operacio (v/d/t/x): ")
    match codi:
        case "v" | "venda":
            caixa += float(input("Import de la venda: "))
        case "d" | "devolucio":
            caixa -= float(input("Import retornat: "))
        case "t":
            print(f"Total en caixa: {caixa:.2f} €")
        case "x":
            print(f"Tancament. Total final: {caixa:.2f} €")
            break
        case _:
            print("Codi no reconegut. Usa v, d, t o x.")

El patró complet de la lliçó en miniatura: while True com a cor del programa, | per acceptar sinònims, case _ per als errors de tecleig i un únic break com a sortida. Com sempre, float() fallarà si l'Anna escriu text a l'import — la xarxa de seguretat arribarà al mòdul 7.

Conclusió

Els teus bucles han deixat de ser trens sense frens: amb break pares tan bon punt trobes el que busques, amb continue et saltes el que no interessa, amb pass reserves el lloc del que està per escriure, amb l'else dels bucles detectes cerques sense èxit sense variables bandera, i amb while True + break has construït el patró universal dels programes interactius. A més, match/case et dona una forma moderna i llegible de despatxar opcions. Tot plegat ha quedat encaixat a menu.py, el primer programa de Papyrus que dialoga amb l'Anna i l'esquelet de tot el que ve.

Queda un últim superpoder d'aquest mòdul. Hauràs notat que molts dels nostres bucles segueixen el mateix patró: recórrer una llista per construir-ne una altra (preus amb IVA, títols filtrats per estoc...). Python té una sintaxi específica, compacta i elegantíssima per a aquest patró: les comprensions de llistes. Són el tret d'identitat del codi pythònic, i amb elles tancarem el mòdul a la propera lliçó.

Curs de Programació en Python

Mòdul 1: Introducció a Python

Mòdul 2: Estructures de Control

Mòdul 3: Funcions i Mòduls

Mòdul 4: Estructures de Dades

Mòdul 5: Programació Orientada a Objectes

Mòdul 6: Gestió de Fitxers

Mòdul 7: Gestió d'Errors i Excepcions

Mòdul 8: Temes Avançats

Mòdul 9: Proves i Depuració

Mòdul 10: Desenvolupament Web amb Python

Mòdul 11: Ciència de Dades amb Python

Mòdul 12: Projecte Final

© Copyright 2026. Tots els drets reservats