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
self
har 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 kommer vi att använda Visual Studio Code (oftast kallat bara VSCode) istället för Thonny. Skriv följande i terminalfönstret för att få tillgång till editorn ($
ska inte skrivas utan representerar prompten i terminalen).
|
|
Det första gör modulen prog/vscode tillgänglig i din nuvarande session. Det andra kommandot ser till att modulen prog/vscode från och med nu automatiskt läggs till när du loggar in, dvs du behöver bara göra detta en gång.
För att starta VSCode skriv
|
|
Följ instruktionerna här för instruktioner om hur du installerar Python-extension och lintern Ruff i VSCode samt hur du kan installera VSCode på din egen dator.
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:
Alla värden i Python är objekt, t.ex. strängar, heltal, listor, dictionaries.
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
Alla värden i Python är objekt, t.ex. strängar, heltal, listor, dictionaries.
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.
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 samma studie om mentala rotationer
som användes i Temauppgift 3.
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:
TP = 0
TN = 1
FP = 2
FN = 3
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 en
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.py
importeras. - Data från en CSV-fil läses in och en instans av
DataRow
fö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:
1,R2_3_3_2_0Y0.pct,1355,[n],[n],0
För att skapa en instans av mrdata.DataRow
som innehåller data från denna rad
skriver vi:
row1 = mrdata.DataRow(1, "R2_3_3_2_0Y0.pct", 1335, "[n]", "[n]", 0)
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:
print(row1.trial)
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:
Korrekta svar:
Trial: 1, image: R2_3_3_2_0Y0.pct, time: 1355
Trial: 2, image: R3_4_3_2_90Y150.pct, time: 2079
Trial: 3, image: 2_4_4_2_0Y150.pct, time: 1834
Trial: 4, image: 3_3_3_2_0Y100.pct, time: 4780
Trial: 5, image: 3_3_3_3_90Y50.pct, time: 1685
Trial: 6, image: R2_4_4_2_0Y50.pct, time: 1237
Trial: 7, image: R3_3_3_3_90Y100.pct, time: 2961
Trial: 8, image: 2_3_3_2_0Y0.pct, time: 1275
Trial: 9, image: R3_4_3_3_180Y150.pct, time: 4716
.
.
.
Felaktiga svar:
Trial: 10, image: 2_4_4_2_180Y150.pct, time: 3794
Trial: 33, image: 3_3_3_3_180Y50.pct, time: 1831
Trial: 43, image: 3_3_3_3_180Y100.pct, time: 5983
Trial: 44, image: R2_3_4_2_90Y150.pct, time: 2750
.
.
.
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 avDataRow
s 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, ä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 kunna via argument till funktionen kunna ange om sorteringen ska ske stigande eller fallande. OBS! Det är inte godkänt att använda
.reverse()
för att ändra sorteringsordning. Ni måste ändra i algoritmen så att den ändrar sorteringsordning. - er 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. Kodlösningen behöver inte vara “perfekt” dock.
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, är det inget krav att resultatet ska bli färre rader kod nödvändigtvis.
Sidansvarig: Johan Falkenjack
Senast uppdaterad: 2024-07-26