1 Building a Flexible Voting System
1.1 Step 1: Record three choices per voter
1.2 Step 2: Encapsulate the User Interface
1.3 Step 3: Add Exceptions to Report Malformed Votes
1.4 Step 4: Check for Clean, Encapsulated Code
1.5 Step 5: Support Methods to Compute the Winner
1.6 Step 5: Final Check for Clean Code
2 Testing Expectations and What to Turn In

Homework 5: A Customizable Voting Machine

Due Tuesday December 4 at 11:59 pm.

This assignment gives you practice with many concepts from the course so far, including hashmaps, encapsulation, exceptions, and passing methods as arguments.

If you are planning to go on to 3000- or 4000-level CS classes, this would be a good time to switch over to Eclipse.

We expect you to bundle your code into a package for this assignment. See these instructions for how to do that properly in each of DrJava and Eclipse.

You are welcome, but not required, to use Javadoc on this assignment. Those who plan to go onto more Java programming in any context (upper level CS courses, RBE, etc) should at least use Javadoc to add purpose statements to your methods.

1 Building a Flexible Voting System

You are building software to conduct an election. In this election, voters will state their top three choices (rather than a single choice). There are many different ways to determine winners in such preference-based elections. Unfortunately, the people conducting the election haven’t yet decided how they will count the votes. Therefore, they want you to build a voting system that will record votes, but will also let them experiment with different ways to determine the winner.

This starter file gives you a very rudimentary voting program: it presents a login screen that asks a voter to enter the name to vote for, stores that choice, and counts votes for a given candidate. Your job is to

Your solution to this homework should NOT include the countVotes method from the starter file or the current votes variable of type LinkedList<String>. You will still have a votes variable (or something like it), but with a different type that can handle three ranked choices per voter.

If you want to test your Java skills, spend a little time thinking about how you might do this before reading how we break this assignment into steps below.

Warning: Do this assignment in stages, making sure that your program runs properly after each stage. If you try to make all of the changes at once, you’ll spend far longer than needed on this assignment. Build up to your solution step by step. You can get much more credit for fully working early steps than for having most of the steps only partly working.

1.1 Step 1: Record three choices per voter

Edit the starter code to store the number of first, second, and third choice votes for each candidate on a ballot. Before reading on, think about what data structure(s) you might use for this information. After you’ve come up with your proposal on paper, feel free to look at (and use, or not) our suggested data structure.

Add a processVote method that takes three strings (for the first, second, and third choices, respectively) and returns void. This method stores a single voter’s choices in your data structure.

Include test cases for your processVote method in your Examples class.

1.2 Step 2: Encapsulate the User Interface

The starter file has put the entire voting system—ballot information, votes, and input-output methods—into a single class. Separate out (encapsulate) the input-output portion, creating a VotingMachine class to hold the input-output portion. The VotingMachine should have a variable that holds an object with the ballot and vote data.

The VoteBooth class name from the starter file no longer makes sense, since that class no longer contains the entire system. Rename (what’s left of) that class to VoteData.

1.3 Step 3: Add Exceptions to Report Malformed Votes

A vote is only valid if the voter enters three different names, each of which is a candidate on the ballot. Modify your code to check these criteria, using exceptions to report problems and require the voter to vote again if their vote is not valid.

You do not need to submit test cases that demostrate that the re-prompting behavior works, but you should check it yourself.

1.4 Step 4: Check for Clean, Encapsulated Code

Nothing to turn in for this part, but this would be a good time to check whether your code is well encapsulated, has good helper functions, and generally looks clean. You do NOT need to encapsulate the representation of ballots for this assignment (you may assume the ballot will always be a linked list of candidate names), but you should allow different data structures that store the three-choice votes.

1.5 Step 5: Support Methods to Compute the Winner

Add a findWinner method to the VoteData class. Initially, have this method simply return the name of some candidate with the maximum number of first-choice votes (if there is a tie, just return the name of one winner).

Once you have that working, change findWinner to take an argument that computes the "score" for a given candidate. The scoring function should take two arguments: the name of a candidate and the data that holds the votes cast. The function will return an integer, which is the score for that candidate relative to the data. The function computes the score for each candidate independently of the scores for any other candidate. The winner is one of the candidates with the maximum score under the given scoring function.

In your Examples class, include test cases that show how to use your findWinner method to determine the winner under each of the following two scoring methods:

Your test cases should include at least one election in which the two scoring methods would result in different winners.

1.6 Step 5: Final Check for Clean Code

Once again, check that your code is well-encapsulated and clean. Make sure you have appropriate access modifiers on all of your variables and methods.

This is your chance to show that you really get the ideas behind encapsulation and how to structure object-oriented programs properly. This assignment is as much about good software practice than it is about the functionality (which is reasonably straightforward).

2 Testing Expectations and What to Turn In

For this assignment, we will be looking for test cases on only processVote and findWinner. We will not be looking for test cases on all of your helper methods. This gives you more flexibility in the access modifiers you choose for methods (since they no longer need to be public for purposes of testing in the Examples class).

Turn in all .java files for this assignment. We do NOT need any generated Javadoc files.