Tilbake
2.6
Feilsøking og debugging

2.6 Feilsøking og debugging

Lær om syntaksfeil, logiske feil og runtime-feil, print-debugging og try/except.

50 min
8 oppgaver
FeilsøkingSyntaksfeilLogisk feiltry/except
Du leser den lesevennlige versjonen
Din fremgang i kapitlet
0 / 8 oppgaver

Møllen i maskinen

I 1947 fant programmereren Grace Hopper en faktisk møll fanget i en relémaskin – den hadde forårsaket feil. Siden har vi kalt programmeringsfeil for «bugs», og prosessen med å fjerne dem for debugging. Feil er uunngåelig; selv de mest erfarne programmererne skriver kode med feil. Forskjellen er at de vet hvordan de finner og retter dem effektivt. Å finne en feil er ikke et tegn på at du er dårlig – det er en helt naturlig del av prosessen.

Det finnes tre hovedtyper feil. Den enkleste er syntaksfeil – skrivefeil som bryter med språkets regler. Python oppdager dem før programmet starter og peker på linjen, slik som en manglende kolon etter if alder >= 18, en glemt parentes, feil innrykk eller manglende anførselstegn. Slike feil fikser du ved å lese feilmeldingen nøye, sjekke linjen den peker på og linjen over, og lete etter de vanlige tabbene.

Verre er kjøretidsfeil: koden er syntaktisk riktig, men noe går galt mens den kjører. 10 / 0 gir ZeroDivisionError, int("hei") gir ValueError, "5" + 3 gir TypeError, en for høy listeindeks gir IndexError, og en ukjent variabel gir NameError. Python viser da en traceback. Den leser du nedenfra og opp: siste linje sier hva feilen er, linjen over viser koden som forårsaket den, og filnavn pluss linjenummer sier hvor.

📝Oppgave Quiz 1

De feilene Python ikke advarer om

Den vanskeligste feiltypen er logiske feil. Her gir Python ingen feilmelding – koden kjører helt fint, men svaret er feil, fordi logikken i hodet ditt var feil. Et klassisk eksempel er glemte parenteser: tall1 + tall2 + tall3 / 3 deler bare det siste tallet, mens (tall1 + tall2 + tall3) / 3 gir riktig gjennomsnitt. Et annet er en grensefeil: if alder > 18 utelukker 18-åringer, mens if alder >= 18 inkluderer dem. Og en en-av-feil (off-by-one) oppstår når range(10) gir 0–9 i stedet for det du trodde.

Hvordan finner du noe Python tier om? Den mest effektive teknikken for nybegynnere er print-debugging: du legger inn print()-setninger for å se hva som faktisk skjer underveis. Tenk deg en rabattfunksjon som gir negativt resultat:

def beregn_rabatt(pris, rabatt_prosent):
    rabatt = pris * rabatt_prosent
    print(f"DEBUG: rabatt = {rabatt}")
    return pris - rabatt

Debug-utskriften avslører at rabatten ble 2000 i stedet for 20 – formelen manglet en deling på 100. Rettelsen er pris * rabatt_prosent / 100. Et godt råd er å merke debug-utskrifter med «DEBUG:» så de er lette å fjerne etterpå. Et beslektet eksempel: en funksjon som leter etter det største tallet, men starter med storst = 0. For en liste med bare negative tall returnerer den feilaktig 0. Løsningen er å starte med det første elementet: storst = tall_liste[0].

📝Oppgave Quiz 2

Når feil er forventet: try/except

Noen feil kan du ikke forhindre – som at brukeren skriver «hei» når du ba om et tall. I stedet for å la programmet krasje, kan du fange feilen med try/except. Koden som kan feile, legger du i try-blokken. Hvis en feil oppstår, hopper Python til except-blokken; hvis ikke, hoppes den over:

try:
    tall = int(input("Skriv et tall: "))
    print(f"Du skrev {tall}")
except ValueError:
    print("Det var ikke et gyldig tall!")

Du kan ha flere except-blokker for ulike feiltyper, for eksempel både ValueError og ZeroDivisionError. Det finnes også else, som kjøres bare hvis ingen feil oppsto, og finally, som kjøres alltid – uansett om det gikk galt eller ikke.

Et svært nyttig mønster er try/except inne i en løkke, slik at brukeren får prøve på nytt til input er gyldig:

while True:
    try:
        alder = int(input("Hvor gammel er du? "))
        break
    except ValueError:
        print("Ugyldig! Skriv inn et helt tall.")

Dette er mye bedre enn et program som krasjer. Setter du dette sammen, kan du bygge en robust kalkulator: en hent_tall-funksjon som bruker while True med try/except for å sikre gyldige tall, og en beregn-funksjon som sjekker for divisjon med null og ukjent operator. Resultatet er et program som aldri krasjer, uansett hva brukeren finner på.

📝Oppgave Quiz 3

Oppsummering

Feil hører programmering til – fra Grace Hoppers møll til dine egne bugs. Det finnes tre typer: syntaksfeil (skrivefeil Python fanger før kjøring), kjøretidsfeil (krasj under kjøring, som ZeroDivisionError og ValueError) og logiske feil (koden kjører, men gir feil svar). Tracebacks leser du nedenfra og opp.

Din viktigste teknikk er print-debugging: legg inn print()-setninger som viser variabelverdier underveis. Og når feil er forventet – som ugyldig brukerinput – fanger du dem med try/except, gjerne i en løkke som lar brukeren prøve igjen. Da bygger du robuste programmer som ikke krasjer, og du blir en bedre programmerer for hver feil du finner.

Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.