Skip to content

HW6: Teethbrushes

Teethbrushes

To Know Before You Start

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

  2. Sample JUnit tests have been provided to help you get started, and you are encouraged to expand and build upon them.

Learning Objectives

  • Implement specialization and inheritance by creating derived classes that extend base classes and override methods.
  • Manage and encapsulate data using object-oriented principles.
  • Develop and execute JUnit tests to verify code correctness and maintainability.
  • Organize code into packages for better structure and modularity.

Overview

You may have heard, or you may have observed first-hand, that computer science students sometimes have personal hygiene problems. (Not you of course, but perhaps some of your fellow students?) A recent survey identified part of the problem. Many computer science students only brush one tooth (rather than all of them) because they were told to use a toothbrush and the word tooth is singular. An enterprising company has decided to take advantage of this confusion by selling teethbrushes instead.

At the moment, they are starting to build relationships. For example, they have contracted with "Dr. Teeth and the Electric Mayhem" to write their advertising jingles, and they have contracted with you to implement some of the classes needed for their inventory system.

Background

A physical Teethbrush consists of a head (and associated handle or stem) while a physical ElectricTeethbrush consists of a head and a body. The bristles in the head can be flat or polished (i.e., rounded). The body of an ElectricTeethbrush can be rechargeable or not, and can provide ultrasonic cleaning (via the head) or not.

The cost of a Teethbrush is the sum of the BASE_HEAD_COST ($2.00), the hardness cost, and the POLISHED_UPCHARGE ($0.75) if the bristles are polished. The hardness cost is the product of the hardness (which is in the closed interval [0, 5]) of the bristles and the HARDNESS_UPCHARGE ($0.10). So, the harder the bristles, the higher the cost. For example, a Teethbrush that has polished bristles with a hardness of 5 costs $2.00 + $0.75 + $0.50 = $3.25

The head of an ElectricTeethbrush costs the same as the head of a Teethbrush. However, an ElectricTeethbrush comes with multiple heads, whereas a Teethbrush has only one. Hence, the cost of an ElectricTeethbrush is the product of the NUMBER_OF_HEADS (5) and the cost of a Teethbrush, plus the BASE_BODY_COST ($5.00), plus the RECHARGEABLE_UPCHARGE ($20.00) and the ULTRASONIC_UPCHARGE ($10.00) as appropriate. For example, a basic ElectricTeethbrush that has polished bristles with a hardness of 0 has an initial cost of $13.75 + $5.00 = $18.75, and a rechargeable version would cost $18.75 + $20.00 = $38.75.

The shipping cost of an order is the product of the unit shipping cost and the order size, plus a STOCKING_COST ($25.00) if the size of the order is greater than the current inventory level. The unit shipping cost is either the UNIT_SHIPPING_COST_OVERSEAS ($0.30) or the UNIT_SHIPPING_COST_LOCAL ($0.10), reduced by the LARGE_ORDER_DISCOUNT (30.0%) if the order is greater than LARGE_ORDER (1000). For example, suppose someone wants to ship an order of 2000 Teethbrush overseas when there are 100 in inventory. The unit shipping cost will be $0.21 (the $0.30 minus the large order discount of $0.09), meaning the total shipping cost will be $445.00 (i.e., $0.21 x 2000 = $420.00 plus the $25.00 stocking cost).

The Classes to be Written

You must write the Teethbrush and ElectricTeethbrush classes that are summarized in the following UML class diagram.

Class Diagram

Note that attributes and methods that are inherited are not made explicit in this diagram. If a method appears in both a base class and a derived class it means that the method in the derived class overrides the method in the base class.

The Teethbrush Class

As discussed above and as shown in the UML class diagram, a Teethbrush object is characterized by the hardness of the bristles (on a scale of 0-5), and whether the bristles are polished or not (i.e., whether the part of the bristle that comes in contacts with the teeth is flat or rounded). A Teethbrush object also has an associated inventory level.

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

  1. Any time someone attempts to set the hardness attribute to a value less than 0 it must be set to 0.
  2. Any time someone attempts to set the hardness attribute to a value greater than 5 it must be set to 5.
  3. The changeInventory() method can be used to increase (with a positive parameter) or decrease (with a negative parameter) the inventory attribute. It must not change the inventory attribute (and must return false) if the change would make the inventory attribute negative. Otherwise, it must make the change and return true.

The ElectricTeethbrush Class

As discussed above and as shown in the UML class diagram, in addition to the attributes of a Teethbrush, an ElectricTeethbrush can be rechargeable or not, and can be ultrasonic or not.

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

  1. The cost() method in the ElectricTeethbrush class must not duplicate any code in the method that it overrides.

Unit Testing

You can test your code using JUnit. Sample JUnit tests have been provided to help you get started, and you are encouraged to expand and build upon them.

Submission

You must submit (using Gradescope):

  1. Your implementation of the Teethbrush and ElectricTeethbrush classes. Do not submit any JUnit test files.

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

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.

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 folder for this assignment named hw6. Then create a package (in the hw6) named product.
  3. Ensure your code follows the provided style guide using available tools in VSCode.

Important: Package Declaration

The files have the package declaration package hws.hw6.product;. This means that the files should be placed in a directory named product inside a directory named hw6.

For example, you should have a directory structure like this in your VS code:

hws/
├── hw6/
│   └── product/
│       ├── ElectricTeethbrush.java
│       └── Teethbrush.java

Create more test cases for Teethbrush and ElectricTeethbrush

  1. By hand (i.e., using pencil and paper), create several black-box tests cases (i.e., inputs and expected outputs) for the cost() method in the Teethbrush class. Some of these tests should involve random inputs and some should involve rules-of-thumb.

  2. By hand, create tests several black-box cases for the shippingCost() method in the Teethbrush class. Some of these tests should involve random inputs and some should involve rules-of-thumb.

  3. By hand, create several black-box tests cases for the cost() method in the ElectricTeethbrush class. Some of these tests should involve random inputs and some should involve rules-of-thumb.

Writing these black-box test cases before you start writing the code is called test driven development (TDD). Using TDD will help you understand the algorithms that you need to write.

Stub-Out the Classes

  1. Stub-out the Teethbrush class.
  2. Stub-out the ElectricTeethbrush class.
  3. Add the "javadoc" comments to the classes.
  4. Check the style of the two classes and make any necessary corrections.

Implement and Test the Classes

  1. Implement the constructor, setters, and simple getters in the Teethbrush class.

  2. Test the constructor, setters, and simple getters in the Teethbrush class using the black-box tests (and debug if necessary).

  3. If necessary, add white-box tests to get 100% statement coverage and 100% branch coverage (and debug if necessary).

  4. Implement the constructor and simple getters in the ElectricTeethbrush class.

  5. Test the constructor and simple getters in the ElectricTeethbrush class using the black-box tests (and debug if necessary).

  6. If necessary, add white-box tests to get 100% statement coverage and 100% branch coverage (and debug if necessary).

  7. Implement the shippingCost() method in the Teethbrush class.

  8. Test the shippingCost() method in the Teethbrush class using the black-box tests (and debug if necessary).

  9. If necessary, add white-box tests to get 100% statement coverage and 100% branch coverage (and debug if necessary).

  10. Implement the cost() method in the Teethbrush class.

  11. Test the cost() method in the Teethbrush class using the black-box tests (and debug if necessary).

  12. If necessary, add white-box tests to get 100% statement coverage and 100% branch coverage (and debug if necessary).

  13. Implement the cost() method in the ElectricTeethbrush class.

  14. Test the cost() method in the ElectricTeethbrush class using the black-box tests (and debug if necessary).

  15. If necessary, add white-box tests to get 100% statement coverage and 100% branch coverage (and debug if necessary).

Help with JUnit

You should be fairly proficient with JUnit at this point (especially since we will be using JUnit for the rest of the semester). However, if you are still having trouble, help is available at:

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. How would the design of the Teethbrush class change if the polished attribute were represented using a 0–1 indicator instead of a boolean?
  2. What adjustments would be needed in the constructor, cost() method, and isPolished() method?
  3. What is gained by using specialization in this assignment? In other words, what is gained from having the ElectricTeethbrush class extend the Teethbrush class?