Defining Processes in the Simulation
In this lesson, you’re going to set up your moviegoer to move through the processes of the environment. To do this, go ahead and make a new function called
go_to_movies(), which will take in the
env (environment), a
moviegoer, and the
theater as parameters.
The first step for the moviegoer is to arrive at the theater. To keep track of this arrival time, you can go ahead and make a new variable called
arrival_time and set this equal to the
00:31 Now that the moviegoer is at the theater, they’re going to have to go through the processes. So they’ll need to buy a ticket, they’ll need to have that ticket checked, and then they’ll have to decide if they’re going to get food or not.
So start off with buying a ticket. Each of these processes are going to have the
moviegoer request a resource to complete that process. If all the resources are tied up, the
moviegoer will need to wait until a resource becomes free before completing that process. A way to simulate this is by making the function into a generator using the
yield keyword, which will retain state of the function as the
Let’s see what this looks like, and then discuss what’s happening. So go ahead and say
with theater.cashier.request(), then we’ll call this
You’ll want to yield that
request and then yield the
theater, and then call that
.purchase_ticket() method and pass in the
So, there’s quite a bit going on here, and we can break it down a little bit. In these first two lines, you’re using the
cashier.request() method, which will check to see if there’s a
.cashier resource available. And if not, then the
moviegoer will wait. Once one is available, this function will then yield the process of purchasing that ticket.
So, a big takeaway here is the
moviegoer function here is what actually links purchasing the ticket with a
.cashier. If you were to put
.usher here, then the moviegoer would be looking for
.usher resources to purchase tickets from. Once the process is completed, you could call the
.release() method, which would mark this
.cashier resource as being free, but by using
with, as soon as this code block completes, the
.cashier will be freed up.
If you’re not familiar with how the
yield keyword or generators work, this block of code probably looks like magic. You can think of
yield as a return statement, which then is returning these methods when you call
go_to_movies(), but allowing the function to continue on each time it’s called. Getting too deep into
yield is beyond the scope of this course, so feel free to check out a link to a fantastic guide in the description if you need a refresher on how these statements work. Okay!
So now that the moviegoer has the ticket, it’s time to go through the other steps of the process. And like before, the next steps are pretty similar for having the ticket checked and going to concessions. So to check the ticket, you can say
with theater and then call the
.usher and then call
.request() as request.
You’ll first yield that
request, and then you’ll yield the
theater.check_ticket(), and then pass in
And I noticed an autocomplete issue here—
.usher should be singular, so I’ll get rid of that
s. Get rid of this
s, and then also
And to keep things consistent, let’s say
# check ticket.
So now for the concessions area, things are a little bit different. I’m going to say
# buy food here. And because each moviegoer is either going to decide to buy food or not to buy food, you’re going to need to add some randomness to how this works.
So you can say something like
if random.choice() and then just pass in a list of
[True, False], and this is just assuming a 50/50 split between either buying food or not buying food. Now you can put in your
with block, so
with theater.server.request() as request:.
Go ahead and yield that
request, and then once a
.server is available, we’ll say
env.process(), and then the
theater, and then
.sell_food() to the
So each time the
moviegoer gets to this step, it will decide if they’re going to buy food or not, and if they are, it’ll go through and run this block here. So, once they’ve made it past that, it’s time for them to go to their seat, and we’ll assume this happens instantly. And the wait is complete, so you can say your list of
wait_times can now append. Then here, take that
env.now property, and then subtract the
And this will calculate their wait time in minutes by comparing the time it is now to the time they got there. Okay! So now that this function is defined, the
moviegoer knows what the processes for going into the theater and getting to their seat is. They have to buy the ticket, they have to have their ticket checked, and then they have to decide if they’re going to buy food—and if they are, they have to go get that food.
They have the process and they’ll also pay attention to how long it takes them to go through that process. And then append that to
wait_times. All right!
05:35 In the next lesson, you’re going to write a function that will actually run the simulation.
Become a Member to join the conversation.
gileswintle on Dec. 19, 2020
hi, I see that you are writing your classes as inheriting from object. Is this course in Python 2? If not, why do we need to inherit from object?