Beslissingen nemen — if, elif, else
Verschillende paden kiezen afhankelijk van een voorwaarde, waarom inspringing in Python betekenis heeft, en de stille fout die ontstaat als voorwaarden in de verkeerde volgorde staan.
Hoe wil je leren?
Het probleem dat we oplossen
In het vorige hoofdstuk hebben we leren vragen stellen — is age >= 18 waar of onwaar? Maar het programma wist het antwoord en deed er niets mee; het printte alleen True of False.
Nu is het tijd om op dat antwoord te handelen. Eén pad als de voorwaarde waar is, een ander pad als dat niet zo is. Dit is het moment waarop code niet langer een lijst met stappen is, maar begint met beslissingen nemen.
En hier verschilt Python van veel andere programmeertalen: welke regels binnen een voorwaarde vallen en welke erbuiten, wordt bepaald door whitespace. Er zijn geen accolades {}. Het voelt eerst vreemd en daarna ga je het juist fijn vinden — want code die er georganiseerd uitziet, is ook georganiseerd.
Aan het einde van dit hoofdstuk kun je
- Code voorwaardelijk uitvoeren met
if - Een alternatief geven met
else, en meerdere metelif - Correct inspringen, en een
IndentationErrorlezen en oplossen - Uitleggen waarom de volgorde van voorwaarden ertoe doet — de grootste valkuil hier
- Een voorwaarde in een andere voorwaarde plaatsen, en herkennen wanneer je dat beter kunt vermijden
Voorkennis: True en False — leren vragen stellen.
De eenvoudigste vorm
age = 22
if age >= 18:
print("You may enter")
print("Program finished")You may enter
Program finishedDe vorm bestaat uit drie onderdelen:
- Het woord
if, gevolgd door een voorwaarde - Een dubbele punt
:aan het eind van de voorwaarde — die weglaten is de meest voorkomende fout - De regels die volgen, ingesprongen met vier spaties — die ingesprongen regels zijn wat de voorwaarde bepaalt
Als age 15 was geweest, dan had de eerste print niet gedraaid, maar de laatste wel — omdat die buiten de voorwaarde staat.
Inspringing bepaalt de betekenis
Deze twee programma's bestaan uit bijna dezelfde tekens en gedragen zich totaal verschillend:
score = 30
if score >= 50:
print("Passed")
print("Certificate issued")Draai dit en er verschijnt niets in de terminal — beide regels staan binnen de voorwaarde, en de voorwaarde is onwaar.
score = 30
if score >= 50:
print("Passed")
print("Certificate issued")Certificate issuedDe tweede print staat nu buiten de voorwaarde, dus die wordt altijd uitgevoerd — en er is zojuist een certificaat uitgegeven aan iemand die niet is geslaagd. Eén verkeerd ingesprongen regel breekt de bedrijfsregel, en Python geeft geen foutmelding, omdat beide versies geldige code zijn.
Vier spaties, geen tabs. Python accepteert beide, maar als je ze in één bestand mengt, krijg je een TabError. Die is lastig te vinden, want tabs en spaties zien er op het scherm hetzelfde uit. In VS Code, dat je in hoofdstuk 1 hebt geïnstalleerd, voegt de Tab-toets in een Python-bestand vier spaties in — dat is de standaardinstelling, en vier spaties is de officiële conventie van Python.else — het andere pad
age = 15
if age >= 18:
print("You may enter")
else:
print("Sorry, adults only")Sorry, adults onlyelse heeft geen voorwaarde, omdat die al is gegeven — "als geen van de voorgaande waar was". Precies één van de if en de else wordt uitgevoerd; nooit beide, nooit geen van beide.
elif — meerdere paden
marks = 72
if marks >= 80:
grade = "A"
elif marks >= 70:
grade = "B"
elif marks >= 60:
grade = "C"
elif marks >= 40:
grade = "D"
else:
grade = "F"
print(f"Marks {marks} gives grade {grade}")Marks 72 gives grade Belif betekent "anders, als". Dit gebeurt er: Python loopt de keten af, voert de code eronder uit van de eerste voorwaarde die waar is, en verlaat dan de hele keten. Het test de rest zelfs niet.
Met marks = 72: 72 >= 80 is onwaar, 72 >= 70 is waar → grade = "B", klaar. 72 >= 60 en 72 >= 40 zijn ook waar, maar die worden nooit bekeken.
En hier is de grootste valkuil
Omdat elif stopt bij de eerste voorwaarde die waar is, leidt een verkeerde volgorde tot een programma dat draait, geen fout geeft, en het verkeerde antwoord geeft:
marks = 95
if marks >= 40:
grade = "Pass"
elif marks >= 80:
grade = "Excellent"
else:
grade = "Fail"
print(grade)Pass95 punten en geen Excellent. Want 95 >= 40 was meteen waar, en Python stopte daar — de tweede voorwaarde is nooit getest.
De regel om te onthouden: zet de strengste, meest specifieke voorwaarde eerst en de ruimste laatst. Werk je met numerieke klassen, loop dan naar beneden vanaf de grootste, zoals in het cijfervoorbeeld hierboven.
Deze fout valt zo weinig op dat je hem alleen met testen ontdekt. Maak er daarom een gewoonte van: schrijf je een keten van voorwaarden, draai hem dan één keer met een waarde voor elke tak. De cijfercode hierboven zou vijf verschillende antwoorden moeten geven voor 95, 72, 65, 45 en 20. Als er twee hetzelfde zijn, klopt de volgorde niet.
Een voorwaarde in een voorwaarde
is_logged_in = True
is_admin = False
if is_logged_in:
if is_admin:
print("Welcome, admin")
else:
print("Welcome, user")
else:
print("Please log in")Welcome, userDe binnenste if is vier spaties ingesprongen, omdat die onder de buitenste staat, en de eigen print-regels zijn er acht. Dit werkt, maar hoe meer niveaus er zijn, hoe lastiger de code te lezen is. Vaak zegt and hetzelfde duidelijker:
is_logged_in = True
is_admin = False
if is_logged_in and is_admin:
print("Welcome, admin")
elif is_logged_in:
print("Welcome, user")
else:
print("Please log in")Welcome, userWelke van de twee beter is, hangt af van welke het makkelijkst te lezen is. Als je meer dan drie niveaus diep zit, stop en denk opnieuw na — bijna altijd is dat een teken dat de voorwaarden anders gerangschikt kunnen worden.
Invoer valideren
We hebben nu het gereedschap om het probleem op te lossen dat in een eerder hoofdstuk openstond — wat te doen als iemand niets typt, of een woord:
raw = input("Your age: ").strip()
if raw == "":
print("You did not type anything")
elif raw.isdigit():
age = int(raw)
if age >= 18:
print(f"Age {age}: you may enter")
else:
print(f"Age {age}: adults only")
else:
print(f"'{raw}' is not a whole number")Your age: twenty
'twenty' is not a whole numberisdigit() is een nieuwe methode — die controleert of elk teken in de tekst een cijfer is. Het is de eenvoudige manier om te controleren voordat je iets aan int() doorgeeft, en het zorgt ervoor dat ValueError verdwijnt. (isdigit() accepteert geen negatieve getallen of decimalen — daarvoor heb je try nodig, dat later komt.)
Een compleet voorbeeld
fare.py:
# Work out a ticket fare from age and day of week
age = int(input("Passenger age : "))
day = input("Day of week : ").strip().lower()
base_fare = 120.0
# Most specific rule first, loosest last
if age < 5:
fare = 0.0
category = "Infant"
elif age < 18:
fare = base_fare * 0.5
category = "Child"
elif age >= 60:
fare = base_fare * 0.7
category = "Senior"
else:
fare = base_fare
category = "Adult"
is_weekend = day == "saturday" or day == "sunday"
if is_weekend:
fare = fare * 1.2
print()
print(f"Category : {category}")
print(f"Weekend : {is_weekend}")
print(f"Fare : {fare:.2f}")Passenger age : 65
Day of week : Sunday
Category : Senior
Weekend : True
Fare : 100.80Let op twee ontwerpkeuzes. Ten eerste zijn de leeftijdsvoorwaarden met elif aan elkaar geschakeld, omdat een passagier in precies één categorie valt. Ten tweede is de weekendvoorwaarde een aparte if, omdat het een onafhankelijke vraag is — ongeacht de leeftijd geldt de weekendtoeslag er bovenop. Bepalen wat een elif is en wat een aparte if is, dat is het echte werk bij het schrijven van voorwaarden.
Wanneer het misgaat
SyntaxError: expected ':' De dubbele punt aan het eind van de if-, elif- of else-regel ontbreekt.
IndentationError: expected an indented block after 'if' statement De regel na de if is niet ingesprongen. Een voorwaarde heeft minstens één regel nodig die erbinnen valt.
IndentationError: unexpected indent Een regel is zonder reden ingesprongen. Bedenk bij welk blok die regel hoort.
TabError: inconsistent use of tabs and spaces in indentation Tabs en spaties zijn in één bestand door elkaar gebruikt. Zet in je editor de inspringing om naar spaties: voer het commando "convert indentation to spaces" uit.
SyntaxError — een elif of else die alleen staat elif en else horen altijd bij een if, en moeten op hetzelfde niveau worden ingesprongen als die if.
TypeError: '>=' not supported between instances of 'str' and 'int' Je bent vergeten de input() om te zetten. Schrijf int(input(...)).
De voorwaarden zien er goed uit, maar het programma neemt het verkeerde pad Controleer de volgorde. Staat een ruime voorwaarde eerst, dan wordt de strenge nooit getest. Draai het één keer met een waarde voor elke tak.
Stap 4 van 6 — Voorspellen
Test je begrip
Met 85 punten, wat print dit programma?
marks = 85
if marks >= 40:
print("Pass")
elif marks >= 80:
print("Excellent")
else:
print("Fail")- AExcellent Pass
- BPass
- CPass Excellent
- DExcellent
Wat print dit programma?
score = 30
if score >= 50:
print("Passed")
print("Done")- APassed Done
- BDone
- CHelemaal niets
- DPassed
Zelfs als de persoon 25 typt, stopt dit met een TypeError. Wat is de oorzaak, en wat is de oplossing?
age = input("Age: ")
if age >= 18:
print("Adult")
else:
print("Minor")- A`input()` geeft tekst, en tekst kan niet met een getal worden vergeleken — er is `age = int(input("Age: "))` nodig
- BEen `elif` is verplicht vóór een `else`
- C`>=` kan niet in een `if`-voorwaarde worden gebruikt; het moet `>` zijn
- D`age` is een gereserveerd woord, dus de vergelijking is mislukt
Voor antwoorden heb je een account nodig
Log in om je antwoorden te controleren
De vragen staan hierboven, en ze in je hoofd uitwerken is waar het om draait. Log in om de antwoorden, de uitleg en de hints in drie niveaus te zien.
Jouw beurt
Schrijf een bestand met de naam bmi.py dat een lengte in meters en een gewicht in kilogram inleest, de BMI berekent, en de categorie aangeeft.
De formule: bmi = weight / (height * height)
De categorieën:
- Onder 18,5 — Underweight
- 18,5 of meer, maar onder 25 — Normal
- 25 of meer, maar onder 30 — Overweight
- 30 of meer — Obese
De grenzen zijn met opzet geschreven als "onder" (<) en "of meer" (>=). Als je "18,5 tot 24,9" zou schrijven, blijft er een gat in het midden — een BMI van bijvoorbeeld 24,95 zou dan in geen enkele categorie vallen. Met < en >= valt elk getal in precies één categorie.
Vier eisen:
- Toon de BMI met één decimaal
- Zet de voorwaarden in de juiste volgorde, zodat alle vier de categorieën echt werken
- Als de lengte
0is, stop dan voordat je deelt en print een melding — anders krijg je eenZeroDivisionError - Draai het met vier waarden die de vier categorieën dekken, en ook met waarden precies op de grenzen — in welke categorie komt een BMI van precies 25 terecht? (Dat zou Overweight moeten zijn.)
Die vierde eis is de belangrijkste. Waarden die precies op een grens liggen, zijn de plek waar fouten in de volgorde van voorwaarden zichtbaar worden.
Deze missie heeft nog meer
Wat je hierboven las is de volledige missie — er is niets uit weggelaten. Pro voegt toe:
- Wat er echt onder de motorkap gebeurt: hoe Python dit uitvoert
- De volledige oplossing van de oefening, stap voor stap uitgewerkt
- Moeilijkere extra oefeningen
- De sollicitatievraag over dit onderwerp, met een modelantwoord
Stap 6 van 6
Uitdaging — de hoofdstukquiz
Tien vragen van makkelijk naar moeilijk. De laatste zijn met opzet lastig.
Log in om de quiz te maken