I tried to solve this error, but I haven't been able to solve this error for a week.
The hospital has beds at ED rooms, ED1 and ED2, and when the available beds here are used up and there are no more beds, I'm going to implement support for Extra beds in one of the two rooms needed. At this time, I tried to implement by using "AnyOf" for the assignment of a bed to the new patient when the beds in the hospital room ED1, ED2, and Extra are all in use.
However, I got an error as below.
AttributeError: 'Bed' object has no attribute 'env'
Please help me solve this error.
My simplified code is below.
Thanks.
import simpy
import random
from dataclasses import dataclass
from simpy.events import AnyOf
@dataclass
class BedAtt:
name: str
type: str
capacity: int
class Pre_Define:
allbeds = [
BedAtt('ED1', 'ED', 5),
BedAtt('ED2', 'ED', 14),
BedAtt('Extra', 'ED', 10),
BedAtt('IU', 'IU', 15),
]
pt_inter_arrival = 6
m_triage = 17
m_ED_physician = 23
m_IUbed_occupied = 30
m_bed_cleaning = 50
m_additionaltest = 150
n_nurses = 5
n_ed_physician = 5
n_bed_cleanler = 5
n_transporter = 5
prob_ED_Bed1 = 30
prob_ED_Bed2 = 70
prob_Additionaltest = 60
prob_Dis = 75
warmup_period = 0
sim_duration = 720
class Bed():
def __init__(self, id, bed_type: str, care_area: str, name: str):
self.id = id
self.type = bed_type
self.care_area = care_area
self.name = name
class Patient:
def __init__(self, p_id: int) -> None:
self.id = p_id
self.type = None
self.care_area = None
self.name = None
self.admission_decision = ""
self.addtional_test_boolean = None
# For copying from assigned Bed information
self.edbed_info = None
self.iubed_info = None
self.bed_id = None
self.bed_care_area = None
self.bed_name = None
self.bed_status = None
def addtional_test(self):
additionaltest_prob = random.uniform(0, 1)*100
if additionaltest_prob <= Pre_Define.prob_Additionaltest:
self.addtional_test_boolean = True
def admin_decision(self):
admin_decision_prob = random.uniform(0, 1)
if admin_decision_prob <= Pre_Define.prob_Dis/100:
self.admission_decision = "IU"
else:
self.admission_decision = "Admit"
def ed_care_area(self):
edcarearea_decision_prob = random.uniform(0, 1)
if edcarearea_decision_prob <= Pre_Define.prob_ED_Bed1/100:
self.care_area = "ED1"
else:
self.care_area = "ED2"
class EDModel:
def __init__(self, run_number):
self.run_number = run_number
self.env = simpy.Environment()
self.pt_counter = 0
self.tg = simpy.Resource(self.env, capacity = Pre_Define.n_nurses)
self.physician = simpy.Resource(self.env, capacity = Pre_Define.n_ed_physician)
self.bed_cleaner = simpy.Resource(self.env, capacity = Pre_Define.n_bed_cleanler)
self.bed_transporter = simpy.Resource(self.env, capacity = Pre_Define.n_transporter)
self.clean_beds = {
care_area.name: simpy.Store(self.env, capacity=care_area.capacity)
for care_area in Pre_Define.allbeds
}
self.clean_request_Q = simpy.Store(
self.env,
capacity = sum(care_area.capacity for care_area in Pre_Define.allbeds)
)
for care_area in Pre_Define.allbeds:
self.clean_beds[care_area.name].items = [
Bed(i, care_area.type, care_area=care_area.name, name=f'{care_area.name}_bed_{i}')
for i in range(1, care_area.capacity + 1)
]
def generate_pt_arrivals(self):
while True:
pt = Patient(self.pt_counter)
yield self.env.timeout(Pre_Define.pt_inter_arrival)
self.env.process(self.ed_process(pt))
self.pt_counter += 1
def bed_cleaners(self, cleaner_id):
while True:
bed = yield self.clean_request_Q.get()
with self.bed_cleaner.request() as bedreq:
yield bedreq
yield self.env.timeout(Pre_Define.m_bed_cleaning)
print(f'{self.env.now:.2f} bed_cleaners complete {bed.name} cleaning')
yield self.clean_beds[bed.care_area].put(bed)
print(f'{self.env.now:.2f} bed_cleaners put {bed.name} to {bed.care_area}')
def ed_process(self, pt: Patient):
pt.ed_care_area()
print(f'{self.env.now:.2f} patient {pt.id} {pt.care_area} arrival')
with self.tg.request() as req:
yield req
yield self.env.timeout(Pre_Define.m_triage)
edbed = yield self.clean_beds[pt.care_area].get()
#print('edbed:', edbed.name)
extrabed = yield self.clean_beds['Extra'].get()
print('Extra:', extrabed.name)
seledted_bed_ = yield AnyOf(self.env, [edbed, extrabed])
print('seledted_bed_: ', seledted_bed_)
if edbed in seledted_bed_:
# need to remove the extra bed
if extrabed in seledted_bed_:
# got two beds but extra bed back
self.clean_beds['Extra'].put(seledted_bed_)
else:
# stil need to cancel req
extrabed.cancel()
else:
# need to deal with the extra bed
if extrabed in seledted_bed_:
edbed = extrabed
print(f'{self.env.now:.2f} ED patient {pt.id} {pt.care_area} get a bed: {edbed.name}')
with self.physician.request() as req:
yield req
yield self.env.timeout(Pre_Define.m_ED_physician)
pt.addtional_test()
if pt.addtional_test_boolean:
yield self.env.timeout(Pre_Define.m_additionaltest)
pt.admin_decision()
if pt.admission_decision == 'IU':
iubed = yield self.clean_beds[pt.admission_decision].get()
pt.iubed_info = iubed
print(f'{self.env.now:.2f} IU patient {pt.id} get a bed: {iubed.name}')
with self.bed_transporter.request() as transreq:
yield transreq
print(f'{self.env.now:.2f} IU patient {pt.id} return ED bed: {edbed.name}')
yield self.clean_request_Q.put(edbed)
yield self.env.timeout(Pre_Define.m_IUbed_occupied)
print(f'{self.env.now:.2f} patient {pt.id} IU and return IU bed: {iubed.name}')
yield self.clean_request_Q.put(iubed)
else:
print(f'{self.env.now:.2f} patient {pt.id} discharge and return ED bed: {edbed.name}')
yield self.clean_request_Q.put(edbed)
def run(self):
self.env.process(self.generate_pt_arrivals())
for i in range(Pre_Define.n_bed_cleanler):
self.env.process(self.bed_cleaners(i+1)) #, pt
self.env.run(until = Pre_Define.warmup_period + Pre_Define.sim_duration)
EDModel(1).run()