Homework
1-week Assignments
5 homework assignments will be assigned during the semester. Note that their due dates are subject to change.
- HW1 - Due: 9/10 11:00PM (Getting Started)
- HW2 - Due: 9/17 11:00PM (Unit Testing Fundamentals)
- HW3 - Due: 9/24 11:00PM (Classes and Enumerated Types)
- HW4 - Due: 10/1 11:00PM (JUnit)
- HW5 - Due: 10/8 11:00PM (Objects and References)
1 - HW5: Rave'n
Homework 5
![Rave’n](RavenLogo.png)
🛑 To Know Before You Start
As discussed below, on this assignment your grade will be reduced by 5 points for each submission after
the 10th submission. Hence, you should be confident that your code is correct before you submit the first time.Learning Objectives
This homework assignment is designed to help you learn about reference
types, references, and the difference between aliases and deep copies. It will also,
because it is a little longer than previous homework assignments,
convince you to start working on assignments early
(which will be necessary for the programming assignments to come). Finally,
it will, hopefully, teach you the importance of testing your code before you
submit it (even though testing is not required).
Overview
As you know, students in the Computer Science Department are famous
for their wild parties. As you also know, they sometimes don’t spend
enough time planning (whether it be for assignments or parties).
As a result, they sometimes work on assignments
at the last second, and sometimes don’t have enough food and drink for
the number of people that attend their parties. The Department Head
has decided that she would like to see fewer failed parties, so has
contracted with you to create a party planning tool named
Rave’n. (She’ll try to tackle the failed assignment problem later.)
The Classes to be Written
You must write three classes named Item
, Order
, and Invoice
(all
of which must be in the deault package) that are summarized on the
following UML class diagram.
![Class Diagram](Design.png)
As shown in this diagram, an Order
consists of an Item
and a
number, and an Invoice
consists of 0 or more Order
objects. For
example, one Item
that is commonly found at CS parties is pizza,
which might have a description
attribute of "Pizza"
, a serves
attribute of 3
people, and a price
attribute of 8.99
. A typical
CS party might have 600 people in attendance, so the planners might
place an Order
for this Item
with a number
attribute of 200
. A
typical CS party might also serve several other things all of which
would be incorporated in an Invoice
.
Detailed Design Specifications
In addition to the specifications contained in the UML class diagram,
your implementation must conform to the following specifications.
The Item
Class
The description
attribute must be an alias of the parameter that is
passed to the explicit value constructor, and the copy constructor
must invoke the explicit value constructor.
The toString()
method must return a String
representation of the
description
, serves
, and price
attributes that is formated using
"%s for %d at $%5.2f"
.
The Order
Class
The explicit value constructor must make a deep copy of the item
parameter, and the copy constuctor must invoke the explicit value
constructor.
The getServes()
method and the getPrice()
method must return the
corresponding values in the item
attribute multiplied by the
number
attribute. For example, suppose an Item
of pizza serves 3
at a cost of $8.99 and the number
in the Order
is 7
. Then the
getServes()
method must return 21
and the getPrice()
method must
return 62.93
. The getDescription()
method must return the corresponding value from the item
attribute.
The toString()
method must return the number
attribute and the
value returned by the item
attributes toString()
method formatted
using "%d orders of %s"
.
The Invoice
Class
The constructor must initialize the orders
attribute.
The addOrder()
method must add an alias of the parameter named
order
to the attribute named orders
.
The getOrder(int)
method must return null
when the value of the
parameter is out of bounds. Otherwise, it must return a reference to
the appropriate element in the orders
attribute.
The getPrice()
method must return the total price of all Order
objects in the orders
attribute. For example, suppose the Invoice
contains $62.93 worth of pizza, $10.72 worth of soda, and $41.64 worth
of chips. Then, this method must return 115.29.
The getServes()
method must return 0 when there are no Order
objects in the orders
attribute. Otherwise, it must return the
minimum value of all of the serves
attributes associated with the
Order
objects in the orders
attribute. For example, suppose the
Invoice
contains enough pizza to serve 21, enough soda to serve 20,
and enough chips to serve 24. Then, this method must return 20
.
The size()
method must return the number of elements in the orders
attribute.
Testing
You may test your code in either or both of the following two
ways. How you test your code is up to you. But, you should be aware of
the fact that Gradescope will not provide much help.
Unit Testing Using JUnit
You can test your code using JUnit. (You should not use the Test
class from the earlier assignments any longer, especially since you
will be required to use JUnit in the future.)
System Testing Using a Graphical User Interface
You can test the entire system using a graphical user interface (GUI)
that was written by the Department. It is available as a .jar
file.
🫙hw5.jar
Help incoroprating it into your project is available on the
CS Wiki .
To use it you will need to create (and execute) the following main class.
import java.lang.reflect.InvocationTargetException;
import javax.swing.SwingUtilities;
/**
* This is the main class for Rave'n.
*
* @author Computer Science Department, James Madison University
* @version 1
*/
public class Raven {
/**
* The entry point of the application.
*
* @param args The command-line arguments (which are not used).
* @throws InterruptedException
* @throws InvocationTargetException
*/
public static void main(String[] args)
throws InterruptedException, InvocationTargetException {
RavenWindow window;
window = new RavenWindow();
SwingUtilities.invokeAndWait(window);
}
}
The RavenWindow
object that is constructed in the main()
method
will make use of your Item
, Order
, and Invoice
classes.
Submission
You must submit (using Gradescope):
- Your implementation of the
Item
, Order
, and Invoice
classes.
Do not submit any unit tests.
Your grade will be reduced by 5 points for each submission after
the 10th submission. So, you should try to ensure that your code is correct
before you submit it the first time.
Grading
Your code will first be graded by Gradescope and then by the
Professor. The grade you receive from Gradescope is the maximum grade
that you can receive on the assignment
Gradescope Grading
Your code must compile (in Gradescope, this will be indicated in the
section on “Does your code compile?”) and all class names and method
signatures must comply with the specifications (in Gradescope, this
will be indicated in the section on “Do your class names, method
signatures, etc. comply with the specifications?”) for you to receive
any points on this assignment. Gradescope will then grade your
submission as follows:
Criterion | Points | Details |
---|
Conformance to the Style Guide | 0 points | (Success Required) |
Correctness | 100 points | (Partial Credit Possible) |
As discussed above, your grade will be reduced by 5 points for each submission after
the 10th submission. Gradescope will provide you with hints, but may not completely
identify the defects in your submission.
Manual Grading
After the due date, the Professor may manually review your code. At
this time, points may be deducted for inelegant code, inappropriate
variable names, bad comments, etc.
Recommended Process
Since nobody will be looking over your shoulder, you can use any
process that you would like to use. However, it is strongly
recommended that you use the process described here.
Get Started
- Read and understand the entire assignment.
- Create a project for this assignment named
hw5
. (Remember, do not create a module and create separate folders for source and class files). - Activate Checkstyle for this assignment.
Stub-Out the Classes
- Stub-out the
Item
class. - Stub-out the
Order
class. - Stub-out the
Invoice
class. - Add the “javadoc” comments to the three classes class.
- Check the style of the three classes and make any necessary corrections.
Implement and Test (if Desired) the Classes
- Implement and test everything in the
Item
class except the copy constructor. - Implement and test the copy constructor in the
Item
class. - Implement and test the explicit value contstructor and simple getters in the
Order
class. - Implement and test the
toString()
method in the Order
class. - Implement and gest the
getServes()
method in the Order
class. - Implement and gest the
getPrice()
method in the Order
class. - Implement and test the copy constructor in the
Order
class. - Implement and test the constructor,
addOrder()
, getOrder()
, and size()
methods in the Invoice
class. - Implement and test the
getPrice()
method in the Invoice
class. - Implement and test the
getServes()
method in the Invoice
class.
Conduct System Tests (if Desired)
- Download
hw5.jar
to a directory outside of your Eclipse workspace (e.g., the downloads
directory for this course). - Add
hw5.jar
to the project (using the steps described on the CS Department’s wiki)[https://wiki.cs.jmu.edu/student/eclipse/help#using_third-party_classjar_files]. - Execute the
Raven
class. - Add a few orders.
- Ensure that the information displayed is correct.
- Change the number of items in one order.
- Ensure that the information displayed is correct.
- Change the number of items in another order.
- Ensure that the information displayed is correct.
The following screenshot shows an example of how the GUI might be used.
![Screenshot](Screenshot.png)
In this example, the pizza serves 3 and costs $8.99, the bottle of
soda serves 5 and costs $2.68, and the bag of chips serves 8 and costs
$13.88.
Requesting Help About Failed Official Tests
When requesting help about failed official tests, whether from a learning assistant or a Professor,
you must present the tests that you have run that you believe address the issue identified in
the failed test. For example, if Gradescope indicates that your getServes()
method in the Invoice
class failed a test, you must provide the unit tests or system tests that you wrote to verify
the correctness of that method. Of course, you must not post your tests on Piazza.
Questions to Think About
You don’t have to submit your answers to these questions, but you
should try to answer them because they will help you determine whether
or not you understand some of the important concepts covered in this
assignment.
- What does the word “deep” really mean when used in the context of a “deep copy”? Can there be different levels of depth?
- Why is it sometimes appropriate to use an alias and sometimes appropriate to use a deep copy?
- Why did we not require you to submit unit tests for this assignment even though we think that they are necessary?
2 - HW4: Cypherdelic
Homework 4
![Cypherdelic](Cypherdelic.png)
🛑 To Know Before You Start
As discussed below, on this assignment you may submit to Gradescope at most ten times.
Hence, you should be confident that your code is correct before you submit the first time.Learning Objectives
This homework assignment is designed to help you understand unit
testing and debugging. This includes an understanding of
black-box/closed-box testing, white-box/open-box testing (and the
JUnit framework), test coverage (and the EclEmma/JaCoCo framework),
the debugging process, and instrumentation techniques.
Overview
The (fictitious) company Cypherdelic has written a PhraseCypher
class that can be used to encrypt and decrypt messages using a secret
key phrase. They have also written a suite of white box tests that
covers all statements and branches in this class. They have come to
you to do additional testing to debug the PhraseCypher
class if
necessary. (Hint: It will be necessary to debug the PhraseCypher
class. In other words, it does contain defects.)
Existing Classes
They have provided you with an implementation of the PhraseCypher
class and a white box test suite (written in Java using the JUnit
framework) that covers all statements and branches in the
PhraseCypher
class.
📄PhraseCypher.java
📄WhiteBoxTests.java
Some of the specifications for the PhraseCypher
class are
illustrated in the following UML class diagram:
![Class Diagram](Design.png)
The remaining specifications are included in the comments for the class.
Your Tasks
You must test and debug the PhraseCypher
class that you have been
given. The end result must be a correct version of the PhraseCypher
class with every change you make documented in the
comments. Specifically, you must:
- Create a class named
HeuristicTests.java
that contains JUnit tests based on “rules of thumb” about the inputs for all of the methods in the PhraseCypher
class. - Create a class named
RandomTests.java
that contains JUnit tests based on random inputs for all of the methods in the PhraseCypher
class.⚠️ Note: posted 9/29@12:40PM
The use of the word “random” here is a bit of a misnomer (it was intentional to try to make of use of more colloquial language in an attempt to make it easier to comprehend the spec). The inputs to the methods in the
PhraseCypher
class are not random. Rather, you should come up (just
arbitrarily see definition
1b
, and notice the use of “random” in definition
1a
) with some examples that aren’t already covered by the white-box tests or the heuristic tests. If you are on your way down some kind of rabbit hole that has to do with “randomg number generators or the like, 🛑 stop! Make a u-turn ↪️ 😆.
Both classes must have at least four methods. These methods
must be preceded by the JUnit @Test
annotation and must have names
that begin with each of the following:
charOfTest
valueOfTest
decryptTest
encryptTest
(They can have suffixes like charOfTest1()
,
charOfTest2()
, etc. if you would like to have more than four in
total). You should add these methods one at a time, running all of the
tests on your machine each time you do so. Obviously, you should
not submit to Gradescope until you are confident that HeuristicTests.java
and
RandomTests.java
are correct.
When the actual output of one of your tests does not equal the
expected output you should understand the symptom and the trigger
condition (i.e., stabilize the fault). Then, localize the fault,
correct the fault (documenting the correction in the source code), and
verify the correction.
Some Likely Rules of Thumb
There are a variety of rules of thumb that people use when testing code.
The Explicit Value Constructor
The explicit value constructor must be passed a String
that contains
all of the letters in ALPHABET
. Some obvious parameters to pass
include:
- A
String
that is missing one letter - A
String
that is identical to ALPHABET
- A
String
that is identical to ALPHABET
with the characters in reverse - A
String
that is missing the first letter (i.e., the ' '
character) - A
String
that is missing the last letter in lower-case (i.e., the 'z'
character) - A
String
that is missing the last letter in upper case (i.e., the 'Z'
character) - A
String
that contains no letters
You should be able to think of other rules-of-thumb that might be
likely to uncover defects in a method that is passed a String
.
The charOf()
Method
The charOf()
method is passed an int
that is supposed to
correspond to a char
in ALPHABET
. Some obvious parameters to pass
include:
- 0
- 1
- The length of
ALPHABET
- One less than the length of
ALPHABET
- A negative number
- A large number
You should be able to think of other rules-of-thumb that might be
likely to uncover defects in a method that is passed an int
.
The valueOf()
Method
The valueOf()
method is passed a char
that is in ALPHABET
. Some
obvious parameters to pass include:
- The 0th
char
in ALPHABET
- The 1st
char
in ALPHABET
- The next to last
char
in ALPHABET
- The last
char
in ALPHABET
- A
char
not in ALPHABET
You should be able to think of other rules-of-thumb that might be
likely to uncover defects in a method that is passed a char
.
The encrypt()
Method
The encrypt()
method is passed a String
that contains some or all
of the characters in ALPHABET
. Some obvious parameters to pass
include:
- A
String
that contains all of the letters in ALPHABET
- A
String
that is identical to ALPHABET
- A
String
that is identical to ALPHABET
with the characters in reverse - An upper-case
String
- A lower-case
String
- A mixed-case
String
- A short
String
- A long
String
that contains some letters more than once - A
String
that contains a char
that isn’t in ALPHABET
- A
String
that contains multiple char
s that aren’t in ALPHABET
You should be able to think of other rules-of-thumb that might be
likely to uncover defects in a method that is passed a String
.
The decrypt()
Method
The decrypt()
method is passed an int[]
that contains the indexes
of some or all of the characters in ALPHABET
. Some obvious
parameters to pass include:
- An array with 1 element
- A long array
- An array in which all of the elements are the same
- An array sorted in ascending order
- An array sorted in descending order
- An array containing zeroes
You should be able to think of other rules-of-thumb that might be
likely to uncover defects in a method that is passed an int[]
.
Before Submission
Before you submit your code to Gradescope for the first time you should be able
to check-off each of the following items.
☐ PhraseCypher.java
has no style defects
☐ The PhraseCypher
constructor throws an IllegalArgumentException
as specified
☐ The decrypt()
method returns the empty String
as specified
☐ The encrypt()
method returns an array of length 0 as specified
☐ HeuristicTests.java
has a charOfTest()
method
☐ HeuristicTests.java
has a valueOfTest()
method
☐ HeuristicTests.java
has a decryptTest()
method
☐ HeuristicTests.java
has an encryptTest()
method
☐ RandomTests.java
has a charOfTest()
method
☐ RandomTests.java
has a valueOfTest()
method
☐ RandomTests.java
has a decryptTest()
method
☐ RandomTests.java
has an encryptTest()
method
Note that if your submission does not include all of the required tests it will fail the Official Tests
(not the Self Tests), and you will not receive any hints that indicate this. Hence, it is very important that you manually ensure that your submission is correct.
Submission
You must submit (using Gradescope):
- Your corrected implementation of the
PhraseCypher
class (with appropriate comments). - Your
RandomTests.java
and HeuristicTests.java
.
Because you should not be using Gradescope to verify your code (i.e.,
because you must be able to test and debug code without the help of a
submission system), you may submit to Gradescope at most ten times
and you will not receive any hints about the official tests from Gradescope.
Note that your test classes do not need to comply with the style guide.
Grading
Your code will first be graded by Gradescope and then by the
Professor. The grade you receive from Gradescope is the maximum grade
that you can receive on the assignment
Gradescope Grading
Your code must compile (in Gradescope, this will be indicated in the
section on “Does your code compile?”) and all class names and method
signatures must comply with the specifications (in Gradescope, this
will be indicated in the section on “Do your class names, method
signatures, etc. comply with the specifications?”) for you to receive
any points on this assignment. Gradescope will then grade your
submission as follows:
Criterion | Points | Details |
---|
Conformance to the Style Guide (Style) | 0 points | (All or Nothing; Success Required) |
Passing Your Tests (SelfTests) | 20 points | (All or Nothing; Success Required) |
Correctness (Official Tests) | 80 points | (Partial Credit Possible) |
As discussed above, you may submit to Gradescope at most ten times.
The grade on your last allowed submission will be the grade you receive from
Gradescope.
If your submission does not contain all of the required tests, you will receive
a 0 for correctness.
Manual Grading
After the due date, the Professor may manually review your code. At
this time, points may be deducted for inelegant code, inappropriate
variable names, bad comments, etc.
Questions to Think About
You don’t have to submit your answers to these questions, but you
should try to answer them because they will help you determine whether
or not you understand some of the important concepts covered in this
assignment.
- The assignment does not require that your tests completely cover the code. Why not?
- The white-box tests completely covered the code. How could the code still contain defects?
- Why are both heuristic tests (based on rules of thumb) and random tests necessary (in addition to white-box tests)?
- As you know, applications written in Java must have a main class that contains a method with the signature
public static void main(String[])
that is called the entry point of the application. When you write JUnit tests, you do not need to create such a class. What must the JUnit framework be providing behind the scenes? With this in mind, why does Eclipse differentiate between Run Configurations
for Java applications and JUnit tests? - How does your answer to the previous question make it a little more convenient to use JUnit than the
Test
class you have used on previous assignments? - JUnit contains
assertEquals()
methods that are passed two int
values, two double
values, two String
values, etc. What term is used to describe methods that have the same name but different formal parameters? - When a JUnit test fails, an exception is thrown. What happens if the code you are testing throws an exception for other reasons?
Vocabulary
- black-box testing
- Testing that is based on the specification of the code being tested (without insight into the actual implementation).
- white-box testing
- Testing that is based on the implementation of the code being tested, i.e. the test author has access to the source code under test.
- heuristic
- Describing something that is an acceptable approximation, compromising some completeness or perfection for practicality. Often heuristics are informed from (past) empirical observations. ([more on wikipedia](https://en.wikipedia.org/wiki/Heuristic))
- rule of thumb
- Guideline, informed by past experience. Anachronistically associated with jurisdictional tolerance of domestic violence. ([more on wikipedia](https://en.wikipedia.org/wiki/Rule_of_thumb#Folk_etymology))
- random test
- A test with inputs that were chosen at random by the tester (along with the associated expected output)
3 - HW3: Barbed Wire Fencing
Homework 3
![Barbed Wire Fencing](BarbedWireFencing.png)
Learning Objectives
This homework assignment is designed to help you understand the differences
between enumerated types and classes. It will also start you on the path to becoming a better unit tester.
Overview
Several former members of the JMU Fencing Club are upset with the
United States Fencing Association (USFA) and would like to start an
alternative named Barbed Wire Fencing. Thus far they have been quite
successful in getting people to support their cause (in part because
of their tough-sounding name). However, they know that they must offer
all of the services that are provided by the USFA. So, they have come to
you to start writing some of the software they need.
Specifically, they want you to write a Bout
class that encapsulates
a bout between two fencers, a FencingEvent
enum that the Bout
class uses, and a BladePart
and BodyPart
enum that are used by the
FencingEvent
enum. They have provided you with some classes that
you can use to test these classes and enums.
Existing Classes
They have provided you with a modified version of the Test
class
(based on the Test
class that you wrote for a previous assignment)
that uses overridden forEquals()
methods and reports on the number
of failed tests.
📄Test.java
They have also provided a FencingEventTest
class (that uses the
modified Test
class) that you can use to test the enums.
📄FencingEventTest.java
Note that the testIsScoringTouch()
method in the FencingEventTest
class uses nested loops to test all combinations of BodyPart
objects
and BladePart
objects.
They have also provided a MeleeDriver
class that you can use to test
the entire system using a hypothetical three-person tournament called
a melee.
📄MeleeDriver.java
It does not use the Test
class and does not include the expected
results. Hence, you will have to perform some calculations by hand
before you can use it (i.e., it will report the actual results and you
will have to determine if they are correct).
Finally, they have provided a WhiteBoxTests
class (that uses the
Test
class) that you will use when answering the “Questions to Think
About”.
📄WhiteBoxTests.java
This class contains unit tests that completely cover all of the enums
and classes that you must write, but is not sufficient for verifying
the correctness of your code. In other words, your code could
contain defects and still pass all of these tests.
The Classes to be Written
You must write three enumerated types, two that are simple and have no
attributes or methods, and one that is more complicated. You also must
write one “normal” class. The relationships between these different
components are illustrated in the following UML class diagram.
![Class Diagram](Design.png)
Your implementation must conform to the specifications in this diagram
as well as the specifications listed below.
The BladePart
Enum
Fencing blades have multiple different parts. The two that are relevant for fencing events are the edge and the tip.
The BodyPart
Enum
As you (hopefully) already know, the human body has many different parts. The parts that are relevant for fencing are the head, arms, hands, torso, crotch, and legs.
The FencingEvent
Enum
There are three different fencing events (named for the weapon that is
used in each): foil, epee, and sabre. In addition to the weapon
used during the event, the different events have different attributes,
including: the maximum weight of the weapon, the parts of the blade
that can be used to score a point, and the parts of the body that can
be used to score a point. The attributes in the FencingEvent
enum
are used to keep track of these differences.
The Attributes
In foil events, the maximum weight of the weapon is 500 grams, only
the tip of the blade can be used to score a point (hence the
BladePart[]
attribute named bladeParts
will contain one element),
and points can only be scored on the torso and crotch (hence the
BodyPart[]
attribute named targets
will contain two elements).
In epee events, the maximum weight of the weapon is 775 grams, only
the tip of the blade can be used to score a point (hence the
bladeParts
attribute will contain one element), and points can be scored on
any part of the body (hence the targets
attribute will contain six
elements).
In sabre events, the maximum wight of the weapon is 500 grams, both
the tip and edge of the blade can be used to score points (hence the
bladeParts
attribute will contain two elements), and points can only
be scored on the head, arms, and torso (hence the targets
attribute
will contain three elements)
The Explicit Value Constructor
The explicit value constructor in the FencingEvent
enum has
parameters that can be used to initialize these attributes. The
maximumWeight
parameter obviously contains the maximum weight of the
weapon. The edgeOK
parameter will contain true
if the edge can be
used to score a point (and, hence, the bladeParts
attribute will
need to contain two elements) and will contain false
if only the tip
can be used to score points (and, hence, the bladeParts
attribute
will need to contain one element). The targets
parameter is variable
length (as indicated by the ...
after the type, these are also called
varargs )
and will hold the (appropriately sized) array of BodyPart
objects that can be
scored on.
When invoking this constructor, the actual parameters must include an
int
and a boolean
and may contain 0 or more BodyPart
objects
(separated by commas). Internal to this constructor, the formal
parameter named targets
will be a BodyPart[]
that will contain 0
or more elements (corresponding to the BodyPart
objects in the
actual parameters). For example, this constructor might be invoked in
the FencingEvent
enum as follows:
FOIL(500, false, BodyPart.TORSO, BodyPart.CROTCH)
and might be partially implemented as follows:
private FencingEvent(int maximumWeight, boolean edgeOK, BodyPart... targets) {
this.maximumWeight = maximumWeight;
this.targets = targets;
}
where targets[0]
will be BodyPart.TORSO
and targets[1]
will be BodyPart.CROTCH
.
The Methods
The getMaximumWeight()
method must return the maximum weight for the
weapon used in the FencingEvent
.
The isOnTarget()
method must return true
when the BodyPart
of
interest can be scored on in this FencingEvent
and must return
false
otherwise.
The isLegalBladerPart()
method must return true
when the
BladePart
of interest can be used to score a point in this
FencingEvent
and must return false
otherwise.
The isScoringTouch()
method must return true
when a contact of the
given BladePart
on the given BodyPart
scores a point, and and must
return false
otherwise. This method must not duplicate code in any
of the other methods in the enum
. (It can, of course, invoke other
methods in the enum
.)
The Bout
Class
The explicit value constructor in the Bout
class must initialize all of the attributes in the class in the obvious way, and the accessors in the Bout
class must return the associated attributes.
The increaseRightScore()
and increasLeftScore()
methods must increase the value of the associated attributes by 1.
The toString()
method must return a String
representation of the fencerLeft
, scoreLeft
, fencerRight
, and scoreRight
attributes formatted using "%s %d, %s %d"
as the format String
.
Submission
You must submit (using Gradescope):
- Your implementation of the
Bout
class, the BladePart
enum, the BodyPart
enum, and the FencingEvent
enum. Do not include the Test
class or any of the drivers.
There is no limit on the number of submissions and no penalty for excessive submissions. Note that your submission will not be graded if it does not comply with the specifications. So, your submission should include a stubbed-out version of all of the classes/enums. (This will allow you to get credit for the classes/enums/methods that you do implement correctly.)
Grading
Your code will first be graded by Gradescope and then by the Professor. The grade you receive from Gradescope is the maximum grade that you can receive on the assignment
Gradescope Grading
Your code must compile (in Gradescope, this will be indicated in the section on “Does your code compile?”) and all class names and method signatures must comply with the specifications (in Gradescope, this will be indicated in the section on “Do your class names, method signatures, etc. comply with the specifications?”) for you to receive any points on this assignment. Gradescope will then grade your submission as follows:
Criterion | Points | Details |
---|
Conformance to the Style Guide | 20 points | (All or Nothing; Success Required) |
Correctness | 80 points | (Partial Credit Possible) |
Gradescope will provide you with hints, but may not completely identify the defects in your submission.
Note that some criteria are described as being “Success Required”. This means that Gradescope will not assess subsequent criteria unless these criteria are satisfied (and you will receive a grade of 0 for the subsequent criteria). So, for example, if your code does not conform to the style guide then it will not be assessed using any subsequent criteria and you will receive a grade of at most 20 for the assignment.
Manual Grading
After the due date, the Professor may manually review your code. At this time, points may be deducted for inelegant code, inappropriate variable names, bad comments, etc.
Recommended Process
Since nobody will be looking over your shoulder, you can use any process that you would like to use. However, it is strongly recommended that you use the process described here.
Get Started
- Read and understand the entire assignment.
- Create a project for this assignment named
hw3
. (Remember, do not create a module and create separate folders for source and class files). - Activate Checkstyle for this assignment.
- Download
Test.java
, FencingEventTest.java
, MeleeDriver.java
, and WhiteBoxTests.java
to a directory outside of your Eclipse workspace (e.g., the downloads
directory for this course).
Understand the Test Cases
- Read and understand the test cases in
FencingEventTest.java
. - By hand (i.e., using pencil and paper), calculate the expected output from
MeleeDriver.java
.
Write the Simple enums
- Write
BladePart.java
. - Write
BodyPart.java
.
Stub-Out the Remaining Components
- Create a stub for the
FencingEvent
enum that includes all of the attributes and methods with “javadoc” comments. - Create a stub for the
Bout
class that includes all of the attributes and methods with “javadoc” comments.
Add the Provided Classes to the Project
- Copy
Test.java
into hw3
. - Copy
FencingEventTest.java
into hw3
. - Copy
MeleeDriver.java
into hw3
. - Copy
WhiteBoxTests.java
into hw3
.
Write the Remaining enum and Class
- Write and test
FencingEvent.java
one method at a time. (You can do this using the FencingEventTest
class by commenting out the invocations of the methods that you don’t want to test.) - Write and test
Bout.java
one method at a time. (You will need to write your own tests for this. This will not be a difficult task if you use the Test
class.) - Test the entire system using
MeleeDriver.java
and debug if necessary.
Questions to Think About
You don’t have to submit your answers to these questions, but you should try to answer them because they will help you determine whether or not you understand some of the important concepts covered in this assignment.
Questions About Enumerated Types
- What syntax error is generated in
FencingEvent
if you type a BodyPart
incorrectly? - If you used
String
literals instead of an enum, what syntax error would be generated if you type one of them incorrectly? - Taking your answers to the previous two questions into consideration, what is one of the big advantages of using an enum rather than a collection of
String
literals? - How would you invoke the
isScoringTouch()
method for FencingEvent.EPEE
(for example)? - Could you invoke the
isScoringTouch()
method on the String
literal "EPEE"
if, for example, you had used String
literals instead of an enum? - Taking your answers to the previous two questions into consideration, what is another big advantage of using an enum rather than a collection of
String
literals?
Questions About Test Coverage
- “Launch WhiteBoxTests” using the coverage tool (i.e., click on the
WhiteBoxTests.java
tab to make it active and then click on
to launch the tests using the coverage tool). Does your code pass all of the tests? (It should if you have gotten to this part of the assignment!) - Click on the tab for
FencingEvent.java
. Are all of the statements and branches covered (i.e., is everything highlighted in green)? (They should be if you’ve gotten to this part of the assignment!) - Comment-out the first of the tests in the
WhiteBoxTests
class that checks the isScoringTouch()
method and “Launch WhiteBoxTests” using the coverage tool. What is now true of the branch coverage of the isScoringTouch()
method? Why? - What is now true of the coverage of the
isLegalBladePart()
method? Why? - Why is the
isOnTarget()
method still completely covered?
Before you proceed, undo any changes you made.
Questions About Unit Testing
- In the
FencingEvent
enum, temporarily change the maximum weight of the EPEE
to 785
rather than 775
, and “Launch WhiteBoxTests” using the coverage tool. Despite the fact that the FencingEvent
enum now contains defects, does it pass all of the tests? Is the FencingEvent
enum completely covered? - Is it enough to just cover code when writing unit tests?
- Temporarily, change the
increaseLeftScore()
method in the Bout
class so that it increases the scoreLeft
attribute by 5 rather than 1, and “Launch WhiteBoxTests” using the coverage tool. Despite the fact that the Bout
class now contains defects, does it pass all of the tests? Is the Bout
class completely covered? - Does the
WhiteBoxTests
class test the increaseLeftScore()
and increaseRightScore()
methods or does it just execute them? Does the coverage tool indicate that statements/branches have been tested, or just that they’ve been executed? - What are the implications of your answer to the previous questions? In other words, what must you be sure to do when you are required to write and submit unit tests for future assignments?
- Which testing process was easier to use, the one that used the
Test
class (i.e., WhiteBoxTests.java
and FencingEvent.java
) or the one that didn’t (i.e., MeleeDriver.java
)? Why? - You were given extensive tests for the
FencingEvent
enum. As a result, your FencingEnum
enum should have been correct before you submitted your code. If you become a professional programmer, there will not be a submission system for you to rely on. Instead, what must you do to ensure that your code is correct? With that in mind, what must you now start doing this semester?
Before you proceed, undo any changes you made.
4 - HW2: Duke-n-Donuts v2
Homework 2
![Duke-n-Donuts](Duke-n-Donuts_v2.png)
Learning Objectives
This homework assignment is designed to help you learn several things. First, it will help you learn about the difference between static and non-static members. Second, it will help you learn about unit testing. Third, it will help you learn about how to compare variables and how/why the type of the variables being compared matters.
Overview
The former JMU students that opened Duke-n-Donuts have decided to sell other products (e.g., cookies, cupcakes) and this has made them realize that their original design for the pricing system was bad. In particular, they realize that if they were to continue with the current design they would need to have a utility class for each product (e.g., a DonutPricer
, a CookiePricer
, a CupcakePricer
, etc.), and that each of these classes would be very similar (and, hence, contain duplicate code). So, they have changed the design so that they can have an object for each product rather than a utility class for each product.
For example, with the old design, if Duke-n-Donuts sold donuts and cookies they would need two almost identical utility classes and would use them as follows:
double total;
total = DonutPricer.priceFor(6) + CookiePricer.priceFor(50);
With the new design they will need only one class and will use it as follows:
double total;
Pricer donuts, cookies;
donuts = new Pricer(12, 9.99, 0.99);
cookies = new Pricer(36, 17.99, 0.75);
total = donuts.priceFor(6) + cookies.priceFor(50);
The Classes to be Written
You must write a “normal” class named Pricer
and a utility class named Test
. The Pricer
class is specific to stores like Duke-n-Donuts. The Test
class can be used to test classes that are written for many different kinds of products.
The Pricer
Class
A Pricer
object can be used to price any item that can be sold individually or in boxes.
The UML Class Diagram
The following UML class diagram provides an overview of the attributes and methods in this class (which must be in the default package).
![Class Diagram](Pricer.png)
Notice that there are several important differences between this “normal” class and the utility class from the previous assignment.
- All of the attributes are now non-static and, so, belong to individual objects in the class rather than the class itself.
- The attributes are now initialized in an explicit value constructor.
- The methods are now non-static and, so, make use of the non-static attributes (that have different values for each object in the class).
Detailed Design Specifications
- The constructor must initialize the attributes of the object.
- The other methods must conform to the specifications for the DonutPricer class, but must work for anything that can be sold in boxes or individually (not just donuts).
Note that the official tests for the DonutPricer
class did not necessarily test that your submission satisfied all of the specifications. So, you may think your code was correct when it wasn’t. Make sure you read all of the specifications for this assignment.
The Test
Class
The Test
class is a utility class that can be used to simplify the process of testing other classes. Such a system is sometimes referred to as a test harness or a testing framework. This class must conform to the course style guide (because it is not a test, it is a test harness.)
The UML Class Diagram
The following UML class diagram provides an overview of this class (which must be in the default package).
![Class Diagram](Test.png)
Detailed Design Specifications
In addition to the specifications contained in the UML class diagram, this class must conform to the following specifications.
forEqualDoubles()
must check to determine if the attributes expected
and actual
differ by more than the tolerance
.- If so, it must return
false
and print the values of description
, expected
, and actual
(in that order) using the format String
"%s Expected: %f, Actual: %f\n"
. - If not, it must return
true
(and not print anything).
forEqualInts()
must check to determine if the attributes expected
and actual
differ.- If so, it must return
false
and print the values of description
, expected
, and actual
(in that order) using the format String
"%s Expected: %d, Actual: %d\n"
. - If not, it must return
true
(and not print anything).
forEqualStrings()
must check to determine if the attributes expected
and actual
differ.- If so, it must return
false
and print the values of description
, expected
, and actual
(in that order) using the format String
"%s Expected: %s, Actual: %s\n"
. - If not, it must return
true
(and not print anything).
forFalse()
must check to determine if the attribute named actual
is false
- If so, it must return
true
(and not print anything). - If not, it must return
false
and print the description
using the format String
"%s Expected: false, Actual: true\n"
.
forTrue()
must check to determine if the attribute named actual
is true
- If so, it must return
true
(and not print anything). - If not, it must return
false
and print the description
using the format String
"%s Expected: true, Actual: false\n"
.
For example, one might implement the forEqualInts()
method as follows:
/**
* Display an alert if the actual int value is not equal to the
* expected value.
*
* @param expected The expected value
* @param actual The actual value
* @param description A description of the test
* @return true if the two are equal; false otherwise
*/
public static boolean forEqualInts(int expected, int actual,
String description) {
if (expected != actual) {
System.out.printf("%s Expected: %d, Actual: %d\n",
description, expected, actual);
return false;
} else {
return true;
}
}
An Existing Class
A main class (i.e., a class with a main()
method) that you can use to test the Pricer
class has already been written. It is named PricerTest
and the source code (i.e., the .java
file) is available at:
📄 PricerTest.java
Unlike the DonutPricerTest
class from the previous assignment, this class makes use of the Test
class that you have to write. So, you will not be able to test your Pricer
class until you write the Test
class.
Like the DonutPricerTest
class, this class does not conform to the style guide. As mentioned before, most organizations (including most faculty in the Computer Science Department at JMU) do not require that tests conform to the style guide.
Submission
You must submit (using Gradescope):
- Your implementation of the
Pricer
class and your implementation of the Test
class. Do not include the PricerTest
class.
There is no limit on the number of submissions and no penalty for excessive submissions. Note that your submission will not be graded if it does not comply with the specifications. So, your submission should include a stubbed-out version of all of the classes. (This will allow you to get credit for the classes/methods that you do implement correctly.)
Grading
Your code will first be graded by Gradescope and then by the Professor. The grade you receive from Gradescope is the maximum grade that you can receive on the assignment
Gradescope Grading
Your code must compile (in Gradescope, this will be indicated in the section on “Does your code compile?”) and all class names and method signatures must comply with the specifications (in Gradescope, this will be indicated in the section on “Do your class names, method signatures, etc. comply with the specifications?”) for you to receive any points on this assignment. Gradescope will then grade your submission as follows:
Criterion | Points | Details |
---|
Conformance to the Style Guide | 20 points | (Partial Credit Possible) |
Correctness | 80 points | (Partial Credit Possible) |
Gradescope will provide you with hints, but may not completely identify the defects in your submission.
Manual Grading
After the due date, the Professor may manually review your code. At this time, points may be deducted for inelegant code, inappropriate variable names, bad comments, etc.
Recommended Process
Since nobody will be looking over your shoulder, you can use any process that you would like to use. However, it is strongly recommended that you use the process described here.
Get Started
- Read and understand the entire assignment.
- Create a project for this assignment named
hw2
. (Remember, do not create a module and create separate folders for source and class files). - Activate Checkstyle for this assignment.
- Download
PricerTest.java
to a directory outside of your Eclipse workspace (e.g., the downloads
directory for this course).
Understand the Test Cases
- Read and understand the test cases in
PricerTest.java
. - By hand (i.e., using pencil and paper), calculate the expected answer for each of the test cases in
PricerTest.java
.
Copy and Rename DonutPricer.java
- Copy
DonutPricer.java
from he project named hw1
to the project named hw2
. - In Eclipse, rename
DonutPricer.java
to Pricer.java
. (Hint: Right-click on the file name, pull down to [Refactor], and then across to [Rename…].)
Make Pricer.java
a “Normal” Class
- Delete the initialization of all of the attributes (and save the file).
- Understand why this generated several syntax errors.
- Remove the
final
modifier from all of the attributes (and save the file). - Understand why this resolved the syntax errors.
- Make all of the attributes non-static (i.e., remove the
static
modifiers). - Understand why this generated several style errors.
- Understand why this also generated several syntax errors in the methods that follow.
- Rename the attributes (and save the file). (Hint: Highlight the attribute identifier, right-click on the highlighted identifier, pull down to [Refactor], and then across to [Rename…], type the new identifier, and press [Enter]. Notice that this changes the identifier everywhere in the class.)
- Understand why this resolved the style errors.
- Remove the
static
modifier from all of the methods (and save the file). - Understand why this resolved the syntax errors.
- Write the explicit value constructor.
Stub-Out the Test
Class
- Create a version of the
Test
class that contains all of the methods (with appropriate signatures), each of which should return false
. - Add the “javadoc” comments to the
Test
class and the methods in it. - Check the style of the
Test
class and make any necessary corrections.
Add PricerTest.java
to the Project
- Add
PricerTest.java
to the project. - Make sure there are no compile-time errors in
PricerTest.java
. If there are, you probably need to fix the stubbed-out version of Test.java
(since there should be no syntax errors in PricerTest.java
).
Implement the Test
Class
- Add the
forEqualInts()
method. (Hint: See the example above.) - Add the
forEqualStrings()
method. (Hint: Be careful about how you compare String
objects.) - Add the
forEqualDoubles()
method. (Hint: You should probably use the static abs()
method in the Math
class.) - Add the other methods.
Test and Debug the Pricer
Class
- Run
PricerTest
. - If there is any output it means that your code failed a test. Starting with the first failure, debug the relevant method in the
Pricer
class using the process we discussed. - Re-run
PricerTest
and repeat as necessary.
Questions to Think About
You don’t have to submit your answers to these questions, but you should try to answer them because they will help you determine whether or not you understand some of the important concepts covered in this assignment.
- Notice that the
PricerTest
class now uses an array for the input values and uses a loop to run all of the test. Why is this better than the approach used in the previous assignment? - How could you change the
PricerTest
class so that it keeps a count of the number of failed tests (and reports that number)? - What compile-time errors are generated in the
Pricer
class if you make the attributes in it static
? Why? - Why does the
PricerTest
class test the dounutPricer
again after testing the cookiePricer
? In other words, what defects might this re-test identify? (Hint: Think about your answer to the previous question.) - Why would it be nice to be able to overload methods in the
Test
class?
5 - HW1: Duke-n-Donuts v1
Homework 1
![Duke-n-Donuts](Duke-n-Donuts_v1.png)
Learning Objectives
This homework assignment is designed to help you learn several
things. First, it will help you learn about data types, variables,
literals, arithmetic operators, how utility classes are organized,
static attributes, and declaring static methods. Second, it will help
you become comfortable with some of the tools that you will be using
throughout the semester. Third, it will help you become comfortable
with the various policies (including submission policies) that you
must comply with while working on homework assignments and
programming assignments this semester.
Overview
A group of former JMU students have decided to open a bakery called
Duke-n-Donuts. They have asked you to create a utility class named
DonutPricer
that they can use to calculate the price of a particular
order. All types of donuts are priced the same way and all donuts are
“delivered” in a box (that may be full or partially full). The number
of donuts that fit in a full box is given by BOX_SIZE
. The price of
a full box of donuts is given by PRICE_PER_BOX
and the price of an
individual donut is given by PRICE_PER_INDIVIDUAL
.
The Class to be Written
You must write the DonutPricer
class.
The UML Class Diagram
The following UML class diagram provides an overview of the attributes
and methods in this class (which must be in the default package).
![Class Diagram](DonutPricer.png)
Detailed Design Specifications
In addition to the specifications contained in the UML class diagram,
this class must conform to the following specifications.
- All of the “constants” must be declared to be final.
- All of the methods that are passed a number of donuts and return a number (whether an
int
or a double
) must return 0 when the number of donuts is less than or equal to 0. (Note: There is a method that is passed a number of donuts and returns a boolean
. The specifications for that method are given below.) numberOfFullBoxes()
and numberOfBoxes()
must return the number of full boxes and the total number of boxes required to hold the order. So, for example, an order of 98 donuts will require 8 full boxes and 9 boxes in total.numberOfExtras()
must return the number of donuts in the order that will be in a box that isn’t full. So, for example, an order of 98 donuts will have 2 extras (since 96 of the donuts will be in full boxes).needAnExtraBox()
must return true
if there are extra donuts (i.e., donuts that won’t be in a full box) in the order and must return false
otherwise. This method must not use an if
statement, loop, or ternary operator.priceFor()
must return the price of an order of the given size. When a customer orders less than a full box, they pay the individual price for each donut. So, for example, an order of 6 donuts will have a price of $5.94. When a customer orders a full box, they pay the price of a full box. For example, an order of 12 donuts will have a price of $9.99. Finally, when a customer orders more than a full box, they pay the price of however many full boxes there are plus the cost of the extras. For example, an order of 98 donuts will have a price of $81.90 (8 boxes at $9.99 plus 2 extras at $0.99 each).- Methods must not duplicate the code in other methods unless it is absolutely necessary (e.g., for parameter validation). Instead, methods must invoke each other as needed.
An Existing Class
A main class (i.e., a class with a main()
method) that you can use to test
the DonutPricer
class has already been written. It is named
DonutPricerTest
and the source code (i.e., the .java
file) is
available at:
📄 DonutPricerTest.java
Submission
You must submit (using Gradescope):
- Your implementation of the
DonutPricer
class. Do not include the DonutPricerTest
class.
There is no limit on the number of submissions and no penalty for excessive submissions. Note that your submission will not be graded if it does not comply with the specifications. So, if you do not complete the DonutPricer
class your submission should include a stubbed-out version of all of the methods. This will allow you to potentially get credit for the methods that you do implement.
Grading
Your code will first be graded by Gradescope and then by the Professor. The grade you receive from Gradescope is the maximum grade that you can receive on the assignment
Gradescope Grading
Your code must compile (in Gradescope, this will be indicated in the section on “Does your code compile?”) and all class names and method signatures must comply with the specifications (in Gradescope, this will be indicated in the section on “Do your class names, method signatures, etc. comply with the specifications?”) for you to receive any points on this assignment. Gradescope will then grade your submission as follows:
Criterion | Points | Details |
---|
Conformance to the Style Guide | 20 points | (Partial Credit Possible) |
Correctness | 80 points | (Partial Credit Possible) |
Gradescope will provide you with hints, but may not completely identify the defects in your submission.
Manual Grading
After the due date, the Professor may manually review your code. At this time, points may be deducted for inelegant code, inappropriate variable names, bad comments, etc.
Recommended Process
Since nobody will be looking over your shoulder, you can use any process that you would like to use. However, it is strongly recommended that you use the process described here.
Get Started
- Read and understand the entire assignment.
- Create a project for this assignment named
hw1
. (Remember, do not create a module and create separate folders for source and class files). - Activate Checkstyle for this assignment.
- Download
DonutPricerTest.java
to a directory outside of your Eclipse workspace (e.g., the downloads
directory for this course).
Understand the Test Cases
- Read and understand the test cases in
DonutPricerTest.java
. - By hand (i.e., using pencil and paper), calculate the expected answer for each of the test cases in
DonutPricerTest.java
.
Stub-Out DonutPricer.java
- Create a version of the
DonutPricer
class that contains all of the methods (with appropriate signatures), each of which should return 0
, 0.0
, or false
as appropriate. (Remember: All of the classes you write for this assignment must be in the default package. So, when you create a new class in Eclipse, make sure that the “Package” field is blank.) - Add the “javadoc” comments to the
DonutPricer
class and the methods in it. (Help on javadoc comments is available on the Department’s Wiki.) - Check the style of the
DonutPricer
class and make any necessary corrections.
Add DonutPricerTest.java
to the Project
- Add
DonutPricerTest.java
to the project. (Help on adding source files to a project is available on the Department’s Wiki.) - Make sure there are no compile-time errors in
DonutPricerTest.java
. If there are, you probably need to fix the stubbed-out version of DonutPricer.java
(since there should be no syntax errors in DonutPricerTest.java
).
Implement and Test the DonutPricer
Class
- Add the “constants”.
- Add the
numberOfFullBoxes()
method. - Run the
DonutPricerTest
class and make sure that all of the answers returned by the numberOfFullBoxes()
method are correct. - Debug
numberOfFullBoxes()
if necessary. - Add the
numberOfExtras()
method. - Run the
DonutPricerTest
class and make sure that all of the answers returned by the numberOfExtras()
method are correct. - Debug
numberOfExtras()
if necessary. - Add the
needAnExtraBox()
method. - Run the
DonutPricerTest
class and make sure that all of the answers returned by the needAnExtraBox()
method are correct. - Debug
needAnExtraBox()
if necessary. - Add the
numberOfBoxes()
method. - Run the
DonutPricerTest
class and make sure that all of the answers returned by the numberOfBoxes()
method are correct. - Debug
numberOfBoxes()
if necessary. - Add the
priceFor()
method. - Run the
DonutPricerTest
class and make sure that all of the answers returned by the priceFor()
method are correct. - Debug
priceFor()
if necessary.
Help
Help with Eclipse and help with Gradescope are available on the Department’s Wiki.
Questions to Think About
You don’t have to submit your answers to these questions, but you should try to answer them because they will help you determine whether or not you understand some of the important concepts covered in this assignment.
- What compile-time errors (if any) do you get in
DonutPricer.java
class if you make the attributes non-static? Why? - What compile time errors (if any) do you get in
DonutPricer.java
if you make all of the methods non-static? Why? - What compile-time errors (if any) do you get in
DonutPricerTest.java
if you make the methods in DonutPricer.java
non-static? Why? - Why does the recommended process have you test and debug each method immediately after you implement it?
- Why does the recommended process have you implement the methods in the order it does? For example, why does it have you implement
numberOfBoxes()
after it has you implement numberOfExtraBoxes()
and needAnExtraBox()
?