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
serveTimeandexitTimeto -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
currentattribute 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.itemDelayshould 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
customertonull
- 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
itemsOnBeltby 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 |