The system simulated may be as complex as the earth's climate system or the evolution of the solar system. Or it might be quite simple, like the one you're building. I personally worked with a team building a simulator for the U.S. Army to model the performance of Army medical units in battlefield scenarios. That simulator is still widely used during Army "war games." If you'd care to read about that, here's a link: S-MDS paper.
During each tick of the simulator clock, the cashier scans one item from the basket of the customer at the head of the line. When that customer's basket is empty, they exit the line. On any tick, a new customer may also be added at the end of the line. To be realistic, most simulations, including ours, involve inputs arriving randomly but under some specified probability distribution; customers arrive at random intervals and purchase random numbers of items.
You can see that such a simulation might be useful if, for example, you were considering opening a new market in your neighborhood. If customers arrive too frequently or buy too many items, the line would grow longer and longer. If customers arrive infrequently or don't buy many items, the checker might be idle most of the time. Different assumptions might lead to different decisions: should the market have more checkout counters, should there be self-checkout, is there sufficient customer demand to make it profitable, etc.
The similation is driven by an "event list." Each item on the event list for our market simulator is a non-negative integer. Reading an item from the list is interpreted as ticking the simulator clock. At each tick, the line advances. That means to remove one item from the basket of the customer at the head of the line (unless the line is empty) and, if their basket becomes empty, they exit the line. But something else potentially happens on a tick: if the current event is non-zero, a new customer is added at the rear of the checkout line with that many items in their basket. For example, if the event item is 5, a new customer is created with a basket containing 5 items and the customer joins the checkout line. Number customers consecutively as you create them. At the end of each tick, you should also print out the current line. See the sample output below.
Finally, to make it easier for the TAs to grade your program, the event list will be supplied in a file, one event per line. (This is also to give you practice in creating and reading files.) You will process the file to create the event list. That is, create the event list all at once prior to running the simulation, by reading successive items from the file and storing them in a list. You will write one function to generate the file and another function to read items from the file and store them on a list. The function to create the file is parameterized so that you can control the length of the list, the frequency with which new customers arrive and how many items they can purchase. See the link for a template below.
The common pattern for using the driver (simulator) is to use generateEventsFile to write a file of events to drive the simulator. The parameters control: how many events, what percentage of the events are non-zero, the maximum size of any event (i.e., max number of items in a basket), and the filename. Once you have generated this file, you can extract the events from it into list form using the function generateEventListFromFile. Printing this list shows you the event list. Finally, pass this list to the simulateCheckoutLine function to simulate the behavior of our system for this sequence of events.
>>> from Project3 import * >>> c1 = Customer(15, 5) # testing Customer >>> print(c1) C15(5) >>> c1.getCustomerNumber() 15 >>> c1.getItemsCount() 5 >>> c1.decrementItemsCount() >>> print(c1) C15(4) >>> c1.customerFinished() False >>> c2 = Customer(83, 1) >>> c2.customerFinished() False >>> c2.decrementItemsCount() >>> print(c2) C83(0) >>> c2.customerFinished() True >>> line = CheckoutLine() # testing CheckoutLine >>> line.customerJoinsLine( c1 ) # customer joins Customer C15 joining line. >>> print(line) # printing line Line: [ C15(4) ] >>> line.customerLeavesLine() # customer leaves Customer C15 leaving line. >>> print(line) Line: [ ] >>> c3 = Customer(1, 4) >>> c4 = Customer(2, 2) >>> line.customerJoinsLine( c3 ) Customer C1 joining line. >>> line.customerJoinsLine( c4 ) Customer C2 joining line. >>> print(line) Line: [ C2(2) C1(4) ] >>> line.advanceLine() # line advances >>> print(line) Line: [ C2(2) C1(3) ] >>> line.advanceLine() >>> print(line) Line: [ C2(2) C1(2) ] >>> line.advanceLine() >>> print(line) Line: [ C2(2) C1(1) ] >>> line.advanceLine() Customer C1 leaving line. >>> print(line) Line: [ C2(2) ] >>> len( line ) # how long is the line 1 >>> generateEventsFile( 10, 25, 6, "EventsFile" ) # generate file of events >>> events = generateEventListFromFile( "EventsFile" ) # create list from file >>> events [0, 0, 0, 0, 0, 4, 0, 0, 1, 0] >>> generateEventsFile( 10, 45, 6, "EventsFile" ) # re-generate the file >>> events = generateEventListFromFile( "EventsFile" ) # and list of events >>> events [3, 4, 1, 3, 0, 2, 1, 0, 6, 0] >>> simulateCheckoutLine( events ) # drive simulation from Simulating a simple market, with one cashier. # list of events Step: 1 Customer C1 joining line. Line: [ C1(3) ] Step: 2 Customer C2 joining line. Line: [ C2(4) C1(2) ] Step: 3 Customer C3 joining line. Line: [ C3(1) C2(4) C1(1) ] Step: 4 Customer C1 leaving line. Customer C4 joining line. Line: [ C4(3) C3(1) C2(4) ] Step: 5 Line: [ C4(3) C3(1) C2(3) ] Step: 6 Customer C5 joining line. Line: [ C5(2) C4(3) C3(1) C2(2) ] Step: 7 Customer C6 joining line. Line: [ C6(1) C5(2) C4(3) C3(1) C2(1) ] Step: 8 Customer C2 leaving line. Line: [ C6(1) C5(2) C4(3) C3(1) ] Step: 9 Customer C3 leaving line. Customer C7 joining line. Line: [ C7(6) C6(1) C5(2) C4(3) ] Step: 10 Line: [ C7(6) C6(1) C5(2) C4(2) ] >>>
Your file must compile and run before submission. It must also contain a header with the following format:
# File: Project3.py # Student: # UT EID: # Course Name: CS303E # # Date Created: # Description of Program:
After you're finished with the base assignment, you are invited to play with such extensions. Personal projects like that are a great way to increase your programming competence. But make sure that any extensions aren't included in your submission.
Program incrementally: This is another classic example where programming the whole project before testing any part would be crazy. Some possible steps include:
Here's a possible main() function to test everything:
def main(): # Accept a filename from the user. filename = input("Enter a filename: ").strip() # Populate the file with 10 events (integers). Approximately # 50 percent are non-zero. Each is between [1..7] (items). # (Play with those parameters.) generateEventsFile( 10, 50, 7, filename ) # From the file, generate a list of events (integers) eventlist = generateEventListFromFile( filename ) print("The eventlist:", eventlist) # Use the event list to simulate the market behavior. simulateCheckoutLine( eventlist ) # Be sure to comment this out before submitting. main()