Submitting a Mortgage Application¶
Faisal Qureshi
faisal.qureshi@ontariotechu.ca
http://www.vclab.ca
Copyright information¶
© Faisal Qureshi
License¶
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.Acknowledgments¶
This example is taken from https://simpy.readthedocs.io/en/latest/examples/movie_renege.html
In [23]:
import random
import simpy
from typing import NamedTuple, List, Dict, Optional
In [31]:
def moviegoer(env, movie, num_tickets, theater):
"""A moviegoer tries to by a number of tickets (*num_tickets*) for
a certain *movie* in a *theater*.
If the movie becomes sold out, she leaves the theater. If she gets
to the counter, she tries to buy a number of tickets. If not enough
tickets are left, she argues with the teller and leaves.
If at most one ticket is left after the moviegoer bought her
tickets, the *sold out* event for this movie is triggered causing
all remaining moviegoers to leave.
"""
with theater.counter.request() as my_turn:
# Wait until it's our turn or until the movie is sold out
result = yield my_turn | theater.sold_out[movie]
# Check if it's our turn or if movie is sold out
if my_turn not in result:
theater.num_renegers[movie] += 1
return
# Check if enough tickets left.
if theater.available[movie] < num_tickets:
# Moviegoer leaves after some discussion
yield env.timeout(0.5)
return
# Buy tickets
theater.available[movie] -= num_tickets
if theater.available[movie] < sellout_threshold:
# Trigger the "sold out" event for the movie
theater.sold_out[movie].succeed()
theater.when_sold_out[movie] = env.now
theater.available[movie] = 0
yield env.timeout(1)
In [32]:
def customer_arrivals(env, theater):
"""Create new *moviegoers* until the sim time reaches 120."""
while True:
yield env.timeout(random.expovariate(1 / 0.5))
movie = random.choice(theater.movies)
num_tickets = random.randint(1, 6)
if theater.available[movie]:
env.process(moviegoer(env, movie, num_tickets, theater))
In [33]:
class Theater(NamedTuple):
counter: simpy.Resource
movies: List[str]
available: Dict[str, int]
sold_out: Dict[str, simpy.Event]
when_sold_out: Dict[str, Optional[float]]
num_renegers: Dict[str, int]
In [34]:
seed = 42
num_tickets = 50 # Number of tickets per movie
sellout_threshold = 2 # Fewer tickets than this is a sellout
sim_time = 120 # Simulate until
In [35]:
random.seed(seed)
env = simpy.Environment()
In [36]:
# Create movie theater
movies = ['Python Unchained', 'Kill Process', 'Pulp Implementation']
theater = Theater(
counter=simpy.Resource(env, capacity=1),
movies=movies,
available={movie: num_tickets for movie in movies},
sold_out={movie: env.event() for movie in movies},
when_sold_out={movie: None for movie in movies},
num_renegers={movie: 0 for movie in movies},
)
In [30]:
env.process(customer_arrivals(env, theater))
env.run(until=sim_time)
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[24], line 31, in moviegoer(env, movie, num_tickets, theater) 30 theater.available[movie] -= num_tickets ---> 31 if theater.available[movie] < SELLOUT_THRESHOLD: 32 # Trigger the "sold out" event for the movie 33 theater.sold_out[movie].succeed() NameError: name 'SELLOUT_THRESHOLD' is not defined The above exception was the direct cause of the following exception: NameError Traceback (most recent call last) Cell In[30], line 2 1 env.process(customer_arrivals(env, theater)) ----> 2 env.run(until=sim_time) File ~/venv/sm/lib/python3.11/site-packages/simpy/core.py:246, in Environment.run(self, until) 244 try: 245 while True: --> 246 self.step() 247 except StopSimulation as exc: 248 return exc.args[0] # == until.value File ~/venv/sm/lib/python3.11/site-packages/simpy/core.py:204, in Environment.step(self) 202 exc = type(event._value)(*event._value.args) 203 exc.__cause__ = event._value --> 204 raise exc NameError: name 'SELLOUT_THRESHOLD' is not defined
In [37]:
for movie in movies:
if theater.sold_out[movie]:
sellout_time = theater.when_sold_out[movie]
num_renegers = theater.num_renegers[movie]
print(
f'Movie "{movie}" sold out {sellout_time:.1f} minutes '
f'after ticket counter opening.'
)
print(f' Number of people leaving queue when film sold out: {num_renegers}')
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[37], line 6 3 sellout_time = theater.when_sold_out[movie] 4 num_renegers = theater.num_renegers[movie] 5 print( ----> 6 f'Movie "{movie}" sold out {sellout_time:.1f} minutes ' 7 f'after ticket counter opening.' 8 ) 9 print(f' Number of people leaving queue when film sold out: {num_renegers}') TypeError: unsupported format string passed to NoneType.__format__