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
🛑 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.
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.
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.
importjava.lang.reflect.InvocationTargetException;importjavax.swing.SwingUtilities;/**
* This is the main class for Rave'n.
*
* @author Computer Science Department, James Madison University
* @version 1
*/publicclassRaven{/**
* The entry point of the application.
*
* @param args The command-line arguments (which are not used).
* @throws InterruptedException
* @throws InvocationTargetException
*/publicstaticvoidmain(String[] args)throwsInterruptedException,InvocationTargetException{RavenWindow window;
window =newRavenWindow();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.
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
🛑 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.
Some of the specifications for the PhraseCypher class are
illustrated in the following UML class diagram:
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 chars 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
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.
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.
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”.
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.
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:
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
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 =newPricer(12,9.99,0.99);
cookies =newPricer(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).
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.
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).
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
*/publicstaticbooleanforEqualInts(int expected,int actual,String description){if(expected != actual){System.out.printf("%s Expected: %d, Actual: %d\n",
description, expected, actual);returnfalse;}else{returntrue;}}
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:
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
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).
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:
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.
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.
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()?