Tilbake
5.5

5.5 DRILL — Klasser med spesialmetoder

Full drill på G-sjangeren: fra oppgavetekst til komplett klasse med de spesialmetodene oppgaven krever, i sensors korte stil.

90 min
12 oppgaver
DRILLKlasser med spesialmetoder
Din fremgang i kapitlet
0 / 12 oppgaver

Forkunnskaper — sist du var her

Drillen forutsetter hele Del 5: kap. 5.1 (konstruktør og kallbar instans), kap. 5.2 (utskrift og aritmetikk), kap. 5.3 (arv) og kap. 5.4 (stykkvise funksjoner). Fra resten av boka trenger du funksjoner og standardverdier (kap. 1.6), f-strenger (kap. 1.4), løkker (kap. 1.3), testfunksjoner (kap. 3.1) og tabeller og plotting (kap. 4.1 og kap. 4.3).

Her er de to konstruksjonene du kommer til å skrive flest ganger i dette kapitlet, friskt oppfrisket.

1. Funksjonsklassen. Konstruktøren tar det som er fast, kallmetoden tar det som varierer:

from math import exp

class Gauss:
    def __init__(self, m, s):
        self.m = m
        self.s = s

    def __call__(self, x):
        m, s = self.m, self.s
        return exp(-(x - m)**2/(2*s**2))

g = Gauss(0, 1)
print(g(0), g(1))

Utskrift:

1.0 0.6065306597126334

2. Aritmetikk som gir en ny instans. Plusstegnet mellom to objekter er et metodekall, og metoden skal levere et nytt objekt av samme klasse:

class Vind:
    def __init__(self, ost, nord):
        self.ost = ost
        self.nord = nord

    def __str__(self):
        return f'({self.ost}, {self.nord})'

    def __add__(self, other):
        return Vind(self.ost + other.ost, self.nord + other.nord)

a = Vind(3, 4)
b = Vind(-1, 2)
print(a + b)
print(a)

Utskrift:

(2, 6)
(3, 4)

Legg merke til den siste linja: a er uendret. Aritmetikk lager et tredje objekt og lar operandene være i fred, akkurat som 3 + 4 ikke endrer tretallet.

📜Løsningsoppskriften for sjanger G — sju steg

Les oppgaveteksten én gang med blyanten i hånda, og strek under hvert krav. Gjør så dette, i rekkefølge. Hvert steg svarer til ett spørsmål du besvarer ved å se på oppgaveteksten, ikke ved å tenke selv.

1. class Navn: — hva heter klassen? Navnet står nesten alltid ordrett i oppgaveteksten, og du skal bruke akkurat det navnet. Stor forbokstav.
2. __init__ lagrer alt som er fast. Hvilke størrelser er gitt én gang, når objektet lages? De blir parametre i konstruktøren og lagres som attributter: self.a = a. Har oppgaven en standardverdi («med h=105h = 10^{-5} hvis ikke annet er oppgitt»), skriver du den i signaturen: def __init__(self, f, h=1e-5):.
3. __call__ regner ut funksjonsverdien. Hvilken størrelse varierer fra kall til kall? Den blir parameter i kallmetoden. Skal objektet kunne brukes som en vanlig funksjon — «slik at f(2) gir funksjonsverdien» — er det __call__ oppgaven ber om.
4. __str__ hvis oppgaven vil se objektet. Formuleringer som «slik at print(p) skriver …» eller «en pen utskrift av polynomet» betyr __str__, og den skal returnere en f-streng.
5. __add__ og __mul__ hvis oppgaven bruker + eller * mellom objekter. De returnerer en ny instans av klassen. Eneste unntak: multiplikasjon som er definert som et indreprodukt returnerer et tall, og da skiller du de to tilfellene med isinstance.
6. Arv når to klasser deler kode. Sier oppgaven at den nye klassen er «et spesialtilfelle av» eller «som forrige, men med …», skriver du class Sub(Base): og lar super().__init__(...) være første linje i den nye konstruktøren.
7. Del b): instansier og bruk. Lag objektet med de tallene oppgaven oppgir, og gjør det oppgaven ber om — skriv ut noen verdier, lag en testfunksjon med assert abs(fasit - beregnet) < tol, eller lag et punktgitter og plott. Denne delen kan løses selv om du ikke fikk til del a).

Formen på svaret. Hele besvarelsen skal være kort: fem–tjue linjer, ingen kommentarer utenom der du dokumenterer en antakelse, ingen ekstra utskrift og intet hovedprogram. Sensor leter etter strukturen, ikke etter volum.

Det gjennomarbeidede caset (~20 min)

Under står en komplett, tredelt oppgave i sjanger G, av samme type og vekt som på en avsluttende eksamen. Les oppgaveteksten, prøv deg på del a) før du ser videre, og les så modellbesvarelsene med margnotatene om hva som gir uttelling.

> Oppgave (10 poeng). En dempet svingning — for eksempel utslaget til en fjærbelastet masse i en væske — beskrives av
>
> s(t)=Aebtcos(ωt)s(t) = A e^{-bt}\cos(\omega t)
>
> der AA er startutslaget, b0b \ge 0 er dempingen og ω\omega er vinkelfrekvensen.
>
> a) Skriv en klasse Dempesvingning der AA, bb og ω\omega gis når objektet lages, der s(t) gir utslaget ved tiden tt, og der print(s) skriver formelen med tallene satt inn. (5 poeng)
>
> b) Lag en instans med A=2,0A = 2{,}0, b=0,5b = 0{,}5 og ω=3,0\omega = 3{,}0. Skriv en testfunksjon som kontrollerer verdien i t=0t = 0, og skriv ut en tabell over utslaget for t=0, 0,5, , 2,0t = 0{,}\ 0{,}5{,}\ \ldots,\ 2{,}0. (3 poeng)
>
> c) En udempet svingning er tilfellet b=0b = 0. Skriv en klasse Udempet som arver fra Dempesvingning og bare tar AA og ω\omega. (2 poeng)

✏️Modellbesvarelse del (a): klassen

Skriv Dempesvingning med konstruktør, kallmetode og utskriftsmetode.

Gå gjennom oppskriften: klassenavnet står i teksten (steg 1); AA, bb og ω\omega er gitt når objektet lages, altså faste (steg 2); tt varierer fra kall til kall, altså __call__ (steg 3); «print(s) skriver formelen» betyr __str__ (steg 4). Ingen + eller * mellom objekter, så steg 5 og 6 er ikke aktuelle her.

from math import exp, cos

class Dempesvingning:
    def __init__(self, A, b, w):
        self.A = A
        self.b = b
        self.w = w

    def __call__(self, t):
        return self.A*exp(-self.b*t)*cos(self.w*t)

    def __str__(self):
        return f'{self.A}*exp(-{self.b}*t)*cos({self.w}*t)'

s = Dempesvingning(2.0, 0.5, 3.0)
print(s)
print(s(0))
print(s(1))

Utskrift:

2.0*exp(-0.5*t)*cos(3.0*t)
2.0
-1.2009216041472504

Hva gir uttelling, steg for steg (5 poeng):

- 1 poeng: class Dempesvingning: med __init__ som tar de tre parametrene. Selve rammeverket. Får du bare dette, har du ett poeng.
- 1 poeng: de tre self.-tilordningene. Skriver du A = A i stedet for self.A = A, mister du dette poenget og alt som bygger på det — det er feil #3.
- 2 poeng: __call__ med riktig formel. Selve kjernen. Bruker du ** riktig, har fortegnet i eksponenten på plass og ganger de to faktorene sammen, er poenget ditt. Bytter du cos med sin, mister du ett halvt — strukturen er riktig.
- 1 poeng: __str__ som returnerer en f-streng. Den eksakte formateringen er fri; sensor krever ikke at parentesene står nøyaktig som her, bare at det er en streng og at tallene er med.

Merk at det greske ω\omega i formelen heter w i koden. Det er helt vanlig og fullt akseptert: greske bokstaver skrives ut med latinske bokstaver i Python, og w for omega er standard i faget. Merk også at klassen kalles med s(1), mens print(s) skriver teksten — samme objekt, to helt forskjellige metoder.

✏️Modellbesvarelse del (b) og (c): bruk, test og arv

Instansier klassen, kontroller den med en testfunksjon, skriv verditabellen — og lag subklassen for den udempede svingningen.

Del b). Testfunksjonen trenger en verdi du kan regne i hodet. I t=0t = 0 er e0=1e^0 = 1 og cos0=1\cos 0 = 1, så s(0)=As(0) = A. Det er den ideelle kontrollen: den er eksakt, så toleransen kan være stram.

from math import exp, cos

class Dempesvingning:
    def __init__(self, A, b, w):
        self.A = A
        self.b = b
        self.w = w

    def __call__(self, t):
        return self.A*exp(-self.b*t)*cos(self.w*t)

def test_dempesvingning():
    s = Dempesvingning(2.0, 0.5, 3.0)
    expected = 2.0
    computed = s(0)
    tol = 1e-10
    assert abs(expected - computed) < tol, 'feil i t = 0'

test_dempesvingning()

s = Dempesvingning(2.0, 0.5, 3.0)
for i in range(5):
    t = 0.5*i
    print(f'{t:4.1f} {s(t):8.4f}')

Utskrift:

 0.0   2.0000
 0.5   0.1102
 1.0  -1.2009
 1.5  -0.1991
 2.0   0.7065

Hva gir uttelling (3 poeng): 1 poeng for instansieringen med riktige tall, 1 for testfunksjonen (uten argumenter, med abs(...) < tol og ikke ==), 1 for tabellen. At tabellen har fem linjer og ikke fire er av-én-regelen igjen: fra 0 til 2,0 med steg 0,5 er fire steg og fem punkter, altså range(5).

— naturlig pausepunkt —

Del c). Den udempede svingningen er nøyaktig samme formel med b=0b = 0. Det er den klassiske arvesituasjonen: subklassen har færre parametre, ikke flere, og fyller resten inn selv.

from math import exp, cos

class Dempesvingning:
    def __init__(self, A, b, w):
        self.A = A
        self.b = b
        self.w = w

    def __call__(self, t):
        return self.A*exp(-self.b*t)*cos(self.w*t)

    def __str__(self):
        return f'{self.A}*exp(-{self.b}*t)*cos({self.w}*t)'

class Udempet(Dempesvingning):
    def __init__(self, A, w):
        super().__init__(A, 0.0, w)

    def __str__(self):
        return f'{self.A}*cos({self.w}*t)'

u = Udempet(2.0, 3.0)
print(u)
print(u(0), u(1))
print(isinstance(u, Dempesvingning))

Utskrift:

2.0*cos(3.0*t)
2.0 -1.9799849932008908
True

Hva gir uttelling (2 poeng): 1 poeng for class Udempet(Dempesvingning): med riktig parameterliste, 1 for super().__init__(A, 0.0, w) med nullen på riktig plass. Den overstyrte __str__-en er en bonus og ikke krevd — uten den arves basisklassens versjon, som skriver 2.0*exp(-0.0*t)*cos(3.0*t). Det er ikke galt, bare mindre pent.

Margnotat om delvis uttelling. De to poengene i del c) er uavhengige av del a) og b). Skriver du subklassen riktig, får du poengene selv om __call__ i basisklassen var feil. Det er derfor du alltid skal skrive noe på hver deloppgave: å få alle detaljer 100 % riktig under tidspress er nesten umulig, og poengene er lagt opp etter det.

Oppgaver: samme mal, ny innpakning (~25 min for oppgave 1–6)

Alle oppgavene under er nyskrevne og på eksamensnivå. De roterer klassetypene systematisk: funksjonsklasse, klasse som pakker inn en annen funksjon, vektorklasse med aritmetikk, klasse med rekurrent formel, arvepar og stykkvis klasse — pluss sporingsoppgaver som tester at du vet hvilken metode som kjøres når. Skriv løsningene for hånd, uten å kjøre koden. Det er slik eksamen er.

📝Oppgave 1

(Innstegsoppgave, midtveisnivå, sjanger A — kodesporing, altså «hva skriver dette programmet ut?».) Skriv utskriften nøyaktig, med mellomrom og linjeskift slik terminalen viser den.

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

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

t = Teller(4)
print(t(1))
print(t(1))
print(t.n)

📝Oppgave 2
Eksamensnivå, sjanger G
Hastigheten til en enzymreaksjon beskrives av Michaelis–Menten-uttrykket

v(S)=vmaxSKm+Sv(S) = \frac{v_{\max} S}{K_m + S}

der SS er substratkonsentrasjonen, vmaxv_{\max} er den høyeste hastigheten og KmK_m er den konsentrasjonen som gir halv makshastighet.

a) Skriv en klasse Michaelis der vmaxv_{\max} og KmK_m gis når objektet lages, og der v(S) gir hastigheten.

b) Lag en instans med vmax=120,0v_{\max} = 120{,}0 og Km=2,5K_m = 2{,}5, og skriv ut hastigheten for S=0S = 0, S=2,5S = 2{,}5 og S=100S = 100.

c) Hva er den matematiske grunnen til at verdien i S=KmS = K_m er nøyaktig halvparten av vmaxv_{\max}?

📝Oppgave 3

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

class Prove:
    def __init__(self, navn, ph):
        self.navn = navn
        self.ph = ph

    def __str__(self):
        return f'{self.navn}: pH = {self.ph:.2f}'

p = Prove('Bekk 1', 6.7)
q = Prove('Bekk 2', 7.25)
print(p)
print(str(q) + '!')
print([p.navn, q.ph])

📝Oppgave 4
Eksamensnivå, sjanger G
Den forlengs deriverte av en funksjon ff er

f(x)f(x+h)f(x)hf'(x) \approx \frac{f(x+h) - f(x)}{h}

a) Skriv en klasse Forlengs som tar funksjonen f og steget h med standardverdi 10510^{-5} når objektet lages, og der kallet d(x) gir den forlengs deriverte.

b) Lag en instans for eksponentialfunksjonen, og skriv ut den deriverte i x=0x = 0 sammen med den eksakte verdien.

c) Lag en instans til med h=0,1h = 0{,}1, og forklar hva den ekstra utskriften viser.

📝Oppgave 5
Eksamensnivå, sjanger G

En vindmåling har en østkomponent og en nordkomponent, begge i meter per sekund.

a) Skriv en klasse Vind med __str__ på formen (3, 4) m/s, __add__ som legger sammen komponentvis, og __mul__ som gir indreproduktet når høyre operand er en Vind, og en skalert vind når den er et tall.

b) Legg til en vanlig metode fart som gir farten vø2+vn2\sqrt{v_\text{ø}^2 + v_\text{n}^2}.

c) Vis bruken: summen av to vindvektorer, indreproduktet, en dobling og farten til den første.

📝Oppgave 6

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

class Vind:
    def __init__(self, ost, nord):
        self.ost = ost
        self.nord = nord

    def __str__(self):
        return f'({self.ost}, {self.nord})'

    def __add__(self, other):
        print('legger sammen')
        return Vind(self.ost + other.ost, self.nord + other.nord)

a = Vind(1, 2)
b = Vind(3, 4)
c = a + b + a
print(c)
print(a)

Oppgave 7–12: arv, rekurrente formler og feilsøking (~30 min)

— naturlig pausepunkt —

De neste seks oppgavene er tyngre. To av dem er arv, én kombinerer klasse med en rekurrent formel, én er «finn feilen», og de to siste er en full flerdelt eksamensoppgave og et flervalg av typen «hvilken linje mangler». Ta dem gjerne som en egen økt.

📝Oppgave 7
Eksamensnivå, sjanger G
Chebyshev-polynomene er gitt ved T0(x)=1T_0(x) = 1, T1(x)=xT_1(x) = x og

Tn+1(x)=2xTn(x)Tn1(x)T_{n+1}(x) = 2xT_n(x) - T_{n-1}(x)

a) Skriv en klasse Cheb der graden nn gis når objektet lages, der kallet t(x) gir Tn(x)T_n(x) regnet ut med en løkke, og der print(t) skriver T_3(x) for grad 3.

b) Skriv en testfunksjon som kontrollerer klassen for n=3n = 3 mot det kjente uttrykket T3(x)=4x33xT_3(x) = 4x^3 - 3x i punktet x=0,5x = 0{,}5.

c) Skriv ut T0(0,5)T_0(0{,}5), T1(0,5)T_1(0{,}5) og T2(0,5)T_2(0{,}5), og kontroller den midterste i hodet.

📝Oppgave 8
Eksamensnivå, sjanger G

Hastigheten til en kjemisk reaksjon av orden nn er r(c)=kcnr(c) = kc^n, der cc er konsentrasjonen og kk er hastighetskonstanten.

a) Skriv en klasse Reaksjon der kk og nn gis når objektet lages, der r(c) gir hastigheten, og der print(r) skriver formelen med tallene satt inn.

b) En førsteordens reaksjon er tilfellet n=1n = 1. Skriv en subklasse ForsteOrden som bare tar kk.

c) Gi subklassen en metode halveringstid som returnerer ln2/k\ln 2 / k, og vis at et ForsteOrden-objekt fortsatt regnes som en Reaksjon.

📝Oppgave 9
Eksamensnivå, sjanger O

Programmet under skal representere en saltblanding: __str__ skal beskrive den, + skal blande to porsjoner, og kallet b(x) skal gi hvor mange gram salt det er i x gram av blandingen. Finn alle feilene, forklar hva hver av dem gjør, og skriv programmet riktig.

class Blanding:
    def __init__(self, salt, vann):
        self.salt = salt
        self.vann = vann

    def __str__(self):
        f'{self.salt} g salt i {self.vann} g vann'

    def __add__(self, other):
        return self.salt + other.salt, self.vann + other.vann

    def __call__(x):
        return salt/(salt + vann)*x

a = Blanding(5, 95)
b = Blanding(15, 85)
print(a + b)
print((a + b)(200))

📝Oppgave 10

(Midtveisnivå, sjanger A — kodesporing.) Klassen under er den generelle stykkvise funksjonen fra kap. 5.4. Hva skriver programmet ut?

class Tariff:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __call__(self, x):
        for i, b_ in enumerate(self.b):
            if x < b_:
                return self.a[i]
        return self.a[-1]

t = Tariff([0.5, 1.2, 2.0], [100, 400])
print(t(50), t(100), t(399), t(400), t(1000))

📝Oppgave 11
Eksamensnivå, sjanger G
Løseligheten til et salt i vann avhenger av temperaturen etter

S(T)=S0eΔH(1/T1/T0)S(T) = S_0 e^{-\Delta H (1/T - 1/T_0)}

der TT er temperaturen i kelvin, S0S_0 er løseligheten ved referansetemperaturen T0T_0, og ΔH\Delta H er en stoffavhengig konstant.

a) Skriv en klasse Loslighet der S0S_0 og ΔH\Delta H gis når objektet lages, der T0T_0 har standardverdien 298,0, der s(T) gir løseligheten, og der print(s) skriver formelen med tallene satt inn.

b) Skriv en testfunksjon som kontrollerer at objektet gir nøyaktig S0S_0 ved T=T0T = T_0.

c) Lag en instans med S0=36,0S_0 = 36{,}0 og ΔH=1500,0\Delta H = 1500{,}0, og skriv ut løseligheten ved 273,0 K, 298,0 K og 323,0 K med fire desimaler.

d) Skriv koden som plotter to salter i samme figur — ΔH=1500\Delta H = 1500 og ΔH=4000\Delta H = 4000, begge med S0=36,0S_0 = 36{,}0 — for 81 punkter fra 273 K til 353 K, med legende og navngitte akser. Beskriv figuren i ord.

📝Oppgave 12

(Midtveisnivå, sjanger E — «hvilken linje mangler?». Sjanger E er flervalgstypen der du skal peke ut den ene linja eller det ene kallet som gjør at programmet virker.) Klassen under skal gjøre at print(Fart(90)) skriver 90 km/t, men den skriver i stedet noe slikt som <__main__.Fart object at 0x104e3a1f0>. Velg ett svar.

class Fart:
    def __init__(self, v):
        self.v = v

    def tekst(self):
        return f'{self.v} km/t'

print(Fart(90))

a) print må byttes til print(Fart(90).tekst)
b) self.v = v må byttes til v = v
c) Metoden må hete __str__ i stedet for tekst
d) Klassen mangler en __call__-metode

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.

Sjanger G — klasse med spesialmetoder

Oppgaven «skriv en klasse med spesialmetoder». Den forekommer i 100 % av de åtte gjennomgåtte avsluttende settene og er verdt 8–12 poeng — de tyngste enkeltoppgavene på settet.

Innpakningen roterer år for år: vektor, polynom, funksjon med parametre, stykkvis funksjon. Koden gjør det ikke. Det er de samme fem–seks metodene hver gang, på under tjue linjer.

Steg 1 — hent klassenavnet fra oppgaveteksten

Klassenavnet står nesten alltid ordrett i oppgaven («skriv en klasse Michaelis …»), og du skal bruke akkurat det navnet, med stor forbokstav.

Sensor leser koden med oppgaveteksten ved siden av. Et annet navn tvinger fram ekstra lesing og gjør det vanskeligere å se at du har løst oppgaven.

Steg 2 — konstruktøren tar det som er fast

Alt som gis én gang, når objektet lages, hører i __init__ og lagres som attributt med self.navn = navn. Standardverdier står i signaturen: def __init__(self, f, h=1e-5):.

Testen: skal to kall på samme objekt kunne gi ulikt svar? Da hører størrelsen ikke her.

Steg 3 — kallmetoden tar det som varierer

Formuleringer som «slik at f(2) gir funksjonsverdien» eller «objektet skal kunne brukes som en vanlig funksjon» betyr __call__. Parameteren er den størrelsen som endrer seg fra kall til kall.

Uten __call__ gir obj(3) feilmeldingen «object is not callable».

Steg 4 — utskriftsmetoden returnerer en f-streng

«Slik at print(p) skriver …» betyr __str__. Metoden tar ingen argumenter utenom self og skal returnere en streng.

Glemmer du return, leverer metoden None, og Python svarer TypeError: __str__ returned non-string (type NoneType). Feilmeldingen peker på riktig metode.

Steg 5 — aritmetikk gir en ny instans

Brukes + eller * mellom to objekter, skal __add__ og __mul__ returnere et nytt objekt av klassen: return Klasse(...). Operandene skal være urørt etterpå.

Eneste unntak: multiplikasjon definert som indreprodukt gir et tall. De to tilfellene skilles med isinstance(other, Klasse).

Steg 6 — arv når oppgaven sier «spesialtilfelle av»

Formuleringer som «som forrige klasse, men med …» eller «et spesialtilfelle av» betyr class Sub(Base):. Subklassen har typisk færre parametre og fyller resten inn selv.

super().__init__(...) står som første linje i subklassens konstruktør, og du sender ikke med self i kallet.

Steg 7 — del b): instansier, test, plott

Siste del av oppgaven er alltid bruk: lag objektet med tallene som er oppgitt, skriv ut noen verdier, lag en testfunksjon, eller lag et punktgitter og plott.

Denne delen er uavhengig av del a) og gir poeng selv om klassen ikke ble helt riktig. Den er også den vanligste grunnen til at studenter taper poeng: de bruker all tiden på klassen.

Klassevalg-testen

Spørsmålet som avgjør om en oppgave skal løses med klasse eller med en vanlig funksjon: er det én ting med parametre som skal brukes mange ganger?

Er svaret ja — en funksjon med to–tre konstanter som skal evalueres i mange punkter — er klassen riktig. Er svaret nei, holder en vanlig funksjon. På eksamen sier oppgaveteksten det uansett, men testen hjelper deg å huske hva som hører hvor.

Testfunksjon for en klasse

Samme mal som for en vanlig funksjon, med instansieringen inne i testen:

def test_klasse():
    obj = Klasse(2.0, 0.5)
    expected = 2.0
    computed = obj(0)
    tol = 1e-10
    assert abs(expected - computed) < tol, 'melding'

Velg et punkt der svaret er eksakt — typisk der en eksponent blir null eller et ledd faller bort. Da tåler du en stram toleranse. Testfunksjonen tar ingen argumenter og skriver ikke ut noe.

Vanlig metode i tillegg til spesialmetodene

En klasse kan ha helt vanlige metoder ved siden av spesialmetodene: fart, halveringstid, areal. De defineres som def fart(self): og kalles med navn og parentes: a.fart().

Forskjellen fra et attributt er parentesen. a.ost er en lagret verdi; a.fart() regner ut noe.

Rekurrent formel inne i en kallmetode

En formel som definerer hvert ledd ut fra de foregående, som Tn+1=2xTnTn1T_{n+1} = 2xT_n - T_{n-1}, løses med løkke og to variabler som holder de to siste verdiene.

Rekkefølgen er kritisk: regn ut den nye verdien først, skyv så variablene ett hakk. Rekursjon — at metoden kaller seg selv — er utenfor pensum i dette faget og markeres uønsket i fasit.

Å skrive klassekode uten å kjøre den

Eksamen er hjelpemiddelfri, så klassen skrives i ett gjennomtrekk uten å testes. Vanen som gjør det mulig: skriv metodesignaturene først — __init__, __call__, __str__ — og fyll inn kroppene etterpå.

Da glemmer du aldri self, og du ser med én gang om du har lagt en størrelse i feil metode.

Delvis uttelling i sjanger G

Poengene i en klasseoppgave er fordelt på strukturen, ikke på plettfrihet. Klasseramma, self.-tilordningene, hver spesialmetode og bruken teller hver for seg.

Det betyr at en klasse med riktig oppsett og én fortegnsfeil i formelen får det aller meste av poengene, og at deloppgavene kan løses uavhengig. Skriv derfor noe på hver del.

Repetisjon: oppskriften på ett kort

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.