Lektion 5: Mer om funktioner#
Moment: Objekt. Parameteröverföring och returvärden.
Begrepp som introduceras: Föränderliga och oföränderliga objekt.
Arbetssätt: Arbeta gärna tillsammans med någon, men skriv egen kod. Diskutera med varandra! Försök göra övningarna innan du tittar på svaren. Fråga handledarna om det är något svar du inte förstår!
Uppskattad arbetstid: 6 timmar.
Redovisning: Obligatorisk redovisning för lärare/handledare enligt tiderna på kurssidan.
I denna lektion ska vi exemplifiera mycket av det som togs upp i föregående lektion (funktioner) och dessutom ta upp en del nya saker som har att göra med parametrar och returvärden.
Vad menas med objekt?#
I den första lektionen talade vi om ”list-objekt” och i den tredje om
”turtle-objekt”. Det som synligt verkade lite speciellt med dessa var
att det fanns metoder för att påverka objekten (append
för listor
och left
, forward
m.m. för sköldpaddor). Metoder är funktioner
kopplade till individuella objekt.
För att anropa en metod används punktnotation där man framför
punkten anger vilket objekt som åsyftas och efter punkten vilken
metod som avses. Exempel: t.forward(10)
som anger att
det är just den sköldpadda som t
refererar som ska flyttas.
I Python är faktiskt nästan allting objekt (heltal, flyttal, strängar m.m., men även t.ex, funktioner). Det finns alltså metoder knutna även till t.ex. tal.
Prova t.ex. att skriva (1.0).is_integer()
respektive
(1.5).is_integer()
efter >>>
-promptern! Flyttal har alltså metoden
is_integer()
som returnerar True
om flyttalet är ett heltal, annars
False
.
Det finns dock en viktig skillnad mellan å ena sidan t.ex. list- och turtle-objekt och å andra sidan bl.a. heltals- och flyttals-objekt.
Heltals-, flyttals- liksom även t.ex. sträng-objekt är oföränderliga (eng. immutable) medan t.ex. list- och turtle-objekt är föränderliga (eng. mutable). Det har effekter på vad som händer både vid tilldelningar och parameteröverföring.
Vidstående figur illustrerar hur det ser ut när nedanstående kod körts.
t = turtle.Turtle()
u = turtle.Turtle()
x = 3
y = x
|
![]() |
Om vi sedan kör nedanstående rader blir bilden u = t
y = 4
|
![]() |
Eftersom heltal är oföränderliga måste y
få ett nytt objekt med
innehållet 4 (om man kunde ändra 3:an till en 4:a skulle även x
bli 4 -
sannolikt en mycket oönskad effekt…)
Efter tilldelningen u = t
kommer u
och t
att referera till samma objekt.
Det innebär alltså att t.ex. t.forward(100)
och u.forward(100)
gör
precis samma sak, dvs. flyttar på den gröna paddan.
Den röda paddan är borttappad. Den finns fortfarande i datorns minne men vårt program har svårt att komma åt den.
Vid tilldelning av ett värde av oföränderlig typ till en variabel skapas ett nytt objekt.
Vid tilldelning av ett värde av föränderlig typ till en variabel ändras bara referensen - inget nytt objekt skapas.
Vid funktionsanrop fungerar överföringen av argumenten till parametrarna precis som tilldelningar. Det innebär att om vi skickar ett oföränderligt värde till en parameter så spelar det ingen roll vad funktionen gör med parametern. Om parametern tilldelas ett nytt värde kommer det inte ha någon effekt i den anropande koden.
Om vi skickar ett förändringsbart objekt, t.ex. en turtle, till en funktion så kommer allt funktionen gör med parametern synas.
Återbesök i sköldpaddsdammen#
Vi ska nu titta på några funktioner som gör saker med paddor. Det kommer finnas två lite olika typer av funktioner:
Funktioner som ber en viss given padda göra något som det saknas en metod för. Då kan vi skriva en funktion som tar emot en padda som och utför de saker vi vill med den paddan. Om vi själva hade designat paddorna kanske vi hade gjort detta som en metod.
Vi kan också vilja ha paddorna enbart som hjälpmedel för att producera olika geometriska figurer som rektanglar, cirklar, mm. Eftersom vi inte är intresserade av vilken padda som producerar resultatet skickar vi inte med paddan utan låter funktionen själv skapa den! I själva verket behöver vi inte ens veta att funktionen använder paddor för att åstadkomma det vi vill.
Ytterligare turtle
-metoder som kan vara till nytta i denna lektion#
Metod |
Funktion |
---|---|
xcor()
|
Returnerar paddans x-koordinat. |
ycor()
|
Returnerar paddans y-koordinat. |
heading()
|
Returnerar paddans kurs. 0 är x-axelns riktning och 90 är y-axelns riktning. |
setheading(angle)
|
Sätter paddans kurs. 0 är x-axelns riktning och 90 är y-axelns riktning. |
towards(x, y)
|
Returnerar riktningen till punkten ( |
towards(t)
|
Returnerar riktningen till paddan |
distance(x, y)
|
Returnerar paddans avstånd till punkten ( |
distance(t)
|
Returnerar avståndet från den egna paddan till paddan |
Turtlar som parametrar#
Om man vill flytta en padda utan att den ritar ett spår är följande funktion användbar:
def jump(t, x, y):
t.penup()
t.goto(x, y)
t.pendown()
Funktionen tar alltså emot en padda (eller, mer exakt uttryckt, en referens till ett padd-objekt), lyfter dess penna, går till den angivna positionen och sätter ned pennan.
Turtlar som returvärde#
Exempel: make_turtle
När man skapar en padda med turtle.Turtle()
placeras paddan i origo. Om
det är vanligt att vilja ge den en annan startposition kan vi använda:
def make_turtle(x, y):
t = turtle.Turtle()
jump(t, x, y)
return t
Övningar#
Skriv en funktion
rectangle(x, y, width, height, color)
som skapar en padda och målar en rektangel med angiven bredd, höjd och färg. Rektangelns nedre vänstra hörn ska vara i punkten(x, y)
.Svar
def rectangle(x, y, width, height, color): t = make_turtle(x, y) t.hideturtle() t.fillcolor(color) t.begin_fill() for dist in [width, height, width, height]: t.forward(dist) t.left(90) t.end_fill()
Skriv en funktion
tricolore(x, y, h)
som ritar en fransk flagga med nedre vänstra hörnet i punkten (x, y) och höjden h. Proportionerna ska vara 2:3.Svar
def tricolore(x, y, h): w = h/2 # färgfältens bredd rectangle(x, y, w, h, 'blue') rectangle(x+w, y, w, h, 'white') rectangle(x+2*w, y, w, h, 'red')
Skriv funktionen
pentagram(x, y, side)
som skapar en padda och ritar ett pentagram. Toppen ska placeras i punkten(x, y)
. Parameternside
anger längden på linjerna mellan spetsarna.Tips: Vinkeln i toppen är 36 grader.
Svar
def pentagram(x, y, side): t = make_turtle(x, y) t.hideturtle() t.setheading(270 - 36/2) for i in range(5): t.forward(side) t.left(180-36)
Obligatorisk uppgift 1: Prova funktionerna!
Lägg in ovanstående funktioner (jump
, make_turtle
, rectangle
,
tricolore
och pentagram
) i en Python-fil. Modifiera pentagram
så
att den tar emot en parameter för fyllnadsfärg på samma sätt som
rectangle
. Skriv de rader som producerar följande resultat:

Tips:
Om du ger paddan hastigheten 0 (
t.speed(0)
) så går det fortare att rita!Det räcker med 3 rader kod för att rita de 10 pentagrammen. Använd
for
-satser!
Anmärkning: Färgfyllningen av pentagrammen görs på olika sätt i olika Python-versioner. Det är alltså inte fel om det inre blir färgat i stället för ofärgat som i figuren ovan.
Default-värden på parametrar#
Man kan ge parametrar standardvärden (”default-värden”) som gäller om man utelämnar den.
Exempel: Om man deklarerar rectangle
-funktionen så här:
def rectangle(t, x, y, width, height, color=''):
så kan man anropa den så här:
rectangle(0, 0, 50, 50)
|
En ofylld kvadrat (en tom sträng som fyllnadsfärg anger att ingen fyllnad ska ske) |
rectangle(100, 100, 50, 50, 'blue')
|
En kvadrat fylld med blå färg. |
rectangle(100, 100, 50, 50, color='red')
|
En kvadrat fylld med röd färg. Är ett bra sätt om man har flera parametrar med default-värden. |
Övningar#
Lägg till en parameter
visible
till funktionenmake_turtle
med defaultvärdetTrue
. Anropetmake_turtle(x, y)
ska, som tidigare, skapa en synlig padda medan anropetmake_turtle(x, y, visible=False)
liksommakeTurtle(x, y, False)
ska returnera en osynlig padda. Sätt också alltid osynliga paddors hastighet till högsta möjliga medspeed(0)
.Svar
def make_turtle(x, y, visible=True): t = turtle.Turtle() if not visible: t.hideturtle() t.speed(0) jump(t, x, y) return t
Skriv funktionen
random_turtle(side)
som skapar en padda och flyttar den till en slumpmässig plats i en centrerad kvadrat med sidanside
. Paddan ska få en slumpmässig riktning mellan 0 och 359. Parameternside
ska ha defaultvärdet 500.Svar
def random_turtle(side=500): low = -side//2 high = side//2 t = make_turtle(random.randint(low, high), random.randint(low, high)) t.setheading(random.randint(0, 359)) return t
Obligatorisk uppgift 2: Irrande paddor
Skapa filen
dizzyTurtles.py
.Lägg in raderna
import turtle import random
först i filen.
Lägg in funktionerna
jump
ochrectangle
.Skriv funktionen
move_random(t)
som gör en slumpmässig förflyttning av den padda somt
refererar till.Paddans kursen ska först ändras med ett slumpmässigt värde i intervallet [-45, 45]. Om t.ex. paddan har kurs 90 ska kursen sluta i intervallet [45, 135]. Därefter ska paddan gå framåt. Längden på sträckan som paddan går ska vara ett slumptal i intervallet [0, 25].
För att skapa slumpvärden ska funktionen
random.randint(m, n)
användas. Den returnerar ett slumptal mellanm
ochn
(gränserna kan antas).Skriv nu kod som skapar en padda och ritar en centrerad kvadrat genom ett anrop till funktionen
rectangle
. Kvadraten ska ha sidan 500 och fyllas med någon läcker färg (t.ex. ’lightblue’).Flytta paddan (
jump
) till en slumpmässig position inuti den blåa rutan. Nu kan det se ut så här:Skriv nu kod som med hjälp av en
for
-sats gör 250 anrop tillmove_random
. Då kan det se ut så här:Lägg nu till kod i
move_random
som gör så att om paddan efter förflyttningen befinner sig utanför den blå rutan så vänder den sig mot origo. Då kan det se ut så här:Skapa en till padda på slumpmässig plats inuti den blå rutan. Ge paddorna olika färg (metoden
color
).Låt samma
for
-sats flytta båda paddorna. Ändra så attmove_random
-funktionen anropas 500 gånger per padda.Låt den ena paddan skriva ut texten
'close'
om de är närmare varandra än 50 punkter. Metodenwrite(
sträng)
skriver ut strängen i fönstret intill paddan.Låt också programmet räkna och sedan skriva ut hur många gånger det var nära.
Allmänna frågor#
Vilka datatyper har du hittills sett i Python?
Svar
int
,float
,str
,bool
,list
,tuple
ochturtle
Vad är det för skillnad på uttrycken
2
och"2"
?Svar
Den första har typen
int
och den andra typenstr
.Vad skrivs ut av satsen
print(int(1.8))
?Svar
Prova och förklara resultatet!
Hur gör man för att se vilka funktioner som finns i modulen
math
? Visa!Svar
dir(math)
Vad är skillnaden mellan en funktion och en metod?
Svar
En metod hör till ett objekt vilket inte en funktion (normalt) gör.
Vad är en parameter?
Svar
En parameter är en variabel som nämns i funktionsdefinitionen. När funktionen anropas får parametern värde från motsvarande argument.