Funktioner Linda Mannila
Vad kan vi nu? Primitiva datatyper Tal, strängar, booleska värden Samlingsdatatyp Listan Utskrift Indata Felhantering Intro till funktioner och moduler Villkorssatsen if Looparna for och while
Denna föreläsning Egna funktioner och moduler
grattis_v1.py print "Happy Birthday to you!" print "Happy Birthday, dear Emma." print "Happy Birthday to you!"
Vad är en funktion? Ett miniprogram inne i ett program min_funktion IndataUtdata
grattis_v2.py def grattis_emma(): print "Happy Birthday to you!" print "Happy Birthday, dear Emma." print "Happy Birthday to you!" Funktionshuvud Funktionskropp Definierar en ny funktion: ger betydelse till namnet grattis_emma
grattis_v2.py def grattis_emma(): print "Happy Birthday to you!" print "Happy Birthday, dear Emma." print "Happy Birthday to you!“ Testkörning: Inget händer...?
Att använda funktioner Att definiera en funktion är som att skapa en variabel – den finns där för framtida bruk, men man måste explicit säga när man vill använda den När man använder en funktion säger man att man anropar den Anropet består av funktionens namn följt av en parentes Om vi bara anger funktionens namn utan parenteser tror Python att vi vill få information om den >>> grattis_emma >>> grattis_emma() Happy Birthday to you! Happy Birthday, dear Emma. Happy Birthday to you! >>>
grattis_v3.py def grattis_emma(): print "Happy Birthday to you!" print "Happy Birthday, dear Emma." print "Happy Birthday to you!“ grattis_emma() Testkörning: Happy Birthday to you! Happy Birthday, dear Emma. Happy Birthday to you! Happy Birthday, dear Emma. Happy Birthday to you!
grattis_v4.py def grattis_emma(): print "Happy Birthday to you!" print "Happy Birthday, dear Emma." print "Happy Birthday to you! " def grattis_bo(): print "Happy Birthday to you!" print "Happy Birthday, dear Bo." print "Happy Birthday to you!"
grattis_v5.py def grattis_emma(): print "Happy Birthday to you!" print "Happy Birthday, dear Emma." print "Happy Birthday to you! " def grattis_bo(): print "Happy Birthday to you!" print "Happy Birthday, dear Bo." print "Happy Birthday to you!“ def main(): grattis_emma() print grattis_bo() main()
Att ge indata till en funktion Funktioner blir mer användbara om man kan ge dem indata T.ex. en funktion som beräknar en rektangels area -> mer användbart att i anropet kunna ange längden på sidorna i stället för att ha en funktion som beräknar arean av samma rektangel (t.ex. med sidorna 6 och 7) De data en funktion vill ha som input när den anropas, definieras i funktionshuvudets parameterlista
grattis_v6.py def grattis(person): print "Happy Birthday to you!" print "Happy Birthday, dear %s.” % person print "Happy Birthday to you! " def main(): grattis(”Emma”) print grattis(”Bo”) main() Parameter Argument Parametrar är platshållare för verkliga värden Parametrar kallas också formella parametrar Argument kallas också aktuella parametrar
grattis_v7.py def grattis(person): print "Happy Birthday to you!" print "Happy Birthday, dear %s." % person print "Happy Birthday to you!" def main(): namn = raw_input("Mata in födelsedagshjältens namn: ") grattis(namn) main() När funktionen grattis anropas får parametern person det värde som namn har Alltså: parametern får argumentets värde!
Allmänna riktlinjer Ofta bra att separera den interna dataprocesseringen från interaktionen med användaren med hjälp av funktioner. T.ex. i grattis_v7.py sköts interaktionen i main medan data manipuleras i grattis Ett argument (en aktuell parameter) kan vara ett uttryck. I sådana fall evalueras uttrycket före det skickas till funktionen. En variabel är det enklaste exemplet på ett uttryck – då en variabel skickas som parameter till en funktion evalueras den så att den byts ut mot dess värde. Eftersom det bara är värdet på argumentet/den aktuella parametern som skickas med – inte själva namnet – är det helt ok att den aktuella och formella parametern har olika namn. I det här exemplet heter den formella parametern person medan den aktuella heter namn.
grattis_v8.py def grattis(fornamn, efternamn): print "Happy Birthday to you!" print "Happy Birthday, dear %s %s." % (fornamn, efternamn) print "Happy Birthday to you!" def main(): fnamn = raw_input("Mata in födelsedagshjältens förnamn: ") enamn = raw_input(“Mata in födelsedagshjältens efternamn: “) grattis(fnamn, enamn) main() Flera parametrar Separeras med kommatecken både i funktionshuvudet och anropet
Indatafel i funktioner Att anropa en funktion utan att sända med de indata den kräver (argument, parametrar), resulterar i ett fel, t.ex: Att sända argument till en funktion som inte skall ha några parametrar Att inte sända argument till en funktion som kräver indata Att sända argument av fel typ Att sända fel antal argument till en funktion Att sända rätt antal argument till en funktion men i fel ordning
Fel! def inkrementera(tal): print tal + 1 >>> inkrementera() # inget argument Traceback (most recent call last): File " ", line 1, in -toplevel- inkrementera() TypeError: inkrementera() takes exactly 1 argument (0 given) >>> inkrementera(3,4) # fel antal argument Traceback (most recent call last): File " ", line 1, in -toplevel- inkrementera(3,4) TypeError: inkrementera() takes exactly 1 argument (2 given)
Hur fungerar funktioner? När en funktion anropas övergår Python till att köra den kod som finns i funktionskroppen Ifall anropet innehåller argument kopieras de in som parametrar till funktionen Det är som om man satte in funktionkroppens satser i det anropande programmet på den plats där funktionen anropades. Om funktionen returnerar ett värde, returneras värdet till det anropande programmet när funktionen körts till slut. Det anropande programmet fortsätter där det slutade, dvs. med den sats som kommer efter funktionsanropet.
Funktionsanrop Varje avlång stapel representerar en Python-sats min_funktion(arg) def min_funktion(par): Funktionen anropas Funktionen avslutas Kontrollen överförs
Att använda resultat från funktioner Alla funktioner vi skrivit hittills har skrivit ut resultatet på skärmen direkt Ofta vill man använda resultatet från en funktion någon annanstans i programmet Jfr. matematik f(x) = 2x 2 + 3x 4*f(3) = 4 * (2*9 + 3*3) = 4 * 27 = 108 Vi använder resultatet av funktionen f i en annan beräkning (f(3))
Att använda resultat från funktioner Motsvarande kod i Python: def f(x): svar = 2*(x**2) + 3*x uttryck = 4*f(3) print uttryck Men - hur få resultatet från funktionen f till beräkningen av uttryck ?
Retursatser Entré nyckelordet return def f(x): svar = 2*(x**2) + 3*x return svar uttryck = 4*f(3) print uttryck
Jämför Båda programmen använder funktioner skriver ut något Men utskriften sker på olika ställen I p1 sker utskriften i det anropande programmet (dvs. på den yttre nivån) I p2 skrivs resultatet ut direkt inne i funktionen p1.py def f(x): svar = 2*(x**2) + 3*x return svar uttryck = 4*f(3) print 'f', uttryck p2.py def g(x): svar = 2*(x**2) + 3*x uttryck = 4*svar print 'g', uttryck g(3)
Alla funktioner returnerar något Vi testar att skriva ut resultatet av ett anrop till en funktion som inte innehåller någon retursats Den önskade utskriften sker fortfarande inne i funktionen Dessutom får vi en extra utskrift: None Även om h -funktionen inte explicit returnerar något (dvs. vi har inte skrivit in någon retursats) får vi ändå ett returvärde ( None ) Detta gäller för alla funktioner – Python gör så att varje funktion returnerar något – om inget annat angivits, så returneras None Detta är ett vanligt fel – om du får ett None i en utskrift där du inte förväntat dig det kan det hända att du försökt komma åt ett returvärde för en funktion som inte explicit returnerar något. p3.py def h(x): svar = 2*(x**2) + 3*x uttryck = 4*svar print ’h', uttryck print h(3)
Funktioner med returvärden def ink (tal): return tal + 1 >>> ink(19) # Inget händer >>> resultat = ink(19) # Inget synligt händer >>> print resultat 20
Att använda returnerade värden Returvärdet kan tilldelas till en variabel ord_langd = len("Hej") Returvärdet kan skrivas ut print “Hej har %d tecken“ % len("Hej") Returvärdet kan sändas som argument till en annan funktion min(len("Hello"), len("Hi"))
Exempel >>> length = len('How long am I?') >>> print length 14 >>> ord = "Filifjonka" >>> print “%s innehåller %d tecken” % (ord, len(ord)) Filifjonka innehåller 10 bokstäver
Funktionsanrop med return Varje avlång stapel representerar en Python-sats resultat = min_funktion() def min_funktion(): Funktions- anrop Funktionen avslutas och returnerar värdet X. Detta värde tilldelas variabeln resultat, dvs. variabeln resultat har härefter värdet X. return X Kontrollen överförs
Att använda funktioner Den som använder en redan existerande funktion behöver känna till: Funktionens namn Parametrarna (deras antal, ordning och typ) Vad som returneras eller vad resultatet av funktionen är
Variabler med samma namn Vad händer om en variabel i en funktion ges samma namn som en annan variabel som används på annan plats i programmet, utanför funktionen?
Vilka värden har summa ? def add_one(x): summa = x+1 print 'Inne i funktionen: summa =', summa summa = 9 add_one(9) print 'Utanför funktionen: summa =', summa Provkörning Inne i funktionen: summa = 10 Utanför funktionen: summa = 9
Variablers räckvidd (scope) Lokala variabler Variabler som initialiseras och används inne i en funktion är osynliga utanför funktionen och för andra funktioner Gäller också parametrar Existerar bara lokalt inne i funktionen – kan inte ses eller användas utanför den Tänk på funktioner som stängda lådor som det anropande programmet inte kan se in i – det anropande programmet vet inte vad som händer inne i en funktion Globala variabler variabler som används på yttersta nivån, utanför funktioner och andra strukturer Det är dålig programmeringsstil att referera till globala variabler inne i en funktion – använd i stället parametrar och returvärden
Exempel def add_one_bad(): print sum + 1 def add_one_ok(x): print x + 1 sum = 9 add_one_bad() add_one_ok(sum) Provkörning: 10
Exempel def main(): x = 3 minfunktion () def minfunktion(): print x # minfunktion känner inte till x main() Traceback (most recent call last): File "localscope.py", line 8, in main() File "localscope.py", line 3, in main minfunktion () File "localscope.py", line 6, in minfunktion print x # minfunktion känner inte till x NameError: global name 'x' is not defined >>>
Använd parametrar och returvärden Om du vill använda lokala data från en funktion i en annan använd parametrar: Kom ihåg att parametern och argumentet inte behöver ha samma namn, dvs. funktionsdefinitionen kunde lika väl ha sett ut så här: def main(): x = 3 minfunktion (x) def minfunktion(x): print x main() def minfunktion(whatever): print whatever
Dokumentera Använd dokumentationssträngar för att dokumentera dina funktioner Förklara vad funktionen gör i en lång kommentar (tredubbla citattecken) som kommer genast efter funktionshuvudet, dvs. efter raden som börjar med def Varför? Används för att generera dokumentation automatiskt Ser snart exempel på hur!
Exempel hej.py hejAlternativ.py inkrement.py fitness_wo_functions.py fitness.py
Exempel def hej (): ’’’Skriver hej på skärmen’’’ print “Hej” >>> hej() Hej >>> help(hej) Help on function hej in module __main__: hej() Skriver hej på skärmen
Ett till… def skriv_rad(): ’’’Skriver ut en rad på skärmen’’’ print ' ' >>> skriv_rad() >>> help(skriv_rad) Help on function skriv_rad in module __main__: skriv_rad() Skriver ut en rad på skärmen
Att skapa egna moduler Varje program är en modul! ’’’ hello.py Linda Mannila Programmet skriver ut Hello World på skärmen ’’’ print ’Hello World’
Att använda egna moduler >>> import hello Hello World >>> help(hello) Help on module hello: NAME hello FILE c:\hello.py DESCRIPTION hello.py Linda Mannila 2007 Programmet skriver ut Hello World på skärmen
Egen modul med funktioner ''' fitness.py Linda Mannila 2007 A collection of fitness related functions. ''' def bmi(length, weight): '''Calculates the body mass index (bmi). Length in meters, weight in kg.''' print weight/(length**2) def waistHip(waist, hip): '''Calculates the waist-hip-ratio''' print waist/hip def maxHeartRate(age): '''Estimates the maximum heart rate (MHR)''' print 220-age def VO2(distance): '''Estimates VO2 based on the Cooper test result''' print (distance-504.9) / 44.73
Att använda egna moduler med funktioner >>> import fitness >>> help(fitness) Help on module fitness: NAME fitness FILE \proggk07\forel11\kodexempel\fitness.py DESCRIPTION fitness.py Linda Mannila 2007 A collection of fitness related functions. FUNCTIONS VO2max(distance) Estimates VO2 max based on the ran distance in a Cooper test bmi(weight, length) Calculates the body mass index (bmi). Length in meters, weight in kg. maxHeartRate(age) Estimates the maximum heart rate (MHR) waistHip(waist, hip) Calculates the waist-hip-ratio >>> fitness.bmi(78, 1.75)