Tilbake
9.2

9.2 Avsluttende øvingseksamen 1 — epidemi-innpakning

Komplett 4-timers avsluttende sett etter 13–16-oppgavemalen: et flervalgsskall etterfulgt av full kodeskriving, med epidemimodell som ODE-innpakning.

240 min
14 oppgaver
Avsluttende øvingseksamen 1epidemi-innpakning
Din fremgang i kapitlet
0 / 14 oppgaver
Forkunnskaper: hele boka til og med Del 8, og kap. 9.1 som oppvarming. Settet trekker på sju kapitler mer enn de andre:

- kap. 3.1 og kap. 3.2 — testfunksjoner og rekker (oppgave 7 og 14)
- kap. 5.1 og kap. 5.2__init__, __call__, __str__ og __mul__ (oppgave 2 og 9)
- kap. 6.2 — differenslikninger og oppdateringsrekkefølge (oppgave 10)
- kap. 7.2 og kap. 7.3 — det utleverte ODESolver-hierarkiet og ODE-systemer (oppgave 6 og 11)
- kap. 8.1 og kap. 8.2 — fillesing til nøstet dictionary, filtrering og skriving (oppgave 12 og 13)
- kap. 4.3 — plotting med label= og legend() (oppgave 10b og 11c)

Innpakningen i dette settet er en epidemi: smittetall, en smitterate som varierer med årstiden, en diskret modell med karantene, og et vaksinasjonsscenario løst som ODE-system. Innpakningen roterer år for år på den reelle eksamenen — det er kodemønsteret bak som gjentar seg.

Slik tar du settet

Sett av fire timer i ett stykke, og bruk minuttbudsjettet under som klokke. Skriv koden for hånd eller i en editor uten å kjøre den — i desember har du bare tekstfeltet i Inspera. Å oppdage at man er avhengig av å trykke «kjør» er den dyreste erkjennelsen man kan gjøre på eksamensdagen, og den bør komme nå.

OppgaveSjangerPoengTid
1A — kodesporing24 min
2A — kodesporing (klasse)35 min
3A — kodesporing (array)35 min
4B — indekserings-matche25 min
5C — exception-matche36 min
6E — hvilken linje mangler35 min
Skall1630 min
7F — rekke + testfunksjon620 min
8A — skriv utskriften412 min
9G — klasse med spesialmetoder1035 min
10H — differenslikning + plott930 min
11J — ODE-system med hierarkiet1035 min
12L — fillesing til nøstet dictionary830 min
13L — filtrering og skriving625 min
14F — testfunksjon og bruk623 min
Kodedel59210 min
Sum75240 min

Disponering. Skallet er billige poeng: seks oppgaver, 16 poeng, en halvtime. Bruker du 45 minutter der, stjeler du fra oppgave 9 og 11, som er de tyngste enkeltoppgavene i settet. Er du usikker på et flervalg, kryss av og gå videre — blankt og feil gir det samme.
De store oppgavene har deloppgaver som kan løses uavhengig. Får du ikke klassen i oppgave 9 til å virke, skriv testfunksjonen i oppgave 14 likevel: du vet hva klassen skal gjøre, og det er nok.
Etter oppgave 6 er det et naturlig pausepunkt. Tar du settet som lesetrening over flere kvelder, er skallet én økt, oppgave 7–10 en annen, og oppgave 11–14 en tredje.

Del 1 — flervalgsskallet

Oppgave 1–6 · 16 poeng · ~30 minutter.

Fire «select one» og to matche-tabeller. I matche-tabellene er hver rad 0,5 poeng og vurderes for seg.

📝Oppgave 9.2.1
Eksamensnivå, sjanger A
Oppgave 1 (2 poeng).

Tre kohorter i en smittesporing er lagt i en nøstet liste. Hva skriver programmet ut?

kohort = [[3, 5], [2], [7, 1, 4]]
total = 0
for gruppe in kohort:
    total += len(gruppe) * gruppe[-1]
print(total, len(kohort))

a) 24 3
b) 22 3
c) 24 6
d) 12 3

📝Oppgave 9.2.2
Eksamensnivå, sjanger A
Oppgave 2 (3 poeng).

Hva skriver programmet ut?

class Teller:
    def __init__(self, start):
        self.n = start

    def __call__(self, okning):
        self.n = self.n + okning
        return self.n

t = Teller(4)
print(t(3), t(3), t.n)

a) 7 7 4
b) 7 10 10
c) 4 7 10
d) 7 10 4

📝Oppgave 9.2.3
Eksamensnivå, sjanger A
Oppgave 3 (3 poeng).

Hva skriver programmet ut? Legg merke til at NumPy skriver arrayer uten komma.

import numpy as np

u = np.zeros(6)
u[0] = 100.0
for n in range(3):
    u[n + 1] = u[n] * 0.8
print(u[:4], u.size, u[-1])

a) [100. 80. 64. 51.2] 6 0.0
b) [100. 80. 64. 51.2] 4 51.2
c) [100. 80. 64.] 6 0.0
d) [80. 64. 51.2 41.0] 6 0.0

📝Oppgave 9.2.4
Eksamensnivå, sjanger B
Oppgave 4 (2 poeng, 0,5 per rad).

Gitt

uker = [10, 11, 12]
tall = [[41, 3], [58, 6], [73, 9]]

Par hvert uttrykk med verdien.

RadUttrykk
1tall[uker[0] - 10][1]
2tall[-1][:1]
3tall[1][uker[1] - 11:]
4uker[tall[0][1] - 2]

Alternativer:
1. [58, 6]
2. 11
3. 3
4. [73]

5. [73, 9]

6. 41
7. [3]
8. 12

📝Oppgave 9.2.5
Eksamensnivå, sjanger C
Oppgave 5 (3 poeng, 0,5 per rad).

Filen andel.py inneholder:

import sys

def andel(smittede, testede):
    assert testede > 0, 'ingen tester'
    return 100 * smittede / testede

verdier = {'u10': ['41', '500'], 'u11': ['58', '0'], 'u12': ['sju', '300']}
uke = sys.argv[1]
par = verdier[uke]
print(andel(int(par[0]), int(par[1])))

Par hver kommandolinje med det som skjer.

RadKommandolinje
1python andel.py u10
2python andel.py u11
3python andel.py u12
4python andel.py
5python andel.py U10
6python andel.py u10 ekstra

Alternativer:
1. AssertionError
2. KeyError
3. Ingen feil — programmet skriver et tall
4. ValueError
5. IndexError
6. ZeroDivisionError
📝Oppgave 9.2.6
Eksamensnivå, sjanger E
Oppgave 6 (3 poeng).

Programmet skal løse u=0.2uu' = -0.2u fra t=0t = 0 til t=10t = 10 med 100 steg, med u(0) = 50, ved hjelp av det utleverte ODESolver-hierarkiet. Én linje er fjernet:

from ODESolver import RungeKutta4

def f(t, u):
    return -0.2 * u

solver = RungeKutta4(f)
# HER MANGLER ÉN LINJE
t, u = solver.solve((0, 10), 100)
print(u[-1])

Hvilken linje hører på plassen?

a) solver.u0 = 50.0
b) solver.set_initial_condition(50.0)
c) solver.solve(50.0)
d) solver = RungeKutta4(f, 50.0)

— naturlig pausepunkt —

Del 2 — kodeskriving

Oppgave 7–14 · 59 poeng · ~210 minutter.

Herfra er alt fritekst: du skriver kode i et tekstfelt. Skriv den ferdig uten å kjøre den, og skriv den kort. Deloppgavene kan løses uavhengig av hverandre.

📝Oppgave 9.2.7
Eksamensnivå, sjanger F
Oppgave 7 (6 poeng).

Cosinus kan skrives som en uendelig rekke:

cosx=k=0(1)kx2k(2k)!\cos x = \sum_{k=0}^{\infty} (-1)^k \frac{x^{2k}}{(2k)!}

a) Skriv en funksjon cos_rekke(x, N) som returnerer summen av leddene fra k=0k = 0 til og med k=Nk = N. (4 poeng)

b) Skriv en testfunksjon test_cos_rekke() som sjekker at cos_rekke gir omtrent samme svar som math.cos for x=0.5x = 0.5 med N=10N = 10. Testfunksjonen skal ikke ta argumenter og ikke skrive ut noe. (2 poeng)

📝Oppgave 9.2.8
Eksamensnivå, sjanger A
Oppgave 8 (4 poeng).

Skriv nøyaktig hva programmet skriver ut, med mellomrom og desimaler slik terminalen viser det.

tilfeller = {'u10': 41, 'u11': 58, 'u12': 73}
forrige = 0
for uke in tilfeller:
    if forrige == 0:
        vekst = 0.0
    else:
        vekst = (tilfeller[uke] - forrige) / forrige
    print(f'{uke:>4s}{tilfeller[uke]:5d}{vekst:7.2f}')
    forrige = tilfeller[uke]
📝Oppgave 9.2.9
Eksamensnivå, sjanger G
Oppgave 9 (10 poeng).

Smitteraten i en luftveisinfeksjon varierer med årstiden. En vanlig modell er

β(t)=β0(1+asin ⁣(2πtP))\beta(t) = \beta_0 \left(1 + a \sin\!\left(\frac{2\pi t}{P}\right)\right)

der tt måles i døgn, β0\beta_0 er grunnraten, aa er svingningens relative størrelse og PP er perioden i døgn.

a) Skriv en klasse Smitterate som tar β0\beta_0, aa og PP i konstruktøren, og som gjør instansen kallbar, slik at beta(t) gir β(t)\beta(t). (5 poeng)

b) Utvid klassen med to spesialmetoder: __str__, som returnerer en lesbar formel for raten, og __mul__, slik at beta * k gir en ny Smitterate der grunnraten er ganget med k — det er slik man modellerer et smitteverntiltak som reduserer kontaktraten. (5 poeng)

📝Oppgave 9.2.10
Eksamensnivå, sjanger H
Oppgave 10 (9 poeng).

En kommune modellerer et utbrudd dag for dag. SnS_n er antall mottakelige og InI_n antall smittsomme på dag nn. Alle som smittes, settes i karantene og regnes som smittsomme; en fast andel γ\gamma av de smittsomme friskmeldes hvert døgn:

Sn+1=SnβSnInS_{n+1} = S_n - \beta S_n I_n
In+1=In+(SnSn+1)γInI_{n+1} = I_n + (S_n - S_{n+1}) - \gamma I_n

Legg merke til at In+1I_{n+1} bruker Sn+1S_{n+1}: antall nysmittede er nettopp nedgangen i SS.

a) Skriv en funksjon karantene(S0, I0, beta, gamma, N) som regner ut NN steg og returnerer de to arrayene S og I. (6 poeng)

b) Skriv koden som plotter de to kurvene i samme figur med S0 = 5000, I0 = 10, beta = 2e-4, gamma = 0.25 og N = 60, med aksenavn og forklaring (legende). (3 poeng)

📝Oppgave 9.2.11
Eksamensnivå, sjanger J
Oppgave 11 (10 poeng).

En befolkning på N=100000N = 100\,000 deles i fire grupper: mottakelige SS, smittsomme II, immune RR og vaksinerte VV. Modellen er

S=βSINνS,I=βSINγI,R=γI,V=νSS' = -\beta \frac{SI}{N} - \nu S, \qquad I' = \beta \frac{SI}{N} - \gamma I, \qquad R' = \gamma I, \qquad V' = \nu S

med β=0.32\beta = 0.32, γ=0.10\gamma = 0.10 og ν=0.005\nu = 0.005 (vaksinasjonsraten). Ved t=0t = 0 er I=10I = 10, S=99990S = 99\,990 og R=V=0R = V = 0. Tiden måles i døgn.

Du har ODESolver-modulen med klassene ForwardEuler og RungeKutta4 tilgjengelig.

a) Skriv høyresiden som en funksjon f(t, u) som pakker ut tilstandsvektoren og returnerer de fire deriverte. (4 poeng)

b) Skriv koden som løser systemet fra t=0t = 0 til t=180t = 180 med 1800 steg ved hjelp av RungeKutta4, og som pakker ut de fire komponentene i egne variabler. (3 poeng)

c) Skriv koden som plotter de fire kurvene i samme figur med forklaring, og beskriv hva figuren viser. (3 poeng)

📝Oppgave 9.2.12
Eksamensnivå, sjanger L
Oppgave 12 (8 poeng).

Filen smittetall.txt har én linje per bydel og uke, med semikolon som skilletegn og en overskriftslinje først:

bydel;uke;smittede;innlagte
Storhaug;10;41;3
Storhaug;11;58;6
Storhaug;12;73;9
Hillevag;10;22;1
Hillevag;11;19;2
Hillevag;12;31;4
Tasta;10;7;0
Tasta;11;12;1
Tasta;12;9;1

a) Skriv les_smittetall(filnavn) som returnerer en nøstet dictionary der ytre nøkkel er bydelsnavnet, indre nøkkel er ukenummeret som heltall, og verdien er en dictionary {'smittede': ..., 'innlagte': ...} med heltall. (5 poeng)

b) Skriv toppuke(data, bydel) som returnerer ukenummeret der bydelen hadde flest smittede. (3 poeng)

📝Oppgave 9.2.13
Eksamensnivå, sjanger L
Oppgave 13 (6 poeng).

Bruk dictionaryen fra oppgave 12. Du kan løse denne oppgaven selv om du ikke fikk den forrige til å virke — du vet hvordan strukturen ser ut.

a) Skriv filtrer(data, grense) som returnerer en ny dictionary med bare de bydelene der summen av smittede over alle uker er minst grense. Argumentet data skal ikke endres. (3 poeng)

b) Skriv skriv_totaler(data, filnavn) som skriver en fil med overskriftslinja bydel;total og deretter én linje per bydel på formen navn;sum. (3 poeng)

📝Oppgave 9.2.14
Eksamensnivå, sjanger F
Oppgave 14 (6 poeng).

Denne oppgaven bruker Smitterate-klassen fra oppgave 9. Du kan løse den selv om du ikke fikk klassen til å virke: du vet at beta(t) gir β0(1+asin(2πt/P))\beta_0(1 + a\sin(2\pi t/P)), og at beta * k gir en ny Smitterate med grunnraten ganget med k.

a) Skriv to testfunksjoner: test_smitterate(), som sjekker at raten er riktig i to punkter du kan regne ut for hånd, og test_mul(), som sjekker at beta * k gir riktig type og riktige verdier. (4 poeng)

b) Skriv koden som lager en Smitterate med β0=0.30\beta_0 = 0.30, a=0.25a = 0.25, P=360P = 360, lager et tiltak som reduserer grunnraten til 60 %, og skriver en tabell over begge ratene ved t=0,90,180,270t = 0, 90, 180, 270. (2 poeng)

Oppgave 15 — skal ikke besvares

På det reelle settet står det til slutt en «oppgave» med et tomt svarfelt og en beskjed om at den ikke skal besvares. Nummeret varierer — 15, 16 eller 17, avhengig av hvor mange oppgaver settet har — men funksjonen er alltid den samme: det er feltet der sensor legger inn poengene dine fra midtveiseksamen.

Regnestykket er enkelt. Den avsluttende eksamenen gir maks 75 poeng, midtveiseksamen maks 25, og til sammen blir det 100. Ved å legge midtveispoengene inn i samme oppgavesett kan Inspera regne ut totalen automatisk.

Hva du skal gjøre med den: ingenting. La feltet stå tomt og gå videre. Hvert år er det kandidater som bruker minutter på å lure på hva som skal stå der, og noen som skriver inn en gjetning på egen midtveisscore. Det siste er ikke farlig, men det er bortkastet tid — og tid er det du har minst av på et firetimerssett.

Rett deg selv

OppgaveSjangerRiktigPoeng
1Aa2
2Ab3
3Aa3
4Brad 1→3, 2→4, 3→1, 4→22
5Crad 1→3, 2→1, 3→4, 4→5, 5→2, 6→33
6Eb3
7Frekke + testfunksjon6
8Atre linjer med riktige kolonner4
9Gklasse med tre spesialmetoder10
10Hdifferenslikning + plott9
11JODE-system + plott10
12Lnøstet dictionary8
13Lfiltrering + skriving6
14Ftestfunksjoner + bruk6
Sum75

Slik gir du deg selv poeng på kodeoppgavene. Gå gjennom «Dette gir uttelling»-listen i hver fasit og kryss av det du faktisk skrev. Regelen er mildere enn du tror: riktig struktur teller mest, og en indeksfeil i en ellers riktig løkke koster ett poeng, ikke hele oppgaven. Er du i tvil om noe er «riktig nok», er svaret nesten alltid ja — de offisielle løsningsforslagene i dette faget presenterer sin egen kode som bare ett eksempel på en besvarelse som ville fått full score, ikke som den eneste.
Selvdiagnose — kryss av:
- ☐ Satte du startverdiene før løkka i differenslikningen, og oppdaterte du S før I? (kap. 6.2)
- ☐ Ga range(N) deg N oppdateringer og N + 1 punkter i både oppgave 10 og 11? (kap. 7.1)
- ☐ Returnerte __mul__ en ny instans av klassen, ikke et tall eller en tuppel? (kap. 5.2)
- ☐ Sto self både i metodesignaturene og foran attributtene? (kap. 5.1)
- ☐ Skrev du f(t, u) med tiden først, og solve((0, T), N)? (kap. 7.3)
- ☐ Pakket du ut systemkomponentene med u[:, k] og ikke u[k]? (kap. 7.3)
- ☐ Opprettet du den indre dictionaryen før du satte noe inn i den? (kap. 8.1)
- ☐ Bygde filtrer en ny dictionary uten å endre argumentet? (kap. 8.2)
- ☐ Brukte testfunksjonene abs(expected - computed) < tol og ikke ==? (kap. 3.1)
- ☐ Hadde hvert plot-kall label=, og fulgte legend() etter? (kap. 4.3)
- ☐ Lot du oppgave 15 stå tom?
Om karakteren. Ikke regn poengsummen om til en bokstav. Karakteren settes samlet av begge eksamenene, og C er en god og vanlig karakter i IN1900. Målet med dette settet er ikke å bevise noe, men å finne ut hvilke to eller tre mønstre du fortsatt må skrive ut i sin helhet noen ganger til.
Sensorblikket — hva som gir uttelling når koden ikke er perfekt
Sjangerkartet for dette settet

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.