Tilbake
2.2

2.2 DRILL — Feilhåndtering: hvilken exception utløses?

`try/except` og den mekaniske øvelsen med å avgjøre hvilken exception som utløses **først** og hvilken `except`-blokk som fanger den.

60 min
12 oppgaver
DRILLFeilhåndteringhvilken exception utløses?
Din fremgang i kapitlet
0 / 12 oppgaver
Forkunnskaper. Alt du trenger ligger i tre kapitler:

- kap. 2.1sys.argv, input, int/float og sys.exit. Uten dette kan du ikke lese oppgaveteksten «programmet kjøres som python p.py 6 0».
- kap. 1.2 — lister og indeksering, som er kilden til IndexError.
- kap. 1.5 — ordbøker (dictionaries), som er kilden til KeyError.

En exception er en feil som avbryter programmet. Ordet betyr «unntak»: noe uventet skjedde, og Python kan ikke fortsette som planlagt. Alle exceptions i Python har et navn (ValueError, IndexError, …), og hele øvelsen i dette kapitlet er å kunne navnet på den som utløses først.

📜Løsningsoppskriften for sjanger C
Bolk 1 — oppskriften og feiltypene (~20 min).

Alle oppgaver i denne sjangeren løses med den samme femstegsalgoritmen. Følg den mekanisk, i denne rekkefølgen, én kjøring om gangen:

1. Skriv opp sys.argv. For kallet python p.py 6 0 er det ['p.py', '6', '0'] — filnavnet først, alle elementene som strenger.
2. Gå gjennom programmet linje for linje, ovenfra og ned, med de verdiene du nettopp skrev opp. Ikke hopp.
3. Stopp ved den FØRSTE operasjonen som ikke kan utføres. Det er den som avgjør svaret. Alt som ligger lenger ned i programmet er irrelevant — det kjøres aldri.
4. Navngi feilen ut fra hva som gikk galt: manglet et element (IndexError), var innholdet i en streng utolkbart (ValueError), var typene uforenlige (TypeError), manglet en nøkkel (KeyError), ble det delt på null (ZeroDivisionError), feilet en assert (AssertionError), eller fantes ikke navnet (NameError).
5. Match mot riktig except-blokk, eller mot alternativet «ingen feil» hvis programmet kom helt gjennom.

Steg 3 er hele hemmeligheten. De aller fleste tapte poengene på denne sjangeren skyldes at kandidaten finner en mulig feil lenger nede i programmet og svarer med den, uten å sjekke at programmet i det hele tatt kom dit.

Å fange en feil i stedet for å stoppe

Uten try stopper programmet på første feil. Med try får du sjansen til å reagere: du legger den koden som kan feile inne i try, og skriver hva som skal skje for hver feiltype i en except-blokk under.

Vi bruker samme lille program hele veien i dette kapitlet — det deler to tall fra kommandolinjen:

`try` / `except FeilType` — fang en feil i stedet for å stoppe

Koden inne i try kjøres som normalt. Utløses en exception, avbrytes try-blokken umiddelbart på den linja, og Python leter nedover etter en except-blokk som passer til feiltypen. Passer én, kjøres den, og programmet fortsetter etterpå. Passer ingen, stopper programmet med feilmeldingen som før.

Det viktigste for eksamen: resten av try-blokken kjøres aldri etter at feilen oppsto.

import sys
try:
    x = float(sys.argv[1])
    y = float(sys.argv[2])
    print(x / y)
except IndexError:
    print('Du må gi to tall på kommandolinjen')
except ValueError:
    print('Begge argumentene må være tall')
except ZeroDivisionError:
    print('Kan ikke dele på null')

Utskrift:

Kan ikke dele på null

Kjørt som python3 robust.py 6 0: float('6') og float('0') går bra, men divisjonen feiler, print(x / y) fullføres aldri, og ZeroDivisionError-blokken kjører.

✏️Eksempel 1: Samme program, fire kjøringer, fire utfall

Programmet deling.py under kjøres på fire måter: python3 deling.py 6 2, python3 deling.py 6 0, python3 deling.py 6 to og python3 deling.py 6. Hva skjer i hvert tilfelle?

Her er programmet, kjørt som python3 deling.py 6 2:

import sys
x = float(sys.argv[1])
y = float(sys.argv[2])
print(x / y)

Utskrift:

3.0

Gå gjennom oppskriften for hver av de fire kjøringene:

Kjøringsys.argvFørste linje som ikke kan utføresUtfall
python3 deling.py 6 2['deling.py', '6', '2']ingenskriver 3.0
python3 deling.py 6 0['deling.py', '6', '0']print(x / y) — deling på 0.0ZeroDivisionError
python3 deling.py 6 to['deling.py', '6', 'to']float(sys.argv[2])ValueError
python3 deling.py 6['deling.py', '6']sys.argv[2] finnes ikkeIndexError

De tre siste stopper, og siste linje i feilmeldingen er henholdsvis:
ZeroDivisionError: float division by zero
ValueError: could not convert string to float: 'to'
IndexError: list index out of range
Legg merke til den viktige detaljen i rad 3: float(sys.argv[2]) feiler før divisjonen i det hele tatt forsøkes. Hadde du svart ZeroDivisionError der, hadde du lest for langt ned i programmet.

✏️Eksempel 2: Den robuste versjonen

Skriv om deling.py slik at brukeren får en forståelig beskjed i stedet for en feilmelding, uansett hvilken av de tre feilene som oppstår. Vis utskriften for python3 robust.py 6 to og python3 robust.py 6.

Legg all koden som kan feile inne i try, og gi hver feiltype sin egen except-blokk:

import sys
try:
    x = float(sys.argv[1])
    y = float(sys.argv[2])
    print(x / y)
except IndexError:
    print('Du må gi to tall på kommandolinjen')
except ValueError:
    print('Begge argumentene må være tall')
except ZeroDivisionError:
    print('Kan ikke dele på null')

python3 robust.py 6 to gir:

Utskrift:

Begge argumentene må være tall

python3 robust.py 6 gir:

Utskrift:

Du må gi to tall på kommandolinjen

Og python3 robust.py 6 2 går som før:

Utskrift:

3.0

Uttellingen på en slik oppgave ligger i strukturen: at all koden som kan feile ligger inne i try, og at hver except nevner en feiltype som faktisk kan oppstå. Bytter du om rekkefølgen på de tre except-blokkene, er svaret like riktig — de er uavhengige feiltyper, ingen av dem er en spesialisering av en annen.

📝Oppgave 1

(Innstegsoppgave, sjanger C — hvilken feil utløses?) Hva skjer når linja under kjøres?

antall = int('3.5')

De sju feiltypene du trenger

Eksamen bruker de samme sju navnene år etter år. Her er hver av dem med den minste kodesnutten som utløser den, og med den faktiske meldingen Python gir. Lær deg å kjenne meldingene igjen — de er ofte selve svaralternativet i en matche-tabell.

`IndexError` — elementet finnes ikke

Utløses når du indekserer en liste (eller en streng, eller sys.argv) med en posisjon som ikke finnes. Den vanligste kilden på eksamen er at brukeren ga for få kommandolinjeargumenter, slik at sys.argv[2] ikke eksisterer.

x = [1, 2, 3]
print(x[3])

Utskrift:

IndexError: list index out of range

Dette er siste linje i feilmeldingen; til vanlig utskrift skriver programmet ingenting før det stopper.

Lista har elementene på indeks 0, 1 og 2 — indeks 3 er én for langt. Merk at utsnitt aldri gir IndexError: x[3:] gir bare den tomme lista.

`ValueError` — riktig type, ubrukelig innhold

Utløses når en funksjon får en verdi av riktig type, men med et innhold den ikke kan bruke. De to faste kildene på eksamen er int('tekst') og float('tekst').

print(float('Precip'))

Utskrift:

ValueError: could not convert string to float: 'Precip'

Dette er siste linje i feilmeldingen; til vanlig utskrift skriver programmet ingenting før det stopper.

Meldingen navngir alltid verdien som ikke kunne tolkes, og det gjør ValueError lett å kjenne igjen. Precip er en typisk kolonneoverskrift i en datafil — å glemme å hoppe over overskriftslinja før man konverterer, er en fast felle i fillesingsoppgavene senere i boka.

`ZeroDivisionError` — deling på null

Utløses av /, // og % med 0 på høyre side. Meldingen er ikke helt den samme for heltall og flyttall, og det er verdt å legge merke til:

print(7 // 0)

Utskrift:

ZeroDivisionError: integer division or modulo by zero

Dette er siste linje i feilmeldingen; til vanlig utskrift skriver programmet ingenting før det stopper.

Med flyttall blir meldingen ZeroDivisionError: division by zero i stedet. Selve feiltypen er den samme, så på en matche-tabell er det aldri forskjell på dem.

`TypeError` — typene passer ikke sammen

Utløses når en operasjon er umulig for de typene du gir den, uansett innhold. Det klassiske tilfellet er å legge et tall til en streng.

print('a' + 1)

Utskrift:

TypeError: can only concatenate str (not "int") to str

Dette er siste linje i feilmeldingen; til vanlig utskrift skriver programmet ingenting før det stopper.

Samme mønster med lister: [1, 2] + 3 gir TypeError: can only concatenate list (not "int") to list. Skillet mot ValueError er det du må ha klart: float('to') er en ValueError (rett type, gal verdi), mens 'to' + 1 er en TypeError (uforenlige typer).

`KeyError` — nøkkelen finnes ikke i ordboka

Utløses når du slår opp d[nøkkel] i en ordbok som ikke har den nøkkelen. Dette er ordbokas motstykke til IndexError.

d = {'blindern': 4.2, 'tryvann': 1.8}
print(d['bergen'])

Utskrift:

KeyError: 'bergen'

Dette er siste linje i feilmeldingen; til vanlig utskrift skriver programmet ingenting før det stopper.

Meldingen er bare nøkkelen som manglet, i anførselstegn. Vil du unngå feilen, bruker du d.get('bergen', 0), som gir standardverdien i stedet for å feile.

`NameError` — navnet finnes ikke

Utløses når du bruker et navn som aldri er blitt tilordnet — oftest en skrivefeil, eller en glemt import.

antall = 5
print(antal)

Utskrift:

NameError: name 'antal' is not defined

Dette er siste linje i feilmeldingen; til vanlig utskrift skriver programmet ingenting før det stopper.

Her er antall definert, men antal er skrevet i print. Samme feil får du hvis du bruker sys.argv uten import sys, eller sqrt(2) uten from math import sqrt — begge er faste plantede feil i «finn feilen»-oppgaver.

`AssertionError` — en `assert` slo til
assert betingelse, melding sjekker at betingelsen er sann. Er den falsk, avbrytes programmet med AssertionError og din egen melding.

antall = 0
assert antall > 0, 'antall må være positivt'
print(antall)

Utskrift:

AssertionError: antall må være positivt

Dette er siste linje i feilmeldingen; til vanlig utskrift skriver programmet ingenting før det stopper.

Dette er verdt å merke seg for matche-tabellene: en assert som står før en risikabel beregning, fanger opp problemet først, slik at svaret blir AssertionError og ikke ZeroDivisionError. Vi bruker assert for testfunksjoner i kap. 3.1.

— naturlig pausepunkt —

Bolk 2 — Det gjennomarbeidede eksamenscaset (~10 min)

Nå setter vi oppskriften på et program som er like langt og like sammensatt som et reelt eksamensprogram: det leser to kommandolinjeargumenter, slår opp i en ordbok, har en assert og en divisjon. Alle fem feiltypene vi har sett, kan oppstå i det.

✏️Eksempel 3: Eksamenscase — fem kjøringer, med sensorens blikk i margen

Programmet stasjonssnitt.py under er lagret på maskinen. Match hver av de fem kjøringene mot utfallet:

import sys
stasjoner = {'blindern': 4.2, 'tryvann': 1.8}
navn = sys.argv[1]
antall = int(sys.argv[2])
assert antall > 0, 'antall må være positivt'
snitt = stasjoner[navn] / antall
print(f'{navn}: {snitt:.2f}')

Kjøringer:

RadKall
1python3 stasjonssnitt.py blindern 2
2python3 stasjonssnitt.py bergen 2
3python3 stasjonssnitt.py blindern to
4python3 stasjonssnitt.py blindern
5python3 stasjonssnitt.py blindern 0

Alternativer: (i) ingen feil, (ii) ValueError, (iii) IndexError, (iv) KeyError, (v) AssertionError, (vi) ZeroDivisionError.

Rad for rad, med oppskriften:

Rad 1 — blindern 2. sys.argv er ['stasjonssnitt.py', 'blindern', '2']. navn blir 'blindern', int('2') gir 2, assert 2 > 0 holder, stasjoner['blindern'] finnes, og 4.2/2=2.14.2/2 = 2.1. Ingen feil — (i).

Utskrift:

blindern: 2.10

Sensorens blikk: denne raden er gratis hvis du husker at én rad nesten alltid er «ingen feil». Mange kandidater leter etter en feil i alle radene og roter bort et halvt poeng her.

Rad 2 — bergen 2. Lista er ['stasjonssnitt.py', 'bergen', '2']. Navnet hentes greit, int('2') går bra, assert holder — og så feiler stasjoner['bergen'], fordi ordboka bare har blindern og tryvann. (iv) KeyError:

KeyError: 'bergen'

Rad 3 — blindern to. Nå feiler int('to') på linje 4, altså før ordboksoppslaget. (ii) ValueError:

ValueError: invalid literal for int() with base 10: 'to'

Sensorens blikk: her ligger den vanligste feilen i hele sjangeren. Ordboka inneholder blindern, så det er lett å slappe av og svare «ingen feil». Men programmet kommer aldri til oppslaget.

Rad 4 — blindern. Lista har bare to elementer, så sys.argv[2] på linje 4 finnes ikke. (iii) IndexError:

IndexError: list index out of range

Rad 5 — blindern 0. int('0') gir 0, og så slår assert 0 > 0 til. (v) AssertionError med din egen melding:

AssertionError: antall må være positivt

Sensorens blikk: dette er radens hele poeng. Uten assert-linja ville divisjonen 4.2 / 0 gitt ZeroDivisionError. Assertion-linja står foran og griper inn først. Alternativ (vi) er derfor med i lista nettopp som felle, og brukes ikke.

Fasit: 1–(i), 2–(iv), 3–(ii), 4–(iii), 5–(v).

Om uttelling: hver rad gis eller mistes for seg. Får du fire av fem, får du fire femdeler av poengene — det er aldri alt-eller-ingenting på en matche-tabell, så gjett alltid på radene du er usikker på. Blankt og feil gir likt (0 poeng), og fra 2024/2025 er negativ scoring fjernet.

— naturlig pausepunkt —

Bolk 3 — Resten av apparatet, og tolv drilloppgaver (~30 min)

Fire konstruksjoner gjenstår før du har hele verktøykassen: å få tak i feilmeldingen, rekkefølgen på except-blokkene, else/finally, og å kaste en feil selv med raise.

`except FeilType as e` — få tak i feilmeldingen

Skriver du except ValueError as e, får du selve feilobjektet i variabelen e. Skriver du e ut, får du meldingen Python ville vist. Det er praktisk når du behandler mange verdier og vil vite hvilken som feilet.

tekster = ['3.5', 'to', '7']
for t in tekster:
    try:
        print(float(t) * 2)
    except ValueError as e:
        print('Hoppet over:', e)

Utskrift:

7.0
Hoppet over: could not convert string to float: 'to'
14.0

Legg merke til at løkka fortsetter etter feilen: try/except inne i en løkke lar deg hoppe over de dårlige verdiene og fortsette med resten.

Rekkefølgen på `except`-blokkene

Python leter nedover og bruker den første except som passer. Er en av dem generell (except Exception fanger alt), må den stå sist — ellers blir de spesifikke under aldri brukt.

try:
    x = int('to')
except Exception:
    print('Noe gikk galt')
except ValueError:
    print('Ikke et tall')

Utskrift:

Noe gikk galt

Her utløses en ValueError, men det er except Exception som kjører, fordi den står først. Meldingen Ikke et tall er død kode. Er blokkene derimot uavhengige feiltyper — IndexError, ValueError, ZeroDivisionError — kan de stå i hvilken som helst rekkefølge.

`else` og `finally` i en `try`-setning
else kjøres bare hvis try-blokken gikk helt gjennom uten feil. finally kjøres alltid, med eller uten feil, og brukes til opprydding.

try:
    x = int('42')
except ValueError:
    print('Ikke et tall')
else:
    print('Konverteringen gikk bra:', x)
finally:
    print('Ferdig uansett')

Utskrift:

Konverteringen gikk bra: 42
Ferdig uansett

Med int('to') i stedet, altså en verdi som feiler, blir utskriften:

Utskrift:

Ikke et tall
Ferdig uansett

Legg merke til at else faller bort mens finally kjører uansett. På eksamen er finally sjelden, men den dukker opp i sporingsoppgaver nettopp fordi «kjøres alltid» er lett å glemme.

`raise` — kast en feil selv
raise ValueError('melding') utløser en exception fra din egen kode. Det brukes til å avvise ugyldige argumenter i en funksjon: du sier hva som er galt, og la den som kalte funksjonen bestemme hva som skal skje.

def temp_i_kelvin(t):
    if t < -273.15:
        raise ValueError('temperatur under absolutt nullpunkt')
    return t + 273.15

print(temp_i_kelvin(-300))

Utskrift:

ValueError: temperatur under absolutt nullpunkt

Dette er siste linje i feilmeldingen; til vanlig utskrift skriver programmet ingenting før det stopper.

Fanges feilen, oppfører den seg som alle andre exceptions:

def temp_i_kelvin(t):
    if t < -273.15:
        raise ValueError('temperatur under absolutt nullpunkt')
    return t + 273.15

for t in [20.0, -300.0]:
    try:
        print(temp_i_kelvin(t))
    except ValueError as e:
        print('Avvist:', e)

Utskrift:

293.15
Avvist: temperatur under absolutt nullpunkt

Merk at 20+273.15=293.1520 + 273.15 = 293.15 skrives ut helt normalt for den gyldige verdien.

Drilloppgavene

Tolv oppgaver, alle på eksamensnivå og med full løsning. De veksler mellom matche-tabeller (sjanger C), sporing av try/except (sjanger A) og «finn feilen» (sjanger O). Gjør dem med papir og penn — du har ingen maskin på eksamen.

📝Oppgave 2
Eksamensnivå, sjanger C

Programmet under er lagret som deling.py. Match hver kjøring mot utfallet.

import sys
x = float(sys.argv[1])
y = float(sys.argv[2])
print(x / y)

RadKall
1python3 deling.py 8 4
2python3 deling.py 8 0
3python3 deling.py åtte 4
4python3 deling.py 8

Alternativer: (i) IndexError, (ii) ValueError, (iii) ZeroDivisionError, (iv) ingen feil.

📝Oppgave 3

(Midtveisnivå, sjanger A — kodesporing.) Hva skriver programmet ut? Skriv utskriften nøyaktig, med én linje per print.

verdier = ['4', '0', 'x', '2']
for v in verdier:
    try:
        print(10 / int(v))
    except ValueError:
        print('V')
    except ZeroDivisionError:
        print('Z')

📝Oppgave 4
Eksamensnivå, sjanger C

Programmet under er lagret som oppslag.py.

import sys
maalinger = {'mandag': [4.2, 5.1], 'tirsdag': [3.8]}
dag = sys.argv[1]
nr = int(sys.argv[2])
print(maalinger[dag][nr])

RadKall
1python3 oppslag.py mandag 1
2python3 oppslag.py tirsdag 1
3python3 oppslag.py onsdag 0
4python3 oppslag.py mandag null

Alternativer: (i) KeyError, (ii) IndexError, (iii) ValueError, (iv) ingen feil.

📝Oppgave 5
Eksamensnivå, sjanger C

Programmet under kjøres som python3 doser.py 0 to. Hvilken exception utløses?

import sys
vekt = float(sys.argv[1])
dose = float(sys.argv[2])
print(100 / vekt * dose)

Alternativer: (i) ValueError, (ii) ZeroDivisionError, (iii) IndexError, (iv) TypeError.

📝Oppgave 6
Eksamensnivå, sjanger C

Programmet under er lagret som snitt.py.

import sys
tall = sys.argv[1:]
sum_tall = 0
for t in tall:
    sum_tall += float(t)
print(sum_tall / len(tall))

RadKall
1python3 snitt.py 2 4 6
2python3 snitt.py
3python3 snitt.py 2 fire
4python3 snitt.py 0

Alternativer: (i) ingen feil, (ii) ValueError, (iii) ZeroDivisionError, (iv) IndexError.

📝Oppgave 7
Eksamensnivå, sjanger C

Programmet under er lagret som vekst.py.

import sys
rater = {'lav': 0.01, 'hoy': 0.05}
nivaa = sys.argv[1]
aar = int(sys.argv[2])
assert aar > 0, 'antall år må være positivt'
start = 100.0
for n in range(aar):
    start = start * (1 + rater[nivaa])
print(f'{start:.2f}')

RadKall
1python3 vekst.py hoy 3
2python3 vekst.py middels 3
3python3 vekst.py hoy 0
4python3 vekst.py hoy -2
5python3 vekst.py hoy 3.0

Alternativer: (i) ingen feil, (ii) ValueError, (iii) KeyError, (iv) AssertionError, (v) IndexError.

📝Oppgave 8
Eksamensnivå, sjanger A

Hva skriver programmet under ut?

try:
    x = int('to')
except Exception:
    print('Noe gikk galt')
except ValueError:
    print('Ikke et tall')

📝Oppgave 9

(Midtveisnivå, sjanger A.) Hva skriver programmet under ut?

d = {'a': 1, 'b': 0}
for k in ['a', 'b', 'c']:
    try:
        print(k, 5 // d[k])
    except KeyError as e:
        print('mangler nøkkel', e)
    except ZeroDivisionError as e:
        print('null:', e)

📝Oppgave 10
Eksamensnivå, sjanger O

Programmet bmi.py skal ta vekt i kilo og høyde i meter på kommandolinjen og skrive ut kroppsmasseindeksen, med en forståelig beskjed hvis noe er galt. Det gjør ikke det. Finn alle feilene og skriv den rettede koden.

import sys
vekt = float(sys.argv[1])
try:
    hoyde = float(sys.argv[2])
    print(f'BMI: {vekt / hoyde**2:.1f}')
except Exception:
    print('Noe gikk galt')
except ZeroDivisionError:
    print('Høyden kan ikke være null')

📝Oppgave 11
Eksamensnivå, sjanger C…

Skriv et program hent.py som tar en indeks på kommandolinjen og skriver ut det tilsvarende elementet i lista [2.0, 4.0, 8.0] med én desimal.

a) Programmet skal skrive Indeksen finnes ikke hvis indeksen er utenfor lista, og Argumentet må være et heltall hvis argumentet ikke kan tolkes som heltall.
b) Vis utskriften for python3 hent.py 1 og for python3 hent.py 7.
c) Hva skjer med programmet ditt hvis det kjøres helt uten argumenter, og hvordan kan du rette det?

📝Oppgave 12

(Midtveisnivå, sjanger A.) Hva skriver programmet under ut?

def sjekk(x):
    assert x >= 0, 'negativ verdi'
    return x ** 0.5

for x in [9, -4, 16]:
    try:
        print(sjekk(x))
    except AssertionError as e:
        print('Avvist:', e)

API- og konstruksjonsliste

Begrepsbank

Begrepsbanken er flashcard-/repetisjonsstoff — den gjentar det du nettopp har lest. Hopp trygt over ved førstegangslesing; tidsanslaget for kapitlet gjelder kjernestoffet.

Regelen om den første feilen

Et program stopper på den første operasjonen som ikke kan utføres, og det er den feilen oppgaven spør om. Alt som ligger lenger ned, kjøres aldri — heller ikke en åpenbar deling på null. Praktisk konsekvens: les alltid ovenfra og ned, og stopp der du står, i stedet for å lete etter den «verste» feilen i programmet.

`ValueError` mot `TypeError` — testen som skiller dem

Spør: er typen gal, eller er innholdet i en riktig type ubrukelig?

float('to') er en ValueError: float skal ha en streng, og det fikk den — teksten kan bare ikke tolkes som tall. 'to' + 1 er en TypeError: operasjonen er umulig for en streng og et heltall, uansett hva de inneholder. Samme test virker på [1, 2] + 3 (TypeError) og int('4.0') (ValueError).

`int` godtar fortegn, men ikke desimalpunkt
int('-2') gir −2, mens int('3.0') og int('3.5') gir ValueError. float godtar alle tre, og i tillegg eksponentform som '1e-3'. Derfor er den vanlige oppskriften i kommandolinjeprogrammer å bruke float for fysiske målinger og int bare for antall og indekser.
Heltalls- mot flyttallsdivisjon på null
7 // 0 og 7 / 0 gir samme feiltype (ZeroDivisionError), men ikke samme melding: ZeroDivisionError: integer division or modulo by zero mot ZeroDivisionError: division by zero. På en matche-tabell spør oppgaven om typen, så forskjellen betyr ingenting der — men i en sporingsoppgave der du skal skrive meldingen, gjør den det.
`except Exception` — den generelle fangeren
except Exception fanger alle exceptions. Den er nyttig som siste utpost, men farlig lenger opp: alle spesifikke except-blokker under den blir død kode uten at Python advarer. Regelen er derfor «spesifikk før generell», og i eksamensbesvarelser er det tryggest å bare bruke spesifikke feiltyper — da viser du at du vet hva som faktisk kan gå galt.
`d.get(nøkkel, standard)` — oppslag som ikke feiler
d['bergen'] gir KeyError hvis nøkkelen mangler. d.get('bergen', 0) gir i stedet standardverdien 0 og feiler aldri. Det er den ryddige måten å håndtere manglende data på — og i en matche-tabell er det verdt å se etter: står det .get, er KeyError utelukket for den raden.
Repetisjon — sjekk deg selv før du går videre

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.

Skolesaga er en uavhengig læringsressurs og er ikke tilknyttet eller godkjent av Universitetet i Oslo. Dette er ikke offisielt studiemateriell. Les mer.