HW5: CaterRing¶
Danger
As discussed below, on this assignment you may submit to Gradescope at most ten times without penalty. 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.
Definitions¶
- Aliases
- Two variables are aliases for the same object iff they contain the same reference.
- Copies
- Two objects are copies of each oher iff their attributes are copies of each other. They are said to be deep copies iff their reference-type attributes are also copies of each other, not aliases for the same object.
In the following example, s
and t
are aliases for the same object, but
m
is a copy of n
.
Color s, t, m, n;
s = new Color(69, 0, 132);
t = s;
m = new Color(203, 182, 119);
n = new Color(n);
Overview¶
Some students who have worked in D-Hall for many years have decided to start a catering company (named CaterRing) that will serve off-campus clients. They have come to you to create a meal planning tool.
Existing Classes¶
The CS159 faculty have provided you with the source code for a utility
class that might help you improve the quality of some of your
toString()
methods.
This class is in the hw5.text
package.
Note
This class may contain style errors. You are responsible for detecting and correcting them.
The Components to be Written¶
You must write three components named Food
, Order
, and Meal
that
are summarized in the following UML class diagram.
Detailed Design Specifications¶
In addition to the specifications contained in the UML class diagram, your implementation must conform to the following specifications.
The Food
Component¶
The description
attribute must be a deep copy of the parameter that
is passed to the explicit value constructor, and the copy constructor
must invoke the explicit value constructor. You may assume that the
description
will never be null
.
The equals()
method must return true if all of the attributes of the
owning object are "equal to" (determined appropriately based on the
type of the attribute) the attributes of the given object.
The toString()
method must return a String
representation of the
ouncesPerPerson
, the appropriate form (singular or plural, determined
using the Pluralize
class) of the word "ounce"
, the description
attribute, and the pricePerOunce
attribute that is formatted using
"%d %s per person of %s at $%5.2f per ounce"
. Think about. It must return "I hate that!" when the description is anything other than "Chips".
The Order
Component¶
The explicit value constructor must make a fully deep copy of the food
parameter, and the copy constructor must invoke the explicit value
constructor.
The getPrice()
method must return the ounces
attribute multipled by
the appropriate member of the food
attribute. Think about: It must convert the ounces to pounds before multiplying.
The getServes()
method must return the ounces
attribute divided by the
appropriate member of the food
attribute. It must return the number of
people that can be "fully" served.
The toString()
method must return the value of the ounces
attribute, the appropriate form of the word "ounce"
, and the value
of the food
object's description
attribute formatted using "%d %s
of %s"
. Think about. It must return "That seems like too much" when the ounces attribute is greater than 20.
The Meal
Component¶
The constructor must initialize the orders
attribute.
The addOrder()
method must add an alias of the parameter named
order
to the attribute named orders
unless an Order
with an
"equivalent" Food
(in the sense of the equals()
method in the Food
class) is already in orders
, in which case it must increase the number
of ounces in the existing Order
. It must return the owning object, so that calls to addOrder()
can be chained. Think about. It must return null if the Order object is not in orders and must return this otherwise.
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 element with the given index in the orders
attribute. To think about. It must delete that element before returning it.
The getPrice()
method must return the total price of all Order
objects in the orders
attribute. To think about. It must cap the price of any particular order at $3.00 when performing the calculation.
The getServes()
method must return 0 when there are no Order
objects in the orders
attribute. Otherwise, it must return the
minimum value of the number of people served by all of the
Order
objects in the orders
attribute.
The size()
method must return the number of elements in the orders
attribute.
Examples¶
Examples of some of these specifications may help to clarify them.
Food
¶
One Food
that is commonly found at parties is
hamburgers, which might have a description
attribute of "Ground
Beef"
, an ouncesPerPerson
attribute of 4
, and a pricePerOunce
attribute of 0.40
. The toString()
method must return the following
in this case:
4 ounces per person of Ground Beef at $ 0.40 per ounce
Order
¶
Suppose a Food
of with a description
of "Ground Beef"
has a
serving size of 4 ounces and a price of $0.40 per ounce. Then for an
Order
with a size of 18 ounces, the getServes()
method must return
4
(i.e., 18/4
) and the getPrice()
method must return 7.20
(i.e., 18 * 0.40
).
The toString()
method for this example must return the following:
18 ounces of Ground Beef
Meal
¶
One Food
that is commonly found at parties is
hamburgers, which might have a description
attribute of "Ground
Beef"
, an ouncesPerPerson
attribute of 4
, and a pricePerOunce
attribute of 0.40
. A typical party might have 20 people in
attendance, so the planners might place an Order
for this Food
with an ounces
attribute of 80
. A typical party would also serve
several other foods, all of which would be incorporated in a single
Meal
.
Suppose the Meal
contains $7.20 worth of ground beef, $7.80 worth of
potato chips, and $8.80 worth cole slaw. Then, the getPrice()
method
must return 23.80.
Suppose the Order
contains enough ground beef to serve 4, enough
potato chips to serve 7, and enough cole slaw to serve 24. Then, the
getServes()
method must return 4
.
Finally, suppose the following:
- A serving size of Ground Beef is 4 ounces, costs $0.40 per ounce, and the order consists of 18 ounces
- A serving size of Potato Chips is 2 ounces, costs $0.52 per ounce, and the order consists of 15 ounces
- A serving of Cole Slaw is 3 ounces, costs $0.55 per ounce, and the order consists of 16 ounces
Then there is enough Ground Beed to serve 4 (at a cost of $7.20), there are enough Potato Chips to serve 7 (at a cost of $7.80), there is enough Cole Slaw to serve 5 (at a cost of $8.80), and the entire meal serves 4 (at a cost of $23.80).
Testing¶
How you test your code is up to you. But, you should be aware of the fact that Gradescope will not provide much help. In addition, your Professors and Teaching Assistants will provide less help if you have not tested your code before coming to us. So, it is strongly recommended that you use JUnit to conduct both white/open box and black/closed box testing.
Any tests you write (whether they use JUnit or not), must be
in the hw5.testing
package and must contain the word "Test"
.
Your test classes need not conform to the style guide.
Submission¶
You must submit (using Gradescope) a .zip file (named hw5.zip
) that
contains the files/folders text
(which will contain Pluralize
),
cater
(which will contain your implementation of the Food
,
Order
, and Meal
classes), and testing
(if you choose to write
tests).
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 without penalty. After that, you will be penalized 5 points for each submission.
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) |
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 directory/folder for this assignment named
hw5
. - Download
Pluralize.java
. - Create a directory/folder under
hw5
namedtext
. - Copy
Pluralize.java
into thehw5.text
directory/folder.
Stub-Out the Classes¶
- Create a directory/folder under
hw5
namedcater
. - Stub-out the
Food
class ( in the packagehw5.cater
). - Stub-out the
Order
class ( in the packagehw5.cater
). - Stub-out the
Meal
class ( in the packagehw5.cater
). - Add the "javadoc" comments to the three classes.
- Check the style of the three classes and make any necessary corrections.
Implement and Test the Classes¶
- Implement and test everything in the
Food
class except the copy constructor. - Implement and test the copy constructor in the
Food
class. - Implement and test the explicit value constructor and simple getters in the
Order
class. - Implement and test the
toString()
method in theOrder
class. - Implement and test the
getOunces()
method in theOrder
class. - Implement and test the
getPrice()
method in theOrder
class. - Implement and test the
getServes()
method in theOrder
class. - Implement and test the copy constructor in the
Order
class. - Implement and test the setter methods.
- Implement and test the constructor,
addOrder()
,getOrder()
, andsize()
methods in theMeal
class. - Implement and test the
getPrice()
method in theMeal
class. - Implement and test the
getServes()
method in theMeal
class. - Implement the
size()
method in theMeal
class.
Remember, any tests you write (whether they use JUnit or not), must be
in the hw5.testing
package and must contain the word "Test"
in the
class name.
Relevant Programming Patterns¶
An understanding of the following programming patterns will help you complete this assignment:
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?
- Do you think this assignment used aliases and deep copies appropriately or would you have designed it differently? Why?