CS 161 Lab #8

March 21st

Goals:

This week you'll extend some code I've written that's supposed to model an electronic voting system. The goal is to end up with code that allows the user to create an Election instance, add the names of the candidates, then record votes each time a vote() method is invoked. You'll also add a method that looks through all of the vote totals and declares a winner. Of course, this is all just an excuse to get some practice declaring and using arrays, and getting used to their zero-based index values! (You can see examples of the array-based code we wrote in lecture in the Die class.)

Getting Started

In each lab this semester you will work with a partner. Please be kind in your interactions with your partners! Keep in mind that students in this class have a range of previous programming experience, and that some have been college students for longer than others. We're all in this together, and you have something to learn from your partner, no matter who they are or what their previous experiences have been. I expect that group members will collaborate and work together on each step of the lab.
  1. Take a moment to introduce yourself to your partner(s). After social pleasantries are complete, pick one member of the team to be the "typer". They'll share their screen while editing the lab code in BlueJ. (I think BlueJ works better for these interactions than Eclipse. It's easier to see when sharing screens, and makes it easier to quickly test individual methods than Eclipse does.) Group members should contribute equally while working through the problems below and discuss all code to be written, though only the "typer" will be able to edit code. Resist the temptation to have both members work simultaneously in BlueJ — you're much more likely to "drift apart" over the course of the lab if you do so. The goal here is to have a partner who's engaged on exactly the same step of the lab as you are.

    Consider letting the less experienced member of the group do the typing if it seems like there's a mismatch in experience or comfort levels. That will help make sure they don't get left behind. Worst case, flip a coin to see who does the typing. Or have Java generate a random boolean value. (Type "(new java.util.Random()).nextBoolean()" in the codepad without the double quotes.)

    At the conclusion of the lab, make arrangements for the typer to share a copy of the code with the other member(s) of the group if desired. (E.g. email it, or put it on a shared Google drive, etc.) My solutions to the lab will get posted as well.

  2. Download the ElectionLab project and extract its contents, then start BlueJ and open the project.

Directions:

  1. Take a moment to familiarize yourself with the Java code in the Election class. Right now, there's an array of Strings declared that will hold the names of the candidates in an election. The constructor creates a new array of the proper size, and there are methods for adding new candidates to the election, and printing the list of candidates. The vote-counting code isn't there yet, but you can still create Election instances and play with candidates:

    > Election e = new Election(4);
    > e.printCandidates();
    1) null
    2) null
    3) null
    4) null
    > e.addCandidate("Alice", 1);
    > e.addCandidate("Brad", 2);
    > e.addCandidate("Catherine", 3);
    > e.addCandidate("Doug", 4);
    > e.printCandidates();
    1) Alice
    2) Brad
    3) Catherine
    4) Doug
    
  2. Before we can write the vote method, we need a place to keep the vote totals for each candidate. Add a new field to the class that will hold an array of integers for this purpose. Don't forget to create this array in the constructor, in addition to the array of candidate names.
  3. Define a vote method that takes a 1-based candidate index (just like addCandidate does), and increments the vote count for the corresponding candidate. You should ignore the vote if the candidate index isn't valid. You can test your vote method by invoking the methods below, then using the object inspector to view the contents of your vote count array. ("Brad" should've won, of course.)

    > Election e = new Election(4);
    > e.addCandidate("Alice", 1);
    > e.addCandidate("Brad", 2);
    > e.addCandidate("Catherine", 3);
    > e.addCandidate("Doug", 4);
    > e.printCandidates();
    1) Alice
    2) Brad
    3) Catherine
    4) Doug
    > e.vote(1);
    > e.vote(2);
    > e.vote(2);
    > e.vote(3);
    > e.vote(2);
    
  4. Next, add a printResults method that looks through the vote counts, and declares a winner. The easiest way to do this is keep track of the index of the largest total you've encountered as you work through the array. If you find a larger total, update the index. When you're all done with the loop, you can use the index to get both the name of the winning candidate, and the number of votes they received:

    > Election e = new Election(4);
    > e.addCandidate("Alice", 1);
    > e.addCandidate("Brad", 2);
    > e.addCandidate("Catherine", 3);
    > e.addCandidate("Doug", 4);
    > e.printCandidates();
    1) Alice
    2) Brad
    3) Catherine
    4) Doug
    > e.vote(1);
    > e.vote(2);
    > e.vote(2);
    > e.vote(3);
    > e.vote(2);
    > e.printResults();
    The winner is candidate 2, Brad, with 3 votes.
    
  5. The way things are implemented now, there's nothing to stop the user from adding candidates (or replacing existing ones) even after voting has started. Modify the class so that candidates can't be added or modified after the first vote has been cast. (You'll want a boolean field to help you with this, and edit addCandidate so that it prints an error message if it's called after voting has started.) The interactions below show that addCandidate worked normally until vote was called, but the attempt to replace the candidate "Brad" with "Bart" failed after the first vote:

    > Election e = new Election(4);
    > e.addCandidate("Alice", 1);
    > e.addCandidate("Brad", 2);
    > e.addCandidate("Catherine", 3);
    > e.addCandidate("Doug", 4);
    > e.printCandidates();
    1) Alice
    2) Brad
    3) Catherine
    4) Doug
    > e.vote(1);
    > e.addCandidate("Bart", 2);
    Hey -- you can't change candidates after voting starts!
    > e.vote(2);
    

Extras

If time permits, consider trying one or more of the following exercises:


Brad Richards, 2024