Göm meny

Introuppgift 3

Syftet med denna introuppgift är att ni ska öva er på att skriva klasser från grunden, samt skapa instanser av dessa klasser som sedan utför enklare kod. Fokus ligger både på syntax och modellering.

Instruktionerna är uppdaterade för VT18!

Redovisningstider

Redovisningstider hittar du i TimeEdit. Se till att du anmält dig till en grupp för Tema 3.

Komplettering

Vid frånvaro skickar du in en screencast på max 10 minuter där du går igenom din/er kod och tar upp redovisningsfrågorna längst ner.

Inlämningen skickar du in enligt instruktioner på sidan Inlämningsinstruktioner.

Uppgifter

För dessa övningsuppgifter all kod ska följa kodstandarderna PEP 8, samt PEP 257 och kontrolleras med programmen pep8 och pep257.

Vid redovisning kommer ni att få demonstrera ett urval av uppgifterna. Ni kommer också att få frågor om era lösningar.

Kunskapsmål för introuppgift till Tema 3

Efter att ha gjort denna uppgift ska du

  • förstå struktur och syntax för att skapa enklare egna klasser
  • känna till och kunna använda metoderna __init__() och __str__()
  • förstå skillnaden mellan klass och instans
  • förstå användningen av self som variabel och argument
  • förstå vad inkapsling innebär med avseende på objektorienterad programmering
  • kunna skapa enklare klasser som kapslar in en datastruktur som är enbart uppbyggd av inbyggda datatyper (strängar, siffror, listor och dictionarys)
  • kunna skapa enklare klasser som kapslar in en datastruktur som både innehåller inbyggda datatyper (se ovan), men även instanser av klasser du själv skapat
  • behärska syntax för att definiera, läsa och ändra på värden på instansvariabler
  • behärska syntax för att definiera metoder i en klass
  • behärska syntax för att anropa metoder som är bundna till instanser av en klass som du själv skapat

Som ni märker är hel del repetition med viss påbyggnad jämfört med Introuppgift 1.

Uppgifter

Uppgift 1-2 är obligatoriska. Uppgift 3 är frivillig.

OBS! Filer till introuppgiften hittar ni i ~729G75/kursmaterial/tema3/introuppgift3

Uppgift 1: Husdjur

Uppdatering 2018-04-12: pet_tester.py har fått ett par buggrättningar (använder instansvarabeln kind som i instruktionerna istället för type) samt lägger till leksaker på rätt sätt. Den gamla versionen (med buggar) finns också i kurskatalogen, men heter då pet_tester_type.py.

I uppgift 1 ska ni definierar klassen Pet. Spara er kod i en fil med namnet pet.py. Scenariot är att att instanser av klassen ska användas i ett ett text-baserat program som lagrar och bearbetar information om husdjur. Dokumentera sedan klassen genom att rita ett klassdiagram. Detaljerade instruktioner för klassen och klassdiagrammet hittar ni nedan.

Testkörning/demonstration av klassen Pet

För att testa er Pet-klass kan ni köra pet_tester.py som ni hittar bland filerna till introuppgift 3 (ni kopierade väl filerna enligt instruktionerna ovan?). Er fil pet.py måste ligga i samma katalog som pet_tester.py. Ni kan köra pet_tester.py även medan ni skriver på Pet-klassen. pet_tester.py fångar upp de vanligaste undantagen och skriver ut vissa felmeddelanden:

$ python3 pet_tester.py

Du kan också prova skapa instanser och testa Pet-klassen manuellt genom att skapa instanser och anropa metoderna och skriva ut innehållet i instansvariablerna, t.ex.

pet1 = pet.Pet("Harry")
print(pet1.name)
pet1.kind = "häst"
pet1.add_toy("gummianka")
print(pet1.toys)
pet1.add_toy("fotboll")
print(pet1.toys)
print(pet1)

Instansvariabler i klassen Pet

Varje instans av Pet ska ha kunna lagra följande information:

  • instansvariabeln name ska lagra husdjurets namn som en som en sträng
  • instansvariabeln kind ska lagra vilket slags djur husdjuret är som en sträng
  • instansvariabeln toys ska lagra leksaker som husdjuret gillar i form av en lista av strängar, t.ex. [] för inga leksaker, ["boll"] för en leksak, eller ["nalle", "boll"] för två leksaker.

Metoder i klassen Pet

__init__(self, name='')

När man skapar en instans av klassen Pet ska man kunna välja om man skickar med ett namn eller inte. Instanser ska alltså kunna alltså skapas med antingen Pet("Fido") och Pet().

add_toy(toy)

Argumentet toy ska vara en sträng med namnet på en leksak. Användning av metoden add_toy lägger till värdet i toy till listan self.toys. Exempelanvändning där pet1 är refererar till ett Pet-objekt: pet1.add_toy("nalle")

__str__()

Om en klass definierar metoden __str__() används den automatiskt av Python för att konvertera instanser av klassen till en sträng. Detta händer t.ex. när man använder print() för att skriva ut en variabel. Exempelanvändning där pet1 refererar till ett Pet-objekt.

  • för name == "Fido", type == "hund" och toys == [] ska pet.__str__() returnera strängen "Fido är en hund som inte har några leksaker."
  • för name == "Fido", type == "hund" och toys == ["boll", "nalle"] ska pet.__str__() returnera strängen "Fido är en hund som har följande leksaker: boll, nalle"

Klass-diagram

Dokumentera strukturen hos klassen Pet genom att rita ett klassdiagram (i UML). Ni kan göra detta efter att ni är färdiga med koden, men diagrammen ska visas upp vid redovisningstillfället och användas vid diskussion med redovisningshandledaren.

Det går bra att rita klassdiagrammet för hand eller med något verktyg.

Se föreläsning 2 tillhörande tema 3 för exempel på klassdiagram, eller lektionsmaterial från kursen 729G06: 729G06, Lektion 3. Ni kan även läsa mer på t.ex. Wikipedia

Uppgift 2: Försöksdata

I uppgift 2 ska ni skapa två klasser:

  1. Mätserieklassen: En klass som representerar en sekvens av mätvärden (en mätserie).
  2. Försökspersonsklassen: En klass som representerar en försöksperson som genomfört en eller fler testomgångar av ett experiment. I ett tänkt program har man beslutat att mätdata från testomgångarna (noll eller fler sekvenser av mätvärden, dvs. instanser av ovan nämnda klass) ska lagras i samma datastruktur som grunddata för varje person.

Testning och demonstration av klasserna

  1. Skapa en fil som ni använder för att definiera klasserna (motsvarande pet.py i uppgift 1). Läs om klasserna ni nästa avsnitt.

  2. Skapa en fil som importerar klasserna och testar kör dem. Ni kan göra detta på liknande sätt som beskrivs i kodsnutten i avsnittet Testkörning och demonstration av klassen Pet i uppgift 1. Istället för att skapa instanser av Pet skapar ni tre instanser av försökspersonsklassen med följande personuppgifter:

  • Försökspersonsinstans 1
    • Namn: Tristan Stortå
    • Födelseår: 1995
    • Försökspersonskod: fp1
  • Försökspersonsinstans 2
    • Namn: Ulla Vägval
    • Födelseår: 2000
    • Försökspersonskod: fp2
  • Försökspersonsinstans 3
    • Namn: Willhelmina Xtra
    • Födelseår: 2005
    • Försökspersonskod: fp3
  1. Läs in mätvärden från datafilerna till försökspersonerna. Läs in filer som börjar med fp1 till försöksperson 1, filer som börjar med fp2 till försöksperson 2 etc. Se instruktionerna för försökspersonklassens metoder i avsnittet nedan.

  2. Skriv ut information om varje försöksperson. Utskriften ska genom att använda metoden __str__() som ni definierar på liknande sätt som ni gjorde med klassen Pet i uppgift 1.

Följ nednastående mall för utskrifterna (nedanstående siffervärden stämmer inte med de ni ska få när ni laddar data från datafilerna).

Namn: Ulla Vägval
Födelseår: 2000
Kod: fp2
Antal mätserier: 2
Mätserie 1: 32 mätpunkter. Max: 105. Min: 4. Medel: 43,49 
Mätserie 2: 24 mätpunkter. Max: 98. Min: 10. Medel: 39,21

Mätserieklassen

Namnge klassen enligt goda principer för klassnamn (se föreläsning och kurslitteratur). Du behöver förstå vad klassens syfte är för att göra detta.

Instansvariabler i mätserieklassen

Mätserieklassen ska lagra mätvärdena i en lista. När man skapar en instans av mätserieklassen ska instansvariabeln vara en tom lista.

Metoder i mätserieklassen

Mätserieklassen ska ha följande metoder:

load_data(filename)

Metoden load_data(filename) ska ta in ett filnamn som sträng och läsa in värdena som spara dem som siffror i instansvariabeln som beskrivits ovan. Mätvärdena är sparade i formatet “ett värde per rad”. Filerna hittar ni i ~729G75/kursmaterial/tema3/introuppgift3 (filnamnen har mönstret fpX-serieX.txt).

get_max_value()

Metoden get_max_value() ska returnera det högsta mätvärdet.

get_min_value()

Metoden get_min_value() ska returnera det lägsta mätvärdet.

get_avg_value()

Metoden get_avg_value() ska returnera genomsnittsvärdet.

Försökspersonsklassen

Försökspersonsklassen ska lagra personuppgifter och ett godtyckligt antal instanser av mätserieklassen. Försökspersonsklassen motsvarar alltså Pet-klassen i uppgift 1, men istället för att ha en lista med strängar (leksakerna), ska försökspersonklassen ha en lista med instanser av mätserieklassen.

  • Bestäm namn på metoder och instansvariabler själva. Kom ihåg det ni gjort i uppgift 1.
  • När man skapar en instans av mätserieklassen ska instansvariabeln vara en tom lista.

Instansvariabler i försökspersonklassen

Uppdatering 2018-04-12: telefonnummer struken från listan över instansvariabler.

Definiera försökspersonklassen så att den har instansvariabler för följande information:

  • namn
  • födelseår
  • telefonnummer
  • kodifierad identitiet
  • ett godtyckligt antal mätserier

Försökspersonsklassen är alltså en lite mer informationsrik variant av Pet-klassen.

Metoder i försökspersonsklassen

Definiera följande metoder för försökspersonerna. Namnge dem enligt goda namngivningsmönster.

  • en __init__()-metod

  • en metod för att lägga till en mätserie

  • metoden __str__() som returnerar en sträng som beskriver försökspersonen. Se exempelutskriften i avsnittet Testkörning och demonstreration av klasserna ovan).

Klassdiagram

Dokumentera strukturen hos klassen mätserieklassen och försökspersonklassen genom att rita ett klassdiagram (i UML). Ni kan göra detta efter att ni är färdiga med koden, men diagrammen ska visas upp vid redovisningstillfället och användas vid diskussion med redovisningshandledaren.

Det går bra att rita klassdiagrammet för hand eller med något verktyg.

Se föreläsning 2 tillhörande tema 3 för exempel på klassdiagram, eller lektionsmaterial från kursen 729G06: 729G06, Lektion 3. Ni kan även läsa mer på t.ex. Wikipedia

Uppgift 3: Representation av text (frivillig uppgift)

I Uppgift 3 får ni de minst specificerade beskrivningarna. Skapa klasser och kod på bästa sätt.

Klassbeskrivningar

Följande klasser ska skapas:

  • en klass som representerar ett ord eller ett skiljetecken
  • en klass som representerar en mening (ska innehålla instanser av klassen för ord/skiljetecken)
  • en klass som representerar ett stycke (ska innehålla instanser av klassen för meningar).
  • en klass som representerar en text (ska innehålla instanser av klassen för stycken.

Informationen kommer alltså att lagras på ett trädstrukturliknande sätt.

Klassdiagram

Dokumentera strukturen hos klassen klasserna till uppgift 3 genom att rita ett klassdiagram (i UML). Ni kan göra detta efter att ni är färdiga med koden, men diagrammen ska visas upp vid redovisningstillfället och användas vid diskussion med redovisningshandledaren.

Det går bra att rita klassdiagrammet för hand eller med något verktyg.

Se föreläsning 2 tillhörande tema 3 för exempel på klassdiagram, eller lektionsmaterial från kursen 729G06: 729G06, Lektion 3. Ni kan även läsa mer på t.ex. Wikipedia

Testkörning och demonstration av klasserna

Dela upp klassdefinitioner och kod som testar klasserna på samma sätt som i uppgift 1 och 2. Loopa igenom nedanstående text för att skapa de olika instanserna till klasserna som beskrivits ovan.

Lorem ipsum dolor sit amet , consectetur adipisicing elit , sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua . Ut enim ad minim
veniam , quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur . Excepteur sint occaecat
cupidatat non proident , sunt in culpa qui officia deserunt mollit anim id
est laborum . 

Lorem ipsum dolor sit amet , consectetur adipisicing elit , sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua . Ut enim ad minim
veniam , quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur . Excepteur sint occaecat
cupidatat non proident , sunt in culpa qui officia deserunt mollit anim id
est laborum . 

Ni en textfil som innehåller ovanstående text hittar ni i ~729G75/kursmaterial/tema3/introuppgift3/. Instanserna ska inte skapas manuellt, utan på samma sätt som ni läste in data till instanserna av mätserieklassen i uppgift 2, skapar ni instanser för ord-, menings-, styckes- och textklassen.

# strängen text_data innehåller ovanstående stycken
t = Text(text_data)

När ni läst in texten och skapar instanserna skriver ni ut något i stil med nedanstående genom ett anrop till print() som får in instansen för text-klassen (implementera __str__()-metoden i varje klass som hjälper er på samma sätt som i uppgift 1 och 2:

Texten innehåller totalt Q stycken.

Stycke 1 innehåller totalt X meningar.
Stycke 1 innehåller totalt Y ord.
Stycke 1 innehåller totalt Z tecken.

Stycke 2 innehåller totalt X meningar.
Stycke 2 innehåller totalt Y ord.
Stycke 2 innehåller totalt Z tecken.

Tips till Uppgift 3

  • klassen för ett stycke skulle kunna ha en metod eller konstruktor som tar in ett helt stycke som en sträng.
  • klassen för en mening skulle kunna ha en metod eller konstruktor som tar in en hel mening som sträng.
  • klassen för ord skulle kunna ha en konstruktor eller metod som tar in ett ord eller skiljetecken (utan mellanslag) som sträng.

Redovisning

Redovisningsförfarande

  • Vid redovisningen kommer handledaren be er demonstrera vissa av de uppgifter ni gjort, samt kontrollera att koden uppfyller kraven för kodstandard (PEP 8 och PEP257).
  • Varje gruppmedlem ska kunna svara på frågorna nedan.
  • Efter redovisningen kommer handledaren bedömma hur väl varje enskild gruppmedlem uppnått kunskapsmålen kopplade till denna uppgift (se ovan).
  • Varje pargrupp har en begränsad tid (ca 10 minuter) att redovisa och diskutera med handledaren.

Komplettering

  • Vid behov kommer er redovisningshandledare anvisa om att ni ska lämna in komplettering enligt kompletteringsinstruktionerna ovan. Inga kompletteringar kommer kunna göras under själva redovisningstiden.

Redovisningsfrågor

  • Finns det någon speciell fil man måste definiera sin klass i?
  • Vad säger PEP8 om namngivning av klasser och metoder?
  • Hur gör man för att använda en klass som är definierad i en annan fil?
  • Vad gör metoden __init__?
  • Vad är self?
  • Vad är det för skillnad på instans och klass?
  • Hur kan man göra för att lagra flera instaner av en klass i en annan?

Sidansvarig: Jody Foo
Senast uppdaterad: 2018-04-12