import os import django # Setup Django (keep or remove if you convert this to a management command) os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hospital_management.settings') django.setup() import random import uuid from datetime import datetime, timedelta, date, time as dt_time from django.utils import timezone from django.core.exceptions import ObjectDoesNotExist from inpatients.models import Ward, Bed, Admission, Transfer, DischargeSummary from accounts.models import User from patients.models import PatientProfile from core.models import Tenant # Facility management FKs from facility_management.models import Building, Floor, Asset # Optional: Operating Room (if your app exists); otherwise we’ll leave OR unset try: from operating_theatre.models import OperatingRoom except Exception: OperatingRoom = None # ------------------------------ # Saudi-inspired constants # ------------------------------ SAUDI_WARD_NAMES = [ 'King Fahd Ward', 'King Abdulaziz Ward', 'Prince Sultan Ward', 'Princess Noura Ward', 'Al-Faisal Ward', 'Al-Rashid Ward', 'Al-Salam Ward', 'Al-Noor Ward', 'Al-Shifa Ward', 'Al-Amal Ward', 'Al-Rahma Ward', 'Al-Baraka Ward', 'Cardiac Care Unit', 'Intensive Care Unit', 'Pediatric ICU', 'Neonatal ICU', 'Medical Ward A', 'Medical Ward B', 'Surgical Ward A', 'Surgical Ward B', 'Orthopedic Ward', 'Maternity Ward', 'Pediatric Ward', 'Oncology Ward' ] SAUDI_SPECIALTIES = [ Ward.WardSpecialty.GENERAL_MEDICINE, Ward.WardSpecialty.SURGERY, Ward.WardSpecialty.CARDIOLOGY, Ward.WardSpecialty.NEUROLOGY, Ward.WardSpecialty.ONCOLOGY, Ward.WardSpecialty.PEDIATRICS, Ward.WardSpecialty.OBSTETRICS, Ward.WardSpecialty.GYNECOLOGY, Ward.WardSpecialty.ORTHOPEDICS, Ward.WardSpecialty.PSYCHIATRY, Ward.WardSpecialty.EMERGENCY, Ward.WardSpecialty.CRITICAL_CARE, Ward.WardSpecialty.REHABILITATION, Ward.WardSpecialty.OTHER ] SAUDI_WINGS = ['North Wing', 'South Wing', 'East Wing', 'West Wing', 'Central Wing', 'VIP Wing', 'Family Wing', 'Isolation Wing'] SAUDI_COMMON_DIAGNOSES = [ 'Diabetes Mellitus Type 2', 'Hypertension', 'Coronary Artery Disease', 'Chronic Kidney Disease', 'Heart Failure', 'Pneumonia', 'Gastritis', 'Cholecystitis', 'Appendicitis', 'Urinary Tract Infection', 'Acute Myocardial Infarction', 'Stroke', 'Pulmonary Embolism', 'Deep Vein Thrombosis', 'Sepsis', 'Acute Renal Failure', 'Chronic Obstructive Pulmonary Disease', 'Asthma', 'Anemia' ] SAUDI_SURGICAL_PROCEDURES = [ 'Coronary Artery Bypass Graft', 'Percutaneous Coronary Intervention', 'Appendectomy', 'Cholecystectomy', 'Hernia Repair', 'Hip Replacement', 'Knee Replacement', 'Cataract Surgery', 'Thyroidectomy', 'Prostatectomy', 'Hysterectomy', 'Cesarean Section', 'Arthroscopy', 'Endoscopy', 'Colonoscopy', 'Angioplasty' ] SAUDI_MEDICATIONS = [ 'Metformin', 'Insulin', 'Lisinopril', 'Amlodipine', 'Atorvastatin', 'Aspirin', 'Warfarin', 'Furosemide', 'Omeprazole', 'Paracetamol', 'Amoxicillin', 'Ciprofloxacin', 'Prednisolone', 'Morphine', 'Tramadol' ] # ------------------------------ # Helpers # ------------------------------ def random_ratio_value(): # return nurse-to-patient ratio as float (e.g., 1:4 -> 0.25) patients_per_nurse = random.choice([4, 5, 6, 8]) return round(1.0 / patients_per_nurse, 3) def pick_tenant_users(tenant, roles=None, limit=20): qs = User.objects.filter(tenant=tenant, is_active=True) if roles: qs = qs.filter(employee_profile__role__in=roles) return list(qs[:limit]) def ensure_building_and_floors(tenant, floors_count=5): """ Ensure at least 1 building with a few floors exists for the tenant. Returns (building, floors_list) """ bld = Building.objects.filter(tenant=tenant).first() if not bld: # Minimal building compatible with your facility_management.Building model bld = Building.objects.create( tenant=tenant, name=f"{tenant.name} Medical Tower", code=f"T{tenant.id}-BLD-01", address=f"{tenant.name} Campus, KSA", building_type=Building.BuildingType.CLINICAL ) floors = list(Floor.objects.filter(building=bld).order_by('floor_number')) if not floors: for n in range(floors_count): floors.append(Floor.objects.create( building=bld, floor_number=n, name=f"Level {n}", )) return bld, floors def any_building_floor(tenant): b = Building.objects.filter(tenant=tenant).order_by('?').first() if not b: b, _floors = ensure_building_and_floors(tenant) f = Floor.objects.filter(building=b).order_by('?').first() if not f: # create one more floor f = Floor.objects.create(building=b, floor_number=0, name="Level 0") return b, f def friendly_phone(): return f"+966-11-{random.randint(100, 999)}-{random.randint(1000, 9999)}" def ward_id_for(tenant): # unique per (tenant, ward_id) return f"WRD-{timezone.now().strftime('%Y%m%d')}-{random.randint(1000,9999)}" # ------------------------------ # Ward creation (FK to Building/Floor) # ------------------------------ def create_saudi_wards(tenants, wards_per_tenant=12): wards = [] for tenant in tenants: # Ensure at least one building/floor exists building, floor = any_building_floor(tenant) nurses = pick_tenant_users(tenant, roles=['NURSE', 'NURSE_PRACTITIONER'], limit=30) physicians = pick_tenant_users(tenant, roles=['PHYSICIAN', 'PHYSICIAN_ASSISTANT'], limit=30) created_by = (nurses or physicians or pick_tenant_users(tenant, None, 1) or [None])[0] for _ in range(wards_per_tenant): name = random.choice(SAUDI_WARD_NAMES) # Make name unique within tenant if needed orig = name suffix = 1 while Ward.objects.filter(tenant=tenant, name=name).exists(): name = f"{orig} {suffix}" suffix += 1 # Choose building/floor (random per ward) bld, flr = any_building_floor(tenant) total_beds = random.randint(20, 60) private_rooms = random.randint(5, 15) semi_private_rooms = random.randint(8, 20) shared_rooms = max(0, total_beds - private_rooms - (semi_private_rooms * 2)) ward = Ward.objects.create( tenant=tenant, ward_id=ward_id_for(tenant), name=name, description=f"Specialized ward providing comprehensive inpatient care", ward_type=random.choice([w[0] for w in Ward.WardType.choices]), specialty=random.choice(SAUDI_SPECIALTIES), total_beds=total_beds, private_rooms=private_rooms, semi_private_rooms=semi_private_rooms, shared_rooms=shared_rooms, building=bld, floor=flr, wing=random.choice(SAUDI_WINGS), nurse_manager=(random.choice(nurses) if nurses else None), min_nurses_day=random.randint(8, 15), min_nurses_night=random.randint(5, 10), nurse_to_patient_ratio=random_ratio_value(), equipment_list=[ 'Cardiac Monitors', 'IV Pumps', 'Ventilators', 'Defibrillators', 'Oxygen Supply', 'Suction Units', 'Patient Beds', 'Wheelchairs' ], special_features=[ 'Prayer Room', 'Family Waiting Area', 'Isolation Rooms', 'Nurse Station', 'Clean Utility Room', 'Dirty Utility Room' ], admission_criteria="Patients requiring specialized inpatient care", age_restrictions=random.choice([ {"min_age": 0, "max_age": None}, {"min_age": 16, "max_age": None}, {"min_age": 0, "max_age": 18}, ]), gender_restrictions=random.choice([g[0] for g in Ward.GenderRestriction.choices]), is_active=True, is_accepting_admissions=random.choice([True, True, True, False]), closure_reason=None, phone_number=friendly_phone(), extension=f"{random.randint(1000, 9999)}", created_by=created_by ) # Attending physicians if physicians: ward.attending_physicians.set(random.sample(physicians, k=min(len(physicians), random.randint(2, 5)))) wards.append(ward) print(f"Created {wards_per_tenant} wards for {tenant.name}") return wards # ------------------------------ # Beds (FK to Ward) + equipment M2M to Assets in same building # ------------------------------ def create_saudi_beds(wards): beds = [] for ward in wards: bed_types = [b[0] for b in Bed.BedType.choices] room_types = [r[0] for r in Bed.RoomType.choices] statuses = [s[0] for s in Bed.BedStatus.choices] cleaning_levels = [c[0] for c in Bed.CleaningLevel.choices] positions = [p[0] for p in Bed.BedPosition.choices] # Nearby facility assets (optional) assets_qs = Asset.objects.filter(building=ward.building) ward_floor_num = ward.floor.floor_number if hasattr(ward.floor, "floor_number") else 0 for num in range(1, ward.total_beds + 1): bed_number = f"{ward.name[:3].upper()}-{num:03d}" room_type = random.choice(room_types) status = random.choice(statuses) # Room number: floor digit + random room_number = f"{ward_floor_num}{random.randint(10, 99)}" # Bed position logic based on room type if room_type == Bed.RoomType.SHARED: pos_choices = positions[:4] # A-D elif room_type == Bed.RoomType.SEMI_PRIVATE: pos_choices = positions[:2] # A-B else: pos_choices = [positions[0]] # A bed_position = random.choice(pos_choices) bed = Bed.objects.create( ward=ward, bed_number=bed_number, room_number=room_number, bed_type=random.choice(bed_types), is_operational=True, is_active=True, is_out_of_service=False, room_type=room_type, status=status, current_admission=None, occupied_since=(timezone.now() - timedelta(days=random.randint(1, 30))) if status == 'OCCUPIED' else None, reserved_until=(timezone.now() + timedelta(hours=random.randint(1, 24))) if (status == 'RESERVED' and random.choice([True, False])) else None, features=[ 'Adjustable Height', 'Side Rails', 'Trendelenburg', 'Reverse Trendelenburg', 'Patient Controls', 'LED Reading Light' ], last_maintenance=timezone.now() - timedelta(days=random.randint(7, 90)), next_maintenance=timezone.now() + timedelta(days=random.randint(30, 180)), maintenance_notes="Routine maintenance completed" if random.choice([True, False]) else None, last_cleaned=timezone.now() - timedelta(hours=random.randint(1, 24)), cleaned_by=None, cleaning_level=random.choice(cleaning_levels), blocked_reason="Maintenance required" if status == 'BLOCKED' else None, blocked_by=None, blocked_until=(timezone.now() + timedelta(hours=random.randint(2, 48))) if status == 'BLOCKED' else None, bed_position=bed_position, created_by=ward.created_by ) # Attach up to 2 assets in same building if assets_qs.exists() and random.random() < 0.6: bed.equipment.add(*assets_qs.order_by('?')[:random.randint(1, 2)]) beds.append(bed) print(f"Created {len(beds)} beds across all wards") return beds # ------------------------------ # Admissions (uses enums + FKs) and sets bed occupancy correctly # ------------------------------ def create_saudi_admissions(tenants, beds, admissions_per_tenant=100): admissions = [] for tenant in tenants: patients = list(PatientProfile.objects.filter(tenant=tenant)) physicians = pick_tenant_users(tenant, roles=['PHYSICIAN', 'PHYSICIAN_ASSISTANT'], limit=50) nurses = pick_tenant_users(tenant, roles=['NURSE', 'NURSE_PRACTITIONER'], limit=50) tenant_beds = [b for b in beds if b.ward.tenant_id == tenant.id] if not patients or not physicians or not tenant_beds: print(f"⚠️ Skipping tenant {tenant.name}: patients={len(patients)}, physicians={len(physicians)}, beds={len(tenant_beds)}") continue creator = (physicians or nurses or [None])[0] for _ in range(admissions_per_tenant): patient = random.choice(patients) admitting_physician = random.choice(physicians) attending_physician = random.choice(physicians) current_bed = random.choice(tenant_beds) current_ward = current_bed.ward admission_dt = timezone.now() - timedelta(days=random.randint(0, 30)) status = random.choice([s[0] for s in Admission.AdmissionStatus.choices]) discharge_dt = None discharge_disp = None if status == Admission.AdmissionStatus.DISCHARGED: discharge_dt = admission_dt + timedelta(days=random.randint(1, 14)) discharge_disp = random.choice([d[0] for d in Admission.DischargeDisposition.choices]) admission = Admission.objects.create( tenant=tenant, patient=patient, admission_datetime=admission_dt, admission_type=random.choice([t[0] for t in Admission.AdmissionType.choices]), admission_source=random.choice([s[0] for s in Admission.AdmissionSource.choices]), chief_complaint=random.choice([ 'Chest pain', 'Shortness of breath', 'Abdominal pain', 'Fever and chills', 'Weakness', 'Nausea and vomiting', 'Headache', 'Dizziness', 'Joint pain', 'Back pain' ]), admitting_diagnosis=random.choice(SAUDI_COMMON_DIAGNOSES), secondary_diagnoses=[random.choice(SAUDI_COMMON_DIAGNOSES) for _ in range(random.randint(0, 3))], admitting_physician=admitting_physician, attending_physician=attending_physician, current_ward=current_ward, current_bed=current_bed, status=status, priority=random.choice([p[0] for p in Admission.AdmissionPriority.choices]), acuity_level=random.randint(1, 5), insurance_verified=random.choice([True, False]), authorization_number=(f"AUTH-{random.randint(100000, 999999)}" if random.choice([True, False]) else None), estimated_length_of_stay=random.randint(2, 14), discharge_planning_started=random.choice([True, False]), discharge_planner=(random.choice(nurses) if nurses and random.random() < 0.5 else None), anticipated_discharge_date=admission_dt.date() + timedelta(days=random.randint(1, 10)), discharge_datetime=discharge_dt, discharge_disposition=discharge_disp, isolation_required=random.choice([True, False, False, False]), isolation_type=(random.choice([i[0] for i in Admission.IsolationType.choices]) if random.random() < 0.25 else None), special_needs=(['Interpreter services', 'Dietary restrictions', 'Mobility assistance'] if random.random() < 0.3 else []), allergies=(random.sample(['Penicillin', 'Sulfa drugs', 'Shellfish', 'Latex', 'Contrast dye'], random.randint(0, 3))), alerts=(random.sample(['Fall risk', 'Suicide risk', 'Flight risk', 'Combative', 'Infection control', 'Allergy alert'], random.randint(0, 3))), code_status=random.choice([c[0] for c in Admission.CodeStatus.choices]), advance_directive=random.choice([True, False]), healthcare_proxy=(None if random.random() < 0.7 else "Next of kin on file"), admission_notes=f"Admitted with {random.choice(SAUDI_COMMON_DIAGNOSES).lower()} requiring inpatient management", created_by=creator ) # Consulting physicians if physicians: admission.consulting_physicians.set(random.sample(physicians, random.randint(0, min(3, len(physicians))))) # Update bed status according to admission status if status in [Admission.AdmissionStatus.ADMITTED, Admission.AdmissionStatus.TRANSFERRED]: current_bed.status = Bed.BedStatus.OCCUPIED current_bed.current_admission = admission current_bed.occupied_since = admission_dt current_bed.reserved_until = None current_bed.save() elif status == Admission.AdmissionStatus.PENDING: # reserve a pending bed sometimes if random.random() < 0.5: current_bed.status = Bed.BedStatus.RESERVED current_bed.reserved_until = admission_dt + timedelta(hours=random.randint(2, 12)) current_bed.save() admissions.append(admission) print(f"Created {admissions_per_tenant} admissions for {tenant.name}") return admissions # ------------------------------ # Transfers (matches enums, timestamps; requested_datetime is auto_now_add) # ------------------------------ def create_saudi_transfers(admissions): transfers = [] for admission in random.sample(admissions, int(len(admissions) * 0.3) or 0): # Find an available bed in a different ward of same tenant available_beds = Bed.objects.filter( ward__tenant=admission.tenant, status=Bed.BedStatus.AVAILABLE ).exclude(ward=admission.current_ward) if not available_beds.exists(): continue to_bed = available_beds.order_by('?').first() to_ward = to_bed.ward # Requesting user (prefer clinical roles) requesters = pick_tenant_users(admission.tenant, roles=['PHYSICIAN', 'NURSE', 'NURSE_PRACTITIONER', 'PHYSICIAN_ASSISTANT'], limit=50) or pick_tenant_users(admission.tenant, None, 5) if not requesters: continue requested_by = random.choice(requesters) status = random.choice([s[0] for s in Transfer.TransferStatus.choices]) scheduled_datetime = timezone.now() + timedelta(hours=random.randint(1, 12)) if status in ['APPROVED', 'SCHEDULED', 'IN_PROGRESS', 'COMPLETED'] else None actual_datetime = scheduled_datetime + timedelta(minutes=random.randint(5, 60)) if status in ['IN_PROGRESS', 'COMPLETED'] else None transfer = Transfer.objects.create( admission=admission, patient=admission.patient, transfer_type=random.choice([t[0] for t in Transfer.TransferType.choices]), from_ward=admission.current_ward, from_bed=admission.current_bed, to_ward=to_ward, to_bed=to_bed, scheduled_datetime=scheduled_datetime, actual_datetime=actual_datetime, status=status, reason=random.choice([ 'Clinical deterioration', 'Need for higher level of care', 'Bed availability', 'Specialist consultation required', 'Patient preference', 'Isolation requirements' ]), priority=random.choice([p[0] for p in Transfer.TransferPriority.choices]), requested_by=requested_by, approved_by=None, completed_by=None, transport_method=random.choice([m[0] for m in Transfer.TransportMethod.choices]), equipment_needed=(['IV pole', 'Oxygen tank', 'Monitor'] if random.random() < 0.4 else []), supplies_needed=(['Medications', 'Patient chart', 'Personal items'] if random.random() < 0.4 else []), patient_condition=random.choice([pc[0] for pc in Transfer.TransferPatientCondition.choices]), vital_signs={ 'blood_pressure': f"{random.randint(90, 180)}/{random.randint(60, 100)}", 'heart_rate': random.randint(60, 120), 'respiratory_rate': random.randint(12, 24), 'temperature': round(random.uniform(36.0, 39.0), 1), 'oxygen_saturation': random.randint(92, 100) }, handoff_report=f"Handoff given to receiving nurse; patient for {random.choice(['specialized care', 'higher acuity monitoring', 'isolation'])}", medications_transferred=random.sample(SAUDI_MEDICATIONS, random.randint(0, 4)), delay_reason=("Bed not ready" if status in ['APPROVED', 'SCHEDULED'] and random.random() < 0.3 else None), complications=("None noted" if status == 'COMPLETED' else None), notes=(f"Transfer completed successfully" if status == 'COMPLETED' else None) ) # Transport team nurses = pick_tenant_users(admission.tenant, roles=['NURSE', 'NURSE_PRACTITIONER'], limit=20) if nurses: transfer.transport_team.set(random.sample(nurses, k=min(len(nurses), random.randint(1, 3)))) # If completed, update bed occupancy and admission location if status == 'COMPLETED': # free from_bed if transfer.from_bed: transfer.from_bed.status = Bed.BedStatus.AVAILABLE transfer.from_bed.current_admission = None transfer.from_bed.occupied_since = None transfer.from_bed.save() # occupy to_bed to_bed.status = Bed.BedStatus.OCCUPIED to_bed.current_admission = admission to_bed.occupied_since = actual_datetime or timezone.now() to_bed.save() # update admission location admission.current_ward = to_ward admission.current_bed = to_bed admission.save(update_fields=['current_ward', 'current_bed']) transfers.append(transfer) print(f"Created {len(transfers)} transfers") return transfers # ------------------------------ # Discharge Summaries (match choices/fields) # ------------------------------ def create_saudi_discharge_summaries(admissions): summaries = [] discharged = [a for a in admissions if a.status == Admission.AdmissionStatus.DISCHARGED and a.discharge_datetime] for admission in discharged: los = (admission.discharge_datetime.date() - admission.admission_datetime.date()).days discharging_physician = admission.attending_physician summary = DischargeSummary.objects.create( admission=admission, discharge_date=admission.discharge_datetime.date(), discharge_time=admission.discharge_datetime.time(), length_of_stay=max(los, 0), admission_diagnosis=admission.admitting_diagnosis, final_diagnosis=random.choice(SAUDI_COMMON_DIAGNOSES), secondary_diagnoses=admission.secondary_diagnoses or [], procedures_performed=random.sample(SAUDI_SURGICAL_PROCEDURES, random.randint(0, 3)), hospital_course=f"Admitted with {admission.admitting_diagnosis.lower()} and responded well to treatment.", complications=(None if random.random() < 0.7 else "Minor wound infection, resolved with antibiotics"), discharge_medications=random.sample(SAUDI_MEDICATIONS, random.randint(3, 8)), medication_changes=(None if random.random() < 0.5 else "Adjusted antihypertensives and insulin dosing."), activity_restrictions=random.choice([ None, "No lifting >10 kg for 2 weeks", "Bedrest x 24 hours", "Activity as tolerated" ]), diet_instructions=random.choice([ None, "Diabetic diet", "Low sodium diet", "Cardiac diet", "Regular diet" ]), wound_care=(None if random.random() < 0.6 else "Keep incision clean and dry. Change dressing daily."), special_instructions=(None if random.random() < 0.5 else "Monitor blood pressure and blood sugar at home."), follow_up_appointments=[ {"provider": "Primary Care Physician", "date": (admission.discharge_datetime.date() + timedelta(days=7)).isoformat(), "time": "10:00"}, {"provider": "Cardiologist", "date": (admission.discharge_datetime.date() + timedelta(days=14)).isoformat(), "time": "14:00"} ], follow_up_instructions="Follow up with PCP in 1 week and specialist in 2 weeks.", warning_signs="Fever >38.5°C, chest pain, worsening shortness of breath.", when_to_call="Call physician or return to ED if any warning signs occur.", discharge_disposition=(admission.discharge_disposition or 'HOME'), discharge_location=("Home" if (admission.discharge_disposition or 'HOME') == 'HOME' else "Rehabilitation facility"), transportation_arranged=random.choice([True, False]), transportation_method=random.choice([t[0] for t in DischargeSummary.TransportationMethod.choices]), durable_medical_equipment=(random.sample(['Walker', 'Hospital bed', 'Oxygen concentrator'], random.randint(0, 2))), supplies_provided=(random.sample(['Wound care supplies', 'Medications', 'Educational materials'], random.randint(0, 3))), education_provided=['Disease management', 'Medication administration', 'Signs and symptoms to report'], education_materials=['Discharge instructions', 'Medication list', 'Educational brochures'], patient_understanding=random.choice([p[0] for p in DischargeSummary.PatientUnderstanding.choices]), discharge_planner=(admission.discharge_planner or None), social_worker_involved=random.choice([True, False]), case_manager_involved=random.choice([True, False]), readmission_risk=random.choice([r[0] for r in DischargeSummary.ReadmissionRisk.choices]), patient_satisfaction=random.randint(6, 10), # 1–10 scale discharging_physician=discharging_physician, primary_nurse=None, summary_completed=True, summary_signed=True, patient_copy_provided=True, created_by=discharging_physician ) summaries.append(summary) print(f"Created {len(summaries)} discharge summaries") return summaries # ------------------------------ # Main # ------------------------------ def main(): print("Starting Saudi Inpatients Data Generation (refactored for updated models)…") tenants = list(Tenant.objects.all()) if not tenants: print("❌ No tenants found. Seed core/tenants first.") return # 1) Wards print("\n1. Creating Wards …") wards = create_saudi_wards(tenants, wards_per_tenant=10) # 2) Beds print("\n2. Creating Beds …") beds = create_saudi_beds(wards) # 3) Admissions print("\n3. Creating Admissions …") admissions = create_saudi_admissions(tenants, beds, admissions_per_tenant=80) # 4) Transfers print("\n4. Creating Transfers …") transfers = create_saudi_transfers(admissions) # 5) Discharge Summaries print("\n5. Creating Discharge Summaries …") summaries = create_saudi_discharge_summaries(admissions) print("\n✅ Done.") print(f"📊 Summary:") print(f" - Wards: {len(wards)}") print(f" - Beds: {len(beds)}") print(f" - Admissions: {len(admissions)}") print(f" - Transfers: {len(transfers)}") print(f" - Discharge Summaries: {len(summaries)}") # Status distribution (nice labels) from collections import Counter st = Counter([a.status for a in admissions]) print("\n🏥 Admission Status Distribution:") for k, v in st.items(): print(f" - {k}: {v}") # Nurse-to-patient ratios used print("\n👩‍⚕️ Nurse-to-Patient Ratios Used:") seen = set() for w in wards: if w.nurse_to_patient_ratio and w.nurse_to_patient_ratio > 0: p = int(round(1 / w.nurse_to_patient_ratio)) seen.add(f"1:{p}") for r in sorted(seen): print(f" - {r}") return { 'wards': wards, 'beds': beds, 'admissions': admissions, 'transfers': transfers, 'summaries': summaries } if __name__ == "__main__": main()