Eigendefinerte funksjonar i Python - Verktøykassa – for lærarar - NDLA

Hopp til innhald
Verktøy og mal

Eigendefinerte funksjonar i Python

Standard Python inneheld mellom anna funksjonane print() og input(), men vi kan lage våre eigne funksjonar òg. Kvifor ikkje lage oss ein matematisk funksjon?

Problemstilling

I artikkelen Modell for kostnad, inntekt og overskot har ei bedrift ein funksjon som er modell for kostnadene K i kroner ved å produsere x einingar av ei vare lik

Kx=0,25x2+500

Sidan prisen på ei eining er 45 kroner, blir inntektsfunksjonen

Ix=45x

Oppgåve – rekning

Finn ein funksjon for overskotet O ut ifrå dei to funksjonane over.

Løysingsforslag

Overskotet finn vi ved å trekkje kostnadene frå inntekta.

Ox = Ix-Kx= 45x-(0,25x2+500)= 45x-0,25x2-500= -0,25x2+45x-500

Vi går no ut ifrå at bedrifta produserer 60 einingar per dag. Dei vurderer å auke produksjonen til 100 einingar per dag, og dei lurer på kor mykje overskotet endrar seg. Oppdraget vårt blir å lage eit program som kan rekne ut skilnaden i overskot ved to ulike tal på produserte einingar.

Koding utan å bruke eigendefinert funksjon

Programmet må ta imot to tal frå brukaren: to tal på produserte einingar (eller to x-verdiar, om vi vil). Desse tala må setjast inn i funksjonen O, differansen må reknast ut og svaret skrivast til skjermen.

Oppgåve – algoritme

Skriv algoritmen til eit slikt program. Hugs å få med gode, forklarande tekstar.

Forslag til algoritme
  • Skriv til skjermen "Dette programmet reknar ut skilnaden i overskot ved å endre produksjonsmengda frå eitt tal til eit anna.".
  • Skriv til skjermen "Skriv inn noverande produksjonsmengde: ".
  • Ta imot talet for produksjonsmengde frå brukaren, og set det lik variabelen p_no.
  • Skriv til skjermen "Skriv inn den nye produksjonsmengda: ".
  • Ta imot talet for ny produksjonsmengde frå brukaren, og set det lik variabelen p_ny.
  • Rekn ut overskotet med talet i variabelen p_ny, og trekk frå svaret på utrekninga av overskotet med variabelen p_no. Set svaret lik variabelen o_endring.
  • Skriv til skjermen "Endringa i overskotet ved å endre produksjonen frå <p_no> einingar til <p_ny> er <o_endring> kroner.".

Oppgåve – koding

Skriv koden til programmet etter algoritmen over i ein programeditor for Python. Kontroller at programmet reknar rett ved til dømes å sjå på grafen til overskotsfunksjonen i artikkelen Modell for kostnad, inntekt og overskot.

Løysingsforslag

print("Dette programmet reknar ut skilnaden i kostnader "
"ved å endre produksjonsmengda frå eitt tal til eit anna.")
p_no = int(input("Skriv inn noverande produksjonsmengde: "))
p_ny = int(input("Skriv inn den nye produksjonsmengda: "))
o_endring = -0.25*p_ny**2 + 45*p_ny - 500 - (-0.25*p_no**2 + 45*p_no - 500)
print(f"Endringa i overskotet ved å endre produksjonen frå "
f"{p_no} einingar til {p_ny} er {o_endring} kroner.")

Koding med eigendefinert funksjon

I utrekninga i den femte linja har vi brukt den matematiske funksjonen O for overskotet som vi kom fram til lengre opp på sida. Innhaldet i linje 5 er vanskeleg å lese. Tenk om vi kunne ha brukt skrivemåten frå matematikken her! Matematisk skriv vi

O100-O(60)

for å finne endringa i overskotet ved å endre produksjonen frå 60 einingar til 100. Dette kan kan vi heldigvis gjere i Python òg. Vi kan endre den femte linja til følgjande:

o_endring = O(p_ny) - O(p_no)

For å kunne gjere det, må vi lage oss funksjonen O, og korleis gjer vi det i Python? Jau, vi kan definere funksjonen med kodeordet def. Funksjonen O blir med dette ein eigendefinert funksjon. Det betyr at vi øvst i programmet vårt skriv følgjande:

def O(x):
    return -0.25*x**2 + 45*x - 500

Desse to kodelinjene blir ikkje utførte i første omgang når vi køyrer programmet fordi dei utgjer ein definisjon. Kodelinjene blir ikkje utførte før vi kallar på den eigendefinerte funksjonen første gong ved å skrive O(p_ny) i koden nedanfor funksjonsdefinisjonen. Då vil programmet leite opp definisjonen av funksjonen O, erstatte x i definisjonen med innhaldet av variabelen p_ny, og vi får rekna ut overskotet ved denne produksjonsmengda.

Oppgåve – algoritme og koding

a) Skriv inn øvst i programkoden definisjonen av funksjonen O over. Endre på linja med utrekningar som vist ovanfor ved å kalle på den eigendefinerte funksjonen, og kontroller at programmet fungerer som før.

b) Kva endringar blir det i algoritmen til programmet når vi bruker den eigendefinerte funksjonen O i staden for å rekne ut overskotsendringa direkte?

Løysingsforslag

Det blir eigentleg ikkje noka endring i algoritmen til programmet. Sjølve funksjonsdefinisjonen er ikkje ein del av algoritmen til programmet sidan det berre er ein definisjon. Den nest siste instruksjonen i algoritmen ovanfor, den einaste plassen der det kunne vere ei endring, gjeld framleis.

Funksjonen O har sin eigen algoritme:

  • Ta imot ein x-verdi.
  • Rekn ut følgjande: -0,25·x2+45·x-500 
  • Returner svaret.

Spørsmål – vurdering

Kvifor er det lurt å endre programkoden ved å lage ein eigendefinert funksjon?

Svar

Den viktigaste årsaka er at vi får ryddigare og kortare programkode. Dette blir viktigare og viktigare jo større programmet blir.

Ei anna viktig årsak er gjenbruk av kode. Kanskje skal den funksjonen du definerer i eitt program brukast i eit anna program? Då er det berre å kopiere og lime inn heile funksjonsdefinisjonen inn i det andre programmet. Å definere eigne funksjonar gjer det mykje lettare å utveksle kode med andre. I Python finst det mange programbibliotek med eigendefinerte funksjonar som vi kan laste ned og bruke.

Pythonkode å lære seg

Vis innhald

Eigendefinert funksjon

Struktur:

def funksjonsnamn(parameter1, parameter2, ...):
    kodelinje
    kodelinje
    ...

Kodelinjene her er definisjonar og blir ikkje utførte før det blir skrive funksjonsnamn(verdi1, verdi2, ...) i den eigentlege programkoden nedanfor funksjonsdefinisjonen. Hugs kolon på slutten av linja som byrjar med "def", og merk at kodelinjene til ein funksjon skal rykkjast inn.

Eksempel:

Vi skal bruke den matematiske funksjonen  f(x)=3x-2  i eit program som skal rekne ut funksjonsverdiar. Då skriv vi

def f(x):
    return 3*x - 2

øvst i programkoden. Kodeordet return bruker vi for å få attende noko frå funksjonen. Dersom vi i koden til programmet skriv

funksjonsverdi = f(1)

vil funksjonen rekne ut  f(1)=3·1-2=1  og setje det lik variabelen funksjonsverdi.

I eksempelet skal funksjonen f berre ha éin verdi inn (x), men vi kan lage funksjonar som skal ha inn fleire verdiar, som det generelle eksempelet over viser.

Aktivitetar

a) Algoritme

Dersom brukaren av programmet tastar inn produksjonstal som gjer at endringa av overskotet blir negativ, til dømes –100, hadde det vore kjekt om programmet kunne skrive til dømes "Overskotet minkar med 100 kroner når talet på produserte einingar blir endra frå ...".

Lag ei tilsvarande setning som passar når overskotet aukar og ei eiga setning som passar når overskotet er uendra. Endre på algoritmen slik at han tek omsyn til korleis overskotet blir endra.

Forslag til algoritme
  • Skriv til skjermen "Dette programmet reknar ut skilnaden i overskot ved å endre produksjonsmengda frå eitt tal til eit anna.".
  • Skriv til skjermen "Skriv inn noverande produksjonsmengde: ".
  • Ta imot talet for produksjonsmengde frå brukaren, og set det lik variabelen p_no.
  • Skriv til skjermen "Skriv inn den nye produksjonsmengda: ".
  • Ta imot talet for ny produksjonsmengde frå brukaren, og set det lik variabelen p_ny.
  • Rekn ut overskotet med talet i variabelen p_ny, og trekk frå svaret på utrekninga av overskotet med variabelen p_no. Set svaret lik variabelen o_endring.
  • Dersom o_endring er mindre enn null:
    • Set o_endring lik minus o_endring.
    • Skriv til skjermen "Overskotet minkar med <o_endring> kroner når talet på produserte einingar blir endra frå <p_no> einingar til <p_ny>.".
  • Dersom o_endring ikkje er mindre enn null, men større enn null:
    • Skriv til skjermen "Overskotet aukar med <o_endring> kroner når talet på produserte einingar blir endra frå <p_no> einingar til <p_ny>.".
  • Dersom o_endring verken er mindre enn null eller større enn null:
    • Skriv til skjermen "Overskotet er uendra når talet på produserte einingar blir endra frå <p_no> einingar til <p_ny>.".

b) Koding

Skriv koden til algoritmen ovanfor.

Tips

Her kan du bruke ein if-elif-else-struktur.

Løysingsforslag

def O(x):
     return -0.25*x**2 + 45*x - 500

print("Dette programmet reknar ut skilnaden i kostnader "
"ved å endre produksjonsmengda frå eitt tal til eit anna.")
p_no = int(input("Skriv inn noverande produksjonsmengde: "))
p_ny = int(input("Skriv inn den nye produksjonsmengda: "))
o_endring = O(p_ny) - O(p_no)

if o_endring < 0:
     o_endring = -o_endring
     print(f"Overskotet minkar med {o_endring} kroner når"
     f" talet på produserte einingar blir endra frå"
     f" {p_no} einingar til {p_ny}.")
elif o_endring > 0:
     print(f"Overskotet aukar med {o_endring} kroner når"
     f" talet på produserte einingar blir endra frå"
     f" {p_no} einingar til {p_ny}.")
else:
     print(f"Overskotet er uendra når talet på produserte einingar"
     f" blir endra frå {p_no} einingar til {p_ny}.")

NB: Her har vi late nokre kommandoar med print() gå over to linjer. Det kan vi gjere ved å setje inn ekstra hermeteikn slik som over.

c) Algoritme

Programmet bør kontrollere at brukaren skriv inn tal mellom 0 og 200, som er den største mengda einingar bedrifta kan produsere. Brukaren av programmet må få ein ny sjanse til å skrive inn produksjonsmengda.

Endre på algoritmen ovanfor slik at dette blir oppfylt.

Forslag til algoritme
  • Skriv til skjermen "Dette programmet reknar ut skilnaden i overskot ved å endre produksjonsmengda frå eitt tal til eit anna.".
  • Skriv til skjermen "Skriv inn noverande produksjonsmengde: ".
  • Ta imot talet for produksjonsmengde frå brukaren, og set det lik variabelen p_no.
  • Så lenge p_no er utanfor det tillatne intervallet: Skriv til skjermen "Du må skrive eit positivt, heilt tal som er mindre enn 201. Prøv ein gong til!". Gå attende to steg, og start derifrå.
  • Skriv til skjermen "Skriv inn den nye produksjonsmengda: ".
  • Ta imot talet for ny produksjonsmengde frå brukaren, og set det lik variabelen p_ny.
  • Så lenge p_ny er utanfor det tillatne intervallet: Skriv til skjermen "Du må skrive eit positivt, heilt tal som er mindre enn 201. Prøv ein gong til!". Gå attende to steg, og start derifra.
  • Rekn ut overskotet med talet i variabelen p_ny, og trekk frå svaret på utrekninga av overskotet med variabelen p_no. Set svaret lik variabelen o_endring.
  • Dersom o_endring er mindre enn null:
    • Set o_endring lik minus o_endring.
    • Skriv til skjermen "Overskotet minkar med <o_endring> kroner når talet på produserte einingar blir endra frå <p_no> einingar til <p_ny>.".
  • Dersom o_endring ikkje er mindre enn null, men større enn null:
    • Skriv til skjermen "Overskotet aukar med <o_endring> kroner når talet på produserte einingar blir endra frå <p_no> einingar til <p_ny>.".
  • Dersom o_endring verken er mindre enn null eller større enn null:
    • Skriv til skjermen "Overskotet er uendra når talet på produserte einingar blir endra frå <p_no> einingar til <p_ny>.".
Tips

Her kan det vere kjekt å bruke ei if-setning.

d) Koding

Endre programmet slik at det kontrollerer at brukaren skriv inn tal mellom 0 og 200, som er den største mengda einingar bedrifta kan produsere.

Tips

Her kan du få bruk for kommandoordet while.

Løysingsforslag

def O(x):
     return -0.25*x**2 + 45*x - 500

print("Dette programmet reknar ut skilnaden i kostnader "
"ved å endre produksjonsmengda frå eitt tal til eit anna.")
p_no = -100
p_ny = -100

while p_no <=0 or p_no > 200:
     p_no = int(input("Skriv inn noverande produksjonsmengde: "))
     if p_no <=0 or p_no > 200:
          print("Du må skrive eit positivt, heilt tal som er"
          " mindre enn 201. Prøv ein gong til!")

while p_ny <=0 or p_ny > 200:
     p_ny = int(input("Skriv inn den nye produksjonsmengda: "))
     if p_ny <=0 or p_ny > 200:
          print("Du må skrive eit positivt, heilt tal som er"
          " mindre enn 201. Prøv ein gong til!")

o_endring = O(p_ny) - O(p_no)

if o_endring < 0:
     o_endring = -o_endring
     print(f"Overskotet minkar med {o_endring} kroner når"
     f" talet på produserte einingar blir endra frå"
     f" {p_no} einingar til {p_ny}.")
elif o_endring > 0:
     print(f"Overskotet aukar med {o_endring} kroner når"
     f" talet på produserte einingar blir endra frå"
     f" {p_no} einingar til {p_ny}.")
else:
     print(f"Overskotet er uendra når talet på produserte einingar"
     f" blir endra frå {p_no} einingar til {p_ny}.")

NB: Her har vi late nokre kommandoar med print() gå over to eller tre linjer. Det kan vi gjere ved å setje inn ekstra hermeteikn slik som over.

Kvifor har vi i starten sett variablane p_no og p_ny lik -100?

Relatert innhald

Skrive av Bjarne Skurdal.
Sist fagleg oppdatert 05.08.2020