Tentamen i EDA011 Programmeringsteknik för F, E, I, π och N Måndagen den 24 april 2006 Skrivtid: 8.00 13.00 Tillåtna hjälpmedel: Java-snabbreferens. Resultat: Resultatet av denna tentamen rapporteras direkt in i LADOK vi kommer inte att sätta upp någon tentamenslista, så ditt resultat kommer inte att anslås för andra än dig själv. Behörighet: För att vara behörig att skriva tentamen måste du ha blivit godkänd på samtliga inlämningsuppgifter. Den som skriver utan att ha blivit godkänd på uppgifterna, och inte fått dispens, kommer att få sin tentamen annullerad du behöver dock inte vara orolig om du har blivit godkänd på dina uppgifter, men de av något skäl inte har förts in i pthandin kontakta i så fall Christian. Instruktioner: Tentornas svårighetsgrad kan variera, men det är alltid lika lätt/svårt att bli godkänd en svårare tenta bedöms snällare än en lätt tenta, och vice versa. Oavsett hur lätt/svår du tycker att denna tenta är, gör ditt bästa. För att bli godkänd behöver du inte göra något som du inte redan gjort på inlämningsuppgifterna. Denna tentamen består av två delar: Del 1 består av uppgift 1-3, som alla bör behandla. Del 2 utgörs av uppgift 4, och riktar sig till dem som strävar efter överbetyg. Uppgiften är inte nödvändigtvis svårare än uppgifterna i del 1, men den kommer att rättas något strängare. Det maximala poängantalet på varje uppgift är angivet vid uppgiften, betygsgränser bestäms i samband med rättningen. Om det är något du är osäker på under tentamen, fråga Christian. Du får gärna skriva på papprets båda sidor. Direkt efter tentamen kommer ett lösningsförslag att läggas ut på kurshemsidan. Del 1 Denna del av tentamen bör alla behandla efter bästa förmåga, godkänt kan ge betyget 3 eller 4. Du bör vara noggrann med variabelnamn och indragningar om du glömmer en klammer, och inte indragningarna visar tydligt hur du har tänkt, så kommer vi att göra poängavdrag. Vi skall denna gång skriva programkod för att administrera den europeiska finalen i melodifestivalen. Vi kommer att använda följande klasser: Country: som beskriver ett land. Varje land har ett namn, en landskod (exempelvis swe, som används för att förenkla inmatningen av resultat), och en totalpoäng. Contest: som beskriver hela tävlingen, med alla deltagande länder och deras röster. Varje land röstar på 10 andra länder, som får 1 till 10 poäng. För att beskriva detta har vi de två klasserna Vote och VotingResult: 1
ett Vote-objekt innehåller ett antal poäng och en referens till ett land (som skall ha poängen), ett VotingResult-objekt beskriver hur ett land röstar, dvs det innehåller en vektor med 10 Vote-objekt. Om allt går rätt till så finns det i ett VotingResult-objekt inte någon röst på landet som har röstat, dessutom innehåller dess Vote-vektor referenser till 10 olika länder (man kan inte ge både 4 och 7 poäng till samma land). Klassen Vote har följande specifikation: class Vote: Vote(Country country, int points) Skapar en röst där ett givet land får ett givet antal poäng. country: det land som får poäng, points: det antal poäng landet får. Country getcountry() Ger en referens till landet som får poängen. int getpoints() Ger antalet poäng som landet får. Klassen Vote är färdigskriven, du behöver inte själv implementera den. Klassen VotingResult skall du däremot skriva själv (se uppgift 1), den har specifikationen: class VotingResult: VotingResult(Country country) Skapar ett objekt som skall beskriva hur ett givet land röstar (landets röstningsresultat ). country: landet som skall rösta. Country getcountry() Ger en referens till det land vars röstningsresultat detta objekt beskriver. void add(country country, int points) Lägger in en ny röst som ger ett givet land ett givet antal poäng vi kan här förutsätta att detta röstningsresultat inte redan innehåller en röst på det givna landet, eller en röst med det givna antalet poäng. Vi kan även förutsätta att det röstande landet inte försöker ge poäng till sig själv (dessa saker testas i huvudprogrammet). Denna operation skall inte själv öka antalet poäng som landet har fått, det löser vi senare. country: en referens till det land som skall få poäng, points: antal poäng som delas ut. boolean containsvotefor(country country) Undersöker om detta röstningsresultat innehåller en röst på ett givet land. country: det land som skall undersökas. Vote getvote(int points) Ger den röst som gav ett visst antal poäng. Vi kan förutsätta att rösterna har lagts in i tur och ordning (dvs att det första anropet av add hade points-värdet 1 och det sista anropet hade points-värdet 10). points: det antal poäng vi är intresserade av (1-10). Klassen VotingResult skall ha följande attribut: private Country country; // det land som ger rösterna private Vote[] votes = new Vote[10]; private int nbrofvotes = 0; När ett land röstat färdigt (dvs när vi anropat add-operationen för 10:e gången) skall nbrofvotesattributet ha fått värdet 10. Uppgift 1 (8 poäng) Implementera klassen VotingResult. 2
Specifikationerna för klasserna Country och Contest är: class Country: Country(String name, String code) Skapar ett nytt land. name: landets namn (exempelvis ( Sverige ), code: landets landskod (exempelvis swe ). String getname() Ger landets namn. String getcode() Ger landets landskod. void addpoints(int points) Ökar landets totala poängantal. points: antal nya poäng. int getpoints() Ger landets totala antal poäng. class Contest: Country findcountry(string countrycode) Söker efter ett land med en given landskod, returnerar null om inget sådant land är inlagt. countrycode: den aktuella landskoden. void inputcountries() Låter användaren mata in ett antal länder (se beskrivning nedan). boolean hasvoted(country country) Undersöker om ett givet land redan har röstat. country: det aktuella landet. VotingResult inputvotingresult(country country) Låter användaren mata in röstningsresultatet från ett land (se beskrivning nedan). Denna operation skall bara skapa och returnera ett VotingResult-objekt, det skall inte ge de olika länderna några poäng (det sköts av operationen apply nedan). country: en referens till landet som skall rösta. void apply(votingresult votingresult) Ger de deltagande länderna de poäng som ett land givit, lagrar röstresultatet i results-attributet (se nedan). votingresult: röstningsresultatet (med de poäng som skall delas ut). void printresults() Skriver ut resultatet efter de hittills inlagda röstresultaten. Resultatet är inte sorterat utan visar bara samtliga deltagande länders namn och poängsumma. Klassen Country är färdigskriven (du skall alltså inte skriva den), men du skall själv skriva klassen Contest. I denna klass skall vi lagra samtliga länder, och alla de VotingResult-objekt som har matats in (vi lagrar dem när apply-operationen anropas). Klassen Contest skall ha följande attribut: private Country[] countries = new Country[32]; private int nbrofcountries; private VotingResult[] results = new VotingResult[32]; private int nbrofvotingresults; Inmatningen av länder i inputcountries skall se ut som i följande exempel (understruken text är det som användaren matar in): Landskod: swe Landsnamn: Sverige Landskod: den Landsnamn: Danmark Landskod: swe Du har redan lagt in Sverige. 3
Landskod: nor Landsnamn: Norge Landskod: Inmatningen av länder avslutas när användaren matar in en tom landskod. Operationen inputvotingresult skall ha följande dialog (vi antar att det är Sveriges röstningsresultat som skall matas in det som användaren matar in är understruket): Vem skall få 1 poäng: nor Vem skall få 2 poäng: nor Ni har redan gett poäng till Norge Vem skall få 2 poäng: jpn Inget sådant land deltar! Vem skall få 2 poäng: swe Ni får inte rösta på er själva! Vem skall få 2 poäng: den Vem skall få 3 poäng: ger Vem skall få 10 poäng: uk Uppgift 2 (27 poäng) Implementera klassen Contest enligt beskrivningen ovan. Vi vill även ha ett huvudprogram, som skall ha följande dialog: Vad vill du göra: 1. Mata in länder. 2. Mata in resultat. 3. Skriva ut resultat. 0. Avsluta. Ange kommando (0-3): 1 När användaren vill mata in resultat från ett land skall vi få följande dialog (om vi utgår ifrån att Sverige redan har röstat): Vem skall rösta (landskod): jpn Något sådant land deltar inte. Vad vill du göra: 1. Mata in länder. 0. Avsluta. Ange kommando (0-3): 2 Vem skall rösta (landskod): swe Sverige har redan röstat! Vad vill du göra: 1. Mata in länder. 0. Avsluta. Ange kommando (0-3): 2 Vem skall rösta (landskod): nor Vem skall få 1 poäng: swe Vem skall få 2 poäng: nor Ni får inte rösta på er själva! Uppgift 3 (10 poäng) Skriv ett huvudprogram enligt beskrivningen ovan. 4
Del 2 Följande del av tentamen behöver bara behandlas av dem som eftersträvar betyget 5 den rättas inte om inte första delen av tentamen är godkänd. Resultatet på denna del räknas bara in i totalresultatet om den är godkänd, dvs ger minst 4 poäng (man kan alltså inte höja sitt betyg genom att ta någon enstaka poäng på denna del). Uppgiften är inte nödvändigtvis svårare än uppgifterna i föregående del, men vid rättningen av denna del har vi större krav på stil och effektivitet än då vi rättar del 1. Herr S är både morgonmänniska och kvällsmänniska, men inget vidare mitt på dagen han vill därför hitta det längsta uppehållet i sitt schema under dagen, och lägga in en tupplur. Schemat för en dag består av ett antal händelser, som var och en beskrivs på tre rader: en rad med starttidpunkten, som två heltal, en rad med sluttidpunkten, som två heltal, en rad med information om vad som skall göras (kan läsas som en textsträng). Du behöver inte bekymra dig om formatet vid inläsning av tidpunkter och information om av som skall göras det räcker att läsa in fyra heltal och en sträng. Efter sista händelsen står en ensam 0:a på en rad. Det är inte givet att händelserna står uppräknade i tidsordning, men vi kan förutsätta att inga händelser överlappar varandra i tiden. Herr S börjar alltid arbeta klockan 8.00 på förmiddagen, och går hem klockan 17.00 på eftermiddagen om den längsta sammanhängande ledigheten inträffar före det första mötet eller efter det sista mötet så använder han denna ledighet för sin tupplur. Ett exempel på schema: 10 15 12 00 föreläsning i E:A 12 15 13 00 extragenomgång i E:B 15 15 17 00 övningar i källaren 13 15 14 00 möte i E:1423 9 00 9 30 möte i lunchrummet 0 I detta exempel har herr S fem ledigheter under dagen, bland annat en timme före första mötet (mellan 8.00 och 9.00), trekvart efter första mötet (mellan 9.30 och 10.15), och en timme och en kvart efter andra mötet (mellan 14.00 och 15.15) i detta fall skulle han förlägga sin tupplur till mellan 14.00 och 15.15, och vi vill ha utskriften: Du kan boka in en tupplur från 14.00 till 15.15, mellan möte i E:1423 och övningar i källaren. Längden på tuppluren blir 1.15. Om tuppluren skall läggas före den första bokningen vill vi ha utskriften mellan arbetsdagens början och i exemplet ovan, och motsvarande om tuppluren inträffar efter sista bokningen. En riktigt bra dag skulle kunna se ut så här: 0 och då kan den gode herr S ta en 9 timmar lång tupplur. En dålig dag kan det däremot vara så illa att herr S arbetar oavbrutet, och programmet skall då meddela att det inte blir tid för någon tupplur. Uppgift 4 (15 poäng) Skriv det program som efterfrågas i texten ovan. För full poäng skall ditt program vara välstrukturerat och använda lämpliga klasser med lämpliga operationer, att skriva all programkod i huvudprogramet räcker inte! För full poäng kan du heller inte förutsätta att händelserna är inmatade i tidsordning. 5
För att lösa uppgifterna är det viktigt man förstå hur de grundläggande klasserna hänger ihop, men tentan kräver inte att du skall skriva mer programkod än vanligt, snarare tvärtom. Figurerna på detta papper är gjorda för att du lättare skall förstå hur klasserna fungerar var inte rädd att fråga om det är något du undrar över! Vi kommer att använda ett delvis nytt poängräkningsystem, som jag hoppas är lättare att förstå än de vi tidigare använt. Gör så gott du kan, om det visar sig att tentamen skulle vara svårare än normalt kommer poänggränserna att anpassas till detta. Om vi antar att Sverige håller på och röstar, och har gett Norge 1 poäng och Danmark 2 poäng, så ser det VotingResult-objekt som vi håller på att generera ut som i figuren intill. Vi skapar detta VotingResult-objekt inne i operationen inputvotingresult och skickar tillbaks det till huvudprogrammet. I detta fall skall användaren mata in 8 länder till innan VotingResultobjektet är färdigt. Från huvudprogrammet skall vi sedan skicka in det VotingResult-objekt vi har skapat till apply-operationen, som ger länderna sina poäng. 6