0%

Fouten, validatie en debuggen · oefening

Lees een traceback vanaf onderaan

Wanneer een exceptie een programma stopt, drukt Python een traceback af. Dat is een spoor dat laat zien welke regels actief waren toen het probleem optrad.

Hier is een klein voorbeeld:

def cost_per_guest(total_cost, guests):
    return total_cost / guests


def show_summary():
    amount = cost_per_guest(90, 0)
    print(amount)


show_summary()

De traceback bevat meerdere regels, maar je hoeft die niet als een verhaal van boven naar beneden te lezen.

Begin onderaan

De laatste regel zegt ongeveer:

ZeroDivisionError: division by zero

Die geeft je:

  • het exceptietype: ZeroDivisionError;

  • het bericht: division by zero.

Dat vertelt je meteen welke bewerking is mislukt.

Ga omhoog naar je code

Boven de laatste regel wijst de traceback naar de deling binnen cost_per_guest. Een andere vermelding laat zien dat show_summary de functie aanriep.

Dit spoor is belangrijk, omdat de regel waar Python een probleem opmerkt niet altijd de plek is waar de verkeerde waarde ontstond. De deling vindt plaats binnen de functie, maar show_summary gaf de nul mee.

Lees elke relevante vermelding als:

Deze regel werd uitgevoerd en kwam hier via de vermelding erboven.

De gemelde regel is bewijs, geen oordeel

Pas niet automatisch de laatste gemarkeerde regel aan. Vraag eerst:

  • Welke waarden bereikten deze bewerking?

  • Waar kwamen die waarden vandaan?

  • Welke waarde schendt de eis van het programma?

Als nul gasten in dit programma onmogelijk is, is de aanroep verkeerd. Als nul een mogelijke echte invoer is, moet het programma valideren voordat het deelt. In latere lessen bouw je die validatie.

Een betrouwbare leesroutine

  1. Lees onderaan het exceptietype en het bericht.

  2. Ga omhoog tot je regels uit jouw programma vindt.

  3. Bepaal welke bewerking mislukte.

  4. Volg verdachte waarden terug naar de plek waar ze werden aangemaakt of doorgegeven.

  5. Maak één onderbouwde wijziging en voer het programma opnieuw uit.

Volg die routine nu in de figuur hieronder. Het programma loopt van de aanroeper omlaag naar de fout, terwijl jij bij de genummerde onderste stap begint en omhoog leest. Bekijk die tegengestelde richtingen. “Caller” is de aanroeper, “Function call” de functieaanroep en “Failed line” de mislukte regel. Rechts staat: lees de fout, vind de mislukte regel en volg de waarde terug. “Start at the bottom” betekent: begin onderaan.

Een traceback loopt van de aanroeper naar de mislukte regel en de fout; de aanbevolen leesvolgorde begint bij de fout onderaan en gaat omhoog naar de mislukte regel en de aanroeper.

De terminal toont de traceback wanneer je code uitvoert. Tijdens de beoordeling kan dezelfde informatie onder het label Python error output verschijnen.

Welk deel van een traceback lees je meestal het best als eerste?

De traceback eindigt met ZeroDivisionError: division by zero voor deze regel:

return kilometers / hours

Welke waarde moet je als eerste terugvolgen?

Opdracht

Het startprogramma probeert het gemiddelde aantal punten per speler te tonen, maar stopt met een exceptie.

Voer het één keer uit en lees de traceback vanaf onderaan. Volg de ongeldige waarde terug naar de functieaanroep en herstel die aanroep zodat het programma 48 punten verdeeld over 6 spelers modelleert.

Het uiteindelijke programma moet dit afdrukken:

8.0

Laat de functie en de deling ongewijzigd. De fout zit in de waarde die de aanroep meegeeft.