1 of 36

Föreläsning 9

Repetition och utvidgning

1

2 of 36

Dagens agenda

  1. Mer om listor
  2. Enka och sammansatta datatyper
  3. Lite smått och gott
    1. F-strängar
    2. Användarvänlig utdata
    3. Klassexempel med fler metoder
  4. Samarbete & hjälp i kursen

2

3 of 36

Listor

3

4 of 36

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?

5 of 36

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()

6 of 36

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.

    • Lösningen med listkopior är ofta mer komplicerad.
    • Du behöver spara två listor i minnet på datorn…

Undvik detta!

Men varför…?

7 of 36

Enkla och sammansatta datatyper

8 of 36

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

9 of 36

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

10 of 36

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

11 of 36

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?

12 of 36

__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…

13 of 36

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!

14 of 36

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)

15 of 36

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.

16 of 36

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)

17 of 36

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)

18 of 36

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)

19 of 36

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?

20 of 36

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!

21 of 36

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)

22 of 36

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!!!!!

23 of 36

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.

24 of 36

f-strängar

25 of 36

Ett alternativt sätt att skriva ut strängar

25

Vi har tittat på två sätt att printa() strängar på:

  • Konkatinering: addera strängar (sträng1 + sträng2):� namn = ”Rudolf” print(”God jul” + namn)
  • Stoppa in flera parametrar (med olika värden) i print:� namn = ”Rudolf” print(”God jul”, namn)

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

26 of 36

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

27 of 36

Användarvänlig utdata

27

Kopplat till användning av print och input

28 of 36

Tydlig utdata för användaren

  • Förklara vad för typ av värde du vill att användaren ska mata in!
  • Mycket text kan bli svårläst 🡪 lägg in mellanslag och tomma rader

28

29 of 36

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:

  • En kompis på KTH
  • En kompis utanför KTH
  • En familjemedlem eller släkting
  • Vem som helst som du är bekväm med att fråga

Du måste självklart testköra dina program många gånger!

30 of 36

Hur programmet testköras?

30

  • Se till att testa ALLA olika val och funktionaliteter i ditt program!
  • Om du har implementerat felhantering: testa så att programmet beter sig som det ska när användaren gör fel!
  • När någon annan testar: observera noga hur de använder ditt program
    • Tolkar de programmet så som du hade tänkt dig?
    • Be dem gärna ”tänka högt” dvs. förklara hur de tänker.

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!

31 of 36

Klasser med fler metoder

31

32 of 36

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() + '|'

33 of 36

Jobba gärna tillsammans!

33

34 of 36

Lära sig tillsammans

  • Ni får inte skicka era labblösningar till någon annan eller visa hela er läsning och förklara den.
  • Ni får prata om hur ni löser labben och visa delar av koden.
    • Visa mycket hellre kod som inte fungerar.
  • Ni får inte redigera i varandras kod

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.

35 of 36

Allmännhandledningen

35

36 of 36

Labb 4

Deadline: Onsdagen 13/12