Vi har i mange artikler benyttet oss både av Pythons innebygde funksjoner og funksjoner importert fra moduler. Her skal vi se hvordan vi kan skrive våre egne funksjoner.
I utgangspunktet kan vi tenke på en funksjon som en boks der vi gir inn noe og får ut noe. Noe à la en matematisk funksjon, f, der vi gir inn et tall, x, og får ut en beregnet funksjonsverdi, f(x). Hvis vi for eksempel har f(x) = 5x2, vil alle verdier vi putter inn i funksjonen, bli opphøyd i andre og multiplisert med 5 før de blir sendt ut igjen.
Eksempel 1 viser hvordan funksjonen f(x) = 5x2 kan skrives i Python.
Eksempel 1:
def f(x):
return 5 * x**2
En funksjon definerer vi i Python ved å skrive kodeordet def etterfulgt av funksjonsnavnet. I eksempel 1 er funksjonsnavnet f. Deretter kommer et sett parenteser og et kolon. Mellom parentesene kan vi ha variabler. Slike variabler kalles parametere. Koden i eksempel 1 har en enkelt parameter, x. Når vi aktiverer funksjoner, bruker vi argumenter for å gi verdier til parameterne.
Den første linja i en funksjon kalles funksjonshodet. I funksjonshodet angir vi navnet på funksjonen og hvilke parametere den har. Thonny markerer navnet på funksjoner med mørkeblå skrift.
Etter funksjonshodet følger en innrykket kodeblokk, som vi kaller funksjonskroppen. Koden i funksjonskroppen gjennomløpes når funksjonen aktiveres. Inni funksjonskroppen vil vi ofte ha kodeordet return, som angir hva som skal sendes ut igjen av funksjonen. I eksempel 1 er dette verdien vi får når vi beregner 5x2. Det kaller vi en returverdi.
Hvis vi nedenfor funksjonen i eksempel 1, uten innrykk, skriver
y = f(3) print(y)
vil Python svare 45.
Vi bruker ikke innrykk på disse linjene fordi de ikke hører med til funksjonen.
I stedet for å si «nedenfor funksjonen» vil vi fra nå av si «i hovedprogrammet».
Når Python kjører koden y = f(3), aktiveres funksjonen f med tallet 3 som argument. Siden funksjonens parameter er x, vil x bli satt lik 3. Så blir 3 brukt i uttrykket 5 * x**2, som da blir 5 · 32 = 45. Returverdien er altså 45.
I stedet for å si at vi aktiverer en funksjon, sier vi gjerne at vi kaller funksjonen, eller kaller opp funksjonen.
Vi har tidligere lært at et likhetstegn i Python betyr at vi skal ta verdien til høyre for likhetstegnet og tildele til variabelen til venstre. Så y = f(3) betyr at returverdien fra funksjonen f skal tildeles til variabelen y. print(y) skriver deretter ut verdien til y, på samme måte som vi har gjort i mange andre artikler.
Vi kunne droppet variabelen y, og bare skrevet
print(f(3))
Men variabelen y gjør logikken tydeligere.
Eksempel 1 var lagt tett opp til den matematiske funksjonen f(x) = 5x2, men funksjoner trenger ikke hete f, og parameteren trenger ikke hete x. I programmering bruker vi gjerne litt mer beskrivende navn. For navn på funksjoner gjelder samme regler som for navn på variabler. Navnene kan bare inneholde bokstaver, tall og understreking, og kan ikke starte med tall. Ifølge stilguiden PEP 8 bør vi også bare bruke små bokstaver i funksjonsnavn, på samme måte som i variabelnavn, og ikke starte med understreking.
Eksempel 2:
Vi skal lage en funksjon som regner om fra grader Fahrenheit til grader Celsius ved hjelp av formelen $c = {\large \frac{5(f-32)}{9}}$, der f er grader Fahrenheit og c grader Celsius.
Funksjonen kan se slik ut:
def fahr_til_cels(fahrenheit):
celsius = 5 * (fahrenheit - 32) / 9
return celsius
Her er funksjonsnavnet fahr_til_cels og parameteren fahrenheit. celsius er en lokal variabel som tilhører funksjonen.
Vi kan også droppe variabelen celsius, og skrive funksjonen mer kompakt som
def fahr_til_cels(fahrenheit):
return 5 * (fahrenheit - 32) / 9
Det blir et spørsmål om smak og behag hva vi velger.
Hvis vi i hovedprogrammet, uten innrykk, skriver
print(f"{fahr_til_cels(100):.02f}")
svarer Python 37.78.
I eksempel 2 har vi ikke brukt c og f som variabelnavn, men valgt det mer beskrivende fahrenheit og celsius, for å gjøre koden mer lesbar for mennesker.
Vi har tidligere brukt kommentarer mye til å forklare hva Python-kode gjør. For funksjoner finnes det en konvensjon om at koden skal beskrives ved hjelp av en såkalt docstring. En docstring er en tekst på første linje i funksjonskroppen, angitt mellom triple anførselstegn. For eksempel slik, for funksjonen i eksempel 2:
def fahr_til_cels(fahrenheit):
"""Konverterer fra grader Fahrenheit til grader Celsius."""
return 5 * (fahrenheit - 32) / 9
Thonny markerer en docstring med grønn skrift, slik som andre strenger.
Python-funksjonen help() benytter seg av en funksjons docstring. Hvis vi i hovedprogrammet skriver
help(fahr_til_cels)
svarer Python:
Help on function fahr_til_cels in module __main__:
fahr_til_cels(fahrenheit)
Konverterer fra grader Fahrenheit til grader Celsius.
Skriv 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. Legg inn en passende docstring i funksjonen.
For å teste funksjonen kan du skrive print(f"{cels_til_fahr(10):.02f}") i hovedprogrammet, og sjekke at Python skriver ut 50.00.
En funksjon kan ha et vilkårlig antall parametere, vi lister dem opp mellom parentesene i funksjonshodet, atskilt med komma.
Eksempel 3:
Funksjonen under beregner og returnerer gjennomsnittet av tre tall:
def snitt(tall_1, tall_2, tall_3):
"""Beregner gjennomsnittet av tre tall."""
return (tall_1 + tall_2 + tall_3) / 3
Eksempel 4:
Funksjonen under finner og returnerer det største av to tall:
def storst(tall_1, tall_2):
"""Finner det største av to tall."""
if tall_1 > tall_2:
return tall_1
else:
return tall_2
Vi har ikke presisert hva som skal skje hvis de to tallene er like, men det er underforstått at det felles tallet da skal returneres. Dette tilfellet fanges opp av else.
I eksempel 4 ser vi at vi gjerne kan ha return flere plasser.
Skriv en Python-funksjon som finner og returnerer det minste av to tall. Test den på en måte du synes er fornuftig.
I funksjoner angir vi ofte returverdier, men vi trenger ikke gjøre det. En funksjon som ikke har angitt returverdi, returnerer None. None er ikke en variabel, men et kodeord i Python. Den innebygde Python-funksjonen print() returnerer for eksempel None.
En funksjon bør bare returnere verdier av én enkelt datatype. Det vil si at funksjonen for eksempel enten returnerer tall eller strenger, men ikke tall i noen tilfeller og strenger i en annen.
Vi bør unngå innlesing og utskrift inni funksjoner. Dette vil låse funksjonen til direkte kommunikasjon med brukeren, og derved gjøre den mindre generell og anvendelig. Innlesing legger vi i hovedprogrammet, og sender det brukeren skriver inn, som et argument til funksjonen. Utskrift legger vi også i hovedprogrammet, og lar funksjonen sende det som skal skrives ut, som en returverdi.
Kilder
-
- Matthes A. (2019). Python Crash Course. no starch press
I noe litteratur kalles parametere for «formelle parametere» og argumenter for «aktuelle parametere». Disse betegnelsene unngår vi for å ikke skape forvirring.
Se film om funksjoner