Sida 1/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö Tentamen, delkurs C# Systemutvecklare SU13, Malmö Facit & rättningsmall Plats: Tid: Plushögskolan Malmö 09.00-13.00 Tillåtna hjälpmedel: Papper, penna, suddgummi. Ej tillåtna hjälpmedel: Datorer, telefoner, böcker, anteckningar, kompendier etc. Max poäng: 120 poäng Del 1, slutna svar: 50 poäng Del 2, öppna svar: 50 poäng Inlämningsuppgift: 20 poäng (avser tidigare gjord gruppinlämningsuppgift ”Tic-Tac-Toe”, som räknas in i poängen enligt följande: Ej gjord/U = 0 poäng, G = 15 poäng, VG = 20 poäng) Betygsgränser: Godkänt 75 poäng Väl godkänt 95 poäng Examinator: Thomas Frank, Nodebite AB Sida 2/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö Del 1, slutna svar, facit Instruktioner: Läs igenom frågorna på följande sidor och välj svarsalternativ. FYLL I DITT NAMN (!) och kryssa i dina svar på denna sida. (Mer än ett ikryssat svar per fråga ger 0 poäng på frågan.) Lämna endast in denna sida för del 1. Namn: Fråga 1-20 (1 poäng per rätt svar) Fråga 21-35 (2 poäng per rätt svar) 1 a b c x d 21 a b x c d 2 a x b c d 22 a x b c d 3 a b c d x 23 a b x c d 4 a b x c d 24 a b c x d 5 a b c d x 25 a b c d x 6 a b c d x 26 a b c x d 7 a b c d x 27 a b x c d 8 a x b c d 28 a x b c d 9 a b c x d 29 a b c x d 10 a b c d x 30 a b c x d 11 a b x c d 31 a b x c d 12 a b x c d 32 a b c d x 13 a x b c d 33 a x b c d 14 a b x c d 34 a b c d x 15 a b c x d 35 a b x c d 16 a b x c d 17 a x b c d 18 a x b c d 19 a b x c d 20 a b c d x Sida 3/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö Fråga 1: Agil Metodik & SCRUM (10 poäng totalt) a) Beskriv med egna ord anledningen till att agil metodik behövs och utvecklades. (2 poäng) Ett poäng ges för vart och ett av dessa begrepp: bättre måluppfyllelse, högre kvalitet, snabbare utveckling, mer transparent process, bättre kundkontakt, premierar kompetensutveckling, nöjdare kund, flexiblare arbetssätt, bättre arbetsmiljö. ELLER: Begrepp som motsvarar dessa. MEN: Bara under förutsättning att begreppens relevans motiveras! b) Återge de fyra hörnstenarna/nyckelprinciperna i det agila manifestet. Anknyt varje princip till ett verklighetsnära exempel. (4 poäng) Ett poäng ges för vart och ett av dessa begrepp, samt (ganska snällt rättat) exempel på dem, behöver inte alls vara exakt ordalydelse: • Individer och interaktioner framför processer och verktyg. • Fungerande programvara framför omfattande dokumentation. • Kundsamarbete framför kontraktsförhandling. • Anpassning till förändring framför att följa en plan. c) Förklara hur man arbetar med SCRUM-metodik och väv gärna in följande termer: produkt, produktägare, produkt-backlog, epics, user stories, tasks, scrum master, sprintplanering & pokerplanning, sprint, sprint backlog, retrospective-möte, daily standup, burn down chart, samt spike. (4 poäng) En halv poäng ges per korrekt förklarat begrepp bland de som listas ovan. Sida 4/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö Fråga 2: In your arms (14 poäng totalt) Du ska skapa en applikation där personer har armar, armarna har händer och händerna har fingrar. I övrigt ska varje persons ha namn, ålder och kön. Man ska kunna be en arm att peka. Armen ska då lyftas, säga till sin hand att peka, varvid handen ska säga till sitt pekfinger att sträcka ut sig och övriga fingrar att dra in sig mot handflatan. (Du behöver inte göra något grafiskt här – det räcker med konsolmeddelanden där armen, handen och fingrarna meddelar vad de gör.) a) Hur löser du detta objektorienterat? Vilken/vilka klasser skapar du? Vilka egenskaper och/eller metoder har klassen/klasserna? Ange även typ för egenskaper och metoder! (4p) class Person (egenskaper: string Name, int Age, string Gender (eller bool Male etc), List<Arm> Arms, int NumberOfArms, metod: konstruktor) class Arm (egenskaper: Hand MyHand, metoder: konstruktor, void Point, void Lift) class Hand (egenskaper: List<Finger> MyFingers, metoder: konstruktor, void Point) class Finger (metod: void Fold, samt Point om underklass IndexFinger ej används) class IndexFinger (ärver av Finger, metod: void Point) En halv poäng per korrekt klass (underklass undantaget), en halv poäng per rimlig listning av egenskaper och metoder inom en klass, konstruktor behöver ej vara med. Varianter på typer som fungerar logiskt godkännes. b) Löser du problemet med arv eller komposition? Eller bådadera? Förklara och motivera! Visa att du förstår dessa två begrepp och skillnaden mellan dem. (2p) En poäng för rätt svar (i detta fall komposition eller arv + komposition). En poäng för korrekt motivering, t.ex.: Jag löser uppgiften med uteslutande komposition, då det inte finns några lämpliga arv – inga klasser som är av samma ”grundtyp”, däremot finns det gott om objekt som behöver andra objekttyper som egenskaper (dvs. komposition): En person har armar, en arm har en hand, en hand har fingrar. Eller: Jag löser uppgiften med arv + komposition. Motivering som ovan vad gäller komposition, samt motivering för arv är fingrar (ett pekfinger är en underklass av finger etc.) Sida 5/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö c) Skriv C#-kod eller pseudokod för armens peka-metod, samt de övriga metoder som kommer att anropas/köras när den körs. (4 poäng + 1 extrapoäng för helt korrekt C#-kod) På följande två sidor finns en fungerande kodlistning för hela applikationen. För att få fyra poäng på denna fråga krävs att man har med korrekt kod/logik för följande metoder: Arm.Point() – rad 39-44 Hand.Point() – rad 65-75 Finger.Fold() – rad 80-83 IndexFinger.Point() – rad 88-91 / eller Finger.Point() om man inte använder underklasser Trevligt är även kod för Arm.Lift() – rad 46-50 – och har man med denna metod uppväger det mindre brister i övriga metoder. En poäng per korrekt skriven metod. (I vissa fall istället en poäng för bra sammanhang.) (Hyfsat) korrekt C#-kod istället för pseudokod ger en extra poäng. d) En person skapas initialt med 2 armar. Skriv C#-kod eller pseudokod för en setter som gör att man kan ändra antalet armar på en person efter att han/hon skapats – dock endast till ett lägre värde än initialt och som lägst till 0 stycken. (2p + 1 extrapoäng för helt korrekt C#-kod) På följande två sidor finns en fungerande kodlistning för hela applikationen. För att få två poäng på denna fråga krävs att man har med kod motsvarande logiken i rad 20-27, samt någon typ av förklaring av hur det satta värdet samspelar med de faktiska antalet objektinstanser av armar en person har, t.ex. utgör gettern på rad 16-19 en sådan förklaring. En poäng per för korrekt skriven setter. En poäng för visad koppling mellan personens armobjekt och get/setter för antal armar. (Hyfsat) korrekt C#-kod istället för pseudokod ger en extra poäng. Sida 6/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. public class Person { public List<Arm> Arms { get; set; } public Person() { Arms = new List<Arm>(); for (var i = 0; i < 2; i++) { Arms.Add( new Arm() ); } } public int NumberOfArms { get { return Arms.Count; } set { while (value < Arms.Count && value >= 0) { Arms.RemoveAt( Arms.Count - 1 ); } } } } public class Arm { public Hand MyHand { get; set; } public Arm() { MyHand = new Hand(); } public void Point() { Lift(); Console.WriteLine( "Telling the hand to point.. " ); MyHand.Point(); } Sida 7/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. public void Lift() { Console.WriteLine( "Lifting this arm!" ); } } public class Hand { public List<Finger> MyFingers { get; set; } public Hand() { MyFingers = new List<Finger>(); for (var i = 0; i < 5; i++) { MyFingers.Add( i == 1 ? new IndexFinger() : new Finger() ); } } public void Point() { Console.WriteLine( "I'm a hand - I tell the fingers what to do!" ); for (var i = 0; i < 5; i++) { dynamic f = MyFingers[i]; Console.WriteLine( f.GetType().Name == "IndexFinger" ? f.Point() : f.Fold() ); } } } public class Finger { public string Fold() { return "Folding a finger!"; } } public class IndexFinger : Finger { public string Point() { return "Pointing an index finger!"; } } Sida 8/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö Fråga 3: Business as usual (26 poäng totalt) Du skriver en applikation som ska kunna hantera data om olika företag. Varje företag har ett namn, ett organisationsnummer, en eller flera ägare (personer och/eller andra företag), samt noll till flera anställda. a) Hur löser du detta objektorienterat? Vilken/vilka klasser skapar du? Vilka egenskaper och/eller metoder har klassen/klasserna? Ange även typ för egenskaper och metoder! (6p) class Company egenskaper: string Name, string OrgNumber, List<dynamic> Owners, List<Employee> Employees metoder: konstruktor, string Ownership class Person egenskaper: string Name, string PersonNumber metod: (ej nödvändig) kontruktor class Employee (ärver av Person) Company bör ha en konstruktor som föhindrar att det går att skapa företag utan minst en ägare, samt kontrollerar att ägaren är ett annat företag eller person. (Alternativt kan man ha en mellanklass Owner som måste ha ett företag eller person kopplad till sig – då klarar man sig om man vill utan throw-statements.) Kommentar: Även long godkännes som datatyp för OrgNumber och PersonNumber. Dock inte int (som inte rymmer ett så långt nummer). Det är inte nödvändigt att ha med klassen Employee (i så fall ersätts den ovan i listorna med Person). Det är inte nödvändigt att ha med PersonNumber. Ett poäng ges per korrekt klass (dock högst två poäng) Ett halvt poäng ges per korrekt egenskap (dock högst tre poäng) Ett poäng ges om man inser och nämner varför Company bör ha en konstruktor. Varianter på typer som fungerar logiskt godkännes. Sida 9/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö b) Löser du problemet med arv eller komposition? Eller bådadera? Förklara och motivera! Visa att du förstår dessa två begrepp och skillnaden mellan dem. (3p) En poäng för rätt svar (i detta fall komposition eller arv + komposition). Två poäng för korrekt motivering, t.ex.: Jag löser uppgiften med uteslutande komposition, då det inte finns några lämpliga arv – inga klasser som är av samma ”grundtyp”, däremot finns det ett objekt som behöver andra objekttyper som egenskaper (dvs. komposition): Ett företag behöver personer och företag som ägare. Eller: Jag löser uppgiften med arv + komposition. Motivering som ovan vad gäller komposition, samt motivering för arv är att en anställd är en underklass till person. c) Skissa/rita upp ett grafiskt gränssnitt där man kan mata in personer och företag, samt lägga till och ta bort ägare och anställda. Ange gärna vilken typer av komponenter du vill använda dig av. Kan du inte namnen så beskriv hur de fungerar (”fäller ner en lista” etc.) (6p) Det finns många grafiska lösningar på denna fråga. På denna och följande sidor ges ett förslag. Grundvy (innan man har markerat person Poängbedömning enligt eller företag, se nästa sida för detta): (en poäng per punkt): • Skapa (& gärna radera) personer. • Skapa (& gärna radera) företag. • Lägga till och ta bort ägare i företag (flera). • Lägga till och ta bort anställda i företag (flera). • Företag kan inte skapas utan minst en ägare. • Beskrivning av komponenter. Sida 10/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö Info-vy när man har markerat en person: Info-vy när man har markerat ett företag: OBS: Redigera-vyerna & Lägg till ny-vyerna är lika (men Lägg till ny startar utan uppgifter ifyllda.) OBS: Man kan INTE spara ett företag innan det har minst en ägare. (Spara-knappen är disablad till dess.) Redigera-vy för person Redigera-vy för företag Rubriker ovanför rutor är labels. Alla boxar med scrolllister är listboxar. Allt som ser ut som knappar är knappar. I redigera-vyerna är namn, pnr och org.nr-fälten redigerbara textboxar utan border. Sida 11/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö d) Ge exempel på en JSON-datastruktur som skulle fungera för att lagra datan mellan körningar. (4p) Ett exempel på JSON-datastruktur som godkänns är: { "persons": [ { "Name": "Person Name", "PersonNumber": "XXXXXX-XXXX", "isEmployee": true id: "P1" } ], "companies": [ { "Name": "Person Name", "PersonNumber": "XXXXXX-XXXX", id: "C1", "OwnerIDs": ["P1","C2"], "EmployeeIDs": ["P1","P3] ] } } Poäng enligt nedan: • En poäng ges för ett JSON-objekt används för huvudstrukturen och håller de olika objekttyperna (employees för sig, personer för sig godkänns). • En poäng till ges om objekttyperna från programmet finns med som JSON-arrayer (companies, persons, samt eventuellt employees). • En poäng ges om JSON-objekten är korrekt genomförda med specificerade egenskaper som motsvarar klassernas egenskaper. • En poäng för den som löser problemet med att man kan få cirkulära referenser och objekt som dubbellagras genom att istället för objekt i Owners och Employeesarrayerna använda någon form av id-system för referens. e) Vilken tillvägagångssätt använder du för att spara datan mellan körningar. (2p) Det ger en poäng att beskriva att man kan skapa en settings-variabel via Application -> Properties -> Settings.settings (med scope User). Det ger ytterligare en poäng att beskriva att denna kan läsas och skrivas via C#, bör vara av typen string och att man med hjälp av ett JSON-bibliotek kan serialisera/deserialisera objektinstanser till JSON och spara i denna settingsvariabel. Sida 12/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö Inga kodexempel är nödvändiga, men kan fungera som alternativ till ovanstående förklaringar. Alternativa lösningar som går ut på att explicit be användaren spara och läsa saker från disk eller använda andra dataformat än JSON godkänns om de är väl förklarade. f) Skriv C#-kod eller pseudokod som gör att man om företag äger företag kan se ägandeskapet i flera led. (4 poäng + 1 extrapoäng för helt korrekt C#-kod). På följande två sidor finns en fungerande kodlistning för hela applikationens logiska del (dvs. ej event handlers eller grafiska kontroller). Denna delfråga löser man med en rekursiv metod (eventuellt med en icke-rekursiv ”ingångsmetod”). Ett exempel på en sådan lösning hittar du på rad 45-63 i kodlistningen. En poäng ges för försök till lösning med rekursiv while-sats (vilket inte fungerar Generellt I detta fall då det inte råder ett ett-till-ett-förhållande från företag till ägande företag.) Två till fyra poäng ges för försök till lösning med rekursiv metod. (Fyra poäng om lösningen är fullt fungerande logiskt sett, tre poäng vid mindre fel..) (Hyfsat) korrekt C#-kod istället för pseudokod ger en extra poäng. Kodlistning: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class Person { public string Name { get; set; } public string PersonNumber { get; set; } public Person(string name,string pNo){ Name = name; PersonNumber = pNo; } } public class Employee : Person { public Employee(string name, string pNo) : base(name, pNo) { } } Sida 13/14 Tentamen delkurs C#, Systemutvecklare, SU13, Malmö 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. public class Company { public string Name { get; set; } public string OrgNumber { get; set; } public List<dynamic> Owners {get; set;} public List<Employee> Employees { get; set; } public Company(string name, string orgNo, params dynamic[] owners) { // Make sure we have at least one owner if( owners.Length < 1 ) throw new System.ArgumentException( "Must have at least one owner.", "owners" ); // Make sure the owners are persons, employees or companies for(var i = 0; i < owners.Length; i++){ var type = owners[i].GetType().Name; if ( ",Company,Person,Employee,".IndexOf( "," + type + ",") < 0 ) throw new System.ArgumentException( "Persons and/or companies", "owners" ); } Name = name; OrgNumber = orgNo; Employees = new List<Employee>(); Owners = new List<dynamic>(); Owners.AddRange(owners); } public string Ownership() { return Name + " is owned by:\n" + Ownership(this,1); } private string Ownership(Company company, int level){ var owners = company.Owners; var report = ""; for(var i = 0; i < owners.Count; i++){ for (var j = 0; j < level-1; j++) report += "\t"; report += owners[i].Name + "\n"; if (owners[i].GetType().Name == "Company") { report += Ownership(owners[i], level+1); } } return report; } }
© Copyright 2024