Make me case record form for my thesis of topic accuracy of alvorado score in diagnosis of acute appendicitis which include routine patient detail , history , examination and at the end alvorado score counting
mkdir -p /tmp/workspace/alvarado-crf && ls /tmp/workspace/alvarado-crf/
~/alvarado-crf/build_crf.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 ──────────────────────────────────────────────────────────────
for section in doc.sections:
section.top_margin = Cm(2)
section.bottom_margin = Cm(2)
section.left_margin = Cm(2.5)
section.right_margin = Cm(2.5)
# ── Styles ────────────────────────────────────────────────────────────────────
normal = doc.styles["Normal"]
normal.font.name = "Arial"
normal.font.size = Pt(11)
# ── Helper functions ──────────────────────────────────────────────────────────
def set_col_width(cell, width_cm):
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
tcW = OxmlElement("w:tcW")
tcW.set(qn("w:w"), str(int(width_cm * 567))) # 1 cm ≈ 567 twips
tcW.set(qn("w:type"), "dxa")
tcPr.append(tcW)
def shade_cell(cell, fill_hex="D9E1F2"):
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"), fill_hex)
tcPr.append(shd)
def heading_para(doc, text, level=1, color_hex="1F3864"):
p = doc.add_paragraph()
p.style = doc.styles[f"Heading {level}"] if f"Heading {level}" in [s.name for s in doc.styles] else doc.styles["Normal"]
run = p.add_run(text)
run.bold = True
run.font.size = Pt(13 if level == 1 else 11)
run.font.color.rgb = RGBColor.from_string(color_hex)
p.paragraph_format.space_before = Pt(10)
p.paragraph_format.space_after = Pt(4)
return p
def section_bar(doc, text):
"""Shaded full-width section bar"""
table = doc.add_table(rows=1, cols=1)
table.style = "Table Grid"
cell = table.cell(0, 0)
shade_cell(cell, "1F3864")
p = cell.paragraphs[0]
run = p.add_run(f" {text}")
run.bold = True
run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
run.font.size = Pt(11)
p.paragraph_format.space_before = Pt(2)
p.paragraph_format.space_after = Pt(2)
doc.add_paragraph("") # spacer
def field_row(table, label, blank_cols=1, hint=""):
"""Add a label + blank cell row to a table"""
row = table.add_row()
lbl_cell = row.cells[0]
shade_cell(lbl_cell, "EBF0FA")
run = lbl_cell.paragraphs[0].add_run(label)
run.bold = True
run.font.size = Pt(10)
for i in range(1, len(row.cells)):
if hint:
row.cells[i].paragraphs[0].add_run(hint).font.color.rgb = RGBColor(0x99,0x99,0x99)
def two_col_field_table(doc, fields, widths=(6, 10)):
"""Create a 2-column label | blank table"""
table = doc.add_table(rows=0, cols=2)
table.style = "Table Grid"
table.alignment = WD_TABLE_ALIGNMENT.CENTER
for label, hint in fields:
row = table.add_row()
shade_cell(row.cells[0], "EBF0FA")
set_col_width(row.cells[0], widths[0])
set_col_width(row.cells[1], widths[1])
r = row.cells[0].paragraphs[0].add_run(label)
r.bold = True
r.font.size = Pt(10)
if hint:
row.cells[1].paragraphs[0].add_run(hint).font.color.rgb = RGBColor(0xAA,0xAA,0xAA)
doc.add_paragraph("")
def four_col_table(doc, pairs):
"""pairs = [(label1, label2), ...] → 4-col table"""
table = doc.add_table(rows=0, cols=4)
table.style = "Table Grid"
for l1, l2 in pairs:
row = table.add_row()
for idx, lbl in enumerate([l1, "", l2, ""]):
c = row.cells[idx]
if idx in (0, 2):
shade_cell(c, "EBF0FA")
r = c.paragraphs[0].add_run(lbl)
r.bold = True
r.font.size = Pt(10)
set_col_width(c, 5)
else:
set_col_width(c, 7)
doc.add_paragraph("")
# ══════════════════════════════════════════════════════════════════════════════
# TITLE BLOCK
# ══════════════════════════════════════════════════════════════════════════════
title_table = doc.add_table(rows=1, cols=1)
title_table.style = "Table Grid"
shade_cell(title_table.cell(0,0), "1F3864")
tp = title_table.cell(0,0).paragraphs[0]
tp.alignment = WD_ALIGN_PARAGRAPH.CENTER
tr = tp.add_run("CASE RECORD FORM")
tr.bold = True
tr.font.size = Pt(16)
tr.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
doc.add_paragraph("")
sub_table = doc.add_table(rows=1, cols=1)
sub_table.style = "Table Grid"
shade_cell(sub_table.cell(0,0), "2E75B6")
sp = sub_table.cell(0,0).paragraphs[0]
sp.alignment = WD_ALIGN_PARAGRAPH.CENTER
sr = sp.add_run("A Study on the Accuracy of Alvarado Score in Diagnosis of Acute Appendicitis")
sr.bold = True
sr.font.size = Pt(12)
sr.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
doc.add_paragraph("")
# ══════════════════════════════════════════════════════════════════════════════
# SECTION A: PATIENT IDENTIFICATION
# ══════════════════════════════════════════════════════════════════════════════
section_bar(doc, "SECTION A: PATIENT IDENTIFICATION")
two_col_field_table(doc, [
("Case/Serial No.:", ""),
("Date of Admission:", "DD / MM / YYYY"),
("Date of Examination:", "DD / MM / YYYY"),
("Patient's Full Name:", ""),
("Age:", "Years"),
("Sex:", "Male / Female / Other"),
("Date of Birth:", "DD / MM / YYYY"),
("Contact Number:", ""),
("Address:", ""),
("IP / OP No.:", ""),
("Ward / Bed No.:", ""),
("Referred By:", ""),
("Occupation:", ""),
("Marital Status:", "Single / Married / Divorced / Widowed"),
("Socioeconomic Status:", "Lower / Middle / Upper"),
("Informant:", "Self / Relative / Other"),
("Reliability of History:", "Reliable / Not Reliable"),
], widths=(6, 10))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION B: CHIEF COMPLAINT & HISTORY OF PRESENTING ILLNESS
# ══════════════════════════════════════════════════════════════════════════════
section_bar(doc, "SECTION B: CHIEF COMPLAINT & HISTORY OF PRESENTING ILLNESS")
two_col_field_table(doc, [
("Chief Complaint:", ""),
("Duration of Symptoms:", "Hours / Days"),
], widths=(6, 10))
# Pain sub-table
p_head = doc.add_paragraph()
r = p_head.add_run("Pain Details")
r.bold = True
r.font.size = Pt(10)
r.font.color.rgb = RGBColor.from_string("2E75B6")
pain_table = doc.add_table(rows=0, cols=4)
pain_table.style = "Table Grid"
pain_fields = [
("Site of Pain:", "Periumbilical / RIF / Diffuse", "Radiation:", "Yes / No — If yes, to: ________"),
("Onset:", "Sudden / Gradual", "Duration:", ""),
("Character:", "Colicky / Constant / Dull", "Severity (NRS 0–10):", " /10"),
("Progression:", "Migrating / Localised / Diffuse", "Aggravating Factors:", ""),
("Relieving Factors:", "", "Associated Factors:", ""),
]
for l1, h1, l2, h2 in pain_fields:
row = pain_table.add_row()
shade_cell(row.cells[0], "EBF0FA")
set_col_width(row.cells[0], 5); set_col_width(row.cells[1], 7)
set_col_width(row.cells[2], 5); set_col_width(row.cells[3], 7)
r1 = row.cells[0].paragraphs[0].add_run(l1); r1.bold=True; r1.font.size=Pt(10)
shade_cell(row.cells[2], "EBF0FA")
r2 = row.cells[2].paragraphs[0].add_run(l2); r2.bold=True; r2.font.size=Pt(10)
if h1: row.cells[1].paragraphs[0].add_run(h1).font.color.rgb = RGBColor(0xAA,0xAA,0xAA)
if h2: row.cells[3].paragraphs[0].add_run(h2).font.color.rgb = RGBColor(0xAA,0xAA,0xAA)
doc.add_paragraph("")
# Associated symptoms
sym_head = doc.add_paragraph()
rs = sym_head.add_run("Associated Symptoms")
rs.bold = True; rs.font.size = Pt(10); rs.font.color.rgb = RGBColor.from_string("2E75B6")
sym_table = doc.add_table(rows=0, cols=4)
sym_table.style = "Table Grid"
symptoms = [
("Nausea:", "Yes / No", "Vomiting:", "Yes / No — No. of episodes: ____"),
("Fever:", "Yes / No", "Anorexia / Loss of Appetite:", "Yes / No"),
("Diarrhoea:", "Yes / No", "Constipation:", "Yes / No"),
("Dysuria:", "Yes / No", "Frequency of Urine:", "Yes / No"),
("Menstrual History (F):", "LMP: ______ Regular/Irregular", "Vaginal Discharge:", "Yes / No"),
]
for l1, h1, l2, h2 in symptoms:
row = sym_table.add_row()
shade_cell(row.cells[0], "EBF0FA"); shade_cell(row.cells[2], "EBF0FA")
set_col_width(row.cells[0], 5); set_col_width(row.cells[1], 7)
set_col_width(row.cells[2], 5); set_col_width(row.cells[3], 7)
r1 = row.cells[0].paragraphs[0].add_run(l1); r1.bold=True; r1.font.size=Pt(10)
r2 = row.cells[2].paragraphs[0].add_run(l2); r2.bold=True; r2.font.size=Pt(10)
if h1: row.cells[1].paragraphs[0].add_run(h1).font.color.rgb = RGBColor(0xAA,0xAA,0xAA)
if h2: row.cells[3].paragraphs[0].add_run(h2).font.color.rgb = RGBColor(0xAA,0xAA,0xAA)
doc.add_paragraph("")
# ══════════════════════════════════════════════════════════════════════════════
# SECTION C: PAST HISTORY
# ══════════════════════════════════════════════════════════════════════════════
section_bar(doc, "SECTION C: PAST HISTORY")
two_col_field_table(doc, [
("Similar Complaints in Past:", "Yes / No — If yes, details: _________________"),
("H/O Diabetes Mellitus:", "Yes / No"),
("H/O Hypertension:", "Yes / No"),
("H/O Cardiac Disease:", "Yes / No"),
("H/O Pulmonary Disease:", "Yes / No"),
("H/O Tuberculosis:", "Yes / No"),
("H/O Previous Abdominal Surgery:", "Yes / No — If yes: _____________________"),
("H/O Previous Hospitalisation:", "Yes / No — Reason: ____________________"),
("H/O Drug Allergy:", "Yes / No — If yes: ___________________________"),
("Current Medications:", ""),
("H/O Malignancy:", "Yes / No"),
("Other Significant Past History:", ""),
], widths=(6.5, 9.5))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION D: PERSONAL, FAMILY & OBSTETRIC HISTORY
# ══════════════════════════════════════════════════════════════════════════════
section_bar(doc, "SECTION D: PERSONAL, FAMILY & OBSTETRIC HISTORY")
two_col_field_table(doc, [
("Smoking:", "Non-smoker / Ex-smoker / Current smoker — Pack years: ____"),
("Alcohol:", "Non-drinker / Occasional / Regular"),
("Tobacco / Other Substance Use:", "Yes / No — Details: __________________"),
("Diet:", "Vegetarian / Mixed"),
("Family H/O Appendicitis:", "Yes / No"),
("Family H/O Malignancy:", "Yes / No — Details: ______________________"),
("Obstetric History (if female):", "G:___ P:___ L:___ A:___ — Pregnancy status: ___"),
], widths=(6.5, 9.5))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION E: GENERAL PHYSICAL EXAMINATION
# ══════════════════════════════════════════════════════════════════════════════
section_bar(doc, "SECTION E: GENERAL PHYSICAL EXAMINATION")
two_col_field_table(doc, [
("General Condition:", "Well / Ill-looking / Toxic / Distressed"),
("Consciousness:", "Alert / Drowsy / Confused"),
("Built & Nutrition:", "Good / Average / Poor"),
], widths=(6, 10))
four_col_table(doc, [
("Pulse Rate:", "Temperature (°F / °C):"),
("Blood Pressure:", "Respiratory Rate:"),
("SpO₂:", "Weight (kg):"),
("Height (cm):", "BMI (kg/m²):"),
])
two_col_field_table(doc, [
("Pallor:", "Present / Absent"),
("Icterus / Jaundice:", "Present / Absent"),
("Cyanosis:", "Present / Absent"),
("Clubbing:", "Present / Absent"),
("Lymphadenopathy:", "Present / Absent — Site: __________________"),
("Oedema:", "Present / Absent — Site: __________________"),
("Dehydration:", "None / Mild / Moderate / Severe"),
], widths=(6, 10))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION F: SYSTEMIC EXAMINATION
# ══════════════════════════════════════════════════════════════════════════════
section_bar(doc, "SECTION F: SYSTEMIC EXAMINATION")
# Abdominal
ab_head = doc.add_paragraph()
rab = ab_head.add_run("Abdominal Examination")
rab.bold=True; rab.font.size=Pt(10); rab.font.color.rgb=RGBColor.from_string("2E75B6")
two_col_field_table(doc, [
("Inspection:", ""),
(" Shape of Abdomen:", "Flat / Scaphoid / Distended / Protuberant"),
(" Abdominal Movement with Respiration:", "Normal / Restricted"),
(" Visible Peristalsis:", "Present / Absent"),
(" Visible Pulsations:", "Present / Absent"),
(" Scars / Sinuses / Striae:", "Present / Absent — Details: ___________"),
("Palpation:", ""),
(" Tenderness:", "Present / Absent"),
(" Site of Max. Tenderness:", "RIF / Periumbilical / Diffuse / Other: ______"),
(" Guarding:", "Present / Absent"),
(" Rigidity:", "Present / Absent — Localised / Generalised"),
(" Rebound Tenderness (Blumberg's):", "Present / Absent"),
(" McBurney's Point Tenderness:", "Present / Absent"),
(" Rovsing's Sign:", "Positive / Negative"),
(" Psoas Sign:", "Positive / Negative"),
(" Obturator Sign:", "Positive / Negative"),
(" Mass Palpable:", "Present / Absent — Size: ____ Consistency: ____"),
(" Liver:", "Not palpable / Palpable — _____ cm below RCM"),
(" Spleen:", "Not palpable / Palpable"),
("Percussion:", ""),
(" Liver Dullness:", "Present / Absent"),
(" Shifting Dullness:", "Present / Absent"),
(" Tympanicity:", "Normal / Increased"),
("Auscultation:", ""),
(" Bowel Sounds:", "Normal / Increased / Decreased / Absent"),
], widths=(7, 9))
# Other systems
ot_head = doc.add_paragraph()
rot = ot_head.add_run("Other Systemic Examination")
rot.bold=True; rot.font.size=Pt(10); rot.font.color.rgb=RGBColor.from_string("2E75B6")
two_col_field_table(doc, [
("Respiratory System:", "NAD / Abnormal — Details: ___________________"),
("Cardiovascular System:", "NAD / Abnormal — Details: ___________________"),
("Central Nervous System:", "NAD / Abnormal — Details: ___________________"),
("Per Rectal Examination:", "Not done / Done — Tenderness: Yes/No — Side: ___"),
("Per Vaginal Examination (F):", "Not done / Done — Findings: ________________"),
], widths=(6.5, 9.5))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION G: INVESTIGATIONS
# ══════════════════════════════════════════════════════════════════════════════
section_bar(doc, "SECTION G: INVESTIGATIONS")
inv_head = doc.add_paragraph()
ri = inv_head.add_run("Haematological Investigations")
ri.bold=True; ri.font.size=Pt(10); ri.font.color.rgb=RGBColor.from_string("2E75B6")
four_col_table(doc, [
("Haemoglobin (g/dL):", "Total WBC Count (/cumm):"),
("Differential Count (N/L/M/E/B):", "Platelet Count (/cumm):"),
("ESR (mm/hr):", "CRP (mg/L):"),
("PCV / Haematocrit (%):", "Blood Group:"),
])
rbs_head = doc.add_paragraph()
rb = rbs_head.add_run("Biochemical Investigations")
rb.bold=True; rb.font.size=Pt(10); rb.font.color.rgb=RGBColor.from_string("2E75B6")
four_col_table(doc, [
("Blood Urea (mg/dL):", "Serum Creatinine (mg/dL):"),
("Serum Sodium (mEq/L):", "Serum Potassium (mEq/L):"),
("Fasting Blood Sugar (mg/dL):", "Serum Bilirubin (mg/dL):"),
("SGOT (U/L):", "SGPT (U/L):"),
("Serum Amylase / Lipase:", "Urine Pregnancy Test (βhCG):",),
])
uf_head = doc.add_paragraph()
ru = uf_head.add_run("Urine Examination")
ru.bold=True; ru.font.size=Pt(10); ru.font.color.rgb=RGBColor.from_string("2E75B6")
four_col_table(doc, [
("Colour / Turbidity:", "Albumin / Sugar:"),
("Pus Cells (HPF):", "RBCs (HPF):"),
("Casts / Crystals:", "Culture & Sensitivity:"),
])
rad_head = doc.add_paragraph()
rr = rad_head.add_run("Radiological Investigations")
rr.bold=True; rr.font.size=Pt(10); rr.font.color.rgb=RGBColor.from_string("2E75B6")
two_col_field_table(doc, [
("X-Ray Abdomen (Erect):", "Normal / Abnormal — Findings: ________________"),
("USG Abdomen & Pelvis:", ""),
(" Appendix Visualised:", "Yes / No"),
(" Appendix Diameter (mm):", ""),
(" Periappendiceal Collection:", "Present / Absent"),
(" Free Fluid in Pelvis:", "Present / Absent"),
(" Other Findings:", ""),
("CT Abdomen (if done):", "Not done / Done — Findings: ________________"),
], widths=(7, 9))
# ══════════════════════════════════════════════════════════════════════════════
# PAGE BREAK before Alvarado Score
# ══════════════════════════════════════════════════════════════════════════════
doc.add_page_break()
# ══════════════════════════════════════════════════════════════════════════════
# SECTION H: ALVARADO SCORE (MANTRELS)
# ══════════════════════════════════════════════════════════════════════════════
section_bar(doc, "SECTION H: ALVARADO SCORE (MANTRELS Scoring System)")
# Introduction note
intro = doc.add_paragraph()
intro.paragraph_format.space_after = Pt(8)
ir = intro.add_run(
"The Alvarado score (also called MANTRELS: Migration of pain, Anorexia, Nausea/Vomiting, "
"Tenderness in RIF, Rebound tenderness, Elevated temperature, Leucocytosis, Shift of WBC to left) "
"is a clinical scoring system used to aid in the diagnosis of acute appendicitis. "
"Maximum score = 10."
)
ir.font.size = Pt(10)
ir.font.italic = True
# Main Alvarado table
alv_table = doc.add_table(rows=1, cols=5)
alv_table.style = "Table Grid"
alv_table.alignment = WD_TABLE_ALIGNMENT.CENTER
# Header row
hdr = alv_table.rows[0].cells
headers = ["#", "CRITERION", "Parameter", "Score Possible", "Score Obtained"]
col_widths = [1, 5, 6, 2.5, 2.5]
for i, (h, w) in enumerate(zip(headers, col_widths)):
shade_cell(hdr[i], "1F3864")
set_col_width(hdr[i], w)
p = hdr[i].paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = p.add_run(h)
r.bold = True; r.font.size = Pt(10)
r.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
# Data rows: (number, letter, criterion, parameter_hint, max_score)
criteria = [
("1", "M", "Migration of Pain to RIF",
"Pain started periumbilical / diffuse\nand shifted to Right Iliac Fossa:\nYes / No", "1"),
("2", "A", "Anorexia",
"Loss of appetite present:\nYes / No", "1"),
("3", "N", "Nausea / Vomiting",
"Nausea or vomiting present:\nYes / No", "1"),
("4", "T", "Tenderness in RIF",
"Tenderness at McBurney's point\nor RIF on palpation:\nPresent / Absent", "2"),
("5", "R", "Rebound Tenderness",
"Rebound tenderness at RIF:\nPresent / Absent", "1"),
("6", "E", "Elevated Temperature",
"Temperature > 37.3 °C (99.1 °F):\nPresent / Absent\nRecorded Temp: ________", "1"),
("7", "L", "Leucocytosis",
"Total WBC Count > 10,000/cumm:\nPresent / Absent\nActual Count: ________", "2"),
("8", "S", "Shift of WBC Count to Left",
"Neutrophilia > 75% or band forms present:\nPresent / Absent\nNeutrophil %: ________", "1"),
]
for num, letter, criterion, param, max_sc in criteria:
row = alv_table.add_row()
cells = row.cells
set_col_width(cells[0], 1); set_col_width(cells[1], 5)
set_col_width(cells[2], 6); set_col_width(cells[3], 2.5); set_col_width(cells[4], 2.5)
shade_cell(cells[0], "2E75B6")
p0 = cells[0].paragraphs[0]; p0.alignment = WD_ALIGN_PARAGRAPH.CENTER
r0 = p0.add_run(num); r0.bold=True; r0.font.size=Pt(10); r0.font.color.rgb=RGBColor(0xFF,0xFF,0xFF)
shade_cell(cells[1], "D9E8FB")
p1 = cells[1].paragraphs[0]
r1a = p1.add_run(f"({letter}) "); r1a.bold=True; r1a.font.size=Pt(10); r1a.font.color.rgb=RGBColor.from_string("1F3864")
r1b = p1.add_run(criterion); r1b.bold=True; r1b.font.size=Pt(10)
cells[2].paragraphs[0].add_run(param).font.size = Pt(9)
p3 = cells[3].paragraphs[0]; p3.alignment = WD_ALIGN_PARAGRAPH.CENTER
r3 = p3.add_run(max_sc); r3.bold=True; r3.font.size=Pt(11)
# Score obtained cell - blank for clinician
p4 = cells[4].paragraphs[0]; p4.alignment = WD_ALIGN_PARAGRAPH.CENTER
cells[4].paragraphs[0].add_run("").font.size = Pt(11)
# Total row
tot_row = alv_table.add_row()
for i, cell in enumerate(tot_row.cells):
shade_cell(cell, "1F3864")
set_col_width(cell, col_widths[i])
tot_row.cells[0].merge(tot_row.cells[3])
p_tot = tot_row.cells[0].paragraphs[0]
p_tot.alignment = WD_ALIGN_PARAGRAPH.RIGHT
r_tot = p_tot.add_run("TOTAL ALVARADO SCORE → ")
r_tot.bold=True; r_tot.font.size=Pt(11); r_tot.font.color.rgb=RGBColor(0xFF,0xFF,0xFF)
p4t = tot_row.cells[1].paragraphs[0]; p4t.alignment = WD_ALIGN_PARAGRAPH.CENTER
r4t = p4t.add_run(" / 10"); r4t.bold=True; r4t.font.size=Pt(12); r4t.font.color.rgb=RGBColor(0xFF,0xFF,0xFF)
doc.add_paragraph("")
# ── Score Interpretation ──────────────────────────────────────────────────────
interp_head = doc.add_paragraph()
ri2 = interp_head.add_run("Score Interpretation")
ri2.bold=True; ri2.font.size=Pt(11); ri2.font.color.rgb=RGBColor.from_string("1F3864")
interp_table = doc.add_table(rows=1, cols=3)
interp_table.style = "Table Grid"
interp_table.alignment = WD_TABLE_ALIGNMENT.CENTER
ih = interp_table.rows[0].cells
for hdr_text, cell in zip(["Score Range", "Probability of Appendicitis", "Suggested Action"], ih):
shade_cell(cell, "1F3864")
hp = cell.paragraphs[0]; hp.alignment = WD_ALIGN_PARAGRAPH.CENTER
hr = hp.add_run(hdr_text); hr.bold=True; hr.font.size=Pt(10); hr.font.color.rgb=RGBColor(0xFF,0xFF,0xFF)
interp_data = [
("1 – 4", "Low probability", "Observation; consider other diagnoses"),
("5 – 6", "Moderate probability", "Active observation, repeat examination"),
("7 – 8", "High probability", "Surgical consultation; probable appendicitis"),
("9 – 10", "Very high probability", "Immediate surgical intervention likely required"),
]
fills = ["EBF0FA", "FFF2CC", "FCE4D6", "FFCCCC"]
for (sc, prob, action), fill in zip(interp_data, fills):
row = interp_table.add_row()
shade_cell(row.cells[0], fill); shade_cell(row.cells[1], fill); shade_cell(row.cells[2], fill)
for cell, text in zip(row.cells, [sc, prob, action]):
p = cell.paragraphs[0]; p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = p.add_run(text); r.font.size=Pt(10)
doc.add_paragraph("")
# ══════════════════════════════════════════════════════════════════════════════
# SECTION I: FINAL DIAGNOSIS & OUTCOME
# ══════════════════════════════════════════════════════════════════════════════
section_bar(doc, "SECTION I: CLINICAL DECISION, FINAL DIAGNOSIS & OUTCOME")
two_col_field_table(doc, [
("Clinical Decision (Based on Score):", "Conservative Management / Surgical Intervention"),
("Operative Findings (if operated):", ""),
(" Appendix Status:", "Normal / Inflamed / Perforated / Gangrenous / Abscess"),
(" Other Intraoperative Findings:", ""),
(" Type of Surgery:", "Open Appendicectomy / Laparoscopic / Other"),
("Histopathology Report:", ""),
(" HPE Diagnosis:", "Acute Appendicitis (Confirmed) / Normal Appendix / Other: ____"),
("Final Diagnosis:", "Acute Appendicitis / Other: _________________________"),
("Outcome:", "Discharged / LAMA / Referred / Expired"),
("Date of Discharge:", "DD / MM / YYYY"),
("Duration of Hospital Stay:", "Days"),
("Complications (if any):", "None / Wound Infection / Abscess / Other: ___"),
], widths=(6.5, 9.5))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION J: CLINICIAN'S REMARKS & SIGNATURE
# ══════════════════════════════════════════════════════════════════════════════
section_bar(doc, "SECTION J: RESEARCHER / CLINICIAN DETAILS & SIGNATURE")
two_col_field_table(doc, [
("Name of Examiner:", ""),
("Designation:", ""),
("Department:", ""),
("Institution:", ""),
("Date:", "DD / MM / YYYY"),
("Signature:", ""),
("Supervisor / Guide Name:", ""),
("Supervisor Signature:", ""),
], widths=(6, 10))
# Footer note
foot = doc.add_paragraph()
foot.alignment = WD_ALIGN_PARAGRAPH.CENTER
fr = foot.add_run(
"This CRF is designed for academic / research purposes. All patient data is confidential. "
"Please maintain patient anonymity as per Institutional Ethics Committee guidelines."
)
fr.font.size = Pt(9); fr.font.italic=True; fr.font.color.rgb=RGBColor(0x66,0x66,0x66)
# ── Save ──────────────────────────────────────────────────────────────────────
output_path = "/tmp/workspace/alvarado-crf/Alvarado_Score_CRF.docx"
doc.save(output_path)
print(f"Saved: {output_path}")
cd /tmp/workspace/alvarado-crf && python3 build_crf.py 2>&1
python3 -c " from docx import Document doc = Document('/tmp/workspace/alvarado-crf/Alvarado_Score_CRF.docx') for p in doc.paragraphs: if p.text.strip(): print(f'[{p.style.name}] {p.text[:80]}') " 2>&1 | head -60
ls -lh /tmp/workspace/alvarado-crf/Alvarado_Score_CRF.docx
Alvarado Score CRF
Word Document · DOCX