onsdag 14 november 2012

Funktioner

Del 2

Funktioner

Funktioner i programmering är en generalisering av funktionsbegreppet från matematiken. Se nedanstående bild där en matematisk definition av f(x) jämförs med motsvarande i Python:
Funktionerna har namnet f, de beror på variabeln x som kallas funktionens argument, och uttrycket definierar funktionen.

För Python gäller
  • Nyckelordet def inleder en funktionsdefinition
  • funktionens namn följs av en parentes med en kommaseparerad lista på argument. En funktion kan ha inga eller flera argument. Satsen avslutas med :
  • Ett block satser utgör koden i funktionen.
  • Satsen return följs av det värde eller objekt som skall returneras av funktionen. Satsen return är ej nödvändig. Om den saknas returnerar funktionen inget.
  • Funktionen avslutas när den når en return-sats eller när sista satsen i det indragna blocket exekverats.

Exempel på funktioner

Bilden ovan visar hur en funktion du känner igen från matematiken definieras i Python. Här följer några andra varianter av funktioner.

Största talet
Returnerar det tal som är störst av två tal a och b.

def storst(a, b) :
    if a > b : return a
    else : return b

Denna funktion har två argument och returnerar ett tal..

Slumpar en tipsrad
Returnerar en sträng "1", "X" eller "2". Obs! funktionen kräver en sats import random i början av filen för att fungera.

def tipsrad() :
    t = random.randint(1,3)
    if t == 1 : return "1  "
    elif t == 2 : return " X "
    else : return "  2"

Denna funktion har inget argument men returnerar en sträng.

Instruktionstext
Skriver ut instruktion till användaren.

def instruktion() :
    print("Välkommen till Månlanda!")
    print("Ditt mål är att landa mjukt.")
    print("Du har begränsad mängd bränsle. Lycka till!")

Denna funktion har varken argument eller returnerar ett värde. Dock är dessa typer av funktioner användbara för att förpacka kod. Antingen för att den ska upprepas på olika ställen i programmet eller för att göra programmet tydligare att läsa.

Rövarspråket
Gör om en text till rövarspråket.

def rovarsprak(text) :
   rt=""
   for c in text.lower() :
       if c in "bcdfghjklmnpqrstvwxz" :
           rt=rt+c+"o"+c
       else :
           rt=rt+c
 return rt

Denna funktion har en sträng som argument och returnerar en annan sträng som byggs upp från argumentet. Funktionen initierar en variabel, rt,  inom funktionen. Se mer om detta nedan.

Att använda funktioner

Före en funktion kan användas måste den vara definierad. Om funktionen i sin tur använder importerade funktioner måste importeringen göras före funktionsdefinitionen. Alltså placeras definitionerna före den kod som refererar till funktionen och efter eventuella importer. En god programstruktur är denna:
  1. importer
  2. globala variabler och konstanter (se nedan)
  3. funktionsdefinitioner
  4. huvudprogrammet
För att anropa en funktion  används funktionens namn följt av de argument man behöver skicka med.

Exempel på program som använder tipsradsfunktionen:

import random

def tipsrad() :
    t = random.randint(1,3)
    if t == 1 : return "1  "
    elif t == 2 : return " X "
    else : return "  2"

print("Tipsrad")
for i in range(13) :
    print(tipsrad())
print("====")

Övning 2.1
Skriv ett program som testar alla funktioner i ovanstående exempel.

Uppgift 2.1
Skriv en funktion som omvandlar temperatur i Fahrenheit till Celsius.

Variablers synlighet och överföring av argument

Variabler har olika synlighet (eng. scope). Det vill säga om de är nåbara från olika delar i programmet. I Python fungerar synligheten för variabler ungefär som tonade rutor i en bil. Variabler i huvudprogrammet är synliga inne i funktionen medan variabler i funktionen inte syns utanför.
  • Variabeln a kallas en global variabel och nås även inne i funktionen för avläsning av värdet ej ändring.
  • Funktionens namn f är synlig både i funktionen och utanför.
  • Argumentet x är en lokal variabel i funktionen och nås inte utifrån
  • Variabeln b initieras i funktionen och är endast nåbar inom funktionen
Om en variabel i en funktion har samma namn som en global så används den lokala variabeln.

Funktionsvariabler och argument raderas ur minnet när funktionen är avslutad. De globala variablerna "lever" under hela programkörningen.

De allra flesta språk har synlighetsregler liknande Python även om skillnader kan förekomma.

Variabler överförs till funktionsargument genom sitt värde. Alltså x i funktionen ovan får värdet 5 om den hade anropats med f(a). Eller med andra ord: när funktionen anropas skapas variabeln x och tilldelas värdet som lagras i a.

Notera: Objekt överförs via referens vilket gör att de hanteras annorlunda. Vi ser på det senare i kursen.

Övning 2.2
Skriv nedanstående program och testa.

a = 5
b = 2

def f(x) :
    a = x
    print("I funktionen a=" + str(a) + " x=" + str(x))

f(b)
print("Utanför funktionen a=" + str(a))

Notera:
Den globala variabeln a behåller sitt värde efter att funktionen returnerat.
Variabeln x får samma värde som b.

Övning 2.3

Varför fungerar inte nedanstående program?

a = 5

def f(x) :
    b = x + a
    print(b)

f(3)
print(b)


Undvik att använda globala variabler i funktioner
Det är lockande att använda globala variabler i funktioner men det bör undvikas om du inte har mycket goda skäl. Poängen med funktioner är att de ska vara återanvändningsbara i olika sammanhang. Om en funktion är beroende av variabler definierade utanför funktionen försvinner den möjligheten. Funktionen i uppgift 11 skulle ha skrivits och anropats enligt nedanstående exempel i ett riktigt program:

a=5
 
def f(x, y) :
    b = x + y
    print(b)

f(3,a) 


Uppgift 2.2
Skriv om programmet i repetitionsuppgift 1.8 så att själva testet om det är ett primtal görs i en funktion som returnerar sant eller falskt.

Överkurs
Python har en variant av anonym funktion (funktion utan namn) som kallas lambda.
Den återfinns även i språket Lisp. Du kan läsa om lambda här.

Inga kommentarer:

Skicka en kommentar