Hoewel for loops een gemakkelijke syntax hebben en zeer veilig zijn in gebruik, toch hebben we nood aan een tweede manier om herhaling in onze programmeercode in te bouwen. Waarom? Wel, for loops eisen dat we op voorhand weten hoeveel keer we moeten herhalen. Voor veel problemen is dit prima. Echter, soms weten we helemaal niet a priori hoeveel herhalingen er nodig zullen zijn om tot het gewenste resultaat te komen. Een while loop legt deze eis niet op, maar herhaalt zolang een bepaalde voorwaarde (geformuleerd als een boolean expressie) geldt.
Een voorbeeld. Je bent pannenkoeken aan het bakken. Je doet deeg in de pan, maar weet op voorhand niet hoe lang het deeg in de pan moet blijven vooraleer je die mag omdraaien. Wat je wél weet:
Zolang het deeg lopend is aan de bovenzijde, wacht je met draaien. Van zodra het deeg niet meer lopend is, is het tijd om de pannenkoek om te draaien!
Enkele voorbeelden zullen straks verduidelijken hoe while loops worden gebruikt, maar eerst bespreek ik Python’s syntax hiervoor:
while boolean expressie :
acties
Deze syntax is heel gelijkaardig aan het conditionele if
statement.
We herkennen opnieuw de boolean expressie die ofwel True ofwel False kan zijn, het dubbelpunt na de boolean expressie en de insprong op de volgende lijn(en).
Net als bij een if statement, test een while statement dus een boolean expressie. Als de expressie True oplevert, worden de acties uitgevoerd.
Eigenlijk is dit identiek aan het if statement.
Echter, in tegenstelling tot een if statement, gaat Python na het uitvoeren van de acties terug naar de boolean expressie, en test die opnieuw.
Is de boolean expressie nog steeds True, dan worden de acties nogmaals uitgevoerd. Eens uitgevoerd, keert Python wederom terug naar de boolean expressie.
Dit wordt herhaald zolang de boolean expressie True is, en totdat de boolean expressie False oplevert.
Pas op dat moment slaat Python de acties over en gaat onder de insprong (En: indentation) verder.
Wanneer de Python interpreter de code leest en arriveert bij de while loop, zijn er verschillende scenario’s mogelijk:
while i < 10:
, dan schrijf je er meteen de regel i = i + 1
onder, en pas daarna begin je de gewenste acties toe te voegen.We laten even het gevaar van een oneindige loop links liggen en concentreren ons op de syntax van een while loop via een voorbeeld waarin we op zoek gaan naar volkomen kwadraten (dit zijn kwadraten van gehele getallen):
# aanmaak variabelen
num = 1
# berekeningen en # uitvoer
while num <= 4:
print ( num **2 , end = ' ' )
num = num + 1
print ( " Enzovoort " )
Dit programma geeft als uitkomst “1 4 9 16 Enzovoort”.
We lezen de code lijn na lijn. Eerst slaan we de integer 1 op in de variabele die we de naam num geven. Dan start een while loop:
num <= 4
wordt een eerste keer gecontroleerd. Kijk even in de variabele num, daarin zit de integer 1. Omdat 1 inderdaad kleiner of gelijk is aan 4, is de boolean expressie True.
We krijgen toegang tot de body van de while loop. Die body bevat twee ingesprongen lijnen, er zijn dus twee acties. Ten eerste printen we de waarde van num gekwadrateerd.
We verwachten dus dat er een 1 wordt geprint. Ten tweede krijgt num een nieuwe waarde. De toekenningsoperator kent het rechterlid toe aan de variabelenaam die links van het gelijkheidsteken staat.
Rechts staat num + 1
, wat gelijk is aan 2. We kennen dus 2 toe aan de variabele met de naam num.
Typisch aan een while loop, en meteen het verschil met een if statement, is dat we na de acties opnieuw naar de boolean expressie worden gestuurd.num <= 4
. We kijken in de variabele num, daarin zit nu de integer 2.
Omdat 2 inderdaad kleiner of gelijk is aan 4, is de boolean expressie True.
We krijgen opnieuw toegang tot de body van de while loop, die eerst de variabelewaarde 2 kwadrateert en print en vervolgens de variabelewaarde met één eenheid vergroot waardoor num de waarde 3 krijgt.
Daarna worden we opnieuw naar de boolean expressie gestuurd.num <= 4
geeft nu False, want 5 is groter dan 4.We krijgen geen toegang meer tot de body van de while loop en voeren enkel nog de laatste lijn uit dewelke “Enzovoort” doet verschijnen.
Akkoord, in bovenstaand voorbeeld was een hele while constructie eigenlijk niet nodig. Met onderstaande code kwamen we tot hetzelfde resultaat.
num = 1
print ( num **2 , end = ' ' )
num = num + 1 # num wordt nu 2
print ( num **2 , end = ' ' )
num = num + 1 # num wordt nu 3
print ( num **2 , end = ' ' )
num = num + 1 # num wordt nu 4
print ( num **2 , end = ' ' )
print ( " Klaar " )
Of, zonder het gebruik van de variabele num kon het nog veel korter, maar daar houden we al helemaal niet van:
print ( 1**2 ,2**2 ,3**2 ,4**2 , " Klaar " )
Waarom is deze code niet goed? Het geeft toch hetzelfde resultaat? Wel, voor beide alternatieven hebben we code gekopiëerd en geplakt. En er is een heel belangrijke redenen om ten allen tijde kopie-plakken in programmeercode te vermijden. Loops zijn uitbreidbaar. Willen we de code doen werken voor een ander aantal getallen, bijvoorbeeld alle kwadraten van 1 tot en met 10 (dus met resultaat “1 4 9 16 25 36 49 64 81 100 Enzovoort”), hoeven we slechts één getalletje aan te passen, zonder opnieuw aan onze code te prutsen. Nogmaals: een computer geraakt een taak niet beu, er is dus geen enkel probleem om de loop duizenden keren te laten uitvoeren. Dat in tegenstelling tot het duizend keer manueel kopiëren van een stuk code.
We bekijken een tweede voorbeeld, waarin we de gebruiker vragen om vijf getallen en daarvan de som berekenen:
# aanmaak variabelen
totaal = 0
teller = 0
# berekeningen
while teller < 5:
totaal += int ( input ( " Geef een geheel getal : " ) )
teller += 1
# uitvoer
print ( " De som van de gegeven getallen is " , totaal )
Bestudeer bovenstaande code. Er worden twee variabelen gebruikt. totaal wordt gebruikt om de vijf getallen in op te tellen.
totaal begint op nul, omdat bij de start van het programma nog geen getallen ingegeven zijn, dus het totaal is nul. teller wordt gebruikt om te tellen hoe vaak de loop doorlopen is.
Omdat de loop vijf keer uitgevoerd moet worden, start teller op nul en de boolean expressie teller < 5
test of teller kleiner is dan 5.
Dus teller moet iedere keer dat de loop doorlopen wordt met 1 verhoogd worden, zodat na vijf keer doorlopen de boolean expressie False geeft.
Je vraagt je misschien af waarom ik teller liet starten bij 0 en de boolean expressie liet testen of teller < 5
.
Waarom begon ik niet bij teller = 1 en testte ik niet teller <= 5
? Het resultaat zou niets veranderen.
De reden is gewoonte: programmeurs zijn gewend om indices bij 0 te laten beginnen en te tellen “tot” een getal (niet “tot en met”).
Als je verder gaat met programmeren zul je ontdekken dat de meeste code deze gewoonte naleeft. De meeste standaard programmeerconstructies die indices gebruiken, doen het ook zo.
Mijn advies is daarom om eraan te wennen, het zal ook jouw code gemakkelijker leesbaar maken.
Nog een opmerking. De variabele teller is wat programmeurs een “wegwerp variabele” (En: “Dummie”) noemen. Het enige doel van deze variabele is te tellen hoe vaak de loop doorlopen is. De variabele heeft geen echte betekenis, noch vóór de loop of in de loop, noch nadat de loop afgelopen is. Programmeurs kiezen vaak één-letter namen voor dit soort variabelen, meestal i of j (ik neem aan dat i ooit begonnen is als afkorting voor “integer”, en j gekozen is omdat het in het alfabet na i komt). In het voorbeeld heb ik voor de duidelijkheid de naam teller gekozen, maar i was even acceptabel geweest.