Capítol 8

Mentre

El for va molt bé quan saps exactament quantes vegades vols repetir una acció. Però, i si no ho saps?
En aquest capítol una instrucció nova, que es diu while

Quantes vegades he de repetir? No ho sé...

Imagina que en Karel ha d'avançar fins a topar amb una paret.
El passadís pot ser curt, llarg o molt llarg.
Com podem fer-ho, si no sabem quantes caselles hem d'avançar?
No sabem si escriure: range(3) o range(10).

La nostra estratègia serà aquesta: «mentre en Karel tingui el camí lliure, que vagi avançant».

Repetir mentre poguem

while comprova una condició i executa un bloc d'instruccions repetidament mentre la condició sigui certa.

Llegeix aquest exemple:

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í va fent, fins que hi hagi un obstacle, perquè llavors, s'atura.

Compara l'efecte de les instruccions for i while:

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

# while: avances 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».

Prem ▶ Executa

En Karel ha avançat fins al final del passadís, sense que en el codi sapiguem quina és la llargada. Si el món hagués tingut vint caselles, aquest codi hauria funcionat igualment.

Qualsevol condició funciona amb 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, com a mínim, una perla.

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 la dreta.

while i if junts

while i if es combinen molt bé. El while controla fins quan continua la iteració; 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:

Prem ▶ Executa

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í. Després ha de donar mitja volta i deixar totes les perles, a mesura que va tornant, totes en caselles consecutives.

Pista: usa un while front_is_clear(): com a iteració principal. Dins d'aquesta iteració, comprova amb if pearl_here(): si cal recollir una perla i, si n'hi ha, la reculls amb grab(). Abans de tornar a començar la iteració, avances una casella fent move(). Ara hauràs arribat al final, quan surtis del while: fes mitja volta amb turn_around(). Llavors, ves tornant i a cada pas, si encara tens perles a la motxilla, fas un drop(). Per saber si tens perles, has de fer servir la pregunta bag_is_full().