Start | funktioner
 

Funktioner



Man kan se funktioner som att man bakar ihop kod som man ofta använder och ger denna kod ett namn. Så istället för att skriva samma sak flera gånger, så använder man en funktion. Vill man i framtiden ändra något, behöver man bara ändra på ett ställe. Man kan också se funktioner som återvinning. Det blir mindre kod, risken för fel minskar.

Funktioner kan ta parametrar (dvs att vi skickar med ett värde vid anropet) eller inte, kan returnera något (ger ifrån sig ett värde) eller inte. En funktion som inte returnerar någonting brukar ibland kallas procedur. Kan vara bra veta. Funktioner inuti klasser brukar man kalla metoder. Ibland råkar någon kanske förväxla metod och funktion. Häng inte upp dig på det. Försök förstå hur det fungerar, snarare än vad någon kallar det.

procedur()

En enkel funktion/procedur nedan.
def hej(): print("Denna funktion skriver bara ut lite text") print("----------------------------------------")
Tja, inget händer innan vi anropat vår funktion.
def hej(): print("Denna funktion skriver bara ut lite text") print("----------------------------------------") hej() hej()

y = f(x)

Låt oss öka tempot lite ...

Normalt vill man skicka in någonting i funktionen (input), som används inne i funktionen. Vi kallar variablerna som fångar upp det inskickade för parameter. När vi, vid körning, skickar med en konkret siffra, då kallar vi denna siffra för argument. Oftast vill vi också att något skall komma ut i andra änden (output). Vi kallar det returvärde.


Säg att vi vill skapa en funktion som heter dubbla och den dubblar det vi skickar in. Vi vill att själva funktionen skall returnera ett värde (output), dvs man tänker sig att funktionen kan ersättas med returvärdet.
def dubbla(siffra): return(siffra * 2) print(dubbla(4))
Det som händer här, det är alltså att vi skickar in 4 som argument. I funktionen blir siffra = 4, det är där funktionen startar. Vi dubblar denna siffra i samma veva som vi skickar tillbaka returvärdet. Stirra dig blind på detta exempel, tills det är glasklart.

Funktionen vi skapat kan användas så ofta vi vill, i alla möjliga olika beräkningar.
def dubbla(siffra): return(siffra * 2) x = 4 y = dubbla(x)*dubbla(2)+dubbla(5) print(y)
Nedan funktion tar en poängsumma som argument, 0-50 poäng. Under 20 poäng är underkänt dvs ger 0 i betyg. 20-30 ger 3a, 30-40 ger 4a och 40-50 ger 5a i betyg. Om vi skapar en tuple kan vi också få tydligare om det är underkänt.
skala = ("underkänt","underkänt","underkänt","3","4","5") def betyg(poang): if(poang<20): return(0) if(poang<30): return(3) if(poang<40): return(4) return(5) print("betyg=",betyg(41)) print("betyg=",betyg(18)) print("betyg=",betyg(22)) print() print("betyg=",skala[betyg(41)]) print("betyg=",skala[betyg(18)]) print("betyg=",skala[betyg(22)])

funk(funk(funk(x)))


f(g(x))

Vi kan låta utdata från en funktion vara indata i en annan funktion.

def f(x): return(x * x) def g(x): return(x + 1) print(g(f(3)))
Vad blir svaret nedan ?
def dubbla(siffra): return(siffra * 2) y = dubbla(dubbla(dubbla(dubbla(2)))) print(y)
Säg att vi vill skapa en funktion som konverterar mellan farenheit och celsius.
def far2cel(temp_far): temp_cel = (temp_far - 32) * 5/9 return (temp_cel) print(far2cel(2))
Det finns inbyggda färdiga funktioner. En sådan funktion är round(tal, decimaler). Nedan ger svaret avrundat till 2 decimaler.
def far2cel(temp_far): temp_cel = (temp_far - 32) * 5/9 return (temp_cel) print(round(far2cel(2), 2))
Man kan tilldela funktioner till egna variabler. Så vi kan kidnappa den inbyggda avrundningen och använda vårt egna namn.
avrunda = round def far2cel(temp_far): temp_cel = (temp_far - 32) * 5/9 return (temp_cel) print(avrunda(far2cel(2), 2))
Vi kan konvertera andra vägen från celsius till farenheit också.
def cel2far(temp_cel): temp_far = (temp_cel * 1.8) + 32 return (temp_far) print(cel2far(20))
Fram och sedan tillbaka borde bli samma summa?
def far2cel(temp_far): temp_cel = (temp_far - 32) * 5/9 return (temp_cel) def cel2far(temp_cel): temp_far = (temp_cel * 1.8) + 32 return (temp_far) print(far2cel(cel2far(20)))

många parametrar


Vi kan ha flera olika parameterar i vår funktion. Säg att vi vill skapa en funktion som räknar ut arean om sidorna är x och y.
def area(x,y): return(x*y) print(area(5,6))
Vi kan ge parametrarna defaultvärden (standardvärden) som gäller ifall vi inte använder argumentet.
def summa(x,y=0,z=0): return(x+y+z) print(summa(3,3))

dec2bin


Datorernas inre värld består av 1:or och 0:or, ström på och ström av. Ju närmare maskinnära programmering vi kommer desto mer 1 och 0 blir det.

Vi vill nu omvandla mellan decimaltal och binärt. Hur kan vi göra det? Det finns oftast många sätt att göra samma sak.

Om vi klurar över algoritmen man lär sig i matteboken, så landar man kanske i något sånt här.
def dec2bin(decimal): binary = "" while decimal >= 1: if decimal%2 == 0: binary = "0" + binary else: decimal = decimal -1 binary = "1" + binary decimal = decimal/2 return(binary) print(dec2bin(435))
Om man håller sig vaken på föreläsningar lär man sig kanske något sånt här, som gör samma sak.
def dec2bin(dec): bin = "" while dec > 0: bit = str(dec % 2) bin = bit + bin dec = dec // 2 return bin print(dec2bin(435))

lista som argument


En funktion kan ta en lista, tuple, dictionary eller ett set som argument.
lista1 = [1,2,3,4,5,6] lista2 = [7,8,9,10,11,12] def finns(tal, lst): for t in lst: if(t==tal): return True return False print(finns(3,lista1)) print(finns(3,lista2))
Leta efter maxvärde eller minvärde ...
def maxvarde(lista): max = -9999999999 for tal in lista: if tal > max: max = tal return(max) def minvarde(lista): min = 9999999999 for tal in lista: if tal < min: min = tal return(min) lst = [1,2,3,4,5,6,7,8,9] print(maxvarde(lst)) print(minvarde(lst)) tup = (1,2,3,4,5,6,7,8,9) print(maxvarde(tup)) print(minvarde(tup)) settet = {1,2,3,4,5,6,7,8,9} print(maxvarde(settet)) print(minvarde(settet))


Rekursiva funktioner


En funktion kan anropa sig själv. Det gäller här att hålla tungan i rätt mun, så att det inte blir en evighetsloop.

Vi kan omvandla mellan decimaltal och binärt med en rekursiv algoritm såhär.

1. Om talet är udda eller jämt slutar det på 1 eller 0.
2. Repetera med heltalskvoten av division med 2 av talet.
def dec2bin(dec): if(dec>0): return(str(dec2bin(dec//2))+str(dec%2)) else: return("") print(dec2bin(435))
Låt oss titta på ovan rekursiva funktion steg för steg. Så vi bygger alltså successivt på LSB på talet, där %2 testar om det är udda eller jämt. Vi skickar på nytt in heltalskvoten av division med 2 i dec2bin som gör samma sak. Successivt halveras talet och vi får fram alla bitar.

d2b(435//2) + 435%2 = d2b(217) + 1
d2b(217//2) + 217%2 = d2b(108) +1+1
d2b(108//2) + 108%2 = d2b(54) +0+1+1
d2b(54//2) + 54%2 = d2b(27) +0+0+1+1
d2b(27//2) + 27%2 = d2b(13) +1+0+0+1+1
d2b(13//2) + 13%2 = d2b(6) +1+1+0+0+1+1
d2b(6//2) + 6%2 = d2b(3) +0+1+1+0+0+1+1
d2b(3//2) + 3%2 = d2b(1) +1+0+1+1+0+0+1+1
d2b(1//2) + 1%2 = d2b(1) +1+1+0+1+1+0+0+1+1


Säg att vi vill räkna ut fakulteten, som exempel. En klassisk rekursiv funktion eftersom den faktiskt är begriplig. Fakultet av 5 skrivs 5! = 1*2*3*4*5 som exempel.
def fak(n): if(n==1): return(1) else: return(n*fak(n-1)) print(fak(5))

På hur många olika sätt kan 4 personer ställa sig i en kö?
def fak(n): if(n==1): return(1) else: return(n*fak(n-1)) def personer_i_ko(per): print("{0} pers kan ställa sig på {1} sätt".format(per,fak(per))) print("På hur många sätt kan x personer ställa sig i en kö?") personer_i_ko(2) personer_i_ko(3) personer_i_ko(4)

Permutationer


På hur många olika sätt kan vi välja ut 3 stycken pristagare (guld, silver och brons) i en grupp på 30 personer? Detta problem sorterar under kombinatorik inom matematiken. Vi behöver räkna ut antal permutationer av k personer i en grupp på n.
def fak(n): if(n==1): return(1) else: return(n*fak(n-1)) def per(n, k): return(fak(n)/fak(n-k)) print(per(30, 3))

Kombinationer


Säg att vi bara skall dela ut 3 stycken likadana diplom bland 30 personer, det står "grattis" på diplomet. Hur många grupper på 3 personer kan det skapas?
def fak(n): if(n==1): return(1) else: return(n*fak(n-1)) def per(n, k): return(fak(n)/fak(n-k)) def comb(n, k): return(per(n, k)/fak(k)) print(comb(30, 3))
Wikipedia: Permutations | Combination

lista av funktioner


Vi kan skapa en lista av funktioner!
def dubbla(tal): return(tal*2) def trippla(tal): return(tal*3) def fyrpla(tal): return(tal*4) def fempla(tal): return(tal*5) funktioner = [dubbla,trippla,fyrpla,fempla] x = funktioner[0](35) print(x) print() for i in range(0,len(funktioner)): print(funktioner[i](25))

funktion som parameter


En funktion kan ha en funktion som parameter.
def dubbla(tal): return(tal*2) def min_funktion(funktionen, argumentet): return(funktionen(argumentet)) print(min_funktion(dubbla, 4))

lambda -funktioner

För att förklara poängen med lambda -funktioner, låt oss först titta på ännu ett exempel på funktioner. Nedan ur matteboken, ungefär. Linjens lutning, derivata.



Säg att vi, givet en funktion, t.ex. den rosa linjen här ovan, vill kunna räkna ut denna funktions lutning i en punkt x,f(x)

Dvs, vi skapar en funktion derivata() som tar en funktion som parameter. Sedan räknar vi ut lutningen i punkten x,f(x) för denna funktion.
def derivata(fun, x, h=0.001): return((fun(x+h)-fun(x-h))/(2*h)) def f(x): return(3*x + 5) dx = derivata(f ,2) print(round(dx))
Vi får svaret 3. Verkar rimligt. y = 3x + 5 har lutningen 3. K = 3, typ. y = kx + m

Om vi vill räkna ut lutningen för en annan eller några andra funktioner, så skapar vi bara fler funktioner som vi kan skicka in.
def derivata(fun, x, h=0.001): return((fun(x+h)-fun(x-h))/(2*h)) def f(x): return(3*x + 5) def g(x): return(7*x -6) def h(x): return(-x**2) dx = derivata(f ,2) print(round(dx)) dx = derivata(g ,2) print(round(dx)) dx = derivata(h ,2) print(round(dx,2))

lambda


Det finns en smart möjlighet här, för att slippa skriva nya funktioner, som vi skickar in, och det är att skicka in funktionen direkt!
def derivata(fun, x, h=0.001): return((fun(x+h)-fun(x-h))/(2*h)) dx = derivata(lambda x:3*x+5, 2) print(round(dx)) dx = derivata(lambda x:7*x-6 ,2) print(round(dx)) dx = derivata(lambda x:-x**2 ,2) print(round(dx,2))
Lambda kallas också anonym funktion. Grejen är den, att funktionen behöver ju inget namn. Vi definierar den som argument, det är allt vi behöver. Vi vill bara skicka in den, inget mer.

Det går att skriva lambda -funktioner som tar flera parametrar.
def exekvera_funktionen(f, a, b): return(f(a,b)) resultat = exekvera_funktionen(lambda x,y:x*2+y*3, 5,5) print(resultat)
def exekvera_funktionen(f, a, b): return(f(a,b)) funktionen = "lambda x,y:x*2+y*3" resultat = exekvera_funktionen(eval(funktionen), 5,5) print(resultat)
def exekvera_funktionen(f, a, b): return(f(a,b)) formel = input("Ange en formel med x och y, t.ex. 2*x+10*y") funktionen = "lambda x,y:" + formel resultat = exekvera_funktionen(eval(funktionen), 5,5) print("Om man stoppar i x=5 och y=5 i formeln",formel,"så blir det",resultat)
Du kan också skapa "vanliga" funktioner på detta vis med lambda.
min_fun = lambda x: x*x*x print(min_fun(10))
min_fun = lambda x,y: x*y print(min_fun(5,5))

tentafråga


Skriv en lambdafunktion som tar 2 strängar och returnerar den längsta av dem.
x = "kalle" y= "olle" def test(fun,a,b): print(fun(a,b)) test(lambda x,y:x if len(x)>len(y) else y,x,y)

Lite frågor

Måste en funktion returnera något?
  Nej
  Ja
Måste man skicka med något till funktionen eller kan man anropa såhär min_fun()
  Nej, funktionen måste inte ha parametrar
  Ja, minst en parameter
def f(x=1,y=2,z=3):
    return(x+y+z)
Om vi gör anropet x = f(2), vad blir x ?
  1
  2
  7
  4
lst = [1,2,3,4]
def f(a):
    s = 0
    for t in a:
        s+=t
    return s
Om vi gör anropet x = f(lst), vad blir x ?
  1
  10
  7
  4
def f(f,x):
    return(f(x))
Om vi gör anropet x = f(lambda x:7*x-6,2), vad blir x ?
  4
  1
  8
  7
Vad kallas en funktion som anropar sig själv?
  Abstrakt
  Rekursiv
  Implicit


19.85502243042 ms