This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Homework

1-week Assignments

5 homework assignments will be assigned during the semester. Note that their due dates are subject to change.

  1. HW1 - Due: 9/10 11:00PM (Getting Started)
  2. HW2 - Due: 9/17 11:00PM (Unit Testing Fundamentals)
  3. HW3 - Due: 9/24 11:00PM (Classes and Enumerated Types)
  4. HW4 - Due: 10/1 11:00PM (JUnit)
  5. HW5 - Due: 10/8 11:00PM (Objects and References)

1 - HW5: Rave'n

Homework 5

Rave’n

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

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):

  1. 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:

CriterionPointsDetails
Conformance to the Style Guide0 points(Success Required)
Correctness100 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.

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

  1. Read and understand the entire assignment.
  2. Create a project for this assignment named hw5. (Remember, do not create a module and create separate folders for source and class files).
  3. Activate Checkstyle for this assignment.

Stub-Out the Classes

  1. Stub-out the Item class.
  2. Stub-out the Order class.
  3. Stub-out the Invoice class.
  4. Add the “javadoc” comments to the three classes class.
  5. Check the style of the three classes and make any necessary corrections.

Implement and Test (if Desired) the Classes

  1. Implement and test everything in the Item class except the copy constructor.
  2. Implement and test the copy constructor in the Item class.
  3. Implement and test the explicit value contstructor and simple getters in the Order class.
  4. Implement and test the toString() method in the Order class.
  5. Implement and gest the getServes() method in the Order class.
  6. Implement and gest the getPrice() method in the Order class.
  7. Implement and test the copy constructor in the Order class.
  8. Implement and test the constructor, addOrder(), getOrder(), and size() methods in the Invoice class.
  9. Implement and test the getPrice() method in the Invoice class.
  10. Implement and test the getServes() method in the Invoice class.

Conduct System Tests (if Desired)

  1. Download hw5.jar to a directory outside of your Eclipse workspace (e.g., the downloads directory for this course).
  2. 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].
  3. Execute the Raven class.
  4. Add a few orders.
  5. Ensure that the information displayed is correct.
  6. Change the number of items in one order.
  7. Ensure that the information displayed is correct.
  8. Change the number of items in another order.
  9. Ensure that the information displayed is correct.

The following screenshot shows an example of how the GUI might be used.

Screenshot

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.

  1. What does the word “deep” really mean when used in the context of a “deep copy”? Can there be different levels of depth?
  2. Why is it sometimes appropriate to use an alias and sometimes appropriate to use a deep copy?
  3. 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

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

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:

  1. 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.
  2. Create a class named RandomTests.java that contains JUnit tests based on random inputs for all of the methods in the PhraseCypher class.

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):

  1. Your corrected implementation of the PhraseCypher class (with appropriate comments).
  2. 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:

CriterionPointsDetails
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.

  1. The assignment does not require that your tests completely cover the code. Why not?
  2. The white-box tests completely covered the code. How could the code still contain defects?
  3. Why are both heuristic tests (based on rules of thumb) and random tests necessary (in addition to white-box tests)?
  4. 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?
  5. 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?
  6. 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?
  7. 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

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

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):

  1. 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:

CriterionPointsDetails
Conformance to the Style Guide20 points(All or Nothing; Success Required)
Correctness80 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.

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

  1. Read and understand the entire assignment.
  2. Create a project for this assignment named hw3. (Remember, do not create a module and create separate folders for source and class files).
  3. Activate Checkstyle for this assignment.
  4. 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

  1. Read and understand the test cases in FencingEventTest.java.
  2. By hand (i.e., using pencil and paper), calculate the expected output from MeleeDriver.java.

Write the Simple enums

  1. Write BladePart.java.
  2. Write BodyPart.java.

Stub-Out the Remaining Components

  1. Create a stub for the FencingEvent enum that includes all of the attributes and methods with “javadoc” comments.
  2. 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

  1. Copy Test.java into hw3.
  2. Copy FencingEventTest.java into hw3.
  3. Copy MeleeDriver.java into hw3.
  4. Copy WhiteBoxTests.java into hw3.

Write the Remaining enum and Class

  1. 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.)
  2. 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.)
  3. 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

  1. What syntax error is generated in FencingEvent if you type a BodyPart incorrectly?
  2. If you used String literals instead of an enum, what syntax error would be generated if you type one of them incorrectly?
  3. 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?
  4. How would you invoke the isScoringTouch() method for FencingEvent.EPEE (for example)?
  5. Could you invoke the isScoringTouch() method on the String literal "EPEE" if, for example, you had used String literals instead of an enum?
  6. 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

  1. “Launch WhiteBoxTests” using the coverage tool (i.e., click on the WhiteBoxTests.java tab to make it active and then click on Launch 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!)
  2. 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!)
  3. 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?
  4. What is now true of the coverage of the isLegalBladePart() method? Why?
  5. Why is the isOnTarget() method still completely covered?

Before you proceed, undo any changes you made.

Questions About Unit Testing

  1. 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?
  2. Is it enough to just cover code when writing unit tests?
  3. 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?
  4. 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?
  5. 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?
  6. 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?
  7. 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

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

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

  1. The constructor must initialize the attributes of the object.
  2. 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

Detailed Design Specifications

In addition to the specifications contained in the UML class diagram, this class must conform to the following specifications.

  1. forEqualDoubles() must check to determine if the attributes expected and actual differ by more than the tolerance.
    1. 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".
    2. If not, it must return true (and not print anything).
  2. forEqualInts() must check to determine if the attributes expected and actual differ.
    1. 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".
    2. If not, it must return true (and not print anything).
  3. forEqualStrings() must check to determine if the attributes expected and actual differ.
    1. 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".
    2. If not, it must return true (and not print anything).
  4. forFalse() must check to determine if the attribute named actual is false
    1. If so, it must return true (and not print anything).
    2. If not, it must return false and print the description using the format String "%s Expected: false, Actual: true\n".
  5. forTrue() must check to determine if the attribute named actual is true
    1. If so, it must return true (and not print anything).
    2. 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):

  1. 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:

CriterionPointsDetails
Conformance to the Style Guide20 points(Partial Credit Possible)
Correctness80 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.

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

  1. Read and understand the entire assignment.
  2. Create a project for this assignment named hw2. (Remember, do not create a module and create separate folders for source and class files).
  3. Activate Checkstyle for this assignment.
  4. Download PricerTest.java to a directory outside of your Eclipse workspace (e.g., the downloads directory for this course).

Understand the Test Cases

  1. Read and understand the test cases in PricerTest.java.
  2. 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

  1. Copy DonutPricer.java from he project named hw1 to the project named hw2.
  2. 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

  1. Delete the initialization of all of the attributes (and save the file).
  2. Understand why this generated several syntax errors.
  3. Remove the final modifier from all of the attributes (and save the file).
  4. Understand why this resolved the syntax errors.
  5. Make all of the attributes non-static (i.e., remove the static modifiers).
  6. Understand why this generated several style errors.
  7. Understand why this also generated several syntax errors in the methods that follow.
  8. 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.)
  9. Understand why this resolved the style errors.
  10. Remove the static modifier from all of the methods (and save the file).
  11. Understand why this resolved the syntax errors.
  12. Write the explicit value constructor.

Stub-Out the Test Class

  1. Create a version of the Test class that contains all of the methods (with appropriate signatures), each of which should return false.
  2. Add the “javadoc” comments to the Test class and the methods in it.
  3. Check the style of the Test class and make any necessary corrections.

Add PricerTest.java to the Project

  1. Add PricerTest.java to the project.
  2. 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

  1. Add the forEqualInts() method. (Hint: See the example above.)
  2. Add the forEqualStrings() method. (Hint: Be careful about how you compare String objects.)
  3. Add the forEqualDoubles() method. (Hint: You should probably use the static abs() method in the Math class.)
  4. Add the other methods.

Test and Debug the Pricer Class

  1. Run PricerTest.
  2. 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.
  3. 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.

  1. 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?
  2. How could you change the PricerTest class so that it keeps a count of the number of failed tests (and reports that number)?
  3. What compile-time errors are generated in the Pricer class if you make the attributes in it static? Why?
  4. 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.)
  5. 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

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

Detailed Design Specifications

In addition to the specifications contained in the UML class diagram, this class must conform to the following specifications.

  1. All of the “constants” must be declared to be final.
  2. 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.)
  3. 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.
  4. 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).
  5. 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.
  6. 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).
  7. 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):

  1. 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:

CriterionPointsDetails
Conformance to the Style Guide20 points(Partial Credit Possible)
Correctness80 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.

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

  1. Read and understand the entire assignment.
  2. Create a project for this assignment named hw1. (Remember, do not create a module and create separate folders for source and class files).
  3. Activate Checkstyle for this assignment.
  4. Download DonutPricerTest.java to a directory outside of your Eclipse workspace (e.g., the downloads directory for this course).

Understand the Test Cases

  1. Read and understand the test cases in DonutPricerTest.java.
  2. 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

  1. 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.)
  2. Add the “javadoc” comments to the DonutPricer class and the methods in it. (Help on javadoc comments is available on the Department’s Wiki.)
  3. Check the style of the DonutPricer class and make any necessary corrections.

Add DonutPricerTest.java to the Project

  1. Add DonutPricerTest.java to the project. (Help on adding source files to a project is available on the Department’s Wiki.)
  2. 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

  1. Add the “constants”.
  2. Add the numberOfFullBoxes() method.
  3. Run the DonutPricerTest class and make sure that all of the answers returned by the numberOfFullBoxes() method are correct.
  4. Debug numberOfFullBoxes() if necessary.
  5. Add the numberOfExtras() method.
  6. Run the DonutPricerTest class and make sure that all of the answers returned by the numberOfExtras() method are correct.
  7. Debug numberOfExtras() if necessary.
  8. Add the needAnExtraBox() method.
  9. Run the DonutPricerTest class and make sure that all of the answers returned by the needAnExtraBox() method are correct.
  10. Debug needAnExtraBox() if necessary.
  11. Add the numberOfBoxes() method.
  12. Run the DonutPricerTest class and make sure that all of the answers returned by the numberOfBoxes() method are correct.
  13. Debug numberOfBoxes() if necessary.
  14. Add the priceFor() method.
  15. Run the DonutPricerTest class and make sure that all of the answers returned by the priceFor() method are correct.
  16. 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.

  1. What compile-time errors (if any) do you get in DonutPricer.java class if you make the attributes non-static? Why?
  2. What compile time errors (if any) do you get in DonutPricer.java if you make all of the methods non-static? Why?
  3. What compile-time errors (if any) do you get in DonutPricerTest.java if you make the methods in DonutPricer.java non-static? Why?
  4. Why does the recommended process have you test and debug each method immediately after you implement it?
  5. 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()?