Lab 8: Bob's Grocery Mart¶
Learning Objectives¶
After completing this lab, you should be able to:
- Write a class that includes getters/setters and throws exceptions.
- Create an ArrayList, add/remove elements, and loop over elements.
- Run JUnit tests for a discrete event simulation with random events.
Background¶
Bob's Grocery Mart (not real) has 73 locations distributed across 12 States. Bob would like to increase the profitability of his stores by improving cashier scheduling. If too few cashiers are scheduled, customers become frustrated and may not return to the store. But with too many cashiers, Bob pays more wages than necessary.
You have been tasked with writing a "checkout simulation" program to analyze the impact of increasing or decreasing the number of cashiers.
The main simulation code has already been written, but the supporting classes (Customer
and Aisle
) are left for you to write.
Part 1: Getters and Setters¶
Download and unzip the Provided Code into your src/labs
folder, creating a new folder named lab08
.
The code does not yet compile, because none of the attributes, getters, and setters are defined.
However, the code provides stubs and Javadoc comments for the other methods you will implement.
Tip
In VS Code, you can type the word get
or set
in the class body and press Enter to generate the getters and setters automatically.
Javadoc comments are not required for getters and setters.
UML for Customer¶
Add the attributes and getters/setters to the Customer
class.
The variables numItems
and enterTime
should be declared final
.
classDiagram
class Customer {
- numItems: int
- enterTime: int
- serveTime: int
- exitTime: int
+ Customer(numItems: int, enterTime: int)
+ getNumItems() int
+ getEnterTime() int
+ getServeTime() int
+ getExitTime() int
+ setServeTime(serveTime: int)
+ setExitTime(exitTime: int)
+ waitTime() int
+ checkoutTime() int
+ totalTime() int
}
UML for Aisle¶
Add the attributes and getters/setters to the Aisle
class.
The variables generator
, line
, and served
should be declared final
.
classDiagram
class Aisle {
+ MAX_BAG_TIME: int = 5$
- generator: Random
- line: ArrayList~Customer~
- served: ArrayList~Customer~
- current: Customer
- itemsOnBelt: int
- itemStart: int
- itemDelay: int
+ Aisle(generator: Random)
+ getGenerator() Random
+ getLine() ArrayList~Customer~
+ getServed() ArrayList~Customer~
+ getCurrent() Customer
+ getItemsOnBelt() int
+ getItemStart() int
+ getItemDelay() int
+ addCustomer(customer: Customer)
+ lineLength() int
+ nextCustomer(curTime: int)
+ nextItem(curTime: int)
+ step(curTime: int)
+ totalServed() int
+ totalWait() int
+ maxWait() int
}
Sanity Check¶
At this point, all classes and JUnit tests should compile.
The only files you will edit in this lab are the Customer
and Aisle
classes.
Please ask for help before moving on if you still have errors.
Part 2: Customer.java¶
Implement the Customer
methods according to the Javadoc comments.
Note the following:
- A customer enters the line at
enterTime
, begins checking out items atserveTime
, and leaves the store atexitTime
. - All times are measured in seconds since the beginning of the simulation (start time is 0).
- The constructor must initialize
serveTime
andexitTime
to -1, which means the time has not yet occurred. - The constructor might throw IllegalArgumentException, but the last three methods might throw IllegalStateException.
- Checking the arguments (and possibly throwing an exception) should be the first thing a method does, before any other statements.
Run the provided CustomerTest
to check your work.
If any tests fail, be sure to change Customer
and not CustomerTest
.
Part 3: Aisle.java¶
Implement the Aisle
methods according to the Javadoc comments.
Note the following:
- The constructor must initialize all (non-static) attributes.
Both ArrayLists should be empty (not
null
), the current customer should benull
, and the integers should be 0. addCustomer()
should be only line of code.- The
current
attribute is set (notnull
) while a customer is being served, and during that time, the customer is in neither ArrayList. - In
nextItem()
, you can usegenerator.nextInt(n)
to get a random number between 0 and n-1.itemDelay
should be a random number between 1 andMAX_BAG_TIME
(inclusive). totalServed()
should be only line of code.totalWait()
uses a for loop to add the wait times of all customers served.maxWait()
uses a for loop to find the max wait time of all customers served.
Simulation Steps¶
The step()
method is somewhat complex (about 12 statements).
Here is an outline:
-
If no items are on the belt
- If there is a current customer
- Set the customer's exit time
- Add the customer to
served
- Set
customer
tonull
- If the line is not empty
- Call
nextCustomer()
- Call
nextItem()
- Call
- If there is a current customer
-
If any items are on the belt
- If the current time is after
itemStart + itemDelay
- Decrease
itemsOnBelt
by 1 - Call
nextItem()
- Decrease
- If the current time is after
Run the provided AisleTest
to check your work.
If any tests fail, be sure to change Aisle
and not AisleTest
.
Part 4: Code Review¶
Try running MartDriver
to see how long customers have to wait.
You can edit the simulation parameters (local variables of main()
) to see different results.
Review MartSimulation
and figure out how the code works.
For example, notice how MartSimulation
calls the step()
method of each aisle over and over again.
You don't need to submit MartSimulation
and MartDriver
, so feel free to experiment with those files.
Gradescope will run the provided AisleTest
and CustomerTest
.
Make sure you pass all the tests before submitting your code.
Submission¶
Submit Aisle.java
and Customer.java
to Gradescope.
Points will be allocated as follows:
Criterion | Points | Details |
---|---|---|
Compile | 0 pts | Success Required |
CompileOfficialTests | 0 pts | Success Required |
Style | 1 pts | Partial Credit Possible |
OfficialTests | 9 pts | Partial Credit Possible |