{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Funksjoner\n",
"\n",
"```{admonition} Læringsutbytte\n",
"Etter å ha arbeidet med dette temaet, skal du kunne:\n",
"1. bruke funksjoner til å strukturere og gjenbruke kode.\n",
"2. forklare hva som menes med globale og lokale variabler.\n",
"```\n",
"\n",
"## Definisjon\n",
"I tillegg til innebygde funksjoner i Python som _print_ og _input_ kan vi lage funksjoner selv. Dette kan være svært nyttig fordi det kan gjøre programmet mer oversiktlig og håndterbart. I tillegg er det nyttig med funksjoner når vi skal gjøre samme ting flere ganger. Si at vi for eksempel har en vilkårlig matematisk funksjon $f(x) = x^2 + x - 5$. Dersom vi vil regne ut $f(x)$ for alle heltallsverdier av $x$ mellom 1 og 50, kan vi gjøre dette med funksjoner. Først definerer vi funksjonen:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"def f(x):\n",
" return x**2 + x - 5"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Vi definerer her en funksjon med kodeordet _def_ og gir den et funksjonsnavn, her _f_. Deretter spesifiserer vi hva inn-verdien/variabelen til funksjonen skal hete i parentes. Her kaller vi den _x_. I programmering kaller vi en slik størrelse for en _parameter_. Gitt én verdi av _x_, skal funksjonen _returnere_ (spesifisert ved _return_-kommandoen) en funksjonsverdi. Legg merke til at syntaksen er ganske lik vilkår (if-tester), while- og for-løkker, med et kolon etter funksjonsnavnet og innrykk på alt som tilhører funksjonen. \n",
"\n",
"Vi får derimot ikke noe output av å definere en funksjon. For å få et output, må vi bruke (vi sier også \"kalle på\") funksjonen:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"1\n"
]
}
],
"source": [
"funksjonsverdi = f(2) # Kaller på funksjonen\n",
"print(funksjonsverdi)\n",
"\n",
"# Eller\n",
"print(f(2)) # Kaller på funksjonen inni en print-funksjon"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"```{admonition} Underveisoppgave\n",
":class: tip\n",
"Lag en Python-funksjon som representerer den matematiske funksjonen $f(x) = \\frac{-x}{2} + \\sqrt{x}$. Lag ei løkke som skriver ut 100 ulike funksjonsverdier.\n",
"```\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"```{code-block} Python\n",
"import numpy as np\n",
"\n",
"def f(x):\n",
" return -x/2 + np.sqrt(x)\n",
" \n",
"for x in range(100):\n",
" print(f(x))\n",
"```\n",
"````\n",
"\n",
"Vi kan også lage funksjoner uten returverdi, for eksempel funksjoner som skriver ut noe:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"Gratulerer med dagen, Silje\n"
]
}
],
"source": [
"# Definerer to funksjoner\n",
"def f(x):\n",
" print(x**2 + x - 5)\n",
" \n",
"def gratulerer(navn):\n",
" print(\"Gratulerer med dagen,\", navn)\n",
"\n",
"# Kaller på funksjonene\n",
"f(2)\n",
"gratulerer(\"Silje\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Her ser vi at vi ikke trenger å skrive _print_ når vi kaller på funksjonene. Dette ser da enda enklere ut enn å bruke retur-verdier, så hvorfor bruker vi _return_ i det hele tatt?\n",
"\n",
"Det er faktisk bedre å bruke return enn print, der det er mulig. Hvis vi for eksempel er interessert i å gjøre noe annet med funksjonsverdiene enn å printe dem, må vi ha konkrete verdier å jobbe med. La oss si at vi ønsker å finne differansen mellom to funksjonsverdier. Hvis vi skal regne med funksjonsverdier, må vi ha en returverdi. Det fungerer nemlig ikke å trekke fra hverandre to print-funksjoner. Eksempelet nedenfor illustrerer dette."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"````{panels}\n",
":column: col-6\n",
":card: border-2\n",
":header: bg-success\n",
" \n",
"Riktig\n",
"^^^\n",
"```{code-block} Python\n",
"def f(x):\n",
" return x**3 - 1/x\n",
" \n",
"print(f(3) - f(1))\n",
"```\n",
"---\n",
":header: bg-danger\n",
"Feil\n",
"^^^\n",
"Følgende kode vil gi feilmelding:\n",
"\n",
"```{code-block} Python\n",
"def f(x):\n",
" print(x**3 - 1/x)\n",
" \n",
"f(3) - f(1)\n",
"```\n",
"````\n",
"\n",
"Vi kan også representere matematiske formler som Python-funksjoner, for eksempel slik:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"def areal_sirkel(r):\n",
" A = np.pi*r**2\n",
" return A\n",
"\n",
"def volum_sylinder(r, h):\n",
" V = np.pi*r**2*h\n",
" return V"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Vi kan også skrive _np.pi\\*r\\*\\*2_ og _np.pi\\*r\\*\\*2\\*h_ direkte etter return i funksjonene ovenfor, istedenfor å gjøre det på to linjer. Dette er litt smak og behag, men ofte kan det være mer oversiktlig å gjøre ting på flere linjer enn på én. Dessuten kan man skrive formelen direkte slik den forekommer i matematikken.\n",
"\n",
"```{admonition} Underveisoppgave\n",
":class: tip\n",
"Volumet til ei kule er gitt ved $\\frac{4}{3}\\pi r^3$. Lag en funksjon som beregner dette volumet og finner differansen mellom volumet til ei kule med radius 10 og ei kule med radius 5.\n",
"```\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"```{code-block} Python\n",
"import numpy as np\n",
"\n",
"def volum_kule(r):\n",
" V = (4/3)*np.pi*r**3\n",
" return V\n",
" \n",
"volumforskjell = volum_kule(10) - volum_kule(5)\n",
"```\n",
"````\n",
"\n",
"Her ser vi også at den siste funksjonen tar to parametre. Det er mulig å bruke så mange parametre i en funksjon som du ønsker. Det går også an å lage funksjoner uten parametre, for eksempel slik:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hei på deg!\n"
]
}
],
"source": [
"def hei():\n",
" print(\"Hei på deg!\")\n",
" \n",
"hei()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Parameternavn\n",
"La oss se på et eksempel der vi kaller på en funksjon på tre måter."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Farten er 5.0 m/s.\n",
"Farten er 5.0 m/s.\n",
"Farten er 5.0 m/s.\n"
]
}
],
"source": [
"def fart(s, t):\n",
" v = s/t\n",
" return v\n",
"\n",
"# Funksjonskall 1\n",
"s = 10 # Strekning i meter\n",
"t = 2 # Tid i s\n",
"print(\"Farten er\", fart(s, t), \"m/s.\")\n",
"\n",
"# Funksjonskall 2\n",
"strekning = 10\n",
"tid = 2\n",
"print(\"Farten er\", fart(strekning, tid), \"m/s.\")\n",
"\n",
"# Funksjonskall 3\n",
"print(\"Farten er\", fart(10, 2), \"m/s.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Vi ser at vi får samme output for alle funksjonskallene. Vi trenger ikke å definere variabler før vi setter dem inn i funksjonen, så funksjonskall 3 er kanskje det enkleste. Men hvis vi for eksempel skal bruke verdien for tid flere steder, kan det være lurt å ha det som en egen variabel. Denne variabelen kan vi kalle hva vi vil, for den blir uansett overført til variabelen _t_ inni funksjonen. Så om vi kaller variablene for strekning og tid eller s og t, har ingenting å si. Inni funksjonen blir likevel verdien til _strekning_ overført til variabelen _s_ og variabelen _t_ får verdien til _tid_."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Funksjoner med flere returverdier\n",
"I motsetning til funksjoner i matematikk kan en funksjon i programmering ha flere retur-verdier. Disse kan vi tilordne til variabler adskilt med komma, som vist nedenfor.\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```{admonition} Underveisoppgave\n",
":class: tip\n",
"Forklar hvordan programmet ovenfor fungerer. Modifiser programmet slik at det også returnerer renta, og skriv ut \"Det tar {tid} år før du har {penger} kroner i banken med en rente på {renter*100} prosent.\"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Lokale og globale variabler\n",
"\n",
"Hva skjer hvis vi ikke returnerer verdier i funksjonen ovenfor? Vil vi uansett kunne printe renta og antallet år? La oss undersøke dette."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'år' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_39764/3569527658.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 8\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[0mpenger\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpenger_i_banken\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1000\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3000\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m0.01\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 10\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Det tar\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mår\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"år før du har\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mround\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpenger\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"kroner med en rente på\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mrenter\u001b[0m\u001b[1;33m*\u001b[0m\u001b[1;36m100\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"prosent\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;31mNameError\u001b[0m: name 'år' is not defined"
]
}
],
"source": [
"def penger_i_banken(startkapital, sluttkapital, renter):\n",
" kapital = startkapital\n",
" år = 0\n",
" while kapital <= sluttkapital:\n",
" kapital = kapital + kapital*renter\n",
" år = år + 1\n",
" return kapital\n",
"\n",
"penger = penger_i_banken(1000, 3000, 0.01)\n",
"print(\"Det tar\", år, \"år før du har\", round(penger,2), \"kroner med en rente på\", renter*100, \"prosent\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Her får vi visst en feilmelding, selv om vi klart kan se at \"år\" er definert som en variabel inni funksjonen. Dette handler om at alle variabler som defineres i en funksjon, kun er tilgjengelig inni denne funksjonen. De kalles derfor _lokale_ variabler. Variabler som er definert utenfor funksjoner, kaller vi da for _globale_ variabler. Disse er tilgjengelig både inni og utenfor en funksjon. Her er to eksempler som viser dette:"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Her er jeg!\n",
"Her er jeg!\n"
]
}
],
"source": [
"def funksjon():\n",
" print(a)\n",
"\n",
"a = \"Her er jeg!\"\n",
"\n",
"funksjon()\n",
"print(a) # Skriver ut den globale variabelen a"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Her er jeg!\n"
]
},
{
"ename": "NameError",
"evalue": "name 'b' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mfunksjon\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mb\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# Prøver å skrive ut den lokale variabelen. Vi får dermed en feilmelding\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;31mNameError\u001b[0m: name 'b' is not defined"
]
}
],
"source": [
"def funksjon():\n",
" b = \"Her er jeg!\" # b defineres lokalt inni funksjonen\n",
" print(b)\n",
"\n",
"funksjon()\n",
"print(b) # Prøver å skrive ut den lokale variabelen. Vi får dermed en feilmelding"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Vi kan gjøre en lokal variabel til en global variabel, dersom vi trenger det. Dette er ikke vanlig så vanlig å gjøre, men vi kan gjøre det slik:"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Energien til legemet er: 9e+16 joule.\n",
"Lysets hastighet i vakuum: 300000000.0 m/s.\n"
]
}
],
"source": [
"def masseenergi(m):\n",
" global c\n",
" c = 3E8 # lyshastigheten i m/s\n",
" E = m*c**2\n",
" return E\n",
"\n",
"print(\"Energien til legemet er:\", masseenergi(1), \"joule.\")\n",
"print(\"Lysets hastighet i vakuum:\", c, \"m/s.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Oppgaver\n",
"\n",
"````{admonition} Oppgave 5.1\n",
":class: tip\n",
"Forklar hvordan programmet nedenfor fungerer.\n",
"```{code-block} Python\n",
"def f(x):\n",
" return x + 1\n",
"\n",
"addisjon = f(1) + f(3)\n",
"subtraksjon = f(1) - f(3)\n",
"\n",
"print(addisjon, subtraksjon)\n",
"```\n",
"````\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"Vi definerer først en funksjon _f_ som skal returnere funksjonsverdien _x + 1_. Deretter kaller vi på (bruker) funksjonen ved å beregne summen av _f(1)_ og _f(3)_ og differansen mellom de samme funksjonsverdiene. Da henter programmet informasjon fra funksjonen ovenfor, og beregner slik: _addisjon = (1 + 1) + (3 + 1) = 6_ og _subtraksjon = (1 + 1) - (3 + 1) = -1_. Resultatene fra dette skrives så ut.\n",
"````\n",
"\n",
"```{admonition} Oppgave 5.2\n",
":class: tip\n",
"I programmet nedenfor definerer vi en funksjon som regner ut volumet til en sylinder. Lag en annen funksjon i samme program som regner ut volumet til ei kule.\n",
"\n",
"($V_{kule} = \\frac{4}{3}\\pi r^3$)\n",
"\n",
"\n",
"```\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"```{code-block} Python\n",
"from numpy import pi\n",
"\n",
"def volum_kule(r):\n",
" V = 4/3*pi*r**3\n",
" return V\n",
"\n",
"# Tester funksjonen\n",
"print(volum_kule(2))\n",
"```\n",
"````\n",
"\n",
"````{admonition} Oppgave 5.3\n",
":class: tip\n",
"Hvert program i denne oppgava inneholder noen feil. Finn feilene og rett på dem slik at programmene kan kjøres korrekt.\n",
"\n",
"1. Funksjonen skal regne ut $f(x) = \\frac{1}{2x} + 1$ og returnere svaret. I programmet skal funksjonen kalles på for $x = 4$:\n",
"\n",
"```{code-block} Python\n",
"def f(x):\n",
" 1/2*x + 1\n",
"\n",
"print(\"f(x) = \",f(x))\n",
"```\n",
"2. Programmet ber brukeren om å skrive en verdi for _x_ og regner ut $f(x) = 3x + \\cos(x)$:\n",
"\n",
"```{code-block} Python\n",
"def f(x):\n",
"return 3x + cos(x)\n",
"\n",
"y = input(\"Skriv inn verdi for x i radianer: \")\n",
"print(\"f(x) =\",f(y))\n",
"```\n",
"\n",
"3. Programmet skal skrive ut funksjonsverdien _G(1)_.\n",
"\n",
"```{code-block} Python\n",
"def G(t):\n",
" a = t**2 - 2\n",
" return a\n",
"\n",
"t = 1\n",
"print(a)\n",
"```\n",
"````\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"1. Uttrykket $1/2*x + 1$ regner ut $f(x) = x + 1$, og ikke den ønskede funksjonen. For at programmet skal regne ut hva _x_ blir i den ønskede funksjonen, må parentes brukes i uttrykket for nevneren. Variabelen _x_ er heller ikke definert. Variabelen kan settes til å være lik 4. Vi kan også kalle funksjonen direkte med f(4).\n",
"```{code-block} Python\n",
"def f(x):\n",
" return 1/(2* x) + 1\n",
"print(\"f(x) = \",f(4))\n",
"```\n",
"\n",
"2. Her må cosinus importeres fra et passende bibliotek. Vi må også ha et innrykk på _return_ i $f(x)$, fordi _return_ tilhører funksjonen. Leddet $3x$ må omskrives til $3*x$. Til slutt må variabelen $y$ omgjøres til float for at programmet skal kunne gjøre flytallsoperasjoner på den gitte verdien fra brukeren.\n",
"```{code-block} Python\n",
"from numpy import cos\n",
"def f(x):\n",
" return 3*x + cos (x)\n",
"y = float(input(\" Skriv inn verdi for x i radianer: \"))\n",
"print(\"f(x) =\",f(y))\n",
"```\n",
"\n",
"3. For å finne hva funksjonsverdien til _G_, må vi huske å _kalle på_ funksjonen:\n",
"```{code-block} Python\n",
"def G(t):\n",
" a = t**2 - 1\n",
" return a\n",
"t = 1\n",
"print(G(t))\n",
"```\n",
"````\n",
"\n",
"````{admonition} Oppgave 5.4\n",
":class: tip\n",
"Lag et program eller flere programmer som bruker funksjoner til å regne ut:\n",
"1. Arealet til en sirkel.\n",
"2. Radius til en sirkel gitt arealet.\n",
"3. Omkretsen til en sirkel.\n",
"4. Volumet til ei kule.\n",
"5. Overflatearealet til ei kule.\n",
"\n",
"Du kan lage en enkel versjon først uten funksjoner. Lag så en versjon som inneholder funksjoner av hver av formlene. Ikke ta input fra brukeren, men sett verdiene direkte inn i funksjonskallene.\n",
"````\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"```{code-block} Python\n",
"from numpy import pi\n",
"\n",
"# 1\n",
"def sirkel_areal(r):\n",
" return pi*r**2\n",
"# 2\n",
"def sirkel_radius(A):\n",
" return (A/pi)**0.5 # Opphøyer i 0.5 eller kan bruke sqrt fra numpy\n",
"# 3\n",
"def sirkel_omkrets(r):\n",
" return 2*pi*r\n",
"# 4\n",
"def kule_volum (r):\n",
" return 4/3*pi*r**3\n",
"# 5\n",
"def kule_overflate (r):\n",
" return 4*pi*r**2\n",
"```\n",
"````\n",
"\n",
"````{admonition} Oppgave 5.5\n",
":class: tip\n",
"Forklar hvorfor programmet under gir _None_ som output.\n",
"```{code-block} Python\n",
"def f(x):\n",
" x = 2*x\n",
"x = 12\n",
"x = x + 12\n",
"x = f(x)\n",
"print(x)\n",
"```\n",
"````\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"Verdien til _x_ blir _None_ fordi funksjonen _f_ ikke returner en verdi. For å sørge for at _x_ får en tallverdi etter å ha kalt på _f_, må _f_ returnere noe – i dette tilfellet et tall.\n",
"```{code-block} Python\n",
"def f(x):\n",
" return 2*x\n",
"x = 12\n",
"x = x + 12\n",
"x = f(x)\n",
"print(x)\n",
"```\n",
"````\n",
"\n",
"````{admonition} Oppgave 5.6\n",
":class: tip\n",
"_Karvonens formel_ kan brukes til å finne pulsen til en person gitt hvilepuls $H_{hvile}$ og treningsintensitet $p$ (i prosent):\n",
"\n",
"$hjerteslag \\ per \\ minutt = \\left(H_{maks} - H_{hvile}\\right)\\cdot\\frac{p}{100} + H_{hvile}$\n",
"\n",
"der $H_{maks}$ er maks antall hjerteslag personen kan ha. Den maksimale pulsen kan en finne ved $H_{maks} = 220 - \\textit{alder til person}$. Lag et program som regner ut pulsen til en 20 år gammel person som trener med 60 \\% intensitet og hvilepuls på $70$ slag per minutt. Lag Karvonens formel som en funksjon.\n",
"````\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"```{code-block} Python\n",
"def karvonen(hvilepuls, intensitet, alder):\n",
" p = intensitet\n",
" maks = 220 - alder\n",
" puls = (maks - hvilepuls)*p/100 + hvilepuls\n",
" return puls\n",
"\n",
"puls = karvonen(70, 60, 20)\n",
"print(\" Personen vil ha en puls på\",puls )\n",
"```\n",
"````\n",
"\n",
"````{admonition} Oppgave 5.7 (kjemi)\n",
":class: tip\n",
"I kjemi har vi ofte bruk for molregning. Lag et enkelt program som regner ut antall mol dersom brukeren taster inn molmasse og masse av et bestemt stoff. Du kan også be brukeren taste inn stoffet det gjelder, slik at du får dette som output også. Lag formelen som en funksjon.\n",
"````\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"```{code-block} Python\n",
"def antall_mol (masse , molmasse ):\n",
" return masse/molmasse\n",
"stoff = input(\" Hvilket stoff vil du finne antall mol til ?: \")\n",
"masse = float(input(\" Skriv inn massen ( gram ): \"))\n",
"molmasse = float(input(\" Skriv inn molmassen ( gram /mol): \"))\n",
"mol = antall_mol (masse , molmasse )\n",
"print(\"Stoffet\", stoff, \"består av\", mol ,\"mol.\")\n",
"```\n",
"````\n",
"\n",
"````{admonition} Oppgave 5.8 (kjemi)\n",
":class: tip\n",
"Lag et program som regner ut pH fra $[H_3O^+]$ ved hjelp av en funksjon.\n",
"````\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"```{code-block} Python\n",
"from numpy import log10\n",
"def ph_H3O(konsentrasjon):\n",
" return -log10 (konsentrasjon)\n",
"\n",
"ph = ph_H3O(1E-5)\n",
"print(\"pH av den gitte konsentrasjonen er:\", ph)\n",
"```\n",
"````\n",
"\n",
"````{admonition} Oppgave 5.9 (fysikk)\n",
":class: tip\n",
"Programmer én av bevegelsesformlene (kinematikklikningene) som en funksjon. Du kan selv velge hva programmet skal regne ut.\n",
"````\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"```{code-block} Python\n",
"def posisjon(v0 , a, t):\n",
" return v0 + a*t\n",
"\n",
"v = posisjon(2, 10, 5) # Tester funksjonen med v0 = 2, a = 10 og t = 5.\n",
"print(\"Farten til legemet er:\", v, \"m/s.\")\n",
"```\n",
"````\n",
"\n",
"````{admonition} Oppgave 5.10 (fysikk)\n",
":class: tip\n",
"Bruk Bohrs formel for spektrene til hydrogenatomet:\n",
"$f =\\frac{B}{h}\\cdot \\left( \\frac{1}{m^2} - \\frac{1}{n^2} \\right)$\n",
"\n",
"Lag et program som regner ut bølgelengden til fotonet som emitteres når et elektron deeksiterer fra skall _m_ til _n_. Bruk en funksjon.\n",
"\n",
"Husk at vi har følgende sammenheng mellom frekvens og bølgelengde ($\\lambda$):\n",
"\n",
"$\\lambda = \\frac{c}{f}$\n",
"\n",
"$B = 2.18\\cdot10^{-18}$, $c = 3.00\\cdot10^8$ m/s og $h = 6.63\\cdot10^{-34}$.\n",
"````\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"```{code-block} Python\n",
"# Konstanter\n",
"B = 2.18E-18\n",
"h = 6.636E-34\n",
"c = 3e8\n",
"\n",
"#Bohrs formel\n",
"def Bohr(n,m):\n",
" f = B/h *(1/ m**2 - 1/n **2)\n",
" bl = c/f # bølgelengde i meter\n",
" bl_nm = bl*1E9 # bølgelengde i nanometer\n",
" return bl_nm\n",
"\n",
"#Energinivåer\n",
"n = int(input(\"Skriv inn en verdi for n:\")) #skallet det eksiteres fra\n",
"m = int(input(\"Skriv inn en verdi for m:\")) #skallet det eksiteres til\n",
"\n",
"print(\"Bølgelengden til lyset fra n =\",n ,\"til m =\", m, \n",
" \"er:\", round(Bohr(n,m)),\"nm\")\n",
"```\n",
"````\n",
"\n",
"````{admonition} Oppgave 5.11 (matematikk)\n",
":class: tip\n",
"Lag en funksjon som tar tre variabler _a_, _b_ og _c_, tilsvarende koeffisientene i andregradsfunksjoner av typen $f(x) = ax^2 + bx + c$. La funksjonen løse andregradslikninger av typen $f(x) = 0$ ved hjelp av andregradsformelen.\n",
"````\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"```{code-block} Python\n",
"def andregradsformelen(a, b, c):\n",
" rotuttrykk = b**2 - 4*a*c\n",
" if rotuttrykk > 0:\n",
" x1 = (-b + rotuttrykk**0.5)/(2*a)\n",
" x2 = (-b - rotuttrykk**0.5)/(2*a)\n",
" return x1, x2\n",
" elif rotuttrykk < 0:\n",
" return \"Likningen har ingen reelle løsninger.\"\n",
" elif rotuttrykk == 0:\n",
" x = -b/(2*a)\n",
" return x\n",
"\n",
"print(andregradsformelen(1, 2, 3))\n",
"print(andregradsformelen(1, -2, 1))\n",
"print(andregradsformelen(1, -4, 3))\n",
"```\n",
"````\n",
"\n",
"````{admonition} Oppgave 5.12\n",
":class: tip\n",
"Hvorfor har _x_ samme verdi før og etter funksjonen _f_ har blitt kalt på i programmet under?\n",
"```{code-block} Python\n",
"def f(x):\n",
" x = x + 3\n",
" return 9*x\n",
"x = 3\n",
"print(x) # Skriver ut 3\n",
"y = f(x)\n",
"print(x) # Skriver ut 3\n",
"```\n",
"````\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"$_x_$ er en global variabel utenfor funksjonen. Den får verdien 3. I tillegg finnes det en lokal variabel med samme navn inni funksjonen. Denne variabelen får verdien $_x = x + 3 = 3 + 3 = 6_$, men denne variabelen er ikke tilgjengelig utenfor funksjonen. \n",
"````\n",
"\n",
"````{admonition} Oppgave 5.13\n",
":class: tip\n",
"De fleste gasser kan modelleres med _tilstandslikninga for idelle gasser_:\n",
"\n",
"$PV = nRT$\n",
"\n",
"der _P_ er trykket i pascal, _V_ er volumet i kubikkmeter, _n_ er stoffmengden i mol, $R = 8.3144598 J/(mol\\cdot K)$ er gasskonstanten og _T_ er temperaturen i Kelvin. \n",
"\n",
"Lag et program der du bruker denne likninga til å lage en funksjon for P og en annen for T. Test funksjonene.\n",
"````\n",
"\n",
"````{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"```{code-block} Python\n",
"def trykk(V, n, T):\n",
" R = 8.3144598 # J/(mol*K)\n",
" P = n*R*T/V\n",
" return P\n",
"\n",
"def temperatur(P, V, n):\n",
" R = 8.3144598 # J/(mol*K)\n",
" T = P*V/(n*R)\n",
" return T\n",
"\n",
"print(trykk(100, 1, 300))\n",
"print(temperatur(100, 1, 1))\n",
"```\n",
"````\n",
"\n",
"````{admonition} Oppgave 5.14*\n",
":class: tip\n",
"Studer programmet nedenfor. Hvilke variabler er lokale, og hvilke er globale? Hva skrives ut?\n",
"\n",
"```{code-block} Python\n",
"def f(x,y):\n",
" global e\n",
" e = x + y + e\n",
" return e\n",
"\n",
"c = 1\n",
"d = 2\n",
"e = 3\n",
"\n",
"print(f(c, d) + e)\n",
"```\n",
"````\n",
"\n",
"```{admonition} Løsningsforslag\n",
":class: tip, dropdown\n",
"Variablene c_, _d_ og _e_ er globale variabler, mens _x_ og _y_ er lokale variabler som kun eksisterer inni funksjonen. Når vi printer _f(c, d) + e_, overføres verdien av _c_ og _d_ til de lokale variablene _x_ og _y_ i funksjonen. Deretter beregnes _e_ ved hjelp av _x_, _y_ og den globale _e_, som har verdien 3. Variabelen _e_ fra funksjonen (nå med verdien 6) defineres som global, og overskriver dermed den tidligere _e_ (med verdien 3). Det er denne _e_-en som legges til _f(c, d)_ i print-kommandoen til slutt.\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Filmer\n",
"I videoen nedenfor kan du få en innføring eller repetisjon i den grunnleggende teorien bak funksjoner.\n",
"\n",
""
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 4
}