Make a Emergency Medicine Initial assessment form for patient coming to ER. According to International Emergency Medicine guidelines, Rules and Regulations. Start with Personal Details like Name age sex, Then Chief Complaint/ Presenting Compliant. Triage. General Condition Then Primary Survey (Airway, Breathing, Circulation, Disability, Exposure). Then SAMPLE. If pregnant - LMP Then systemic Examination, working diagnosis. This is some fields for your understanding you can add accordingly to international emergency medicine guidelines
international emergency medicine initial assessment form guidelines ABCDE primary survey triage 2024
mkdir -p /tmp/workspace/er-assessment-form && ls /tmp/workspace/er-assessment-form/
~/er-assessment-form/build_form.py
from docx import Document
from docx.shared import Pt, Inches, RGBColor, Cm
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT, WD_ALIGN_VERTICAL
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
import copy
doc = Document()
# ── PAGE MARGINS ──────────────────────────────────────────────────────────────
section = doc.sections[0]
section.page_width = Inches(8.5)
section.page_height = Inches(11)
section.top_margin = Cm(1.5)
section.bottom_margin = Cm(1.5)
section.left_margin = Cm(2)
section.right_margin = Cm(2)
# ── COLOUR PALETTE ────────────────────────────────────────────────────────────
RED_DARK = RGBColor(0xC0, 0x00, 0x00)
RED_MID = RGBColor(0xE0, 0x20, 0x20)
RED_LIGHT = RGBColor(0xFF, 0xE0, 0xE0)
GRAY_HEAD = RGBColor(0x26, 0x26, 0x26)
GRAY_LIGHT = RGBColor(0xF5, 0xF5, 0xF5)
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
BORDER_COL = RGBColor(0xCC, 0xCC, 0xCC)
TRIAGE_GREEN = RGBColor(0x1E, 0x8B, 0x4C)
TRIAGE_YELLOW = RGBColor(0xF0, 0xC0, 0x00)
TRIAGE_ORANGE = RGBColor(0xE6, 0x75, 0x00)
TRIAGE_RED = RGBColor(0xC0, 0x00, 0x00)
TRIAGE_BLACK = RGBColor(0x20, 0x20, 0x20)
# ── HELPER FUNCTIONS ──────────────────────────────────────────────────────────
def set_cell_bg(cell, rgb: RGBColor):
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
shd = OxmlElement('w:shd')
shd.set(qn('w:val'), 'clear')
shd.set(qn('w:color'), 'auto')
shd.set(qn('w:fill'), f'{rgb[0]:02X}{rgb[1]:02X}{rgb[2]:02X}')
tcPr.append(shd)
def set_cell_borders(cell, top=None, bottom=None, left=None, right=None, color='CCCCCC'):
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
tcBorders = OxmlElement('w:tcBorders')
for side, val in [('top', top), ('bottom', bottom), ('left', left), ('right', right)]:
if val:
el = OxmlElement(f'w:{side}')
el.set(qn('w:val'), val)
el.set(qn('w:sz'), '6')
el.set(qn('w:space'), '0')
el.set(qn('w:color'), color)
tcBorders.append(el)
tcPr.append(tcBorders)
def add_section_header(doc, title, rgb=None):
"""Red banner heading."""
if rgb is None:
rgb = RED_DARK
tbl = doc.add_table(rows=1, cols=1)
tbl.alignment = WD_TABLE_ALIGNMENT.CENTER
tbl.style = 'Table Grid'
cell = tbl.cell(0, 0)
set_cell_bg(cell, rgb)
cell.width = Inches(7.0)
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.LEFT
run = p.add_run(f' {title}')
run.bold = True
run.font.size = Pt(10.5)
run.font.color.rgb = WHITE
p.paragraph_format.space_before = Pt(3)
p.paragraph_format.space_after = Pt(3)
return tbl
def add_label_line(doc, label, line_char='_', line_len=48):
"""Single labelled field."""
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(1)
p.paragraph_format.space_after = Pt(1)
run = p.add_run(f'{label}: ')
run.bold = True
run.font.size = Pt(9)
run2 = p.add_run(line_char * line_len)
run2.font.size = Pt(9)
run2.font.color.rgb = BORDER_COL
return p
def add_two_col_row(doc, left_label, right_label, left_line=28, right_line=28):
"""Two side-by-side labelled fields in a borderless table."""
t = doc.add_table(rows=1, cols=2)
t.style = 'Table Grid'
t.alignment = WD_TABLE_ALIGNMENT.CENTER
for ci, (lbl, ll) in enumerate([(left_label, left_line), (right_label, right_line)]):
cell = t.cell(0, ci)
for side in ['top','bottom','left','right']:
_set_invisible_border(cell, side)
set_cell_bg(cell, WHITE)
p = cell.paragraphs[0]
p.paragraph_format.space_before = Pt(1)
p.paragraph_format.space_after = Pt(1)
r1 = p.add_run(f'{lbl}: ')
r1.bold = True
r1.font.size = Pt(9)
r2 = p.add_run('_' * ll)
r2.font.size = Pt(9)
r2.font.color.rgb = BORDER_COL
return t
def _set_invisible_border(cell, side):
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
tcBorders = tcPr.find(qn('w:tcBorders'))
if tcBorders is None:
tcBorders = OxmlElement('w:tcBorders')
tcPr.append(tcBorders)
el = OxmlElement(f'w:{side}')
el.set(qn('w:val'), 'none')
el.set(qn('w:sz'), '0')
el.set(qn('w:space'), '0')
el.set(qn('w:color'), 'auto')
tcBorders.append(el)
def add_checkbox_row(doc, items_per_row, *options):
"""Row of labelled checkboxes: □ Option."""
chunks = [options[i:i+items_per_row] for i in range(0, len(options), items_per_row)]
for chunk in chunks:
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(1)
p.paragraph_format.space_after = Pt(1)
for opt in chunk:
r = p.add_run(f'□ {opt} ')
r.font.size = Pt(9)
return p
def add_sub_header(doc, title):
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(3)
p.paragraph_format.space_after = Pt(1)
run = p.add_run(title)
run.bold = True
run.font.size = Pt(9.5)
run.font.color.rgb = RED_DARK
run.underline = True
return p
def add_note_line(doc, label, lines=1, width=68):
for i in range(lines):
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(1)
p.paragraph_format.space_after = Pt(1)
lbl_text = (label + ': ') if i == 0 else (' ' * (len(label)+3))
r1 = p.add_run(lbl_text)
r1.bold = True
r1.font.size = Pt(9)
r2 = p.add_run('_' * width)
r2.font.size = Pt(9)
r2.font.color.rgb = BORDER_COL
return p
def small_space(doc, pts=3):
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(0)
p.paragraph_format.space_after = Pt(0)
run = p.add_run()
run.font.size = Pt(pts)
return p
# ══════════════════════════════════════════════════════════════════════════════
# HEADER
# ══════════════════════════════════════════════════════════════════════════════
# Top banner table
banner = doc.add_table(rows=2, cols=3)
banner.style = 'Table Grid'
banner.alignment = WD_TABLE_ALIGNMENT.CENTER
# Row 0 – main title spanning cols 0-2 (merged)
banner.cell(0,0).merge(banner.cell(0,2))
header_cell = banner.cell(0,0)
set_cell_bg(header_cell, RED_DARK)
hp = header_cell.paragraphs[0]
hp.alignment = WD_ALIGN_PARAGRAPH.CENTER
hr = hp.add_run('🏥 EMERGENCY DEPARTMENT — INITIAL PATIENT ASSESSMENT FORM')
hr.bold = True
hr.font.size = Pt(14)
hr.font.color.rgb = WHITE
hp.paragraph_format.space_before = Pt(5)
hp.paragraph_format.space_after = Pt(5)
# Row 1 – three cells: hospital, form no, date
labels_r1 = [('Hospital / Facility Name', 30), ('Form No.', 12), ('Date & Time of Arrival', 20)]
for ci, (lbl, ll) in enumerate(labels_r1):
cell = banner.cell(1, ci)
set_cell_bg(cell, GRAY_LIGHT)
p = cell.paragraphs[0]
p.paragraph_format.space_before = Pt(3)
p.paragraph_format.space_after = Pt(3)
r1 = p.add_run(f'{lbl}: ')
r1.bold = True
r1.font.size = Pt(9)
r2 = p.add_run('_' * ll)
r2.font.size = Pt(9)
r2.font.color.rgb = BORDER_COL
small_space(doc, 6)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 1 – PERSONAL DETAILS
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '1. PATIENT PERSONAL DETAILS')
small_space(doc, 3)
# Name + MRN
add_two_col_row(doc, 'Patient Full Name', 'Medical Record No. (MRN)', 32, 18)
# DOB + Age + Sex
t = doc.add_table(rows=1, cols=3)
t.style = 'Table Grid'
for ci, (lbl, ll) in enumerate([('Date of Birth', 14), ('Age (Years/Months)', 10), ('Sex', 10)]):
cell = t.cell(0, ci)
for side in ['top','bottom','left','right']:
_set_invisible_border(cell, side)
set_cell_bg(cell, WHITE)
p = cell.paragraphs[0]
p.paragraph_format.space_before = Pt(1)
p.paragraph_format.space_after = Pt(1)
r1 = p.add_run(f'{lbl}: ')
r1.bold = True
r1.font.size = Pt(9)
r2 = p.add_run('_' * ll)
r2.font.size = Pt(9)
r2.font.color.rgb = BORDER_COL
# Gender identity / Pronouns
add_two_col_row(doc, 'Gender Identity / Pronouns', 'Nationality / Ethnicity', 24, 24)
add_two_col_row(doc, 'Contact Number', 'Emergency Contact & Relationship', 22, 26)
add_two_col_row(doc, 'Address', 'Next of Kin Name & Contact', 26, 26)
add_two_col_row(doc, 'Referring Physician / Facility', 'Mode of Arrival', 24, 24)
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(1)
p.paragraph_format.space_after = Pt(1)
r = p.add_run('Mode of Arrival: ')
r.bold = True
r.font.size = Pt(9)
add_checkbox_row(doc, 6, 'Walk-in', 'Ambulance (BLS)', 'Ambulance (ALS)', 'Police', 'Helicopter/Air', 'Other')
add_two_col_row(doc, 'Accompanied By', 'Identification / ID No.', 28, 22)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 2 – TRIAGE
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '2. TRIAGE (Emergency Severity Index — ESI / Manchester Triage System)')
small_space(doc, 3)
# Triage level coloured cells
triage_tbl = doc.add_table(rows=2, cols=5)
triage_tbl.style = 'Table Grid'
triage_tbl.alignment = WD_TABLE_ALIGNMENT.CENTER
levels = [
('LEVEL 1\nRESUSCITATION', TRIAGE_RED, WHITE),
('LEVEL 2\nEMERGENT', TRIAGE_ORANGE, WHITE),
('LEVEL 3\nURGENT', TRIAGE_YELLOW, GRAY_HEAD),
('LEVEL 4\nSEMI-URGENT', TRIAGE_GREEN, WHITE),
('LEVEL 5\nNON-URGENT', TRIAGE_BLACK, WHITE),
]
for ci, (text, bg, fg) in enumerate(levels):
cell = triage_tbl.cell(0, ci)
set_cell_bg(cell, bg)
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run(text)
run.bold = True
run.font.size = Pt(8.5)
run.font.color.rgb = fg
p.paragraph_format.space_before = Pt(3)
p.paragraph_format.space_after = Pt(3)
# Row 1 – checkboxes
for ci in range(5):
cell = triage_tbl.cell(1, ci)
set_cell_bg(cell, GRAY_LIGHT)
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('□')
run.font.size = Pt(14)
p.paragraph_format.space_before = Pt(2)
p.paragraph_format.space_after = Pt(2)
small_space(doc, 3)
add_two_col_row(doc, 'Triage Nurse Name', 'Triage Time', 28, 20)
add_two_col_row(doc, 'Triage Category (circle / tick above)', 'Target Time to Physician', 28, 20)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 3 – CHIEF COMPLAINT / PRESENTING COMPLAINT
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '3. CHIEF COMPLAINT / PRESENTING COMPLAINT')
small_space(doc, 3)
add_note_line(doc, 'Chief Complaint (in patient\'s own words)', 1, 66)
add_note_line(doc, 'Onset & Duration', 1, 56)
add_note_line(doc, 'Location / Radiation', 1, 54)
add_note_line(doc, 'Character / Quality', 1, 54)
add_two_col_row(doc, 'Severity (0–10 Pain Scale)', 'Aggravating Factors', 22, 26)
add_two_col_row(doc, 'Relieving Factors', 'Associated Symptoms', 26, 26)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 4 – VITAL SIGNS ON ARRIVAL
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '4. VITAL SIGNS ON ARRIVAL')
small_space(doc, 3)
vs_tbl = doc.add_table(rows=3, cols=4)
vs_tbl.style = 'Table Grid'
vs_tbl.alignment = WD_TABLE_ALIGNMENT.CENTER
vitals = [
[('BP (mmHg)', 18), ('HR (bpm)', 14), ('RR (/min)', 14), ('SpO₂ (%)', 12)],
[('Temperature (°C/°F)', 16), ('GCS (E_V_M = /15)', 14), ('Blood Glucose (mmol/L / mg/dL)', 12), ('Weight (kg)', 12)],
[('Pain Score (0–10)', 12), ('AVPU\n□ Alert □ Voice □ Pain □ Unresponsive', 26), ('ECG Rhythm', 14), ('Time of VS', 14)],
]
for ri, row in enumerate(vitals):
for ci, (lbl, ll) in enumerate(row):
cell = vs_tbl.cell(ri, ci)
set_cell_bg(cell, GRAY_LIGHT if ri % 2 == 0 else WHITE)
p = cell.paragraphs[0]
p.paragraph_format.space_before = Pt(2)
p.paragraph_format.space_after = Pt(2)
r1 = p.add_run(f'{lbl}\n')
r1.bold = True
r1.font.size = Pt(8.5)
r2 = p.add_run('_' * ll)
r2.font.size = Pt(9)
r2.font.color.rgb = BORDER_COL
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 5 – GENERAL CONDITION
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '5. GENERAL CONDITION ON ARRIVAL')
small_space(doc, 3)
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(1)
p.paragraph_format.space_after = Pt(1)
r = p.add_run('Overall Appearance: ')
r.bold = True
r.font.size = Pt(9)
add_checkbox_row(doc, 5, 'Well / NAD', 'Acutely Ill', 'Distressed', 'Moribund', 'Unconscious')
add_checkbox_row(doc, 5, 'Ambulatory', 'Stretcher-Borne', 'Agitated', 'Pale', 'Diaphoretic')
add_checkbox_row(doc, 4, 'Cyanotic', 'Jaundiced', 'Oedematous', 'Cachexic')
add_note_line(doc, 'General Condition Description', 2, 66)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 6 – PRIMARY SURVEY (ABCDE)
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '6. PRIMARY SURVEY — ABCDE APPROACH (Treat First What Kills First)')
small_space(doc, 3)
# --- A: AIRWAY ---
add_sub_header(doc, 'A — AIRWAY (with C-spine control if trauma)')
add_checkbox_row(doc, 4, 'Patent', 'Partially Obstructed', 'Completely Obstructed', 'At Risk')
add_checkbox_row(doc, 5, 'Talking Freely', 'Stridor', 'Gurgling', 'Snoring', 'Silent')
add_checkbox_row(doc, 5, 'No Intervention', 'Head-Tilt/Chin-Lift', 'Jaw Thrust', 'Suction', 'OPA Inserted')
add_checkbox_row(doc, 5, 'NPA Inserted', 'LMA/i-gel Inserted', 'Intubated (ETT)', 'Surgical Airway', 'C-Spine Immobilised')
add_note_line(doc, 'Airway Notes', 1, 62)
small_space(doc, 3)
# --- B: BREATHING ---
add_sub_header(doc, 'B — BREATHING & VENTILATION')
add_checkbox_row(doc, 4, 'Spontaneous', 'Laboured', 'Shallow', 'Absent')
add_checkbox_row(doc, 5, 'Equal Air Entry', 'Reduced L', 'Reduced R', 'Wheeze', 'Crackles')
add_checkbox_row(doc, 5, 'Room Air', 'O₂ via Mask', 'High-Flow O₂', 'NIV/CPAP', 'Assisted Ventilation')
add_two_col_row(doc, 'O₂ Flow Rate (L/min)', 'SpO₂ on O₂ (%)', 18, 18)
add_two_col_row(doc, 'Percussion Note', 'Tracheal Position', 20, 20)
add_note_line(doc, 'Breathing Notes', 1, 62)
small_space(doc, 3)
# --- C: CIRCULATION ---
add_sub_header(doc, 'C — CIRCULATION & HAEMORRHAGE CONTROL')
add_checkbox_row(doc, 4, 'Normal Perfusion', 'Hypoperfused', 'Shock', 'Cardiac Arrest')
add_checkbox_row(doc, 5, 'Regular Pulse', 'Irregular Pulse', 'Bounding', 'Weak/Thready', 'Absent')
add_checkbox_row(doc, 5, 'Capillary Refill <2s', 'CRT 2-4s', 'CRT >4s', 'Cold Peripheries', 'Mottled Skin')
add_checkbox_row(doc, 5, 'No Bleeding', 'External Bleeding', 'Tourniquet Applied', 'IV Access x1', 'IV Access x2')
add_checkbox_row(doc, 4, 'IO Access', 'Fluid Bolus Given', 'CPR In Progress', 'Defibrillated')
add_two_col_row(doc, 'IV Site & Gauge', 'Fluids Administered (type/volume)', 20, 28)
add_note_line(doc, 'Circulation Notes', 1, 62)
small_space(doc, 3)
# --- D: DISABILITY ---
add_sub_header(doc, 'D — DISABILITY (Neurological Status)')
t_gcs = doc.add_table(rows=2, cols=4)
t_gcs.style = 'Table Grid'
t_gcs.alignment = WD_TABLE_ALIGNMENT.CENTER
gcs_headers = ['GCS — Eye (E)', 'GCS — Verbal (V)', 'GCS — Motor (M)', 'Total GCS /15']
for ci, h in enumerate(gcs_headers):
cell = t_gcs.cell(0, ci)
set_cell_bg(cell, RED_LIGHT)
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = p.add_run(h)
r.bold = True
r.font.size = Pt(8.5)
p.paragraph_format.space_before = Pt(2)
p.paragraph_format.space_after = Pt(2)
gcs_opts = [
'1=None 2=To Pain\n3=To Voice 4=Spontaneous',
'1=None 2=Sounds\n3=Words 4=Confused 5=Oriented',
'1=None 2=Extension\n3=Flexion 4=Withdrawal\n5=Localises 6=Obeys',
'□ ___ /15'
]
for ci, txt in enumerate(gcs_opts):
cell = t_gcs.cell(1, ci)
set_cell_bg(cell, GRAY_LIGHT)
p = cell.paragraphs[0]
r = p.add_run(txt)
r.font.size = Pt(8)
p.paragraph_format.space_before = Pt(2)
p.paragraph_format.space_after = Pt(2)
small_space(doc, 2)
add_checkbox_row(doc, 4, 'Alert', 'Responds to Voice', 'Responds to Pain', 'Unresponsive')
add_two_col_row(doc, 'Pupils R: Size____mm React____', 'Pupils L: Size____mm React____', 28, 28)
add_checkbox_row(doc, 4, 'Pupils Equal', 'Anisocoria', 'Reactive', 'Fixed & Dilated')
add_checkbox_row(doc, 4, 'Focal Neuro Deficit', 'Seizure Activity', 'BM (Blood Sugar)', 'Temperature')
add_two_col_row(doc, 'Blood Glucose (mmol/L)', 'Temperature (°C)', 20, 18)
add_note_line(doc, 'Disability Notes', 1, 62)
small_space(doc, 3)
# --- E: EXPOSURE ---
add_sub_header(doc, 'E — EXPOSURE & ENVIRONMENTAL CONTROL')
add_note_line(doc, 'Exposed Area / Findings (rashes, wounds, burns, deformity)', 1, 46)
add_checkbox_row(doc, 5, 'No External Injuries', 'Lacerations', 'Contusions', 'Burns', 'Fracture Deformity')
add_checkbox_row(doc, 5, 'Rash / Urticaria', 'Oedema', 'Petechiae / Purpura', 'Stigmata of Disease', 'Surgical Scars')
add_two_col_row(doc, 'Core Temperature (°C)', 'Keep Warm / Hypothermia Protocol', 18, 28)
add_note_line(doc, 'Exposure Notes', 1, 62)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 7 – SAMPLE HISTORY
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '7. SAMPLE HISTORY')
small_space(doc, 3)
add_sub_header(doc, 'S — Signs & Symptoms')
add_note_line(doc, 'Signs & Symptoms (detailed)', 2, 66)
add_sub_header(doc, 'A — Allergies')
add_checkbox_row(doc, 3, 'No Known Drug Allergies (NKDA)', 'Drug Allergy', 'Food / Environmental Allergy')
add_note_line(doc, 'Allergy Details (Drug / Reaction)', 1, 56)
add_sub_header(doc, 'M — Medications (Current)')
add_note_line(doc, 'Prescription Medications', 2, 66)
add_note_line(doc, 'OTC / Herbal / Supplements', 1, 56)
add_checkbox_row(doc, 4, 'Anticoagulants', 'Antiplatelets', 'Insulin / OHAs', 'Immunosuppressants')
add_sub_header(doc, 'P — Past Medical / Surgical History')
add_checkbox_row(doc, 5, 'Hypertension', 'Diabetes', 'IHD / CAD', 'Heart Failure', 'Stroke / TIA')
add_checkbox_row(doc, 5, 'COPD / Asthma', 'CKD', 'Liver Disease', 'Malignancy', 'Epilepsy')
add_checkbox_row(doc, 4, 'Psychiatric History', 'Immunocompromised', 'Previous Surgery', 'Other')
add_note_line(doc, 'Past Medical / Surgical History Details', 2, 60)
add_sub_header(doc, 'L — Last Oral Intake')
add_two_col_row(doc, 'Last Food Intake (Date & Time)', 'Last Fluid Intake (Date & Time)', 26, 26)
add_two_col_row(doc, 'Last Bowel Movement', 'Last Urine Output', 22, 22)
add_sub_header(doc, 'E — Events Leading to This Visit / Environment')
add_note_line(doc, 'Events / Mechanism of Injury / Circumstances', 2, 64)
add_checkbox_row(doc, 4, 'Spontaneous', 'Post-Trauma', 'Intentional (self-harm)', 'Suspected Assault')
add_two_col_row(doc, 'Immunisation Status', 'Travel History (recent)', 24, 24)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 8 – OBSTETRIC HISTORY (IF FEMALE / APPLICABLE)
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '8. OBSTETRIC / GYNAECOLOGICAL HISTORY (If Female / Applicable)')
small_space(doc, 3)
add_checkbox_row(doc, 4, 'Not Applicable', 'Possibly Pregnant', 'Known Pregnant', 'Post-Partum')
add_two_col_row(doc, 'LMP (Last Menstrual Period)', 'Estimated Gestational Age (weeks)', 22, 22)
add_checkbox_row(doc, 4, 'urine β-hCG: □ +ve □ -ve □ Pending', 'G____ P____ A____', 'Contraception Use', 'Previous Ectopic')
add_two_col_row(doc, 'Pregnancy Complications', 'Obstetric Notes', 28, 26)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 9 – SYSTEMIC EXAMINATION
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '9. SYSTEMIC EXAMINATION')
small_space(doc, 3)
systems = [
('Cardiovascular (CVS)', ['Heart Sounds: S1____ S2____ Murmur____', 'JVP____ Peripheral Pulses____', 'Apex Beat____ Heaves/Thrills____']),
('Respiratory (RS)', ['Air Entry: R____ L____', 'Added Sounds (Wheeze/Crackles/Rub)____', 'Percussion: R____ L____']),
('Abdomen (GIT)', ['Tenderness____ Guarding____ Rigidity____', 'Organomegaly: Liver____ Spleen____', 'Bowel Sounds____ PR Exam (if indicated)____']),
('Central Nervous System (CNS)', ['Orientation: Time____ Place____ Person____', 'Cranial Nerves____ Motor____ Sensory____', 'Reflexes____ Cerebellar____ Meningism____']),
('Musculoskeletal (MSK)', ['Deformity____ Swelling____ Tenderness____', 'Range of Motion____ Neurovascular Status____']),
('Dermatological / Skin', ['Rash____ Wounds____ Pressure Sores____ Colour____']),
('ENT / Head & Neck', ['Eyes (PERLA, EOM)____ Ears____ Throat____', 'Lymph Nodes____ Thyroid____ JVP____']),
('Genitourinary (if applicable)', ['Flank Tenderness____ Suprapubic Tenderness____ External Genitalia____']),
]
for sys_name, sub_items in systems:
tbl = doc.add_table(rows=1, cols=2)
tbl.style = 'Table Grid'
tbl.alignment = WD_TABLE_ALIGNMENT.CENTER
# Left col: system name
c0 = tbl.cell(0, 0)
c0.width = Inches(1.8)
set_cell_bg(c0, RED_LIGHT)
p0 = c0.paragraphs[0]
p0.paragraph_format.space_before = Pt(3)
p0.paragraph_format.space_after = Pt(3)
r0 = p0.add_run(sys_name)
r0.bold = True
r0.font.size = Pt(9)
r0.font.color.rgb = RED_DARK
# Right col: sub-items
c1 = tbl.cell(0, 1)
set_cell_bg(c1, WHITE)
p1 = c1.paragraphs[0]
p1.paragraph_format.space_before = Pt(2)
p1.paragraph_format.space_after = Pt(2)
r1 = p1.add_run('\n'.join(sub_items))
r1.font.size = Pt(8.5)
small_space(doc, 2)
add_note_line(doc, 'Additional Examination Findings', 2, 66)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 10 – INVESTIGATIONS ORDERED
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '10. INVESTIGATIONS ORDERED')
small_space(doc, 3)
add_sub_header(doc, 'Laboratory (Pathology)')
lab_tbl = doc.add_table(rows=3, cols=4)
lab_tbl.style = 'Table Grid'
lab_items = [
'FBC / CBC', 'U&E / BMP', 'LFT', 'Coagulation (PT/APTT/INR)',
'Troponin I/T', 'D-Dimer', 'CRP / ESR', 'Procalcitonin',
'ABG / VBG', 'Lactate', 'Blood Culture x2', 'Urine FEME + MC&S',
]
for idx, item in enumerate(lab_items):
ri = idx // 4
ci = idx % 4
cell = lab_tbl.cell(ri, ci)
set_cell_bg(cell, GRAY_LIGHT if ri % 2 == 0 else WHITE)
p = cell.paragraphs[0]
p.paragraph_format.space_before = Pt(2)
p.paragraph_format.space_after = Pt(2)
r = p.add_run(f'□ {item}')
r.font.size = Pt(8.5)
add_note_line(doc, 'Other Lab Tests', 1, 60)
small_space(doc, 2)
add_sub_header(doc, 'Imaging')
add_checkbox_row(doc, 5, 'CXR', 'AXR', 'CT Head', 'CT Chest', 'CT Abdomen/Pelvis')
add_checkbox_row(doc, 5, 'CT Angiography', 'FAST Ultrasound', 'Bedside Echo', 'X-Ray (specify)', 'MRI (specify)')
add_note_line(doc, 'Imaging Requested (specify views)', 1, 58)
small_space(doc, 2)
add_sub_header(doc, 'Point-of-Care / Bedside Tests')
add_checkbox_row(doc, 5, 'ECG (12-lead)', 'FAST US', 'Urine Pregnancy Test', 'Urinalysis Dipstick', 'Peak Flow')
add_checkbox_row(doc, 4, 'Blood Glucose (POC)', 'SpO₂ Monitor', 'Cardiac Monitor', 'EtCO₂')
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 11 – WORKING DIAGNOSIS / DIFFERENTIAL
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '11. WORKING DIAGNOSIS / DIFFERENTIAL DIAGNOSES')
small_space(doc, 3)
add_note_line(doc, 'Primary Working Diagnosis', 1, 58)
add_note_line(doc, 'Differential Diagnosis 1', 1, 58)
add_note_line(doc, 'Differential Diagnosis 2', 1, 58)
add_note_line(doc, 'Differential Diagnosis 3', 1, 58)
add_note_line(doc, 'ICD-10 Code (if known)', 1, 30)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 12 – IMMEDIATE MANAGEMENT & TREATMENT
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '12. IMMEDIATE MANAGEMENT & TREATMENT INITIATED')
small_space(doc, 3)
add_checkbox_row(doc, 5, 'O₂ Therapy', 'IV Access', 'IV Fluids', 'Cardiac Monitor', 'Urinary Catheter')
add_checkbox_row(doc, 5, 'Nasogastric Tube', 'Analgesia Given', 'Antiemetic Given', 'Antibiotics Given', 'Antidote Given')
add_checkbox_row(doc, 4, 'Immobilisation / Splint', 'Wound Care', 'CPR Initiated', 'Defibrillation')
add_two_col_row(doc, 'Medications Given (Name / Dose / Route / Time)', '', 60, 2)
add_note_line(doc, 'Drug 1', 1, 62)
add_note_line(doc, 'Drug 2', 1, 62)
add_note_line(doc, 'Drug 3', 1, 62)
add_note_line(doc, 'Procedures Performed', 2, 60)
add_note_line(doc, 'Response to Treatment', 1, 58)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 13 – RISK STRATIFICATION & SAFETY SCREENING
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '13. RISK STRATIFICATION & SAFETY SCREENING')
small_space(doc, 3)
add_checkbox_row(doc, 4, 'Sepsis Screening (qSOFA): □ Positive □ Negative', 'HEART Score (Chest Pain ACS)', 'NIHSS (Stroke)', 'WELLS Score (DVT/PE)')
add_two_col_row(doc, 'Sepsis Bundle Initiated (Time)', 'Stroke Pathway Activated (Time)', 28, 26)
add_checkbox_row(doc, 3, 'Safeguarding Concern (Child)', 'Safeguarding Concern (Adult)', 'Domestic Violence Screening Done')
add_checkbox_row(doc, 3, 'Suicide / Self-Harm Risk: □ Low □ Moderate □ High', 'Psychiatric Liaison Notified', 'Capacity Assessment Done')
add_note_line(doc, 'Risk Notes', 1, 62)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 14 – DISPOSITION / PLAN
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '14. DISPOSITION & PLAN')
small_space(doc, 3)
add_checkbox_row(doc, 5, 'Admit (Ward/ICU/HDU)', 'Discharge Home', 'Transfer to Another Facility', 'Refer to Specialist', 'Observation / Short Stay')
add_checkbox_row(doc, 3, 'Admit to Resus Bay', 'Admit to Majors', 'Admit to Minors / Fast Track')
add_two_col_row(doc, 'Admitting Ward / Specialty', 'Admitting Physician / Consultant', 26, 26)
add_two_col_row(doc, 'Discharge Condition', 'Discharge Time', 22, 18)
add_note_line(doc, 'Discharge Instructions / Follow-up Plan', 2, 60)
add_note_line(doc, 'Referral Details', 1, 62)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 15 – SIGNATURES & DOCUMENTATION
# ══════════════════════════════════════════════════════════════════════════════
add_section_header(doc, '15. CLINICIAN SIGNATURES & DOCUMENTATION')
small_space(doc, 3)
sig_tbl = doc.add_table(rows=3, cols=3)
sig_tbl.style = 'Table Grid'
sig_headers = ['Triage Nurse', 'Emergency Physician / Resident', 'Attending Consultant']
for ci, h in enumerate(sig_headers):
c = sig_tbl.cell(0, ci)
set_cell_bg(c, RED_LIGHT)
p = c.paragraphs[0]
p.paragraph_format.space_before = Pt(3)
p.paragraph_format.space_after = Pt(3)
r = p.add_run(h)
r.bold = True
r.font.size = Pt(9)
r.font.color.rgb = RED_DARK
sig_rows = [['Name: _______________', 'Name: _______________', 'Name: _______________'],
['Signature: __________\nTime: _______________', 'Signature: __________\nTime: _______________', 'Signature: __________\nTime: _______________']]
for ri, row_data in enumerate(sig_rows):
for ci, txt in enumerate(row_data):
c = sig_tbl.cell(ri+1, ci)
set_cell_bg(c, GRAY_LIGHT if ri == 0 else WHITE)
p = c.paragraphs[0]
p.paragraph_format.space_before = Pt(3)
p.paragraph_format.space_after = Pt(3)
r = p.add_run(txt)
r.font.size = Pt(9)
small_space(doc, 3)
add_note_line(doc, 'Additional Clinical Notes / Communication Log', 3, 64)
small_space(doc, 4)
# ══════════════════════════════════════════════════════════════════════════════
# FOOTER
# ══════════════════════════════════════════════════════════════════════════════
footer_tbl = doc.add_table(rows=1, cols=1)
footer_tbl.style = 'Table Grid'
fc = footer_tbl.cell(0, 0)
set_cell_bg(fc, GRAY_HEAD)
fp = fc.paragraphs[0]
fp.alignment = WD_ALIGN_PARAGRAPH.CENTER
fr = fp.add_run(
'This form complies with IFEM (International Federation for Emergency Medicine) standards, '
'Manchester Triage System (MTS), Emergency Severity Index (ESI), and ACEP Clinical Policy guidelines. '
'| Form Version: 1.0 | Review Date: Annually | Confidential Patient Record'
)
fr.font.size = Pt(7.5)
fr.font.color.rgb = WHITE
fp.paragraph_format.space_before = Pt(3)
fp.paragraph_format.space_after = Pt(3)
# ── SAVE ──────────────────────────────────────────────────────────────────────
out_path = '/tmp/workspace/er-assessment-form/ER_Initial_Assessment_Form.docx'
doc.save(out_path)
print(f'Saved: {out_path}')