• No results found

Programmering och databaser

N/A
N/A
Protected

Academic year: 2022

Share "Programmering och databaser"

Copied!
81
0
0

Loading.... (view fulltext now)

Full text

(1)

}

Programmering och databaser

KURSKOMPENDIUM }

EDAA20

http://cs.lth.se/edaa20

2017/2018

(2)
(3)

EDAA20 Programmeringsteknik,

godkända obligatoriska uppgifter 2017/2018

Skriv ditt namn och din namnteckning nedan:

Namn: . . . .

Namnteckning: . . . .

Godkända uppgifter Datum Handledarens namnteckning

Laboration 1 Laboration 2 Laboration 3 Laboration 4 Laboration 5 Laboration 6 Laboration 7 Laboration 8 Laboration 9 Laboration 10 Laboration 11

För att bli godkänd på en uppgift måste du lösa deluppgifterna och diskutera dina lösningar med en labhandledare. Denna diskussion är din möjlighet att få feedback på ditt program. Ta vara på den!

Se till att handledaren noterar dina uppgifter som godkända på detta godkännandeblad.

Dessa underskrifter är ditt kvitto på att du är godkänd på laborationerna. Spara dem tills du fått slutbetyg i kursen.

(4)
(5)

LUNDS TEKNISKA HÖGSKOLA EDAA20

Institutionen för datavetenskap 2017/2018

Innehåll

1 Övningar – anvisningar 7

Övning 1 Variabler och tilldelningssatser . . . 8

Övning 2 Loopar, vektorer . . . 10

Övning 3 Objekt . . . 12

Övning 4 Implementera klasser . . . 15

Övning 5 Strängar, vektorer och matriser . . . 18

Övning 6 Listor . . . 21

Övning 7 Arv . . . 25

2 Eclipse – en handledning 29 3 Java-laborationer – anvisningar 35 Laboration 1 introduktion . . . 36

Laboration 2 eget spel . . . 41

Laboration 3 vektorer . . . 43

Laboration 4 använda färdigskrivna klasser, kvadrat . . . 46

Laboration 5 blockmullvad . . . 52

Laboration 6 implementera klasser, Turtle . . . 59

Laboration 7 algoritmer, labyrint . . . 64

Laboration 8 matriser, Memory-spel . . . 68

Laboration 9 kortaste väg, ArrayList . . . 72

Laboration 10 TurtleRace, del 1: ArrayList . . . 78

Laboration 11 TurtleRace, del 2: mer arv . . . 80

5

(6)
(7)

7

1 Övningar – anvisningar

I kursen ingår ett antal övningar. Under övningarna ska du självständigt eller tillsammans med en kamrat lösa övningsuppgifterna. Vilken övning som är lämplig att göra vilken vecka framgår av kursprogrammet. Försök ligga i fas, för övningarna utgör en viktig del av din programme- ringsträning.

Lösningsförslag kommer att publiceras på kursens hemsida.

(8)

8 Övning 1 – Variabler och tilldelningssatser

Övning 1 – Variabler och tilldelningssatser

Följande uppgifter på denna övning passar bra att provköra på dator: 1, 4, 5, 6, 7, 8 och 9 Variabler och tilldelningssatser

1. Skriv kod som beräknar summan av talen 3, 8 och 12 och skriver ut resultatet.

2. Betrakta följande programavsnitt:

int nbrA = 2;

int nbrB = nbrA + 3;

int nbrC = 3 * (nbrA + nbrB) - 1;

nbrA = nbrC / 5;

nbrC = 0;

En bild av minnessituationen (vilka variabler som finns och variablernas värden) ska ritas efter respektive tilldelningssats. Efter första tilldelningssatsen ser det ut så här:

2 nbrA

Rita de fyra övriga bilderna.

3. Betrakta följande program, där fyra heltal läses från tangentbordet och några (ointressan- ta) beräkningar görs:

public class Example1 {

public static void main(String[] args) { Scanner scan = new Scanner(System.in);

int a = scan.nextInt();

int b = scan.nextInt();

int c = scan.nextInt();

int d = scan.nextInt();

int e = (c + d) - (a + b);

c = c + 2;

a = (2 * e + c) / 4;

System.out.println(a + " " + b + " " + c + " " + d + " " + e);

} }

a) En av parenteserna i programmet är onödig. Vilken? Varför?

b) Vilka värden skrivs ut när talen 1, 2, 4 och 8 läses in från tangentbordet? Använd en tabell där du noterar de successiva variabelvärdena.

c) Vilka värden skrivs ut när talen 1, 2, 8 och 4 läses in från tangentbordet?

4. Två heltalsvariabler a och b har deklarerats och fått värden. Skriv satser som byter värde på a och b (”swappar” värdena). Exempel:

int a = 10;

int b = 25;

// ... dina satser

System.out.println(a + " " + b); // ger utskriften 25 10

(9)

Övning 1 – Variabler och tilldelningssatser 9

Inläsning och beräkning

5. Skriv ett program (en klass med en main-metod) som först läser en starttid (två tal, timmar och minuter, till exempel 12 41) och därefter en sluttid (två andra tal, till exempel 16 28) och därefter beräknar och skriver ut hur många minuter det är mellan tiderna. Du kan förutsätta att sluttiden är större än starttiden. Ledning: det behövs fyra int-variabler för de fyra inlästa talen. Ge dessa variabler vettiga namn.

6. Ändra i programmet från uppgift 5 så att tidsavståndet skrivs ut i timmar och minu- ter i stället för i minuter. Detta kan man göra på två sätt: antingen genom att använda en if-sats eller genom att använda heltalsdivision och operatorn %, som ger resten vid heltalsdivision.

Slumptal

7. Skriv satser för att slumpa och skriva ut ett tal mellan 100 och 199 (100 inkluderat men 200 inte inkluderat).

8. Skriv satser för att slumpa och skriva ut ett tal mellan 10 och 30 (10 och 30 inkluderat).

9. Skriv ett program som drar två olika slumptal mellan 1 och 100 och skriver ut dessa med det minsta talet först.

Aritmetiska uttryck

10. Skriv följande som tilldelningssatser i Java:

a) y=sin(20) b) z=aex+be−cos(x)

c) hyp=√ a2+b2

11. Talet x är av typ double. Hur konverterar man värdet av x till närmaste int-tal?

12. a) Hur kan man med operatorn % avgöra om heltalet n är jämnt?

b) Hur kan man med operatorn % avgöra om heltalet n slutar med en nolla?

c) Talet number är tresiffrigt. Skriv tilldelningar så att digit1, digit2, digit3 tilldelas värdet av respektive siffra. Använd operatorerna % och /.

(10)

10 Övning 2 – Loopar, vektorer

Övning 2 – Loopar, vektorer

Följande uppgifter på denna övning passar bra att provköra på dator: 2, 3, 6, 7, 9 och 10 Logiska uttryck

1. Förenkla följande logiska uttryck (a är en int-variabel, ready är en boolean-variabel):

a) a > 2 && a > 5 b) a > 2 || a > 5

c) !(a > 2)

d) !(a > 2 && a < 9) e) !(a < 0 || a > 10)

f) ready == true g) ready == false Loopar

2. Skriv ett program som läser in ett heltal n och därefter beräknar och skriver ut n! (n- fakultet). Använd en for-loop.

3. Skriv ett program som gör samma sak som programmet i uppgift 2 men med en while- loop istället.

Summering

4. Skriv ett program som läser 30 temperaturvärden och beräknar och skriver ut medeltem- peraturen.

5. Indata består av 101 reella tal. Det första talet kallas limit. Skriv satser som läser talen och beräknar två summor: dels summan av de tal som är mindre än limit, dels summan av de tal som är större än limit. Tal som är lika med limit ska inte summeras.

6. Ett arbete ger lön enligt följande: första dagen är lönen en krona. De följande dagarna får man dubbelt så mycket betalt som man fick närmast föregående dag. Skriv ett pro- gram som avgör hur många dagar man måste arbeta innan man har tjänat ihop en miljon kronor.

Beräkna max och min

7. a) Skriv ett program som från tangentbordet läser ett antal heltal (använd hasNextInt() för att undersöka om det finns fler tal att läsa). I programmet ska du beräkna och skriva ut det största av talen.

b) Hur förändras lösningen i deluppgift a om man istället ska söka efter minsta talet?

Vektorer

8. I en vektor int[] a = new int[8]; har man tilldelat elementen a[0] till a[7] följande värden: 3 25 4 –18 0 –1 5 16 Vilka värden skrivs ut med följande Java-satser?

(11)

Övning 2 – Loopar, vektorer 11

k = 2;

System.out.println(a[k]);

System.out.println(3*a[7]);

System.out.println(2*a[k – 1] + 5 – a[2*k]);

k = a[6];

System.out.println(a[k]);

9. Skriv programrader där 10 reella tal läses och lagras i en vektor. Talen skall sedan skrivas ut i omvänd ordning.

10. Implementera följande metoder.

a) /** Beräknar summan av talen i vektorn v. */

public static int sum(int[] v);

/** Hittar minsta talet i vektorn v. */

public static int min(int[] v);

(12)

12 Övning 3 – Objekt

Övning 3 – Objekt

Använda färdiga klasser b)

1. Klasserna SimpleWindow och Square från labbarna antas vara tillgängliga. Vad ritas på skärmen när nedanstående program exekveras? Visa med en (någorlunda) skalenlig figur.

public class SquareExample {

public static void main(String[] args) {

SimpleWindow w = new SimpleWindow(400, 400, "Squares");

Square sq1 = new Square(100, 100, 200);

Square sq2 = new Square(300, 300, 50);

sq1.draw(w);

sq2.draw(w);

} }

2. I denna uppgift är kodsnuttar utklippta från programkoden i föregående uppgift. Dra streck mellan begreppen nedan och den kodsnutt som illustrerar begreppet.

Begrepp Kodsnutt

metodanrop new Square(100, 100, 200);

ett nytt objekt skapas (400, 400, Squares");

en ny referensvariabel deklareras public static void main(String[] args)

typ public class SquareExample

namn på en referensvariabel draw(w)

argumentet w skickas in till metod sq1

argument till konstruktor Square

klassrubrik sq1.draw(w);

här börjar exekveringen Square sq1

3. Nedanstående program innehåller tre fel som upptäcks av kompilatorn. Korrigera felen.

public class ErrorTest {

public static void main(String[] args) {

SimpleWindow w = new SimpleWindow(600, 600);

sq = new Square(100, 200, 50);

while sq.getX() < 300 { sq.draw(w);

sq.move(10, 10);

} } }

Objekt i minnet

4. Bilden visar minnessituationen (vilka variabler som finns, variablernas värden, vilka ob- jekt som finns, attributens värden) när följande sats har exekverats:

Square sq1 = new Square(20, 30, 40);

(13)

Övning 3 – Objekt 13

20 30 40 x y side sq1

a) Rita en ny bild som visar hur minnessituationen förändras om man dessutom exe- kverar följande sats:

Square sq2 = sq1;

b) Ändra bilden i deluppgift a så att den visar minnessituationen om man slutligen exekverar satsen:

sq1 = null;

5. Vi brukar för enkelhets skull rita en referens som en pil som pekar på det objekt referens- variabeln refererar till. Egentligen är referensen ett tal, nämligen adressen till den plats i minnet där objektet är lagrat. Ett exempel (ännu ej fullständigt) på hur referensvariabler- nas värden och objekten lagras i datorns minne visas här:

47540

x y side sq1

30 40 20 5200 5204

...

...

...

47540 47544 47548

...

sq2

Gör färdigt figuren så att den visar hur det ser ut efter att följande två satser exekverats:

Square sq1 = new Square(20, 30, 40);

Square sq2 = sq1;

Från kod till specifikation

6. De föregående uppgifterna handlar om att skriva program genom att använda färdiga klasser, t.ex. Square. Hur klassen Square kan användas (namn på metoder etc.) kan du läsa i specifikationen av klassen.

Nu ska du träna på att själv skriva en specifikation genom att göra tvärtom. Följande program använder en klass Apartment. Lista ut vilka metoder som finns och skriv en specifikation för klassen Apartment.

public class CalculateRent {

public static void main(String[] args) { Scanner scan = new Scanner(System.in);

System.out.println("Lägenhetsnummer:");

int nbr = scan.nextInt();

System.out.println("Yta:");

double area = scan.nextDouble();

(14)

14 Övning 3 – Objekt

Apartment a = new Apartment(nbr, area);

System.out.println("Månadshyra per kvadratmeter:");

a.setSquareMetreRent(scan.nextDouble());

System.out.println("Månadshyra: " + a.getRent());

} }

(15)

Övning 4 – Implementera klasser 15

Övning 4 – Implementera klasser

Följande uppgifter på denna övning passar bra att provköra på dator: 2, 3, 4 och 5 Implementera metoder

1. En groda hoppar omkring på en gräsmatta. Från början befinner sig grodan i mitten av gräsmattan, d.v.s. i en punkt med koordinaterna (0, 0). Koordinaterna har enheten meter.

Grodan beskrivs initialt av följande klass:

public class Frog { private int x;

private int y;

public Frog() { x = 0;

y = 0;

}

public int getX() { return x;

}

public int getY() { return y;

}

public void jumpSouth(int n){

y = y-n;

} }

Observera att grodan inte ska ritas ut någonstans.

a) Lägg till en ny metod i klassen Frog. Metoden ska heta getMeters och ska returnera ett heltal. Heltalet som returneras ska vara antalet meter som grodan hoppat sen den skapades. getMeters ska inte ha några parametrar.

Börja med att skriva metodrubriken. Varför ser den ut som den gör? Fundera sen på implementationen av metoden.

b) Lägg till ytterligare en ny metod i klassen Frog. Metoden ska heta jumpNorth och den ska inte returnera någonting. Metoden ska ha en heltalsparameter n. Implemen- tationen av metoden ska se till så att grodan hoppar n meter norrut.

c) I en fullständig version av grodan skulle man givetvis vilja att den kan hoppa även åt öst och väst. Implementera metoder även för detta

(16)

16 Övning 4 – Implementera klasser

Implementera klasser

2. Implementera färdigt klassen Car:

public class Car {

private String nbr; // registreringnummer private Person owner; // ägare

/** Skapar en bil med registreringsnummer licenseNbr som ägs av personen owner. */

public Car(String licenseNbr, Person owner) { // Lägg till egen kod här.

}

/** Tar reda på bilens registreringsnummer. */

public String getLicenseNbr() { // Lägg till egen kod här.

}

/** Tar reda på bilens ägare. */

public Person getOwner() { // Lägg till egen kod här.

}

/** Sätter bilens ägare till newOwner. */

public void changeOwner(Person newOwner) { // Lägg till egen kod här.

} }

3. Rita en figur som visar vilka objekt som finns samt värdet av alla variabler och attribut efter det att följande satser har exekverats.

Person p = new Person("Bo Ek");

Car c1 = new Car("ABC123", p);

p = new Person("Eva Alm");

Car c2 = new Car("XYZ789", p);

Klassen Car finns i föregående uppgift och klassen Person ser ut så här.

public class Person { private String name;

/** Skapar en person med namnet name. */

public Person(String name) { this.name = name;

}

/** Tar reda på personens namn. */

public String getName() { return name;

} }

(17)

Övning 4 – Implementera klasser 17

4. I ett system för bokning av platser på tåg förekommer en klass RailwayCoach som beskri- ver en vagn i tåget. Klassen har följande specifikation:



/** Skapar en vagn med nbrSeats platser. */

RailwayCoach(int nbrSeats);

/** Tar reda på antalet platser i vagnen. */

int getNbrSeats();

/** Tar reda på antalet lediga (obokade) platser. */

int getNbrFreeSeats();

/** Bokar n platser i vagnen. Det får förutsättas att n <= antalet lediga platser. */

void makeReservation(int n);

Implementera klassen fullständigt, dvs deklarera attribut och implementera konstruktorn och operationerna. Observera att man bara är intresserad av antalet lediga platser, inte numren på de platser som är lediga.

5. Klassen Person beskriver personer (klassen har fler operationer, men dem är vi inte in- tresserade av här):



/** Skapar en person med åldern age. */

Person(int age);

/** Undersöker om denna person är äldre än personen p.

Returnerar då true, annars false. */

boolean isOlderThan(Person p);

Implementera klassen.

(18)

18 Övning 5 – Strängar, vektorer och matriser

Övning 5 – Strängar, vektorer och matriser

Följande uppgifter på denna övning passar bra att provköra på dator: 1, 2, 4 och 6 Strängar

1. Antag att metoderna equals och compareTo i klassen String inte är tillgängliga. Skriv följande metod:



/** Undersöker om strängarna s1 och s2 är lika långa och alla tecknen i s1 är lika med motsvarande tecken i s2. */

public static boolean equals(String s1, String s2);

2. Skriv följande metod:

/** Bildar en sträng som innehåller tecknen i s i omvänd ordning. */

public String reverse(String s);

Till exempel ska reverse(”asdfg”) ge strängen ”gfdsa”. Använd ett StringBuilder- objekt.

3. Skriv en satser som räknar antalet ’t’ och antalet ’P’ i en given sträng s.

Vektorer

4. Implementera följande metoder.

a) /** Sök efter positionen för talet x i vektorn v.

Returnerar -1 om x ej finns i vektorn. */

public static int indexOf(int[] v);

b) /** Undersöker om talen i vektorn v är sorterade i växande ordning. */

public static boolean isSorted(int[] v);

c) /** Undersöker om vektorerna v1 och v2 är lika, dvs. om de är lika långa och alla v1[i] == v2[i]. */

public static boolean equal(int[] v1, int[] v2);

5. En vektor a innehåller 100 heltal. Vilken utskrift fås av nedanstående satser om int i = 0;

while (i < a.length && a[i] != 0) { i++;

}

System.out.println(i);

a) det finns en nolla i vektorn, i vektorelementet a[33]?

b) det inte finns någon nolla i vektorn?

c) det finns 50 nollor i vektorn, i vektorelementen med udda index dvs. i a[1], a[3], . . . , a[99]?

(19)

Övning 5 – Strängar, vektorer och matriser 19

Matriser

6. Antag att m är en heltalsmatris. Skriv satser för att skriva ut alla värden i hela matrisen.

Från utskriften ska man tydligt kunna se vilken rad och kolumn respektive tal ligger på.

Exempel:

[0] [1] [2]

[0] 2 53 87 [1] 3 33 2 [2] 0 70 80

Ni behöver inte justera columnerna efter antalet siffror. Det är tillräckligt för uppgiften att alltid använda två mellanslag (vilket duger om talen inte är längre än i exemplet ovan).

7. Sudoku är ett logikspel som går ut på att man ska placera ut siffror i ett rutmönster. Det klassiska, ursprungliga rutmönstret består av 3×3 rutor (”regioner”) som i sin tur består av 3×3 rutor. Det gäller att placera in siffrorna 1 till 9 på ett sådant sätt att varje vågrät rad, lodrät rad och region innehåller varje siffra exakt en gång. Uppgiften går inte ut på att lösa ett sudoku.

Klassen SudokuGrid nedan beskriver rutnätet i Sudoku.

a) Implementera färdigt klassen. Tips: Låt noll beteckna icke-angivet värde (tom ruta) eftersom 0 inte är en giltig siffra i Sudoku.

public class SudokuGrid {

/** Skapar ett tomt Sudokurutnät. */

public SudokuGrid () {

}

/** Placerar siffran value i rutan (row,col).

Samtliga parametrar antas ha ett värde mellan 1 och 9 */

public void put(int row, int col, int value) {

}

/** Tar bort siffran i rutan (row,col).

Samtliga parametrar antas ha ett värde mellan 1 och 9 */

public void clear(int row, int col) {

}

/** Tar reda på siffran i rutan (row,col), noll om rutan tom.

Samtliga parametrar antas ha ett värde mellan 1 och 9 */

public int get(int row, int col) {

(20)

20 Övning 5 – Strängar, vektorer och matriser

}

/** Tar reda på om rutan (row,col) är tom.

Samtliga parametrar antas ha ett värde mellan 1 och 9 */

public boolean empty(int row, int col) {

} }

b) Lägg till en metod allSet som returnerar true om samtliga rutor i rutnätet är ifyllda, false om det fortfarande finns minst en tom ruta.

c) Lägg till en metod checkRow(int row) som kontrollerar om raden row i sudokurut- nätet är korrekt, d.v.s. antingen är tomma eller, om inte tomma, bara innehåller siff- rorna 1-9 helt utan dubletter. Metoden ska returnera en boolean: false om det finns dubletter eller felaktiga siffror annars true.

d) Lägg till en metod checkRegion(int row, int col) som kontrollerar om regionen där rutan row, col befinner sig är korrekt ifylld. Metoden ska returnera false om det finns dubletter av någon ifylld siffra i angiven rutas region. True i alla andra fall.

8. Klassen Matrix beskriver en kvadratisk matris:

public class Matrix {

private double[][] a; // talen i matrisen

/** Skapar en matris med n rader och n kolonner. */

public Matrix(int n) { a = new double[n][n];

}

/** Tar reda på elementet med index i, k. */

public double get(int i, int k) {...}

/** Adderar matrisen m till denna matris (matriserna förutsätts vara lika stora). */

public void add(Matrix m) {...}

/** Beräknar spåret av matrisen, dvs summan av diagonalelementen från övre vänstra hörnet till nedre högra hörnet. */

public double trace() {...}

}

Implementera de tre operationerna get, add och trace. Vid addition av matriser adderar man element för element.

(21)

Övning 6 – Listor 21

Övning 6 – Listor

Följande uppgifter på denna övning passar bra att provköra på dator: 2 1. Ett ArrayList-objekt cards är deklarerad och skapad enligt följande:

ArrayList<Card> cards = new ArrayList<Card>();

// Här läggs ett antal kort in i cards Klassen Card har följande specifikation:

Card 

/** Konstanter för färgern: */

static final int SPADES = ...;

static final int HEARTS = SPADES + 1;

static final int DIAMONDS = SPADES + 2;

static final int CLUBS = SPADES + 3;

/** Skapar ett spelkort med färgen suit (SPADES, HEARTS, DIAMONDS, CLUBS) och valören rank (1-13). */

Card(int suit, int rank);

/** Tar reda på färgen. */

int getSuit();

/** Tar reda på valören. */

int getRank();

a) Skriv satser för att summera kortens valörer.

b) Skriv satser som tar reda på om spader dam finns bland korten. Resultatet av sök- ningen ska vara att en variabel pos innehåller spader dams position i vektorn (-1 om spader dam ej finns i vektorn).

c) Ett nytt kort med valören r och färgen s ska sättas in i listan. Korten i listan ska vara ordnade i stigande valör. Skriv satser som ser till att detta nya kort skapas och hamnar på sin rätta plats i listan med hänsyn till dess valör.

2. Ett antal arbetsuppgifter, ”jobb”, som tar olika lång tid ska fördelas på ett antal maskiner.

Man vill göra ett schema för vilken maskin som ska göra vilket jobb på så sätt att alla jobb är klara så tidigt som möjligt. Exempel på ett schema med 3 maskiner (1-3) och 7 jobb (j1–j7), jobbens längd står inom parentes:

j (16)

M 4

j 2 (14) j (6) j (5)

j 7 (3) j (4) j (2)

5 6 3 1

1 M 2 M 3

Ett enkelt sätt att lösa uppgifter av denna typ är att fördela jobben i avtagande ordning efter tidsåtgång och att ge varje jobb till den maskin som har minst att göra. Denna sche- maläggningsalgoritm kallas LPT-algoritmen (Longest Processing Time) och har använts för att skapa schemat i figuren. Algoritmen ger inte alltid det optimala resultat, men ett tillräckligt bra resultat. Att räkna ut den optimala lösningen skulle ta alldeles för lång tid om antal maskiner och jobb är stort. Jobben beskrivs av följande klass:

(22)

22 Övning 6 – Listor

Job 

/** Skapar ett jobb med namnet name som tar tiden time att utföra. */

Job(String name, int time);

/** Returnerar jobbets tidsåtgång. */

int getLength();

/** Returnerar en sträng som representerar jobbet på formen namn (tidsåtgång). */

String toString();

Lös följande deluppgifter. De klasser som hänvisas till finns sist i uppgiften.

a) Studera klassen Machine och se till att du förstår koden. Se speciellt på attributet jobs. Hur ser deklarationen ut? Vad betyder <Job>?

b) Varför passar det bättre att lagra jobben i ett ArrayList-objekt än i en vektor av typen Job[]?

c) Ange exempel på attribut, parameter och lokal variabel i klassen Machine.

d) Studera klassen Sheduler och se till att du förstår koden. Studera speciellt konstruk- torn och jämför den med konstruktorn i Machine. I konstruktorn i Machine skapar man listan som ska innehålla maskiner, men i konstruktorn i Scheduler skapar man inte vektorn machines. Förklara varför.

e) Implementera metoderna machineWithLeastToDo och makeSchedule.

f) Studera huvudprogrammet (klassen med main-metoden) och se till att du förstår koden. Vad skrivs ut (i detalj) när man exekverar programmet?

En maskin beskrivs av följande klass:

public class Machine { private int nbr;

private ArrayList<Job> jobs;

/** Skapar maskin nr nbr. */

public Machine(int nbr) { this.nbr = nbr;

jobs = new ArrayList<Job>();

}

/** Tar reda på maskinens nr. */

public int getNbr() { return nbr;

}

/** Tilldelar maskinen jobbet j. */

public void assignJob(Job j) { jobs.add(j);

}

/** Tar bort alla jobb från maskinen. */

public void clearJobs() { jobs.clear();

}

/** Tar bort och returnerar nästa jobb som maskinen ska utföra.

Returnerar null om maskinen inte har några jobb. */

public Job getNextJob() { if (jobs.isEmpty()) {

return null;

(23)

Övning 6 – Listor 23

}

return jobs.remove(0);

}

/** Tar reda på den totala tiden för maskinens jobb. */

public int getTotalTime() { int time = 0;

for (int i = 0; i < jobs.size(); i++) { time = time + jobs.get(i).getLength();

}

return time;

}

/** Returnerar en sträng som innehåller maskinens schemalagda jobb med kommatecken mellan. */

public String jobsAsString() {

StringBuilder b = new StringBuilder();

for (int i = 0; i < jobs.size(); i++) { b.append(jobs.get(i));

if (i != jobs.size() - 1) { b.append(", ");

} }

return b.toString();

} }

Implementeringen av klassen Scheduler, som sköter schemaläggningen, finns här:

public class Scheduler {

private Machine[] machines;

/** Skapar en schemaläggare för maskinerna i vektorn machines. */

public Scheduler(Machine[] machines) { this.machines = machines;

}

/* Returnerar den maskin som har minst att göra. */

private Machine machineWithLeastToDo () { // Fyll i egen kod

}

/** Fördelar jobben i listan jobs på maskinerna enligt LPT-algoritmen.

Jobben är sorterade efter avtagande tidsåtgång. */

public void makeSchedule(ArrayList<Job> jobs) { // Fyll i egen kod

}

/** Skriver ut maskinernas scheman. */

public void printSchedule() {

System.out.println("Maskin\tTid\tJobb");

for (int i = 0; i < machines.length; i++) {

System.out.println(machines[i].getNbr() + "\t"

+ machines[i].getTotalTime() + "\t"

+ machines[i].jobsAsString());

} } }

Här är ett program som skapar det schema som visas i exemplet ovan. I ett riktigt program skulle man naturligtvis läsa in antal maskiner, jobbens namn och tidsåtgång istället för att

(24)

24 Övning 6 – Listor

ange dem explicit i programmet.

public class TestScheduler {

public static void main(String[] args) { Machine[] m = new Machine[3];

for (int i = 0; i < m.length; i++) { m[i] = new Machine(i + 1);

}

ArrayList<Job> jobList = new ArrayList<Job>();

String [] names = {"j4", "j2", "j5", "j6", "j3", "j7", "j1"};

int[] times = {16, 14, 6, 5, 4, 3, 2};

for (int i = 0; i < names.length; i++) { jobList.add(new Job(names[i], times[i]));

}

Scheduler s = new Scheduler(m);

s.makeSchedule(jobList);

s.printSchedule();

} }

(25)

Övning 7 – Arv 25

Övning 7 – Arv

Följande uppgifter på denna övning passar bra att provköra på dator: 3 Arv

1. Personer, studenter och lärare har ordnats i följande klasshierarki:

Person(String name) String name

Person

Student(String name, String program) String program

Student

Teacher(String name, String department) String department

Teacher

a) Implementera klasserna Person och Student.

b) Följande tilldelningssatser är självklart korrekta:

Person p = new Person("Nils Nilsson");

Student s = new Student("Bo Ek", "D");

Teacher t = new Teacher("Eva Alm", "CS");

Åskådliggör i en bild hur objekten ser ut.

c) Satserna i föregående uppgift har utförts. Vilka av följande satser är korrekta, åt- minstone så långt kompilatorn kan avgöra det?

p = s;

s = p;

s = t;

s = (Student) p;

d) Satsen s = (Student) p; kan ge ett fel under exekvering. När inträffar felet? Vad kallas felet?

e) Alla klasser har en operation toString() som ska ge en ”läsbar representation”

av objektet (läroboken avsnitt 11.6). I klasserna Person och Student har metoden implementerats enligt följande:

public class Person {

public String toString() { return name;

} }

public class Student extends Person { public String toString() {

return super.toString() + ", " + program;

} }

Vad betyder super.toString()? Vilken utskrift får man av nedanstående satser?

Person p = new Person("Nils Nilsson");

Student s = new Student("Bo Ek", "D");

System.out.println(p.toString());

System.out.println(s.toString());

(26)

26 Övning 7 – Arv

p = s;

System.out.println(p.toString());

2. Uppgift: Givet klasserna A och B, vad skrivs ut när mainmetoden körs?

public class A {

protected int[] numbers;

public A(int x) {

numbers = new int[x];

for (int i = 0; i < numbers.length; i++) { numbers[i] = i * x;

} }

public void print() {

System.out.print(this.toString());

}

public String toString() {

StringBuilder sb = new StringBuilder();

for (int i = 0; i < numbers.length; i++) { int count = numbers[i];

for (int k = 0; k < count; k++) { sb.append("A");

}

sb.append("\n");

}

return sb.toString();

} }

public class B extends A { public B(int x) {

super(x);

}

public String toString() {

StringBuilder sb = new StringBuilder();

for (int i = 0; i < numbers.length; i++) { int count = numbers[i];

for (int k = 0; k < count; k++) { sb.append("B");

}

sb.append("\n");

}

return sb.toString();

} } Mainmetoden:

public static void main(String[] args) { A a1 = new A(3);

A a2 = new B(2);

a1.print();

(27)

Övning 7 – Arv 27

a2.print();

}

Abstrakta klasser och metoder

3. Antag att vi har följande klasshierarki:

Shape

move(int, int) y

x

side

draw(SimpleWindow) Square

radius

draw(SimpleWindow) Circle

Här är klasserna:

public class Shape { protected int x;

protected int y;

/** Skapar en figur med läget x, y. */

protected Shape(int x, int y) { this.x = x;

this.y = y;

}

/** Flyttar figuren avståndet dx i x-led, dy i y-led. */

public void move(int dx, int dy) { x += dx;

y += dy;

} }

public class Circle extends Shape { private int radius;

/** Skapar en cirkel med mittpunkten i x, y och radien radius. */

public Circle(int x, int y, int radius) { super(x, y);

this.radius = radius;

}

/** Ritar cirkeln i fönstret w. */

public void draw(SimpleWindow w) { w.moveTo(x + radius, y);

for (int i = 1; i <= 180; i++) {

w.lineTo(x + (int) (radius * Math.cos(Math.toRadians(2 * i))), y - (int) (radius * Math.sin(Math.toRadians(2 * i))));

} } }

(28)

28 Övning 7 – Arv

public class Square extends Shape { private int side;

/** Skapar en kvadrat med övre vänstra hörnet i x, y och sidlängden side */

public Square(int x, int y, int side) { super(x, y);

this.side = side;

}

/** Ritar kvadraten i fönstret w. */

public void draw(SimpleWindow w) { w.moveTo(x, y);

w.lineTo(x + side, y);

w.lineTo(x + side, y + side);

w.lineTo(x, y + side);

w.lineTo(x, y);

} }

a) Det finns ett problem i en av ovanstående klasser som orsakar ett fel när man försöker kompilera följande kod:

SimpleWindow w = new SimpleWindow(600, 600, "figurer");

Shape s = new Circle(100, 100, 20);

s.move(5, 5);

s.draw(w);

Circle c = new Circle(200, 200, 50);

c.move(5, 5);

c.draw(w);

I vilken sats uppträder kompileringsfelet. Vad är problemet? Ändra i klassen/klas- serna ovan så att alla satserna går att kompilera.

b) Här är ett program där det skapas några figurer som sedan ritas ut i ett ritfönster.

public class Main {

public static void main(String[] args) { Drawing theShapes = new Drawing();

theShapes.insert(new Square(100, 300, 100));

theShapes.insert(new Circle(400, 400, 50));

theShapes.insert(new Square(450, 450, 50));

theShapes.insert(new Square(200, 200, 35));

theShapes.draw(new SimpleWindow(600, 600, "Några figurer"));

} }

Implementera klassen Drawing.

(29)

2 Eclipse – en handledning

Inledning

Här beskrivs Eclipse, den programutvecklingsmiljö som utnyttjas i programmeringskurserna.

Mera information finns på:

http://www.eclipse.org Eclipse hemsida. Enorma mängder information.

http://help.eclipse.org Hjälpsidor för Eclipse, senaste versionen. Dessa hjälpsidor finns också lokalt i Eclipse-systemet, under Help Contents i Help-menyn.

http://www.eclipse.org/downloads/ Nedladdning av Eclipse för olika datorer. Välj

”Eclipse IDE for Java Developers”.

Det finns också många handledningar som är betydligt utförligare än denna, till exempel på www.vogella.com/articles/Eclipse/article.html.

Att utveckla Javaprogram

Ett Javaprogram består av en eller flera klasser som lagras i filer med tillägget .java. Dessa filer innehåller ”vanlig text” (bokstäver, siffror och andra tecken). Innan man kan exekvera (köra) programmet måste filerna kompileras (översättas) till ett annat format (bytekod) som datorn

”förstår”. Bytekoden lagras i filer med tillägget .class. Översättningen görs av en kompilator som heter javac, och programmet körs av en Javatolk som heter java.

Allt detta kan man hantera manuellt. Då editerar man .java-filerna med Emacs eller en annan texteditor, kompilerar dem med javac och kör programmet med java. Det kan se ut så här:

% emacs HelloWorld.java &

% javac HelloWorld.java

% ls

HelloWorld.class HelloWorld.java

% java HelloWorld Hello, world!

%

Starta en editor, skriv följande programtext:

public class HelloWorld {

public static void main(String[] args) { System.out.println("Hello, world!");

} }

Kompilera programmet Lista innehållet i katalogen

Två filer: kompilerad kod och källkod Kör programmet

Det är inget fel med att utveckla program på detta sätt, men det har en del nackdelar: stora program består av många klasser och det kan vara svårt att hålla reda på dem, man måste komma ihåg att kompilera varje fil som man ändrar, när kompilatorn hittar fel i ett program måste man i editorn hitta motsvarande rad i filen för att kunna rätta till felet, om man vill följa exekveringen av ett program måste man ha en separat ”debugger” (felsökningsprogram).

Ett alternativt sätt att arbeta är att använda en integrerad utvecklingsmiljö (Integrated Deve- lopment Environment, IDE). Det är ett program med ett grafiskt användargränssnitt där editor,

(30)

30 Eclipse – en handledning

kompilator och debugger är integrerade. Man startar IDE-programmet och hanterar sedan alla moment i programutvecklingen inifrån denna miljö.

Programutvecklingen består fortfarande av editering, kompilering och programkörning, men det blir enklare att utföra dessa moment — de utförs av IDE-programmet genom att man klickar på knappar eller väljer ur menyer.

Det finns många olika IDE-program, mer eller mindre avancerade (Eclipse, IDEA, JBuilder, Netbeans, JCreator, . . . ). I programmeringskurserna utnyttjas Eclipse.

Eclipse

Översikt

Eclipse är ett avancerat IDE-program som erbjuder all funktionalitet som behövs för utveckling av Javaprogram. Det finns också ett stort antal ”plugins” som utökar Eclipse med nya möjligheter (utveckling av webbprogram, databasprogram, diagramritning, andra programspråk än Java, osv). Programmet är gratis.

Eftersom Eclipse har så många möjligheter är det inte helt enkelt att lära sig att använda fullt ut. Man måste sätta sig in i en hel del terminologi och lära sig hitta bland alla menyer och kommandon. Men grunderna är inte alltför komplicerade, och de beskrivs här.

Några termer måste man känna till:

Projekt (project) Ett antal .java- och .class-filer som hör ihop, till exempel alla filer som behövs för en laboration eller en inlämningsupgift. Motsva- ras av en katalog i filsystemet.

Arbetsområde (workspace) Det område där man sparar de projekt som man skapar.

Motsvaras av en katalog i filsystemet (projekten är underkataloger till denna katalog).

Perspektiv (perspective) Utseendet hos Eclipsefönstret. Ett perspektiv har ett an- tal fönster och knappar för kommandon.

Det finns massor av möjligheter att ställa in Eclipse så att det fungerar på olika sätt (Preferences i Window-menyn). Varje inställningssida har en knapp Restore Defaults som ställer tillbaka alla inställningar till de ursprungliga.

Användning av Eclipse

Vi förutsätter i detta avsnitt att Eclipse har installerats (hur man gör skiljer sig något mellan olika datorer; se separata anvisningar). Vi förutsätter också att vi har skapat ett arbetsområde med ett projekt test0 som innehåller en fil HelloWorld.java och en kompilerad fil HelloWorld.class. Hur man skapar projekt och filer visar vi i nästa avsnitt. När man startar Eclipse får man ett fönster som visas i figur 1 (under Linux, det kan se något annorlunda ut på andra datorer):

Om det inte står Java i fönstrets titelrad så är fel perspektiv aktiverat. Byt då perspektiv med Open Perspective i Window-menyn. I projektvyn (längst till vänster under Package Explorer) ser man de projekt man har skapat. När man klickar på pilen vid ett projekt så öppnas projektet så att man ser innehållet. .java-filerna finns i katalogen src under (default package), .class-filerna finns i en katalog bin som inte visas i projektvyn.

Området i mitten är en texteditor. När man dubbelklickar på en fil i ett projekt så laddas filen in i editorn. Man kan editera flera filer samtidigt i olika flikar.

I editorn arbetar man som i alla editorer: man skriver och tar bort text som vanligt, markerar text genom att dra med musen, klipper ut och klistrar in med control-x och control-v, och så vidare. Eclipse-editorn känner till hur Javaprogram ska formateras, så den gör automatiskt indragningar där de ska vara, stoppar in en högerparentes av rätt slag när man skriver en

(31)

Eclipse – en handledning 31

Figur 1:Eclipse-fönster, Java

vänsterparentes, och så vidare. Man kan till och med formatera om en hel fil så att programmet följer kodkonventionerna; det gör man med kommandot Format i Source-menyn.

Eclipse-editorn kontrollerar också programmet och kompilerar det under tiden man skriver.

Om man skriver något som bryter mot Javas regler så markeras rader som innehåller fel med kryss till vänster om raden. Man får en förklaring av felet genom att hålla musmarkören över krysset.

Området under texteditorn har flera flikar. I Console visas utskrifter från program som körs, och där skriver man också indata till programmet. I Problems visas felmeddelanden som finns i filer som man sparat.

Man kör ett program genom att högerklicka på filen som innehåller main-metoden i projekt- vyn och välja Run As > Java Application. (Eller genom att välja Run As > Java Application i Run-menyn eller genom att klicka på Run-ikonen i verktygsraden.)

Om man råkat stänga till exempel editorfönstret utan att vilja det eller ställt till något an- nat med Javaperspektivet, så kan man återställa perspektivet till utgångsläget med kommandot Reset Perspective i Window-menyn.

Skapa projekt och klass

Nu visar vi steg för steg hur man skapar ett nytt projekt med en klass och hur man kör pro- grammet. Projektet ska heta test1 och innehålla en klass Calculator med följande utseende:

/** Calculator beräknar summan av två tal */

public class Calculator {

public static void main(String[] args) { double nbr1 = 5.5;

double nbr2 = 11.3;

double sum = nbr1 + nbr2;

System.out.println("Summan av talen är " + sum);

} }

Detta är inte ett vettigt program, eftersom det bara kan beräkna summan av talen 5.5 och 11.3.

Om man vill beräkna summan av två andra tal måste man ändra i programmet och kompilera

(32)

32 Eclipse – en handledning

om det. Något mera användbart skulle programmet bli om det läste in talen från tangentbordet, men vi gör det så enkelt som möjligt nu.

Gör följande:

1. Skapa projektet test1. Välj File > New > Java Project, skriv namnet på projektet, klicka på Finish.

2. Skapa en fil Calculator.java. Markera projektet test1 i projektvyn, klicka på New Java Class- ikonen i verktygsraden, skriv namnet på klassen (Calculator), klicka på Finish.

3. Öppna projektet, src-katalogen och (default package) genom att klicka på pilarna. Dubbel- klicka på Calculator.java för att ladda in filen i editorn. Som du ser så har Eclipse redan fyllt i klassnamnet och de parenteser som alltid ska finnas. Komplettera klassen med main- metoden som visas ovan.

4. Spara filen.

5. Kör programmet genom att högerklicka på filen och välja Run As > Java Application.

Utskriften som görs med System.out.println hamnar i konsolfönstret (om utskriften inte blir Summan av talen är 16.8 så har du skrivit fel i programmet).

En del program behöver utnyttja klasser som inte finns i det aktuella projektet. (Egentligen gör alla program det, de använder Javas standardklasser, men dessa är alltid tillgängliga och man behöver inte göra något för att programmen ska komma åt dem.) Man måste för projektet ange var dessa klasser finns. Det gör man genom att högerklicka på projektet och välja Build Path >

Configure Build Path.

Sedan finns det två fall:

• Klasserna som ska utnyttjas finns i ett annat projekt i samma arbetsområde. Klicka på Projects > Add. . . och markera projektet som innehåller klasserna.

• Klasserna som ska utnyttjas finns i en biblioteksfil (.jar-fil, Java Archive) i ett annat projekt.

Klicka på Libraries > Add JARs. . . och välj rätt .jar-fil. Om .jar-filen finns utanför arbets- området klickar man i stället på Add External JARs. . . och letar upp filen.

Hitta fel i program

Fel i program är av två slag: dels ”språkfel” som kompilatorn hittar (man glömmer ett semi- kolon, glömmer att deklarera en variabel, stavar fel till ett ord och liknande fel), dels ”logiska fel” som medför att ett program ger felaktigt resultat när det exekveras.

Som exempel tar vi programmet som beräknar summan av två tal från föregående avsnitt.

Satsen som beräknar summan och sparar den i variabeln sum ser ut så här:

double sum = nbr1 + nbr2;

Om vi i stället hade skrivit dubbel sum = nbr1 + nummer2; hade vi gjort två språkfel: typen för reella tal heter double, inte dubbel, och variabeln där värdet av det andra talet finns heter nbr2, inte nummer2. Kompilatorn markerar alla fel av denna typ, och de är för det mesta enkla att korrigera (det kan vara svårt att tolka felmeddelandena i början, men det lär man sig efterhand).

Logiska fel är svårare att hitta. Antag att vi hade skrivit satsen på följande sätt:

double sum = nbr1 - nbr2;

(33)

Eclipse – en handledning 33

Detta är en helt korrekt sats och programmet kan kompileras och köras utan problem, men resultatet blir inte korrekt (man får utskriften Summan av talen är -5.8).

Det här programmet är så litet och felet är så uppenbart att man kan hitta felet genom att bara titta på programmet. Men i allmänhet är det inte så enkelt: ”riktiga” program är mycket större och felet kan vara mycket mera komplicerat.

För att hitta logiska fel behöver man skaffa sig information om vad som händer under exekve- ringen av programmet. Ett sätt att göra det är att lägga in utskrifter av viktiga variabelvärden på lämpliga ställen i programmet (det är ju egentligen det vi gjort i ovanstående program, där vi omedelbart efter summeringen skriver ut summavärdet). Detta sätt är dock svårhanterligt och tidsödande.

Bättre är att utnyttja en debugger (”avlusare”). Då får man möjlighet att själv kontrollera exekveringen av programmet: man kan köra programmet rad för rad och man kan under tiden titta på hur variabelvärdena ändras. Man kan också sätta brytpunkter i programmet. När man sedan startar programmet så stoppas exekveringen när den når en brytpunkt.

Man sätter en brytpunkt på en rad genom att dubbelklicka till vänster om raden, och man tar bort en brytpunkt på samma sätt. När man har satt en brytpunkt kan man starta debuggern.

Det gör man genom att högerklicka på filen och välja Debug As > Java Application. Eclipse byter till debug-perspektivet. Fönstrets nya utseende visas i figur 2.

I mitten finns editorfönstret. Den rad som står i tur att exekveras är markerad med en pil.

Ovanför editorfönstret finns en vy med information om det körande programmet. I verktygsra- den finns ikoner för kommandon. De viktigaste är:

Resume — fortsätt exekveringen till nästa brytpunkt eller till programmets slut.

Terminate — avsluta exekveringen av programmet.

Step over — exekvera en rad i programmet.

Step into — exekvera till nästa rad, gå in i metoder som anropas.

Figur 2:Eclipse-fönster, debug

(34)

34 Eclipse – en handledning

Importera och exportera filer

När man arbetar med Eclipse har man normalt alla sina filer i projekt i arbetsområdet. Om man har filer någon annanstans kan man importera dem till ett existerande projekt. Det gör man genom att högerklicka på projektet, välja Import. . . > General > File System och leta upp filerna.

Genom att i stället välja Export kan man exportera filer.

Man kan också importera och exportera hela projekt. Det gör man genom att högerklicka i projektvyn och välja Import > General > Archive File respektive genom att högerklicka på ett projekt och välja Export > General > Archive File. Ett arkiverat projekt sparas som en kompri- merad .zip-fil.

Att skapa nya projekt (för egna övningar)

Du kan skapa egna projekt i Eclipse, där du kan öva på att skriva egna program. Om du lägger dina program i egna projekt hamnar de i en egen katalog i Eclipse, precis som laborationerna.

Hur du skapar ett nytt projekt ser du i avsnittet ”Skapa projekt och klass” (som börjar på s. 31). Här beskrivs hur du gör kursens klasser (SimpleWindow, Square, m. fl.) tillgängliga för ditt nya projekt. Om du inte gör detta så kommer Eclipse att ge felmeddelanden då du försöker använda dessa (t. ex. i import-satser).

• Högerklicka på ditt nya projekt i vänsterspalten i Eclipse.

• En lång meny dyker upp, där du väljer Build Path > Configure Build Path... .

• I rutan som dyker upp väljer du fliken Libraries.

• Klicka på Add JARs...

• I listan över projekt öppnar du cs_pt och väljer filen cs_pt.jar. Klicka OK för att lämna projektlistan, därefter OK för att lämna Build Path-inställningarna.

Nu ska ditt nya projekt kunna utnyttja kursens klasser, precis som laborationerna.

(35)

35

3 Java-laborationer – anvisningar

Java-laborationerna ger exempel på tillämpningar av det material som behandlas under kursen och ger träning på att skriva program. I kursen ingår 11 sådana laborationer.

• Laboration 1-5 är individuella, det vill säga att de ska lösas med självständigt enskilt ar- bete. Det är tillåtet att diskutera laborationerna och dess lösningar med kurskamraterna, men var och en måste skriva sin egen lösning. Laboration 6-11 löses i grupp om två.

Du måste arbeta med varje laboration under ”rätt” vecka (om du inte är sjuk, se nedan).

Om du är mycket ambitiös kan du dock arbeta i förväg och få flera uppgifter godkända vid ett redovisningstillfälle, under förutsättning att laborationsledaren har tid med detta.

Du får däremot inte komma i efterhand och kräva att bli godkänd på flera uppgifter (utom om du har varit sjuk).

• Till varje laboration finns det förberedelser som du ska göra före laborationen. Kontakta kursansvarig om det dyker upp några frågor när du förbereder laborationen.

Vi förutsätter att du har förberett dig innan du kommer till laborationen — det är nödvän- digt för att labhandledaren ska kunna hjälpa dig på bästa sätt.

Om du har förberett dig väl bör du hinna med alla uppgifterna under laborationen. Om du inte gör det så får du göra de resterande uppgifterna på egen hand och redovisa dem vid påföljande laborationstillfälle eller resurstillfälle (och förbereda dig mera till nästa la- boration).

• Om du är sjuk vid något laborationstillfälle så måste du anmäla detta till kursansvarig (anna.axelsson@cs.lth.se) före laborationen. Annars riskerar du att bli hänvisad till nästa gång kursen går (nästa läsår), och du kan då inte slutföra kursen (och få poäng) förrän då.

Om du varit sjuk bör du göra uppgiften på egen hand och redovisa den vid ett senare till- fälle. Har du varit sjuk och behöver hjälp för att lösa laborationen så kontakta kursansvarig Det kommer också att anordnas en ”uppsamlingslaboration” i slutet av kursen.

(36)

36 Laboration 1 – introduktion

Laboration 1 – introduktion

Mål: Under denna laboration ska du lära dig vad ett datorprogram är och se exempel på enkla program. Du ska också lära dig att editera, kompilera och exekvera enkla Java-program med hjälp av programutvecklingsverktyget Eclipse. Du ska också prova att använda Eclipse debugger.

Förberedelseuppgifter

• Läs avsnittet Bakgrund.

• Läs igenom anvisningarna om Eclipse (finns i kurskompendiet).

Bakgrund

Ett datorprogram är ett antal rader text som beskriver lösningen till ett problem. Vi börjar med att titta på ett mycket enkelt problem: att från datorns tangentbord läsa in två tal och beräkna och skriva ut summan av talen. Lösningen kan se ut så här i Java:

1 import java.util.Scanner;

2

3 public class Calculator {

4 public static void main(String[] args) {

5 System.out.println("Skriv två tal");

6 Scanner scan = new Scanner(System.in);

7 double nbr1 = scan.nextDouble();

8 double nbr2 = scan.nextDouble();

9 double sum = nbr1 + nbr2;

10 System.out.println("Summan av talen är " + sum);

11 }

12 }

Detta är nästan samma program som beskrivs i Eclipse-handledningen, men talen som sum- meras läses från tangentbordet. Du behöver inte förstå detaljerna i programmet nu, men vi vill redan nu visa ett program som gör någonting intressantare än bara skriver ut ”Hello, world!”.

Allt som behövs för att du ska förstå programmet kommer vi att gå igenom under de första veckorna av kursen. Förklaring av de viktigaste delarna av programmet:

• Rad 1: en inläsningsklass Scanner importeras från ett ”paket” med namnet java.util.

Detta paket och många andra ingår i Javas standardbibliotek.

• Rad 3: public class Calculator talar om att programmet, klassen, heter Calculator.

• Rad 4: public static void main(String[] args) talar om att det som vi skriver är ett

”huvudprogram”. Varje Javaprogram måste innehålla en klass med en main-metod. Exe- kveringen börjar och slutar i main-metoden.

• Rad 5: texten Skriv två tal skrivs ut på skärmen (println betyder ”print line”). När man använder Eclipse så hamnar utskrifter i konsolfönstret.

• Rad 6: inläsningsobjektet scan skapas. Vi kommer senare att gå igenom ordentligt vad detta betyder — nu räcker det att du vet att man alltid måste skapa ett sådant objekt när man vill läsa från tangentbordet.

• Rad 7: en variabel nbr1 som kan innehålla ett reellt tal (double-tal) deklareras. Det betyder att man skapar plats för variabeln i datorns minne. Man tilldelar också nbr1 ett talvärde som man läser in från tangentbordet med nextDouble().

• Rad 8: samma sak med variabeln nbr2.

• Rad 9: variabeln sum deklareras. Talen nbr1 och nbr2 adderas och summan lagras i sum.

(37)

Laboration 1 – introduktion 37

• Rad 10: resultatet (innehållet i variabeln sum) skrivs ut.

• Rad 11: slut på main-metoden.

• Rad 12: slut på klassen.

Uppgifter

1. Logga in på datorn.

2. Under laborationerna kommer du att använda en hel del färdigskrivna eller nästan färdig- skrivna program. Nu ska du skapa ett Eclipse-arbetsområde (workspace) som innehåller alla dessa filer.

Arbetsområdet, som heter edaa20-workspace, finns i packad form i filen edaa20-workspace.zip som hämtas från kursens hemsida:

1. Starta en webbläsare och gå till cs.lth.se/edaa20/ws.

2. En fil laddas automatiskt ner. Öppna den och packa upp innehållet. Kom ihåg var du lägger den.

Nu har du fått en katalog edaa20-workspace. Katalogen innehåller bl.a. projekt- katalogerna cs_pt, Lab01, Lab02,. . .

3. Starta Eclipse. (På Windows-maskinerna i datorsalarna hittar man Eclipse genom att söka eller under E i startmenyn). En dialogruta där du ska välja arbetsområde visas. Välj katalogen edaa20-workspace som tidigare skapades när du packade upp. I Eclipse-fönstret finns i projektvyn (”Package Explorer”, längst till vänster) projekten cs_pt, Lab01, Lab02, Lab03, . . . — det är de projektkataloger som finns i edaa20- workspace. Filerna med namn som börjar på Lab innehåller färdigskrivna program som utnyttjas under laborationerna. cs_pt innehåller en biblioteksfil (.jar-fil) med klasser som utnyttjas. I samma projekt finns källkoden (.java-filerna) till dessa klasser

— de behövs inte för laborationerna, men en del brukar vara intresserade av att titta på dem.

3. Du ska nu ladda in filen Calculator.java i en editor så att du kan ändra den. Man måste klicka en hel del för att öppna en fil:

a) Expandera projektet Lab01 genom att klicka på pilen bredvid projektet.

b) Expandera katalogen src genom att klicka på pilen.

c) Expandera paketet (default package) genom att klicka på pilen.

d) Öppna filen Calculator.java genom att dubbelklicka på filnamnet. Filen öppnas i en editorflik.

4. Kör programmet: markera Calculator.java i projektvyn, högerklicka och välj Run As >

Java Application. I konsolfönstret skrivs texten Skriv två tal. Klicka i konsolfönstret, skriv två tal och tryck på return. Observera: när man skriver reella tal ska man vid inläsning använda decimalkomma. När man skriver reella tal i programkod använder man decimalpunkt.

Man kan köra det senaste programmet en gång till genom att klicka på Run-ikonen i verktygsraden.

5. Ändra main-metoden i klassen Calculator så att fyra rader skrivs ut: talens summa, skillnad, produkt och kvot. Exempel på utskrift när talen 24 och 10 har lästs in:

Summan av talen är 34.0

(38)

38 Laboration 1 – introduktion

Skillnaden mellan talen är 14.0 Produkten av talen är 240.0 Kvoten mellan talen är 2.4

Du ska alltså efter utskriften av summan lägga in rader där talens skillnad, produkt och kvot beräknas och skrivs ut. Subtraktion anger man med tecknet -, multiplikation med *, division med /.

Under tiden du skriver så kommer du att märka att Eclipse hela tiden kontrollerar så att allt du skrivit är korrekt. Fel markeras med kryss till vänster om raden. Om du håller musmarkören över ett kryss så visas en förklaring av felet. Om man sparar en fil som innehåller fel så visas felmeddelandena också i Problem-fliken längst ner.

6. Spara filen. Filen kompileras automatiskt när den sparas.

När .java-filen kompileras skapas en ny fil med samma namn som klassen men med tillägget .class. Denna fil innehåller programmet översatt till byte-kod och används när programmet exekveras.

Man ser inte .class-filerna inuti Eclipse, men de lagras i arbetsområdet precis som .java-filerna. .java-filerna finns i en katalog src under respektive projektkatalog, .class- filerna finns i en katalog bin.

7. Kör programmet och kontrollera att utskriften är korrekt. Rätta programmet om den inte är det.

8. Du ska nu använda Eclipse debugger för att följa exekveringen av programmet. Normalt använder man debuggern för att hitta fel i program, men här är avsikten bara att du ska se hur programmet exekverar rad för rad och att du ska bekanta dig med debuggerkom- mandona.

• Sätt en brytpunkt på den första raden i main-metoden. (Läs avsnittet ”Hitta fel i program” i Eclipse-handledningen om du inte vet hur man gör.) Kör programmet under debuggern (Debug As > Java Application).

• Svara ja på frågan om du vill byta till Debug-perspektivet.

• Klicka på Step Over-ikonen några gånger. Notera att den rad i programmet som ska exekveras markeras i editorfönstret och att variabler som deklareras dyker upp i variabelvyn till höger. Variablernas aktuella värden visas i ett av eclipse-fönsterna, se till att du ser detta och kan identifiera hur variablerna får sina värden under programmets exekvering.

• Sätt en brytpunkt på raden där du skriver kvoten mellan talen.

• Klicka på Resume-ikonen för att köra programmet fram till brytpunkten.

• Klicka på Resume igen för att köra programmet till slut.

Byt tillbaka till Java-perspektivet genom att klicka på knappen Java längst till höger i verktygsfältet.

9. Följande program använder den färdiga klassen SimpleWindow:

import se.lth.cs.pt.window.SimpleWindow;

public class SimpleWindowExample {

public static void main(String[] args) {

SimpleWindow w = new SimpleWindow(500, 500, "Drawing Window");

w.moveTo(100, 100);

w.lineTo(150, 100);

(39)

Laboration 1 – introduktion 39

} }

Specifikationen av klassen SimpleWindow finns online via länk från kurshemsidan. Förkla- ring av de viktigaste delarna av programmet:

• På den första raden importeras den färdiga klassen SimpleWindow.

• Raderna som börjar med public och de två sista raderna med } är till för att uppfylla Javas krav på hur ett program ska se ut.

• På nästa rad deklareras en referensvariabel med namnet w och typen SimpleWindow.

Därefter skapas ett SimpleWindow-objekt med storleken 500×500 pixlar och med titeln ”Drawing Window”. Referensvariabeln w tilldelas det nya fönsterobjektet.

• Sedan flyttas fönstrets ”penna” till punkten 100, 100.

• Slutligen ritas en linje.

Programmet finns inte i arbetsområdet, utan du ska skriva det från början. Skapa en fil SimpleWindowExample.java:

a) Markera projektet Lab01 i projektvyn,

b) Klicka på New Java Class-ikonen i verktygsraden.

c) Skriv namnet på klassen (SimpleWindowExample).

d) Klicka på Finish.

Dubbelklicka på SimpleWindowExample.java för att ladda in filen i editorn (om detta inte redan gjorts automatiskt). Som du ser har Eclipse redan fyllt i klassnamnet och de parenteser som alltid ska finnas. Komplettera klassen med main-metoden som visas ovan.

Spara filen, rätta eventuella fel och spara igen. Provkör programmet.

10. Ändra programmet genom att välja bland metoderna i klassen SimpleWindow. Till exempel kan du rita en kvadrat, ändra färg och linjebredd på pennan, rita fler linjer, skriva text, etc.

11. Öppna filen LineDrawing.java. I filen finns följande kod, komplettera programmet så att det fungerar. Raderna med kommentarer ska ersättas med riktig programkod.

public class LineDrawing {

public static void main(String[] args) {

SimpleWindow w = new SimpleWindow(500, 500, "LineDrawing");

w.moveTo(0, 0);

while (true) {

// vänta tills användaren klickar på en musknapp

// rita en linje till den punkt där användaren klickade }

} }

Ledtråd: SimpleWindow innehåller också metoder för att ta hand om musklick. Dessa metoder har följande beskrivning:



/** Väntar tills användaren har klickat på en musknapp */

void waitForMouseClick();

/** Tar reda på x-koordinaten för musens position vid senaste musklick */

int getMouseX();

(40)

40 Laboration 1 – introduktion

/** Tar reda på y-koordinaten för musens position vid senaste musklick */

int getMouseY();

Fundera ut vad som händer i programmet. while (true) betyder att repetitionen ska fortsätta ”i oändlighet”. Man avbryter programmet genom att välja Quit i File-menyn i SimpleWindow-fönstret.

Spara filen, rätta eventuella fel och spara då igen. Provkör programmet.

Checklista

Exempel på vad du ska kunna efter laborationen:

• Starta Eclipse, öppna önskat arbetsområde (workspace) och öppna önskat projekt.

• Skapa .java-filer och skriva in enkla Java-program. (Med enkla program menas här ett program på några rader som till exempel Calculator.)

• Kunna använda metoden System.out.println och förstå vad som händer när den används.

• Förstå vad det innebär att läsa in tal från tangentbordet.

• Spara .java-filer (kompilering sker då automatiskt).

• Exekvera program.

• Använda debuggern:

Sätta och ta bort brytpunkt.

Starta debuggern.

Köra fram till en brytpunkt med Resume.

Exekvera stegvis med Step over (och senare i kursen med Step Into).

Byta mellan debug-perspektivet och Java-perspektivet.

(41)

Laboration 2 – eget spel 41

Laboration 2 – eget spel

Mål: Du ska skriva ett program med din egen kod. Du ska träna på att deklarera och använda variabler samt på att använda alternativ och repetition.

Förberedelseuppgifter

• Läs igenom texten i avsnittet Bakgrund.

• Hitta på ett spel och bestäm hur det ska fungera.

• Skissa ditt program (gärna pseudokod) på papper.

Bakgrund

På den här laborationen ska du skriva ett textbaserat spel. Du ska själv hitta på hur det ska fungera.

Inspiration

Här finns några förslag att hämta inspiration ifrån. Du kan använda något av förslagen, modifi- era något av förslagen eller hitta på något helt eget spel.

• Spela ”gissa talet” och ge ledtrådar om talet är för litet eller för stort.

• Hitta på något enkelt tärningsspel att spela med användaren.

• Träna användaren i multiplikationstabellen.

• Rita många kvadrater i ett fönster och låta användaren gissa antalet.

• Kolla reaktionstiden hos användaren genom att mäta tiden det tar att trycka Enter efter att man fått vänta en slumpmässig tid på att strängen ”NU!” skrivs ut. Om man trycker Enter innan startutskriften ges blir den uppmätta tiden 0 och på så sätt kan ditt program detektera att användaren har tryckt för tidigt. Mät reaktionstiden upprepade gånger och beräkna medelvärdet.

• Låt användaren svara på flervalsfrågor om din favoritfilm.

• Spela sten/sax/påse med användaren.

• Låt användaren på tid så snabbt som möjligt skriva olika ord baklänges.

Några metoder som kan vara bra att ha:

• Dra slumptal:

Random



/** Skapar en slumptalsgenerator(). */

Rendom();

/** Returnerar ett slumptal mellan 0 och bound-1. */

int nextInt(int bound);

/** Returnerar ett slumptal mellan 0.0 och 1.0. */

double nextDouble();

Exempel:

Random rand = new Random();

int nbr = rand.nextInt(10); // nbr tilldelas slumptal mellan 0 och 9

• Mäta tid:

System

(42)

42 Laboration 2 – eget spel



/** Returnerar aktuell tid i millisekunder. */

static long currentTimeMillis()

Exempel:

long start = System.currentTimeMillis();

• Låta programmet vänta en viss tid:

Thread



/** Låter programmet vänta millis millisekunder. */

static void sleep(long millis);

Exempel:

Thread.sleep(2000); // Programmet väntar 2 sekunder

Krav på programmet

• Ditt program måste innehålla minst ett alternativ (if-sats) och minst en repetition (for- eller while-sats).

• Din kod ska vara lätt att läsa och förstå (bra val av variabelnamn, vettig indentering ...).

• Det är en konst att begränsa sig. Se till att du inte tar dig vatten över huvudet.

Kontrollera gärna din idé med labhandledaren i början av laborationen.

Utveckla ditt program stegvis. Börja med ett program som bara gör något litet. Då har du tidigt ett program som fungerar. Bygg sedan ut det efterhand.

Datorarbete

1. Logga in på datorn, starta Eclipse, öppna projektet Lab02.

2. Skapa en fil med namnet SmallGame.java (eller något namn du väljer själv). För att skapa en fil ska du

• markera projektet Lab02

• klicka på New Java Class-ikonen eller högerklicka och välja New och därefter Class

• skriva namn på klassen (t.ex. SmallGame)

• klicka på Finish

3. Skriv ditt program. Testa och se till att spelet fungerar som avsett.

4. Låt någon annan kursdeltagare läsa ditt program och köra spelet. Notera den återkoppling du får på programmet. På samma sätt ska du ge feedback på en annan kursdeltagares program.

5. Använd den återkoppling du fick för att förbättra ditt program.

Checklista

Exempel på vad du ska kunna efter laborationen:

• Skapa .java-filer och skriva enkla program i Eclipse.

• Skriva programkod med alternativ (if-sats).

• Skriva programkod med repetition (for- eller while-sats).

(43)

Laboration 3 – vektorer 43

Laboration 3 – vektorer

Mål: Du ska träna på att läsa och felsöka programkod. Du ska träna på att skriva program där koden är uppdelad i metoder samt på vektorer.

Förberedelseuppgifter

• Läs igenom texten i avsnittet Bakgrund och lös den uppgift som finns där.

Bakgrund

SMHI har stora mängder data över Sveriges klimat och miljö. Följande värden över dygnsme- deltemperaturen i Lund under februari 2017 är hämtade från deras webbsida: 0.8, 0.3, 0.9, 2.4, 2.0, 0.8, -2.1, -2.6, -3.5, -0.6, -0.4, -0.9, -2.9, -2.4, -0.6, 2.0, 3.6, 2.9, 4.5, 5.7, 6.2, 5.7, 3.3, 0.4, -0.7, 5.3, 7.4, 5.5.

Vi kan bl.a. se att dygnsmedeltemperaturen var 0, 81 februari och att dygnsmedeltempera- turen var under 0 den 7 februari.

SMHI har också definitioner för när det är vår, sommar etc.. I programmet nedan beräknas vilket datum det blev vår i Lund 2017. Studera programmet och svara på följande frågor:

• Vad skrivs ut (dvs. vilket datum startade våren)?

• Vad är det för kriterier som används i programmet för att definiera vilket datum våren startar.

public class ComputeFirstSpringDate {

public static void main(String[] args) {

double [] februaryTemp = {0.8, 0.3, 0.9, 2.4, 2.0, 0.8, -2.1, -2.6, -3.5, -0.6, -0.4, -0.9, -2.9, -2.4, -0.6, 2.0, 3.6, 2.9, 4.5, 5.7, 6.2, 5.7, 3.3, 0.4, -0.7, 5.3, 7.4, 5.5,

4.3, 3.1, 4.3, 3.8, 3.8, 1.2};

System.out.println(firstSpringDate(februaryTemp));

}

/** Returnerar datumet för när våren startar.

Om inte våren startar under månaden returneras -1.

Vektorn a innehåller dygnsmedeltemperaturerna under månaden samt under de 6 första dygnen i nästkommande månad. */

public static int firstSpringDate(double[] a) { int nbrDays = 0;

for (int i = 14; i < a.length; i++) { if (a[i] > 0) {

nbrDays++;

if (nbrDays == 7) { return i - 6 + 1;

} } else {

nbrDays = 0;

} }

return -1;

} }

References

Related documents

”Ölyckan”, ”pechbröd”, ”dahlior” är inte bara avgörande ord för respektive text utan så laddade att de i samspel skapar ett språk (här: sätt att tala)

Ur intervjuerna kan det utläsas att klientens historia spelar in i socialsekreterarnas avvägningar och bedömningar, både genom att säga någonting om vad klienten har klarat av

• Notera att vi inte har skapat Dice-objekten än, utan enbart en vektor med plats för 5 referensvariabler som inte pekar på något (null). dices null

Det finns en färdig klass Random för att generera slumptal.. Övning

HJÄLP MED LÄXOR för barn från 10 år och äldre.

[texten uppvisar här dels en intentionalitet – det kroppsliga livets möjliga riktning mot frihet – och dels, implicit, ett etiskt ställningstagande, då det låter den

De pekar på Östergötland och menar att de lyckades korta köerna när man införde vårdval 2013, men att hörselvården blivit betydligt sämre!. Bland annat pekar man på att

Material våg med en eller två decimaler, vatten, brustabletter (typ C-vitamintabletter), sockerbitar, bägare eller liknande kärl, mätglas, större skål som rymmer mätglaset