Write on surgical audit and Ethics in surgical practice. discuss evidence-based surgery- from standard literature like sabiston/bailey , if possible in an easy memorable format/Table in a downloadable one/two page pdf/image.
mkdir -p /tmp/workspace/surgical-audit && ls /tmp/workspace/surgical-audit/
~/surgical-audit/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer,
HRFlowable, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import PageBreak
# ── Colour palette ──────────────────────────────────────────────────────────
DARK_BLUE = colors.HexColor("#1a3a5c")
MID_BLUE = colors.HexColor("#2d6a9f")
LIGHT_BLUE = colors.HexColor("#d6e8f7")
ACCENT = colors.HexColor("#e8511a")
GOLD = colors.HexColor("#f0a500")
PALE_GOLD = colors.HexColor("#fff8e1")
PALE_GREEN = colors.HexColor("#e8f5e9")
PALE_RED = colors.HexColor("#fce4ec")
WHITE = colors.white
GREY_BG = colors.HexColor("#f5f7fa")
DARK_GREY = colors.HexColor("#333333")
MID_GREY = colors.HexColor("#666666")
# ── Styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
banner_style = S("banner",
fontName="Helvetica-Bold", fontSize=18,
textColor=WHITE, alignment=TA_CENTER,
spaceAfter=2, spaceBefore=2, leading=22)
subtitle_style = S("subtitle",
fontName="Helvetica", fontSize=9,
textColor=colors.HexColor("#cce4ff"), alignment=TA_CENTER,
spaceAfter=2, leading=11)
section_title = S("sec_title",
fontName="Helvetica-Bold", fontSize=11,
textColor=WHITE, alignment=TA_LEFT,
spaceAfter=1, spaceBefore=1, leading=13)
body = S("body",
fontName="Helvetica", fontSize=8,
textColor=DARK_GREY, leading=10,
spaceAfter=2, alignment=TA_JUSTIFY)
body_bold = S("body_bold",
fontName="Helvetica-Bold", fontSize=8,
textColor=DARK_GREY, leading=10, spaceAfter=2)
small = S("small",
fontName="Helvetica", fontSize=7,
textColor=MID_GREY, leading=9, spaceAfter=1)
source_style = S("source",
fontName="Helvetica-Oblique", fontSize=7,
textColor=MID_GREY, alignment=TA_CENTER, spaceAfter=0)
cell_hdr = S("cell_hdr",
fontName="Helvetica-Bold", fontSize=8,
textColor=WHITE, leading=10, alignment=TA_LEFT)
cell_body = S("cell_body",
fontName="Helvetica", fontSize=7.5,
textColor=DARK_GREY, leading=9.5, alignment=TA_LEFT)
cell_body_bold = S("cell_body_bold",
fontName="Helvetica-Bold", fontSize=7.5,
textColor=DARK_GREY, leading=9.5, alignment=TA_LEFT)
bullet_style = S("bullet",
fontName="Helvetica", fontSize=7.5,
textColor=DARK_GREY, leading=9.5,
leftIndent=8, bulletIndent=0,
spaceAfter=1, alignment=TA_LEFT)
num_style = S("num",
fontName="Helvetica-Bold", fontSize=8.5,
textColor=ACCENT, alignment=TA_CENTER,
leading=10)
# ── Helper: coloured section header row ─────────────────────────────────────
def sec_hdr(text, bg=MID_BLUE, span=None):
"""Returns a single-row Table acting as a section header."""
p = Paragraph(text, section_title)
cols = [p]
t = Table([cols], colWidths=[17.4*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("ROWBACKGROUNDS", (0,0), (-1,-1), [bg]),
]))
return t
def mini_hdr(text, bg=DARK_BLUE):
p = Paragraph(f"<b>{text}</b>", cell_hdr)
t = Table([[p]], colWidths=[17.4*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("LEFTPADDING", (0,0), (-1,-1), 5),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
return t
# ── Document setup ───────────────────────────────────────────────────────────
OUTPUT = "/tmp/workspace/surgical-audit/Surgical_Audit_Ethics_EBS.pdf"
doc = SimpleDocTemplate(
OUTPUT, pagesize=A4,
leftMargin=1.3*cm, rightMargin=1.3*cm,
topMargin=1.2*cm, bottomMargin=1.2*cm
)
story = []
# ════════════════════════════════════════════════════════════════════════════
# BANNER
# ════════════════════════════════════════════════════════════════════════════
banner_data = [[Paragraph("SURGICAL AUDIT · ETHICS · EVIDENCE-BASED SURGERY", banner_style)]]
banner = Table(banner_data, colWidths=[17.4*cm])
banner.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
]))
story.append(banner)
sub = Table([[Paragraph("Sources: Sabiston Textbook of Surgery (Elsevier) · Bailey & Love's Short Practice of Surgery 28e", subtitle_style)]], colWidths=[17.4*cm])
sub.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), MID_BLUE),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
]))
story.append(sub)
story.append(Spacer(1, 4))
# ════════════════════════════════════════════════════════════════════════════
# PAGE 1 – 2 columns side-by-side: Audit | Ethics
# ════════════════════════════════════════════════════════════════════════════
# ─── LEFT COLUMN: SURGICAL AUDIT ────────────────────────────────────────────
def make_audit_col():
el = []
# Definition box
def_data = [[Paragraph(
"<b>SURGICAL AUDIT</b> — a formal, cyclic process comparing actual "
"surgical care (structure, process, outcome) against <i>explicit "
"criteria and defined standards</i>, to drive continuous improvement.",
cell_body)]]
def_tbl = Table(def_data, colWidths=[8.2*cm])
def_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE),
("BOX", (0,0), (-1,-1), 0.8, MID_BLUE),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
]))
el.append(def_tbl)
el.append(Spacer(1, 4))
# Audit vs Research 3-Q table
el.append(Paragraph("<b>AUDIT vs RESEARCH — 3 Key Questions (HRA)</b>", body_bold))
qdata = [
[Paragraph("<b>#</b>", cell_hdr),
Paragraph("<b>Question</b>", cell_hdr),
Paragraph("<b>→ Audit if…</b>", cell_hdr)],
[Paragraph("1", cell_body), Paragraph("Randomisation?", cell_body),
Paragraph("No", cell_body)],
[Paragraph("2", cell_body), Paragraph("Treatment changed from standard?", cell_body),
Paragraph("No", cell_body)],
[Paragraph("3", cell_body), Paragraph("Generalisable findings?", cell_body),
Paragraph("No", cell_body)],
]
qt = Table(qdata, colWidths=[0.7*cm, 4.8*cm, 2.6*cm])
qt.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MID_BLUE),
("BACKGROUND", (0,1), (-1,-1), LIGHT_BLUE),
("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_BLUE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, MID_BLUE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTSIZE", (0,0), (-1,-1), 7.5),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 3),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
el.append(qt)
el.append(Spacer(1, 5))
# 7-step audit cycle
el.append(Paragraph("<b>THE AUDIT CYCLE — 7 Steps (Bailey & Love)</b>", body_bold))
steps = [
("1", "Define the audit question (MDT)", LIGHT_BLUE),
("2", "Identify evidence & current standards", WHITE),
("3", "Design audit — measure vs agreed standards", LIGHT_BLUE),
("4", "Measure over agreed interval", WHITE),
("5", "Analyse & compare vs standards", LIGHT_BLUE),
("6a", "Standards met? → Re-audit at interval", PALE_GREEN),
("6b", "Gap found? → Identify intervention (training, equipment, policy)", PALE_RED),
("7", "RE-AUDIT (closes the loop)", GOLD),
]
sdata = [[Paragraph(f"<b>{n}</b>", num_style),
Paragraph(txt, cell_body)] for n, txt, _ in steps]
bg_cmds = [("BACKGROUND", (0, i+1), (-1, i+1), steps[i][2]) for i in range(len(steps))]
st = Table(sdata, colWidths=[0.9*cm, 7.3*cm])
style_cmds = [
("GRID", (0,0), (-1,-1), 0.4, MID_BLUE),
("ALIGN", (0,0), (0,-1), "CENTER"),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 3),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("BACKGROUND", (0, 7), (-1, 7), GOLD),
("TEXTCOLOR", (0, 7), (-1, 7), DARK_BLUE),
] + bg_cmds
st.setStyle(TableStyle(style_cmds))
el.append(st)
el.append(Spacer(1, 4))
# Types of audit
el.append(Paragraph("<b>TYPES OF SURGICAL AUDIT</b>", body_bold))
tdata = [
[Paragraph("<b>Type</b>", cell_hdr), Paragraph("<b>Scope</b>", cell_hdr), Paragraph("<b>Example</b>", cell_hdr)],
[Paragraph("Local/single-site", cell_body), Paragraph("Departmental M&M meetings", cell_body), Paragraph("SSI rates in one hospital", cell_body)],
[Paragraph("Multisite/National", cell_body), Paragraph("Regional or national collaborative", cell_body), Paragraph("NCEPOD, NNAP", cell_body)],
[Paragraph("Snapshot audit", cell_body), Paragraph("Prospective, time-limited, multi-centre", cell_body), Paragraph("EuroSurg, STARSurg", cell_body)],
]
tt = Table(tdata, colWidths=[2.3*cm, 3.2*cm, 2.7*cm])
tt.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MID_BLUE),
("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_BLUE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, MID_BLUE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTSIZE", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 3),
("RIGHTPADDING", (0,0), (-1,-1), 3),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
el.append(tt)
el.append(Spacer(1, 3))
el.append(Paragraph("★ Surgeons must maintain personal outcome data for revalidation (UK GMC requirement)", small))
return el
# ─── RIGHT COLUMN: SURGICAL ETHICS ──────────────────────────────────────────
def make_ethics_col():
el = []
# 4 Pillars
el.append(Paragraph("<b>4 PILLARS OF MEDICAL ETHICS (Beauchamp & Childress)</b>", body_bold))
pillars = [
("⚖ Autonomy", "Respect patient's right to decide; valid informed consent required", PALE_GREEN),
("🏥 Beneficence", "Act in patient's best interest; balance benefit vs harm", LIGHT_BLUE),
("✘ Non-maleficence", "'First, do no harm' — minimise surgical risk", PALE_RED),
("⚡ Justice", "Fair resource allocation; equal access to surgery", PALE_GOLD),
]
pdata = [[Paragraph(f"<b>{p}</b>", cell_body_bold), Paragraph(d, cell_body)]
for p, d, _ in pillars]
bg_p = [("BACKGROUND", (0, i), (-1, i), pillars[i][2]) for i in range(len(pillars))]
pt = Table(pdata, colWidths=[2.6*cm, 5.6*cm])
pt.setStyle(TableStyle([
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#999999")),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 3),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("VALIGN", (0,0), (-1,-1), "TOP"),
] + bg_p))
el.append(pt)
el.append(Spacer(1, 4))
# Informed Consent checklist
el.append(Paragraph("<b>INFORMED CONSENT — ELEMENTS (Mnemonic: <font color='#e8511a'>VALID-DC</font>)</b>", body_bold))
consent = [
("V", "Voluntary", "Free from coercion or undue influence"),
("A", "Adequate info", "Nature, purpose, benefits explained"),
("L", "Likelihood of risks", "Significant risks disclosed (\"material test\")"),
("I", "Intended procedure", "Patient knows exactly what will be done"),
("D", "Disclosure of alternatives", "Including no-treatment option"),
("D", "Decision capacity", "Patient has mental capacity to decide"),
("C", "Confirmation", "Verbal or written, documented in notes"),
]
cdata = [[Paragraph(f"<b>{a}</b>", num_style),
Paragraph(f"<b>{t}</b>", cell_body_bold),
Paragraph(d, cell_body)] for a, t, d in consent]
ct = Table(cdata, colWidths=[0.6*cm, 2.4*cm, 5.2*cm])
ct.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#2d9f6a")),
("ROWBACKGROUNDS", (0,0), (-1,-1), [PALE_GREEN, WHITE]),
("TEXTCOLOR", (0,0), (0,-1), colors.HexColor("#2d9f6a")),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#aaddbb")),
("FONTNAME", (0,0), (0,-1), "Helvetica-Bold"),
("LEFTPADDING", (0,0), (-1,-1), 3),
("RIGHTPADDING", (0,0), (-1,-1), 3),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING", (0,0), (-1,-1), 2),
("FONTSIZE", (0,0), (-1,-1), 7.5),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
el.append(ct)
el.append(Spacer(1, 4))
# Key ethical issues in surgery
el.append(Paragraph("<b>ETHICAL ISSUES IN SURGICAL PRACTICE</b>", body_bold))
issues = [
("Disclosure & honesty", "Duty to disclose complications, errors; open disclosure policy"),
("Surgical innovation", "New procedures need IRB/ethics approval; IDEAL framework"),
("Futile surgery", "Avoid operating when benefit is nil; shared decision-making"),
("Conflicts of interest", "Industry ties, financial incentives must be transparent"),
("Trainee involvement", "Patient must be informed if trainee performing key steps"),
("End-of-life surgery", "Assess goals of care; palliative vs curative intent"),
("Resource allocation", "Evidence-based, fair criteria for high-cost procedures"),
]
idata = [[Paragraph(f"<b>{t}</b>", cell_body_bold), Paragraph(d, cell_body)] for t, d in issues]
it = Table(idata, colWidths=[2.6*cm, 5.6*cm])
it.setStyle(TableStyle([
("ROWBACKGROUNDS", (0,0), (-1,-1), [PALE_GOLD, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#ccbb88")),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 3),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("FONTSIZE", (0,0), (-1,-1), 7.5),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
el.append(it)
return el
# build 2-column layout for page 1
audit_col_hdr = Table([[Paragraph("🔍 SURGICAL AUDIT", section_title)]], colWidths=[8.5*cm])
audit_col_hdr.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), MID_BLUE),
("LEFTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
]))
ethics_col_hdr = Table([[Paragraph("⚖ ETHICS IN SURGICAL PRACTICE", section_title)]], colWidths=[8.5*cm])
ethics_col_hdr.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), colors.HexColor("#2d6a3a")),
("LEFTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
]))
# Combine into 2-col table
audit_items = make_audit_col()
ethics_items = make_ethics_col()
def items_to_cell(items):
from reportlab.platypus import KeepInFrame
inner = Table([[i] for i in items], colWidths=[8.2*cm])
inner.setStyle(TableStyle([
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 0),
("TOPPADDING", (0,0), (-1,-1), 1),
("BOTTOMPADDING", (0,0), (-1,-1), 1),
]))
return inner
audit_cell = items_to_cell(audit_items)
ethics_cell = items_to_cell(ethics_items)
two_col = Table(
[[audit_col_hdr, ethics_col_hdr],
[audit_cell, ethics_cell]],
colWidths=[8.7*cm, 8.7*cm]
)
two_col.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 0),
("TOPPADDING", (0,0), (-1,-1), 0),
("BOTTOMPADDING", (0,0), (-1,-1), 0),
("LINEAFTER", (0,0), (0,-1), 1, MID_BLUE),
("RIGHTPADDING", (0,0), (0,-1), 5),
("LEFTPADDING", (1,0), (1,-1), 5),
]))
story.append(two_col)
story.append(Spacer(1, 3))
story.append(Paragraph("Sources: Bailey & Love 28e, Ch.13 | Sabiston Textbook of Surgery, Ch.6", source_style))
# ════════════════════════════════════════════════════════════════════════════
# PAGE 2 – EVIDENCE-BASED SURGERY
# ════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())
# Banner P2
banner2_data = [[Paragraph("EVIDENCE-BASED SURGERY (EBS)", banner_style)]]
banner2 = Table(banner2_data, colWidths=[17.4*cm])
banner2.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
]))
story.append(banner2)
sub2 = Table([[Paragraph("Sabiston Ch.6 — Brooke, Greenup & Haynes | Bailey & Love 28e, Ch.13", subtitle_style)]], colWidths=[17.4*cm])
sub2.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), MID_BLUE),
("TOPPADDING", (0,0), (-1,-1), 2), ("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
story.append(sub2)
story.append(Spacer(1, 5))
# Defn box
defn2 = Table([[Paragraph(
"<b>Evidence-Based Surgery</b> integrates the <b>best available research evidence</b> with "
"<b>clinical expertise</b> and <b>individual patient values</b> to guide surgical decisions. "
"No surgeon can know all evidence — EBS provides a systematic framework to find and apply it. "
"<i>(Sabiston)</i>", cell_body)]], colWidths=[17.4*cm])
defn2.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE),
("BOX", (0,0), (-1,-1), 1, MID_BLUE),
("LEFTPADDING", (0,0), (-1,-1), 6), ("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 4), ("BOTTOMPADDING", (0,0), (-1,-1), 4),
]))
story.append(defn2)
story.append(Spacer(1, 4))
# 5 A's mnemonic
story.append(Paragraph("<b>THE 5 A's OF EBS (Sabiston, Fig 6.1) — Mnemonic: <font color='#e8511a'>ASK → ACQUIRE → APPRAISE → APPLY → ASSESS</font></b>", body_bold))
fives = [
("A1", "ASK", "Frame a clinical question using PICOT framework", "P-I-C-O-T", PALE_GREEN),
("A2", "ACQUIRE", "Search MEDLINE, EMBASE, Cochrane for relevant evidence", "Databases", LIGHT_BLUE),
("A3", "APPRAISE", "Critically evaluate study design, bias, confounders", "Critical appraisal", PALE_GOLD),
("A4", "APPLY", "Integrate evidence with patient values & clinical expertise", "Shared decision", PALE_RED),
("A5", "ASSESS", "Audit outcome — does it match the evidence? (close the loop)", "Re-audit", PALE_GREEN),
]
fdata = [[Paragraph(f"<b>{a}</b>", num_style),
Paragraph(f"<b>{s}</b>", cell_body_bold),
Paragraph(d, cell_body),
Paragraph(f"<i>{t}</i>", small)] for a, s, d, t, _ in fives]
ft = Table(fdata, colWidths=[0.8*cm, 2.5*cm, 10.5*cm, 3.3*cm])
bg_f = [("BACKGROUND", (0, i), (-1, i), fives[i][4]) for i in range(len(fives))]
ft.setStyle(TableStyle([
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#aaaacc")),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 3),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TEXTCOLOR", (0,0), (0,-1), ACCENT),
("FONTNAME", (0,0), (0,-1), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 7.5),
] + bg_f))
story.append(ft)
story.append(Spacer(1, 5))
# PICOT table
story.append(Paragraph("<b>PICOT FRAMEWORK (Sabiston Table 6.1) — Evaluating Research Questions</b>", body_bold))
picot = [
[Paragraph("<b>Letter</b>", cell_hdr), Paragraph("<b>Element</b>", cell_hdr),
Paragraph("<b>Question to ask</b>", cell_hdr), Paragraph("<b>Example</b>", cell_hdr)],
[Paragraph("<b>P</b>", num_style), Paragraph("Population / Problem", cell_body),
Paragraph("Is the study population comparable to my patient?", cell_body),
Paragraph("Adults with colorectal cancer", cell_body)],
[Paragraph("<b>I</b>", num_style), Paragraph("Intervention", cell_body),
Paragraph("What is being tested?", cell_body),
Paragraph("Laparoscopic vs open colectomy", cell_body)],
[Paragraph("<b>C</b>", num_style), Paragraph("Comparison", cell_body),
Paragraph("What is it compared to?", cell_body),
Paragraph("Open resection", cell_body)],
[Paragraph("<b>O</b>", num_style), Paragraph("Outcome", cell_body),
Paragraph("What results were measured?", cell_body),
Paragraph("30-day morbidity, LOS, survival", cell_body)],
[Paragraph("<b>T</b>", num_style), Paragraph("Time frame", cell_body),
Paragraph("How long was follow-up?", cell_body),
Paragraph("5-year disease-free survival", cell_body)],
]
pt2 = Table(picot, colWidths=[1.0*cm, 3.2*cm, 7.5*cm, 5.4*cm])
pt2.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_BLUE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, MID_BLUE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("TEXTCOLOR", (0,1), (0,-1), ACCENT),
("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 7.5),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 3),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(pt2)
story.append(Spacer(1, 5))
# ─── Levels of Evidence ─────────────────────────────────────────────────────
story.append(Paragraph("<b>LEVELS OF EVIDENCE (Oxford / GRADE) — Hierarchy for Surgical Evidence</b>", body_bold))
loe = [
[Paragraph("<b>Level</b>", cell_hdr), Paragraph("<b>Study Type</b>", cell_hdr),
Paragraph("<b>Strength</b>", cell_hdr), Paragraph("<b>Limitations in Surgery</b>", cell_hdr)],
[Paragraph("I", cell_body_bold), Paragraph("Systematic Review / Meta-analysis of RCTs", cell_body),
Paragraph("★★★★★ Highest", cell_body),
Paragraph("Few surgical RCTs; blinding difficult", cell_body)],
[Paragraph("II", cell_body_bold), Paragraph("Well-designed RCT", cell_body),
Paragraph("★★★★☆ High", cell_body),
Paragraph("Sham surgery ethical dilemma; learning curve bias", cell_body)],
[Paragraph("III", cell_body_bold), Paragraph("Cohort / Case-control study", cell_body),
Paragraph("★★★☆☆ Moderate", cell_body),
Paragraph("Selection bias; confounding", cell_body)],
[Paragraph("IV", cell_body_bold), Paragraph("Case series / Case report", cell_body),
Paragraph("★★☆☆☆ Low", cell_body),
Paragraph("No controls; publication bias", cell_body)],
[Paragraph("V", cell_body_bold), Paragraph("Expert opinion / Consensus", cell_body),
Paragraph("★☆☆☆☆ Lowest", cell_body),
Paragraph("Most of historical surgical practice!", cell_body)],
]
le_bg = [PALE_GREEN, LIGHT_BLUE, LIGHT_BLUE, PALE_GOLD, PALE_RED, PALE_RED]
let = Table(loe, colWidths=[1.0*cm, 5.5*cm, 4.0*cm, 6.6*cm])
let.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("ROWBACKGROUNDS", (0,1), (-1,-1), [PALE_GREEN, LIGHT_BLUE, LIGHT_BLUE, PALE_GOLD, PALE_RED]),
("GRID", (0,0), (-1,-1), 0.4, MID_BLUE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTSIZE", (0,0), (-1,-1), 7.5),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 3),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(let)
story.append(Spacer(1, 5))
# ─── Study designs (Bailey & Love Table 13.2) ───────────────────────────────
story.append(Paragraph("<b>STUDY TYPES IN SURGICAL RESEARCH (Bailey & Love, Table 13.2)</b>", body_bold))
study_types = [
[Paragraph("<b>Type</b>", cell_hdr), Paragraph("<b>Definition</b>", cell_hdr), Paragraph("<b>Surgical Use</b>", cell_hdr)],
[Paragraph("Observational\n(Retro/Prospective)", cell_body),
Paragraph("Evaluation of condition/treatment in a defined population without intervention", cell_body),
Paragraph("Complication rates, outcomes databases, NCEPOD", cell_body)],
[Paragraph("Case-control", cell_body),
Paragraph("Compares patients with a condition vs matched controls (looking backward)", cell_body),
Paragraph("Risk factors for anastomotic leak", cell_body)],
[Paragraph("Cohort", cell_body),
Paragraph("Follows groups with/without exposure over time (forward-looking)", cell_body),
Paragraph("Survival after hepatic resection", cell_body)],
[Paragraph("RCT", cell_body),
Paragraph("Gold standard — subjects randomised to intervention vs control", cell_body),
Paragraph("Laparoscopic vs open inguinal hernia repair", cell_body)],
[Paragraph("Systematic Review\n& Meta-analysis", cell_body),
Paragraph("Aggregates results from multiple RCTs/cohort studies", cell_body),
Paragraph("Cochrane reviews of surgical techniques", cell_body)],
]
stt = Table(study_types, colWidths=[3.0*cm, 8.4*cm, 5.7*cm])
stt.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#1a3a5c")),
("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_BLUE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, MID_BLUE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTSIZE", (0,0), (-1,-1), 7.5),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 3),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(stt)
story.append(Spacer(1, 4))
# Key takeaway box
key_box = Table([[Paragraph(
"⭐ <b>KEY MNEMONIC — Remember EBS as FAIR:</b> "
"<font color='#e8511a'><b>F</b></font>rame the question (PICOT) | "
"<font color='#e8511a'><b>A</b></font>cquire & appraise (study design + bias) | "
"<font color='#e8511a'><b>I</b></font>ntegrate with patient values | "
"<font color='#e8511a'><b>R</b></font>eaudit outcomes",
cell_body)]], colWidths=[17.4*cm])
key_box.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), PALE_GOLD),
("BOX", (0,0), (-1,-1), 1.2, GOLD),
("LEFTPADDING", (0,0), (-1,-1), 6), ("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 5),
]))
story.append(key_box)
story.append(Spacer(1, 3))
story.append(Paragraph(
"Sources: Sabiston Textbook of Surgery (Elsevier, 21e) Ch.6 — Brooke, Greenup & Haynes | "
"Bailey & Love's Short Practice of Surgery (28e) Ch.13 | Cochrane Library | Oxford CEBM",
source_style))
# ── Build ────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF saved: {OUTPUT}")
cd /tmp/workspace/surgical-audit && python generate_pdf.py 2>&1
ls -lh /tmp/workspace/surgical-audit/
Surgical Audit Ethics EBS
PDF Document · PDF
| Topic | Mnemonic |
|---|---|
| EBM process | 5 A's: Ask · Acquire · Appraise · Apply · Assess |
| Research question | PICOT: Population · Intervention · Comparison · Outcome · Time |
| Informed consent | VALID-DC: Voluntary · Adequate info · Likelihood of risks · Intended procedure · Disclosure of alternatives · Decision capacity · Confirmation |
| Ethics pillars | ABNI: Autonomy · Beneficence · Non-maleficence · Justice |
| EBS summary | FAIR: Frame · Acquire/Appraise · Integrate · Re-audit |