Weiger negatieve aantallen
Laat require_count onder nul de afgesproken ValueError geven; geef geldige aantallen terug.
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.
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.
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.
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))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.
| Invoer | Betekenis | Resultaat |
|---|---|---|
| Capaciteit 8, geboekt 3 | Geldige reservering | 5 vrije plaatsen |
| Capaciteit 8, geboekt 8 | Helemaal vol | 0 vrije plaatsen |
| Capaciteit 0, geboekt 0 | Ongeldige capaciteit | ValueError |
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.
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.
def seats_left(capacity, booked):
return capacity - booked
if capacity < 1:
raise ValueError("Capaciteit moet minstens een zijn.")
print(seats_left(0, 0))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.
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.
| Functie | Ongeldige situatie | Foutmelding |
|---|---|---|
require_count(count) | Het aantal is negatief | Aantal moet nul of hoger zijn. |
ratio(part, whole) | Het totaal is nul of negatief | Totaal moet positief zijn. |
normalize_name(text) | De opgeschoonde naam is leeg | Naam ontbreekt. |
bounded(value, low, high) | Eerst: low is groter dan high | Ongeldige grenzen. |
bounded(value, low, high) | Daarna: value ligt buiten het inclusieve bereik | Waarde 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.
Laat require_count onder nul de afgesproken ValueError geven; geef geldige aantallen terug.
Laat ratio alleen door een positieve whole delen; geef anders de afgesproken ValueError.
Strip text in normalize_name, weiger een leeg resultaat en geef anders de opgeschoonde naam terug.
Laat bounded eerst omgekeerde grenzen weigeren en daarna een waarde buiten het inclusieve bereik.
Hierna gebruik je een functie zelf als invoer voor een andere functie.
Voer je code uit en ontdek
wat je hebt gemaakt.
Je hoeft het niet in één keer goed te doen. Na het uitvoeren zie je hier welke stappen al kloppen.