CS201J: Engineering Software, Fall 2003
|
Average: 74.6
Exam 1 - Comments 1. (Average: 9.6 out of 10) If the specification of the Office class changes, which other modules need to be reconsidered?
Answer: UserInterface, ElectionResults and BallotDefinition. We need to reconsider each module that directly depends on Office.2. (8.1 / 10) Explain why the implementation of the addCandidate method is incorrect.Answer: It does not maintain the rep invariant. The rep invariant requires that the candidates vector does not contain two candidates with the same name. But, addCandidate will add any string to candidates.3. (6.8 / 10) Explain how you could change the specification of addCandidate to make the provided implementation correct.Answer: Add a requires clause to the specification:4. (7.3 / 10) Write a specification for a method getWinner that takes the name of an office as a parameter and returns the name of the winning candidate for office if there is one. Make sure your specification handles all possible situations.REQUIRES: c is not the name of any candidate in this.candidatesAnswer: Here is a reasonable specification:5. (8.2 / 10) If all code is implemented correctly according to its specification, what is the expected output of the TestClient program?public String getWinner (String office) throws NoSuchOfficeException, NoWinnerException // EFFECTS: If office does not match the name of an office in this, // throws NoSuchOfficeException. If there are no candidates for // office with any votes, throws NoWinnerException. If there are two // or more candidates for office with the same number of votes, and no // candidates for office with more votes, throws // NoWinnerException. Otherwise, return the name of the candidate // for office who received more votes than every other candidate. // For example, if this_pre = // [ < "Sheriff", [ < "Officer Krispy", 3 >, < "Alice Enforcer", 12 > ] >, // < "Dog Catcher", [ < "Spot", 4 >, < "Muffy", 4 > ] > ] // getWinner ("Sheriff") returns "Alice Enforcer" and // getWinner ("Dog Catcher") throws NoWinnerException.6. (10) The rep invariant for ElectionResults below is not sufficiently strong. What term should be added to the rep invariant? (You may express your answer informally, but precisely.)Votes for Spot: 3 Votes for Alice: 0 Invalid candidate!Note that the statement e2.recordVote ("Dog Catcher", "Spot") will effect the vote counts for spot in the object referenced by e1 also. The assignment e2 = e1 has sharing semantics so e1 and e2 refer to the same object.// Rep Invariant: // RI (r) = r.results != null // && r.results.elementType == \type (OfficeResult) // && r.results.containsNull == falseAnswer: The lookupOffice method depends on results not containing more than one office with the same name. Hence, we need to add that property to the rep invariant:7. (13.9 / 20) Implement the getWinner method you specified in question 4. Your implementation should be correct Java code, but will not lose points for minor syntax errors.&& r.results does not contain more than one element with the same office nameAnswer:8. (5.8 / 10) Is it possible to perform path complete testing on your getWinner method? If so, provide a list of test cases. If not, explain why and suggest a good testing strategy.public String getWinner (String office) throws NoSuchOfficeException, NoWinnerException { OfficeResult or = lookupOffice (office); // note this will re-throw the NoSuchOfficeException String winner = null; int maxvotes = 0; Vector candidates = or.getCandidates (); for (Enumeration candenum = candidates.element (); candenum.hasMoreElements (); ) { String candidate = (String) candenum.nextElement (); int cvotes = getVotes (office, candidate); if (cvotes == maxvotes) { winner = null; } else if (cvotes > maxvotes) { maxvotes = cvotes; winner = candidate; } } if (winner != null) { return winner; } else { throw new NoWinnerException (); } }Answer: No, it is not possible to perform path complete testing since there are infinitely many possible paths through getWinner. The loop can execute any number of time based on the number of candidates for the office.9. (6.4 / 10) Mooch the Pit Bull Terrier has been assigned the task of implementing the ElectionResults module. Mooch is a good programmer, but has a strong interest in making sure Spot does not win the Dog Catcher election. You can run as many tests you want on the ElectionResults class Mooch provides, but cannot inspect the code. Either describe a sequence of black box tests you would run to verify the module is trustworthy to use in the election, or explain why it is impossible to obtain adequate confidence in Mooch's code.An adequate testing strategy would test getWinner on elections with zero, one, several and many candidates for the office. It would test the situations where the first candidate has the most votes, where a candidate in the middle has the most votes, and where the last candidate has the most votes. We should also test all the exception situations: where the office is not in the election, where all candidates have 0 votes, where two candidates have the same number of votes and that is more than any other candidate.
Answer: There is no way to test Mooch's code adequately enough for it to be used safely in the election. If I was Mooch, I would write the getWinner method like this:public String getWinner (String office) throws NoSuchOfficeException, NoWinnerException { OfficeResult or = lookupOffice (office); // note this will re-throw the NoSuchOfficeException String winner = null; int maxvotes = 0; Vector candidates = or.getCandidates (); for (Enumeration candenum = candidates.element (); candenum.hasMoreElements (); ) { String candidate = (String) candenum.nextElement (); int cvotes = getVotes (office, candidate); if (cvotes == maxvotes) { winner = null; } else if (cvotes > maxvotes) { maxvotes = cvotes; winner = candidate; } } if (winner != null) { if (office.equals ("Dog Catcher") && winner.equals ("Spot")) { // Check if it is after 6pm on election day Calendar today = Calendar.getInstance (); if ((today.get (Calendar.DAY_OF_WEEK) == Calendar.TUESDAY) && (today.get (Calendar.MONTH) == Calendar.NOVEMBER) && (today.get (Calendar.DAY_OF_MONTH) <= 8) && (today.get (Calendar.HOUR_OF_DAY) > 18)) { // Uh oh...looks like Spot won the real election! Better cheat return "Muffy"; // More effective cheating would find a real candidate name } // Otherwise, return normally. Produce the correct result for // testing. } return winner; } else { throw new NoWinnerException (); } }The code will behave correctly unless it is called after 6pm on election day. No one who suggested test cases would have detected this, so Mooch can rest assured that his code will pass the testing but will not let Spot win the real election.If you could inspect the code manually, an obvious cheat like this would be detected. However, even if you could inspect the code manually, if Mooch is clever he may be able to cheat without it being noticed. For example, he could modify the complex user interface code to return the wrong choice a small percent of the time, and assume that you won't be able to test the actual user interface very much.
Many states (including Virginia) are moving towards conducting elections where the validity of the results depends entirely on the correctness of some software. The vendors of that software keep the code secret from the public. For more information see:
- http://verifiedvoting.org/
- PfaffenBLOG — Bryan Pfaffenberger (TCC Professor)'s Electronic Voting page
- FEC Voting System Standards — guidelines for testing and inspecing code for voting equipment. Example guideline from Section 5:
i. Excluding code generated by commercial code generators, is written in small and easily identifiable modules, with no more than 50% of all modules exceeding 60 lines in length, no more than 5% of all modules exceeding 120 lines in length, and no modules exceeding 240 lines in length. "Lines" in this context, are defined as executable statements or flow control statements with suitable formatting and comments. The reviewer should consider the use of formatting, such as blocking into readable units, which supports the intent of this requirement where the module itself exceeds the limits. The vendor shall justify any module lengths exceeding this standard;(Would your PS4 code satisfy this guideline?)(I am) "commited to helping Ohio deliver its electoroal votes to the president next year".
Walden O'Dell, CEO of Diebold Inc., a leading manufacturer of electronic voting machines, in fundraising letter Aug 14 2003.
University of Virginia Department of Computer Science CS 201J: Engineering Software |
Sponsored by the National Science Foundation |
cs201j-staff@cs.virginia.edu |