Innhold
Skrive funksjoner
Vi skal skrive en Python-funksjon, cels_til_fahr(), som regner om fra grader Celsius til grader Fahrenheit ved hjelp av formelen $f = {\large \frac{9c}{5}} + 32$, der f er grader Fahrenheit og c grader Celsius. Funksjonen kan bli slik:
def cels_til_fahr(celsius):
"""Konverterer fra grader Celsius til grader Fahrenheit."""
fahrenheit = 9 * celsius / 5 + 32
return fahrenheit
Vi skriver så
print(f"{cels_til_fahr(10):.02f}")
i hovedprogrammet. Når vi kjører koden, svarer Python 50.00.
Vi skal skrive en Python-funksjon som finner og returnerer det minste av to tall.
Vi bruker funksjonen i eksempel 4 som mal, endrer funksjonsnavnet fra storst til minst og snur ulikhetstegnet:
def minst(tall_1, tall_2):
"""Finner det minste av to tall."""
if tall_1 < tall_2:
return tall_1
else:
return tall_2
For å teste funksjonen kan det være lurt å prøve med en variant der tall_1 < tall_2, en variant der tall_1 > tall_2, og en variant der tall_1 == tall_2. Så i hovedprogrammet skriver vi
print(minst(1, 2)) print(minst(2, 1)) print(minst(1, 1))
Vi får skrevet ut 1 i alle tre tilfeller.
Funksjonsparametere
Vi skal skrive en Python-funksjon som simulerer terningkast, det vil si genererer tilfeldige tall mellom 1 og 6, og returnerer resultatet.
Funksjonen kan se som vist under. I hovedprogrammet før funksjonen importerer vi randint.
from random import randint
def terningkast():
"""Simulerer et terningkast."""
return randint(1, 6)
Hvis vi i hovedprogrammet skriver
print(terningkast())
vil vi få skrevet ut et vilkårlig tall mellom 1 og 6.
Vi har funksjonen normal(x, my = 0, sigma = 1) som beregner sannsynlighetstetthet i en normalfordeling.
Så skal vi skrive kode som bruker normal() til å beregne sannsynlighetstettheten til 3 i en normalfordeling der sigma er 5, men my beholder standardverdien 0.
Vi kan ikke hoppe over my og bare gi en verdi til sigma, for skriver vi normal(3, 5), er det my som blir satt til 5, men sigma beholder standardverdien 1. Vi navngir derfor parameteren sigma, og skriver
normal(3, sigma = 5)
Lokale og globale variabler
Vi har funksjonen kvadrer(), som vist under:
def kvadrer(y):
"""Kvadrerer y."""
z = y**2
return z
Så skal vi avgjøre hva som blir skrevet ut når vi i hovedprogrammet skriver
y = 5
z = 6
y = kvadrer(z)
print(f"y = {y}, z = {z}")
Her er det gjort et forsøk på å forvirre ved å bruke variablene y og z både i funksjonen og i hovedprogrammet. Men variablene i funksjonen er lokale, og vi trenger ikke ta hensyn til dem i det hele tatt. Alt vi trenger å vite er at kvadrer() returnerer den kvadrerte verdien av det vi gir inn som argument. Når z = 6, blir derfor y = kvadrer(6) = 62 = 36, og vi får skrevet ut y = 36, z = 6.
Funksjoner i Python Tutor
Vi har bildet under av kode i Python Tutor, der vi har klikket oss fram så langt at verdien til returvariabelen er beregnet, men funksjonen ikke har returnert. Så skal vi tegne en skisse av hvordan vi tror høyre side av bildet i Python Tutor ser ut.

Høyre side ser slik ut:

Vi ser at kvadrer er en variabel med en pil som peker til en funksjon. Vi ser også at vi har variablene y = 5 og z = 6 i hovedprogrammet, slik de er blitt opprettet i linje 6 og 7.
Videre ser vi at kvadrer() er en funksjon med lokale variabler y = 6 og z = 36. y er 6 fordi parameteren y fikk verdien 6 fra argumentet z i funksjonskallet. z er 36 fordi z er beregnet som y2 = 62 = 36. Returverdien er 36 fordi returverdien er verdien til z.
Lagre funksjoner i moduler
Vi skal først skrive funksjonen fakultet(), slik den er vist, inn i ei tom fil, og lagre fila med navnet kombinatorikk.
Vi åpner ei ny fil i Thonny ved å velge «Fil» – «Ny», og limer inn koden under:
def fakultet(n):
"""Beregner n!"""
fakt = 1
for m in range(2, n + 1):
fakt *= m
return fakt
Så velger vi «Fil» – «Lagre» eller «Fil» -«Lagre som», og oppgir kombinatorikk som navn. Thonny lagrer fila med navnet kombinatorikk.py, der py betyr at det dreier seg om ei fil med Python-kode.
Så skal vi åpne ei ny fil, importere fakultet() fra kombinatorikk, bruke fakultet() til å beregne fakultetet til 5, og skrive ut resultatet.
Vi åpner ei ny fil i Thonny, og skriver inn kode tilsvarende dette:
from kombinatorikk import fakultet print(fakultet(5))
Vi kan alternativt velge å importere hele modulen kombinatorikk. Da må vi referere til fakultet som kombinatorikk.fakultet:
import kombinatorikk print(kombinatorikk.fakultet(5))
Når vi kjører koden, får vi skrevet ut 120.
Funksjoner som kaller funksjoner
Vi skal åpne fila kombinatorikk og legge til funksjonen kombinasjon(), slik den er vist, og lagre fila igjen.
Vi velger «Fil» – «Åpne» i Thonny, og klikker på kombinatorikk.py. Så legger vi til koden til kombinasjon() under funksjonen fakultet(). Hele fila ser nå slik ut:
def fakultet(n):
"""Beregner n!"""
fakt = 1
for m in range(2, n + 1):
fakt *= m
return fakt
def kombinasjon(n, k):
"""Beregner antall kombinasjoner av k blant n"""
return int(fakultet(n) / (fakultet(k) * fakultet(n - k)))
Vi har her brukt 2 tomme linjer mellom de to funksjonene, det er i henhold til stilguiden PEP 8, men det har ingen betydning for virkemåten.
Vi lagrer så fila igjen ved å velge «Fil» – «Lagre», eller trykke <ctrl>s.
Så skal vi åpne ei ny fil, importere kombinasjon() fra kombinatorikk, bruke kombinasjon() til å beregne antall kombinasjonsmuligheter når 7 elementer velges fra en mengde på 34, og skrive ut resultatet.
Vi åpner ei ny fil i Thonny, og skriver inn kode tilsvarende dette:
from kombinatorikk import kombinasjon print(kombinasjon(34, 7))
Vi kan alternativt velge å importere hele modulen kombinatorikk. Da må vi referere til kombinasjon som kombinatorikk.kombinasjon:
import kombinatorikk print(kombinatorikk.kombinasjon(34, 7))
Når vi kjører koden, får vi skrevet ut 5379616.
Vi skal skrive en funksjon som beregner sannsynligheten for få k «kron» i n flipp med en mynt, basert på at $P(k) = {\large \binom{n}{k}} \cdot (0{,}5)^n$.
Vi har kalt funksjonen sanns_kron(), men den kan hete hva som helst. Før funksjonen importer vi kombinasjon() fra modulen kombinatorikk, fordi vi trenger den til å beregne ${\large \binom{n}{k}}$.
Koden kan se slik ut:
from kombinatorikk import kombinasjon
def sanns_kron(n, k):
"""Beregner sanns. for k kron i n flipp med en mynt"""
return kombinasjon(n, k) * 0.5**n
Vi kan alternativt velge å importere hele modulen kombinatorikk. Da må vi referere til kombinasjon som kombinatorikk.kombinasjon:
import kombinatorikk
def sanns_kron(n, k):
"""Beregner sanns. for k kron i n flipp med en mynt"""
return kombinatorikk.kombinasjon(n, k) * 0.5**n
Hvis vi i hovedprogrammet skriver
print(sanns_kron(7, 5))
får vi skrevet ut 0,1640625 når vi kjører koden,
Vi skal utvide funksjonen fra oppgave 2 slik at den beregner sannsynligheten for at en hendelse med sannsynlighet p skal inntreffe k ganger i n forsøk, basert på at $P(k) = {\large \binom{n}{k}} \cdot p^k \cdot {(1-p)}^{(n-k)}$. Funksjonen skal hete binomisk(), og ligge i fila kombinatorikk under fakultet() og kombinasjon().
Vi velger «Fil» – «Åpne» i Thonny, og klikker på kombinatorikk.py. Så legger vi til koden til den nye funksjonen, som kan se slik ut:
def binomisk(n, k, p):
"""Beregner sanns. for k i n forsøk med sannsynlighet p"""
return kombinasjon(n, k) * p**k * (1 - p)**(n - k)
Vi lagrer så fila igjen ved å velge «Fil» – «Lagre», eller trykke <ctrl>s.
Så skal vi åpne ei ny fil, importere binomisk() fra kombinatorikk, bruke binomisk() til å beregne sannsynligheten for at en hendelse med sannsynlighet 0,2 skal inntreffe 4 ganger i 8 forsøk, og skrive ut resultatet med 5 desimaler.
Vi åpner ei ny fil i Thonny, og skriver inn kode tilsvarende dette:
from kombinatorikk import binomisk print(f"{binomisk(8, 4, 0.2):.5f}")
Vi kan alternativt velge å importere hele modulen kombinatorikk. Da må vi referere til binomisk som kombinatorikk.binomisk:
import kombinatorikk print(f"{kombinatorikk.binomisk(8, 4, 0.2):.5f}")
Når vi kjører koden, får vi skrevet ut 0,04588.
Rekursjon
Vi skal skrive en rekursiv funksjon som beregner summen av de n første leddene av den harmoniske rekka ${\large\frac{1}{1}} + {\large\frac{1}{2}} + {\large\frac{1}{3}} + \dots + {\large\frac{1}{n}}$
Vi baserer oss da på at
S1 = 1
og
$S_n = {\large \frac{1}{n}} + S_{n-1}$
Denne definisjonen kan vi kode direkte:
def harmonisk(n):
"""Beregner 1/1 + 1/2 + ... + 1/n"""
if n == 1:
return 1
else:
return 1/n + harmonisk(n - 1)
I hovedprogrammet skriver vi
print(f"{harmonisk(10):.5f}")
Når vi kjører koden, får vi skrevet ut 2,92897.
Vi har en rekursiv funksjon, summer():
def summer(n):
if n == 1:
return n
else:
return n + summer(n - 1)
Så skal vi gjøre en analyse av koden med penn og papir, og forklare hva som blir skrevet ut når vi i hovedprogrammet skriver
print(summer(3))
Først kalles summer() opp fra print() med argument 3. Deretter kaller summer() seg selv rekursivt to ganger med argumenter lik henholdsvis 2 og 1. Deretter vil vi få returverdier på henholdsvis 1, 2 + 1 = 3 og 3 + 3 = 6, så vi får skrevet ut 6.
Så skal vi forklare hva skjer hvis vi i stedet skriver
print(summer(-3))
I dette tilfellet vil vi få en uendelig kjede av rekursive kall fordi grunnbetingelsen n = 1 aldri blir nådd. Etter noe tid vil kjøringen av koden avsluttes med en feilmelding om for stor rekursjonsdybde.