Föreläsning 9
Repetition och utvidgning
1
Dagens agenda
2
Listor
3
Påminnelse: Listor kopieras inte automatiskt!
4
djurlista = ['katt', 'hund', 'kanin']
ny_djurlista = djurlista
ny_djurlista.append('snigel')
print(djurlista)
Vad kommer skrivas ut här?
Listreferenser (pekare)
5
djurlista = ['katt', 'hund', 'kanin']
ny_djurlista = djurlista
djurlista |
['katt', 'hund', 'kanin'] |
ny_djurlista |
|
ny_djurlista innehåller inte djurlistan utan en referens (eller pekare) till djurlistan. På så sätt skapas inga kopior av listor!
print(id(djurlista))
print(id(ny_djurlista))
Du kan se att båda listorna är sparade på samma plats i minnet med hjälp av id()
Att kopiera listor…
6
Varför vill vi undvika att kopiera listor?
Det behövs sällan! Ofta vill du ha en korrekt lista så det är bättre att uppdatera orginallistan.
Undvik detta!
Men varför…?
Enkla och sammansatta datatyper
Enkla datatyper
8
Datatyp | Förkortning | Exempel |
Heltal | int | ålder = 13 |
Decimaltal | float | längd = 1.63 |
Strängar | str | namn = ’Samira’ |
Boolean | bool | vaccination_stelkramp = True |
NoneType | | betyg = None |
Datatyper som bara innehåller ett värde
values
Sammansatta datatyper
9
Datatyp | Förkortning | Exempel |
Lista | list | namn_lista = [’Fia’, ’Ada’, ’Fia’] |
Dictionary | dict | åldrar = {’Fia’ : 7, ’Ada’ : 6 } |
Set | set | unika_namn = {’Fia’, ’Ada’} |
Tuppel | tuple | student_info = (’Fia’, 7) |
(Egna klasser) | | ny_elev = Elev(’Ali’, 6) |
Datatyper som innehåller flera värden
Pass by value
Mer komplexa sammansatta datatyper
10
Sammansättningar (exempel) | Pythonexempel |
Lista med listor | listlista = [[’Fia’, 7], [’Ada’, 6]] |
Lista med dictionaries | elever = [{’namn’ : ’Fia’, ’ålder’ : 7}, � {’namn’ : ’Ada’, ’ålder’ : 6 }] |
Dictionary med listor | elever = {’Fia’ : [7, 1.23], � ’Ada’ : [6, 1.31]} |
Lista med objekt | elevlista = [elevobjekt1, elevobjekt2] |
Sammansatta som innehåller sammansatta datatyper
Pass by reference
Vad kommer vi åt var?
11
class Elev:
def __init__(self, namn, ålder):
self.namn = namn
self.ålder = ålder
�def __str__(self):
return 'Namn: ' + self.namn + '\nÅlder: ' + str(self.ålder)
��# Skriv ut ett elevobjekt sparat i en enkel variabel
elevobjekt = Elev('Elvira', 5)
print(elevobjekt)
�# Skriv ut ett elevobjekt sparat i en lista
elevlista = [elevobjekt]
print(elevlista)
Vad kommer skrivas ut här?
__str__() kommer inte åt objekt sparade i sammanasatta datastrukturer
12
elevobjekt =
Använd __repr__() istället i dessa fall!
elevlista =
Elev('Elvira', 5)
Elev('Elvira', 5)
print kommer inte åt __str__ innanför listan…
Kopiera sammansatta datastrukturer med modulen copy
13
import copy
�djurlista = ['katt', 'hund', 'kanin']
ny_djurlista = copy.copy(djurlista)
ny_djurlista.append('snigel')
print(djurlista)
print(ny_djurlista)
Använd __repr__() istället i dessa fall!
Kopiera sammansatta datastrukturer med modulen copy
14
import copy
�elevlistlista = [['Fia', 7], ['Ada', 6]]
ny_elevlistlista = copy.copy(elevlistlista)
ny_elevlistlista.append(['Linus', 7])
�# Skriv ut den gammla och nya elevlistlistan
print(elevlistlista)
print(ny_elevlistlista)
Vad kommer att hända i dessa två fall?
ny_elevlistlista[0].append(3)
�# Skriv ut den gammla och nya elevlistlistan
print(elevlistlista)
print(ny_elevlistlista)
Grund vs. djup kopia
15
Objekt1
namn: ’Fia’
ålder: 7
Objekt2
namn: ’Ada’
ålder: 6
Objekt3
namn: ’Ali’
ålder: 6
Shallow copy (bara copy) skapar en kopia av listan, men inte av de sammansatta elementen i listan. En grundkopia av listan till höger skulle se ut så här:
copy.copy()
copy.deepcopy()
Deep copy skapar en kopia av listan och de sammansatta elementen i listan. En djupkopia av listan till vänster skulle alltså vara en ”äkta” kopia av listan.
Kopiera sammansatta datastrukturer med deepcopy (modulen copy)
16
import copy
�elevlistlista = [['Fia', 7], ['Ada', 6]]
ny_elevlistlista = copy.deepcopy(elevlistlista)
ny_elevlistlista.append(['Linus', 7])
�# Skriv ut den gammla och nya elevlistlistan
print(elevlistlista)
print(ny_elevlistlista)
ny_elevlistlista[0].append(3)
�# Skriv ut den gammla och nya elevlistlistan
print(elevlistlista)
print(ny_elevlistlista)
Vad skrivs ut?
17
import copy
�class Elev:
def __init__(self, namn, ålder):
self.namn = namn
self.ålder = ålder
�def __str__(self):
return 'Namn: ' + self.namn + '\nÅlder: ‘ + str(self.ålder)
�elev1 = Elev('Mimmi', 10)
elev2 = Elev('Musse', 10)
elevlista = [elev1, elev2]
�ny_elevlista = copy.copy(elevlista)
ny_elevlista[0].ålder = 11
�for elev in elevlista:
print(elev)
Vad skrivs ut?
18
import copy
�class Elev:
def __init__(self, namn, ålder):
self.namn = namn
self.ålder = ålder
�def __str__(self):
return 'Namn: ' + self.namn + '\nÅlder: ‘ + str(self.ålder)
�elev1 = Elev('Mimmi', 10)
elev2 = Elev('Musse', 10)
elevlista = [elev1, elev2]
�ny_elevlista = copy.copy(elevlista)
ny_elevlista.append(Elev('Kalle', 9))
�for elev in elevlista:
print(elev)
Komma åt strängrepresentationen av objekt sparade i en sammansatt datatyp
19
class Elev:
def __init__(self, namn, ålder):
self.namn = namn
self.ålder = ålder
�def __repr__(self):
return self.namn + ' ' + str(self.ålder) + ‘ år.'
elevobjekt1 = Elev('Elvira', 5)
elevobjekt2 = Elev('Rufus', 5)
elevlista = [elevobjekt1, elevobjekt2]
print(elevlista)
Vad kommer skrivas ut här?
Vad har gått snett här?
20
def meny():
print('Välkommen till telefonboken. Här är dina val: ’\
’\n1. Lägg till en kontakt’\
’\n2. Sök efter en kontakt’\)
val = input('Vad vill du göra (ange en siffra 1-3)? ')
if val == '1’:
print('Här kommer en kontakt att läggas till.’)
meny()
elif val == '2’:
print('Här kommer du att kunna söka efter en kontakt')
meny()
�meny()
Bortse från att va 1 och 2 inte är implementerade.
NEJ! Rekursiva anrop till menyn!
Vad har gått snett här?
21
djurlista = ['katt', 'hund', 'kanin', 'apa', 'ödla']
stor_djurlista = []
�for djur in range(len(djurlista)):
stor_djurlista.append(djur.capitalize())
�print(stor_djurlista)
Variabler i for-slingor!
22
grönsaker = [’gurka’, ’tomat’, ’majs’]
for i in grönsaker:
print(i)
grönsaker = [’gurka’, ’tomat’, ’majs’]
for grönsak in range(len(grönsaker)):
print(grönsak)
Vad kommer att skrivas ut?
Vad kommer att skrivas ut?
NOOOO!!!!!
Bättre variabler i for-slingor!
23
grönsaker = [’gurka’, ’tomat’, ’majs’]
for grönsak in grönsaker:
print(grönsak)
grönsaker = [’gurka’, ’tomat’, ’majs’]
for i in range(len(grönsaker)):
print(i)
Nu är det mycket lättare att se om du vill skriva ut (printa) ett index eller själva elementet i listan.
f-strängar
Ett alternativt sätt att skriva ut strängar
25
Vi har tittat på två sätt att printa() strängar på:
F-strängar är ett tredje alternativ som är väldigt smidigt!� namn = ”Rudolf”� print(f”God jul {namn}”)
Stoppa in alla värden inom måsvingar {} inuti strängen!
Formaterade strängar
Fler f-strängar
26
class Katt:
def __init__(self, namn, ålder):
self.namn = namn
self.ålder = ålder
self.ben = 4
�def __str__(self):
return f"{self.namn} är {self.ålder} år gammal."
katt1 = Katt('Chossan', 14)
print(katt1)
F-strängar kan användas i andra sammanhang än print
Användarvänlig utdata
27
Kopplat till användning av print och input
Tydlig utdata för användaren
28
Testkör ditt program!
29
Det är lätt att missa att något skulle kunna vara otydligt i sitt eget program, därför är det viktigt att även låta någon annan testa programmet!
Denna person skulle kunna vara:
Du måste självklart testköra dina program många gånger!
Hur programmet testköras?
30
Det är inte alltid som du har tillgång till någon som kan testköra så ta vara på tillfället och var uppmärksam!
Klasser med fler metoder
31
Studentklassen
class Student:
betygs_konvertering = { 'F’: 0, 'E': 3, 'D': 3.5, 'C': 4, 'B': 4.5, 'A': 5 }
�def __init__(self, namn, ålder):
self.namn = namn
self.ålder = float(ålder)
self.betyglista = []
self.__tot_betyg = 0 # Privat attribut (går inte att komma åt denna utanför klassen)
�def __str__(self):
return "Namn: " + self.namn + ", Ålder: " + str(self.ålder) + ", Totalbetyg: " + str(self.__tot_betyg)
def __repr__(self):
return self.namn + ": " + str(self.ålder) + ": " + self.betyg_str() + '|'
Jobba gärna tillsammans!
33
Lära sig tillsammans
34
Målet är att ni ska lära er!
När du är klar med en labb borde du kunna göra den igen på betydligt kortare tid.
Det brukar vara svårt om en inte tagit sig igenom många av de jobbiga buggarna själv.
Allmännhandledningen
35
Labb 4
Deadline: Onsdagen 13/12