Assignment 01: HamSpam

Starter code: hamspam-student.zip
Collaboration: not permitted

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 the latest version of the Java8 SE SDK and the latest version of the Eclipse IDE for Java development.

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 an entire Eclipse 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. Programming assignments generally do not permit collaboration. At the top of each assignment, the collaboration policy is clearly stated.

    When collaboration is not permitted, copying partial or whole solutions, obtained from other students or elsewhere, is academic dishonesty, as is showing your code to other students or looking at other students’ code.

    Remember, you can use the course Piazza site to quickly (and anonymously, if you like) get help from both the course staff and your classmates. When using Piazza, don’t copy/paste large chunks of code into your question. Instead, do the same thing you should do if asking a classmate for help: ask your question by describing the problem you’re having, or use a small synthetic example that illustrates your difficulty. If your question requires that you show your code, mark it as a “private” question, and only the course staff will be able to see it; then make sure you’ve uploaded to Gradescope, as we’re able to view your project there.

  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 exhaustively 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 University’s Academic Regulations and otherwise at my discretion.

Downloading the SDK

The first thing to do is to download the Java8 SDK (Ideally, not Java 12 – we haven’t tested all of the assignments with Java12 yet!).

Go to Oracle’s Technology Network website (http://java.oracle.com/), navigate to the Java section, then find the Java SE downloads section. (When I wrote this text, the direct link was at: https://www.oracle.com/technetwork/java/javase/downloads/index.html; if this link does not work, please contact me to update it.)

You should arrive at a page that looks like the following:

SDK download landing page

Click the download button for the JDK, and you should arrive at a page listing the various downloads available:

SDK download page

Choose the correct version for your operating system. For Mac OS X, there is only one choice. For Windows on a relatively new machine, you almost certainly want the “x64” version. (For Linux, you will probably want to install your distribution’s version of the OpenJDK. Check your specific Linux distribution’s package manager for the preferred Java8 SDK on your distribution.) Accept the license agreement using the small radio button, then click the download link.

The key point here is that you are downloading the Java8 SE SDK (that is, the JDK) – you are not downloading Java EE or ME, and you are not downloading the “Java Runtime Environment” (“JRE”).

You should be downloading the latest version, which at the time of this writing is the Java SE Development Kit 8u221 . Java12 might or might not work with future projects.

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 Java8 SE SDK installed on your system. To verify:

The 1.8 part is the most important thing here.

Again, the 1.8 part is the most important thing here.

Downloading Eclipse

Go to Eclipse’s web site (http://www.eclipse.org/), and press the shiny “Download” button:

Eclipse home page

Click “Download” (or perhaps “Download 64 bit” as shown below) again:

Eclipse download page

And then once more to download the installer for Eclipse:

Eclipse final download page

Depending upon your OS, this file may be an compressed archive (.tar.gz or .zip) or a directly executable installer (.exe). If it’s an archive, open it to find the installer (Eclipse Installer).

Installing Eclipse

Run the installer. You will be prompted to choose which “flavor” of Eclipse you want:

Eclipse installer

Marvel briefly at the many options available, but make sure you select the “Eclipse IDE for Java Developers”.

The default installation directory is fine (on my Mac, this is /Users/liberato/eclipse/java-2019-06, that is, in eclipse/java-2019-06 inside my home directory), or you can place it in whatever directory you choose. In either case, make sure you note where it’s going so you can find it! The installer will download and install Eclipse, and this process can take a few minutes.

Launching Eclipse

If all goes well, you should see something like this:

Eclipse installer success

Go ahead and click the “Launch” button. After a brief loading screen, you should see a window prompting you to choose a workspace:

Eclipse installer

A brief but important digression: The place you choose for the Eclipse workspace is where all of your work for this course will go. I strongly, strongly, strongly suggest you do one (or ideally both) of the following:

In any event: storage and bandwidth are virtually free, and the University has both computer labs and loaner computers available. “My computer crashed” won’t be acceptable as an excuse in this class.

Now back to our regularly scheduled program.

Choose an appropriate directory to store your workspace and click OK. After a bit more loading, you’ll see the default Eclipse “Welcome” screen:

Eclipse installer

Eclipse has been installed.

Configuring Eclipse

Quit Eclipse using the appropriate menu item.

Now re-open it. (Do you remember where you installed it?) You should again arrive at the Welcome screen.

Open the Preferences menu item. On a Mac, this will be located in the Eclipse menu in the top-of-the-screen menubar; on Windows, it will be located under the Window menu at the top of the Eclipse window. Either way, it should look something like the following:

Eclipse preferences

Eclipse has about eleventy-hojillion configuration options, but we’re only going to look at one of them for this assignment.

Expand the “Java” item on the left by clicking the small triangle next to it, then select “Installed JREs” by clicking on it (not the triangle, but the words “Installed JREs”). Here’s what it looks like on my Mac:

Installed JREs

And here’s what it looks like on a student’s Windows 10 PC:

Installed JREs, Windows

You should see a list of one or more JREs, depending upon what’s installed on your computer. If you don’t see “Java SE 8” (on a Mac) or “jdk1.8.0_181” (or similar on Windows and Linux – “jdk” and “1.8” are the important parts), click the Search... button on the right, and it should show up (assuming you installed one earlier!). If it doesn’t, contact the TA or instructor via Piazza immediately for assistance, or check with a classmate for help. Make sure that “Java SE 8” or “jdk1.8.0_181” is selected (note the Windows screenshot doesn’t yet have the correct item selected!).

Again, the important thing here is that the “1.8” or “Java 8” or the like is selected.

Downloading and importing the starter code

Download and save (but do not decompress) the provided archive file containing the starter code. Note that in this and future labs, the starter code is linked to at the top of the assignment.

Open Eclipse. Depending upon how you left things after installing Eclipse, you might see either the welcome screen, or the standard eclipse workspace. Close the welcome screen if it’s open. Then choose “Import…” from the “File” menu. A window will come up so you can choose how to import. Select “General” and within that, “Existing Projects into Workspace” (It may seem strange, but do not choose “Projects from Folder or Archive”) Then click “Next”.

import

Choose the button for “Select archive file:” and locate the file you downloaded above. Then click “Finish”.

select file

(Side note: It is possible your browser will automatically decompress the hamspam-student.zip file for you! If that happens, you will need to slightly modify the instructions above. Instead of “Select archive file:“, use “Select root directory:” instead, and then navigate to the place where your browser decompressed the .zip.)

You should see a hamspam-student Java project in the Package Explorer window on the left. Click on the triangles to reveal the content of this directory and the src, support, and test directories within it.

expanded

Finally, we’re going to make the support directory read-only. The folder contains support code that we encourage you to use (and which must be used to pass certain tests), but you must not change or add anything in this folder. (In this and future assignments, if you change or add files in this directory, you might find that your program runs fine on your machine but that the autograder will not compile it successfully.)

To help ensure that you do not change anything in support, we suggest that you set the folder to be read-only. You can do this by right-clicking on it in the Package Explorer, choosing “Properties” from the menu, choosing “Resource” from the list on the left of the pop-up “Properties” window, unchecking the “Permissions” checkbox for “Owner-Write”, and clicking the “OK” button. A dialog box will show with the title “Confirm recursive changes”, and you should click on the “Yes” button.

permissions

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

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 Eclipse

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

Finding and fixing compilation errors. You can see that Eclipse has noted that “The blank final field hamNumber may not have been initialized,” as displayed in the Errors list at the bottom and as shown by the red underlines in the source for HamSpam.java.

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; to set the instance variable to the argument passed to the constructor.)

Note that each distinct instance of HamSpam may have a different pair of ham and spam numbers; 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 hamspam values.

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 (which does have a main method), then click the green play button in the top row of the Eclipse window (it looks like a white triangle inside of a green circle), or choose “Run” from the Run menu. A console will appear in the bottom of the Eclipse window. Follow along, pressing Enter after each number you enter, to see the (sometimes incorrect) results of the current implementation of Ham and Spam.

Running tests. Next, choose HamSpamTest.java in the Package Explorer and run it using the play button or the menu, as above. When you do, the package explorer on the left will switch to a JUnit pane, which will show the testing output. JUnit is a standard unit-testing library for Java that we’ll be using extensively in this course.

You should see a total of fourteen tests: four tests that pass (with small green checkmarks), and ten tests that fail (with small blue Xs). Familiarize yourself with the testing interface: hover over the buttons to see what they do (notably, one toggles showing only failed tests), and double-click on a test to jump to it. 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)

You may have to resize the JUnit pane to see the full message.

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; you can double-click on at hamspam.HamSpamTest.testHamAndSpamGetValue(HamSpamTest.java:41) (or just the test itself, as noted above) to jump to the test in the source pane. 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 and selecting “Open Declaration”, or by double-clicking on HamSpam.java in the Package Explorer and scrolling to it.

Your goal should be 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().

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.

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 press the “Play” button and run a bunch of tests quickly and repeatedly is much more convenient, especially as programs grow more complex.

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, click on the “hamspam-student” project in the package explorer. Then choose “Export…” from the “File” menu. In the window that appears, under “General” choose “Archive File”.

export archive

Then choose “Next” and enter a destination for the output file. Be sure that the “hamspam-student” project is selected, and that all Java source files in src files are included (the easiest way to do this is to click “Select All”).

save export

Save the exported file with a .zip extension (any name is fine). Then log into Gradescope, select the HamSpam assignment, and submit the file for grading, just as you did for Homework 01. You’ll see the contents of the .zip file in the upload window after you select it:

upload

If you uploaded a not-fully-correct submission, you might see something like the following:

autograded

Compilation errors will be provided by the autograder, but the exact details of the tests we run on your code are deliberately not provided. 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. If it turns out you missed something and your code doesn’t pass 100% of the tests, you can keep working until it does.