Göm meny
Gäller för: HT22

Temauppgift 6 - Del 1

Syftet med denna uppgift ä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.

OBS! Filer till Del 1 hittar ni i /courses/729G46/kursmaterial/temauppg6/del1

Uppgift 1: Husdjur

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.

Nedan ser ni klassdiagrammet för klassen Pet.

Anmärkning: Metoden __str__() är tillagd här för tydlighets skull. I vanliga fall skriver man inte ut den explicit.

Klassen Pet

Instanser av klassen Pet representerar ett husdjur. Klassen definierar instansvariabler för att lagra husdjurets namn, dess art, och vilka leksaker den gillar. Klassen ska också definiera __str__() metoden som används t.ex. när vi skriver ut instanser med print().

Instansvariabler

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

  • __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", kind == "hund" och toys == [] ska pet.__str__() returnera strängen "Fido är en hund som inte har några leksaker."
    • för name == "Fido", kind == "hund" och toys == ["boll", "nalle"] ska pet.__str__() returnera strängen "Fido är en hund som har följande leksaker: boll, nalle"
    • Anm.: Det är OK att tomma strängar skrivs ut om kind eller name är tomma strängar. Ni behöver inte heller bry er om kongruens mellan räkneordet “en” och djurarten (dvs det är OK att t.ex. *“Misse är en lodjur …” skrivs ut).

Testkörning och demonstration av klassen Pet

Alternativ 1

För att testa er Pet-klass kan ni köra pet_tester.py som ni hittar bland filerna till Del 2 i kurskatalogen. 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

Alternativ 2

Ni kan alternativt 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)

Uppgift 2: Försöksdata

I Uppgift 2 ska ni skapa två klasser:

  1. DataSeries: En klass som representerar en sekvens av mätvärden (en mätserie).
  2. Person: 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.

Nedan ser ni klassdiagram för Uppgift 2.

Datafiler

Mätvärdena är sparade i formatet “ett värde per rad”. Filerna hittar ni i /courses/729G46/kursmaterial/temauppg6/del1/ (filnamnen har mönstret fpX-serieX.txt).

Vad ska man börja med?

Eftersom klassen Person är beroende av klassen DataSeries är det rimligt att börja med att implementera klassen DataSeries. Ni kan testa klassen separat genom att lägga testkod för klasserna inne i en if __name__ == "__main__" i filen som definierar klassen.

Klassen DataSeries

Instanser av klassen DataSeries ska lagra en sekvens av mätvärden. Metoder ska finnas för att ladda in data från fil, ta fram max-, min- och genomsnittsvärden.

Instansvariabler

Klassen DataSeries ska lagra mätvärdena i en lista. Välj själva om ett filnamn ska anges när man skapar en instans, eller om det är OK att inte ange ett filnamn när man skapar en DataSeries-instans.

Metoder

Klassen DataSeries ska ha följande metoder:

  • load_data(filename): Metoden ska ta in ett filnamn som sträng och läsa in värdena som spara dem som siffror i instansvariabeln Dataseries.values`.
  • get_max_value(): Metoden ska returnera det högsta mätvärdet.
  • get_min_value(): Metoden ska returnera det lägsta mätvärdet.
  • get_avg_value(): Metoden ska returnera genomsnittsvärdet.
  • __str__(): Metoden ska returnera en strängbeskrivning av sig själv på formatet "XX mätpunkter. Max: YYY. Min: Z. Medel: NNN". Instanser av ´Person´ kommer använda detta när den ska beskriva sina mätserier.

OBS! __str__() anropas aldrig explicit utan den används genom att konvertera ett objekt till en sträng, eller när ett objekt skrivs ut med print().

Klassen Person

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

När man skapar en instans av Person ska instansvariabeln dataseries_collection vara en tom lista.

Instansvariabler

Definiera klassen Person så att den har nedanståend instansvariabler

  • name: personens namn
  • birthyear: personens födelseår
  • ID: kodifierad identitiet
  • dataseries_collection: ett godtyckligt antal mätserier

Försökspersonsklassen är alltså en lite mer informationsrik variant av Pet-klassen som har mätvärden istället för leksaker.

Metoder

Definiera följande metoder i klassen Person

  • __init__(): Välj själv vilka argument som ska tas emot.
  • add_dataseries(): En metod för att lägga till en mätserie. Metoden tar emot ett sökvägen till den fil vars värden som ska läggas till. Det betyder att ni behöver skapa DataSeries-instansen i denna metod.
  • __str__(): Metoden __str__() som returnerar en sträng som beskriver försökspersonen. Se till att använda __str__() från DataSeries för att ta fram beskrivningar av varje dataserie som en person har. Se exempelutskriften i avsnittet Testkörning och demonstreration av klasserna.

OBS! __str__() anropas aldrig explicit utan den används genom att konvertera ett objekt till en sträng, eller när ett objekt skrivs ut med print().

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
  3. Läs in mätvärden från datafilerna till försökspersonerna (alla tre). 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 metoderna i klassen Person. OBS! Det är helt ok att hårdkoda filnamnen, ni behöver inte skriva kod som letar upp filerna.

  4. Skriv ut information om varje försöksperson. Utskriften ska genom att använda metoden __str__() implicit genom att skriva ut varje person med print(). 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

OBS! Alla filer till alla försökspersoner ska läsas in och information för alla tre försökspersoner ska visas när programmet körs.


Sidansvarig: Jody Foo
Senast uppdaterad: 2022-12-08