Werk herhalen met lussen
Als een lus nooit eindigt
Een for-lus over een vaste, eindige verzameling stopt als de verzameling op is. Dat is het soort for-lus dat je tot nu toe hebt geschreven.
Een while-lus belooft dat niet. Ze stopt als de voorwaarde False wordt en niets dwingt dat af. Blijft de voorwaarde altijd True, dan blijft de lus zich herhalen. Dat is een oneindige lus en elke programmeur schrijft er uiteindelijk een.
In deze les leer je ze herkennen, stoppen en voorkomen. De voorbeelden zijn bewust kapot, dus lees ze in plaats van ze uit te voeren. Op deze pagina staan geen Run-knoppen.
De klassieker: niets verandert
count = 3
while count > 0:
print(count)
De voorwaarde vraagt naar count. Het blok verandert count nooit. Die blijft altijd 3, de voorwaarde blijft altijd True en Python blijft 3 afdrukken totdat iets buiten het programma het stopt.
Bij deze afteller ontbreekt de regel die count verlaagt.
De subtiele variant: veranderen in de verkeerde richting
count = 3
while count > 0:
print(count)
count = count + 1
Hier verandert count wel, dus op het eerste gezicht lijkt de lus compleet. Maar de waarde gaat de verkeerde kant op. count stijgt voorbij 4, 5, 6 en raakt elke ronde verder verwijderd van het einde.
Lees de voorwaarde en de wijziging als een paar. De voorwaarde zegt dat de lus eindigt als count de waarde 0 bereikt. De wijziging moet count dus naar 0 toe bewegen.
De verborgen variant: de wijziging zit vast in een if
attempts = 0
answer = "no"
while answer == "no":
attempts += 1
if attempts > 10:
answer = "yes"
print("Finally")
Deze eindigt wel. Verander de voorwaarde in de if en de wijziging wordt nooit bereikt:
attempts = 0
answer = "no"
while answer == "no":
attempts += 1
if attempts < 0:
answer = "yes"
print("Finally")
Het aantal pogingen begint bij nul en stijgt, dus attempts < 0 wordt nooit waar. De regel die answer verandert bestaat, maar Python bereikt die nooit. Als de wijziging van een voorwaardevariabele in een if staat, vraag je dan af of die if waar zal worden.
Vergelijk de drie paden hieronder: één beweegt de voorwaarde naar False, één maakt geen voortgang en één gaat er verder vandaan. Bekijk vooral de pijlen. Ends betekent eindigt, no progress geen voortgang en wrong way de verkeerde richting; true forever betekent altijd waar.
In het diagram is count -= 1 de korte vorm van count = count - 1, net zoals count += 1 er één bij optelt.

Wat er op Python Land gebeurt
Als je er toch een uitvoert, stop die dan en bekijk de voorwaarde en de wijziging voordat je opnieuw probeert. Wat je ziet, hangt af van waar de les draait.
In een browserles draait je code in een worker op de pagina. Uitvoer verschijnt terwijl het programma draait, dus een eindeloze lus die afdrukt kan de terminal snel vullen. Een lus zonder print() kan stil lijken. Na een paar seconden verschijnt boven de editor een waarschuwing:
⚠ This does not look like it is finishing.
Ernaast staat een knop Stop. Klik daarop. De terminal legt uit dat het programma mogelijk een lus bevat die nooit eindigt of gewoon veel meer werk doet dan verwacht.
Stoppen start Python op de achtergrond opnieuw, dus de volgende uitvoering heeft iets langer nodig om te beginnen. Je code in de editor blijft behouden.
De debugger gebruikt een andere veiligheidsgrens. Hij legt maximaal 1.000 gebeurtenissen vast voordat hij het resultaat toont. Bij een eindeloze lus opent hij een afgekort uitvoeringsverloop in plaats van de pagina te laten vastlopen. Je kunt de herhaalde regels en veranderende variabelen bekijken en daarna Stop in de debuggerwerkbalk gebruiken om te stoppen. De pagina herladen is niet nodig.
In een serverles verandert de knop Run in Stop terwijl je programma wacht of werkt. Gebruik die om een vastgelopen interactieve uitvoering te beëindigen. Serveruitvoering heeft ook tijd- en uitvoerlimieten, maar een interactieve sessie gebruikt niet dezelfde korte tijdslimiet als een inzending. Wacht dus niet tot die vanzelf stopt.
Een time-out of Stop-waarschuwing bij een les die snel klaar hoort te zijn, is een sterke aanwijzing dat een lus niet eindigt. Het is informatie, geen berisping.
Controleer een while-lus voordat je haar uitvoert
Drie vragen, in deze volgorde:
Naar welke variabele vraagt de voorwaarde?
Welke regel in het blok verandert die variabele?
Brengt die wijziging de variabele dichter bij het beëindigen van de lus?
Als je bij vraag 2 geen regel kunt aanwijzen, heb je de fout al gevonden voordat je iets uitvoert. Dat kost een paar seconden en bespaart je een afgebroken uitvoering.
Soms is het eerlijke antwoord dat een while-lus het verkeerde hulpmiddel is. Als je één keer per item in een vaste, eindige verzameling herhaalt en de lus die verzameling niet uitbreidt, stopt een for-lus zodra de items op zijn en is er geen teller nodig.
Lussen die bewust blijven draaien
Niet elke eindeloze lus is een fout. Dit zie je in echte programma’s:
while True:
...
True is geen vergelijking. Het is gewoon de booleaanse waarde True, dus de voorwaarde kan niet vanzelf False worden. Programma’s die op invoer wachten of een menu tonen totdat de gebruiker stopt, worden vaak zo geschreven.
Zo’n lus heeft een bewuste uitgang in het blok nodig. Precies dat leer je in de volgende les.
Welke van deze lussen eindigt nooit?
total = 0
while total < 5:
print(total)
total = total - 1
Een while-lus in je programma eindigt nooit. Wat kun je het beste eerst controleren?
Wat je moet onthouden
Een oneindige lus is geen ramp. Het is een fout met een duidelijk symptoom, een stopmogelijkheid als je er een tegenkomt en meestal een oplossing van één regel. Leer de drie vragen en stel ze voordat je een while-lus uitvoert. Dan is het al snel niet meer spannend.
Opdracht
In deze les is er niets om uit te voeren. Lees de kapotte voorbeelden zorgvuldig en beantwoord beide vragen.
Zorg voordat je verdergaat dat je kunt uitleggen:
waarom een
for-lus over een vaste, eindige lijst die ze niet uitbreidt wel eindigt, terwijl eenwhile-lus haar voorwaarde altijd waar kan houden;de drie manieren waarop een
while-lus niet eindigt: geen wijziging, een wijziging in de verkeerde richting en een wijziging in eenifdie nooit waar is;wat verschijnt als een browserprogramma niet klaar is en wat de knop Stop doet;
hoe Step een eindeloze lus beperkt tot 1.000 vastgelegde gebeurtenissen en het afgekorte uitvoeringsverloop laat bekijken;
de drie vragen die je over een
while-lus moet stellen voordat je haar uitvoert.