Assignment 01: HamSpam

Starter code: hamspam-student.zip

Computer science is the study of the theory of computation and its applications. In this course, we will weight the scales toward application. Two important parts of applying the theory of computation are knowing how to make a computer do what you want (programming) and checking that it’s doing what you want (testing). This assignment consists of a textual description of a “toy problem”, provides starter code to solve that problem, and asks you to solve the problem and test that your solution is correct.

Overview

In this assignment, you’ll download and install a version of the Java SE SDK and Visual Studio Code, a lightweight editor and integrated development environment that can be used for Java programming (and many other things!).

Then, you’ll learn to download and set up starter code that we provide, a skill which you’ll need for almost every future programming assignment in this course. You’ll use that code to complete an implementation of the Ham and Spam counting game. Along the way, you’ll start to learn about unit testing, a repeatable, automatable way to detect bugs (and not incidentally, a way for us to test your submissions). Finally, you’ll learn to export and submit the project to the autograder.

Goals

Some reminders

  1. Start this (and future) assignment(s) early. It is your responsibility to start early enough that you can get help if you have trouble!

  2. This is the first programming assignment. You may work with at most one partner! If you do choose to work with a partner, make sure to fill out the Author.java file! But for this assignment it’s especially important that you make sure you can do all the steps on your own computer, not just watch your partner do them, as you’ll need to set up your own computer for future programming.

  3. Do not expect partial credit if you submit a program that does not compile or contains an infinite loop. Errors of these sorts in your project will cause the autograder to fail, and you will receive a zero for your submission.

  4. We do our best to check the assignments and autograder. But, if you think something is wrong with the autograder or assignment (as opposed to your submission), contact the course staff immediately. Capture a screenshot of the error, and export a copy of your assignment in the state that triggers the error. Providing these to us will help us immensely in narrowing down the problem.

  5. Late submissions will not be accepted. Excuses with documentation may permit you to submit an assignment late on a case-by-case basis, consistent with the syllabus, the University’s Academic Regulations and otherwise at my discretion.

Downloading and installing the Java SDK

The first thing to do is to download and install the OpenJDK Java 11 SDK. If you know you already have a copy of the JDK 11 installed (from a previous class, perhaps), you can skip this step.

Downloading the SDK

Go to https://adoptopenjdk.net, select the “OpenJDK 11 (LTS)” and otherwise keep the default “JVM”, probably “HotSpot”.

Download the “Latest release” (at the time I wrote this, you did this by clicking a big blue button).

Installing the SDK

Locate the downloaded file, which will be stored with in your web browser’s standard download location.

Under Windows, it’s a self-extracting executable file (.exe) that runs the installer; under OS X, it’s an installer package (.pkg) inside of a disk image (.dmg). Either way, double-click the file. (Your web browser might also have prompted you to run the downloaded file, which is fine, too.)

Once you run the installer, you should be guided through a series of dialog boxes. You should choose a default (standard) install: the JDK for all users.

Verifying the installation

If everything appears to have gone well, you should have the Java SDK installed on your system. To verify:

and

javac 11.0.8

The exact numbers might differ depending upon which version you installed, but the 1.8 part is the most important thing here.

You’re looking to see that a folder staring with jdk1.11 or something similar is in this directory. It’s OK if there’s also a JRE installed (in a folder starting with jre, as shown here), but you must also have the JDK installed.

Setting up (or downloading) Visual Studio Code

If you already have VSC installed, you can customize it with the extensions we’ll be using in this class:

Or just install the Java Extension Pack from Microsoft and the “Archiver” extension separately.

If you don’t already have it installed, you can download and install a version of VSC with the Java extensions already active by following the directions here: https://code.visualstudio.com/docs/languages/java under “Install Visual Studio Code for Java”. You’ll still need to install the Archiver extension.

Finally, if you just install VSC, the first project is configured to prompt you to install all of these extensions – so if you miss one, you’ll get another chance.

(A side note: Do you have to use VSC or all of these extensions? No, you can use any tool you like. However, the course staff will only support use of VSC, and all instructions will be written assuming you’re using it.)

Downloading and importing the starter code

Download and save the provided archive file containing the starter code – it’s compressed in the zip format. Note that in this and future labs, the starter code is linked at the top of the assignment’s page.

Depending upon your browser and operating system, you may end up with the zipped archive file, or you may end up with the decompressed archive, which will appear as a folder (also known as directory), named hamspam-student. Put this folder into an appropriate location on your computer.

A brief but important digression: You should probably put your files for 186 all in one place. I strongly, strongly, strongly suggest you do one (or ideally both) of the following:

In any event: remote storage is virtually free, and the files created for this course are tiny relative to, say, your carefully-curated K-pop MP3 collection. “My computer crashed” won’t be generally be acceptable as an excuse in this class.

Now back to our regularly scheduled program.

Open VSC. Depending upon if you’ve used it before, you may have various “Welcome to Visual Studio!” kinds of windows pop up. Read their contents if you like, and then close them. Eventually, you will have a single window left, that says something like “Visual Studio Code – Editing evolved” and a list of options. Choose the “Open folder…” option (or select it from the drop-down “File” menu), find your hamspam-student folder, and open it. You must use “Open folder” and not “open file” or VSC won’t know that the file(s) you are editing are part of a project and the tests won’t work.

You may be prompted to install the course-specific extensions if you haven’t already. (Do so unless you have reason not to.)

You may also see a prompt asking if you “want to exclude the Visual Studio Code Java project settings files […] from the file explorer.” I suggest you do so “in workspace” or “globally” – this will prevent you from accidentally breaking VSC’s Java configuration for this project.

You should see a hamspam-student folder in the Explorer window on the left.

Folder are represented by small arrows pointing down for folders whose contents is shown, and to the right for folders whose contents is hidden. Click on the folder name to toggle whether its contents is shown or not. In particular, click on src, support, and test.

You should see three Java source files among the folders: HamSpam.java, HamCommander.java, and HamSpamTest.java. You can open them by clicking on them. Do so, and take a look through each of them. You’ll see that they involve a game about “Ham”, “Spam”, and numbers, and that VSC has detected errors.

src, support and test

In this (and all future) projects, you’ll see these three directories. What do they mean?

On Ham and Spam

“Ham and Spam” is a children’s counting game. Before it is played, the players agree on a ham number and a spam number. Both are integers greater than one, and they cannot be the same number. The players then take turns saying the hamspam value for each successive integer, starting at one. Usually, the hamspam value is just the number. But:

For example, if the ham number is three, and the spam number is four, then the first twelve hamspam values are:
1, 2, ham, spam, 5, ham, 7, spam, ham, 10, 11, hamspam

For this assignment, you are going to modify the HamSpam class provided to produce the correct value or values for a game of “Ham and Spam”.

Using VS Code

Let’s walk through using VSC to identify and fix errors, run code, and run unit tests.

Finding and fixing compilation errors. You can see that VSC has highlighed the HamSpam.java in red. The red underlines in the source for HamSpam.java indicate there’s an error; if you hover the mouse pointer over that line, you’ll see that “The blank final field hamNumber may not have been initialized.”

In other words, the instance variable hamNumber is declared (private final int hamNumber) but never set to a value if the class is instantiated. Your lazy instructor didn’t even provide you with code that compiles!

Fix the error by modifying the constructor of HamSpam to set the instance variable hamNumber to the appropriate argument of the constructor. (A reminder: when a local variable, such as the argument to the constructor, has the same name as an instance variable, you can disambiguate the instance variable by including the this. qualifier. In other words, you can write this.hamNumber = hamNumber; in the constructor to set the instance variable to the argument passed to the constructor.)

Then fix the same error for spamNumber.

Each distinct instance of HamSpam may have a different pair of ham and spam numbers. For example, an instances with a ham number of four and a spam number of five is created when a program calls new HamSpam(4, 5)). These values are tracked in these instance variables. When you open HamSpamTest.java you’ll see that more than one instance of HamSpam is created, each with its own ham and spam numbers.

Running programs. Once you’ve eliminated errors, you can run the program. But you’ll note there’s no main method in HamSpam.java. Instead, open HamCommander.java and take a look at its main method. To run it, right-click on HamCommander.java in the left-hand side of the window , then choose “Run” from the context menu. A “Terminal” showing the “Java Process Console” will appear in the bottom of the VSC window. Follow along, pressing Enter after each number you enter, to see the (sometimes incorrect) results of the current implementation of Ham and Spam.

If you want to check your implementation of HamSpam, you can do it this way. But now we’ll look at automated tests, which provide a faster way to more reliably repeat the same set of checks each time you run them.

Running tests. Open the “Command Palette” using the “View” menu. (You can also use a keyboard shortcut to do so; on a Mac, for example, it’s Command-Shift-P.) You are looking for an item labeled “Java: Run all tests”. To find it quickly, type the word “tests” to narrow the listed choices. Choose the item and run it by clicking on it or pressing “Enter” when it’s selected.

This will open a “Java Test Report” in a new window.

You should see a total of fourteen tests: four tests that pass, and ten tests that fail. Familiarize yourself with the testing interface: You can click on “All”, “Failed”, or “Passed” up to show only those tests; you can clicker the icon to the far right of each test to jump to the test’s source code; you can click the arrow on the left of each test to see the “stack trace” (that is, the currently-executing methods when the test failed).

For example, if you select testHamAndSpamGetValue, you should see the following under Failure Trace:

org.junit.ComparisonFailure: getValue returns incorrect value
expected:<[hamspam]> but was:<[12]>
at hamspam.HamSpamTest.testHamAndSpamGetValue(HamSpamTest.java:41)

…and much more of the stack track, but it’s typically only the top line or two that will be relevant

JUnit tests work by checking that the expected result of a method call equals the actual result. The failed test indicates that one (or more) methods in the starter code aren’t returning correct values. Examine the test; again, click on the icon to its right, or navigate to it manually in HamSpamTest.java around line 46.

Here, you can see that the test case expects the result of hamspamThreeFour.getValue(12) to be the string "hamspam", but as the output in the Failure Trace indicates, it produced the string "12" instead.

Diagnosing and fixing problems. Go to the declaration of getValue(); you can do so by right-clicking on it in HamSpamTest.java and selecting “Go to Definition”, or by double-clicking on HamSpam.java in the Package Explorer and scrolling to it.

Your goal is to correct the implementation of the getValue() method. The correct solution is not merely to make the function return “hamspam” when n == 12. Instead, you should revise the code so that the function will return the correct string for any n.

There is at least one thing to fix. The getValue() method currently checks for equality against numbers, not divisibility. You can use the modulus (remainder) operator (%) to check for divisibility. It divides one number by another and returns the remainder. For example, if you wanted to print out whether the value of a variable n was divisible by three, you could write:

if ((n % 3) == 0) {
  System.out.println(n + " is divisible by 3");
else {
  System.out.println(n + " is not divisible by 3");
}

Notably, the value ((n % 3) == 0) will evaluate to true if and only if n is divisible by three. You can use this fact in your implementation of getValue(). One straightforward correct implementation will involves three if statements. Post a question on CampusWire or come chat with us during office hours if you get stuck.

Finishing up. Next, you’ll need to write getValues(), which will allocate and return an array of String containing the correct hamspam values for the range. Think carefully about what you need to do: create and return an array of the right size with the right values. Break this down into several parts: How big should the array be? Then, how do you put the right values into the right places of the array?

When we autograde your program, we will test both getValue() and getValues() with other ham and spam numbers to make sure each works properly. Our test cases will obey the constraints described in this assignment (for example, the ham number and spam number will always be greater than one, and never be equal to one another), but are otherwise unconstrained.

In this assignment, we’ve given you all the test cases. But in future assignments, there are test cases we are going to use that you won’t be able to examine for yourself. You will have to think about the problem and make sure you’re not missing any details or corner cases if you want to pass them. (We’ll teach you to write tests soon, but there’s no magic: copy/paste and edit an existing test to get 90% of the way there.)

You can also use the HamCommander class for interactive testing. But as you’ll see, just being able to “Run tests” quickly and repeatedly is much more convenient, especially as programs grow more complex.

Working with a partner

For this assignment, it’s probably best if you do it yourself – that way, you’ll know you have VSC set up correctly and that you know how to submit the assignment through Gradescope.

If you choose to work with a partner on this or any other assignment, you will need to edit the comments in the Author.java file appropriately. See the syllabus for details.

Submitting the assignment

When you have completed the changes to your code, you should export an archive file containing the entire Java project. To do this, open the Command Palette again, and choose “Archive Folder”. This will create a zip file containing the project in the same folder where you stored the hamspam-student folder. It will have a numerical suffix, for example, hamspam-student_1598196069605.zip. (You can also make the zip file yourself with another tool, if you prefer.)

Next, log into Gradescope, select the HamSpam assignment, and submit the file for grading. You’ll see the contents of the .zip file in the upload window after you select it.

If you are doing a submission with a partner, be sure to note that when submitting! Do so in two steps: First, edit Authors.java; and second, make sure you select your partner in the submission dialog box on Gradescope. Only one partner needs to submit the file; both will receive the same credit.

Compilation errors will be provided by the autograder, but the exact details of the tests we run on your code are deliberately not provided in Gradescope. For this assignment, the tests you have locally and the tests run on Gradescope are the same, but this won’t always be the case. You must read assignments carefully – if your submission is not passing a test, it is almost certainly because your submission doesn’t match the requirements of the assignment.

Remember, you can resubmit the assignment as many times as you want, until the deadline. (Make sure you upload the right version!) If it turns out you missed something and your code doesn’t pass 100% of the tests, you can keep working until it does.