Tilbake
3.2

3.2 Rekker og summer: Taylor- og potensrekker

Implementere en endelig sum som tilnærmer en funksjon — det kanoniske `s = 0; løkke; return s`-mønsteret, inkludert rekurrente rekker med løkke.

55 min
7 oppgaver
RekkersummerTaylor-potensrekker
Din fremgang i kapitlet
0 / 7 oppgaver

Forkunnskaper

Fire ting fra tidligere i boka:

- Løkker og range fra kap. 1.3, særlig at stoppverdien i range er eksklusiv. Det er den enkeltdetaljen som avgjør flest poeng i dette kapitlet.
- Funksjoner fra kap. 1.6: def, argumenter og return.
- Potenser og heltallsdivisjon fra kap. 1.1. Du trenger å vite at / alltid gir flyttall, og at ** er potens.
- Testfunksjoner fra kap. 3.1 — hver oppgave i dette kapitlet ender med en test.

Matematikken bak er ikke pensum her; du skal implementere formelen, ikke utlede den. Vil du likevel vite hvorfor en endelig sum kan tilnærme en funksjon, står utledningen i Taylorpolynomer med restledd og Uendelige rekker og konvergenstester.

Kapitlet er delt i fire løkker med tidsanslag og tar knapt en time.

Løkke 1 — fra summetegn til løkke (~12 min)

En kalkulator har ingen «eksponentialknapp» inni seg. Den regner ut exe^x ved å legge sammen ledd fra en uendelig rekke og stoppe når leddene blir små nok. Formelen er

ex=k=0xkk!e^x = \sum_{k=0}^{\infty} \frac{x^k}{k!}

Vi kan selvsagt ikke legge sammen uendelig mange ledd. Det vi kan, er å stoppe etter ledd nummer NN:

exk=0Nxkk!e^x \approx \sum_{k=0}^{N} \frac{x^k}{k!}

Les summetegnet som en oppskrift på en løkke. Under tegnet står k = 0: det er der løkka begynner. Over står NN: det er der den slutter, og NN skal være med. Til høyre står leddet: det er uttrykket som legges til hver runde.

Det er hele oversettelsen. Alt annet i dette kapitlet er varianter av den samme fire linjene.

📜Rekke-summeringsmønsteret

Bokas faste mal for sjanger F. Fire steg, alltid i denne rekkefølgen:

1. Nullstill akkumulatoren før løkka: s = 0.
2. Løkke over leddnumrene, med range(N+1) når summen går til og med NN.
3. Legg til leddet: s += <uttrykk med k>.
4. Returnér summen etter løkka: return s.

from math import factorial

def exp_rekke(x, N):
    s = 0
    for k in range(N+1):
        s += x**k / factorial(k)
    return s

print(exp_rekke(1.0, 5))

Utskrift:

2.7166666666666663

Tre detaljer som er poenggivende hver gang:

- range(N+1), ikke range(N). Summen går til og med NN, og stoppverdien i range er eksklusiv. Med range(N) mister du det siste leddet.
- return s står utenfor løkka. Havner return inne i løkka, avbrytes funksjonen etter første runde og du får bare det første leddet.
- Løkkevariabelen heter det samme som i formelen. Står det kk under summetegnet, skriv k i koden. Sensor leser koden mot formelen, og like navn gjør sammenligningen umiddelbar.

Akkumulatoren `s = 0` … `s += ledd`

En akkumulator er en variabel som samler opp et resultat gjennom en løkke. Den settes til null før løkka og økes med ett ledd per runde.

s += ledd betyr nøyaktig det samme som s = s + ledd: hent den gamle verdien, legg til, og lagre tilbake i samme variabel. Skrivemåten kalles en augmentert tilordning.

Startverdien må stå før løkka. Står s = 0 inne i løkka, nullstilles summen hver runde, og funksjonen returnerer bare siste ledd.

s = 0
for k in range(1, 5):
    s += k*(k+1)
print(s)

Utskrift:

40

`range(N+1)` i en rekkesum

Går summen fra k=0k = 0 til og med k=Nk = N, har den N+1N+1 ledd, og løkka skrives for k in range(N+1):. Stoppverdien i range er eksklusiv, så range(N+1) gir verdiene 0,1,,N0, 1, \ldots, N.

Begynner summen på k=1k = 1 i stedet, skrives løkka for k in range(1, N+1): — første argument er startverdien, som er inklusiv.

N = 3
print(list(range(N+1)), list(range(1, N+1)))

Utskrift:

[0, 1, 2, 3] [1, 2, 3]

Regelen i én setning: les grensene rett av summetegnet, og legg alltid én til den øvre.

`factorial(k)` fra `math`

Fakultet: produktet av alle heltall fra 1 til og med kk, og 0!=10! = 1 per definisjon. Funksjonen hentes med from math import factorial — modulen står først i importsetningen.

Den tar et ikke-negativt heltall og returnerer et heltall. Sender du et flyttall inn, får du ValueError.

from math import factorial
for k in range(5):
    print(k, factorial(k))

Utskrift:

0 1
1 1
2 2
3 6
4 24

Du skal ikke implementere fakultet selv. Det er bortkastet tid på eksamen, og de offisielle løsningsforslagene bruker factorial direkte.

✏️Eksempel 1: eksponentialrekka, ledd for ledd

Hvor mange ledd trengs før rekka for e0,5e^{0{,}5} treffer verdien fra math.exp på ti desimaler? Vis summen for N=1,3,6N = 1, 3, 6 og 1515.


Vi bruker malen uendret og kaller funksjonen med fire ulike verdier av NN.

from math import factorial, exp

def exp_rekke(x, N):
    s = 0
    for k in range(N+1):
        s += x**k / factorial(k)
    return s

for N in [1, 3, 6, 15]:
    print(N, exp_rekke(0.5, N))
print('math.exp(0.5) =', exp(0.5))

Utskrift:

1 1.5
3 1.6458333333333333
6 1.6487196180555554
15 1.6487212707001278
math.exp(0.5) = 1.6487212707001282

Med ett ledd (N=1N = 1) er svaret bare 1+0,51 + 0{,}5. Med seks ledd stemmer fem desimaler, og med seksten ledd stemmer alle sifrene bortsett fra det siste — avviket er om lag 410164\cdot 10^{-16}, altså ren avrundingsstøy.

Det er nettopp derfor testfunksjonen fra kap. 3.1 bruker abs(expected - computed) < tol og aldri ==.

Legg merke til hvor raskt fakultetet i nevneren vokser. Ledd nummer 15 er 0,515/15!0{,}5^{15}/15!, altså rundt 210172\cdot 10^{-17}. Det er grunnen til at få ledd holder når xx er liten — og et varsel om at mange flere ledd trengs når xx er stor.

📝Oppgave 1

(Innstegsoppgave, sjanger A — kodesporing, altså «hva skriver programmet ut?».) Hva skriver programmet ut?

s = 0
for k in range(4):
    s += 2*k
    print(s, end=' ')

📝Oppgave 2

(Midtveisnivå, sjanger A — kodesporing av en rekkesum.) Hva skriver programmet ut? Pass på formateringen: {ledd:6.3f} betyr totalbredde 6 med 3 desimaler.

from math import factorial
s = 0
for k in range(3):
    ledd = 2**k / factorial(k)
    s += ledd
    print(f'{k} {ledd:6.3f} {s:6.3f}')

📝Oppgave 3
Eksamensnivå, sjanger F
Rekka for exe^x er

ex=k=0xkk!e^x = \sum_{k=0}^{\infty} \frac{x^k}{k!}

a) Skriv exp_rekke(x, N) som summerer leddene fra k=0k = 0 til og med k=Nk = N.

b) Skriv en testfunksjon som sammenligner med math.exp for x=0,5x = 0{,}5 med N=15N = 15.

c) Hva skjer med testen hvis du bytter range(N+1) til range(N)?

Løkke 2 — ledd som skifter fortegn (~12 min)

— naturlig pausepunkt —

Mange av de nyttigste rekkene har ledd som veksler mellom pluss og minus. Den naturlige logaritmen er et eksempel:

ln(1+x)=k=1(1)k+1xkk=xx22+x33\ln(1+x) = \sum_{k=1}^{\infty} (-1)^{k+1}\frac{x^k}{k} = x - \frac{x^2}{2} + \frac{x^3}{3} - \cdots

I koden løses dette med én faktor. Du trenger ingen if-setning og ingen hjelpevariabel som skifter fortegn — bare et fortegnsledd som er en potens av 1-1.

Legg samtidig merke til at denne summen starter på k=1k = 1, ikke på k=0k = 0. Det er en av de tre tingene du leser rett av summetegnet: startverdi, sluttverdi og leddets uttrykk.

`(-1)**k` — det alternerende fortegnet

Uttrykket (-1)**k er 1 når kk er et partall og 1-1 når kk er et oddetall. Det er standardmåten å få et ledd til å skifte fortegn på.

Parentesen rundt 1-1 er nødvendig: -1**k betyr -(1**k), som alltid er 1-1, fordi ** binder sterkere enn det unære minustegnet.

Skal det første leddet være positivt når summen starter på k=1k = 1, bruker du (-1)**(k+1).

for k in range(4):
    print(k, (-1)**k, end='  ')
print()

Utskrift:

0 1  1 -1  2 1  3 -1  

✏️Eksempel 2: logaritmerekka, med start på k = 1

Skriv ln1p_rekke(x, N) som tilnærmer ln(1+x)\ln(1+x) med leddene fra k=1k = 1 til og med k=Nk = N, og sammenlign med math.log for x=0,5x = 0{,}5.


To ting skiller denne fra eksponentialrekka: løkka starter på 1, og fortegnet veksler. Begge deler leses rett av formelen.

from math import log

def ln1p_rekke(x, N):
    s = 0
    for k in range(1, N+1):
        s += (-1)**(k+1) * x**k / k
    return s

print(ln1p_rekke(0.5, 5))
print(ln1p_rekke(0.5, 30))
print(log(1.5))

Utskrift:

0.40729166666666666
0.4054651080980436
0.4054651081081644

Med fem ledd stemmer to desimaler. Med tretti ledd stemmer ni. Sammenlign med eksponentialrekka, der seks ledd ga fem riktige desimaler: denne rekka konvergerer langt saktere, fordi nevneren bare er kk og ikke k!k!.

Konsekvensen for en testfunksjon er praktisk. Toleransen må velges etter metoden, ikke etter ønske: med N=30N = 30 er avviket rundt 101110^{-11}, så tol = 1e-10 går akkurat. Med N=5N = 5 måtte du hatt tol = 1e-2.

Margnotat om uttelling: de to detaljene sensor ser etter her er range(1, N+1) — altså at løkka starter der summetegnet sier — og at fortegnet er (-1)**(k+1) slik at det første leddet blir positivt. Bommer du på eksponenten i fortegnet, får du hele summen med motsatt fortegn; det er ett poeng, ikke oppgaven.

📝Oppgave 4
Eksamensnivå, sjanger F
Cosinus kan skrives

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

a) Skriv cos_rekke(x, N) som summerer leddene til og med k=Nk = N.

b) Skriv en testfunksjon mot math.cos for x=1,2x = 1{,}2 med N=10N = 10 og toleranse 1e-10.

c) Hvorfor kan du ikke bruke tol = 1e-10 med N=2N = 2?

Løkke 3 — rekker med bare oddetallsledd (~15 min)

Sinus hyperbolicus beskriver blant annet formen på en hengende kjede, og har rekka

sinhx=n=0x2n+1(2n+1)!=x+x33!+x55!+\sinh x = \sum_{n=0}^{\infty} \frac{x^{2n+1}}{(2n+1)!} = x + \frac{x^3}{3!} + \frac{x^5}{5!} + \cdots

Her er hvert eneste ledd en oddetallspotens. Fristelsen er å løkke over alle heltall og hoppe over partallene med en if. Ikke gjør det. Løkk over leddnummeret, og la uttrykket lage oddetallet.

Det er nettopp det 2n+12n+1 gjør: med n=0,1,2,3n = 0, 1, 2, 3 blir 2n+12n+1 lik 1,3,5,71, 3, 5, 7. Løkkevariabelen teller ledd; uttrykket regner ut hvilken potens leddet har.

Oddetallsindeksering `2*n+1`

Når rekka bare har oddetallspotenser, løkker du over leddnummeret n og bruker 2*n+1 der eksponenten og fakultetet skal stå. Løkkevariabelen er da antall ledd du har tatt med, ikke potensen.

Med n = 0, 1, 2, 3 gir 2*n+1 verdiene 1, 3, 5 og 7. Skal du ha partallspotenser i stedet, er uttrykket 2*n.

for n in range(4):
    print(n, 2*n+1)

Utskrift:

0 1
1 3
2 5
3 7

Regelen som sparer deg for feil: det samme uttrykket skal stå både i eksponenten og i fakultetet. Står det x**(2*n+1) i telleren, skal nevneren være factorial(2*n+1) — ikke factorial(n).

✏️Eksempel 3: sinus hyperbolicus med fire ledd

Skriv sinh_rekke(x, N) som summerer de N+1N+1 første oddetallsleddene, og sjekk mot math.sinh for x=0,8x = 0{,}8.


Malen er uendret. Det eneste nye er at 2*n+1 erstatter k to steder.

from math import factorial, sinh

def sinh_rekke(x, N):
    s = 0
    for n in range(N+1):
        s += x**(2*n+1) / factorial(2*n+1)
    return s

print(sinh_rekke(0.8, 3))
print(sinh_rekke(0.8, 8))
print(sinh(0.8))

Utskrift:

0.8881056101587302
0.8881059821876232
0.888105982187623

Fire ledd (N=3N = 3) gir seks riktige desimaler, og ni ledd treffer alle sifrene bortsett fra det siste. Rekka konvergerer nesten like raskt som eksponentialrekka, og av samme grunn: fakultetet i nevneren.

En liten kontroll du kan gjøre i hodet på eksamen: det første leddet er xx selv, siden 20+1=12\cdot 0 + 1 = 1 og 1!=11! = 1. Gir funksjonen din noe annet enn 0,8 når du kaller den med N=0N = 0, er indekseringen gal.

Margnotat om uttelling: her er det to poenggivende ting og én felle. Poengene ligger i range(N+1) og i at 2*n+1 står begge steder. Fellen er å skrive factorial(n) i nevneren; da får du en helt annen funksjon, og testen mot math.sinh avslører det med en gang.

📝Oppgave 5
Eksamensnivå, sjanger F
Invers tangens hyperbolicus har rekka

artanhx=n=0x2n+12n+1,x<1\operatorname{artanh} x = \sum_{n=0}^{\infty} \frac{x^{2n+1}}{2n+1}, \qquad |x| < 1

Legg merke til at nevneren er 2n+12n+1 — ikke (2n+1)!(2n+1)!.

a) Skriv atanh_rekke(x, N).

b) Skriv en testfunksjon mot math.atanh for x=0,5x = 0{,}5. Velg NN og toleranse som passer sammen, og begrunn valget i en kommentar.

c) Kontroller i hodet hva funksjonen gir for N=0N = 0, og forklar hvorfor.

Løkke 4 — rekurrente rekker, løst med løkke (~16 min)

Noen rekker er ikke gitt ved en formel for leddet, men ved en rekurrens: hvert ledd defineres ut fra de forrige. Chebyshev-polynomene er det klassiske eksempelet:

T0(x)=1,T1(x)=x,Tn+1(x)=2xTn(x)Tn1(x)T_0(x) = 1, \qquad T_1(x) = x, \qquad T_{n+1}(x) = 2xT_n(x) - T_{n-1}(x)

De brukes i numerisk analyse fordi de fordeler tilnærmingsfeilen jevnt over et intervall. For oss er de interessante av en helt annen grunn: de er den ene rekketypen der studenter systematisk velger feil verktøy.

Løsningen er en løkke som husker de to siste verdiene. Du trenger to variabler, og du oppdaterer dem i takt.

📜Rekurrent rekke med løkke — hold på de to siste

Malen for en rekurrens som trenger de to foregående verdiene:

1. Ta unna basistilfellene med en if øverst: den minste verdien returneres direkte.
2. Sett de to lagrene til de kjente startverdiene: T_forrige og T_denne.
3. Løkke fra 1 til nn — én runde per steg du må ta deg fram.
4. Regn den nye verdien først, i en egen variabel, og flytt deretter lagrene ett hakk.
5. Returnér den siste verdien.

def chebyshev(n, x):
    if n == 0:
        return 1.0
    T_forrige = 1.0
    T_denne = x
    for k in range(1, n):
        T_neste = 2*x*T_denne - T_forrige
        T_forrige = T_denne
        T_denne = T_neste
    return T_denne

for n in range(6):
    print(n, chebyshev(n, 0.5))

Utskrift:

0 1.0
1 0.5
2 -0.5
3 -1.0
4 -0.5
5 0.5

Punkt 4 er hele oppgaven. Skriver du T_forrige = T_denne før du har regnet ut den nye verdien, er den gamle T_forrige allerede overskrevet, og formelen bruker feil tall. Hjelpevariabelen T_neste finnes utelukkende for å hindre det.

Merk også at løkka går til range(1, n), ikke range(1, n+1): når T1T_1 allerede er satt, trengs bare n1n-1 steg for å komme fram til TnT_n. Sjekk det med n=2n = 2: løkka går én runde og regner ut T2T_2.

✏️Eksempel 4: Chebyshev-polynomet med testfunksjon

Test chebyshev(n, x) mot den kjente formelen T3(x)=4x33xT_3(x) = 4x^3 - 3x for x=0,3x = 0{,}3.


Fasiten kommer her ikke fra math, men fra en formel du kan skrive opp uavhengig av koden. Det er en helt gyldig — og ofte bedre — kilde til expected.

def chebyshev(n, x):
    if n == 0:
        return 1.0
    T_forrige = 1.0
    T_denne = x
    for k in range(1, n):
        T_neste = 2*x*T_denne - T_forrige
        T_forrige = T_denne
        T_denne = T_neste
    return T_denne

def test_chebyshev():
    x = 0.3
    expected = 4*x**3 - 3*x
    computed = chebyshev(3, x)
    tol = 1e-10
    msg = f'ventet {expected}, fikk {computed}'
    assert abs(expected - computed) < tol, msg

test_chebyshev()
print('Testen gikk gjennom')
print(chebyshev(3, 0.3))

Utskrift:

Testen gikk gjennom
-0.792

Regn gjerne etter for hånd: T2=20,30,31=0,82T_2 = 2\cdot 0{,}3\cdot 0{,}3 - 1 = -0{,}82, og T3=20,3(0,82)0,3=0,792T_3 = 2\cdot 0{,}3\cdot(-0{,}82) - 0{,}3 = -0{,}792. Formelen 4x33x4x^3 - 3x gir 40,0270,9=0,7924\cdot 0{,}027 - 0{,}9 = -0{,}792. De to veiene møtes.

Margnotat om uttelling. Sensor krysser av for fire ting: at basistilfellet n=0n = 0 er behandlet, at begge startverdiene er satt, at oppdateringen bruker en hjelpevariabel slik at ingen verdi går tapt, og at løsningen bruker løkke. Bommer du på løkkegrensen — range(1, n+1) i stedet for range(1, n) — får du Tn+1T_{n+1} i stedet for TnT_n. Det er ett poeng, og strukturen står.

📝Oppgave 6
Eksamensnivå, sjanger F

Fibonacci-tallene er definert ved F0=0F_0 = 0, F1=1F_1 = 1 og Fn+1=Fn+Fn1F_{n+1} = F_n + F_{n-1}, og dukker opp i modeller for bestandsvekst.

a) Skriv fib(n) med en løkke, etter malen for rekurrente rekker.

b) Skriv en testfunksjon som sjekker tre verdier du kan slå opp i hodet.

c) Forklar i én setning hvorfor T_neste-triksen fra malen ikke er strengt nødvendig her, men hvorfor du likevel bør skrive det slik.

📝Oppgave 7
Eksamensnivå, sjanger O

Programmet skal summere rekka k=0Nxk/k!\sum_{k=0}^{N} x^k/k! og teste den. Det har tre feil.

import factorial from math

def exp_rekke(x, N):
    for k in range(N):
        s = 0
        s += x**k / factorial(k)
    return s

def test_exp_rekke(x, N):
    assert exp_rekke(x, N) == 2.718281828

a) Nevn de tre feilene og si hva hver av dem fører til.

b) Skriv den rettede koden.

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.

Rekke

En sum av ledd som følger et mønster. I dette emnet er rekkene alltid endelige: du summerer fra ledd 0 (eller 1) til og med ledd NN, og bruker summen som en tilnærming til en funksjonsverdi. Jo flere ledd, jo bedre tilnærming — hvor mange som trengs, avhenger av hvor raskt leddene minker.

Sjanger F

Bokas kode for oppgaven «skriv en funksjon som summerer en rekke, og skriv en testfunksjon til den». Sjangeren står i hvert eneste av de åtte nyere avsluttende settene og er verdt 4–6 poeng. Innpakningen roterer mellom eksponential, logaritme, cosinus, sinus hyperbolicus, invers tangens hyperbolicus, arcus sinus og Chebyshev — øvelsen er identisk.

Å lese et summetegn som en løkke

Tre ting leses rett av tegnet: startverdien under tegnet blir første argument i range, sluttverdien over tegnet blir stoppverdien pluss én, og uttrykket til høyre blir det du legger til hver runde. Alt annet er den samme malen hver gang.

Akkumulator

Variabelen som samler opp summen. Den settes til 0 før løkka og økes med += inne i løkka. Nullstilles den inne i løkka, mister du hele summen og sitter igjen med siste ledd.

Trunkering av en rekke

Å stoppe en uendelig sum etter ledd NN. Feilen du gjør, kalles trunkeringsfeilen, og den er omtrent lik det første leddet du utelot. Det er derfor toleransen i testfunksjonen må velges etter hvor mange ledd du tar med.

Konvergenshastighet

Hvor raskt leddene minker. Rekker med fakultet i nevneren — eksponential, cosinus, sinus hyperbolicus — treffer mange desimaler med få ledd. Rekker med bare kk eller 2n+12n+1 i nevneren — logaritme, invers tangens hyperbolicus — trenger titalls ledd for samme nøyaktighet.

Alternerende rekke

En rekke der leddene skifter fortegn. Løses med faktoren (-1)**k, aldri med en if-setning. Parentesen rundt minus én er nødvendig, fordi ** binder sterkere enn det unære minustegnet.

Oddetallsrekke

En rekke der bare oddetallspotensene er med, som sinus hyperbolicus og invers tangens hyperbolicus. Du løkker over leddnummeret og lar 2*n+1 lage potensen. Samme uttrykk skal stå i eksponenten og i nevneren.

Partallsrekke

Samme idé med 2*k i stedet: cosinusrekka har leddene x2k/(2k)!x^{2k}/(2k)!. Kontrollen er den samme — det samme uttrykket begge steder.

Rekurrens

En definisjon der hvert ledd bygger på de foregående, som Tn+1=2xTnTn1T_{n+1} = 2xT_n - T_{n-1}. Løses alltid med løkke og to lagervariabler i dette emnet.

Lagervariablene i en rekurrens

To variabler som holder de to siste verdiene, pluss en hjelpevariabel for den nye. Rekkefølgen er: regn ut den nye verdien først, flytt deretter lagrene ett hakk. Flytter du først, er verdien du trengte allerede overskrevet.

Basistilfelle

Den minste verdien i en rekurrens, som returneres direkte med en if øverst i funksjonen. Chebyshev trenger ett (n=0n = 0), Fibonacci trenger at både F0F_0 og F1F_1 er dekket av startverdiene.

Hvorfor løkke og ikke selvkall

En funksjon som kaller seg selv er utenfor pensum i IN1900 og markeres uønsket i de offisielle løsningsforslagene (#9). I tillegg blir den svært treg for rekurrenser med to ledd, fordi antall kall dobles for hvert nivå.

Ledd-uttrykket

Uttrykket til høyre for summetegnet, oversatt direkte til Python. Teller og nevner skrives som de står: x**k / factorial(k), (-1)**k * x**(2*k) / factorial(2*k). Ingen forenkling er nødvendig, og forenkling er en vanlig kilde til feil.

Valg av toleranse i en rekketest

Toleransen skal ligge like over avviket rekka faktisk har med det antall ledd du valgte. Med fakultet i nevneren og 15 ledd er 1e-10 trygt; med en langsom rekke og 5 ledd må du opp i 1e-2. Skriv én kommentarlinje om valget.

Fasit fra en kjent formel
expected trenger ikke komme fra math. En eksakt formel du kan skrive opp uavhengig — som T3(x)=4x33xT_3(x) = 4x^3 - 3x — er en like god, og ofte bedre, kilde: den er tydelig uavhengig av koden du tester.
Heltallsrekker og `==`

Regelen om toleranse gjelder flyttall. Er alle verdiene heltall, som i Fibonacci, er assert expected == computed helt riktig, og en toleranse ville vært unødvendig pynt.

Kontrollen «hva gir N = 0?»

En gratis fornuftssjekk på eksamen: første ledd i eksponentialrekka er 1, i oddetallsrekkene er det xx selv, og i logaritmerekka er det xx. Stemmer ikke det, er indekseringen gal — og du har oppdaget det uten å kunne kjøre koden.

Repetisjon: malen 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.