CS 211 Project 2: Obligatory Objects
- Due: Monday 2/15/2016 by 11:59 pm
- Approximately 5.7% of total grade
- Submit to Blackboard
CODE DISTRIBUTION:
- Provided files: p2pack.zip
- Tests: Contained in
p2pack.zip
- Honors Section Tests: CircularQueueTests.java
CHANGELOG:
- Tue Feb 9 18:53:01 EST 2016
- The Honors Section problem has been added. Download the tests above and read the honors section problem for what to do.
- Fri Feb 5 12:24:31 EST 2016
- The class structure for
GneeralLE
was originally identical toSlopeInterceptLE
by accident; this has been corrected. - Thu Feb 4 20:57:04 EST 2016
- The original posting of the spec was missing overviews of the
SlopeInterceptLE
andGeneralLE
classes which have now been added.
Table of Contents
- 1. Project Overview
- 2. Background on Linear Equations
- 3. Problem: Slope/Intercept Linear Equations
- 4. Problem: General Form of Linear Equations
- 5. Problem: Proper Integer Queues
- 6. Honors Section: Circular Queues that Expand
- 7. Other Manual Inspection Criteria
- 8. Running the Automated Tests
- 9. Project Submission
1 Project Overview
1.1 Problem Sets
This project has 3 problems to complete. All of them involve creating new classes which do not exist in Java. The first two problems involve modeling simple linear equations of two variables using classes. This will introduce the idea of invariants: properties that should always be true about a class after one of its methods completes. The third problem revisits the queues of the previous project and implements them in a proper, Java-esque fashion as an object with associated methods. The honors problems builds on this to improve the efficiency of the queue methods and makes it more flexible to allow for expansion.
1.2 Project Files
The following files are relevant to the project. Some are provided in
the project distribution while others you must create. You should
submit all files listed unless marked as Optional
(in the State
column).
File | State | Notes |
---|---|---|
SlopeInterceptLE.java | Create | Create for first problem |
SlopeInterceptTests.java | Testing | Tests for first problem |
GeneralLE.java | Create | Create for second problem |
GeneralLETests.java | Testing | Tests for second problem |
ProperQueue.java | Create | Create for third problem |
ProperQueueTests.java | Testing | Tests for third problem |
P2Tests.java | Testing | Run all standard tests for the project |
CircularQueue.java | Honors | Create for honors problem |
CircularQueueTests.java | Honors | Tests for honors problem |
junit-cs211.jar | Testing | JUnit library for command line testing |
ID.txt | Create | Create in setup to identify yourself |
2 Background on Linear Equations
Throughout much of your Mathematics education, you've likely spent time using linear equations to represent the relationship between things and solved them as parts of larger problems. We like to solve problems with computers, so a good first step could be developing our own library of classes to represent these equations.
The primary motivation of the object-oriented programming paradigm is to guarantee that operations on data preserve internal invariants for that data. Most of us know that the radius and diameter of a circle have the relationship \(r = 2d\). If circles are represented using both radius and diameter, changing one must affect the other: a circle with radius 5 and diameter 322 badly violates our notion of what constitutes a proper circle. This is the essence of the object-oriented paradigm, to only allow access to manipulate an object via certain methods which will preserve the internal consistency of the object's state.
In the next few problems we will be representing linear equations with real number coefficients in two different formats. We need a representation that keeps track of the different variables and constants, and that also maintains the relationship between them as the variables are changed. We consider first the slope intercept form, and then the general form.
Should you need a math refresher, Wikipedia's Linear Equations article contains useful reminders of terminology and formulas.
3 Problem: Slope/Intercept Linear Equations
Files to submit
-
SlopeInterceptLE.java
- Define a class to model a linear equation of variables \(x\) and \(y\) in slope intercept form. A skeleton for this file is provided in the project pack.
-
SlopeInterceptLETests.java
- Provides tests of the correctness of the above class.
3.1 Good old Em ex plus Bee
A linear equation is in slope intercept form if it is written \[ y = m x + b \] where \(m\) and \(b\) are constants that do not change while \(x\) and \(y\) are variables that do change.
Define a class which models a linear equation in slope intercept form.
A template is provided for you in the file SlopeInterceptLE.java
.
You will need to add any fields that are required for the class to
work properly and fill in definitions for the below methods.
3.2 Class Structure of SlopeInterceptLE
// A class to model linear equations of two variable (x and y) in // slope intercept form. public class SlopeInterceptLE { // Public constructor that accepts values for the slope m and // intercept b, defaults the value of x to 0.0 and sets y // appropriately. public SlopeInterceptLE(double m, double b); // Public constructor that accepts values for the slope m and // intercept b and initial value of x and sets y appropriately. public SlopeInterceptLE(double m, double b, double x); // Return the numeric value of the equation which is the numeric // quantity that should be on both left and right sides of the equal // sign. public double value(); // Return the current value of x public double getX(); // Return the current value of y public double getY(); // Set the value of x and change y accordingly to preserve the // equation. public void setX(double x); // Set the value of $y$ and change $x$ accordingly to preserve the // equation. public void setY(double y); // Return a =String= version of the general form of the equation. // The pretty version's general format should be as follows. // // y = M.MM * x + B.BB // // M.MM is the slope with 2 digits of accuracy and B.BB is the // intercept with two digits of accuracy. Look for a method of the // String class to assist with formatting. // // Examples: // y = 1.23 * x + 122.41 // y = -1.23 * x + -122.41 public String toString(); }
3.3 Implementation Notes
The method
public String toString()
should return a String
version of the general form of the equation.
This string's general format should be
y = M.MM * x + B.BB
where M.MM
is replaced with the value of \(m\) with 2 decimal
digits of accuracy and similarly for B.BB
being replaced by
\(b\). For example, if \(m = 1.23, b= 122.408\), the appropriate
string to produce is
y = 1.23 * x + 122.41
If \(m = -1.23, b= -122.408\), the appropriate string to produce is
y = -1.23 * x + -122.41
This task is significantly easier if you examine the String.format()
method and learn a few things about format strings for producing nice
looking output. Format strings are used with System.out.printf()
which is derived from the C language printf
function. There are
several places to learn about them.
3.4 Sample Session
Welcome to DrJava. Working directory is /... > SlopeInterceptLE si = new SlopeInterceptLE(1.0,2.0) > si y = 1.00 * x + 2.00 > si.toString() y = 1.00 * x + 2.00 > si.getX() 0.0 > si.getY() 2.0 > si.value() 2.0 > si.setX(4) > si.value() 6.0 > si.getY() 6.0 > si y = 1.00 * x + 2.00 > si.toString() y = 1.00 * x + 2.00 > si = new SlopeInterceptLE(0.25, 10.25, 1.0); > si.getX() 1.0 > si.getY() 10.5 > si y = 0.25 * x + 10.25 > si.setY(4.5) > si.getY() 4.5 > si.getX() -23.0 > si y = 0.25 * x + 10.25 > si.value() 4.5 > si = new SlopeInterceptLE(-0.25, -10.25, -1.0); > si.toString() y = -0.25 * x + -10.25 > si = new SlopeInterceptLE(0.67512, -1.999, -1.0); > si.toString() y = 0.68 * x + -2.00
3.5 (10%) SlopeInterceptLE
Manual Inspection Criteria grading
- Fields of the class are present, documented, and have an appropriate access modifier to prevent external sources from modifying them
- Methods should be short and sweet
4 Problem: General Form of Linear Equations
Files to submit
-
GeneralLE.java
- Define a class to model a linear equation of variables \(x\) and \(y\) in general form. You must create this file.
-
GeneralLETests.java
- Provides tests of the correctness of the above class.
4.1 General LE
A linear equation is in general form if it is written \[ a x + b y = c\] where \(a,b,c\) are constants that do not change while \(x\) and \(y\) are variables that do change.
Define a class which models a linear equation in general form.
You will need to create the file GeneralLE.java
and fill in the
appropriate fields and methods.
4.2 Class Structure of GeneralLE
public class GeneralLE { // Public constructor that accepts values for the three constants a, // b, and c, as well as the variable x. This is the only public // constructor. public GeneralLE(double a, double b, double c, double x); // Return the numeric value of the equation which is the numeric // quantity that should be on both left and right sides of the equal // sign. public double value(); // Return the current value of x public double getX(); // Return the current value of y public double getY(); // Set the value of x and update other values as appropriate to // preserve the equation. public void setX(double x); // Set the value of y and update other values as appropriate to // preserve the equation. public void setY(double y); // Return a String version of the general form of the equation. The // pretty version's general format should be // // A.AA * x + B.BB * y = C.CC // // A.AA, B.BB, and C.CC are the coefficients for the linear equation // with 2 decimal digits of accuracy. Examples: // // 1.23 * x + 45.68 * y = 2.00 // -54.99 * x + -9.86 * y = 42.41 public String toString(); // Produce a version of this GeneralLE in slope intercept form. The // values of x and y must be preserved but the coefficients should // be converted to slope intercept form. The resulting // SlopeInterceptLE is not connected to the generating GeneralLE in // any way: changes to one do not affect the other. public SlopeInterceptLE toSlopeInterceptLE(); }
4.3 Implementation Notes
As with SlopeInterceptLE
, the toString()
method is made much
easier if you master the String.format()
method to produce formatted
output.
To complete the conversion method toSlopeInterceptLE()
, you will
need to do a little bit of arithmetic to generate the slope and
intercept. Make sure to include a comment explaining the algebra
involved.
4.4 Sample Session
Welcome to DrJava. > GeneralLE g = new GeneralLE(1, 10, 11, 1); > g 1.00 * x + 10.00 * y = 11.00 > g.value() 11.0 > g.getX() 1.0 > g.getY() 1.0 > g.setX(5) > g.getY() 0.6 > g.value() 11.0 > g.setY(5.5) > g.getX() -44.0 > g 1.00 * x + 10.00 * y = 11.00 > g.value() 11.0 > SlopeInterceptLE si = g.toSlopeInterceptLE(); > si y = -0.10 * x + 1.10 > si.getX() -44.0 > g.getX() -44.0 > si.getY() 5.5 > g.getY() 5.5 > si.value() 5.5 > si y = -0.10 * x + 1.10 > g.value() 11.0 > g 1.00 * x + 10.00 * y = 11.00 > g = new GeneralLE(1.999, -10.238, 11.2345, 1); > g.toString() 2.00 * x + -10.24 * y = 11.23
4.5 (10%) GeneralLE
Manual Inspection Criteria grading
- Fields of the class are present, documented, and have an appropriate access modifier to prevent external sources from modifying them
- Methods are short and sweet
- Some documentation for the
toSlopeInterceptLE()
method is provided which explains how the conversion process is accomplished
5 Problem: Proper Integer Queues
Files to submit
-
ProperQueue.java
- Create this file and implement the
ProperQueue
class in it. -
ProperQueueTests.java
- Provides tests of the correctness of the above class.
5.1 A Better Queue than Last Time
We will revisit the notion of a queue that we introduced in our previous project. There will be two significant changes:
- Queues this time will be built as a class with methods called
ProperQueue
instead of just using an array itself as the queue. There will still be an array inside of the objects of this class but it will be better encapsulated to hide details of the implementation. - We are storing
Integer
objects in the queue instead of primitive-typeint
values. This implies thatnull
is a possible value in the array.
5.2 int
versus Integer
The Integer
type is a simple idea: sometimes, we must have an object
instead of a primitive type in order to deal with references;
Integer
is a class that represents individual int
values, while
also giving us a reasonable place to write methods and to provide
constants related to integers. Java has some built-in support for
converting between these "boxed types" and the primitive types they
mimic. We can almost leave it up to Java to implicitly convert between
int
and Integer
when needed, except in times when different
overloaded methods were written for both, as we might see in some of
the unit testing code. (This is why there are some casting expressions
to turn an int
into an Integer
). The last thing to consider about
them is that, as a class type, variables that should refer to an
Integer
might actually store the null
value. This couldn't happen
with the primitive int
type.
5.3 Class Structure of ProperQueue
We are borrowing some of the structure from Java's own Queue
interface and specializing it to a class that only holds Integer
values (it's not time yet for generics), and to make an initial and
permanent fixed size for any particular ProperQueue
object. We want
to add
items to a queue, we want to remove
items and see what was
removed, and we want to check what is the element
at the head of the
queue without actually removing it. But sometimes queues don't have
items when we ask to remove or peek at an element; and since our
queues have an unchangeable capacity, sometimes we can't add another
element. Should the queue just yield null
values, or raise
exceptions? We will provide both versions of behavior for all three of
those actions (just like our source of inspriation, Java's Queue
interface, does). We will also have some simpler functionality that
should be very direct to complete.
5.4 Fields
size
: number of elements currently stored in the queue.private int size
elements
: an array ofInteger
values that stores the elements of our queue, just like last time (squashed towards the front of the array).private Integer[] elements
5.5 Methods
- constructor. Must initialize all instance variables. When
maxCapacity
isn't a positive integer, this creates a queue with zero capacity.public ProperQueue (int maxCapacity)
getSize
: returns how many elements are currently stored in the queue.public int getSize()
getCapacity
: returns the maximum number of elements that can be stored in the queue at once.public int getCapacity()
isFull
: indicates if the queue is currently entirely filled with elements or not.public boolean isFull()
isEmpty
: indicates if the queue currently holds no elements.public boolean isEmpty()
toString
: creates and returns aString
representation of theQueue
by showing each number in the queue, each separated by an individual space character, but without an extra space at the end.public String toString()
add
: attempts to add the elemente
to the end of the queue. throws aRuntimeException
with the message"Queue full"
when the queue is full (and can't accept another item). Returns
true
upon successful addition of the element. Attempting to addnull
to the queue raises aRuntimeException
with the message"Cannot add null"
The method prototype is:
public boolean add (Integer e)
offer
: variation of theadd
method that does not raise an exception when space is unavailable; it would returnfalse
instead under those circumstances.remove
: attempts to remove the front item in the queue and return it. Raises aRuntimeException
with the message"Queue empty"
when no item is available for removing.
public Integer remove()
poll
: variation of theremove
method that does not raise an exception when no element was available for removal. It returnsnull
in that circumstance.public Integer poll()
element
: this method will copy the front item from the queue and return it, but it does not actually remove the item from the queue (it doesn't modify the queue at all). Raises aRuntimeException
with the message"Queue empty"
if the queue is empty.
public Integer element()
peek
: variation of theelement
method that will returnnull
instead of raising an exception when no elements were present in the queue.public Integer peek()
5.6 Implementation Notes
As with the queues of the previous project, the intention is for
ProperQueues
to keep the front element at array index 0 in their
internal array. On removing an element, shift all elements to lower
indices.
Several methods require RuntimeExceptions
to be thrown with specific
messages. Review the syntax to create and raise exceptions for these
situations.
The string representation of queues is slightly different than in the first project: no trailing whitespace is allowed. Observe:
> ProperQueue q = new ProperQueue(4); > q.add(15); > q.offer(25); > q.add(35); > q.toString() "15 25 35"
You will need to structure your toString()
differently from the
previous project to account for this difference.
It may be worthwhile to write an internal helper method which shifts
elements. This method may be utilized in both remove()
and poll()
as both require similar functionality.
5.7 Sample Session
The following interactive session in DrJava demonstrates the core
functionality of the ProperQueue
.
Welcome to DrJava. > ProperQueue q = new ProperQueue(5); > q.toString() "" > q > q.getSize() 0 > q.getCapacity() 5 > q.isEmpty() true > q.isFull() false // add() returns true on a successful addition > boolean result = q.add(20); > result true > q.toString() "20" > q 20 > q.isEmpty() false > q.isFull() false > q.getSize() 1 // element() returns the first element without removing it > q.element() 20 > q 20 // remove() returns the first element and removes it > Integer first = q.remove(); > first 20 > q > q.getSize() 0 // Attempting to remove() from an empty queue raises an exception > first = q.remove(); java.lang.RuntimeException: Queue empty at ProperQueue.remove(ProperQueue.java:140) // Attempting to poll() an empty queue returns null > first = q.poll(); > first null // add() and offer() are identical when the queue has room > q.add(15) true > q.offer(25) true > q.add(35) true > q.offer(45) true > q.add(55) true // q is now full (at capacity) > q.getSize() 5 > q.getCapacity() 5 > q.isFull() true // add() on a full queue raises an exception without altering the queue > q.add(65) java.lang.RuntimeException: Queue full at ProperQueue.add(ProperQueue.java:91) // offer() on a full queue returns false without altering the queue > q.offer(65) false > q 15 25 35 45 55 > q.offer(65) false > q 15 25 35 45 55 // remove() and poll() are identical when the queue has elements > first = q.remove() 15 > q 25 35 45 55 > first = q.poll() 25 > q 35 45 55
5.8 (20%) ProperQueue
Manual Inspection Criteria grading
- Methods should be short and sweet
- Provide a few comments to document sections of your code which shift
elements around in methods such as
poll()
andremove()
- Document fields and describe how they are to used within the class
- For methods that involve special behavior for certain inputs or conditions, ensure that the special cases are clearly identified and handled prior to moving on to the general case.
- As there are quite a few methods associated with this class, make sure to organize the methods within the class.
- Document any and all methods, including helper methods, that are not part of the required public methods.
6 Honors Section: Circular Queues that Expand
Files to submit:
-
CircularQueue.java
- Create this file and implement the
CircularQueue
class in it. -
CircularQueueTests.java
- Provides tests of the correctness of the above class.
6.1 Improvements in Time and Space
A dissatisfying aspect of the ProperQueue
is its need to shift
elements in the internal array every time a removal is performed.
This leads to more computational work being done than is strictly
necessary. Rather than shifting elements, one can add a field to the
queue which indicates the index of the front
element. As elements
are removed, this field front
changes to reflect the location of the
new first element rather than moving all elements around. Similarly,
a rear
field tracks the back end of the queue. As rear
reaches
the end of the queue, if there is space at the beginning of the array
due to removed elements, rear
wraps around. This wrap-around leads
to front
being bigger than rear
in some cases and gives rise to
notion of circularity for a CircularlQueue
. The following diagram
illustrates some of these ideas.
An additional annoyance of our previous queues is their fixed
capacity: when the internal array is full, further add()
and
offer()
requests do not modify the queue. To remedy this situation,
the CircularQueue
will implement expansion. As there is no way make
arrays larger in Java, the simple solution is to allocate a new,
larger array and copy elements over to it. For the CircularQueue
,
this is a good opportunity to straighten elements out so that the
front
is back at the 0th element of the array. A common size change
that leads to reasonable performance is to double the size of the
array used when expansion is required. The above example is continued
below to illustrate expansion.
6.2 Class Structure of CircularQueue
CircularQueue
possesses all of the methods that ProperQueue
does
plus one additional method. The behavior of some methods differs from
ProperQueue
. A summary appears in the implementation notes in the
next section.
// Implements a queue of integers as an object with // methods. Internally ints are stored in an array with empty cells // containing nulls. The queue tracks the number of elements it // contains (size) and expands by allocated arrays twice the size of // current size if a request to add is made when at capacity. // Removing elements does not shift but instead adjusts an internal // index dictating the location of hte front element. Similarly, // adding adjusts an internal index indicating the location of the // rear element. The queue will wrap around to use empty front slots // in the array if they are available leading to its "circular" // nature. public class CircularQueue{ // Create an empty queue with the given maximum capacity. Allocate // an array of the given size but it does not need to be initialized // with any special values. Initialize the queue's size to 0. If // maxCapacity is less than or equal to zero, use an initial // capacity of 1. public CircularQueue(int maxCapacity); // Return the number of elements that have been added to the queue // but not removed. public int getSize(); // Return the maximum number of elements that can be stored in the // queue which corresponds to the length of it its internal array. public int getCapacity(); // Return true if the queue's size is equal to its maxium capacity // and false otherwise. public boolean isFull(); // Return true if zero items are currently in the queue, false // otherwise. public boolean isEmpty(); // Add the element e to the end of the queue. This method should // only throw an exception if e is null. Otherwise it should add the // given element and return true. If the queue is full, allocate a // new array twice as large as the present array, copy elements over // to it and proceed to use the new array henceforth. public boolean add(Integer e); // Identical to add(x) in all respects public boolean offer(Integer e); // If the queue is empty throw a RuntimeException with the message // "Queue empty". Otherwise, remove the front element from the // queue. This method should not shift elements in the internal // array but should instead adjust internals to the position of the // new front element. Slots of the array where elements are removed // should be filled with null. public Integer remove() ; // If the queue is empty, return null. Otherwise behave exactly as // remove() does. public Integer poll () ; // Return the front item in the queue without modifying the // queue. If the queue is empty throw a RuntimeException with the // message "Queue empty" public Integer element(); // Return the front item in the queue without modifying the // queue. If the queue is empty return null. public Integer peek(); // Produce a string representing the queue. This string should not // contain any null elements: only the integers that have been added // in their queue order. Each element should be separated by a // space, with *NO* additional space at the end after the last // element. Sample formats are as follows. // // |-----------------------------------------+----------------| // | Code | q.toString() | // |-----------------------------------------+----------------| // | CircularQueue q = new CircularQueue(4); | "" | // | q.add(4); q.add(7); | "4 7" | // | q.add(9); | "4 7 9" | // | q.remove() | "7 9" | // | q.remove() | "9" | // | q.add(2); | "9 2" | // | q.add(7); | "9 2 7" | // | q.add(3); | "9 2 7 3" | // | q.remove() | "2 7 3" | // | q.add(5); | "2 7 3 5" | // | q.add(8); | "2 7 3 5 8" | // | q.add(11); | "2 7 3 5 8 11" | // | q.remove() | "7 3 5 8 11" | // |-----------------------------------------+----------------| public String toString(); // Produce a string version of the internal array of elements used // by the queue. Methods from the java.util.Arrays class may prove // helpful as the format of the internals string is modelled after // how arrays are stringified there. Sample formats are below. // // |-----------------------------------------+--------------------------------------| // | Code | q.internalsString() | // |-----------------------------------------+--------------------------------------| // | CircularQueue q = new CircularQueue(4); | "[null, null, null, null]" | // | q.add(4); q.add(7); | "[4, 7, null, null]" | // | q.add(9); | "[4, 7, 9, null]" | // | q.remove() | "[null, 7, 9, null]" | // | q.remove() | "[null, null, 9, null]" | // | q.add(2); | "[null, null, 9, 2]" | // | q.add(7); | "[7, null, 9, 2]" | // | q.add(3); | "[7, 3, 9, 2]" | // | q.remove() | "[7, 3, null, 2]" | // | q.add(5); | "[7, 3, 5, 2]" | // | q.add(8); | "[2, 7, 3, 5, 8, null, null, null]" | // | q.add(11); | "[2, 7, 3, 5, 8, 11, null, null]" | // | q.remove() | "[null, 7, 3, 5, 8, 11, null, null]" | // |-----------------------------------------+--------------------------------------| public String internalsString(); }
6.3 Implementation Notes
The two primary goals of CircularQueue
are to
- Avoid shifting elements while efficiently using available array space.
- Expand when the internal array is full and new elements are to be inserted.
Many of the methods associated with CircularQueue
are nearly
identical to ProperQueue
. Below are some major differences that
will require some new code.
Initialization in the Constructor
public CircularQueue(int maxCapacity)
The constructor for CircularQueues
should allocate an array of at
least length 1. If the parameter maxCapacity
is 0 or less, ignore
it and initialize the internal array of elements to be size 1.
It may be necessary to set the front and rear indices to strange
initial values like -1
to get the rest of the methods to work out
right. You will most likely need to track the size
of the queue in
addition to front and rear indices.
Internal Representation
public String internalsString()
This method is meant to produce a "picture" (string version) of the
internal array used by the CircularQueue
. It is not present in
ProperQueue
. The format of these strings is easily produced using
methods from the java.util.Arrays
so that this method can be as
short as a single line. It is mainly used to verify that the internal
layout of the queue is correct.
add() and offer() always succeed
public boolean add(Integer e) public boolean offer(Integer e)
Unlike the ProperQueue
, methods to put elements in a CircularQueue
should always work. Thus add()
and offer()
should behave
identically and always return true. The only reason to raise an
exception is in the event that the parameter e
is null
.
The general approach to expansion when the array is full is to take the following steps.
- Check if queue's array is full by comparing size and capacity
- When full, trigger an expansion
- Expansion should allocate a new array that is twice the size of the old array
- Copy elements from the old array in queue-order into the new larger array
- Adjust internal fields so that the queue now uses the new larger array and has its front and rear indices set appropriately
- After it is certain that the internal array has enough space (not full or expansion has finished) place the new element in the queue adjusting the rear index appropriately.
6.4 Sample Session
The following table gives code to create and manipulate a
CircularQueue
. The table is right top to bottom left to right and
shows what each method call returns and the results of how the queue
would look after the code is executed according to its toString()
method and its internal structure as evidenced by the
internalsString()
method.
|----+---------------------------+--------+----------------+--------------------------------------| | | Code | Return | q.toString() | q.internalsString() | |----+---------------------------+--------+----------------+--------------------------------------| | 0 | CircularQueue q; | | | | | 1 | q = new CircularQueue(4); | | "" | "[null, null, null, null]" | | 2 | q.add(4); q.add(7); | true | "4 7" | "[4, 7, null, null]" | | 3 | q.add(9); | true | "4 7 9" | "[4, 7, 9, null]" | | 4 | q.remove() | 4 | "7 9" | "[null, 7, 9, null]" | | 5 | q.remove() | 7 | "9" | "[null, null, 9, null]" | | 6 | q.add(2); | true | "9 2" | "[null, null, 9, 2]" | | 7 | q.add(7); | true | "9 2 7" | "[7, null, 9, 2]" | | 8 | q.add(3); | true | "9 2 7 3" | "[7, 3, 9, 2]" | | 9 | q.remove() | 9 | "2 7 3" | "[7, 3, null, 2]" | | 10 | q.add(5); | true | "2 7 3 5" | "[7, 3, 5, 2]" | | 11 | q.add(8); | true | "2 7 3 5 8" | "[2, 7, 3, 5, 8, null, null, null]" | | 12 | q.add(11); | true | "2 7 3 5 8 11" | "[2, 7, 3, 5, 8, 11, null, null]" | | 13 | q.remove() | 2 | "7 3 5 8 11" | "[null, 7, 3, 5, 8, 11, null, null]" | |----+---------------------------+--------+----------------+--------------------------------------|
Below is the same example above but written long-form to show each
action followed by toString()
and internalsString()
results.
> CircularQueue q = new CircularQueue(4); > q > q.toString() "" > q.internalsString() "[null, null, null, null]" > q.add(4); q.add(7); > q.toString() "4 7" > q.internalsString() "[4, 7, null, null]" > q.add(9); > q.toString() "4 7 9" > q.internalsString() "[4, 7, 9, null]" > q.remove() 4 > q.toString() "7 9" > q.internalsString() "[null, 7, 9, null]" > q.remove() 7 > q.internalsString() "[null, null, 9, null]" > q.toString() "9" > q.add(2); > q.toString() "9 2" > q.internalsString() "[null, null, 9, 2]" > q.add(7); > q.toString() "9 2 7" > q.internalsString() "[7, null, 9, 2]" > q.add(3); > q.toString() "9 2 7 3" > q.internalsString() "[7, 3, 9, 2]" > q.remove() 9 > q.toString() "2 7 3" > q.internalsString() "[7, 3, null, 2]" > q.add(5); > q.toString() "2 7 3 5" > q.internalsString() "[7, 3, 5, 2]" > q.add(8); > q.toString() "2 7 3 5 8" > q.internalsString() "[2, 7, 3, 5, 8, null, null, null]" > q.add(11); > q.remove() 2 > q.toString() "7 3 5 8 11" > q.internalsString() "[null, 7, 3, 5, 8, 11, null, null]" >
6.5 (5%) (Honors CircularQueue
Test Cases grading
Test cases for the CircularQueue
are provided in
CircularQueueTests.java
.
6.6 (10%) (Honors) CircularQueue
Manual Inspection Criteria grading
- No shifting is done on adding/removing elements from the queue.
- Internal fields are used to track the indices of the front and rear of the queue as well as other necessary features such as size.
- The process to expand the internal space/array associated with the
queue is clearly documented and has clean code to transfer elements
from old to new array. Consider implementing this as a
private
internal method. - Methods that share functionality such as
add()
andoffer()
invoke one another to avoid copying/pasting code. - All fields of the class are clearly named and documented.
7 Other Manual Inspection Criteria
7.1 (5%) Correct Project Setup grading
Correctly setting up the directory structure for each project greatly eases the task of grading lots of projects. Graders get cranky when strange directory structures or missing files are around and you do not want cranky graders. The following will be checked for setup on this project.
- The Setup instructions were followed closely
- The Project Directory is named according to the specification
- There is an Identity Text File present with the required information in it
- Code can be compiled and tests run from the command line
7.2 (5%) Coding Style and Readability grading
Reading code is made much easier if it is styled reasonably well. On this assignment, you will get credit for properly doing the following:
- Indenting and {bracketing} code uniformly throughout the program
- Including comments above each method which describe its purpose and any limitations. Some information can be transcribed from the project specification.
- commenting complex parts of code to describe what is happening in them. Some methods are required to have these, while others may need them if your approach is unusual.
On subsequent assignments, you may be penalized for dirty-looking code and lazy/absent commenting, so get in good habits now while there are rewards for it.
8 Running the Automated Tests
8.1 (50%) Automated Tests grading
We are providing a battery of unit tests in the file P2Tests.java
which test the code. These are examples and may not be the exact
tests used for evaluation so you may want to begin studying how these
tests work and experiment with your own.
8.2 Command Line Invocation of Tests
Graders will mostly run tests on the command line while grading so it is in your own interest to verify that your code passes the tests when run on the command line, as it will let you see what you will get on this portion of the assignment.
To run the tests on the command line, make sure that
junit-cs211.jar
is in the project directory. This file contains th
JUnit
library for running tests, and is part of the code
distribution linked at the top of the project specification).
Systems Discrepancy: Windows uses a semicolon to separate paths, but Unix/Mac OSX uses a colon in the same place (see below). It is easy to overlook the difference! They look nearly the same if you're not looking closely. We will provide both versions here, but pay attention to what machine you're on and use the correct style.
Unix Users (including Mac OS X): To test your code use the following
commands at the terminal. The OS-prompt here is >
. (Don't type those
leading >
's).
# Compile and Run tests for first problem > javac -cp junit-cs211.jar:. SlopeInterceptLETests.java > java -cp junit-cs211.jar:. SlopeInterceptLETests JUnit version 4.12 ..... Time: 0.106 OK (5 tests) ... # Similar compile/run for other classes # Run tests for all problems simultaneously > javac -cp .:junit-cs211.jar *.java > java -cp .:junit-cs211.jar P2Tests JUnit version 4.12 .......................................................................................... Time: 0.017 OK (38 tests)
Windows Users: To test your code use the following commands which
replaces colons with SEMICOLONS. Other examples throughout the
specification will use colons, but you are smart and will remember to
use semicolons in all situations like this classpath situation. Here,
the prompt is shown as >
. (Don't actually type those >
's).
# Compile and Run tests for first problem > javac -cp junit-cs211.jar;. SlopeInterceptLETests.java > java -cp junit-cs211.jar;. SlopeInterceptLETests JUnit version 4.12 ..... Time: 0.106 OK (5 tests)
8.3 Testing with Dr. Java
DrJava can run these tests by opening the various test files and clicking on the Test button. Be sure to successfully compile first. Click on test errors to jump to the test code. Useful! This JUnit testing integration is one of the reasons DrJava is supported in our class.
9 Project Submission
9.1 Provided Files
Download the zip file p2pack.zip which contains necessary files for this assignment. Unzip this file which will create a folder which you should as you project directory as described below.
9.2 Project Directory
Rename the pXpack
directory (folder) according to the project
directory convention: NetID-LabSecNum-pNum
where
- masonID is your GMU Net ID, the first part of your GMU email address.
- labSecNum is your lab section number, such as
201
,202
,2H1
, etc. - pNum represents the project number, such as
p1
.
Examples
msnyde14-2H1-pX
for Mark Snyder in lab section 2H1ckauffm2-205-pX
for Chris Kauffman in lab section 205
All work you do should be saved in your project directory for eventual zipping and submission.
9.3 Identity Text File
Create a text file in your project directory called ID.txt
which
has identifying information in it. A sample ID.txt
looks like this:
Mark Snyder msnyde14 G0071234 Lecture: 002 Lab: 205
It contains a full name, mason ID, G#, lecture section, and lab section in it.
Failure to submit your work in an appropriately named directory and
with the ID.txt
file in it with correct information will result in
the loss of 5%.
9.4 Submission
Create a zip file of your homework directory and submit it to the course Blackboard page. Do not e-mail the professor or TAs your code.
Create a .zip
file of your directory as you will learn in the first
programming lab.
To submit your zip to Blackboard:
- Click on the Projects Link
- Click on Project 2
- Scroll down to "Attach a File"
- Click "Browse My Computer"
- Select your Zip file
You may submit as many times as you like; only the final valid submission will be graded. If you turn in late work within 48 hours, it will consume late tokens. If you turn in late work beyond 48 hours, that particular submission is invalid and will be ignored.
You should always verify that your submission is successful. Go back
to the assignment and download your last submission; is there actually
a file there? Can you unzip that file, and see .java
files in there
as you'd expect? Can you run those files? It turns out you can do
quite a bit to ensure you've properly submitted your work. Don't get a
zero just because of a failure to actually turn in the right files! It
is your responsibility to correctly turn in your work.