Föreläsning 4
Funktioner och scope, moduler, importer och rekursion
Dagens agenda
Funktioner
Kapitel 5 i Möbius
På återbesök i telefonboken
Problem med koden
Den är:
En del av lösningen
FUNKTIONER!
Vad är en funktion?
Fördelar med funktioner
Delar in koden i mer lätthanterliga delar
Ett kodstycke som:
Funktioner är ett exempel på abstraktion
🡪 vi gömmer funktionalitet i funktioner så att koden blir mer lättläst.
Inbyggda funktioner
Python har flera funktioner som vi kan använda utan att vi behöver skapa dem själv. Vi har redan använt följande exempel:
Exempel:
I Pythons dokumentation kan ni hitta alla inbyggda funktioner:
Definiera en funktion
def skriv_ut_hej():
print("Hej") #Koden i funktionen
Funktionshuvud
Definition
Funktionsnamn
Viktigt med indenteringen
Den koden som är indenterad efter definitionshuvudet hör till funktionen.
Nu har du definierat funktionen, talat om att den finns och vad som ska hända om den körs.
Men den kommer inte köras utan att du ber om det!
Anropa en funktion
def skriv_ut_hej():
print("Hej")
skriv_ut_hej()
Anrop
Om du inte anropar funktionen så körs den inte
Anropa en funktion flera gånger
def skriv_ut_hej():
print("Hej")
for i in range(3)
skriv_ut_hej()
Funktionen skriv_ut_hej kommer köras 3 gånger!
Parametrar
def hälsa(namn):
print("Hej", namn)
hälsa("klassen")
Parameter
Kan användas i funktionen
Anpassar funktionens beteende
Parametrar ger dig mer kontroll över funktionen.
Skickas in i funktionen
Returvärden
def kvadrera(tal):
kvadrat = tal * tal
return kvadrat
kvadrat = kvadrera(3)
Returvärdet skickas tillbaka efter att funktionen körts.
Returvärden ger dig tillgång till resultatet av funktionen.
Spara returvärdet i en variabel så att du kan använda det senare.
Hur ska vi kalla på denna funktion?
Tänk på vilken typ av parameter och returvärde du har och spara returvärdet!
Fler parametrar
def summera(tal1, tal2):
summa = tal1 + tal2
return summa
summan = summera(2, 3)
Parameter 1
Du måste skicka in alla parametrar när du kallar på funktionen
Parameter 2
Det är upp till dig att bestämma hur många parametrar du vill definiera din funktion med.
Fler returvärden
def summera_och_multiplicera(tal1, tal2):
summa = tal1 + tal2
produkt = tal1 * tal2
return summa, produkt
summa, produkt = summera_och_multiplicera(2, 3)
Vi kan returnera fler värden med hjälp av ,
Se till att spara båda returvärdena!
Är det något konstigt med de här funktionsanropen?
print("Hej")
namn = "Tomten",
print("Hej", namn + "!")
namnlista = ["Tomten", "Rudolf", "Tomtemor"]
for namn in namnlista:
print(namn, end = " ")
Vi har skickat in olika många parametrar i print()
Default-parametrar
def summera(tal1, tal2, tal3 = 0):
summa = tal1 + tal2 + tal3
return summa
�tal1 = int(input("Tal 1: "))
tal2 = int(input("Tal 2: "))
tal3 = int(input("Tal 3: "))
print(addera(tal1, tal2))
print(addera(tal1, tal2, tal3))
Det går att anropa summera med både två och tre parametrar
Defaultvärde om inget anges
Namnge funktioner
Funktioner ska följa samma namngivningskonvensioner som variabler!
Det är vanligt att använda verb i funktionsnamn för att tala om vad funktionen gör!
Uppgift:
Namnge funktionen och variablerna så att programmet blir tydligare!
Kommentera funktioner
Docstring
Lägg till en flerradskommentar högst upp i funktionen som talar om vad funktionen gör och vad den har för in och utdata!
Flerradskommentar med 3 citattecken!
Om du håller musen över funktionsnamnet så visas docstringen!
Scope
🏡
Var bor våra variabler?
Lokala och globala variabler
kvadrat är en lokal variabel som bara kan användas i funktionen.
tre_kvadrat är en global variabel och kan användas överallt (efter rad 5) i koden.
Globala variabler är definierade
Utanför funktioner
Globalt scope
Lokalt scope
Lokal kod
Global kod
Global kod
Huvudfunktionen – ett huvudprogram
def summera(tal1, tal2):
summa = tal1 + tal2
return summa
def main():
summa1 = summera(2, 3)
summa2 = summera(4, 5)
tot_summa = summera(summa1, summa2)
main()
Huvudprogrammet – main()
Gör det enkelt att se vad huvudfunktionen i programmet är!
Glöm inte att anropa main()!
På återbesök i telefonboken
Moduler
Kapitel 6 i Möbius
Moduler
Exempel
Du kan läsa om alla inbyggda moduler i Pythons dokumentation: https://docs.python.org/3/library/
Det finns en hel del inbyggda bibliotek eller moduler i python som vi kan använda istället för att skriva egna. T.ex:
Att importera en modul
import math
from random import randint
from math import *
Om vi vill använda en funktion i en modul måste vi först importera den modulen.
Det kan vi göra på flera sätt:
importerar hela math modulen
importerar funktionen randint från modulen random
importerar allt från modulen math
Att använda en funktion från en modul
import math
print(math.sqrt(4))
print(math.pi)
print(math.pow(3, 4))
sqrt() är en funktion i math som beräknar roten ur
En konstant pi, definierad i modulen
pow() är en funktion i math som beräknar upphöjt i
Ett annat sätt att göra samma sak
from math import *
print(sqrt(4))
print(pi)
print(pow(3, 4))
import math
print(math.sqrt(4))
print(math.pi)
print(math.pow(3, 4))
Vi har importerat ALLT i math-modulen så vi behöver inte specificera att vi vill använda sqrt() som finns i math (math.sqrt())
Vad är skillnaden?
Random
from random import randint
slag1 = randint(1,6)
slag2 = randint(1,6)
print("Du slog " + str(slag1) + " och " + str(slag2) + " på tärningarna")
Här finns olika funktioner för att generera pseudoslumptal. Användbart om vi vill t.ex. simulera en tärning:
Observera att vi inte behöver skriva random.randint()!
Mycket bättre att bara importera den/de funktioner som du behöver istället för att importera allt med *
Ett finare program
from random import randint
�def tärningsslag():
print("Du slog: " + str(randint(1,6)))
�def main():
antal_slag = int(input("Hur många gånger vill du slå? "))
for i in range(antal_slag):
tärningsslag()
main()
Alltid högst upp!
Importera moduler med långa namn
import matplotlib.pyplot as plt
Import modul as smeknamn
För att slippa behöva skriva långa modulnamn när vi programmerar kan vi använda ordet as.
Matplotlib är ett jättestort bibliotek som innehåller många moduler. Om vi vill importera modulen pyplot så måste vi skriva:
matplotlib.pyplot
Det är vanligt att kalla pyplot för plt men du kan välja vad du vill
OBS. du behöver installera matplotlib för att kunna importera modulerna!
Installera moduler
pip install library_name
Moduler som inte finns i pythons standardbibliotek (de som kommer med när du installerar python) måste installeras!
Detta gör du i terminalen genom att använda programmet pip med kommandot install, se rutan nedan!
Om det inte funkar, testa att skriva:
sudo pip install library_name
Bonus modul: colorama
Printa i färg med colorama biblioteket!
Importera colorama:
pip install colorama
Skapa egna moduler
Modulen tärning
from tärning import tärningsslag
�def main():
antal_slag = int(input("Hur många gånger vill du slå? "))
for i in range(antal_slag):
tärningsslag()
main()
from random import randint
def tärningsslag():
print("Du slog: ", end= " ")
print(randint(1,6))
tärning.py
Nu importerar vi från en egen fil!
Hjälpfunktioner i en separat fil
Vår egna modul som vi importerar i spela_tärning.py
if __name__ == "__main__":
if __name__ == "__main__":
"""Kod som du bara vill ska köras om du explicit talar om för python att du vill köra den här filen (inte om du importerar från den till en annan fil)"""
Detta läggs ALLTID sist i filen!
Det går bra att hoppa över detta, men det är smidigt om du vill provköra filen som du ska importera och det är ganska vanligt att inkludera detta i python-kod.
Denna rad körs bara om vi kör tärning.py, dvs.�python3 tärning.py
Varför vill vi undvika globala variabler?
Det gör det mycket svårare att hålla koll på hur programmet beter sig.
Rekursion
Kapitel 6 i Möbius
Rekursion
def beräkna_fakultet(n):
if n == 1: # Basfall
return 1
else:
return n * beräkna_fakultet(n-1) # Rekursions-steg
En funktion som anropar sig själv
VIKTIGT: Det måste finnas ett basfall där funktionen returnerar ett värde
Vad händer om du anropar beräkna_fakultet(4)?
Gå igenom rad för rad!
Rekursiv fibonacci
Loopa fibonacci
Är någon bättre?
Rekursiva fibonacci: beräkna fib(5)
5
4
3
1
3
2
1
2
0
1
0
2
1
1
0
Alla talen under 5 behöver returneras från funktionen!
Den rekursiva fibonacci-lösningen blir snabbt mycket sämre än loopen!
Rekursion ersätter inte iteration (loopar)!!!
def meny():
val = input("Ange siffra 1-3")
while val != "3":
if val == "1":
print("Du valde 1.")
elif val == "2":
print("Du valde 2.")
else:
print("Välj om!")
val = input("Ange siffra 1-3")
print("Du valde 3. Hejdå!")
def meny():
val = input("Ange siffra 1-3")
while val != "3":
if val == "1":
print("Du valde 1.")
elif val == "2":
print("Du valde 2.")
else:
print("Välj om! ")
meny()
NEJ!!!!
Labb 1
Sten, sax, påse
Deadline: Fredag 10/11