Stel dat je de gebruiker vraagt naar vijf getallen, deze optelt en het totaal weergeeft. Met wat je tot nu toe gezien hebt, zou dat code er als volgt kunnen uitzien:
getal1 = int(input( "Getal 1: " ))
getal2 = int(input( "Getal 2: " ))
getal3 = int(input( "Getal 3: " ))
getal4 = int(input( "Getal 4: " ))
getal5 = int(input( "Getal 5: " ))
print( "Totaal is", getal1 + getal2 + getal3 + getal4 + getal5 )
Dit lukt nog omdat het aantal gevraagde getallen beperkt is. Maar wat als je 100 getallen moet opvragen? Dan zou je bovenstaande regel 100 keer moeten herhalen??? Dit kan eenvoudiger door een loop te gebruiken.
De eerste loop die hier besproken wordt is de while
loop.
Een while
statement bestaat uit een test gevolgd door één of meerdere acties,
waarbij de acties alleen worden uitgevoerd zolang de test True
oplevert.
De syntax van een while
statement ziet er als volgt uit:
while <boolean expressie>:
<acties>
Net als bij een if
statement, test een while
statement een boolean
expressie. Wanneer de expressie True
oplevert, wordt het blok code
onder de while
uitgevoerd. In tegenstelling tot een if
statement
gaat Python meteen na het uitvoeren van het blok code terug naar
de boolean expressie naast de while
en test die opnieuw. Wanneer de
expressie nog steeds True
oplevert, wordt het blok code een tweede maal
uitgevoerd. Na uitvoering keert Python nogmaals terug naar de
boolean expressie, en dit telkens opnieuw tot de boolean
expressie False
oplevert. Pas dan slaat Python het blok code
onder de while
over en gaat verder met het vervolg van de code.
Merk op dat als de boolean expressie meteen False
oplevert het blok code onder de while
onmiddellijk wordt overgeslagen, net zoals gebeurt bij een if
statement.
Dit alles wordt duidelijker met onderstaande voorbeelden.
while
loop, een eerste voorbeeldVoorbeeld: print de nummers 1 tot en met 5.
Met een while
loop kan de code er als volgt uit zien:
num = 1
while num <= 5:
print( num )
num += 1
print( "Klaar" )
Het stroomdiagram bij deze code ziet er als volgt uit 8.11.
Het is van essentieel belang dat je deze code begrijpt. We overlopen elke stap.
De eerste regel initialiseert een variabele num
en krijgt de waarde 1. Dit
is de eerste waarde die afgedrukt moet worden.
De while
loop start en voert de boolean expressie num <= 5
uit. num
heeft waarde 1
wat kleiner is dan 5 dus de expressie levert True
. Het blok code onder de while
wordt
uitgevoerd (code met insprong).
De eerste regel van het blok code print de waarde van num
, dus 1.
De tweede regel telt 1 op bij de waarde van num
die nu de waarde 2 krijgt.
Python gaat vervolgens terug naar de boolean expressie. De laatste print() regel wordt dus nog niet uitgevoerd omdat de loop nog niet afgelopen is.
Omdat num
de waarde 2 heeft (nog steeds kleiner dan 5) evalueert de boolean expressie nog steeds als True
.
Het blok code wordt dus nogmaals uitgevoerd: 2 wordt afgedrukt, num
krijgt waarde 3, en de code keert terug bij de boolean expressie.
Dit wordt telkens opnieuw herhaald tot num
de waarde 6 heeft.
Nu evalueert de boolean expressie als False
(6 is immers niet kleiner dan of
gelijk aan 5). Het blok code (met insprong) wordt
overgeslagen en Python gaat verder met het vervolg van het programma.
In dit voorbeeld is dat de laatste regel code die het woord “Klaar”
afdrukt, en het programma eindigt.
Wijzig de code hierboven zodat de getallen 1, 3, 5, 7, en 9 afgedrukt worden. Test uit in Spyder.
while
loop, een tweede voorbeeldVraag de gebruiker naar vijf getallen en bereken de som. De code kan er als volgt uitzien:
totaal = 0
teller = 0
while teller < 5:
totaal += int(input( "Geef een getal: " ))
teller += 1
print( "Totaal is", totaal )
Bestudeer bovenstaande code. Er worden twee variabelen gebruikt.
totaal
wordt gebruikt om de som te kunnen berekenen. Deze variabele
start met waarde nul omdat er bij het begin van het programma nog geen getallen
ingegeven zijn en de som dus nul is. Telkens wanneer de loop wordt doorlopen,
verhoogt de waarde van totaal
met het ingevoerde getal.
De variabele teller
wordt gebruikt om na te gaan hoe vaak de loop doorlopen is.
Bij het begin van het programma is de loop nog niet
doorlopen dus start teller
met waarde nul. De loop moet in totaal vijf keer uitgevoerd
worden. De boolean expressie test dus of teller
kleiner is dan 5. Iedere keer dat
de loop doorlopen wordt, moet de waarde van teller
met 1 verhoogd worden zodat na vijf keer doorlopen
de boolean expressie False
is en overgegaan kan worden naar de rest van de code.
Misschien lijkt het je logischer om teller
te laten starten bij 1 en teller <= 5
te testen. Dit is echter niet gebruikelijk. Wij gaan dat dan ook niet doen en volgen
de gebruikspraktijk van programmeurs.
Opmerking: De variabele teller
is wat programmeurs een “wegwerp
variabele” noemen. Het enige doel van deze variabele is te tellen hoe
vaak de loop doorlopen is. Programmeurs kiezen vaak één-letter namen
voor dit soort variabelen, meestal i
of j
. In het voorbeeld werd voor de
duidelijkheid de naam teller
gekozen, maar i
was beter geweest.
Wijzig de code hierboven zodat niet alleen het totaal maar ook het gemiddelde wordt afgedrukt. Test uit in Spyder.
In het begin van dit hoofdstukje werd een voorbeeldcode gegeven waarbij de gebruiker
gevraagd werd vijf getallen in te geven. De prompt “Getal x
: “ werd gebruikt,
waarbij x
een cijfer voorstel. Kun je de code vanuit “while
loop, een tweede voorbeeld”
aanpassen zodat de prompt er hetzelfde uitziet als in het beginvoorbeeld? Behoud de loop structuur.
while
loop onder controle van de gebruikerIn voorgaande voorbeeld werd de gebruiker beperkt tot de invoer van vijf getallen. Het gebeurt echter regelmatig dat het aantal op te vragen data variabel is en de gebruiker zoveel getallen kan ingeven als hij wil, inclusief helemaal geen getallen. Dat betekent dat je vooraf niet weet hoe vaak de loop doorlopen moet worden maar dat de gebruiker dit bepaalt. Er moet dus een mogelijkheid ingebouwd worden waarbij de gebruiker aangeeft dat hij klaar is met de invoer.
De code hieronder laat zien hoe je een while
loop kunt opzetten die de
gebruiker zoveel getallen laat ingeven als gewenst. De gebruiker stopt
met het ingeven van getallen door -in dit geval- een nul in te geven. Het totaal wordt
afgedrukt wanneer de loop beëindigd is.
num = -1 # beginwaarde voor num is -1, verschillend van 0
totaal = 0 # deze variabele geeft de som, startend bij beginwaarde 0
while num != 0:
num = int(input( "Geef een getal: " )) # num krijgt telkens de waarde van het ingevoerde getal
totaal += num
print( "Totaal is", totaal )
Deze code functioneert maar is niet gebruikelijk. Er zitten minimaal twee
schoonheidsfouten in. Ten eerste wordt num
geïnitialiseerd op -1. Deze
waarde heeft in principe geen betekenis maar moet wel verschillend van 0
zijn zodat de loop minstens één keer uitgevoerd wordt. Ten tweede stopt
de loop niet meteen als de gebruiker nul ingeeft. De ingave van de gebruiker
wordt eerst opgeteld bij totaal
. In dit geval wijzigt de waarde van totaal
niet.
Maar indien vooraf gesteld wordt dat de gebruiker de loop kan eindigen door
bijvoorbeeld een negatief getal in te geven, dan klopt het eindtotaal niet meer.
Een mogelijke oplossing ziet er als volgt uit:
num = int(input( "Geef een getal: " ))
totaal = 0
while num != 0:
totaal += num
num = int(input( "Geef een nummer: " ))
print( "Totaal is", totaal )
Dit lost bovenstaande schoonheidsfouten op, maar introduceert er wel
een nieuwe, namelijk de herhaling van de input()
functie.
Hoe je dat kunt oplossen volgt later.
Maak een loop die de gebruiker een aantal getallen laat ingeven totdat hij nul ingeeft. Druk het totaal en het gemiddelde af. Vergeet niet te testen met nul getallen ingeven, en met een aantal keer hetzelfde getal ingeven.
De code hieronder begint bij nummer 1 en telt nummers op totdat het een nummer tegenkomt dat gekwadrateerd, deelbaar is door 1000. De loop bevat een fout. Kijk of je de fout weet te vinden zonder de code uit te voeren!
nummer = 1
totaal = 0
while (nummer * nummer) % 1000 != 0:
totaal += nummer
print( "Totaal is", totaal )
De titel boven deze paragraaf gaf het antwoord al: deze
code bevat een loop die nooit eindigt. Bij uitvoering lijkt het
alsof het programma “hangt”; wel draait maar niks doet. Het programma is echter
bezig een nooit-eindigende optelling uit te voeren. nummer
begint immers bij 1 maar
wordt in de loop nooit gewijzigd. Daarom wordt de boolean expressie nooit
False
. Dit is een “eindeloze loop.” Dit soort loops zijn het grootste
gevaar als je while
loops implementeert.
Als je deze code uitvoert in IDLE, kun je de uitvoering afbreken door
Ctrl-C
te drukken.
Om eindeloze loops te voorkomen, maak je er best de gewoonte van, wanneer je begint met het
schrijven van een while
loop, onmiddellijk een regel code toe te voegen die
een wijziging maakt in hetgeen getest wordt. Bijvoorbeeld, als je schrijft while i < 10
,
schrijf er dan meteen de regel i += 1
onder. Daarna voeg je de
rest van de code tussen deze twee regels toe.
Verbeter de code hierboven zodat het geen eindeloze loop meer is.
while
loop oefeningenOefen een paar eenvoudige while
loops.
Schrijf code die aftelt. Er wordt begonnen met een specifiek nummer, bijvoorbeeld 10. Dan telt de code af naar nul, waarbij ieder nummer geprint wordt (10, 9, 8, …). Nul wordt niet geprint, maar in plaats daarvan drukt het programma de tekst “Start!” af.
De faculteit van een positief geheel getal is gelijk aan dat getal,
vermenigvuldigd met alle positieve gehele getallen die kleiner zijn
(exclusief nul). Je schrijft de faculteit als het getal met een
uitroepteken erachter. Bijvoorbeeld, de faculteit van 5 is
\(5! = 5 * 4 * 3 * 2 * 1 = 120\). Schrijf code die de faculteit van een
getal berekent. Test het programma niet met getallen die hoog zijn, want
de faculteit stijgt exponentieel (het is voldoende om tot 10! te
testen). Hint: Om dit met een while
loop te doen, moet je twee
variabelen gebruiken: één die aan het einde van de loop het antwoord
bevat, en één die de huidige factor bevat. In de loop vermenigvuldig je
het antwoord met de factor, alvorens 1 van de factor af te trekken.
Initialiseer deze variabelen met de juiste waarden voor de loop.