At the moment I am creating doctors as following:
JavaScript
x
2
1
doctor = simpy.Resource(self.env, capacity=3)
2
These doctors are requested for a flow of patients using the following:
JavaScript
1
4
1
with self.doctor.request() as req:
2
yield req2
3
*patient encounter*
4
What I would like to do, is initialize the doctors with some kind of fatigue level (and other characteristics) like:
JavaScript
1
9
1
# Class representing a doctor and their characteristics
2
class Doctor(object):
3
def __init__(self, env, id, exp_level, fatigue):
4
self.env = env
5
self.id = id
6
self.exp_level = exp_level
7
self.fatigue = fatigue
8
self.isAvailable = True
9
Then in the encounter I would like to access the doctor to add fatigue such as:
JavaScript
1
5
1
with self.doctor.request() as req:
2
yield req2
3
*patient encounter*
4
self.doctor.fatigue += 5
5
Where once the fatigue crosses a threshold the doctor goes on break and the fatigue is reset, such as:
JavaScript
1
6
1
def monitor_break(self):
2
while True:
3
if Doctor.fatigue > 9:
4
Doctor.fatigue = 0
5
yield self.env.timeout(15)
6
Any idea on how to do this?
Advertisement
Answer
First I would use a store for your docs instead of using a resource. Second I would decorate the store with a get override to check if the doc needs a nap
something like this
JavaScript
1
132
132
1
"""
2
A simple sim where Doctors put themselves on break when they get tired
3
4
Programmer Michael R. Gibbs
5
"""
6
7
import simpy
8
import random
9
10
class Doctor():
11
"""
12
Doctor that get tired
13
"""
14
15
def __init__(self, env, id):
16
self.env = env
17
self.id = id
18
self.fatigue = 0
19
20
class Doc_Pool():
21
"""
22
decorates a simpy store
23
to chekc a doc's fatigue level
24
and doing a timeout if fatigue is too
25
high before returning the doc to the pool
26
"""
27
28
def __init__(self, env, num_of_docs, max_fatigue):
29
30
self.env = env
31
32
self.store = simpy.Store(env)
33
self.store.items = [Doctor(env, i+1) for i in range(num_of_docs)]
34
self.max_fatigue = max_fatigue
35
36
def get(self):
37
"""
38
get a doc from the real store
39
"""
40
41
return self.store.get()
42
43
def put(self, doc):
44
"""
45
put a doc in the store
46
unless the doc needs a break
47
"""
48
49
if doc.fatigue > self.max_fatigue:
50
# needs a break
51
self.env.process(self._doc_timeout(doc))
52
53
else:
54
self.store.put(doc)
55
56
57
def _doc_timeout(self, doc):
58
"""
59
gives the doc a break, then put in store
60
"""
61
62
print(f'{self.env.now:.0f} doctor {doc.id} starting break with fatigue {doc.fatigue:0.2f}')
63
64
yield self.env.timeout(doc.fatigue)
65
66
doc.fatigue = 0
67
68
self.store.put(doc)
69
70
print(f'{self.env.now:.0f} doctor {doc.id} ending break')
71
72
73
class Patient():
74
"""
75
Simple class to track patients
76
"""
77
78
next_id = 1
79
80
def __init__(self):
81
82
self.id = self.get_next_id()
83
84
@classmethod
85
def get_next_id (cls):
86
id =cls.next_id
87
cls.next_id += 1
88
return id
89
90
def gen_pats(env, doc_store):
91
"""
92
Generates the arrival off patients
93
and queue them up for a doctor visit
94
"""
95
96
while True:
97
pat = Patient()
98
print(f'{env.now:.0f} patient {pat.id} has arrived')
99
100
yield env.timeout(random.uniform(1,5))
101
102
env.process(doc_visit(env, pat, doc_store))
103
104
def doc_visit(env, pat, doc_store):
105
"""
106
gets a doc, do visit, add fatigue to doc, end visit
107
"""
108
109
doc = yield doc_store.get()
110
111
print(f'{env.now:.0f} patient {pat.id} is visiting doctor {doc.id}')
112
113
env.timeout(random.uniform(1,6))
114
115
doc.fatigue += random.uniform(1,5)
116
117
doc_store.put(doc)
118
119
print(f'{env.now:.0f} patient {pat.id} visiting doctor {doc.id} has ended')
120
121
122
# boot up sim
123
env = simpy.Environment()
124
125
doc_store = Doc_Pool(env, 3, 10)
126
127
env.process(gen_pats(env, doc_store))
128
129
env.run(200)
130
131
print('end of simulation')
132