Skip to content

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 at serveTime, and leaves the store at exitTime.
  • All times are measured in seconds since the beginning of the simulation (start time is 0).
  • The constructor must initialize serveTime and exitTime 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 be null, and the integers should be 0.
  • addCustomer() should be only line of code.
  • The current attribute is set (not null) while a customer is being served, and during that time, the customer is in neither ArrayList.
  • In nextItem(), you can use generator.nextInt(n) to get a random number between 0 and n-1. itemDelay should be a random number between 1 and MAX_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 to null
    • If the line is not empty
      • Call nextCustomer()
      • Call nextItem()
  • If any items are on the belt

    • If the current time is after itemStart + itemDelay
      • Decrease itemsOnBelt by 1
      • Call nextItem()

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