← Python/Denken in functies
Les 6 van 8
MODULE 03 · 06◷ 26 min

Weiger ongeldige argumenten duidelijk

Na deze les kun je
  • Een functiecontract met grenzen formuleren
  • Met ValueError ongeldige waarden weigeren
  • Geldige en ongeldige aanroepen apart behandelen

Een reserveringsberekening kan technisch met een capaciteit van nul rekenen, maar daarmee is de aanvraag nog niet geldig. Je wilt duidelijk melden welke invoer niet is toegestaan. Dan kan de aanroeper de fout herstellen zonder te raden wat jouw antwoord betekent.

Spreek af welke waarden mogen

Een functiecontract beschrijft welke invoer is toegestaan en wat de functie daarvoor levert. Bij validatie controleer je of de argumenten aan die afspraak voldoen. Doe dat voordat je met de normale berekening verdergaat.

In het voorbeeld gebruiken we gehele getallen. Een ruimte heeft minstens één plaats en het aantal geboekte plaatsen ligt tussen nul en de capaciteit, inclusief beide grenzen. Bij geldige invoer geeft de functie het aantal vrije plaatsen terug.

Voor ongeldige waarden gebruiken we een uitzondering: een foutsignaal dat de gewone uitvoering onderbreekt. Met raise ValueError("...") geef je dat signaal bewust, met een eigen melding. ValueError past hier bij een waarde die niet aan de afgesproken grenzen voldoet.

Controleer vóór het rekenen

Het voorbeeld doet twee geldige aanroepen en daarna bewust één ongeldige. Druk op Voorbeeld uitvoeren. Je ziet eerst twee antwoorden en vervolgens een foutmelding; die laatste melding is hier het gewenste gedrag.

Geldige boekingen en een duidelijke fout
def seats_left(capacity, booked):
    if capacity < 1:
        raise ValueError("Capaciteit moet minstens een zijn.")
    if booked < 0 or booked > capacity:
        raise ValueError("Boeking valt buiten de capaciteit.")
    return capacity - booked

print(seats_left(8, 3))
print(seats_left(8, 8))
print(seats_left(0, 0))
Verwachte fout
5
0
ValueError: Capaciteit moet minstens een zijn.

Bij acht plaatsen en drie boekingen blijven er vijf plaatsen over. Bij acht boekingen blijven er nul over: nul vrije plaatsen is een geldig antwoord. Een capaciteit van nul wordt daarentegen bij de eerste controle geweigerd.

InvoerBetekenisResultaat
Capaciteit 8, geboekt 3Geldige reservering5 vrije plaatsen
Capaciteit 8, geboekt 8Helemaal vol0 vrije plaatsen
Capaciteit 0, geboekt 0Ongeldige capaciteitValueError

Zodra de raise wordt uitgevoerd, komt de functie niet meer bij haar normale return. De fout gaat naar de aanroeper. In het voorbeeld wordt ze niet opgevangen, waardoor de uitvoering daar stopt en de fout zichtbaar wordt.

Daarom is een foutsignaal duidelijker dan hier zomaar nul teruggeven. Nul heeft al een geldige betekenis: alle plaatsen zijn geboekt. De aanroeper moet een ongeldige aanvraag van dat gewone resultaat kunnen onderscheiden.

Veelgemaakte fout: te laat controleren

Een controle kan correct geschreven zijn en toch nooit worden uitgevoerd. In deze zelfstandige foutvariant staat zij na een onvoorwaardelijke return. Voorspel wat de ongeldige aanvraag nu oplevert.

Een controle na de return
def seats_left(capacity, booked):
    return capacity - booked
    if capacity < 1:
        raise ValueError("Capaciteit moet minstens een zijn.")

print(seats_left(0, 0))
Verwachte uitvoer
0

De uitvoer is nul, alsof de aanvraag een normaal antwoord heeft. De return heeft de functie al verlaten voordat Python de controle zou bereiken. Zet de validatie daarom vóór de berekening en de normale return.

Ook de volgorde van meerdere controles kan betekenis hebben. Het voorbeeld controleert eerst of de capaciteit geldig is en daarna of de boeking binnen die capaciteit past. Zo meldt het eerst de afspraak waarop de volgende controle is gebaseerd.

Controleer de waarde die je werkelijk gebruikt

Bij tekst kan opschonen onderdeel van de afspraak zijn. Als alleen randspaties niet mogen meetellen, gebruik je eerst .strip() en controleer je daarna het resultaat. De oorspronkelijke tekst kan nog spaties bevatten terwijl het bruikbare resultaat al leeg is.

Voor de opdrachten gelden de onderstaande exacte meldingen. Gebruik telkens raise ValueError met de genoemde tekst; de tekst maakt deel uit van het functiecontract.

FunctieOngeldige situatieFoutmelding
require_count(count)Het aantal is negatiefAantal moet nul of hoger zijn.
ratio(part, whole)Het totaal is nul of negatiefTotaal moet positief zijn.
normalize_name(text)De opgeschoonde naam is leegNaam ontbreekt.
bounded(value, low, high)Eerst: low is groter dan highOngeldige grenzen.
bounded(value, low, high)Daarna: value ligt buiten het inclusieve bereikWaarde buiten grenzen.

Bij geldige invoer geeft require_count het aantal terug, ratio de gewone deling part / whole, normalize_name de opgeschoonde tekst en bounded de ongewijzigde waarde. De tests vangen verwachte fouten zelf op. Je hoeft hier nog geen eigen foutafhandeling te schrijven; leer eerst bewust signaleren waar de normale route moet stoppen.

AAN DE SLAG 0/4
1

Weiger negatieve aantallen

Laat require_count onder nul de afgesproken ValueError geven; geef geldige aantallen terug.

2

Controleer vóór je deelt

Laat ratio alleen door een positieve whole delen; geef anders de afgesproken ValueError.

3

Valideer de opgeschoonde naam

Strip text in normalize_name, weiger een leeg resultaat en geef anders de opgeschoonde naam terug.

4

Controleer in de juiste volgorde

Laat bounded eerst omgekeerde grenzen weigeren en daarna een waarde buiten het inclusieve bereik.

Wat je meeneemt

  • Een functiecontract bevat zowel toegestane waarden als afspraken over het resultaat.
  • Valideer vóór de normale berekening; raise onderbreekt die route met een foutsignaal.
  • Controleer grenzen en opgeschoonde waarden in een bewuste volgorde.

Hierna gebruik je een functie zelf als invoer voor een andere functie.

main.py
UitvoerPython
›
›_

Hier komt je resultaat.

Voer je code uit en ontdek
wat je hebt gemaakt.

0/4 stappen
EVEN MEEKIJKEN

Bekijk hoe het kan.

Je mag de oplossing bekijken. Deze poging telt dan niet mee als afgeronde les. Met Reset kun je daarna opnieuw zelf oefenen.