Tilbake
4.1

4.1 DRILL — Kodesporing: «hva skrives ut?»

Systematisk drill i å kjøre kode mekanisk i hodet og angi utskriften **eksakt** — Oppgave 1, den billigste og mest forutsigbare poengkilden.

90 min
16 oppgaver
DRILLKodesporinghva skrives ut?
Din fremgang i kapitlet
0 / 16 oppgaver
Kapitlets plass i kurset

Forkunnskaper — sist du var her

Hele del 1 til 3: kap. 1.1 — Variabler og datatyper,
kap. 1.2 — Betingelser,
kap. 1.3 — Løkker,
kap. 2.1 — Funksjoner,
kap. 3.1 — Lister,
kap. 3.2 — Ordbøker og
kap. 3.3 — Strenger.

Dette kapitlet lærer deg ingen ny konstruksjon. Det lærer deg å lese dem du allerede kan, uten å ta feil.

Tre ting du bruker på hver eneste oppgave, kort oppfrisket:

print(3, "a")
print(9 / 3, 9 // 3)
print([1, 2], {"a": 1})

Utskrift:

3 a
3.0 3
[1, 2] {'a': 1}

Merk ett mellomrom mellom komma-argumenter, at / alltid gir desimaltall, og at lister og ordbøker skrives med sine parenteser og med enkle anførselstegn rundt tekster. Disse tre detaljene avgjør flere poeng i Oppgave 1 enn all algoritmisk forståelse til sammen.

Sporingsmetoden — fem steg (~10 min)

Å spore kode er et håndverk med en fast oppskrift. Den er kjedelig, og det er hele poenget: du skal ikke gjette hva programmet gjør, du skal regne det ut.

📜Bokas sporingsmetode
Steg 1 — Før en tavle. Tegn en tabell med én kolonne per variabel som
endrer seg, og én kolonne til høyre som heter «Utskrift så langt». Én rad per linje eller per runde i løkka. Dette er ikke pynt: uten tavle husker du feil.

Steg 2 — Tell rundene i løkka først. range(3) gir 0, 1, 2 — tre runder.
range(1, 4) gir 1, 2, 3 — også tre. range(len(liste)) gir nøyaktig de lovlige indeksene. Skriv opp verdiene før du begynner å regne, så slipper du å telle mens du sporer.

Steg 3 — Les hver print bokstavelig. Komma gir ett mellomrom. En liste
skrives med hakeparenteser, en ordbok med krøllparenteser, og tekster inne i
dem får enkle anførselstegn. En tekst skrevet ut alene får ingen.

Steg 4 — Hold styr på typen. Er verdien et heltall eller et desimaltall? En
tekst eller et tall? / gir alltid float; // og % gir heltall når begge sidene er heltall; + på to tekster skjøter dem.

Steg 5 — Skriv svaret eksakt, uten pynt. Ikke 5.0 for heltallet 5, ikke
'tekst' med anførselstegn i svarfeltet, ingen ekstra mellomrom. I et auto-rettet felt er formen en del av svaret.

Fellekatalogen — de sju fellene som går igjen

Oppgave 1 er ikke tilfeldig satt sammen. De samme sju fellene roterer, og hver deloppgave tester som regel nøyaktig én av dem.

Nr.FellenKjennetegn i koden
1Tekst forvekslet med tall (#3)anførselstegn rundt sifre, eller + mellom to verdier som «ser ut som tall»
2Glemt konvertering (#4)int(...) står ett sted og ikke et annet
3Muteringsrekkefølgeto variabler oppdateres i samme runde, og den andre bruker den nye verdien
4Nøstet akkumuleringen løkke inne i en løkke, ofte med en if og en teller
5while med flere variablerbetingelsen avhenger av noe som endres midt i kroppen
6Indeks og av-med-én (#5, #6)liste[i], liste[-1], range(1, len(...))
7Ordbok som endrer seg selvd[k] = d[k] + 1 inne i en løkke

De seksten oppgavene i dette kapitlet roterer alle sju, med fire økter etter tema. Kjenner du igjen fellen på synet, vet du også hvor du skal være ekstra nøye.
✏️Gjennomsporet eksamenscase — en full Oppgave 1, med sensors blikk
Oppgave 1 (8 poeng). Fire deloppgaver. Skriv utskriften nøyaktig, med
mellomrom og linjeskift slik terminalen viser den.

a) (2 p)

a = "12" b = "3" print(a + b, int(a) + int(b))

b) (2 p)

x = 3 y = 2 for i in range(2):
    x = x + y y = x - y print(x, y)

c) (2 p)

tall = [4, 8, 15]
print(tall[-1] - tall[0], len(tall))

d) (2 p)

d = {}
for bokstav in "banan":
    if bokstav not in d:
        d[bokstav] = 0 d[bokstav] = d[bokstav] + 1 print(d)
Deloppgave a — felle 1 og 2. To verdier som ser ut som tall, men er tekster.

UttrykkType på sideneResultat
a + btekst + tekst"123" — skjøtet
int(a) + int(b)tall + tall15 — lagt sammen

a = "12" b = "3" print(a + b, int(a) + int(b))
Utskrift:
123 15

Margnotat (2 p): ett poeng per riktig verdi. Skriver du 15 15, har du

oversett anførselstegnene; skriver du 123 123, har du oversett int(...).
Fellen er #3 — heltall forvekslet med tekst.

— naturlig pausepunkt —
Deloppgave b — felle 3. To variabler oppdateres i samme runde, og den andre
linja bruker den nye verdien av x.

Rundex etter linje 1y etter linje 2
start32
i = 03 + 2 = 55 - 2 = 3
i = 15 + 3 = 88 - 3 = 5

x = 3 y = 2 for i in range(2):
    x = x + y y = x - y print(x, y)
Utskrift:

8 5
Margnotat (2 p): her er tavla hele forskjellen. Bruker du den gamle
verdien av x på linje to, får du 8 3 — riktig metode, feil rekkefølge, og på et auto-rettet felt null poeng. Fyll ut én rad om gangen, ovenfra og ned.
Deloppgave c — felle 6. Negativ indeks og lengde.
UttrykkVerdi
tall[-1]15 — siste element
tall[0]4 — første element
len(tall)3 — antall elementer

tall = [4, 8, 15]
print(tall[-1] - tall[0], len(tall))

Utskrift:

11 3

Margnotat (2 p): merk at ingen av de to verdiene har hakeparenteser. Det er
enkeltverdier hentet ut av lista, ikke lista selv. Fellen er #5 — å lese -1 som nest siste, eller lengden som største indeks.

Deloppgave d — felle 7. En ordbok som endrer seg selv.

BokstavNy nøkkel?Ordboka etter runden
bja{'b': 1}
aja{'b': 1, 'a': 1}
nja{'b': 1, 'a': 1, 'n': 1}
anei{'b': 1, 'a': 2, 'n': 1}
nnei{'b': 1, 'a': 2, 'n': 2}

d = {}
for bokstav in "banan":
    if bokstav not in d:
        d[bokstav] = 0 d[bokstav] = d[bokstav] + 1 print(d)
Utskrift:
{'b': 1, 'a': 2, 'n': 2}
Margnotat (2 p): to ting må stemme samtidig — tallene og rekkefølgen.

Nøklene står i den rekkefølgen de ble opprettet i, ikke alfabetisk og ikke etter størrelse. Og tekstnøklene skrives med enkle anførselstegn.

Om tidsbruk: hele denne oppgaven er 8 poeng av 100, og bør ta rundt 20
minutter med tavle. Det er de billigste poengene på settet — men bare hvis du skriver formen riktig.

Drilløkt 1 — Typer, uttrykk og forgrening (~16 min)

Fire oppgaver som tester felle 1, 2 og utskriftsformen. Før tavle på alle fire, selv om de ser enkle ut — det er nettopp de enkle som taper poeng på formen.

📝Oppgave 1

(Innstegsoppgave, sjanger A — kodesporing.) Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

a = "7" b = "3" print(a + b)
print(int(a) + int(b))
print(int(a) // int(b), int(a) % int(b))

📝Oppgave 2

(Innstegsoppgave, sjanger A — kodesporing.) Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

print(9 / 3)
print(9 // 3, 9 % 3)
print(2 ** 3, 7 / 2)

📝Oppgave 3
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

poeng = 60 if poeng > 60:
    print("bestatt")
elif poeng > 40:
    print("nesten")
else:
    print("ikke bestatt")
print("ferdig")

📝Oppgave 4
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

print("a", "b")
print("a" + "b")
print(1, 2.0, True)
print("2" * 3)

Drilløkt 2 — Løkker og oppdateringsrekkefølge (~18 min)

Her kommer fellene som faktisk krever tavle. Fyll ut én rad per runde, ovenfra og ned, og ikke hopp over en linje fordi du «ser» hva den gjør.

📝Oppgave 5
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

a = 2 b = 1 for i in range(3):
    a = 2 * a + b b = a - b print(a, b)

📝Oppgave 6
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

total = 0 for i in range(4):
    for j in range(i):
        if j % 2 == 0:
            total = total + 1 print(total)

📝Oppgave 7
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

n = 20 s = 0 runder = 0 while n > 1:
    s = s + n n = n // 2 runder = runder + 1 print(s, n, runder)

📝Oppgave 8
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

antall = 0 sum_verdi = 0 for i in range(10, 0, -3):
    antall = antall + 1 sum_verdi = sum_verdi + i print(i, antall, sum_verdi)

Drilløkt 3 — Lister og indekser (~16 min)

Nå kommer felle 6 for fullt. Skriv alltid indeksene over elementene før du begynner — det tar fem sekunder og fjerner halvparten av feilene.

📝Oppgave 9
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

maalinger = [3, 9, 12, 5]
print(maalinger[1], maalinger[-2])
print(maalinger[0] + maalinger[3])
print(len(maalinger), maalinger)

📝Oppgave 10
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

tall = [2, 5, 8]
ny = []
for t in tall:
    ny.append(t * 2)
tall[0] = 99 print(tall)
print(ny)
print(tall + ny)

📝Oppgave 11
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

verdier = [6, 2, 9, 4]
resultat = []
for i in range(1, len(verdier)):
    resultat.append(verdier[i] - verdier[i - 1])
print(resultat)
print(len(resultat), verdier[-1] - verdier[0])

📝Oppgave 12
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

tall = [5, 3, 8, 1, 7]
valgt = []
i = 0 while i < len(tall):
    if tall[i] > tall[0]:
        valgt.append(tall[i])
    i = i + 2 print(valgt, len(valgt))
print(i, tall[-1])

Drilløkt 4 — Ordbøker, tekst og funksjoner (~18 min)

Den siste økta er den tyngste. Her kommer felle 7, og de sammensatte oppgavene der du må spore et funksjonskall inne i en løkke.

📝Oppgave 13
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

d = {"a": 2}
d["b"] = 5 d["a"] = d["a"] + 3 print(d)
print(len(d), d["a"], "c" in d)

📝Oppgave 14
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

d = {}
for tall in [4, 1, 4, 2, 4, 1]:
    if tall not in d:
        d[tall] = 0 d[tall] = d[tall] + 1 print(d)
print(len(d), d[4], d[1] + d[2])

📝Oppgave 15
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

linje = "31;Grorud;Fornebu" felt = linje.split(";")
ny = "" for tegn in felt[0]:
    ny = tegn + ny print(felt)
print(len(felt), felt[-1])
print(ny, int(ny) + 1)

📝Oppgave 16
Eksamensnivå, sjanger A

Hva skriver programmet ut? Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

def juster(x, grense):
    if x > grense:
        return x - grense return 0

sum_verdi = 0 tallene = [12, 7, 20]
for tall in tallene:
    sum_verdi = sum_verdi + juster(tall, 10)
print(sum_verdi)
print(juster(10, 10), juster(3, 10), juster(25, 10))

API- og konstruksjonsliste

Begrepsbank

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

Sporingstavle

En tabell med én kolonne per variabel som endrer seg, én rad per linje eller runde, og en siste kolonne «Utskrift så langt».

Den er ikke pynt, og den er ikke for sensor — den er for deg. Uten tavle holder du to eller tre verdier i hodet samtidig, og nettopp det er det oppgaven er konstruert for å gjøre vanskelig.

Regn med et halvt minutt per deloppgave. Det er billig, mot 8 poeng.

Antall runder i en `range`

Det første du skriver opp, før du regner på noe.

range(3) gir 0, 1, 2. range(1, 4) gir 1, 2, 3. range(10, 0, -3) gir 10, 7,
4, 1. range(0) gir ingen runder. Stoppverdien er alltid eksklusiv, uansett retning.

Antall runder er stopp - start når steget er 1. Med et annet steg må du skrive verdiene ut — det er raskere enn å regne, og du bommer ikke.

Muteringsrekkefølge

At en linje ser variablenes verdier slik de er akkurat da, ikke slik de var ved rundens start.

Står det

a = 2 b = 1 a = a + b b = a + b print(a, b)

Utskrift:

3 4

bruker den siste linja den nye a (3), ikke den gamle (2). Å fylle ut tavla parallelt i stedet for ovenfra og ned er den vanligste kilden til feil svar i løkkeoppgaver.

Kantverdi

Verdien som ligger nøyaktig på grensen i en betingelse.

60 > 60 er usann; 60 >= 60 er sann. Oppgave 1 velger nesten alltid data som ligger på kanten, fordi det er der forskjellen mellom > og >= vises.

Vanen som lønner seg: hver gang du ser en sammenligning, sjekk om verdien er akkurat like stor. Er den det, er det sannsynligvis hele poenget med deloppgaven.

Antall runder i en nøstet løkke

Med faste grenser ganges antallet: for i in range(3) med
for j in range(2) inni gir 3 ganger 2, altså 6 runder.

Med en indre grense som avhenger av den ytre må du telle: for j in range(i) gir 0, 1, 2 … runder etter tur. Den første runden gjør da ingenting, fordi
range(0) er tom.

Skriv opp j-verdiene per i i en egen kolonne. Det er raskere enn å prøve å holde dem i hodet.

Løkkevariabelen etter løkka

En løkkevariabel forsvinner ikke når løkka er ferdig. Den beholder den siste verdien den fikk, og kan leses på linja etter.

For for i in range(10, 0, -3): er i lik 1 etterpå — den siste verdien
range ga, ikke stoppverdien.

For en while gjelder det samme, men med en vri: variabelen har den verdien som gjorde betingelsen usann. Etter while i < 5: med i = i + 2 fra 0, er i lik 6, ikke 5.

`print` med komma

Komma mellom argumentene gir ett mellomrom mellom dem i utskriften, og
print avslutter alltid med linjeskift.

Pluss gjør noe annet: print("a" + "b") er ett argument, og gir ab uten mellomrom.

Skillet er verdt et poeng i nesten hver eneste Oppgave 1. Les hvert print bokstavelig: hvor mange argumenter er det, og hva står mellom dem?

Utskrift av en liste
print(liste) viser hakeparenteser, komma og ett mellomrom etter hvert komma — og tekster inne i lista får enkle anførselstegn.

print(liste[0]) viser ingen av delene: det er én verdi, ikke en liste.

Begge formene dukker gjerne opp i samme deloppgave, nettopp for å teste om du ser forskjellen. Skriv svaret slik terminalen ville vist det, tegn for tegn.

Utskrift av en ordbok
print(ordbok) viser krøllparenteser, kolon og komma: {'a': 1, 'b': 2}.

Tekstnøkler får enkle anførselstegn, heltallsnøkler får ikke. En telling over
tall gir {4: 3, 1: 2}, mens en telling over ord gir {'buss': 3}.

Rekkefølgen er den nøklene ble opprettet i. Å overskrive en verdi flytter ikke nøkkelen bakerst, og ordboka sorterer aldri.

Heltall mot desimaltall
/ gir alltid desimaltall, også når regnestykket går opp: 9 / 3 er 3.0.
// og % gir heltall når begge sidene er heltall.

I et auto-rettet svarfelt er 3 og 3.0 to ulike svar, og bare det ene er riktig. Det samme gjelder 18 mot 18.0.

Vanen som lønner seg: skriv typen i margen ved siden av hver verdi mens du sporer. Da ser du selv når en divisjon har gjort et heltall om til et desimaltall.

Tekst mot tall i en sporing

Anførselstegn er det første du leter etter, før du regner på noe.

"1" + "2" er "12"; 1 + 2 er 3. "ab" * 3 gjentar; 2 * 3 ganger.
"12" == 12 er usann. Og alt som kommer fra input(), en fil eller .split() er tekst, uansett hvor mye det ser ut som et tall.

Dette er feilkode #3 og #4, og de to er tilsammen den hyppigste fellen i
Oppgave 1.

Auto-rettet svarfelt

I de nyere settene rettes Oppgave 1 maskinelt: du skriver svaret i et lite felt, og en maskin sammenligner det med fasiten.

Det betyr at formen er en del av svaret. Skriv 18, ikke 18.0. Skriv
tekst, ikke 'tekst' med anførselstegn. Ikke legg til mellomrom du ikke ser i terminalen, og ikke fjern noen heller.

Er du i tvil om formen, skriv den slik print ville vist den — det er alltid fasiten.

Å spore en betingelseskjede

I en if-elif-else-kjede kjøres nøyaktig én gren: den første som er sann. Resten prøves ikke engang.

To selvstendige if-er er noe helt annet — der er begge spørsmål, og begge kan slå til. Forskjellen er ett ord i koden, og den snur svaret.

Se også etter linjer uten innrykk under kjeden. De står utenfor og kjøres uansett hvilken gren som slo til.

Å spore et funksjonskall

Når en løkke kaller en funksjon, sporer du funksjonen for seg først.

Lag en liten tavle med én rad per kall: argumentene inn, betingelsene inne i funksjonen, og verdien ut. Deretter setter du returverdiene inn i den ytre tavla.

Husk at en funksjon uten return gir None, og at return avslutter umiddelbart — linjer under blir aldri kjørt.

Å spore en ordbok som endrer seg

Skriv ordboka på nytt, i sin helhet, etter hver runde. Ikke prøv å holde endringene i hodet.

To spørsmål per runde: ble nøkkelen opprettet nå, eller fantes den fra før?
Og hva ble den nye verdien?

Rekkefølgen i utskriften følger opprettelsen. Derfor må du notere når hver nøkkel dukket opp første gang — det er ikke noe du kan rekonstruere til slutt.

Tidsbruk på Oppgave 1

Oppgave 1 er rundt 8 av 100 poeng, fordelt på fem til sju deloppgaver. Det gir omtrent 20 av de 240 minuttene.

Bruk dem. Dette er den eneste oppgaven der du kan være sikker på å få alle poengene, fordi svaret er mekanisk og fasiten entydig.

Men ikke bruk mer. Blir du sittende fast på én deloppgave, skriv ditt beste forsøk og gå videre — deloppgavene rettes hver for seg, og Oppgave 4 venter med nesten halve eksamen.

Repetisjon — de sju setningene som må sitte

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.