Temauppgift 4
Temauppgift 4 ger en introduktion till objektorienterad programmering, och är uppdelad i tre delar:
- Del 1: Identifiera objekt och metoder i kod. Egen övning, förberedelse för att kunna prata om objektorienterad kod.
- Del 2: Skriv en egen klass, samt testa och använd den klassen. Redovisas samt kodinlämning.
- Del 3: Skriv en sorteringsalgoritm för att sortera instanser av klassen ni skrev i Del 2. Redovisas samt kodinlämning.
Redovisning, inlämning och kompletteringar
- Allmän information om den muntliga redovisningen, samt eventuella kompletteringar kan ni läsa om sidan Redovisning.
- Ni får antingen 1 poäng, 3 poäng eller Komplettering på inlämningar som hör ihop med temauppgift 4-6. Vid Komplettering får ni instruktioner om vad som ska kompletteras.
Att redovisa
Vid redovisningstillfället redovisar ni följande:
- Förklara skillnaden mellan en klass och en instans. Ge exempel från er egen kod.
- Förklara hur man skapar en instans av en klass och vad som händer när man skapar en instans av en klass (vilken metod anropas). Ge exempel från er egen kod.
- Peka ut anrop av metod i en egenskriven klass i er egen kod. Förklara vad argumentet
selfhar för värde i ert metodanrop. - Peka ut användning av instansvariabler i er egen kod.
- Se till att ni använder termerna klass, instans, (instans)metod, instansvariabel korrekt under redovisningen.
Ni ska även demonstrera att era program från Del 2 och Del 3 fungerar som de ska.
Var förberedda så att ni hinner med redovisningen på 10 minuter!
Poäng
För 1 poäng på Temauppgift 4 ska följande göras:
- Del 1: alla uppgifter
- Del 2: alla uppgifter
- Del 3: 1-poängsuppgifterna
- Kod ska följa PEP8 och PEP257
För 3 poäng på Temauppgift 4 ska följande göras:
- Del 1: alla uppgifter
- Del 2: alla uppgifter
- Del 3: 3-poängsuppgifterna
- Kod ska följa PEP8 och PEP257
Uppgiftsnivåer och betyg
Se avsnittet om LAB2 på sidan Examination & Deadlines för information om kraven för att få VG på kursmomentet LAB2 (Temauppgift 4-6). Se avsnittet om att uppgradera temauppgiftsbedömning på sidan Examination & Deadlines om ni vill uppgradera bedömningen.
Kodkrav
- all kod följer PEP8-standarden
- all kod följer PEP257
Funktionskommentarer (PEP257) ska inte beskriva hur ni implementerat funktionerna, utan vad funktionerna gör och hur man använder dem (förklara argumenten).
Se Tips: Kontrollera PEP 8 och PEP 257 för tips om hur du kontrollerar för PEP8 och PEP257 automatiskt.
Del 0 - Visual Studio Code
Under Tema 4-6 är det tillåtet att använda ytterligare verktyg i VSCode för att hjälpa er med kodningen. Detta är dock helt frivilligt och ni kan fortsätta använda VSCode utan extra verktyg om ni föredrar det. Detta är särskilt rekommenderat för den som inte blivit godkänd på duggan.
Följ instruktionerna här för instruktioner om hur du installerar Python-extension och lintern Ruff i VSCode.
Del 1 - Identifiera klasser och metoder
I denna del ska ni analysera pythonkod och identifiera objekt och metoder som förekommer i koden. Det är såklart inte bara objekt och metoder som finns i pythonkod, men det är objekten och metoderna som är av intresse i dessa uppgifter.
Ni kan dock även passa på att repetera och identifiera begrepp som vi pratat om tidigare i kursen: sats, uttryck, variabel, funktionsanrop, tilldelning, nyckelord, block, jämförelse m.m.
Uppgift 1
Identifiera objekt och metoder i nedanstående kod (kör koden om ni vill). Dokumentera era svar. OBS! Namnen är skrivna som enstaka bokstäver för att ni ska fokusera på syntaxen, inte för att det är bra att göra det i riktig kod.
def b(c):
d = 0
while d < len(c):
print(c[d])
d += 1
a = [1, 2, 3]
a.append(4)
b(a)
Svar:
Metodanrop kännetäcknas av att de sitter ihop med ett objekt med punktnotation och har ett efterföljande parentespar; objekt.metod(). I detta exempel har vi ett metodanrop till .append() på näst sista raden.
Uppgift 2
Identifiera objekt och metoder i nedanstående kod (kör koden om ni vill). Dokumentera era svar. OBS! Namnen är skrivna som enstaka bokstäver för att ni ska fokusera på syntaxen, inte för att det är bra att göra det i riktig kod.
def f(g):
b = ""
while b != "q":
b = input("Skriv ett ord: ")
for c, d in g.items():
if c.startswith(b):
e = f"Menar du {c}? På engelska heter det {d}."
print(e)
a = { "hej" : "hello", "bil" : "car", "äpple" : "apple" }
f(a)
Svar
Metodanrop kännetäcknas av att de sitter ihop med ett objekt med punktnotation och har ett efterföljande parentespar; objekt.metod(). I detta exempel har vi ett metodanrop till .items() och .startswith().
Del 2 - DataRow
Här kommer ni att implementera klassen DataRow. Klassen innehåller ett antal instansvariabler och metoder, och representerar data i en studie på mentala rotationer. Detaljer på hur klassen ska se ut hittas i instruktionerna för Uppgift 1.
Läs igenom uppgiften och använd vid behov kurslitteraturen eller “Kom igång med klasser, objekt, instansvariabler och metoder” för att lösa uppgiften.
Kort om studien och experimentet
I studien visade Ganis och Kievit biler till ett antal försökspersoner (FP). Två figurer fanns med på bilderna, en till höger och en till vänster. FPs uppgift var att avgöra om den högra figuren hade samma form som den vänstra. Dock kunde den högra figuren vara roterad 0, 50, 100, eller 150 grader. Om FP tyckte att det var samma form skulle hen trycka på en knapp, om inte skulle FP trycka på en annan knapp.
Exempel på bild som visades (högra figuren roterad 100 grader):

Filer
I mappen /courses/729G46/kursmaterial/temauppg4/del2/json finns råfiler till ett dataset från en studie om mentala rotationer. Om du inte kan komma åt filsystemet på LiU kan du ladda ner en zippad version av katalogen. Data för varje enskild försöksperson finns sparad i en enskild fil, t.ex. sub1.json för försöksperson 1.
Innehåll i filerna
I det här fallet lagrar JSON-filerna datat som kolumner. Efter inläsning av JSON-filen sub1.json till ett dictionery (se sidan om JSON) får vi nedanstående. Innehållet har formaterats om för läsbarhet och endast de
5 första försöken visas här.
|
|
Det är alltså ett dictionary med sex nycklar. Värdet till varje nyckel är en lista. Varje värde på ett visst index hör ihop med alla andra värden på samma index. T.ex. så hör det första elementet i listan till nyckeln “response time”, ihop med första elementet i listan till nyckeln “trial”.
Här kommer en förklaring till vad värdena betyder:
- Listan under nyckeln
"trial"innehåller benämningarna på varje försök som försökspersonen gjort. - Listan under nyckeln
"image"innehåller namnen på bilderna som visades. - Listan under nyckeln
"response time"innehåller värden som berättar hur lång tid det tog för försökspersonen att svara varje omgång. - Listan under nyckeln
"expected answer"innehåller det förväntade svaren."[b]"betyder att figurerna var lika och"[n]"betyder att figurerna inte var lika. - Listan under nyckeln
"subject answer"innehåller försökspersonens svar. - Listan under nyckeln
"rotation"berätar med hur många grader som den högra figuren i den visade bilden var roterad.
OBS! Ibland blir det fel vid datainsamling. Var därför uppmärksamma på att värden i vissa filer kan saknas. Om ett värde saknas av någon anledning står det "N/A".
Uppgift 1: Skapa klassen DataRow
Skapa en fil mrdata.py. Denna ska innehålla klassen DataRow. Instanser av
klassen DataRow kommer användas i nästa uppgift för att lagra information om
en trial för en försöksperson som deltagit i studien om mentala rotationer.
Klassen DataRow ska implementeras enligt nedanstående klassdiagram:

Metoden DataRow.get_error_type() ska returnera den feltyp som svaret tillhör. I fälten correct_answer och subjects_answer så markerar strängen "[n]" att bilden är roterad och "[b]" att den inte är det. Metoden DataRow.get_error_type() ska returnera ett heltal mellan -1 och 3 enligt nedan:
- Om försökspersonen svarade att bilden var roterad (
"[n]") och detta var korrekt, returneras0. - Om försökspersonen svarade att bilden inte var roterad (
"[b]") och detta var korrekt, returneras1. - Om försökspersonen svarade att bilden var roterad (
"[n]") och detta inte var korrekt, returneras2. - Om försökspersonen svarade att bilden inte var roterad (
"[b]") och detta inte var korrekt returneras3. - Om datat i raden är felaktig returneras
-1(i princip om försökspersonens svar varken är"[n]"eller"[b]").
För att inte behöva komma ihåg dessa siffror kan man definiera variabler på toppnivå i filen mrdata.py enligt följande:
|
|
Ovanstående är alltså globala variabler, men vi kommer inte ändra deras värden utan använda dem som konstanter.
Att testa klassen
För att underlätta med testningen av er klass finns följande testskript: /courses/729G46/kursmaterial/temauppg4/test_datarow.py. Kopiera det till samma katalog som er fil mrdata.py och kör det.
Om du inte kan komma åt filsystemet på LiU kan du ladda ner en zippad version av katalogen.
test_datarow.py skapar instanser av er klass och undersöker om den har rätt instansvariabler, samt att metoden DataRow.get_error_type() fungerar som den ska.
Uppgift 2: Använd klassen DataRow
Nu när ni har skapat DataRow-klassen så är det dags att använda den.
Kopiera katalogen csv från /courses/729G46/kursmaterial/temauppg4/ till ett lämpligt ställe i din hemkatalog.
Om du inte kan komma åt filsystemet på LiU kan du ladda ner en zippad version av katalogen.
Skapa ett nytt pythonskript som gör följande:
- Er fil
mrdata.pyimporteras. - Data från en CSV-fil läses in och en instans av
DataRowför varje rad i CSV-filen skapas. Instanserna som skapas ska sparas i en lista. - Alla rader där försökspersonens svar var korrekt skrivs ut.
DataRow-objektens instansvariabler ska användas vid utskriften. - Alla rader där försökspersonen svar var felaktiga skrivs ut.
Skilj på korrekta och felaktiga rader genom att använda metoden get_error_type().
Om en rad innehåller ett värde som är "N/A" kan ni hoppa över den raden, dvs. strunta i att skapa en instans för den raden.
Skapa en instans av DataRow
Den första raden i sub1.csv är följande:
|
|
För att skapa en instans av mrdata.DataRow som innehåller data från denna rad skriver vi:
|
|
Instansvariablerna
Givet att row1 är en instans av mrdata.DataRow som skapats enligt ovan, kan vi skriva ut innehållet i instansvariabeln trial genom att skriva:
|
|
Utskriften
Varje rad du skriver ut ska ha följande information:
- vilken omgång (trial) datat kommer ifrån
- vilken bild som visades
- tiden försökspersonen tog innan hen svarade
Det kan t.ex. se ut så här:
|
|
Del 3 - Sortera objekt
I denna del ska ni implementera två sorteringsalgoritmer för att sortera listor av DataRow-instanser. Välj vilken variant av uppgiften ni löser beroende på om ni satsar på 1 poäng på Temauppgift 4 eller 3 poäng på Temauppgift 4.
I alla uppgifter används funktionen load_data(filepath) som tar in en sökväg till en csv-fil som ska läsas in. Ni kan lägga denna funktion i fil som ni importerar i alla uppgifter.
Uppgift 1
1 poäng
I uppgift 1 ska ni sortera en lista med DataRow-objekt efter responstid med hjälp av Bubble Sort-algoritmen.
Ni kan utgå från den länkade koden, men ni behöver göra ändringar i koden som gör att den sorterar en lista med DataRow-objekt istället för en lista med heltal.
- Skriv en funktion som ni döper till
load_data()som tar in namn på fil och returnerar en lista medDataRow-objekt. Denna funktion kommer ni kunna använda även i Uppgift 2, så ni kan lägga denna i en separat fil och importera den. - Skriv sedan en funktion som ni döper till
bubblesort()som tar in listan medDataRow-objekt och returnerar en sorterad lista medDataRow-objekt. Sorteringen ska ske genom att använda bubble sort-algoritmen.
3 poäng
För att få 3 poäng på Temauppgiften ska på Uppgift 1 ska följande vara uppfyllt:
- er lösning uppfyller kraven för 1 poäng
- man ska kunna skicka ett extra argument till
bubblesort()för att ange vilken avDataRows instansvariabler som listan avDataRow-objekt ska sorteras efter. Det ska vara möjligt att sortera efter åtminstone två av attributen.
När ni skriver ert program, försök att bryt ut funktionalitet till funktioner för att öva på det. Ge era funktioner beskrivande namn i verb-form för att göra er kod mer lättläst.
Eftersom vi bryter ut funktioner här för att öva på det så är det inget krav att resultatet ska bli färre rader kod nödvändigtvis.
Uppgift 2
1 poäng
Er uppgift är att implementera en av de nedanstående sorteringsalgoritmerna så att den kan sortera en lista med DataRow-objekt efter stigande responstid.
Ert pargruppsnummer i EXA2 avgör vilken av algoritmerna ni ska implementera. Är ni t.ex. grupp A.1, B.1 eller D.1 implementerar ni Heapsort, osv.
VIKTIGT! Er implementation skall innehålla någon form av rekursion (se exempel).
3 poäng
För att få 3 poäng på Temauppgift 4 ska er lösning på uppgift 2 uppfylla följande:
- er lösning uppfyller kraven för 1 poäng
- man ska via argument till sorteringsfunktionen kunna ange både vilket attribut som man ska sortera efter.
- det ska gå att sortera efter minst två olika attribut
- man ska via argument till funktionen kunna ange om sorteringen ska ske stigande eller fallande. OBS! Det är inte tillräckligt att använda
.reverse()för att ändra sorteringsordning efter att sorteringen är färdig. Ni måste ändra i algoritmen så att den ändrar sorteringsordning. - lösningen är skriven på ett sätt som inte upprepar samma kod i onödan. Dvs. återanvänd kod genom att dela upp i mindre funktioner där det behövs. Uppdelningen behöver inte vara “perfekt” dock.
När ni skriver ert program, försök att bryta ut funktionalitet till funktioner för att öva på det. Ge era funktioner beskrivande namn i verb-form för att göra er kod mer lättläst.
Eftersom vi bryter ut funktioner här för att öva på det så är det inget krav att resultatet ska bli färre rader kod nödvändigtvis.
Sidansvarig: Johan Falkenjack
Senast uppdaterad: 2025-10-10
