1.3 Herhaling
Dezelfde bewerking meermaals, zonder ze meermaals op te schrijven
Na deze les kan je:
- een
for-lus schrijven die een vast aantal keren herhaalt rangegebruiken om te bepalen hoe vaak en met welke waarden- de waarden in een lus volgen met een trace table
- herkennen welke regels binnen de lus horen en welke erbuiten
De vorige les eindigde bij een programma dat een totaal kan bijhouden, zij het met één regel per artikel. Een mandje met twintig artikelen vergt dan twintig regels, en een teller die tot honderd loopt honderd. In deze les vervang je zo’n reeks door twee regels.
1 Hetzelfde, tien keer
Neem de tafel van zeven. Met wat je al weet uit de vorige lessen, ziet ze er zo uit.
Tien regels, en ze verschillen op precies één plaats: het getal dat van \(1\) tot \(10\) loopt. Al de rest staat er tien keer identiek bij. Voor zo’n reeks bijna identieke instructies heeft Python een aparte vorm.
2 De lus
Een lus voert een blok regels meermaals uit. De vorm ligt vast.
De naam i is de lusvariabele. Ze krijgt bij elke iteratie een volgende waarde uit range(1, 11), en dat zijn de getallen van \(1\) tot en met \(10\). Het geïndenteerde blok wordt telkens opnieuw uitgevoerd, met die ene waarde ingevuld.
Van range moet je twee vormen kennen.
| vorm | levert |
|---|---|
range(5) |
\(0, 1, 2, 3, 4\) |
range(1, 11) |
\(1, 2, \ldots, 10\) |
De bovengrens hoort er in beide gevallen niet bij. Dat oogt vreemd en het heeft een voordeel: range(5) telt precies vijf waarden af, en range(a, b) telt er precies \(b - a\).
Tien regels zijn twee regels geworden, en de tafel van acht kost geen enkele regel extra.
3 Wat er bij elke iteratie verandert
De accumulator uit de vorige les hoort thuis in een lus. Hieronder telt een programma de getallen van \(1\) tot en met \(4\) op.
De trace table krijgt er een rij per iteratie bij, en een kolom voor de lusvariabele.
| iteratie | i |
totaal |
|---|---|---|
| voor de lus | 0 |
|
| 1 | 1 |
1 |
| 2 | 2 |
3 |
| 3 | 3 |
6 |
| 4 | 4 |
10 |
| na de lus | 4 |
10 |
Twee dingen vallen op. De lusvariabele krijgt haar waarde van range en jij kent ze nooit zelf toe. De accumulator daarentegen draagt zijn waarde van de ene iteratie naar de volgende, en daarom moet hij vóór de lus een beginwaarde krijgen.
De laatste rij zegt dat i blijft bestaan nadat de lus is afgelopen, met de waarde die ze in de laatste iteratie kreeg. Bouw daar verder niets op: een lusvariabele hoort bij haar lus, en je gebruikt ze enkel binnen het geïndenteerde blok.
4 Binnen of buiten de lus
De indentatie uit les 1.1 bepaalt hier wat er herhaald wordt. Alles wat geïndenteerd staat, gebeurt bij elke iteratie. Alles wat daarna tegen de kantlijn staat, gebeurt één keer, wanneer de lus afgelopen is.
In de cel hierboven staat print(totaal) buiten de lus, dus verschijnt enkel het eindresultaat 10. Zet je die regel geïndenteerd, dan verschijnen er vier regels, namelijk de tussenstanden 1, 3, 6 en 10. Beide zijn zinvol, en welke je nodig hebt, hangt af van wat je wil zien.
Zet de beginwaarde van een accumulator vóór de lus, niet erin. Staat totaal = 0 geïndenteerd, dan begint het totaal bij elke iteratie opnieuw bij nul en blijft er op het einde enkel de laatste waarde over.
5 Een lus in een functie
Een lus in een functie levert iets op dat je overal kan hergebruiken.
De n + 1 zorgt ervoor dat n zelf meetelt, aangezien de bovengrens er niet bij hoort. Merk op dat de drie bouwstenen van de vorige lessen hier samenkomen: een functie die een waarde teruggeeft, een accumulator die aangroeit, en een lus die het werk herhaalt.
De som van de eerste \(n\) getallen kan ook zonder lus:
\[ 1 + 2 + \ldots + n = \frac{n(n+1)}{2} . \]
Voor de uitkomst maakt dat niets uit, voor het werk wel. som_tot(100) doet honderd iteraties, de formule doet één berekening. Bij honderd getallen merk je daar niets van, bij een miljard wel. Een herhaling vervangen door één formule is een van de sterkste ingrepen die je op een programma kan doen.
6 Conclusie
Een lus voert hetzelfde blok meermaals uit, met bij elke iteratie een andere waarde in de lusvariabele. Wat geïndenteerd staat, hoort bij de lus, en wat erna komt gebeurt één keer. Een accumulator krijgt zijn beginwaarde ervoor en draagt zijn waarde doorheen alle iteraties.
Wat een for-lus niet kan, is stoppen zodra iets waar is. Ze telt een vast aantal iteraties af en meer niet. Om een programma te laten kiezen heb je voorwaarden nodig, en die komen later aan bod.
In de volgende les loopt een lus niet over getallen maar over de letters van een tekst, en dan wordt ze pas echt bruikbaar.
7 Begrippen
- lus (loop): een blok regels dat meermaals na elkaar uitgevoerd wordt.
- lusvariabele (loop variable): de naam die bij elke iteratie een volgende waarde krijgt.
- iteratie (iteration): één keer het blok van de lus uitvoeren.
range: de reeks getallen die eenfor-lus afloopt, met de bovengrens er niet bij.
8 Oefeningen
Beantwoord zonder de computer.
Hoe vaak wordt de geïndenteerde regel uitgevoerd bij
for i in range(4):, en welke waarden krijgti?Maak een trace table voor de code hieronder en geef het eindresultaat.
Wat verschijnt er als je in die code
print(totaal)geïndenteerd zet, zodat hij binnen de lus valt?
TipAntwoorda. Vier keer, met
igelijk aan \(0\), \(1\), \(2\) en \(3\). De bovengrens \(4\) hoort er niet bij.b.
14.iteratie itotaalvoor de lus 01 112 253 314c. Drie regels, namelijk
1,5en14. Je ziet dan de tussenstanden in plaats van enkel het eindresultaat.Vul de cel hieronder aan.
Je hebt de getallen van \(1\) tot en met \(10\) nodig, en de bovengrens hoort er niet bij.
De functie hieronder moet het product van de getallen van \(1\) tot en met
nteruggeven. Voorngelijk aan \(5\) is dat \(1 \cdot 2 \cdot 3 \cdot 4 \cdot 5\), dus \(120\).Bij een som gebruik je
+=. Voor een product bestaat*=, dat op dezelfde manier werkt.De beginwaarde is hier \(1\) en niet \(0\), aangezien alles maal nul weer nul is.
Schrijf
gemiddelde_tot(n), die het gemiddelde teruggeeft van de getallen van \(1\) tot en metn. Voorngelijk aan \(10\) is dat5.5.som_tothierboven telt die getallen al op en je kan haar hier aanroepen. Een gemiddelde is die som gedeeld door het aantal getallen, en dat delen gebeurt één keer.Er verschijnt
5.5. De deling staat na de lus en niet erin, aangezien ze binnen de lus op een onvolledig totaal zou werken. Dat een deling met/een kommagetal oplevert, ken je uit les 1.2.Een spaarrekening van \(1000\) euro brengt elk jaar \(5\%\) op, telkens op het bedrag dat er op dat ogenblik staat. Bereken hoeveel er na tien jaar staat, en toon met
int()de volle euro’s.Vijf procent van
kapitaaliskapitaal * 0.05, en dat komt er elk jaar bij. De lus moet tien keer lopen, dus volstaatrange(10).Er verschijnt
1628. Het kommagetal zelf heeft een lange staart na de komma, enint()houdt daarvan de volle euro’s over. Merk op dat de lusvariabele in het blok niet voorkomt:range(10)dient hier enkel om tien keer af te tellen.
In de rij van Fibonacci is elk getal de som van de twee die eraan voorafgaan, en ze begint met \(1\) en \(1\). Laat de eerste tien getallen van de rij verschijnen. Je hebt twee namen nodig die bij elke iteratie opschuiven.
Zodra je
huidigeeen nieuwe waarde geeft, is de oude nergens meer te vinden. Bewaar ze eerst onder een derde naam, net zoals bij het verwisselen in les 1.2.Er verschijnen
1,1,2,3,5,8,13,21,34en55. De derde naam is nodig omdat de toekenning aanhuidigede waarde overschrijft dievorigedaarna nog nodig heeft.