The first assignment is mostly a warmup exercise to refresh your knowledge of Java and programming with polymorphism. The goal is for you to be able to compile and run code with the setup we give you so you are familiar with the development and submission process for this class. We recommend you read through the Running Java From the Command Line notes to understand how to compile and run your code if you are not using an IDE.
We provide you with a zip file that has all of the skeleton code for this assignment. Any detailed specifications (if not already specified here) will be documented in the Javadoc of this skeleton code.
For submission, see the Deliverables section. We need you to submit all of the code you wrote, as well as a README answering discussion questions and any other information important to the submission.
This first assignment has a very simple package setup: hw1 is the first package and enclosing folder for all the files. You will probably want to set up a directory called cs226 or something similar, and then unzip all your assignment skeleton zip files into that folder.
Files you will be editing are marked with an asterisk (*).
hw1-student.zip
--
hw1/
BasicCounter.java *
Counter.java
FlexibleCounter.java *
PolyCount.java *
ResetableCounter.java
TenCounter.java *
Unique.java *
These provided files should compile as is. From the directory hw1
is in, you can compile everything by running $ javac -Xlint:all hw1/*.java
, or using the generic compile script from the Java Command Line notes.
Your first task is to write a simple Java program Unique
that analyzes the command line it is given in a peculiar way. The program accepts any number of integers as command line arguments and prints each unique integer it was presented with as its output. For example, the invocation
java hw1.Unique 0 0 10 0 1 0 0 0 10 1
should generate the output
0
10
1
while the invocation
java hw1.Unique 1 9 2 3 1 4 9 5 3 6 0
should generate the output
1
9
2
3
4
5
6
0
instead. Note that order doesn’t matter as long as you print the correct set of numbers, one line per number, without any additional output!
If an argument is not an integer, your program should throw an IllegalArgumentException
. In the case you exit with an exception, it is not required that you do or don’t print the previous unique numbers.
As an added complication, you are not allowed to use any Java classes that serve as advanced data structures, specifically no Java collection classes like ArrayList
or HashMap
. You can use regular Java arrays, and in fact that’s probably the best way to go; the only “problem” is that we don’t specify an upper limit on the number of arguments, you’ll have to figure out how to deal with that…
IllegalArgumentException
.In your README, you should address the following:
1. Describe (in English) your algorithm and why it works.
2. Was there a different approach you started with that didn’t work?
3. Would using Java collection classes have made the process easier? If so, how? Do you think it would have made your code run faster? Why or why not?
4. Any difficulties getting your development environment set up? I.e. could you compile and run everything ok?
Your second task is to write a number of “counters” that can be used interchangeably (at least as far as Java is concerned). You are given the following interface in the Counter.java
file:
package hw1;
/** The essence of any counter. */
public interface Counter {
/**
* Current value of this counter.
* @return the current value of the counter.
*/
int value();
/** Increment this counter. */
void up();
/** Decrement this counter. */
void down();
}
You are also given a ResetableCounter.java
file with the following interface declaration:
public interface ResetableCounter extends Counter {
/** Reset the counter to it's initial value. */
void reset();
}
You are going to be developing a few implementations of ResetableCounter
s. To refresh your Java, think about what it means for ResetableCounter
to extend Counter
.
Develop the following:
ResetableCounter
called BasicCounter
that starts at the value 0 and counts up and down by +1 and -1 respectively.ResetableCounter
called TenCounter
that starts at the value 1, counts up by multiplying by 10, and counts down by dividing by 10.
ResetableCounter
called FlexibleCounter
that allows clients to specify a start value as well as an additive increment (used for counting up) when a counter is created.
new FlexibleCounter(-10, 42)
would yield a counter with the current value -10; after a call to up()
its value would be 32.FlexibleCounter
and pass it a a negative increment value, your FlexibleCounter
implementation should throw an IllegalArgumentException
.A major theme of this class will be testing the data structures you implement. For this assignment, we can stick with assertion testing using Java assert
statements, but we will cover a better approach later.
We provide you with a PolyCount.java
file that is more-or-less a testing suite for any implementation of a ResetableCounter
. To start, you should probably comment out the lines 43 and 44 and just start with testing your BasicCounter
. Once that is working you can uncomment and be able to test all implementations in the same run. You should add to this file to make a more comprehensive test of any ResetableCounter
implementation. If you would like, it also wouldn’t be a bad idea to add more methods and maybe test specific pieces of each implementation (for example, test that you throw exceptions when you should).
Make sure in your final deliverable that you pass your own tests from this file as we will be checking this in the autograder. (We will also do our own testing.)
public
and private
! The essence of those counters is not just to hold a bunch of data, but to ensure that a certain approach to counting is followed; making everything public is a bad idea here.extends
keyword). Classes implement interfaces however (using theimplements
keyword).FlexibleCounter
and BasicCounter
) to have any relationship.In your README, you should address the following:
1. What does ResetableCounter
extending Counter
do? In general, what does it mean for one interface to extend another.
2. Is any ResetableCounter
also a Counter
? Is any Counter
also a ResetableCounter
?
3. As far as PolyCount
is concerned, why did we write testAnyCounter()
method to take a ResetableCounter
as it’s parameter instead of a specific counter (like BasicCounter
)?
The files you have // TODO
items in are listed explicitly below:
Unique.java
BasicCounter.java
FlexibleCounter.java
PolyCount.java
TenCounter.java
You need to submit all of these files to the autograder along with a README. You can upload them individually or in a zip file. If you upload them in a zip file make sure they are all at the top level, you cannot have any extra directories or else the autograder won’t be able to find them.
Make sure the code you hand in does not produce any extraneous debugging output. If you have commented out lines of code that no longer serve any purpose you should remove them.
You must hand in the source code and a README file. The README file can be plain text (README
with no extension), or markdown (README.md
). In your README be sure to answer the discussion questions posed in this description, clearly labelled for each part of the assignments. You should also discuss your solution as a whole and let the staff know anything important, such as things you couldn’t figure out or specific trouble you had. If you are going to be using late days on an assignment, we ask that you note it in your README.
If you want to learn markdown formatting, here is a good starting point.
Once you are ready to submit your files, go to the assignment 1 page for Gradescope and click submit. Note that you can resubmit any time up until the deadline. Only your most recent submission will be graded. Please refer to the course syllbus as far as policies regarding late days and penalties.
After you submit, the autograder will run and you will get feedback on your functionality and how you performed on our test cases. Some test cases are “hidden” from you so you won’t actually know your final score on the test cases until after grades are released. On this assignment, since it is a warmup, we will only hide a few test cases. In future assignments, you will only be shown a few tests (to verify you compile), and the rest will be hidden.
If you see the “Autograder Failed to Execute” message, then either your submission did not compile at all or there was a packaging error. Please see the Gradescope Submission Notes for help debugging why your submission is not working.
You do not need to fully implement each file before you submit, but you’ll probably fail the test cases for the parts of the assignment you haven’t done yet. Also note that only the files with // TODO
items in them will be copied. You cannot modify any of the provided interface files (such as Counter.java
) as the autograder will overwrite any changes you made with the original provided file.
Normally, your files will have to be checkstyle compliant. However, for this assignment we will not enforce that to give you a little more time in getting your development environment set up. You will still get checkstyle feedback in the autograder, but for this assignment that component will be worth 0 points. It is probably a good idea to make sure you are able to work with checkstyle for future assignments. However, please don’t take this as an invitation to use bad style – we will still be keeping an eye out for reasonable style!
For reference, here is a short explanation of the grading criteria; some of the criteria don’t apply to all problems, and not all of the criteria are used on all assignments.
Packaging refers to the proper organization of the stuff you hand in, following both the guidelines for Deliverables above as well as the general submission instructions for assignments.
Style refers to Java programming style, including things like consistent indentation, appropriate identifier names, useful comments, suitable javadoc
documentation, etc. Many aspects of this are enforced automatically by Checkstyle when run with the provided configuration file.
public
, protected
, and private
appropriately, etc.). Simple, clean, readable code is what you should be aiming for.Testing refers to proper unit tests for all of the data structure classes you developed for this assignment, using the JUnit 4 framework as introduced in lecture. Make sure you test all parts of the implementation that you can think of and all exception conditions that are relevant.
Performance refers to how fast/with how little memory your program can produce the required results compared to other submissions.
Functionality refers to your programs being able to do what they should according to the specification given above; if the specification is ambiguous and you had to make a certain choice, defend that choice in your README
file.
If your submission does not compile, you will not receive any of the autograded-points for that assignment. It is always better to submit code that at least compiles. You will get freebie points just for compiling.
If your programs have unnecessary warnings when using javac -Xlint:all
you will be penalized 10% functionality per failed part. (You are also unable to use the @SuppressWarnings
annotation - we use it just to filter our accepted warnings from yours.)
If your programs fail because of an unexpected exception, you will be penalized 10% functionality per failed part. (You are not allowed to just wrap your whole program in to a universal try-catch.)