Systematisk feilsøking, debugging-teknikker og testing av programkode.
Feilsøking og testing
Alle programmerarar lagar feil – det er ein heilt naturleg del av utviklingsprosessen. Skilnaden mellom ein nybyrjar og ein erfaren programmerar er ikkje at den erfarne lagar færre feil, men at den erfarne er betre til å finne og rette dei.
Det finst tre hovudtypar feil i program:
1. Syntaksfeil – brot på reglane i programmeringsspråket
2. Køyretidsfeil – feilen oppstår når programmet blir køyrt
3. Logiske feil – programmet køyrer utan feilmeldingar, men gir feil resultat
I dette kapittelet skal du lære:
- Korleis du skil mellom dei tre feiltypane
- Systematisk feilsøking med print-debugging
- Korleis du les og tolkar feilmeldingar
- Testing med assert og edge cases
Oppstår når koden bryt reglane i programmeringsspråket. Programmet startar ikkje eingong.
# Manglende kolon etter if
if x > 5
print("Stor") # SyntaxError: expected ':'
# Feil innrykk
def beregn():
print("Hei") # IndentationError: expected an indented blockKøyretidsfeil (RuntimeError)
Programmet startar, men krasjar undervegs.
tall = [1, 2, 3]
print(tall[5]) # IndexError: list index out of range
resultat = 10 / 0 # ZeroDivisionError: division by zero
alder = int("hei") # ValueError: invalid literal for int()Logiske feil
Programmet køyrer utan feilmeldingar, men gir feil resultat. Desse er vanskelegast å finne!
# Skal beregne gjennomsnitt, men glemmer parenteser
gjennomsnitt = sum_tall / antall + 1 # Feil: deler bare sum_tall
gjennomsnitt = sum_tall / (antall + 1) # Riktig: deler på (antall + 1)Klassifiser følgjande feil som syntaksfeil, køyretidsfeil eller logisk feil:
1. print("Hei" (manglande parentes)
2. Eit program som reknar ut arealet av ein sirkel med areal = 2 * pi * r i staden for pi * r**2
3. navn = input("Navn: ") etterfølgt av print(navn + 10)
1. Syntaksfeil – manglande avsluttande parentes er eit brot på Python-syntaksen. Python vil gi SyntaxError: '(' was never closed og programmet vil ikkje starte.
2. Logisk feil – formelen 2 * pi * r er omkrinsen, ikkje arealet. Programmet køyrer utan feilmeldingar, men gir feil svar. Dette er den vanskelegaste feiltypen fordi Python ikkje kan vite kva du meinte å skrive.
3. Køyretidsfeil – du kan ikkje leggje saman ein streng (navn) og eit tal (10) i Python. Programmet startar og ventar på input, men krasjar med TypeError når det prøver å utføre addisjonen.
Kva type feil er det når programmet køyrer utan feilmeldingar, men gir feil resultat?
Print-debugging
Den enklaste og mest brukte feilsøkingsteknikken er å leggje inn print-setningar for å sjå kva som skjer inne i programmet.
Strategi:
1. Identifiser kvar feilen truleg oppstår
2. Legg inn print()-setningar for å vise variabelverdiar
3. Køyr programmet og analyser utskrifta
4. Flytt/legg til print-setningar for å snevre inn feilen
5. Fjern print-setningar når feilen er funnen
Eksempel – feilsøkje ei utrekning:
def beregn_karakter(poeng, maks_poeng):
prosent = poeng / maks_poeng * 100
print(f"DEBUG: poeng={poeng}, maks={maks_poeng}, prosent={prosent}")
if prosent >= 90:
return 6
elif prosent >= 75:
return 5
elif prosent >= 55:
return 4
elif prosent >= 40:
return 3
elif prosent >= 20:
return 2
else:
return 1
karakter = beregn_karakter(45, 60)
print(f"DEBUG: karakter={karakter}")Tips: Bruk prefikset DEBUG: på feilsøkingsutskrifter, slik at dei er lette å finne og fjerne etterpå.
Følgjande program skal finne det største talet i ei liste, men gir feil resultat. Bruk print-debugging til å finne feilen.
def finn_storst(tall):
storst = 0
for t in tall:
if t > storst:
storst = t
return storst
resultat = finn_storst([-3, -1, -7, -2])
print(resultat) # Forventer -1, men får 0Vi legg inn print-setningar for å sjå kva som skjer:
def finn_storst(tall):
storst = 0
print(f"DEBUG: startverdi storst={storst}")
for t in tall:
print(f"DEBUG: sjekker {t} > {storst} => {t > storst}")
if t > storst:
storst = t
return storstUtskrift:
DEBUG: startverdi storst=0
DEBUG: sjekker -3 > 0 => False
DEBUG: sjekker -1 > 0 => False
DEBUG: sjekker -7 > 0 => False
DEBUG: sjekker -2 > 0 => FalseFeilen: Startverdien storst = 0 er større enn alle negative tal! Ingen verdiar erstattar han.
Løysing: Sett storst = tall[0] (første element) i staden for 0:
def finn_storst(tall):
storst = tall[0] # Bruk første element som startverdi
for t in tall[1:]:
if t > storst:
storst = t
return storstFølgjande program skal rekne ut summen av alle partal i ei liste, men gir feil resultat. Finn feilen og forklar han.
def sum_partall(tall):
total = 0
for t in tall:
if t % 2 == 1:
total += t
return total
resultat = sum_partall([1, 2, 3, 4, 5, 6])
print(resultat) # Forventer 12, men får 9Erfarne programmerarar følgjer ein systematisk framgangsmåte for feilsøking:
Steg 1: Les feilmeldinga nøye
Python-feilmeldingar inneheld verdifull informasjon:
Traceback (most recent call last):
File "program.py", line 5, in <module>
resultat = tall[10]
IndexError: list index out of range- Fila og linjenummeret: line 5 – feilen er på linje 5- Feiltypen:
IndexError – indeksen er utanfor rekkevidda til lista- Skildringa:
list index out of range – du prøver å hente eit element som ikkje finstSteg 2: Isoler feilen
- Kommenter ut delar av koden for å finne kvar feilen oppstår
- Test med enkle, kjende inputverdiar
- Reduser problemet til den minste koden som reproduserer feilen
Steg 3: Forstå feilen
- Kva forventa du at koden skulle gjere?
- Kva gjer koden faktisk?
- Kva er skilnaden?
Steg 4: Rett feilen og test
- Gjer éi endring om gongen
- Test med fleire ulike inputverdiar
- Kontroller at rettinga ikkje introduserer nye feil
Du får feilmeldinga:
Traceback (most recent call last):
File "sensor.py", line 12, in <module>
temperatur = int(svar)
ValueError: invalid literal for int() with base 10: 'tjueto'Kva er mest sannsynleg årsaka til feilen?Testing med assert
assert er eit Python-nøkkelord som sjekkar om eit vilkår er sant. Viss vilkåret er usant, krasjar programmet med ein AssertionError.
def beregn_areal(lengde, bredde):
return lengde * bredde
# Tester
assert beregn_areal(5, 3) == 15, "5 × 3 skal gi 15"
assert beregn_areal(0, 10) == 0, "0 × 10 skal gi 0"
assert beregn_areal(2.5, 4) == 10.0, "2.5 × 4 skal gi 10.0"
print("Alle tester bestått!")Edge cases – grensetilfelle som ofte avslører feil:
- Tom liste eller streng
- Null (0) som input
- Negative tal
- Svært store tal
- Same verdi for all input
def gjennomsnitt(tall):
if len(tall) == 0:
return 0 # Håndter tom liste
return sum(tall) / len(tall)
# Test med edge cases
assert gjennomsnitt([10]) == 10 # Bare ett element
assert gjennomsnitt([]) == 0 # Tom liste
assert gjennomsnitt([-5, 5]) == 0 # Positive og negative
assert gjennomsnitt([3, 3, 3]) == 3 # Alle like
print("Alle tester bestått!")Skriv testar med assert for funksjonen er_gyldig_alder(alder) som returnerer True viss alderen er mellom 0 og 150.
def er_gyldig_alder(alder):
return 0 <= alder <= 150
# Vanlige tilfeller
assert er_gyldig_alder(25) == True, "25 er gyldig"
assert er_gyldig_alder(0) == True, "0 er gyldig"
assert er_gyldig_alder(150) == True, "150 er gyldig"
# Ugyldige verdier
assert er_gyldig_alder(-1) == False, "-1 er ugyldig"
assert er_gyldig_alder(151) == False, "151 er ugyldig"
assert er_gyldig_alder(-100) == False, "-100 er ugyldig"
# Edge cases - grenseverdier
assert er_gyldig_alder(1) == True, "1 er gyldig"
assert er_gyldig_alder(149) == True, "149 er gyldig"
print("Alle tester bestått!")Vi testar:
- Vanlege verdiar som vi veit skal gi True eller False
- Grenseverdiar (0, 1, 149, 150, 151, -1) som er der feil ofte oppstår
- Ekstremt ugyldige verdiar for å vere sikre
Skriv ein funksjon er_partall(tall) som returnerer True viss talet er partal, og False elles. Skriv deretter minst 5 assert-testar som dekkjer vanlege tilfelle og edge cases.
Oppsummering
I dette kapittelet har du lært systematisk feilsøking og testing:
- Syntaksfeil – brot på reglane i språket, blir oppdaga før programmet startar
- Køyretidsfeil – programmet krasjar under køyring (IndexError, TypeError, osv.)
- Logiske feil – programmet gir feil resultat utan feilmeldingar
- Print-debugging – legg inn print() for å sjå kva som skjer inne i koden
- Systematisk feilsøking – les feilmelding → isoler → forstå → rett → test
- assert – sjekk at funksjonar gir rett resultat med kjende inputverdiar
- Edge cases – test med grenseverdiar som tomme lister, null og negative tal
Nøkkelomgrep
| Omgrep | Forklaring |
|---|---|
| Syntaksfeil | Brot på reglane i programmeringsspråket |
| Køyretidsfeil | Feil som oppstår når programmet blir køyrt |
| Logisk feil | Programmet gir feil resultat utan feilmeldingar |
| Print-debugging | Bruke print() til å vise variabelverdiar under feilsøking |
| assert | Sjekkar at eit vilkår er sant, krasjar viss ikkje |
| Edge case | Grensetilfelle som kan avsløre feil (tom liste, 0, negative tal) |
Følgjande program har tre feil – éin syntaksfeil, éin køyretidsfeil og éin logisk feil. Finn og rett alle tre. Forklar kva type feil kvar av dei er.
def beregn_statistikk(malinger)
antall = len(malinger)
gjennomsnitt = sum(malinger) / antall
avvik = []
for i in range(antall + 1):
avvik.append(malinger[i] - gjennomsnitt)
total_avvik = sum(avvik) / antall
return gjennomsnitt, total_avvik
resultat = beregn_statistikk([20, 22, 25, 21, 23])
print(f"Gjennomsnitt: {resultat[0]}, Avvik: {resultat[1]}")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.