Lektion 7. Obligatorisk redovisning 3.
Moment: | Utforma och implementera en enkel klass. Använda arrayer. Iterationer. Läsa tal från tangentbordet. |
Begrepp som introduceras: | Dokumentation med Javadoc. |
Arbetssätt: |
Arbeta gärna tillsammans med någon men skriv egen kod. Diskutera med varandra! |
Uppskattad arbetstid: | 6 timmar. Notera gärna hur lång tid du själv behöver och framför det vid redovisningen! |
Redovisning: |
Obligatorisk redovisning för lärare/handledare enligt tiderna på
kurssidan. Frågor utan svar ska besvaras vid redovisningen. Fråga handledaren om du inte förstår svaren på frågor med |
Förberedelse
-
Skapa mappen
lektion07
där du sparar det du gör i denna lektion. - Läs minilektionen om hur man skickar objektreferenser till och från metoder! Informationen där är viktig för några av de efterfrågade metoderna.
- Läs minilektionen om JavaDoc.
- Läs kodningsreglerna och se till att du följer dem när du börjar koda!
Mätserieklassen
Du skall skriva en klass Measurements
för att lagra serier av mätvärden av typ double
.
Ett objekt ur klassen skall alltså representera en serie.
Värden skall lagras i en array.
När man skapar ett objekt så skall man ange hur många värden som maximalt skall lagras.
Om värdena t ex är dygnsmedeltemperaturer under en månad så skapar man ett objekt med plats för 31 värden.
Värdena behöver inte vara kända när objektet skapas utan skall kunna matas in successivt. Det betyder att man måste hålla reda på hur många värden som matats in med hjälp av en instansvariabel. Det är inte säkert att alla platser i arrayen kommer att utnyttjas.
I nedanstående figurer står store
för arrayreferensen och stored
för antalet
lagrade värden, tillika index för nästa värde som ska lagras.
Satser | Resultat |
---|---|
Measurements m = new Measurements(10) |
![]() |
m.add(-2); m.add(0); m.add(6); m.add(1); m.add(2): |
![]() |
Den vita delen av arrayen är den använda delen medan den grå är den hittills oanvända delen.
Konstruktorer och metoder
Följande metoder skall finnas (med dessa typer, namn och parametrar):
-
public Measurements(int max)
Konstruktor som skapar ett objekt med plats förmax
värden. -
public String toString()
Returnerar en textrepresentation av objektet. Exempel:<-2.0, 0.0, 2.0>
. Strängen ska innehålla de element som adderats, inte den oanvända delen av arrayen. -
public void add(double value)
Lägger till värdetvalue
på plats efter senast lagrade värde. Förutsätt tills vidare att det finns plats.Innan uppgiften redovisas ska dock metoden klara av fallet att arrayen är full. Den ska då ersättas av en ny, dubbelt så stor, array. Värdena från den gamla arrayen skall naturligtvis kopieras över till den nya.
-
public int stored()
Returnerar antalet lagrade värden. -
public double get(int index)
Returnerar värde lagrat på platsindex
. -
public double mean()
Returnerar medelvärdet av de lagrade värdena. -
public double min()
Returnerar det minsta av de lagrade värdena. -
public double max()
Returnerar det största av de lagrade värdena. -
public double stdDev()
Returnerar standardavvikelsen för de lagrade värdena. Se formel nedan. -
public Measurements(double[] values)
Konstruktor som som skapar ett objekt med data från arrayenvalues
. -
public double[] get()
Returnerar en array med de värden som lagrats i arrayen. Den array som returneras skall vara lika lång som det antal värden som lagrats. -
public Measurements smooth()
Skapar ett nyttMeasurements
-objekt med utjämnade värden (se nedan).
Man vill när som helst (alltså oberoende om alla värden är inmatade eller ej) kunna beräkna medelvärde och standardavvikelse för det hittills inmatade talen.
Exempel: Koden
ska ge utskrifterna
(Javakoden ovan kan hämtas härifrån.)
Medelvärdet och standardavvikelsen för värdena x1, x2, ..., xn beräknas med hjälp av formlerna
(Kom ihåg att man i matematiken brukar ha 1 som första index men att man i Java och många andra språk börjar med 0.)
Metoden smooth()
skall skapa och returnera ett nytt Measurements
-objekt där
värdet på plats i är medelvärdet av värdena på plats i-1, i och i+1 i originalet.
Värdet på första och sista plats skall vara samma som i originalet.
index: | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
värde: | 2. | 1. | 6. | 5. | 4. | 9. | 2. |
smooth(): | 2. | 3. | 4. | 5. | 6. | 5. | 2. |
Skriv också följande:
-
En
main
-metod i klassenMeasurements
med koden ovan. Kontrollera att dina resultat stämmer! -
En separat klass
TestMeasurements
med enbart enmain
-metod som läser tal från tangentbordet och lägger in dessa i ettMeasurements
-objekt. Inläsningen avslutas när det som står på tur att läsas inte kan tolkas som ett tal. Låt metoden sedan använda metodena iMeasurements
-objektet för skriva ut skrivs min-, max- och medelvärdet talen.
Ledning: Det första exemplet i minilektionen omScanner
-klassen visar hur man läser tal från tangentbordet. Du behöver också användaScanner
-metodenhasNextDouble()
för att se om det går att läsa ytterligare ett tal.
Observera
- Din kod ska uppfylla kodningsreglerna.
- Koden skall vara kommenterad med Javadoc. Se minilektionen om Javadoc!
- Din kod måste följa specifikationen med rätt namn på metoder och rätt parametertyper!
-
Eftersom det är övningar i grundläggande algoritmer ska du inte använda metoder i klassen
Arrays
. Det är oftast inte heller lämpligt att användafor-each
-loopar.
Lämplig arbetsgång
- Klassen behöver två instansvariabler: en array med
double
-värden och en av heltalstyp som anger hur många platser i arrayen som används. Den senare är 0 från början (utom för konstruktorn som tar emot en array). -
Eftersom
add
hör till de svårare metoderna bör man först göra en enkel version som förutsätter att den skapade arrayen har plats för det nya värdet. Denna version kräver bara ca 2 rader kod. -
Skriv
toString
-metoden. Tänk på att metoden bara ska göra en sträng av de värden som faktiskt har lagrats dvs den ska inte ta med hela arrayen (om den inte är fullt utnyttjad). -
Skriv
main
-metoden som provaradd
- ochtoString
-metoderna med olika antal lagrade värden. Se vad som händer om du försöker lagra fler värden än det finns plats för! -
Skriv sedan
max
-,min
-,mean
- ochstdDev
-metoderna. De är alla förhållandevis enkla. Tänk på att- bara gå över de värden som faktiskt lagrats och
- att både negativa och positiva värden kan förekomma liksom värdet 0!
main
-metod och kontrollera att de ger rätt resultat! -
Gör nu klar
add
-metoden. Om arrayen är full så skapar du ett nytt array-objekt med dubbelt så många platser som i det nu använda array-objektet. Kopiera över värdena och sätt instansvariabeln att referera det nya objektet. -
Metoden
smooth
ska skapa och returnera ett nyttMeasurements
-objekt. Du kan användaadd
-metoden för att fylla detta nya objekt men det går att göra på andra sätt också. - Gör resten av av uppgiften. Tänk på att skriva testanrop till alla metoder du skriver! Använd (bl.a.) de data som finns ovan i denna beskrivning så att du kan kontrollera resultaten.
Uppgifter och frågor att diskutera vid redovisningen
- Det finns två möjliga sätt att skriva konstruktorn som tar en array som parameter. Vilka? Vilket är bäst och varför?
-
De olika möjligheterna att skriva metoden
double[] get()
- Hur ska man göra en metod som returnerar medianen? Beskriv i ord - du behöver inte skriva någon kod
- Klassen har ju ingen parameterlös konstruktor. Hur skulle en sådan kunna se ut?
Allmänna frågor
-
Vilka datatyper kan användas som index i arrayer?
Alla heltalstyper (inklusive
char
) utomlong
. -
Vilka datatyper kan lagras i arrayer?
Alla dvs alla primitiva typer och alla objekttyper.
-
Kan man ta bort en array?
Nej. Ett arrayobjekt (liksom alla objekt) kan man kan bara "tappa bort" den vilket sker om man inte har någon referens till det.
-
Kan man ta bort och lägga till värden i en array? Hur, i så fall?
Nej. Ett array-objekt har en fix storlek som inte kan ändras.
-
Vad händer om man adresserar sig utanför en arrays gränser?
Programmet av bryts med ett undantag kallat
ArrayIndexOutOfBoundsException
.
Frivillig utvidgning
Skriv en metodsmooth(int n)
som returnerar ett nytt Measurement
-objekt
där alla värden (utom de i början och slutet) är ersatta med medelvärdet av de kringliggande värdena.
Värdet på plats i skall vara medelvärdet av de på platserna
i-n, i-(n-1), ... , i-1, i, i+1, ... , i+(n-1), i+n
Exempel: Om originalobjektet har följande lagrat
2 1 6 5 4 9 2
så skall anropen smooth(1)
och smooth(2)
returnerade objekt innehållande värden enligt följande tabell:
index: | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
värde: | 2. | 1. | 6. | 5. | 4. | 9. | 2. |
smooth(): | 2. | 3. | 4. | 5. | 6. | 5. | 2. |
smooth(1): | 2. | 3. | 4. | 5. | 6. | 5. | 2. |
smooth(2): | 2. | 1. | 3.6 | 5.0 | 5.2 | 9. | 2. |
När det ute vid kanterna inte går att använda hela bredden på "operatorn" så behålls alltså originalvärdena.
Högst frivillig modifiering:
I stället för att
låta alla värden vara oförändrade när man inte kan använda hela bredden
på "operatorn" så kan man använda en successivt avsmalnande operator ute i kanterna.
Det skulle alltså innebära att t ex smooth(2)
skulle ersätta
det näst första och näst sista med medelvärdet av de tre första respektive
de tre sista. I exemplet ovan skulle det alltså bli 3.
och 5.
på index 1
respektive 5
i sista
kolumnen (dvs samma värden som för smooth(1)
).
Gå till nästa lektion eller gå tillbaka
Dölj style3dev.css för att bli av med annoteringarna!