25
Hemtentamen november HT 2007 - 1 - Programmera med DotNet Hemtentamen 18-19 november 2007 (Version 1.3) Hemtentamen börjar kl 09.00 18/11 och slutar kl 09.00 20/11. Svaren på uppgifterna ska redovisas dels i ett svarsformulär i PingPong, dels genom en zip-fil som även den ska lämnas in via ett speciellt formulär i PingPong som heter ”Inlämning av zip-fil till hemtentamen november”. Både zip-filen och svarsformuläret måste skickas in före kl 09.00 den 20/11. Du kan ställa frågor om tolkningar av uppgifterna mm under själva tentamenstiden. Skicka det som PIM till Mats. Alla frågor som besvaras och som bedöms av intresse för alla andra kommer även att läggas ut i en diskussionsgrupp som hör till tentan. OBS - Det är INTE meningen att ni själva ska lägga in något där! Alla uppgifter ska lösas självständigt! Det är självklart inte tillåtet att samarbeta på denna hemtentamen! Anvisningar för zip-filen som ska skickas in. Zip-filen måste heta nnnnn.zip där nnnnnn är ditt efternamn_förnamn. T.ex. Nordstrom_Mats.zip. Den ska innehålla två kataloger Uppgift 4 samt Uppgift 6 (Det är alltså två uppgifter som ska redovisas på detta sätt) Se närmare i dessa uppgifter vad som ska redovisas. De ska även innehålla ett textdokument som ska heta readme.txt I readme.txt ska du tala om vad du heter och där ska du även skriva in en rad där det står: Min egen tentamenskod är XXXXXX Vad XXXXX är ska du hitta på själv, det ska INTE vara något av dina egna lösenord! Vi ska sedan kunna fråga dig: "Vilken tentamenskod hade du" så du måste komma ihåg vad du skrev här. (Detta för att vi i efterhand ska kunna kontrollera att det var din zip-fil) Zip-filen ska du sedan lämna in via det inlämningsformulär som finns i mappen för hemtentan och som ligger omedelbart efter svarsformuläret. Sist i själva svarsformuläret i PingPong ska du även markera om du har skickat in en zip-fil och vilka uppgifter den innehåller. Obs: När du fyller i småluckor i PingPong får du INTE ta med blanka tecken. När du klistrar in kod i större textfält ska du klistra in koden exakt som den är! (Här får du förståss inte ta bort blanktecken!!!) Oavsett vad PingPong säger så är gränsen för G 50%.

Programmera med DotNet Hemtentamen 18-19 november 2007user.it.uu.se/~matsn/ppa/ht2007/tenta_november_2007.pdf · 2007-11-19 · Hemtentamen november HT 2007 - 1 - Programmera med

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Hemtentamen november HT 2007 - 1 -

Programmera med DotNet Hemtentamen 18-19 november 2007 (Version 1.3)

Hemtentamen börjar kl 09.00 18/11 och slutar kl 09.00 20/11. Svaren på uppgifterna ska redovisas dels i ett svarsformulär i PingPong, dels genom en zip-fil som även den ska lämnas in via ett speciellt formulär i PingPong som heter ”Inlämning av zip-fil till hemtentamen november”. Både zip-filen och svarsformuläret måste skickas in före kl 09.00 den 20/11. Du kan ställa frågor om tolkningar av uppgifterna mm under själva tentamenstiden. Skicka det som PIM till Mats. Alla frågor som besvaras och som bedöms av intresse för alla andra kommer även att läggas ut i en diskussionsgrupp som hör till tentan. OBS - Det är INTE meningen att ni själva ska lägga in något där! Alla uppgifter ska lösas självständigt! Det är självklart inte tillåtet att samarbeta på denna hemtentamen! Anvisningar för zip-filen som ska skickas in. Zip-filen måste heta nnnnn.zip där nnnnnn är ditt efternamn_förnamn. T.ex. Nordstrom_Mats.zip. Den ska innehålla två kataloger Uppgift 4 samt Uppgift 6 (Det är alltså två uppgifter som ska redovisas på detta sätt) Se närmare i dessa uppgifter vad som ska redovisas. De ska även innehålla ett textdokument som ska heta readme.txt I readme.txt ska du tala om vad du heter och där ska du även skriva in en rad där det står: Min egen tentamenskod är XXXXXX Vad XXXXX är ska du hitta på själv, det ska INTE vara något av dina egna lösenord! Vi ska sedan kunna fråga dig: "Vilken tentamenskod hade du" så du måste komma ihåg vad du skrev här. (Detta för att vi i efterhand ska kunna kontrollera att det var din zip-fil) Zip-filen ska du sedan lämna in via det inlämningsformulär som finns i mappen för hemtentan och som ligger omedelbart efter svarsformuläret. Sist i själva svarsformuläret i PingPong ska du även markera om du har skickat in en zip-fil och vilka uppgifter den innehåller. Obs: När du fyller i småluckor i PingPong får du INTE ta med blanka tecken. När du klistrar in kod i större textfält ska du klistra in koden exakt som den är! (Här får du förståss inte ta bort blanktecken!!!) Oavsett vad PingPong säger så är gränsen för G 50%.

Hemtentamen november HT 2007 - 2 -

Uppgift 1: Viktiga Begrepp Vilka av nedanstående påståenden stämmer in på begreppen som följer efteråt?

Bokstav Påstående

A En slags typ som specificerar ett kontrakt över vad objekten till en klass kan göra, men inte hur det görs. Den klass som implementerar detta kontrakt måste även implementera det beteende som specificeras av kontraktet.

B Här reserveras plats för 1000 heltal när man exekverar satsen: int[] a = new int[1000];

C Ansvarar för att försöka snabba upp koden under exekveringen D Ett fenomen som möjliggörs av arv och överskuggning. E Är kopplat till hur väl ett stycke kod hänger ihop logiskt. F En form av accessor-metod som gör att vi kan ge åtkomst till en privat collection

genom samma typ av notation som används för vanliga arrayer. G En teknik som används för att avgöra vilken klass som skall implementera vad i en

applikation. H Beskriver hur klasser är beroende av varandra. I Ett gemensamt mellan-nivåspråk. J Genom att använda detta kan man åstadkomma så att man utifrån kan läsa av värdet på

instansvariabler men inte ändra värdet på dem. K Vid parameteröverföring så får den formella parametern en referens till den aktuella. L En sådan klass får inte instantieras. M Metodvalet kan avgöras redan vid kompileringen. N Ett sätt att hantera fel som uppkommer vid exekveringen av ett program. O Med hjälp av denna teknik kan flera metoder i samma klass exekvera ”samtidigt” P Applikationer som inte exekveras under kontroll av CLR-en. Q Typer av dessa slag kan en användare inte definiera själv. R En slags datatyp där programmeraren i förväg exakt kan definiera vilka värden som är

tillåtna. S Används i .NET för att undvika namnkonflikter. T Den kan expandera sig själv vid behov

I PingPong kommer frågan att se ut så här: (med reservation för radbrytningar) Uppgift 1 - Viktiga begrepp. Skriv in Motsvarande bokstav före det begrepp du anser passa bäst ihop Observera att det finns 5 påståenden som inte matchar begreppen! [ ] JIT [ ] Abstract [ ] Indexer [ ] Coupling [ ] ArrayList [ ] Interface [ ] Unmanaged code [ ] Exception [ ] Cohesion [ ] Statisk bindning [ ] Primitive types [ ] Trådning [ ] Property [ ] Ansvarsdriven design [ ] Enumeration

Uppgift 2: OO och vintersemester.

Varje år brukar vi försöka hyra en stuga en långhelg för skidåkning med alla barn och barnbarnen. Förra året var vi i närheten av Romme Alpin, en skidanläggning som ligger nära Borlänge. Vi fick tag på en stor stuga, fyra rum och kök, så vi fick gott om plats. En bastu fanns det också och den använde vi som torkrum. Att kalla Romme för Alpin var väl lite att ta i, visst fanns det många bra nedfarter men inte var de precis som en alppist heller. Och någon kabinbana fanns det inte! Men det var trevligt, kul och tur med vädret hade vi också. Några av barnen gick i skidskola och för de allra minsta fanns en pulkabacke. Och ville man prova något nytt fanns många olika slags skidor och snowboards att hyra. På kvällarna spelade vi kort eller sällskapsspel – TV’n skippade vi! Fråga 1 och fråga 2 utgår! På grund av ”ett tekniskt fel” kom svaren på fråga 1 och 2 att vara med i version 1.0 så därför utgår nu dessa två delfrågor. Frågorna finns kvar i PingPong och du får gärna svara på dem där för övnings skull men jag kommer inte att ge poäng för svaren. Fråga 3 - Vilka av följande rader avser arv pappaklass barnklass skidbacke alppist rum torkrum pulkabacke nedfart sällskapsspel kortspel barn barnbarn skidor snowboard snowboard utrustning släplift lift I PingPong kommer fråga 1,2,3 att visas som alternativfrågor där du ska markera det rätta alternativen. Fråga 4 Antag att följande begrepp ska implementeras antingen som en abstrakt klass eller som en icke abstrakt klass eller som ett interface. Markera för var och ett av orden nedan vilket som är den troligaste implementationen. ( i denna delfråga avses normalbetydelsen av orden och de har egentligen ingenting med texten ovan att göra även om flera ord även förekommer där) Skidutrustning Långfärdsskridskor Kläder Maskintvättbar CD-bok Maskintvättmedel

Hemtentamen november HT 2007 - 3 -

Hemtentamen november HT 2007 - 4 -

I PingPong kommer detta som ett lucktest där du ska fylla i A för abstrakt klass, K för klass och I för interface.

Hemtentamen november HT 2007 - 5 -

Uppgift 3: Hur ser det ut? Betrakta följande klass: class Låda { public int N; public Låda A; public Låda B; public Låda(int N) { this.N = N; this.A = this; this.B = this; } public Låda(int N, Låda A):this(N) { this.A = A; } public Låda(int N, Låda A, Låda B):this(N,A) { this.B = B; } public void Connect(Låda A, Låda B) { this.A = A; this.B = B; } } Någon annan stans gör man: Låda låda; låda = new Låda(1, new Låda(2), new Låda(3)); låda.A.A = new Låda(4, låda); låda.B.A = new Låda(5, new Låda(6, låda.A, låda.B)); // Fråga a,b,c ska besvaras i deetta läge låda.A.Connect(låda, låda.B); // Resten av frågorna ska besvaras i detta läge Hur ser det ut? Rita upp den struktur som nu skapats i minnet innan den sista satsen (den med metoden Connect) har exekverats. Det ska bli ett antal lådor, en för varje objekt och i varje låda ska det finnas en siffra som vi nedan kallar "lådans nummer". Om vi säger låda3 så menar vi den låda som har siffran 3 i sig. Du ska nu först beskriva den bild du ritat genom att svara på frågorna a till c nedan. Antag för frågorna a,b och c att satsen låda.A.Connect(låda, låda.B); INTE har exekverats ännu! a) Hur många lådor är det?

Hemtentamen november HT 2007 - 6 -

b) Hur många referenser (pilar) finns det som går till låda3? c) Om du startar från låda (som i din figur bör kallas för låda1), vilken är den längsta väg som du

kan ta för att komma tillbaka till låda (låda1) utan att passera någon annan låda flera gånger. Beskriv vägen genom att tala om vilka A eller B man ska följa. Om du t.ex. anser att låda.A.B.A refererar till låda så ska du svara ABA.

I det följande antar vi att satsen låda.A.Connect(låda, låda.B); har exekverats. d) Om vi lägger in Console.WriteLine(låda.???.N); alldeles efter Connect-anropet, vad ska det då stå i stället för ??? för att utskriften ska bli 1.

Svara med det kortaste uttryck som är möjligt. e) Det finns nu en låda som lever lite farligt och som antagligen kommer att försvinna vid nästa

skräpsamling. Vilken låda? f) Om du tittar på din figur så ser du att det finns några lådor förutom den som ”försvann” i

skräpsamlingen som har referenser till sig själv i sina A eller B-variabler. Välj nu ut den låda med det lägsta N-talet och skriv en sats, så kort som möjligt, så att den referens som nyss pekade till sig själv pekar till den låda med det högsta N-talet i stället!

Hemtentamen november HT 2007 - 7 -

I PingPong kommer frågorna att se ut så här: Uppgift 3, Hur ser det ut? a) Hur många lådor är det? [ ] b) Hur många referenser (pilar) finns det som går till låda3? [ ] c) Om du startar från låda (som i din figur bör kallas för låda1), vilken är den längsta väg som du

kan ta för att komma tillbaka till låda (låda1) utan att passera någon annan låda flera gånger. Beskriv vägen genom att tala om vilka A eller B man ska följa. Om du t.ex. anser att låda.A.B.A refererar till låda så ska du svara ABA.

[ ] OBS! I det följande antar vi att satsen låda.A.Connect(låda, låda.B); har exekverats. d) Vad ska det då stå i stället för ??? i satsen Console.WriteLine(låda.???.N); för att utskriften ska bli 1. Svara med det kortaste uttryck som är möjligt. [ ] e) Det finns nu en låda som lever lite farligt och som antagligen kommer att försvinna vid nästa

skräpsamling. Vilken låda? Svara bara med en siffra = lådans N-värde. [ ] f) Om du tittar på din figur så ser du att det finns några lådor förutom den som ”försvann” i

skräpsamlingen som har referenser till sig själv i sina A eller B-variabler. Välj nu ut den låda med det lägsta N-talet och skriv en sats, så kort som möjligt, så att den referens som nyss pekade till sig själv pekar till låda (låda1) i stället!

Och – snälla snälla – ta INTE med några blanka tecken och glöm inte att ta med ; [ ]

Uppgift 4. KontrollKontrollanten Man vill ”samla” flera olika slags kontroller i ett fönster i olika ”grupper” så att man sedan enkelt kan visa upp eller gömma en hel grupp av kontroller på en gång. Till sin hjälp tänker man sig att ha en klass som sköter om detta. Skriv därför en klass KontrollKontrollanten med följande grundläggande metoder.

public void Add(Control c, string grupp) public void Visa(string grupp) public void Göm(string grupp)

Metoden Add ska spara kontrollen c tillsammans med sin gupptillhörighet grupp. Metoden Visa ska se till så att alla kontroller som sparats i gruppen grupp ska visas, övriga ska vara som de är för tillfället (visade eller gömda). Om gruppnamnet är alla så ska alla kontrollerna visas oavsett grupptillhörighet. Metoden Göm är som Visa men man ska gömma kontrollerna i stället. Tips: För att visa eller gömma en kontroll av typ Control kan man använda egenskapen Visible Uppgift 4a. Skriv klassen KontrollKontrollanten enligt ovanstående specifikation och redovisa den som Uppgift 4a i PingPong. OBS om du gör alla uppgifterna, läs sist hur de ska redovisas! Uppgift 4b. Skapa ett testformulär där du kan testa din klass. Här är en bild på ett formulär som jag har använt:

Den gula PictureBoxen och Label A2 har sparats i grupp a och textboxen B1 och radioknappen B2 har sparats i grupp b. När man sedan trycker t.ex. Göm så göms alla som tillhör den grupp man skrivit in i textboxen bredvid knapparna. I detta fall allihop men om man skriver a i stället för alla och sedan trycker på Göm så är det bara den gula rutan och A2 som göms. I ditt testformulär måste du ha minst två olika grupper och minst två kontroller i varje grupp. Redovisa koden för ditt formulär i Pingpong under rubriken Uppgift 4b.

Hemtentamen november HT 2007 - 8 -

Hemtentamen november HT 2007 - 9 -

Uppgift 4c Nu ska du ändra lite i KontrollKontrollanten så att den blir lättare att använda. Lägg in följande konstruktor: public KontrolKontrollanten(Button visa, Button göm, TextBox vad) Man ska alltså ”ge” KontrollKontrollanten de båda knapparna som används som Visa och Göm-knapp. Man ska även ge kontrollanten den textbox där man ska skriva in vilken grupp som ska visas eller gömmas. Tänk dig sedan att KontrollKontrollanten är en klass som kan läggas i ett bibliotek och det enda en användare nu ska behöva veta är dels konstruktorn, dels den publika metoden Add. Användaren ska inte längre kunna se metoderna Visa och Göm utan dessa ska du antingen ta bort eller deklarera som privata (om KontrollKontrollanten själv skulle ha användning för dem) Gör även det testformulär som behövs för att testa uppgiften. Använd helst samma utseende som du hade i förra deluppgiften. Redovisa koden för både KontrollKontrollanten och ditt testformulär i PingPong under rubriken uppgift 4c Uppgift 4d Hittills är det bara objekt av typ Control som kan användas. Nu vill man istället göra så att vilket objekt som helst ska kunna få vara med under förutsättningen att objektet har en publik metod Visa(bool b). Om Visa anropas med true så ska objektet synas på skärmen och om Visa anropas med false så ska objektet inte synas. För redovisningens skull ska du nu först göra en ny klass KontrollKontrollanten_4d som är en kopia av KontrollKontrollanten (fast med nytt namn på konstruktorn förståss). Sedan skriver du om denna klass och redovisar denna klass så att vi ser vilka ändringar du har gjort. Gör även i princip samma testformulär som tidigare där minst fyra kontroller ska vara med. Redovisa koden för både KontrollKontrollanten_4d och ditt testformulär samt övrig eventuell kod som du skrivit i PingPong under rubriken Uppgift 4d Uppgift4e Bifogat finns en klass Uppgift4e.Test som har en enda synlig metod ShowMe. Den finns i filen Uppgift4e.dll som finns att ladda ner och den ska läggas till projektets resurser. (i VS högerklicka Resources i Solution Explorer och leta upp filen) (Klassen heter egentligen Test men den finns i namespace Uppgift4e så du kan använda hela namnet Uppgift4e.Test eller du kan lägga in using Uppgift4e i början och använda Test inne i programmet). Konstruktorn har ett argument och det ska vara ditt eget testformulär (där de andra kontrollerna ligger) och metoden ShowMe(bool b) visar upp objektet om b är true, annars göms objektet. Se till så att den kommer med på något sätt, gärna i en egen grupp u4d. Du får inte ändra något i KontrollKontrollanten_4d från uppgift 4d! KontrollKontrollanten_4d är tänkt att ligga i ett bibliotek och redan den variant som du gjorde i 4d ska klara att visa upp Uppgift4e.Test.

Hemtentamen november HT 2007 - 10 -

Redovisa för den kod du använt för att visa upp Uppgift4e.Test i PingPong under rubriken uppgift4e. (Testformuläret och övrigt som du använt men KontrollKontrollanten_4d visar du här ENDAST om du ändå gjort några ändringar i den sedan uppgift 4d. Tala även om vad du såg när den visades upp! OBS. Inte i någon av ovanstående uppgifter får du använda delegater annat än för Click-hanteringen när man trycker på en knapp! (De delegater som Visual Studio genererar automatiskt åt formuläret är undantagna). Det går visserligen att lösa uppgifterna med delegater men i denna tentamen låtsas vi just nu att du inte läst om delegaterna ännu och dessutom skulle det skymma sikten för vad vi vill se att du lärt dig! Behöver jag redovisa alla uppgifterna om jag gjort alla? Om du gjort 4a, 4b och 4c räcker det att redovisa 4b och 4c men i PingPong i rutan för 4a skriver du att du visar upp klassen i 4c i stället. Har du dessutom gjort 4d ska klassen KontrollKontrollanten_4d redovisas för sig! Dessutom ska all övrig kod inklusive testformulär redovisas. Har du dessutom gjort 4e ska du redovisa all ny kod du gjort jämfört med 4d. Uppgift 4d och 4e beror inte av varandra utan du kan lösa t.ex. 4e utan att lösa 4d eller tvärtom. Det finns flera olika sätt att lösa 4d och 4e på. För full poäng på både 4d och 4e krävs att du använder två olika sätt att lösa det på, båda sätten utan att använda delegater. Använder du i princip samma sätt på 4d och 4e blir det ett litet avdrag, max -1p.

Hemtentamen november HT 2007 - 11 -

Uppgift 5. Lexikon På en programmeringskurs i C# fick studenterna följande uppgift: Deluppgift a (till studenterna) Skriv en klass Lexikon som kan användas för att spara ord tillsammans med ordets betydelse. Man ska kunna spara flera olika betydelser under samma ord. Man ska kunna få en sorterad utskrift av alla orden och deras betydelse(r). Se API nedan. API för Lexikon: Lexikon(String Name) Konstruktor. Man ska kunna göra olika lexikon med olika namn.

Namnet ska visas på utskriften. public void Add(String ord, String betydelse) Lägg in ett ord samt dess betydelse i lexikonet. public void Visa() Visa upp först en rad med namnet på detta lexikon, därefter alla ord

samt deras betydelser. Listan ska formateras som i körexemplet nedan. Utskriften ska ske på Consol

protected virtual void Skriv(String s) All utskrift ska ske i Skriv som bara ska göra Console.Write(s) Se mer i deluppgift b nedan. Klassen ska kunna provas med följande kod: Lexikon bok = new Lexikon("Min ordbok"); bok.Add("vis", "klok (genom erfarenheter under ett långt liv)"); bok.Add("visa", "namn på ett kreditkortsföretag"); bok.Add("visa", "låta (någon) se"); bok.Add("visa", "sång"); bok.Add("mulla", "Att gnida in snö i någons ansikte"); bok.Add("tulla", "Att betala tull"); bok.Add("tulla", "Att ta mindre mängd av (något som bör sparas)"); bok.Add("bank", "företag som lånar ut pengar, sysslar med värdepapper etc"); bok.Add("bank", "vall, underlag för väg el. järnväg"); bok.Add("bank", "grus- el. sandrygg i vatten"); bok.Add("bank", "molnvägg"); bok.Add("bank", "förvaringsplats, förråd"); bok.Add("hälsa", "tillstånd där man mår bra, friskhet"); bok.Add("hälsar", "säga goddag, välkomna"); bok.Add("hälsar", "skicka bud, meddela"); bok.Visa(); Console.WriteLine("\nTryck return för att avsluta testprogrammet."); Console.ReadLine(); // För att man ska hinna se listan innan programmet avslutas När bok.Visa() exekveras ska man nu få en sorterad lista formaterad som i följande exempel: Lexikon Min ordbok bank företag som lånar ut pengar, sysslar med värdepapper etc vall, underlag för väg el. järnväg

Hemtentamen november HT 2007 - 12 -

grus- el. sandrygg i vatten molnvägg förvaringsplats, förråd hälsa tillstånd där man mår bra, friskhet hälsar säga goddag, välkomna skicka bud, meddela mulla Att gnida in snö i någons ansikte tulla Att betala tull Att ta mindre mängd av (något som bör sparas) vis klok (genom erfarenheter under ett långt liv) visa namn på ett kreditkortsföretag låta (någon) se sång Dvs för varje ord ska man få alla lagrade betydelser. Ordet ska bara visas en gång om det har flera betydelser. Listan ska vara sorterad på orden men behöver inte vara sorterad på betydelserna inom samma ord. Deluppgift b till studenterna. All utskrift sker via metoden Skriv. Detta gör att man lätt kan ändra var utskriften ska hamna. Det är därför som Skriv ska vara deklarerad som protected virtual. Nu vill man att all utskrift ska komma dels på konsolen (Console), dels på en fil med namnet test.txt. Använd arv och definiera om Skriv så att detta sker! -----------Slut på hur uppgiften definierades till studenterna!---------------

Hemtentamen november HT 2007 - 13 -

En av studenterna, vi kan kalla honom för Kalle Kodare, skrev följande kod: 1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace Uppgift_5 6 { 7 // Struct Betydelse av Kalle Kodare 8 struct Betydelse 9 { 10 public String Ord; 11 public String Betyder; 12 } 13 14 // Klass Lexikon av Kalle Kodare 15 public class Lexikon 16 { 17 private String Namn; 18 private List<Betydelse> ordbok; 19 20 public Lexikon(String n){ 21 String Namn = n; 22 List<Betydelse> ordbok = new List<Betydelse>(); 23 } 24 public void Add(String ord, String betyder){ 25 Betydelse b; 26 b.ord = ord; 27 b.betyder = betyder; 28 ordbok.Add(ord,betyder); 29 } 30 public void Visa(){ 31 Skriv("Lexikon " + Namn + "\n\n"); 32 sorteraBok(ordbok); 33 String ordinnan = ""; 34 foreach (Betydelse b in ordbok) 35 { 36 if (b.ord != ordinnan) Skriv(b.ord+ "\t"); 37 else Skriv("\t"); 38 Skriv(b.betyder); 39 Skriv("\n") 40 } 41 } 42 protected virtual void Skriv(String s) 43 { 44 Console.Write(s); 45 } 46 private void sorteraBok(List<Betydelse> bok) 47 { 48 Betydelse[] sbok = new Betydelse[bok.Count]; 49 for (int i = 0; i < sbok.Length; i++) ; 50 sbok[i] = bok[i]; 51 sortera(sbok); 52 foreach (Betydelse b in sbok) bok.Add(b); 53 54 } 55 private void sortera(Betydelse[] b) 56 { 57 bool ejklar = true; 58 while (ejklar) 59 { 60 ejklar = false; 61 for (int i = 0; i < b.Length; i++)

Hemtentamen november HT 2007 - 14 -

62 { 63 if (b[i].ord.CompareTo(b[i+1].ord) > 0) 64 { 65 ejklar = true; 66 Betydelse tmp = b[i]; 67 b[i] = b[i + 1]; 68 b[i + 1] = tmp; 69 } 70 } 71 } 72 } 73 } 74} (I slutet finns samma kod fast utan radnummer!) Koden innehåller en hel del fel, både syntax-fel och andra fel och din uppgift är att hjälpa Kalle Kodare att debugga programmet så det fungerar som det ska. Först några ord om själva programmet och hur Kalle Kodare tänkt. Kalle Kodare har valt datatypen List för att spara orden och för varje par ord/betydelse skapar han först ett struct-objekt som han sedan sparar i sin ordbok. När han ska skriva ut orden sorterar han dem först och då har han läst i en bok om bubblesort så han har använt den algoritmen. I boken sorterade man en array så Kalle Kodare tänker sig att först flytta det som ska sorteras till en array, sortera arrayen och sedan flytta tillbaka. I utskriftsdelen tänker han sig sedan en test på om det var samma ord som nyss och i så fall ska bara betydelsen skrivas ut. \n och \t som förekommer i strängarna betyder ny rad respektive tabulator-tecken. Gör nu följande: Uppgift 5 a Skriv först en egen Main i en egen startklass med testkoden ovan så att du kan prova. (Lägg märke till den namespace som används så du inte får onödigt fel i din egen Main p.g.av detta, eller tabort/byt ut namespace i Lexikon) Rätta sedan alla fel som kompilatorn meddelar som allvarliga fel, dvs fel som gör att programmet överhuvudtaget inte kan köras. För varje fel du hittar ta reda på den rimligaste orsaken rätta sedan felet. (Det går t.ex inte att bara ta bort rader som det är fel i!). Tala sedan om vilka fel du fann i koden och hur du åtgärdade detta. Obs! Rätta ENDAST fel som gör att det inte går att exekvera programmet! Rätta tillsvidare INTE fel som bara ger varningar om du får sådana fel! Om du inte hittar alla dessa fel kan du ju inte fortsätta, men du får då ta hjälp genom att skicka PIM till mig (Mats) och fråga efter dessa fel. Du får förståss inga poäng på denna deluppgift om du gör det men du kan i alla fall fortsätta med resten av uppgifterna. Motsvarande hjälp finns inte för de följande delfrågorna! Uppgift 5b

Hemtentamen november HT 2007 - 15 -

Du ska nu kunna provköra programmet men då kommer du troligen att få några fel-avbrott. Ta reda på varför du får det och rätta sedan koden. Du kan förståss bara rätta ett fel-avbrottsfel i taget (eftersom man får just bara ett felavbrott i taget när man provkör). Tala sedan om vilka slags felavbrott du fick, vad det berodde på och hur du rättade det. Uppgift 5c När felavbrotten är avklarade ska du få en lista men den ser inte alls rätt ut. Rätta nu de logiska fel som finns och som gör att listan blir felaktig (det är två sådana fel). För varje fel tala om vad det blev för slags fel och tala om hur du åtgärdade felet. Uppgift 5d Grattis. Du har hjälpt Kalle Kodare med hans första deluppgift. Hjälp honom nu även med den andra deluppgiften nämligen att via en subklass ändra Skriv så att man även skriver ut på en fil. Följande sats skapar en utström som kan användas och de två satser som följer kan användas för att skriva på den utströmmen: private StreamWriter ut = new StreamWriter(new FileStream("test.txt", FileMode.Create)); ----------- ut.Write(s); ut.Flush(); Du måste även använda using System.IO; Uppgift 5d kan lösas utan att du har gjort någon av de tidigare deluppgifterna!

Hemtentamen november HT 2007 - 16 -

Uppgift 5e Detta är ingen uppgift egentligen utan en rubrik så att du kan hitta det i PingPong. Oavsett hur många fel du hittat ska du här bara klistra in hela din klass Lexikon som ett slags efterkontroll. Du får inga poäng på denna deluppgift men den hjälper mig när jag ska rätta de övriga deluppgifterna Uppgift 5f Valet av List som datastruktur var egentligen inte bra. Bättre vore det att använda SortedList som fungerar som Hashtable fast nycklarna hålls sorterade. Se mer i boken sid 199. Skriv om Lexikon och använd SortedList istället. Ta även bort all kod som därmed blir onödig. I PingPong kommer frågorna att se ut så här: Uppgift 5 a Tala om vilka fel du fann i koden som gjorde att det inte gick att köra samt hur du åtgärdade detta. ************* Textruta för ditt svar ************* Uppgift 5b Tala om vilka slags felavbrott du fick när du körde programmet. Vad berodde det på och hur du rättade det? ************* Textruta för ditt svar ************* Uppgift 5c För varje logiskt fel tala om vad det blev för slags fel och tala om hur du åtgärdade felet. ************* Textruta för ditt svar ************* Uppgift 5d Redovisa din subklass till Lexikon här. ************* Textruta för ditt svar ************* Uppgift 5e Klistra in hela din klass Lexikon som den nu ser ut ************* Textruta för ditt svar ************* Uppgift 5f Klistra in koden för din uppdaterade Lexikon (med SortedList). ************* Textruta för ditt svar *************

Hemtentamen november HT 2007 - 17 -

Uppgift 6, ZuulLib I den här uppgiften förutsätter vi att du redan har gjort alla klasser som ska höra till biblioteket ZuulLib och att du provat klasserna via "Inför hemtentamen fråga sju". Du ska alltså ha ett antal klasser som definieras av dokumentet "Användarhandledning till ZuulLib" Innan du börjar ska du ändra metoden GetAllThings() i klassen Things! Den ska se ut så här: // Returns a string with a list of all names of the things public string GetAllThings() { return getAllThings(); } public string getAllThings() { string returnString = ""; foreach (DictionaryEntry e in mythings) { AThing thing = (AThing)e.Value; returnString += " " + thing.LongName; } return returnString; } (Av historiska skäl finns både getAllThings och GetAllThings. GetAllThings är den som måste finnas men jag visar upp båda för säkerhets skull utifall du själv använder getAllThings någon annan stans) OBS! (Tips!) Kontrollera även att du använder (anropar) samma Things.GetAllThings både när du ska tala om vad som finns hos spelaren och vad som finns i rummet! (I min version av ZuulLib var det inte så, så det kan tänkas att samma dåliga design finns kvar även i din!). Annars kommer du inte att se den nya utskriften i båda fallen ”hos spelaren” resp ”i rummet”. Som du ser används en ny egenskap LongName och den ska du lägga in i AThing. Den ska vara definierad som: public virtual string LongName { get { return Name; } } dvs i normalfallet som Name, men barnklasser kan komma att ändra det. Det kommer till användning i Uppgift 6b nedan men om du bara gör Uppgift 6a behöver du inte göra denna ändring men då måste du kontrollera så att GetAllThings returnerar en tom sträng om det inte finns några saker! Om du inte gjort det redan måste du först kompilera alla klasserna som hör till din ZuulLib och skapa en ZuulLib.dll. (Obs, bara biblioteks-klasserna! Inga egna rum eller egna spel eller liknande får vara med här!). Gör så här: Öppna ett kommandofönster och gå till katalogen med biblioteksklasserna. Se till att det bara är själva biblioteksklasserna som ligger där. gör: csc /target:library /out:ZuulLib.dll *.cs

Hemtentamen november HT 2007 - 18 -

Nu ska du ha fått en egen ZuulLib.dll (om det gick igenom kompileringen förståss!) Uppgift a) Gör ett eget spel. Du ska nu använda ditt eget bibliotek samt några rum som du får av oss för att göra ett eget spel. Gör en egen MyGame som ärver från Game och där du definierar upp hela spelet. Den kan heta vad som helst, här kallar vi den klassen för MyGame. Gör en egen startklass Zuul med en metod Main som bara startar upp MyGame, t.ex via: class Zuul{ public static void Main(){ MyGame game = new MyGame(); game.Start(); } } I filen Grottan.dll finns redan flera rum som du ska använda. Dessutom finns där en egen spelare! (Grottan.dll hämtar du från PingPong Hemtentamen november.) I MyGame ska du sedan göra följande:

Skapa en spelare: (OBS, lätt att missa detta!!): Metoden CreatePlayer ska inte skapa en ny Player utan där ska du istället använda en klass som heter PlayerHT2007 och som ärver från Player. Det är BARA i CreatePlayer som detta gäller! Skapa rum mm. Följande rums-klasser som finns i Grottan.dll måste vara med: StartRum, Gång, Sal, Förråd. Dessutom ska du göra två egna rum MinToa och TeleRum, se mer nedan. Du ska bara göra ett rum från varje klass! Du får sätta ihop rummen precis som du vill men du måste förståss se till så att du kan komma till alla rummen och att du kan komma tillbaka från alla rummen. Från MinToa måste det finnas en förbindelse till Förråd! StartRum måste vara det rum man startar i! Det är praktiskt om man kan nå många rum direkt från Gång. Rita upp en figur först hur du tänker dig att du vill sätta ihop rummen, det går mycket lättare dels att bygga rummen, dels att sedan provspela det hela då! Saker som du tycker ska vara med från början får du själv lägga in. Skapa kommandon. Alla kommandon som finns i ditt NormalRoom måste skapas på vanligt sätt.

Rum som du måste göra själv Det finns två huvudproblem i Grottan: 1 Så fort man kommer in så griper en elak grottmarodör in och tar bort alla förbindelser som fanns

från förrådet till andra rum. Och i förrådet finns toapapper som du kommer att behöva! 2 I salen (klassen Sal) finns en CD-spelare, men den behöver lite mer grejor för att kunna spela

något. Och du kan inte komma in i salen om du har några grejer med dig!

Hemtentamen november HT 2007 - 19 -

Problem 1 – Att kunna hämta toapappret. Gör en ny rums-klass MinToa som ärver från den befintliga klassen WC. I MinToa kan du definiera om metoden Enter (som finns i Room) så att du där öppnar en förbindelse från förrådet tillbaka till MinToa. Problem 2 – Att komma in med grejor till salen. Gör en ny rums-klass TeleRum som ska ärva från den befintliga klassen TestRum. TeleRum kommer att bli ett rum där det finns en maskin varmed man kan teleportera sig direkt till salen! I TeleRum ska du definiera om use-kommandot så att use maskin ska förflytta spelaren direkt till salen förutsatt att maskin finns i rummet eller hos spelaren. (Den kommer att finnas där av sig själv i början av spelet!) Dessutom ska man tala om för spelaren att ”det gick” - se mer om AThing i Användarhandledningen. För övrigt ska use-kommandot vara enligt orginalspecifikationen! Din nya definition ska utnyttja existerande kod på bästa möjliga sätt. Hur testkör jag? I katalogen som du ska kompilera ska det finnas följande filer MyGame.cs, Zuul.cs, MinToa.cs, TeleRum.cs ZuulLib.dll, Grottan.dll samt fler egna rummsklasserna om du har några. Kompilera sedan med csc /reference:ZuulLib.dll,Grottan.dll *.cs Kör med Zuul Det finns 6 riktiga koder att ta reda på. Det finns även ett fåtal falska. Här kommer vägledning för hur man ska hitta koderna förutsatt att du gjort allt rätt! 1 Toa-besöket. Förutsatt att du lyckas komma tillbaka till MinToa med toapapper får du kod med use

toapapper. Dessutom ska du få en kod om du går tillbaka till förrådet en gång till. 2 Salen En lyckad use maskin i TeleRum ger kod use CD-skiva förutsatt att man har den med sig, ger kod i TeleRum När man lyckas spela skivan i salen får man kod dessutom ska examine CD-spelare (om man har den) alltid en kod. I PingPong kommer frågorna på deluppgift a att se ut så här: Uppgift 6 – deluppgift a, Grottan Källkod finns i zip-filen Ja/Nej Kod A = [ ] Kod B = [ ] Kod C = [ ] Kod D = [ ]

Hemtentamen november HT 2007 - 20 -

Kod E = [ ] Kod F = [ ] Kod G= [ ] Har du hittat alla riktiga så ska en lucka vara tom i svaret. Du ska även skicka in din källkod - se slutet av uppgiften. Uppgift 6b) Lägg till två nya slags saker och ändra två kommandon Du ska nu lägga till två nya slags saker som båda ärver från AThing. Klassen Bottle som kan användas för att förvara en vätska i. Klassen Fluid som man kan ta med om man har en flaska med sig. Kommandot take xxx

ska ”utökas” så att om xxx finns i rummet och är en vätska så ska DoTakeFluid(...) anropas med vätskan som fanns i rummet. I övriga fall ska man göra som förut. DoTakeFluid(Fluid thing) Om man nu har en tom flaska med sig så ska vätskan tas bort från rummet och läggas in i flaskan. Dessutom ska vätskans TakeSucceed-text skrivas ut. Om man inte har någon tom flaska med sig så ska vätskans TakeFailed-text skrivas ut. Ingenting mer ska hända. Om man har flera tomma flaskor med sig så ska man välja den första som är tom (vilken som är den första ska inte spela någon roll).

Kommandot use xxx

ska utökas så att man först kontrollerar om xxx finns i rummet och är en vätska. I så ska man göra som förut, dvs anropa DoUseThing med saken (vätskan i det här fallet) men dessutom ska man efteråt bara ta bort vätskan från rummet. (Man har så att säga förbrukat den utan att det hände något!). Om xxx finns i rummet men inte är en vätska ska man göra som förut. Om xxx inte finns i rummet ska man först kontrollera om den finns i någon flaska som man bär med sig. Om den inte finns där heller ska man göra som vanligt när saken inte finns, men om den finns i en flaska man bär med sig så ska man göra så att den flaskan blir tom samt anropa den vanliga DoUseThing med xxx, dvs normalbeteendet för en sak som man har med sig (förutom att flaskan tömdes)

Övriga kommandon inga ändringar. Mer om klasserna Bottle och Fluid. Kom ihåg att båda ska vara public! public class Fluid – ska ärva från AThing. Den ska dessutom ha en utökad konstruktor public Fluid(string n, string u, string failed, string succeed, string takefailed, string takesucceed) där de två sista strängarna ska användas i de nya egenskaperna TakeFailed och TakeSucceed Två nya egenskaper, båda virtuella och med både get och set ska definieras. Det är egenskaperna TakeFailed och TakeSucceed som används av take-kommandot. Se ovan.

Hemtentamen november HT 2007 - 21 -

Texterna får sina initialvärden via konstruktorn men de kan alltså tänkas att de förändras eftersom de även ska ha set definierad. Och kom ihåg att de ska deklareras virtual. public class Bottle – ska ärva från AThing Ska dessutom ha den nya egenskapen public virtual Fluid Content { get ... set … } Som returnerar eller sätter innehållet i flaskan. Om flaskan är tom så ska get returnera null. Egenskapen LongName ska överskuggas så att den returnerar [empty xxx] om flaskan är tom, och [xxx with yyy] om flaskan är fylld. xxx är det ursprungliga namnet och yyy är namnet på det som finns i flaskan Exempel på tänkbar sekvens: take stone take bag take bottle take milk ? You have stone [bag with milk] [empty bottle] För att detta ska gå måste även egenskapen Name i klassen AThing ändras till public virtual string Name ... Tips 1: För att kontrollera vilken typ ett objekt är av kan man använda is som i if (thing is Fluid) osv Tips 2: För att gå igenom alla saker i Things kan du hämta inspiration från GetAllThings ovan. Lägg även märke till att Things själv implementerar interface IEnumerable! Provkör din nya ZuulLib. Gör sedan en ny ZuulLib.dll med ovanstående inlagt Nu ska du prova din nya ZuulLib med ett redan givet spel! Spelet finns i Garaget.dll och den hämtar du från PingPong Hemtentamen oktober. För att testa din egen ZuulLib.dll ska du i en och samma katalog lägga

Hemtentamen november HT 2007 - 22 -

ZuulLib.dll, Garaget.dll och Zuul.cs Zuul.cs ska se ut så här: using ZuulLib; class Zuul{ public static void Main(){ Game game = new Uppgift7B_GameExample(); game.Start(); } } Inga andra filer ska ligga i katalogen. Kompilera med csc /reference:ZuulLib.dll,Garaget.dll *.cs Om det går bra, kör sedan med Zuul Tips för spelet. Det finns 8 riktiga koder. Det kan finnas falska koder som kan visas vid felprogrammering. Kod nr 7 och 8 finns i startrummet. Använd use och take med och utan oljekanna. Obs om man går ut och tillbaka till startrummet kommer ny olja att finnas där. Kod 6: take petrol i Store Room. Kod 1: När man smort låset med oljan Kod 2: I hjälmen i rummet innanför det lås man måste värma upp. (examine helmet) Kod 3: När man tankar bilen, förutsatt att man gör rätt när man tankar. (Annars borde det komma en felanmärkning) Kod 4: undersök fortkörningsböterna Kod 5: undersök parkeringsböterna För att komma ut ur garaget med bilen måste man tanka minst 1 gallon. Men för att komma fram hela vägen till parkeringsplatsen (som är målet i spelet) måste man ha minst 2 gallon. Och tyvärr så läcker tanken så man måste ha med sig 2 gallon till garaget när man ska tanka upp. I PingPong kommer frågorna på deluppgift b att se ut så här: Uppgift 6 – deluppgift b, Garaget Källkod finns i zip-filen [ ] Ja/Nej Kod 1 = [ ] Kod 2 = [ ] Kod 3 = [ ] Kod 4 = [ ] Kod 5 = [ ] Kod 6 = [ ] Kod 7 = [ ] Kod 8 = [ ]

Hemtentamen november HT 2007 - 23 -

OBS! Uppgiften ska även redovisas i zip-filen som ska skickas in. I en mapp som ska heta uppgift 6 så ska du lägga: - En mapp med källkoden till ZuulLib som den ser ut efter uppgift 6b

(Har du bara gjort 6a så skickar du den källkoden för ZuulLib men du behöver alltså inte skicka båda varianterna om du gjort både 6a och 6b)

- Källkoden till MyGame som du gjorde i deluppgift a - Övriga rum som du gjorde i uppgift a. MinToa, TeleRum samt ev flera om du gjort flera). - Den ZuulLib.dll som du skapat (den som du använder i deluppgift b) Se även till att någon klass i ZuulLib innehåller ditt eget namn! Totalt sett ska den zip-fil som du ska skicka in innehåller - mappen Uppgift 5 med källkoden till den uppgiften. - mappen Uppgift 6 enligt ovan. - en textfil readme.txt. Se första sidan!

Hemtentamen november HT 2007 - 24 -

Appendix A – Koden till uppgift 5 utan radnummer using System; using System.Collections.Generic; using System.Text; namespace Uppgift_5 { // Struct Betydelse av Kalle Kodare struct Betydelse { public String Ord; public String Betyder; } // Klass Lexikon av Kalle Kodare public class Lexikon { private String Namn; private List<Betydelse> ordbok; public Lexikon(String n){ String Namn = n; List<Betydelse> ordbok = new List<Betydelse>(); } public void Add(String ord, String betyder){ Betydelse b; b.ord = ord; b.betyder = betyder; ordbok.Add(ord,betyder); } public void Visa(){ Skriv("Lexikon " + Namn + "\n\n"); sorteraBok(ordbok); String ordinnan = ""; foreach (Betydelse b in ordbok) { if (b.ord != ordinnan) Skriv(b.ord+ "\t"); else Skriv("\t"); Skriv(b.betyder); Skriv("\n") } } protected virtual void Skriv(String s) { Console.Write(s); } private void sorteraBok(List<Betydelse> bok) { Betydelse[] sbok = new Betydelse[bok.Count]; for (int i = 0; i < sbok.Length; i++) ; sbok[i] = bok[i]; sortera(sbok); foreach (Betydelse b in sbok) bok.Add(b); } private void sortera(Betydelse[] b) { bool ejklar = true; while (ejklar) { ejklar = false; for (int i = 0; i < b.Length; i++) {

Hemtentamen november HT 2007 - 25 -

if (b[i].ord.CompareTo(b[i+1].ord) > 0) { ejklar = true; Betydelse tmp = b[i]; b[i] = b[i + 1]; b[i + 1] = tmp; } } } } } }