LUNDS TEKNISKA HÖGSKOLA 1(4) Institutionen för datavetenskap Tentamen, EDAA20/EDA501 Programmering 2014 04 29, 8.00 13.00 Anvisningar: Denna tentamen består av tre uppgifter. Preliminärt ger uppgifterna 15 + 15 + 10 = 40 poäng. För godkänt betyg krävs 20 poäng. Tillåtet hjälpmedel: Java-snabbreferens. Lösningsförslag kommer att finnas på kursens hemsida senast dagen efter tentamen. När rättningen är klar meddelas detta på kursens hemsida. Tentamensvillkor för EDA501: Om du tenterar utan att vara tentamensberättigad annulleras din skrivning. För att undvika att någon skrivning annulleras av misstag kommer alla som, enligt institutionens noteringar, tenterat utan att vara tentamensberättigade att kontaktas via epost. Felaktigheter i institutionens noteringar kan därefter påtalas fram till nästa tentamenstillfälle då resterande skrivningar annulleras.
2(4) Introduktion Alla uppgifterna handlar om betygsbedömning i grundskolan. År 2011 ändrades betygssystemet till en betygsskala med sex steg med beteckningarna A, B, C, D, E och F. Betyg A är högsta betyg. A E är godkända resultat medan F är ej godkänt. Betygssättning på både enskilda prov och i hela ämnen sker med hjälp av betygsmatriser. En betygsmatris innehåller betygskraven för betygen A, C och E för ett antal aspekter av ett ämne (se tabell 1). Betygskraven för en aspekt är alltid inkluderande, dvs ett krav för ett lägre betyg är alltid en delmängd av kravet för ett högre betyg. Så om man uppfyller kravet för betyg A uppfyller man automatiskt kravet för betyg C och E, om man uppfyller kravet för betyg C uppfyller man automatiskt kravet för betyg E. Betygsmatrisen används för att sätta betyg: För betyg A måste betygskravet för betyg A vara uppfyllt för samtliga aspekter. För betyg B måste betygskravet för betyg C vara uppfyllt för samtliga aspekter samt betygskravet för betyg A för mer än hälften av aspekterna. För betyg C måste betygskravet för betyg C vara uppfyllt för samtliga aspekter. För betyg D måste betygskravet för betyg E vara uppfyllt för samtliga aspekter samt betygskravet för betyg C för mer än hälften av aspekterna. För betyg E måste betygskravet för betyg E vara uppfyllt för samtliga aspekter. Är inte betygskravet för betyg E uppfyllt för samtliga aspekter ges betyg F. Klassen Aspect, som beskriver en aspekt, är färdigskriven. Du behöver bara känna till att varje aspekt har ett unikt id-nummer (används i uppgift 3). Aspekt Betygskrav E Betygskrav C Betygskrav A Läsa med flyt Skriva texter Eleven kan läsa skönlitteratur och sakprosatexter för barn och ungdomar med flyt genom att använda lässtrategier på ett i huvudsak fungerande sätt. Eleven kan skriva olika slags texter med begripligt innehåll, i huvudsak fungerande struktur och viss språklig variation. Eleven kan läsa skönlitteratur och sakprosatexter för barn och ungdomar med gott flyt genom att använda lässtrategier på ett ändamålsenligt sätt. Eleven kan skriva olika slags texter med relativt tydligt innehåll och relativt väl fungerande struktur samt förhållandevis god språklig variation. Osv............ Tabell 1: Betygsmatris för ämnet svenska. Eleven kan läsa skönlitteratur och sakprosatexter för barn och ungdomar med mycket gott flyt genom att använda lässtrategier på ett ändamålsenligt och effektivt sätt. Eleven kan skriva olika slags texter med tydligt innehåll, väl fungerande struktur samt god språklig variation.
3(4) 1. I fortsättningen behandlar vi betygssättning av prov. Elever som deltar i prov beskrivs av den färdigskrivna klassen Pupil, som bland annat har metoder String getpnbr() och String getname() som tar reda på elevens personnummer och namn. Vid ett prov har varje elev sin egen bedömningstabell där man noterar hur väl de olika aspekterna är uppfyllda. En sådan tabell beskrivs av klassen GradeTable: GradeTable /** Skapar en bedömningstabell för eleven pupil. Tabellen har nbraspects rader */ GradeTable(Pupil pupil, int nbraspects); /** Tar reda på eleven */ Pupil getpupil(); /** Noterar att eleven klarat betygsnivå grade (A, C eller E) på aspekten med nummer a */ void mark(int a, char grade); /** Ger true om eleven klarat betygsnivå grade (A, C eller E) på aspekten med nummer a */ boolean ismarked(int a, char grade); /** Ger elevens sammanvägda betyg (A-F) */ char gettestgrade(); Implementera klassen GradeTable. Anvisningar: Aspekterna numreras 0, 1, 2,... Bedömningstabellen ska implementeras med hjälp av en boolean-matris med en rad för varje aspekt och tre kolumner för betygsnivåerna E, C och A. Kom ihåg att avklarad betygsnivå A nivå C och E, avklarad nivå C nivå E. 2. Klassen Test hanterar bedömningen av ett prov. Olika prov testar olika aspekter. Test /** Skapar ett prov som ska bedöma aspekterna aspects */ Test(String title, String date, ArrayList<Aspect> aspects); /** Skapar en bedömningstabell för eleven pupil och sparar tabellen i en lista */ void addpupil(pupil pupil); /** Markerar att eleven med personnumret pnbr klarat betygsnivå grade (A, C eller E) på aspekten med nummer a */ void mark(string pnbr, int a, char grade); /** Skriver ut en resultatlista: en rubrikrad med provets namn och datum, sedan en rad för varje elev med namn, personnummer och betyg */ void printresults(); Implementera klassen Test.
4(4) 3. En lärare som ger och bedömer ett prov skriver inte in resultaten direkt i ett Test-objekt. I stället skriver läraren in resultaten i ett ark i ett kalkylprogram. Arket exporteras sedan till en textfil. Textfilen innehåller: En rad med provets namn och datum, en rad med id-nummer för alla aspekter som bedöms i provet (se nedan), en rad för varje elev med personnummer och betygsnivå för varje aspekt (A, C, E som vanligt, streck för ej avklarad aspekt). Exempel på textfil för ett prov där fem studenter deltog och fem aspekter bedömdes: Svenska 2014-04-29 1123 1124 1131 1132 1140 010430-1234 A A C A C 010224-2345 A C C C C 001204-3456 C C - - C 010316-4567 E C E C C 010212-5678 A C C C E Skriv en main-metod som läser in ett prov från tangentbordet (egentligen skulle vi läst från en textfil, men vi förenklar uppgiften något och läser från tangentbordet istället) och producerar en resultatlista för provet (med metoden printresults i klassen Test). Du kan förutsätta att indata följer det angivna formatet och att alla data är korrekta (orealistiskt, men det blir mindre att skriva). Den färdigskrivna klassen TestRegister hanterar allt som har med prov att göra. Klassen har tillgång till alla elever och alla aspekter och alla färdiga prov måste registreras i registret. Metoder som utnyttjas i denna uppgift: TestRegister /** Skapar ett provregister */ TestRegister(); /** Ger aspekten med givet id-nummer, null om det inte finns någon sådan aspekt */ Aspect getaspect(int aspectid); /** Ger eleven med givet personnummer, null om det inte finns någon sådan elev */ Pupil getpupil(string pnbr); /** Registrerar ett nytt färdigt prov */ void register(test test); Tyvärr finns det ingen Scanner-metod för att läsa bara ett tecken men i detta fall kan man läsa de olika betygen enligt följande exempel: String s = scan.next(); char ch = s.charat(0);
LUNDS TEKNISKA HÖGSKOLA 1(3) Institutionen för datavetenskap Lösningsförslag, tentamen i EDAA20/EDA501 2014 04 29 1. public class GradeTable { private static final int aindex = 2, cindex = 1, eindex = 0; private Pupil pupil; private boolean[][] table; public GradeTable(Pupil pupil, int nbraspects) { this.pupil = pupil; table = new boolean[nbraspects][3]; public Pupil getpupil() { return pupil; public void mark(int a, char grade) { if (grade == A ) { table[a][aindex] = table[a][cindex] = table[a][eindex] = true; else if (grade == C ) { table[a][cindex] = table[a][eindex] = true; else { table[a][eindex] = true; public boolean ismarked(int a, char grade) { int index; if (grade == A ) { index = aindex; else if (grade == C ) { index = cindex; else { index = eindex; return table[a][index]; public char gettestgrade() { int nbraspects = table.length; int[] count = new int[table[0].length]; for (int gradeindex = 0; gradeindex < count.length; gradeindex++) { int nbr = 0; for (int i = 0; i < nbraspects; i++) { if (table[i][gradeindex]) { nbr++; count[gradeindex] = nbr; char grade; if (count[aindex] == nbraspects) { grade = A ; else if (count[cindex] == nbraspects) {
2(3) if (count[aindex] > nbraspects / 2.0) { grade = B ; else { grade = C ; else if (count[eindex] == nbraspects) { if (count[cindex] > nbraspects / 2.0) { grade = D ; else { grade = E ; else { grade = F ; return grade; 2. public class Test { private String name; private String date; private ArrayList<Aspect> aspects; private ArrayList<GradeTable> gradetables; public Test(String name, String date, ArrayList<Aspect> aspects) { this.name = name; this.date = date; this.aspects = aspects; gradetables = new ArrayList<GradeTable>(); public void addpupil(pupil p) { gradetables.add(new GradeTable(p, aspects.size())); public void mark(string pnbr, int a, char grade) { GradeTable gt = findgradetablefor(pnbr); gt.mark(a, grade); public void printresults() { System.out.println(name + " " + date); for (int i = 0; i < gradetables.size(); i++) { GradeTable gt = gradetables.get(i); System.out.println(gt.getPupil().getName() + "\t" + gt.getpupil().getpnbr() + "\t" + gt.gettestgrade()); private GradeTable findgradetablefor(string pnbr) { for (int i = 0; i < gradetables.size(); i++) { if (gradetables.get(i).getpupil().getpnbr().equals(pnbr)) { return gradetables.get(i); return null;
3(3) 3. public class TestMain { public static void main(string[] args) { TestRegister treg = new TestRegister(); Scanner scan = new Scanner(System.in); String testname = scan.next(); String testdate = scan.next(); ArrayList<Aspect> aspects = new ArrayList<Aspect>(); while (scan.hasnextint()) { int aspectid = scan.nextint(); Aspect a = treg.getaspect(aspectid); aspects.add(a); scan.nextline(); Test test = new Test(testName, testdate, aspects); while (scan.hasnext()) { String pnbr = scan.next(); Pupil p = treg.getpupil(pnbr); test.addpupil(p); for (int i = 0; i < aspects.size(); i++) { char grade = scan.next().charat(0); if (grade == A grade == C grade == E ) { test.mark(pnbr, i, grade); test.printresults(); treg.register(test);