Capítol 7 — Mentre
Capítol 7

Mentre

El for és perfecte quan saps exactament quantes vegades vols repetir una acció. Però, i si no ho saps? En aquest capítol aprendrem while, el bucle que continua mentre una condició sigui certa, i s'atura sol quan el món ja no la compleix.

Quan no saps quantes vegades has de repetir

Imagina que en Karel ha d'avançar fins a topar amb una paret. El món pot tenir tres caselles o pot tenir deu. Amb for hauríes d'escriure el nombre exacte: range(3) o range(10). Però si el programa no sap la mida del món, no pot triar el número correcte.

La pregunta correcta no és «quantes vegades?», sinó «fins quan?». I la resposta és: «mentre tingui el camí lliure davant meu, continua avançant».

Això és exactament el que expressa while.

Repetir mentre… while

while comprova una condició i executa el bloc indentat de sota repetidament mentre la condició sigui certa. Cada vegada que acaba el bloc, torna a comprovar la condició. Quan la condició és falsa, el bucle s'atura i el programa continua.

while front_is_clear():
    move()

En Karel comprova si té la via lliure davant. Si és cert, avança. Torna a comprovar. Si és cert de nou, avança. I així fins que hi hagi un obstacle o la paret del món. Llavors s'atura.

Compara for i while:

# for: saps exactament quantes vegades
for i in range(5):
    move()

# while: avanças fins que el camí s'acabi
while front_is_clear():
    move()

El for és com dir «fes-ho cinc vegades». El while és com dir «fes-ho fins que no puguis».

Atenció: en aquest exemple no pots modificar el codi. Prem ▶ Executa i observa com funciona:

En Karel ha avançat fins al final del corredor sense que el codi hagués de saber la mida del món. Si el món hagués tingut vint caselles, el mateix codi hauria funcionat igual.

Qualsevol condició funciona amb while

Com en el cas de if, pots usar qualsevol de les condicions que ja coneixes dins d'un while:

  • while front_is_clear(): — avança mentre el camí estigui lliure.
  • while pearl_here(): — continua mentre hi hagi perles a la casella.
  • while not bag_is_empty(): — continua mentre la motxilla tingui perles.

La paraula clau not inverteix la condició: not bag_is_empty() és cert quan la motxilla no és buida, és a dir, quan en Karel porta alguna cosa.

En l'exemple de sota, en Karel té tres perles a la motxilla i les ha de deixar caure una per una mentre camina cap a l'Est:

Quan la motxilla s'ha buidat, la condició not bag_is_empty() s'ha tornat falsa i el bucle s'ha aturat. El codi no necessitava saber que eren tres perles.

while i if junts

while i if es combinen molt bé. El while controla fins quan continua el bucle; l'if de dins decideix el que es fa a cada passada.

Observa un exemple clàssic: en Karel recorre un corredor de llargada desconeguda i recull totes les perles que troba pel camí. No sap quantes perles hi ha ni en quines caselles estan:

Atenció: en aquest exemple no pots modificar el codi. Prem ▶ Executa i observa com funciona:

El while assegura que en Karel avança fins a la paret, sigui on sigui. L'if de dins s'ocupa de les perles sense que el programa s'aturi si una casella és buida. Els dos junts fan quelcom que cap dels dos podria fer sol.

Compte amb el bucle infinit

Si la condició d'un while mai no es torna falsa, el bucle no s'atura mai. Això s'anomena un bucle infinit i és un error habitual.

Per exemple:

# ❌ Bucle infinit: la condició sempre és certa
while front_is_clear():
    turn_left()   # gira però no avança → el camí segueix lliure per sempre

En Karel girarà a l'esquerra indefinidament perquè mai no avança cap al mur. La condició front_is_clear() seguirà sent certa eternament.

La regla per evitar-ho: el cos del while ha de fer alguna cosa que pugui canviar la condició. Si el while comprova front_is_clear(), el cos ha d'incloure algun move() o una acció que pugui apropar en Karel a un obstacle.

Exercici

En Karel és a l'extrem esquerre d'un corredor de llargada desconeguda. Hi ha perles disperses per algunes caselles, però no saps en quines ni quantes en total. En Karel ha de recórrer tot el corredor d'un extrem a l'altre i recollir totes les perles que trobi pel camí.

Pista: usa un while front_is_clear(): com a bucle principal. Dins, mou-te i comprova amb if pearl_here(): si cal recollir alguna cosa.