Create a beautiful pdf on long format answers according to the numbers given to each question at least 1 A4 sheet long Take reference from standard surgery books and also add diagrams or flowchart if any needed Don't answer mcqs
mkdir -p /tmp/workspace/surgery-exam && ls /tmp/workspace/surgery-exam/
~/surgery-exam/generate_pdf.py
#!/usr/bin/env python3
"""
MBBS Phase 3 Part 2 - General Surgery & Allied
Long Answer Questions - Comprehensive Study PDF
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.lib import colors
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Arrow, Polygon, Circle
from reportlab.graphics.charts.flowcharts import *
from reportlab.graphics import renderPDF
import io
# ─── Colour palette ───────────────────────────────────────────────────────────
DARK_BLUE = colors.HexColor('#1a2a5e')
MED_BLUE = colors.HexColor('#2563eb')
LIGHT_BLUE = colors.HexColor('#dbeafe')
ACCENT_TEAL = colors.HexColor('#0e7490')
ACCENT_GREEN= colors.HexColor('#15803d')
GOLD = colors.HexColor('#b45309')
LIGHT_GOLD = colors.HexColor('#fef9c3')
LIGHT_GREEN = colors.HexColor('#dcfce7')
LIGHT_TEAL = colors.HexColor('#ccfbf1')
RED = colors.HexColor('#dc2626')
LIGHT_RED = colors.HexColor('#fee2e2')
PURPLE = colors.HexColor('#7c3aed')
LIGHT_PURPLE= colors.HexColor('#ede9fe')
GREY_BG = colors.HexColor('#f8fafc')
GREY_BORDER = colors.HexColor('#e2e8f0')
WHITE = colors.white
BLACK = colors.black
# ─── Custom Flowables ─────────────────────────────────────────────────────────
class ColoredBox(Flowable):
"""A rounded colored info box."""
def __init__(self, content_paragraphs, bg_color=LIGHT_BLUE, border_color=MED_BLUE,
left_accent=True, width=None):
self.content = content_paragraphs
self.bg = bg_color
self.border = border_color
self.left_accent = left_accent
self._width = width or (A4[0] - 4*cm)
super().__init__()
def wrap(self, availWidth, availHeight):
self._width = availWidth
return self._width, 0 # height computed in draw
def draw(self):
pass # rendered via Table
def make_box(paragraphs, bg=LIGHT_BLUE, border=MED_BLUE, width=None):
"""Return a Table acting as a styled box."""
w = width or (A4[0] - 4*cm)
data = [[paragraphs]]
t = Table(data, colWidths=[w])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('BOX', (0,0), (-1,-1), 1.5, border),
('LEFTPADDING', (0,0), (-1,-1), 10),
('RIGHTPADDING', (0,0), (-1,-1), 10),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
('ROWBACKGROUNDS', (0,0), (-1,-1), [bg]),
]))
return t
def make_two_col_table(left_items, right_items, headers=("",""), bg=LIGHT_BLUE, border=MED_BLUE):
"""Two-column comparison table."""
data = [list(headers)]
max_rows = max(len(left_items), len(right_items))
for i in range(max_rows):
l = left_items[i] if i < len(left_items) else ""
r = right_items[i] if i < len(right_items) else ""
data.append([l, r])
col_w = (A4[0] - 4*cm) / 2
t = Table(data, colWidths=[col_w, col_w])
style = [
('BACKGROUND', (0,0), (-1,0), border),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('ALIGN', (0,0), (-1,-1), 'LEFT'),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('BACKGROUND', (0,1), (-1,-1), bg),
('ROWBACKGROUNDS', (0,1), (-1,-1), [bg, WHITE]),
('GRID', (0,0), (-1,-1), 0.5, border),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('FONTSIZE', (0,1), (-1,-1), 9),
]
t.setStyle(TableStyle(style))
return t
def make_table(headers, rows, bg=LIGHT_BLUE, border=MED_BLUE):
data = [headers] + rows
n_cols = len(headers)
col_w = (A4[0] - 4*cm) / n_cols
t = Table(data, colWidths=[col_w]*n_cols)
style = [
('BACKGROUND', (0,0), (-1,0), border),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('ALIGN', (0,0), (-1,-1), 'LEFT'),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('BACKGROUND', (0,1), (-1,-1), bg),
('ROWBACKGROUNDS', (0,1), (-1,-1), [bg, WHITE]),
('GRID', (0,0), (-1,-1), 0.5, border),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('FONTSIZE', (0,1), (-1,-1), 9),
]
t.setStyle(TableStyle(style))
return t
# ─── Flowchart using Drawing ──────────────────────────────────────────────────
def make_flowchart(steps, colors_list=None, width=None, title=""):
"""Create a simple vertical flowchart."""
w = width or (A4[0] - 4*cm)
box_h = 30
box_w = w - 20
arrow_h = 20
total_h = len(steps) * (box_h + arrow_h) + 20 + (30 if title else 0)
d = Drawing(w, total_h)
y = total_h - 10
if title:
d.add(String(w/2, y-15, title, fontSize=11, fontName='Helvetica-Bold',
textAnchor='middle', fillColor=DARK_BLUE))
y -= 30
default_colors = [MED_BLUE, ACCENT_TEAL, ACCENT_GREEN, GOLD, PURPLE, RED]
for i, step in enumerate(steps):
col = (colors_list[i] if colors_list and i < len(colors_list)
else default_colors[i % len(default_colors)])
box_y = y - box_h - i * (box_h + arrow_h)
# Box
d.add(Rect(10, box_y, box_w, box_h, rx=5, ry=5,
fillColor=col, strokeColor=WHITE, strokeWidth=1))
# Text
d.add(String(w/2, box_y + box_h/2 - 5, step, fontSize=9,
fontName='Helvetica-Bold', textAnchor='middle',
fillColor=WHITE))
# Arrow (not after last)
if i < len(steps) - 1:
arrow_y_top = box_y
arrow_y_bot = arrow_y_top - arrow_h
d.add(Line(w/2, arrow_y_top, w/2, arrow_y_bot + 6,
strokeColor=DARK_BLUE, strokeWidth=2))
# Arrowhead triangle
d.add(Polygon([w/2 - 6, arrow_y_bot + 8, w/2 + 6, arrow_y_bot + 8,
w/2, arrow_y_bot], fillColor=DARK_BLUE, strokeColor=DARK_BLUE))
return d
def make_horizontal_flowchart(steps, col_list=None, width=None):
"""Horizontal flowchart for shorter step chains."""
w = width or (A4[0] - 4*cm)
n = len(steps)
arrow_w = 15
box_w = (w - arrow_w * (n-1)) / n
box_h = 50
pad = 10
total_h = box_h + 20
d = Drawing(w, total_h)
default_colors = [MED_BLUE, ACCENT_TEAL, ACCENT_GREEN, GOLD, PURPLE, RED]
for i, step in enumerate(steps):
col = (col_list[i] if col_list and i < len(col_list)
else default_colors[i % len(default_colors)])
x = i * (box_w + arrow_w)
d.add(Rect(x, pad, box_w, box_h, rx=4, ry=4,
fillColor=col, strokeColor=WHITE, strokeWidth=1))
# Wrap text
words = step.split()
line1 = ' '.join(words[:3])
line2 = ' '.join(words[3:]) if len(words) > 3 else ''
d.add(String(x + box_w/2, pad + box_h/2 + (4 if line2 else 0), line1,
fontSize=8, fontName='Helvetica-Bold', textAnchor='middle',
fillColor=WHITE))
if line2:
d.add(String(x + box_w/2, pad + box_h/2 - 8, line2,
fontSize=8, fontName='Helvetica-Bold', textAnchor='middle',
fillColor=WHITE))
if i < n-1:
ax = x + box_w
ay = pad + box_h / 2
d.add(Line(ax, ay, ax + arrow_w - 5, ay,
strokeColor=DARK_BLUE, strokeWidth=2))
d.add(Polygon([ax + arrow_w - 7, ay - 5, ax + arrow_w - 7, ay + 5,
ax + arrow_w, ay], fillColor=DARK_BLUE, strokeColor=DARK_BLUE))
return d
# ─── Styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
cover_title_style = ParagraphStyle('CoverTitle', fontSize=26, leading=32,
textColor=WHITE, fontName='Helvetica-Bold', alignment=TA_CENTER, spaceAfter=8)
cover_sub_style = ParagraphStyle('CoverSub', fontSize=14, leading=18,
textColor=colors.HexColor('#bfdbfe'), fontName='Helvetica', alignment=TA_CENTER)
cover_info_style = ParagraphStyle('CoverInfo', fontSize=11, leading=15,
textColor=WHITE, fontName='Helvetica', alignment=TA_CENTER)
section_header_style = ParagraphStyle('SectionHeader', fontSize=16, leading=20,
textColor=WHITE, fontName='Helvetica-Bold', alignment=TA_LEFT,
spaceBefore=16, spaceAfter=4, leftIndent=0)
question_title_style = ParagraphStyle('QuestionTitle', fontSize=13, leading=18,
textColor=DARK_BLUE, fontName='Helvetica-Bold', alignment=TA_LEFT,
spaceBefore=10, spaceAfter=6)
sub_heading_style = ParagraphStyle('SubHeading', fontSize=11, leading=15,
textColor=ACCENT_TEAL, fontName='Helvetica-Bold', alignment=TA_LEFT,
spaceBefore=8, spaceAfter=4)
body_style = ParagraphStyle('Body', fontSize=10, leading=15,
textColor=BLACK, fontName='Helvetica', alignment=TA_JUSTIFY,
spaceBefore=4, spaceAfter=4)
bullet_style = ParagraphStyle('Bullet', fontSize=10, leading=14,
textColor=BLACK, fontName='Helvetica', leftIndent=16, bulletIndent=4,
spaceBefore=2, spaceAfter=2)
bold_body_style = ParagraphStyle('BoldBody', fontSize=10, leading=14,
textColor=DARK_BLUE, fontName='Helvetica-Bold', spaceBefore=4, spaceAfter=2)
italic_style = ParagraphStyle('Italic', fontSize=9.5, leading=13,
textColor=colors.HexColor('#374151'), fontName='Helvetica-Oblique',
spaceBefore=2, spaceAfter=2)
ref_style = ParagraphStyle('Ref', fontSize=8, leading=11,
textColor=colors.HexColor('#6b7280'), fontName='Helvetica-Oblique',
alignment=TA_RIGHT)
small_bold = ParagraphStyle('SmallBold', fontSize=9, leading=13,
textColor=DARK_BLUE, fontName='Helvetica-Bold')
note_style = ParagraphStyle('Note', fontSize=9, leading=13,
textColor=GOLD, fontName='Helvetica-BoldOblique', spaceBefore=2, spaceAfter=2)
def b(text): return f'<b>{text}</b>'
def i(text): return f'<i>{text}</i>'
def bi(text): return f'<b><i>{text}</i></b>'
def col(text, c): return f'<font color="{c}">{text}</font>'
def section_banner(title, bg=DARK_BLUE):
data = [[Paragraph(title, section_header_style)]]
t = Table(data, colWidths=[A4[0] - 4*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('LEFTPADDING', (0,0), (-1,-1), 12),
('RIGHTPADDING', (0,0), (-1,-1), 12),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
]))
return t
def question_banner(qnum, title, marks, bg=MED_BLUE):
txt = f'Q{qnum}. {title} [{marks}]'
data = [[Paragraph(txt, ParagraphStyle('QBanner', fontSize=12, leading=16,
textColor=WHITE, fontName='Helvetica-Bold'))]]
t = Table(data, colWidths=[A4[0] - 4*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('LEFTPADDING', (0,0), (-1,-1), 10),
('RIGHTPADDING', (0,0), (-1,-1), 10),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
]))
return t
# ─── Document setup ───────────────────────────────────────────────────────────
OUTPUT = '/tmp/workspace/surgery-exam/Surgery_Exam_Answers.pdf'
doc = SimpleDocTemplate(OUTPUT, pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2.2*cm, bottomMargin=2.2*cm,
title="MBBS Surgery Long Answer Exam")
story = []
W = A4[0] - 4*cm # usable width
# ═══════════════════════════════════════════════════════════════════════════════
# COVER PAGE
# ═══════════════════════════════════════════════════════════════════════════════
cover_bg_data = [[
Paragraph("MBBS Phase 3 Part 2", cover_sub_style),
Spacer(1, 0.3*cm),
Paragraph("GENERAL SURGERY & ALLIED", cover_title_style),
Spacer(1, 0.2*cm),
Paragraph("Term 2 Examination", cover_sub_style),
Spacer(1, 0.8*cm),
Paragraph("Long Answer Model Responses", ParagraphStyle('X', fontSize=15,
textColor=colors.HexColor('#a5f3fc'), fontName='Helvetica-Bold', alignment=TA_CENTER)),
Spacer(1, 1.5*cm),
Paragraph("Questions Covered", ParagraphStyle('Y', fontSize=12,
textColor=WHITE, fontName='Helvetica-Bold', alignment=TA_CENTER)),
Spacer(1, 0.3*cm),
Paragraph("Q3 | Q4 | Q5 | Q6 | Q7 | Q8 | Q21", ParagraphStyle('Z', fontSize=13,
textColor=colors.HexColor('#fde68a'), fontName='Helvetica-Bold', alignment=TA_CENTER)),
Spacer(1, 1.8*cm),
HRFlowable(width=W, thickness=1, color=colors.HexColor('#93c5fd')),
Spacer(1, 0.4*cm),
Paragraph("References: Bailey & Love's Surgery 28e | Robbins Pathology | Current Surgical Therapy 14e | Bailey & Love | Scott-Brown's Otolaryngology",
ParagraphStyle('Refs', fontSize=9, textColor=colors.HexColor('#93c5fd'),
fontName='Helvetica-Oblique', alignment=TA_CENTER)),
]]
cover_table = Table([[cover_bg_data[0][i] for i in range(len(cover_bg_data[0]))]], colWidths=[W])
# Actually let's do it as a single cell block
cover_content = [
Spacer(1, 1*cm),
]
cover_items = [
Paragraph("MBBS Phase 3 Part 2", cover_sub_style),
Spacer(1, 0.3*cm),
Paragraph("GENERAL SURGERY & ALLIED", cover_title_style),
Spacer(1, 0.2*cm),
Paragraph("Term 2 Examination", cover_sub_style),
Spacer(1, 0.8*cm),
Paragraph("Long Answer Model Responses", ParagraphStyle('X', fontSize=15,
textColor=colors.HexColor('#a5f3fc'), fontName='Helvetica-Bold', alignment=TA_CENTER)),
Spacer(1, 1.5*cm),
Paragraph("Questions Covered", ParagraphStyle('Y', fontSize=12,
textColor=WHITE, fontName='Helvetica-Bold', alignment=TA_CENTER)),
Spacer(1, 0.3*cm),
Paragraph("Q3 | Q4 | Q5 | Q6 | Q7 | Q8 | Q21", ParagraphStyle('Z', fontSize=13,
textColor=colors.HexColor('#fde68a'), fontName='Helvetica-Bold', alignment=TA_CENTER)),
Spacer(1, 2*cm),
HRFlowable(width=W, thickness=1, color=colors.HexColor('#93c5fd')),
Spacer(1, 0.4*cm),
Paragraph("References: Bailey & Love's Surgery 28e | Robbins Pathology | Current Surgical Therapy 14e | Scott-Brown's Otolaryngology | Murray & Nadel Respiratory Medicine",
ParagraphStyle('Refs', fontSize=9, textColor=colors.HexColor('#93c5fd'),
fontName='Helvetica-Oblique', alignment=TA_CENTER)),
]
cover_cell = Table([[item] for item in cover_items], colWidths=[W])
cover_cell.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), DARK_BLUE),
('LEFTPADDING', (0,0), (-1,-1), 20),
('RIGHTPADDING', (0,0), (-1,-1), 20),
('TOPPADDING', (0,0), (-1,-1), 2),
('BOTTOMPADDING', (0,0), (-1,-1), 2),
]))
story.append(cover_cell)
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# Q3 SHORT NOTES (4 marks each = 20 marks)
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_banner("Q3. SHORT NOTES (4 Marks Each = 20 Marks)"))
story.append(Spacer(1, 0.3*cm))
# ── 3a. Pleomorphic Adenoma ───────────────────────────────────────────────────
story.append(question_banner("3a", "Pleomorphic Adenoma", "4 Marks"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Definition"), sub_heading_style))
story.append(Paragraph(
"Pleomorphic adenoma (PA) is the most common benign salivary gland tumour, accounting for "
"60–70% of all salivary gland neoplasms. The term 'pleomorphic' reflects the histological "
"diversity of epithelial, myoepithelial, and stromal components.",
body_style))
story.append(Paragraph(b("Epidemiology"), sub_heading_style))
story.append(make_table(
["Parameter", "Details"],
[["Age", "Any age; peak 3rd–6th decade (avg. 45 years)"],
["Sex", "More common in women"],
["Site", "Parotid gland >80%; also submandibular, hard palate"],
["Malignant transformation", "~5%; carcinoma ex pleomorphic adenoma"]],
bg=LIGHT_BLUE, border=MED_BLUE))
story.append(Paragraph(b("Clinical Features"), sub_heading_style))
story.append(Paragraph(
"Presents as a <b>painless, well-defined, solitary, mobile mass</b> with slow progressive "
"growth over years. Deep lobe parotid tumours may cause a paratonsillar bulge. Warning signs "
"of malignant transformation include sudden increase in size and facial nerve palsy.",
body_style))
story.append(Paragraph(b("Histopathology"), sub_heading_style))
story.append(Paragraph(
"Gross: well-circumscribed, firm, white-to-tan nodular mass with possible cartilaginous areas. "
"Microscopy reveals a mixture of epithelial cells (ductal), myoepithelial cells, and variable "
"stroma (myxoid, chondroid, hyalinised). Immunohistochemistry: luminal cells express CK7; "
"myoepithelial cells express p63, S-100, SOX10, SMA.",
body_style))
story.append(Paragraph(b("Treatment"), sub_heading_style))
story.append(Paragraph(
"Superficial parotidectomy with preservation of facial nerve, ensuring excision with a cuff "
"of normal tissue around the pseudopods. <b>Enucleation alone is avoided</b> due to capsular "
"breach and high local recurrence rate (20–45%).",
body_style))
story.append(make_box(
[Paragraph("<b>Key Point:</b> Do NOT enucleate - high recurrence. Superficial parotidectomy is standard. "
"Recurrent PA may undergo malignant transformation (carcinoma ex PA).", note_style)],
bg=LIGHT_GOLD, border=GOLD))
story.append(Paragraph(i("Reference: Bailey and Love's Short Practice of Surgery, 28th Ed., Ch. 54"), ref_style))
story.append(Spacer(1, 0.4*cm))
# ── 3b. Thoracic Outlet Syndrome ─────────────────────────────────────────────
story.append(question_banner("3b", "Thoracic Outlet Syndrome (TOS)", "4 Marks"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Definition"), sub_heading_style))
story.append(Paragraph(
"Thoracic Outlet Syndrome (TOS) is a group of disorders caused by compression of the "
"neurovascular structures (brachial plexus, subclavian artery/vein) as they pass through "
"the thoracic outlet - the space between the clavicle, first rib, and scalene muscles.",
body_style))
story.append(Paragraph(b("Types"), sub_heading_style))
story.append(make_table(
["Type", "Compressed Structure", "Frequency", "Features"],
[["Neurogenic TOS", "Brachial plexus (C8/T1)", "~95%", "Pain, paraesthesia, weakness in arm/hand"],
["Venous TOS (Paget-Schroetter)", "Subclavian vein", "~4%", "Arm swelling, cyanosis, effort thrombosis"],
["Arterial TOS", "Subclavian artery", "~1%", "Ischaemia, Raynaud's, emboli to hand"]],
bg=LIGHT_TEAL, border=ACCENT_TEAL))
story.append(Paragraph(b("Causes / Anatomy"), sub_heading_style))
story.append(Paragraph(
"Bony anomalies: cervical rib (most common), elongated C7 transverse process, abnormal "
"first rib, post-clavicular fracture callus. Soft tissue: tight scalene muscles, anomalous "
"fibromuscular bands. Predisposing postures: overhead repetitive activities.",
body_style))
story.append(Paragraph(b("Clinical Features"), sub_heading_style))
for pt in [
"Neck and shoulder pain radiating to arm (C8/T1 distribution)",
"Paraesthesia and numbness in ring and little fingers (ulnar pattern)",
"Weakness of intrinsic hand muscles - Gilliatt-Sumner hand (wasting of thenar, hypothenar)",
"Positive provocation tests: Adson's test, Wright's test, Roos test (EAST test)",
"In venous TOS: arm oedema, cyanosis, dilated collateral veins over shoulder"
]:
story.append(Paragraph(f"• {pt}", bullet_style))
story.append(Paragraph(b("Investigations"), sub_heading_style))
for inv in ["X-ray: cervical rib, first rib anomaly",
"MRI/CT angiography: vascular compression",
"Nerve conduction studies: ulnar nerve slowing",
"Duplex ultrasound / venography for venous TOS"]:
story.append(Paragraph(f"• {inv}", bullet_style))
story.append(Paragraph(b("Treatment"), sub_heading_style))
story.append(make_two_col_table(
["Physiotherapy and postural correction", "Scalene muscle stretching", "NSAIDs for pain"],
["First rib resection (transaxillary/supraclavicular approach)", "Cervical rib excision",
"Thrombolysis + vein decompression (Paget-Schroetter)"],
headers=["Conservative", "Surgical"],
bg=LIGHT_TEAL, border=ACCENT_TEAL))
story.append(Paragraph(i("Reference: Rosen's Emergency Medicine 10e; Sabiston Textbook of Surgery"), ref_style))
story.append(Spacer(1, 0.4*cm))
# ── 3c. Stages of Tubercular Lymphadenitis ────────────────────────────────────
story.append(question_banner("3c", "Stages of Tubercular Lymphadenitis", "4 Marks"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Introduction"), sub_heading_style))
story.append(Paragraph(
"Tubercular lymphadenitis is the most common form of extra-pulmonary tuberculosis, "
"accounting for 30–40% of peripheral lymphadenopathy. The cervical group is most often "
"affected (scrofula). Caused by Mycobacterium tuberculosis.",
body_style))
stages_flow = make_flowchart([
"Stage I: Reactive Lymphadenitis",
"Stage II: Periadenitis",
"Stage III: Caseation / Caseous Necrosis",
"Stage IV: Collar-Stud Abscess",
"Stage V: Sinus Formation"
], colors_list=[MED_BLUE, ACCENT_TEAL, ACCENT_GREEN, GOLD, RED], title="Stages of Tubercular Lymphadenitis")
story.append(stages_flow)
story.append(Spacer(1, 0.3*cm))
story.append(make_table(
["Stage", "Pathology", "Clinical Features"],
[["I - Reactive lymphadenitis",
"Lymphocytic proliferation, no caseation. Node soft, tender.",
"Single or multiple enlarged, tender, soft, discrete nodes"],
["II - Periadenitis",
"Pericapsular inflammation; nodes become matted together.",
"Matted nodes; adherent to overlying skin and deep structures"],
["III - Caseation",
"Central caseous necrosis within node. Typical TB granuloma: Langhans giant cells.",
"Firm, non-tender node; skin may become indurated"],
["IV - Collar-stud / Cold abscess",
"Caseous material liquefies, pus tracks through deep fascia; bilocular collection.",
"Fluctuant swelling above and below deep fascia connected through a defect - 'collar-stud'"],
["V - Sinus",
"Collar-stud abscess ruptures through skin; chronic discharging sinus.",
"Discharging sinus with bluish-undermined edges; secondary infection possible"]],
bg=LIGHT_BLUE, border=MED_BLUE))
story.append(Paragraph(b("Treatment"), sub_heading_style))
story.append(Paragraph(
"<b>Anti-tubercular therapy (ATT):</b> HRZE for 2 months (intensive phase) then HR for "
"4 months (continuation phase). Surgery indicated for: diagnostic biopsy, aspiration of "
"fluctuant nodes, excision of persistently enlarged nodes, sinus tract excision.",
body_style))
story.append(Paragraph(i("Reference: Bailey and Love's Surgery 28e; Das's Clinical Surgery"), ref_style))
story.append(Spacer(1, 0.4*cm))
# ── 3d. Solitary Thyroid Nodule ───────────────────────────────────────────────
story.append(question_banner("3d", "Solitary Thyroid Nodule", "4 Marks"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Definition"), sub_heading_style))
story.append(Paragraph(
"A solitary thyroid nodule (STN) is a discrete swelling within an otherwise normal thyroid "
"gland, palpable or detected on imaging. Prevalence: palpable ~5%; ultrasound detectable ~19–67%. "
"About 5–10% of STNs are malignant.",
body_style))
story.append(Paragraph(b("Causes (Differential Diagnosis)"), sub_heading_style))
story.append(make_table(
["Benign (90–95%)", "Malignant (5–10%)"],
[["Colloid cyst / adenomatous nodule", "Papillary carcinoma (most common, 80%)"],
["Follicular adenoma", "Follicular carcinoma"],
["Thyroid cyst (simple/haemorrhagic)", "Medullary carcinoma"],
["Hashimoto's thyroiditis (focal)", "Anaplastic carcinoma"],
["Hürthle cell adenoma", "Lymphoma (rare)"]],
bg=LIGHT_GREEN, border=ACCENT_GREEN))
story.append(Paragraph(b("Evaluation - FNAC is gold standard"), sub_heading_style))
stn_eval = make_horizontal_flowchart(
["History & Examination", "TFTs + USS", "FNAC (Bethesda)", "Thyroid Scan if needed", "Surgery Decision"],
col_list=[MED_BLUE, ACCENT_TEAL, ACCENT_GREEN, GOLD, RED])
story.append(stn_eval)
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Bethesda Classification (FNAC)"), sub_heading_style))
story.append(make_table(
["Category", "Diagnosis", "Malignancy Risk", "Action"],
[["I", "Non-diagnostic", "1–4%", "Repeat FNAC"],
["II", "Benign", "0–3%", "Clinical follow-up"],
["III", "AUS/FLUS", "~10–15%", "Repeat FNAC or molecular testing"],
["IV", "Follicular neoplasm", "25–40%", "Lobectomy"],
["V", "Suspicious for malignancy", "50–75%", "Near-total thyroidectomy"],
["VI", "Malignant", "97–99%", "Total thyroidectomy"]],
bg=LIGHT_BLUE, border=MED_BLUE))
story.append(Paragraph(b("Features Favouring Malignancy"), sub_heading_style))
for feat in ["Age <20 or >60 years", "Male sex", "Rapidly growing solid nodule",
"Hard, irregular, fixed", "Cervical lymphadenopathy",
"Hoarseness (RLN involvement)", "History of radiation to neck",
"Family history of MEN2 or medullary carcinoma"]:
story.append(Paragraph(f"• {feat}", bullet_style))
story.append(Paragraph(i("Reference: Bailey and Love's Surgery 28e; Das's Clinical Surgery"), ref_style))
story.append(Spacer(1, 0.4*cm))
# ── 3e. MEN Syndrome ──────────────────────────────────────────────────────────
story.append(question_banner("3e", "Multiple Endocrine Neoplasia (MEN) Syndrome", "4 Marks"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Definition"), sub_heading_style))
story.append(Paragraph(
"Multiple Endocrine Neoplasia (MEN) syndromes are a group of autosomal dominant inherited "
"disorders characterised by the development of tumours in two or more endocrine glands.",
body_style))
story.append(make_table(
["Feature", "MEN 1 (Wermer's)", "MEN 2A (Sipple's)", "MEN 2B"],
[["Gene mutation", "MEN1 (menin, Ch. 11q13)", "RET proto-oncogene", "RET proto-oncogene"],
["Parathyroid", "Hyperplasia/adenoma (95%)", "Hyperplasia (20–30%)", "Usually absent"],
["Pancreas", "Gastrinoma, insulinoma, VIPoma (30–75%)", "Absent", "Absent"],
["Thyroid", "Absent", "Medullary carcinoma (100%)", "Medullary carcinoma (100%)"],
["Adrenal", "Absent", "Phaeochromocytoma (50%)", "Phaeochromocytoma (50%)"],
["Other", "Pituitary adenoma (prolactinoma 60%)", "Nil specific", "Marfanoid, mucosal neuromas, ganglioneuromas"],
["Mnemonic", "3 Ps: Pituitary, Parathyroid, Pancreas", "2 Ps: Parathyroid + Phaeochromocytoma + Medullary Ca", "Marfanoid body"]],
bg=LIGHT_PURPLE, border=PURPLE))
story.append(Paragraph(b("Clinical Significance"), sub_heading_style))
story.append(Paragraph(
"MEN syndromes require genetic screening of family members. In MEN2, prophylactic "
"thyroidectomy is recommended in RET mutation carriers before age 5 (MEN2A) or in infancy "
"(MEN2B). Phaeochromocytoma must be treated before thyroid surgery.",
body_style))
story.append(Paragraph(i("Reference: Bailey and Love's Surgery 28e; Sabiston Textbook of Surgery"), ref_style))
story.append(Spacer(1, 0.4*cm))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# Q4 EXPLAIN WHY (4 marks each = 12 marks)
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_banner("Q4. EXPLAIN WHY (4 Marks Each = 12 Marks)", bg=ACCENT_TEAL))
story.append(Spacer(1, 0.3*cm))
# ── 4a. Abdominal TB at IC junction ───────────────────────────────────────────
story.append(question_banner("4a", "Abdominal Tuberculosis is More Common at the Ileocaecal Junction", "4 Marks", bg=ACCENT_TEAL))
story.append(Spacer(1, 0.2*cm))
story.append(make_box([
Paragraph("<b>Short Answer:</b> The ileocaecal (IC) region accounts for 80–90% of all "
"gastrointestinal tuberculosis cases because of a unique combination of anatomical, "
"physiological, and immunological factors.", body_style)], bg=LIGHT_TEAL, border=ACCENT_TEAL))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Reasons"), sub_heading_style))
reasons_4a = [
("<b>1. Abundant lymphoid tissue (Peyer's patches):</b>",
"The terminal ileum and ileocaecal region contain the highest concentration of Peyer's patches "
"in the gut. M. tuberculosis, after being swallowed, is taken up by M cells overlying Peyer's patches, "
"establishing primary infection."),
("<b>2. Physiological stasis:</b>",
"The ileocaecal valve slows intestinal transit. Prolonged contact time between ingested "
"mycobacteria and intestinal mucosa greatly increases the chance of mucosal penetration."),
("<b>3. Relative alkaline pH:</b>",
"The caecum and terminal ileum have a relatively alkaline environment, which is favourable "
"for mycobacterial survival and growth."),
("<b>4. Extensive lymphatic drainage:</b>",
"Rich mesenteric lymphatic supply around the ileocaecal region facilitates retrograde "
"spread from mesenteric nodes back to bowel wall."),
("<b>5. High absorptive activity:</b>",
"The terminal ileum is the primary site of absorption - increased absorptive surface contact "
"promotes mycobacterial uptake."),
("<b>6. Retrograde spread from appendix:</b>",
"The lymphatic drainage of the appendix drains directly into the ileocaecal lymph nodes, "
"facilitating direct spread to the IC junction."),
]
for title, desc in reasons_4a:
story.append(Paragraph(title, bold_body_style))
story.append(Paragraph(desc, body_style))
story.append(Paragraph(b("Pathological Forms at IC junction"), sub_heading_style))
story.append(make_table(
["Form", "Frequency", "Key Features"],
[["Ulcerative", "~60%", "Transverse ulcers along lymphoid follicles; bleeding, malabsorption"],
["Hypertrophic", "~10%", "Fibrosis, thickening; RIF mass mimicking carcinoma caecum"],
["Ulcero-hypertrophic", "~30%", "Mixed features; stricture, obstruction"]],
bg=LIGHT_TEAL, border=ACCENT_TEAL))
story.append(Paragraph(i("Reference: Bailey and Love's Surgery 28e; Das's Clinical Surgery"), ref_style))
story.append(Spacer(1, 0.4*cm))
# ── 4b. Beta Blocker before Thyroid Surgery ───────────────────────────────────
story.append(question_banner("4b", "Beta Blocker is Needed Before Thyroid Surgery", "4 Marks", bg=ACCENT_TEAL))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Context"), sub_heading_style))
story.append(Paragraph(
"Beta blockers are administered preoperatively in patients with <b>hyperthyroidism</b> "
"(Graves' disease, toxic adenoma, toxic MNG) who are undergoing thyroid surgery. They are "
"not routinely required for euthyroid patients.",
body_style))
story.append(Paragraph(b("Reasons Beta Blockers are Needed"), sub_heading_style))
beta_reasons = [
("1. Control of sympathetic hyperactivity:",
"Hyperthyroidism causes excess thyroid hormone which sensitises the myocardium to "
"catecholamines via upregulation of beta-adrenergic receptors. This causes tachycardia, "
"hypertension, AF, and tremor. Beta blockers (propranolol) block these effects."),
("2. Prevention of thyroid storm:",
"Surgical manipulation of a toxic gland can release large amounts of preformed T3/T4 into "
"circulation, triggering thyroid storm (hyperpyrexia, tachycardia, hypotension, coma). "
"Beta blockade prevents the cardiovascular manifestations and is life-saving."),
("3. Reduce vascularity of gland:",
"Propranolol decreases thyroid blood flow by blocking beta-2 adrenergic vasodilation, "
"reducing intraoperative bleeding."),
("4. Inhibit peripheral T4 to T3 conversion:",
"Propranolol inhibits 5'-deiodinase, reducing conversion of T4 to the more active T3, "
"thus reducing the metabolic effects."),
("5. Anxiolysis and stabilisation:",
"Helps control tremor, anxiety, and tachycardia preoperatively, improving patient fitness for anaesthesia."),
]
for title, desc in beta_reasons:
story.append(Paragraph(f"<b>{title}</b>", bold_body_style))
story.append(Paragraph(desc, body_style))
story.append(make_box([
Paragraph("<b>Standard Protocol:</b> Propranolol 40–80 mg TDS for 7–10 days preoperatively, "
"maintained until heart rate <80 bpm. Combined with antithyroid drugs (Carbimazole) "
"and Lugol's iodine (reduces vascularity by Wolf-Chaikoff effect).", body_style)],
bg=LIGHT_GOLD, border=GOLD))
story.append(Paragraph(i("Reference: Bailey and Love's Surgery 28e; Das's Clinical Surgery"), ref_style))
story.append(Spacer(1, 0.4*cm))
# ── 4c. Appendicitis managed earlier in children & elderly ────────────────────
story.append(question_banner("4c", "Appendicitis is Managed Earlier in Children and Elderly", "4 Marks", bg=ACCENT_TEAL))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("General Principle"), sub_heading_style))
story.append(Paragraph(
"Acute appendicitis progresses to perforation faster and with less obvious signs in both "
"extremes of age (children and elderly) compared with young adults. Early operative "
"intervention is therefore mandatory to prevent perforation and peritonitis.",
body_style))
story.append(make_two_col_table(
[
b("In Children:"),
"Appendix wall is thin - rapid perforation (within 24-36 hrs)",
"Omentum is underdeveloped - cannot wall off perforation",
"High prevalence of lymphoid hyperplasia as cause",
"Inability to localise pain - diagnosis is delayed",
"Vomiting and diarrhoea common - mistaken for gastroenteritis",
"Free perforation leads to generalised peritonitis rapidly",
"High mortality if generalised peritonitis develops",
],
[
b("In Elderly:"),
"Atherosclerosis reduces mesenteric blood flow - rapid ischaemia",
"Blunted immune response - less inflammatory reaction",
"Atypical presentation - little guarding or rebound",
"Delayed presentation to hospital (>48 hrs usually)",
"Higher incidence of appendiceal malignancy (underlying cause)",
"Omentum less mobile - poor localisation",
"High co-morbidities increase perioperative risk",
],
headers=["Children", "Elderly"],
bg=LIGHT_RED, border=RED
))
story.append(Paragraph(b("Consequence"), sub_heading_style))
story.append(Paragraph(
"Perforation rates: up to 80–100% in children under 2 years vs. 70% in elderly vs. "
"20–30% in young adults. Hence the Alvarado score is used to guide early surgery, "
"and threshold for appendicectomy is lower at these age extremes.",
body_style))
story.append(Paragraph(i("Reference: Bailey and Love's Surgery 28e; Current Surgical Therapy 14e"), ref_style))
story.append(Spacer(1, 0.4*cm))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# Q5 SHORT NOTES (3 marks each = 15 marks)
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_banner("Q5. SHORT NOTES (3 Marks Each = 15 Marks)", bg=ACCENT_GREEN))
story.append(Spacer(1, 0.3*cm))
# ── 5a. Zuska's (Atkin's) Disease ─────────────────────────────────────────────
story.append(question_banner("5a", "Zuska's Disease (Atkin's Disease / Periductal Mastitis)", "3 Marks", bg=ACCENT_GREEN))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
"Zuska's disease (also called periductal mastitis or mammary duct fistula) is a benign "
"inflammatory condition of the breast characterised by <b>non-lactational breast abscesses</b> "
"recurring at the areolar margin with eventual <b>mammary duct fistula</b> formation.",
body_style))
story.append(Paragraph(b("Pathogenesis"), sub_heading_style))
story.append(Paragraph(
"Squamous metaplasia of lactiferous duct epithelium near the nipple causes ductal "
"obstruction. Keratin plugs accumulate, causing ductal dilatation and rupture. "
"Spillage of keratin into periductal tissue triggers intense inflammatory reaction. "
"Strong association with <b>smoking</b> (anaerobic organisms like Bacteroides).",
body_style))
story.append(Paragraph(b("Clinical Features"), sub_heading_style))
for pt in [
"Young women, often smokers",
"Recurrent periareolar abscess (often off-centre)",
"Nipple retraction (central/slit-like) due to periductal fibrosis",
"Mammary duct fistula: sinus opening at areolar margin discharging caseous material",
"Not associated with pregnancy or lactation",
]:
story.append(Paragraph(f"• {pt}", bullet_style))
story.append(Paragraph(b("Treatment"), sub_heading_style))
story.append(Paragraph(
"Acute: incision and drainage. Definitive: total duct excision (Hadfield's operation) "
"with fistulectomy. Antibiotics covering anaerobes (metronidazole + co-amoxiclav). "
"Cessation of smoking is essential.",
body_style))
story.append(Spacer(1, 0.3*cm))
# ── 5b. Traumatic Fat Necrosis of Breast ─────────────────────────────────────
story.append(question_banner("5b", "Traumatic Fat Necrosis of the Breast", "3 Marks", bg=ACCENT_GREEN))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
"A benign condition caused by saponification of fat in breast tissue following trauma. "
"Clinically and radiologically it can mimic carcinoma - making it a <b>great simulator of cancer</b>.",
body_style))
story.append(Paragraph(b("Pathogenesis"), sub_heading_style))
story.append(Paragraph(
"Blunt trauma (seat belt, sports, biopsy, surgery, radiation) disrupts adipocytes. "
"Lipase released causes saponification. Initially haemorrhage and necrosis, then "
"macrophage infiltration (foam cells/lipophages), giant cell reaction, fibrosis, "
"and ultimately calcification.",
body_style))
story.append(Paragraph(b("Clinical Features"), sub_heading_style))
for pt in [
"History of trauma (sometimes forgotten)",
"Hard, irregular, painless lump - closely mimics carcinoma",
"Skin tethering or dimpling (due to fibrosis)",
"Eggshell calcification on mammography (pathognomonic when present)",
"No axillary lymphadenopathy",
]:
story.append(Paragraph(f"• {pt}", bullet_style))
story.append(Paragraph(b("Diagnosis & Treatment"), sub_heading_style))
story.append(Paragraph(
"Triple assessment (clinical + imaging + FNAC/core biopsy). On core biopsy: lipophages, "
"foreign body giant cells, haemosiderin deposits. If benign: reassurance and observation. "
"Excision if diagnosis is uncertain or lump is large.",
body_style))
story.append(Spacer(1, 0.3*cm))
# ── 5c. Omental Torsion ───────────────────────────────────────────────────────
story.append(question_banner("5c", "Omental Torsion", "3 Marks", bg=ACCENT_GREEN))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
"Omental torsion is a rare cause of acute abdomen caused by twisting of the omentum "
"around its vascular pedicle, leading to venous obstruction, oedema, and eventually "
"haemorrhagic infarction of the affected omental segment.",
body_style))
story.append(Paragraph(b("Types"), sub_heading_style))
story.append(make_two_col_table(
["Primary (idiopathic): no predisposing lesion; rotation of free omental segment",
"More common on right side (redundant omentum near caecum)"],
["Secondary: associated with hernia sac, adhesions, cysts, or tumour",
"Precipitated by sudden exertion, coughing, or change in posture"],
headers=["Primary Torsion", "Secondary Torsion"],
bg=LIGHT_GREEN, border=ACCENT_GREEN
))
story.append(Paragraph(b("Clinical Features"), sub_heading_style))
for pt in [
"Acute right-sided abdominal pain (mimics acute appendicitis or cholecystitis)",
"Nausea, vomiting present",
"Low-grade fever; leucocytosis",
"Tender mass palpable in RIF/RUQ",
"Normal WBC appendicitis labs - important differentiator",
]:
story.append(Paragraph(f"• {pt}", bullet_style))
story.append(Paragraph(b("Diagnosis & Treatment"), sub_heading_style))
story.append(Paragraph(
"Diagnosed at laparoscopy/laparotomy (CT scan may show omental lesion with whirl sign). "
"Treatment: resection of necrotic omentum (laparoscopic preferred).",
body_style))
story.append(Spacer(1, 0.3*cm))
# ── 5d. Stages of Wound Healing ──────────────────────────────────────────────
story.append(question_banner("5d", "Stages of Wound Healing", "3 Marks", bg=ACCENT_GREEN))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
"Wound healing is a precisely orchestrated biological process involving four overlapping phases. "
"The phases are: Haemostasis, Inflammation, Proliferation, and Remodelling.",
body_style))
wh_flow = make_flowchart([
"Phase 1: HAEMOSTASIS (Seconds to hours)",
"Phase 2: INFLAMMATION (Days 1-4)",
"Phase 3: PROLIFERATION / REPAIR (Days 4-21)",
"Phase 4: REMODELLING / MATURATION (Weeks to years)"
], colors_list=[RED, MED_BLUE, ACCENT_GREEN, PURPLE], title="Phases of Wound Healing")
story.append(wh_flow)
story.append(Spacer(1, 0.2*cm))
story.append(make_table(
["Phase", "Duration", "Key Events", "Key Cells/Molecules"],
[["Haemostasis",
"Seconds - hours",
"Vasoconstriction; platelet plug; coagulation cascade; fibrin clot formation",
"Platelets; thrombin; fibrin; PDGF, TGF-β released"],
["Inflammation",
"Hours - day 4",
"Vasodilation and vascular permeability (rubor, calor, dolor, tumor); phagocytosis of bacteria and debris",
"Neutrophils (day 1-2); Macrophages (day 2-4); IL-1, TNF-α, IL-6"],
["Proliferation",
"Day 4 - 3 weeks",
"Fibroblast migration; collagen synthesis (type III initially); angiogenesis; epithelialisation; wound contraction",
"Fibroblasts; Myofibroblasts (contraction); EGF, FGF, VEGF; Type III collagen"],
["Remodelling",
"Weeks - 2 years",
"Type III collagen replaced by Type I; cross-linking; scar maturation; tensile strength increases to 80% of normal",
"Collagenase (MMPs); collagen type I; scar tissue pale, flat, avascular"]],
bg=LIGHT_GREEN, border=ACCENT_GREEN))
story.append(make_box([
Paragraph("<b>Important:</b> Maximum tensile strength of healed wound is only 80% of original "
"tissue. Myofibroblasts are responsible for wound contraction (important in hypertrophic "
"scars and contractures). Vitamin C deficiency impairs collagen synthesis.", note_style)],
bg=LIGHT_GOLD, border=GOLD))
story.append(Paragraph(i("Reference: Scott-Brown's Otorhinolaryngology; Robbins Pathology"), ref_style))
story.append(Spacer(1, 0.3*cm))
# ── 5e. Martorell's Ulcer ─────────────────────────────────────────────────────
story.append(question_banner("5e", "Martorell's Ulcer", "3 Marks", bg=ACCENT_GREEN))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
"Martorell's ulcer (hypertensive ischaemic leg ulcer / HYTILU) is a type of skin ulcer "
"occurring in the context of poorly controlled <b>hypertension</b>, resulting from "
"arteriolar occlusion in the skin and subcutaneous tissue.",
body_style))
story.append(Paragraph(b("Pathogenesis"), sub_heading_style))
story.append(Paragraph(
"Chronic hypertension causes arteriolar medial calcification and hyalinosis (particularly "
"in the leg). This leads to progressive subcutaneous arteriolar occlusion, ischaemia of "
"the dermis and subcutaneous fat, causing ulceration without large vessel disease.",
body_style))
story.append(Paragraph(b("Clinical Features"), sub_heading_style))
for pt in [
"Typical patient: older female, obese, poorly controlled hypertension",
"Location: postero-lateral aspect of lower leg (unlike venous ulcers which are medial)",
"Extremely painful (unlike venous ulcers which are mildly painful)",
"Regular, well-defined margins with necrotic base",
"No varicosities; no oedema initially",
"Normal peripheral pulses (unlike ischaemic ulcers)",
"Biopsy: arteriolar hyalinosis, medial calcification",
]:
story.append(Paragraph(f"• {pt}", bullet_style))
story.append(Paragraph(b("Treatment"), sub_heading_style))
story.append(Paragraph(
"Strict blood pressure control (the primary treatment). Analgesia (opioids may be needed). "
"Wound care. Skin grafting once blood pressure controlled.",
body_style))
story.append(Spacer(1, 0.4*cm))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# Q6 PRE-OPERATIVE EVALUATION
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_banner("Q6. PRE-OPERATIVE EVALUATION (4+3+3 = 10 Marks)", bg=GOLD))
story.append(Spacer(1, 0.3*cm))
# ── 6a. Components of Pre-operative Evaluation ────────────────────────────────
story.append(question_banner("6a", "Components of Pre-operative Evaluation", "4 Marks", bg=GOLD))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
"Pre-operative evaluation aims to identify and optimise patient risk factors before "
"surgery to minimise operative morbidity and mortality. It has four main components:",
body_style))
story.append(Paragraph(b("1. History"), sub_heading_style))
story.append(make_table(
["Domain", "Key Points"],
[["Chief complaint & surgical indication", "Nature, duration, urgency of surgery"],
["Medical co-morbidities", "IHD, HTN, DM, COPD, CKD, liver disease, coagulopathy"],
["Drug history", "Anticoagulants (stop), antiplatelet agents, steroids, OCP, insulin"],
["Allergy history", "Drugs, latex, iodine, anaesthetic agents"],
["Previous surgery/anaesthesia", "Complications (difficult airway, MH, bleeding)"],
["Family history", "Malignant hyperthermia, coagulopathies"],
["Social history", "Smoking (stop 8 weeks pre-op), alcohol, BMI"]],
bg=LIGHT_GOLD, border=GOLD))
story.append(Paragraph(b("2. Physical Examination"), sub_heading_style))
for pt in [
"General: BMI, anaemia, jaundice, cyanosis",
"Airway assessment: Mallampati score, mouth opening, neck mobility (predict difficult intubation)",
"CVS: BP, HR, JVP, heart sounds, peripheral pulses",
"RS: breath sounds, wheeze, crepitations, peak flow",
"CNS: baseline neurological status",
"Local: examine the surgical site",
]:
story.append(Paragraph(f"• {pt}", bullet_style))
story.append(Paragraph(b("3. Risk Assessment"), sub_heading_style))
story.append(Paragraph(
"ASA classification (I-VI) grades patient fitness. Goldman Cardiac Risk Index used for "
"cardiac risk. RCRI (Revised Cardiac Risk Index) for major non-cardiac surgery. "
"CPET (cardiopulmonary exercise testing) for borderline cases.",
body_style))
story.append(make_table(
["ASA Class", "Definition"],
[["I", "Healthy patient"],
["II", "Mild systemic disease"],
["III", "Severe systemic disease"],
["IV", "Severe systemic disease, constant threat to life"],
["V", "Moribund; not expected to survive without operation"],
["VI", "Brain-dead (organ donation)"]],
bg=LIGHT_GOLD, border=GOLD))
story.append(Paragraph(b("4. Consent and Documentation"), sub_heading_style))
story.append(Paragraph(
"Informed written consent explaining: procedure, alternatives, risks (general + specific), "
"expected outcomes. Anaesthetic review for high-risk cases. MDT discussion for complex cases.",
body_style))
story.append(Spacer(1, 0.3*cm))
# ── 6b. Investigations before major surgery ────────────────────────────────────
story.append(question_banner("6b", "Investigations Routinely Done Before Major Surgery", "3 Marks", bg=GOLD))
story.append(Spacer(1, 0.2*cm))
story.append(make_table(
["Category", "Investigation", "Rationale"],
[["Haematology", "FBC (Hb, WBC, platelets)", "Detect anaemia, infection, thrombocytopenia"],
["Haematology", "Blood group & crossmatch", "Blood transfusion preparation"],
["Haematology", "Coagulation (PT, aPTT, INR)", "Detect coagulopathy, guide anticoagulant reversal"],
["Biochemistry", "Urea, Creatinine, Electrolytes", "Renal function; electrolyte correction"],
["Biochemistry", "Liver function tests", "Hepatic reserve for drug metabolism"],
["Biochemistry", "Blood glucose/HbA1c", "DM optimisation"],
["Cardiac", "ECG", "Baseline; detect arrhythmia, ischaemia"],
["Cardiac", "Echo (selected patients)", "Valvular disease, LV function"],
["Respiratory", "CXR", "Cardiac size, pulmonary lesions, baseline"],
["Respiratory", "Spirometry (COPD)", "Pulmonary risk assessment"],
["Infection", "Urine R/E and C/S", "Exclude UTI (source of sepsis post-op)"],
["Special", "Sickle cell screen (relevant ethnicity)", "Prevent sickling under anaesthesia"],
["Special", "HIV, Hepatitis B/C", "Infection control precautions"]],
bg=LIGHT_GOLD, border=GOLD))
story.append(Spacer(1, 0.3*cm))
# ── 6c. Premedication in Anaesthesia ──────────────────────────────────────────
story.append(question_banner("6c", "Premedication in Anaesthesia - Indications and Common Drugs", "3 Marks", bg=GOLD))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
"Premedication refers to drugs administered before anaesthesia to improve patient "
"comfort, facilitate smooth anaesthetic induction, and reduce complications.",
body_style))
story.append(make_table(
["Aim", "Drug Class", "Example", "Dose/Route"],
[["Anxiolysis/Sedation", "Benzodiazepine", "Midazolam", "0.05-0.1 mg/kg IV/IM"],
["Anxiolysis/Sedation", "Benzodiazepine", "Diazepam", "5-10 mg oral night before"],
["Analgesia", "Opioid", "Morphine / Pethidine", "0.1 mg/kg IM"],
["Reduce gastric acid (aspiration prophylaxis)", "H2 blocker", "Ranitidine", "150 mg oral"],
["Reduce gastric acid", "PPI", "Omeprazole", "20 mg oral"],
["Reduce gastric volume", "Prokinetic", "Metoclopramide", "10 mg IV"],
["Anticholinergic (reduce secretions)", "Anticholinergic", "Atropine / Glycopyrrolate", "0.6 mg IM"],
["Antiemetic", "5HT3 antagonist", "Ondansetron", "4-8 mg IV"],
["Prevent allergy/bronchospasm", "Antihistamine", "Chlorphenamine", "10 mg IV"],
["Reduce airway reactivity (COPD)", "Bronchodilator", "Salbutamol inhaler", "2-4 puffs"],
["Beta blockade (hyperthyroid)", "Beta blocker", "Propranolol", "20-40 mg oral"]],
bg=LIGHT_GOLD, border=GOLD))
story.append(make_box([
Paragraph("<b>Nil by Mouth (NBM) rules:</b> Solids - 6 hours; Clear fluids - 2 hours before induction. "
"Purpose: prevent aspiration pneumonitis (Mendelson's syndrome).", body_style)],
bg=LIGHT_TEAL, border=ACCENT_TEAL))
story.append(Spacer(1, 0.4*cm))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# Q7 FAT EMBOLISM SYNDROME
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_banner("Q7. FAT EMBOLISM SYNDROME (5 Marks)", bg=PURPLE))
story.append(Spacer(1, 0.3*cm))
story.append(question_banner("7", "Pathogenesis, Clinical Features, Management and Complications of Fat Embolism", "5 Marks", bg=PURPLE))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Definition"), sub_heading_style))
story.append(Paragraph(
"Fat embolism refers to the presence of fat globules in pulmonary or systemic circulation. "
"Fat embolism <i>syndrome</i> (FES) is the clinical triad of respiratory distress, "
"neurological dysfunction, and petechial rash occurring after fat embolism, usually "
"following long bone fractures or orthopaedic surgery.",
body_style))
story.append(Paragraph(b("Aetiology"), sub_heading_style))
story.append(make_two_col_table(
["Long bone fractures (femur, tibia) - most common",
"Pelvic fractures", "Multiple fractures",
"Intramedullary nailing", "Joint arthroplasty"],
["Pancreatitis", "Severe burns",
"Liposuction", "Sickle cell disease",
"Fatty liver with trauma", "Decompression sickness"],
headers=["Traumatic Causes", "Non-Traumatic Causes"],
bg=LIGHT_PURPLE, border=PURPLE))
story.append(Paragraph(b("Pathogenesis"), sub_heading_style))
path_flow = make_flowchart([
"Long bone fracture / marrow disruption",
"Fat globules enter torn venous sinusoids",
"Emboli reach pulmonary capillaries",
"MECHANICAL: occlusion of microvasculature",
"BIOCHEMICAL: Lipase releases free fatty acids",
"Endothelial injury + platelet aggregation + complement activation",
"Pulmonary/cerebral oedema, petechiae, ARDS"
], colors_list=[DARK_BLUE, MED_BLUE, ACCENT_TEAL, ACCENT_GREEN, GOLD, RED, PURPLE],
title="Pathogenesis of Fat Embolism Syndrome")
story.append(path_flow)
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Clinical Features - Gurd's Criteria"), sub_heading_style))
story.append(Paragraph(
"FES typically presents <b>24-72 hours</b> after the causative injury. Diagnosis by "
"Gurd and Wilson criteria (1 major + 4 minor):",
body_style))
story.append(make_two_col_table(
["Respiratory insufficiency (PaO2 <60 mmHg)", "Cerebral symptoms without head injury",
"Petechial rash (pathognomonic - axilla, chest, conjunctiva)"],
["Tachycardia >120 bpm", "Pyrexia >38.5°C", "Thrombocytopenia",
"Haematocrit fall >10%", "High ESR", "Fat macroglobulinaemia",
"Urinary fat globules"],
headers=["MAJOR Criteria", "MINOR Criteria"],
bg=LIGHT_PURPLE, border=PURPLE))
story.append(Paragraph(b("Investigations"), sub_heading_style))
for inv in [
"ABG: hypoxaemia (PaO2 <60 mmHg), hypocapnia",
"CXR/HRCT: bilateral diffuse infiltrates ('snowstorm' appearance)",
"FBC: anaemia, thrombocytopenia",
"Serum lipase: elevated",
"MRI brain: multiple petechial haemorrhages ('star-field' pattern)",
"Bronchoscopy + BAL: fat-laden macrophages (oil red O stain)",
"ECG: right heart strain, S1Q3T3",
]:
story.append(Paragraph(f"• {inv}", bullet_style))
story.append(Paragraph(b("Management"), sub_heading_style))
story.append(make_table(
["Priority", "Intervention", "Detail"],
[["1 - Respiratory support", "Oxygen / CPAP / Mechanical ventilation",
"Maintain PaO2 >80 mmHg; lung-protective ventilation if ARDS (TV 6 ml/kg, PEEP 5-8)"],
["2 - Early fracture fixation", "IM nail / ORIF",
"Reduces ongoing fat release; NOT contraindicated"],
["3 - Fluid resuscitation", "IV fluids",
"Maintain haemodynamic stability; avoid hypovolaemia"],
["4 - Corticosteroids (controversial)", "Methylprednisolone 1.5 mg/kg",
"May reduce inflammatory response; not routine"],
["5 - Heparin", "Low-dose heparin",
"Activates lipase, may clear fat; also DVT prophylaxis"],
["6 - Supportive", "Analgesia, anti-seizure drugs",
"Control neurological complications"]],
bg=LIGHT_PURPLE, border=PURPLE))
story.append(Paragraph(b("Prevention"), sub_heading_style))
story.append(Paragraph(
"Early fracture stabilisation (within 24 hours). Adequate fluid resuscitation. "
"Corticosteroid prophylaxis (methylprednisolone) in high-risk multiple fractures. "
"Careful intramedullary reaming technique.",
body_style))
story.append(Paragraph(b("Complications"), sub_heading_style))
story.append(make_table(
["System", "Complication"],
[["Pulmonary", "ARDS (acute respiratory distress syndrome), refractory hypoxia"],
["Neurological", "Coma, seizures, focal deficits, cerebral oedema"],
["Haematological", "DIC (disseminated intravascular coagulation)"],
["Renal", "Acute kidney injury (fat deposits in glomeruli)"],
["Ocular", "Purtscher's retinopathy (retinal fat emboli causing blindness)"],
["Cardiac", "Right heart failure, arrhythmias"],
["Mortality", "10% mortality in established FES"]],
bg=LIGHT_PURPLE, border=PURPLE))
story.append(Paragraph(i("Reference: Robbins & Kumar Basic Pathology; Murray & Nadel Respiratory Medicine; Bailey and Love's Surgery 28e"), ref_style))
story.append(Spacer(1, 0.4*cm))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# Q8 COMPLICATIONS OF SPINAL CORD INJURY
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_banner("Q8. COMPLICATIONS OF SPINAL CORD INJURY (5 Marks)", bg=RED))
story.append(Spacer(1, 0.3*cm))
story.append(question_banner("8", "Enumerate and Discuss Various Complications of Spinal Cord Injury", "5 Marks", bg=RED))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Overview"), sub_heading_style))
story.append(Paragraph(
"Spinal cord injury (SCI) is a devastating condition with multiple systemic complications "
"affecting virtually every organ system. Complications are the main cause of morbidity and "
"mortality in SCI patients long after the initial injury.",
body_style))
story.append(Paragraph(b("Classification of Complications"), sub_heading_style))
# Mindmap-style table for complications
story.append(make_table(
["System", "Complication", "Key Points"],
[["Respiratory",
"Pulmonary complications",
"Lesions above C4: complete ventilatory failure (diaphragm denervated). "
"C4-T6: impaired intercostal/abdominal function, atelectasis, pneumonia. "
"Mucus plugging. Require mechanical ventilation."],
["Urological",
"Neurogenic bladder",
"Upper motor neurone: spastic, hyperreflexic bladder (reflex voiding, incomplete emptying). "
"Lower motor neurone: flaccid bladder (overflow incontinence). "
"Long-term: UTI, urolithiasis, chronic renal failure (major cause of late death)."],
["Gastrointestinal",
"Neurogenic bowel",
"Upper MN: hyperreflexic bowel - constipation, autonomic dysreflexia from faecal impaction. "
"Lower MN: flaccid bowel - faecal incontinence. Requires bowel programme."],
["Skin",
"Pressure ulcers",
"Loss of sensation + immobility. Occur over bony prominences. "
"Prevention: regular repositioning (2-hourly), pressure-relieving mattresses. "
"Grade I-IV. Treatment: debridement, flap surgery for deep ulcers."],
["Cardiovascular",
"Autonomic dysreflexia",
"Most common in T6 and above injuries. "
"Paroxysmal hypertension + bradycardia + flushing above injury + pallor below. "
"Triggered by bladder/bowel distension. Emergency: sit up, remove trigger, nifedipine."],
["Cardiovascular",
"Orthostatic hypotension",
"Loss of sympathetic vasoconstriction. BP drops on sitting/standing. "
"Managed with compression stockings, abdominal binders, fludrocortisone."],
["Haematological",
"Thromboembolic disease",
"DVT in 30% without prophylaxis within 2 weeks. PE fatal in 1-2%. "
"Thromboprophylaxis: LMWH + compression stockings mandatory."],
["Musculoskeletal",
"Spasticity",
"Upper MN lesion: spasticity, clonus, hyperreflexia. "
"Management: physiotherapy, baclofen (oral/intrathecal), botulinum toxin."],
["Musculoskeletal",
"Heterotopic ossification",
"Ectopic bone formation around joints (hip, knee). Occurs in ~25% of SCI. "
"Pamidronate + NSAIDs for prevention; surgical excision if severe."],
["Musculoskeletal",
"Osteoporosis",
"Disuse osteoporosis below injury level. Pathological fractures. "
"Bisphosphonates, weight-bearing exercises where possible."],
["Neurological",
"Post-traumatic syringomyelia",
"Fluid-filled cavity within cord. Occurs in ~28% up to 30 years post-injury. "
"Presents with ascending pain, sensory loss, increasing weakness. MRI diagnostic. "
"Treatment: syringopleural/syringosubarachnoid shunt."],
["Neurological",
"Chronic neuropathic pain",
"Central sensitisation. Burning, shooting pain at/below injury level. "
"Managed with pregabalin, amitriptyline, duloxetine, spinal cord stimulation."],
["Reproductive",
"Sexual dysfunction",
"Male: erectile and ejaculatory dysfunction (majority). "
"Female: amenorrhoea initially, then normal menstruation returns. "
"Fertility preserved in women; male fertility impaired (sperm motility reduced)."],
["Psychological",
"Depression & adjustment disorder",
"~30% develop clinical depression. Multidisciplinary rehabilitation team essential. "
"Cognitive behavioural therapy, antidepressants."]],
bg=LIGHT_RED, border=RED))
story.append(Paragraph(b("Autonomic Dysreflexia - Emergency Management Flowchart"), sub_heading_style))
ad_flow = make_flowchart([
"Identify trigger (bladder/bowel/skin)",
"Sit patient upright (lowers BP)",
"Loosen tight clothing/catheter",
"Empty bladder (catheterise/irrigate)",
"Disimpact rectum if needed",
"If BP still >150: Nifedipine 10mg sublingual or Glyceryl trinitrate topical"
], colors_list=[RED, GOLD, MED_BLUE, ACCENT_TEAL, ACCENT_GREEN, PURPLE],
title="Autonomic Dysreflexia - Emergency Management")
story.append(ad_flow)
story.append(Paragraph(i("Reference: Bailey and Love's Surgery 28e; Bradley & Daroff Neurology; Rosen's Emergency Medicine"), ref_style))
story.append(Spacer(1, 0.4*cm))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# Q21 APPENDIX ANATOMY + APPENDICITIS MANAGEMENT
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_banner("Q21. APPENDIX - ANATOMY, APPENDICITIS & APPENDICULAR LUMP (4+4+5 = 13 Marks)", bg=DARK_BLUE))
story.append(Spacer(1, 0.3*cm))
# ── 21a. Surgical Anatomy of Appendix ─────────────────────────────────────────
story.append(question_banner("21a", "Surgical Anatomy of the Appendix", "4 Marks"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Macroscopic Anatomy"), sub_heading_style))
story.append(make_table(
["Feature", "Detail"],
[["Length", "Average 9 cm (range 2-20 cm)"],
["Width", "~0.6 cm"],
["Origin", "From the posteromedial wall of caecum, 2.5 cm below ileocaecal valve, where three taenia coli converge"],
["Peritoneal cover", "Completely invested by peritoneum; attached to terminal ileum by mesoappendix"],
["Blood supply", "Appendiceal artery (branch of ileocolic artery from SMA) - terminal artery (no collaterals)"],
["Venous drainage", "Appendiceal vein - ileocolic vein - SMV - portal vein (path for pylephlebitis)"],
["Lymphatics", "Drain to ileocolic lymph nodes in mesoappendix"],
["Nerve supply", "Sympathetic T10; parasympathetic vagus nerve"],
["Content", "All four layers: mucosa, submucosa (abundant lymphoid follicles - 'intestinal tonsil'), muscularis, serosa"]],
bg=LIGHT_BLUE, border=MED_BLUE))
story.append(Paragraph(b("Positions of the Appendix (Surgical Importance)"), sub_heading_style))
story.append(make_table(
["Position", "Frequency", "Clinical Significance"],
[["Retrocaecal / Retroperitoneal", "65%", "Most common; pain/tenderness posterior (Rovsing's +); psoas sign +"],
["Pelvic / Subcaecal", "31%", "Pain suprapubic/on PR; may cause urinary symptoms; Obturator sign +"],
["Pre-ileal", "1%", "Vomiting and periumbilical pain prominent"],
["Post-ileal", "0.5%", "Rare; difficult to locate at surgery"],
["Paracaecal (right-sided)", "2.5%", "Standard RIF tenderness at McBurney's point"]],
bg=LIGHT_BLUE, border=MED_BLUE))
story.append(make_box([
Paragraph("<b>McBurney's Point:</b> Junction of lateral 1/3 and medial 2/3 of line joining "
"right ASIS to umbilicus. Point of maximum tenderness in appendicitis. "
"Lanz's point: junction of right 1/3 and middle 1/3 of inter-ASIS line.", body_style)],
bg=LIGHT_GOLD, border=GOLD))
story.append(Spacer(1, 0.3*cm))
# ── 21b. Types of Appendicitis ─────────────────────────────────────────────────
story.append(question_banner("21b", "Types of Appendicitis", "4 Marks"))
story.append(Spacer(1, 0.2*cm))
story.append(make_table(
["Type", "Pathology", "Clinical Features"],
[["Catarrhal (Simple/Mucosal)",
"Congestion and oedema of mucosa only; neutrophil infiltration of mucosa",
"Mild abdominal pain; may resolve spontaneously; appendix grossly normal"],
["Suppurative (Acute Appendicitis)",
"Transmural inflammation; pus in lumen; surface fibrin exudate; tense, red appendix",
"Classic presentation: periumbilical pain migrating to RIF; fever; N/V; McBurney's +"],
["Gangrenous",
"Ischaemia due to arterial thrombosis; black, necrotic wall; foul-smelling pus",
"Very ill patient; high fever >39°C; severe tenderness; rebound; toxic appearance"],
["Perforated",
"Full thickness necrosis causes rupture; free pus in peritoneal cavity",
"Sudden initial relief of pain then general peritonitis; rigid abdomen; septic shock"],
["Appendix Abscess",
"Walled off perforation by omentum and loops of bowel; pericaecal abscess",
"Localised RIF mass; tender; no generalised peritonitis - 'appendicular mass'"],
["Chronic / Recurrent",
"Fibrous obliteration; recurrent episodes of subacute inflammation",
"Recurrent dull RIF pain; resolves spontaneously"],
["Stump Appendicitis",
"Inflammation of retained stump after appendicectomy (>1 cm)",
"Post-appendicectomy RIF pain; diagnosis on CT"]],
bg=LIGHT_BLUE, border=MED_BLUE))
story.append(Paragraph(b("Alvarado Score"), sub_heading_style))
story.append(make_table(
["Clinical Feature", "Score"],
[["Migration of pain to RIF", "1"],
["Anorexia", "1"],
["Nausea/vomiting", "1"],
["RIF tenderness", "2"],
["Rebound tenderness", "1"],
["Elevated temperature (>37.5°C)", "1"],
["Leukocytosis (WBC >10,000)", "2"],
["Shift to left (neutrophilia)", "1"],
["Total", "10"],
["Score 1-4: Low risk, observe | 5-6: Equivocal, investigate | 7-10: High, operate", ""]],
bg=LIGHT_BLUE, border=MED_BLUE))
story.append(Spacer(1, 0.3*cm))
# ── 21c. Management of Appendicular Lump ──────────────────────────────────────
story.append(question_banner("21c", "Management of Appendicular Lump", "5 Marks"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Definition"), sub_heading_style))
story.append(Paragraph(
"An appendicular lump (mass) forms when a perforating appendix is walled off by the "
"omentum, adjacent loops of bowel, and parietal peritoneum, preventing generalised "
"peritonitis. It typically presents >72 hours after onset of symptoms.",
body_style))
story.append(Paragraph(b("Clinical Features"), sub_heading_style))
for pt in [
"Tender, ill-defined mass in RIF, >3 days after onset of acute appendicitis",
"Soft, doughy consistency (resolving) vs. hard (abscess)",
"Low-grade fever (38-38.5°C)",
"WBC mildly elevated",
"No generalised peritonitis",
"USS/CT: confirms mass/collection; assesses for abscess",
]:
story.append(Paragraph(f"• {pt}", bullet_style))
story.append(Paragraph(b("Management"), sub_heading_style))
mgmt_flow = make_flowchart([
"Appendicular Lump Confirmed (CT/USS)",
"OCHSNER-SHERREN CONSERVATIVE REGIMEN",
"Monitor: Temp, Pulse, Tenderness, Mass size (draw outline daily)",
"IV antibiotics: Ceftriaxone + Metronidazole",
"IV fluids, NBM initially, then soft diet",
"Resolves? YES → Interval appendicectomy at 6-8 weeks",
"Worsens? / Abscess forms → Percutaneous CT-guided drainage / Surgery"
], colors_list=[DARK_BLUE, MED_BLUE, ACCENT_TEAL, ACCENT_GREEN, ACCENT_GREEN, GOLD, RED],
title="Management of Appendicular Lump")
story.append(mgmt_flow)
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(b("Ochsner-Sherren Regimen (Conservative Management)"), sub_heading_style))
story.append(make_table(
["Parameter", "Action"],
[["Position", "Semi-recumbent (Fowler's position) to limit spread"],
["Diet", "Initially NBM with IV fluids; then sips of water, gradually build up"],
["Antibiotics", "IV: Ceftriaxone 1g BD + Metronidazole 500mg TDS for 7-10 days"],
["Analgesia", "Paracetamol ± NSAIDs; avoid opioids (mask peritonism)"],
["Monitoring", "4-hourly temperature, pulse; daily examination; mark mass outline"],
["Signs of resolution", "Temperature normalises, mass decreases, tenderness resolves"],
["Signs of failure", "Rising temperature, increasing mass, generalised peritonitis, abscess"]],
bg=LIGHT_BLUE, border=MED_BLUE))
story.append(Paragraph(b("Indications for Immediate Surgery Despite Appendicular Mass"), sub_heading_style))
for ind in [
"Signs of peritonitis (mass spreading, generalised peritonitis)",
"Appendicular abscess not amenable to percutaneous drainage",
"Failure of conservative management (fever persisting >7 days)",
"Intestinal obstruction",
"Suspicion of underlying malignancy (elderly patients - always histology)",
]:
story.append(Paragraph(f"• {ind}", bullet_style))
story.append(Paragraph(b("Interval Appendicectomy"), sub_heading_style))
story.append(Paragraph(
"Performed <b>6-8 weeks after resolution</b> of the appendicular mass. Reasons: "
"(1) 20% recurrence risk if not done, (2) exclude underlying malignancy (caecal carcinoma "
"mimics appendicular mass in elderly). <b>In elderly patients, colonoscopy and barium "
"enema must be done before interval appendicectomy.</b>",
body_style))
story.append(make_box([
Paragraph("<b>High Yield Points:</b> (1) Appendicular lump = conservative management first. "
"(2) Appendicular abscess = percutaneous drainage or surgery. "
"(3) Always do interval appendicectomy 6-8 weeks later. "
"(4) Exclude malignancy in elderly (colonoscopy). "
"(5) Terminal blood supply = rapid gangrene once obstructed.", note_style)],
bg=LIGHT_GOLD, border=GOLD))
story.append(Paragraph(i("Reference: Current Surgical Therapy 14e; Bailey and Love's Surgery 28e"), ref_style))
# ═══ FINAL REF PAGE ═══
story.append(PageBreak())
story.append(section_banner("REFERENCES", bg=DARK_BLUE))
story.append(Spacer(1, 0.4*cm))
refs = [
"1. Bailey R, Cloves H. Bailey and Love's Short Practice of Surgery, 28th Edition. CRC Press, 2023.",
"2. Kumar V, Abbas A, Aster J. Robbins & Kumar Basic Pathology, 10th Edition. Elsevier, 2023.",
"3. Cameron J, Cameron A. Current Surgical Therapy, 14th Edition. Elsevier, 2023.",
"4. Murray J, Nadel J. Murray & Nadel's Textbook of Respiratory Medicine. Elsevier, 2022.",
"5. Marx J et al. Rosen's Emergency Medicine, 10th Edition. Elsevier, 2023.",
"6. Townsend CM. Sabiston Textbook of Surgery, 21st Edition. Elsevier, 2022.",
"7. Cummings CW. Cummings Otolaryngology Head and Neck Surgery, 7th Edition.",
"8. Scott-Brown's Otorhinolaryngology Head & Neck Surgery, 8th Edition.",
"9. Das S. Das's Clinical Surgery, 16th Edition.",
"10. Fischer JE. Fischer's Mastery of Surgery, 8th Edition.",
]
for ref in refs:
story.append(Paragraph(ref, ParagraphStyle('RefFull', fontSize=9.5, leading=14,
fontName='Helvetica', spaceBefore=4)))
# ═══════════════════════════════════════════════════════════════════════════════
# BUILD
# ═══════════════════════════════════════════════════════════════════════════════
def page_number(canvas, doc):
canvas.saveState()
# Header
canvas.setFillColor(DARK_BLUE)
canvas.setFont('Helvetica-Bold', 8)
canvas.drawString(2*cm, A4[1] - 1.5*cm, "MBBS Phase 3 Part 2 | General Surgery & Allied")
canvas.drawRightString(A4[0] - 2*cm, A4[1] - 1.5*cm, "Long Answer Model Responses")
canvas.setStrokeColor(MED_BLUE)
canvas.setLineWidth(0.5)
canvas.line(2*cm, A4[1] - 1.7*cm, A4[0] - 2*cm, A4[1] - 1.7*cm)
# Footer
canvas.setFillColor(DARK_BLUE)
canvas.setFont('Helvetica', 8)
canvas.drawCentredString(A4[0]/2, 1.4*cm, f"Page {doc.page}")
canvas.line(2*cm, 1.7*cm, A4[0] - 2*cm, 1.7*cm)
canvas.restoreState()
doc.build(story, onFirstPage=page_number, onLaterPages=page_number)
print(f"PDF created: {OUTPUT}")
print("Done!")
cd /tmp/workspace/surgery-exam && python3 generate_pdf.py 2>&1
~/surgery-exam/generate_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/surgery-exam/generate_pdf.py'
cd /tmp/workspace/surgery-exam && python3 generate_pdf.py 2>&1
~/surgery-exam/generate_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/surgery-exam/generate_pdf.py'
cd /tmp/workspace/surgery-exam && python3 generate_pdf.py 2>&1
~/surgery-exam/generate_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/surgery-exam/generate_pdf.py'
cd /tmp/workspace/surgery-exam && python3 generate_pdf.py 2>&1
ls -lh /tmp/workspace/surgery-exam/Surgery_Exam_Answers.pdf
Surgery Exam Answers
PDF Document · PDF
| Sub-question | Topic Covered |
|---|---|
| 3a | Pleomorphic Adenoma - epidemiology, histology (CK7/p63/S-100), Bethesda for FNAC, treatment (superficial parotidectomy) |
| 3b | Thoracic Outlet Syndrome - 3 types (neurogenic/venous/arterial), Adson/Wright/Roos tests, management table |
| 3c | Stages of Tubercular Lymphadenitis - 5-stage flowchart (reactive → periadenitis → caseation → collar-stud → sinus) |
| 3d | Solitary Thyroid Nodule - Bethesda classification (I-VI), evaluation flowchart, malignancy features |
| 3e | MEN Syndrome - Full table comparing MEN1/2A/2B (genes, organs, RET mutation) |