MBBS Proff answers PDF form
mkdir -p /tmp/workspace/mbbs-proff-answers && ls /tmp/workspace/mbbs-proff-answers/
~/mbbs-proff-answers/generate_answers.py
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,
HRFlowable, Table, TableStyle, PageBreak)
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
OUTPUT = "/tmp/workspace/mbbs-proff-answers/MBBS_Proff_Answers.pdf"
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=1.8*cm, leftMargin=1.8*cm,
topMargin=2*cm, bottomMargin=2*cm
)
styles = getSampleStyleSheet()
# Custom styles
title_style = ParagraphStyle(
'DocTitle', parent=styles['Title'],
fontSize=16, spaceAfter=4, textColor=colors.HexColor('#1a237e'),
alignment=TA_CENTER
)
subtitle_style = ParagraphStyle(
'SubTitle', parent=styles['Normal'],
fontSize=11, spaceAfter=12, textColor=colors.HexColor('#37474f'),
alignment=TA_CENTER
)
part_style = ParagraphStyle(
'PartHeader', parent=styles['Heading1'],
fontSize=14, spaceBefore=12, spaceAfter=6,
textColor=colors.white,
backColor=colors.HexColor('#1a237e'),
borderPad=6
)
q_num_style = ParagraphStyle(
'QNum', parent=styles['Heading2'],
fontSize=12, spaceBefore=10, spaceAfter=4,
textColor=colors.HexColor('#1a237e')
)
subq_style = ParagraphStyle(
'SubQ', parent=styles['Normal'],
fontSize=10.5, spaceBefore=6, spaceAfter=2,
textColor=colors.HexColor('#b71c1c'),
fontName='Helvetica-Bold'
)
answer_style = ParagraphStyle(
'Answer', parent=styles['Normal'],
fontSize=10, spaceBefore=2, spaceAfter=4,
leading=15, alignment=TA_JUSTIFY
)
bullet_style = ParagraphStyle(
'Bullet', parent=styles['Normal'],
fontSize=10, spaceBefore=1, spaceAfter=1,
leftIndent=16, leading=14,
bulletIndent=6
)
heading3_style = ParagraphStyle(
'H3Custom', parent=styles['Heading3'],
fontSize=10.5, spaceBefore=5, spaceAfter=2,
textColor=colors.HexColor('#2e7d32')
)
note_style = ParagraphStyle(
'Note', parent=styles['Normal'],
fontSize=9, spaceBefore=3, spaceAfter=3,
backColor=colors.HexColor('#e8f5e9'),
borderColor=colors.HexColor('#2e7d32'),
borderWidth=0.5, borderPad=4,
leftIndent=10, rightIndent=10,
fontName='Helvetica-Oblique'
)
def hr():
return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor('#90a4ae'), spaceAfter=4, spaceBefore=4)
def part_header(text):
return [Spacer(1, 8), Paragraph(text, part_style), Spacer(1, 4)]
def qheader(text):
return [Paragraph(text, q_num_style)]
def subq(text):
return Paragraph(text, subq_style)
def ans(text):
return Paragraph(text, answer_style)
def bullet(text):
return Paragraph(f"• {text}", bullet_style)
def h3(text):
return Paragraph(text, heading3_style)
def note(text):
return Paragraph(text, note_style)
def sp(h=4):
return Spacer(1, h)
story = []
# ── TITLE PAGE ──────────────────────────────────────────────────────────────
story.append(sp(20))
story.append(Paragraph("MBBS PROFESSIONAL EXAMINATION", title_style))
story.append(Paragraph("Surgery – Model Answers", subtitle_style))
story.append(Paragraph("Parts B & C | Based on Standard Surgical Textbooks", subtitle_style))
story.append(hr())
story.append(sp(6))
# ════════════════════════════════════════════════════════════
# PART B
# ════════════════════════════════════════════════════════════
story += part_header("PART B – 25 Marks")
# ── Q21: SEPTIC SHOCK ────────────────────────────────────────────────────────
story += qheader(["<b>Q21 (15 Marks) – Clinical Scenario: 62-year-old diabetic with septic shock</b>"])
# (a)
story.append(subq("(a) Most Likely Diagnosis & Elaboration [1+2 Marks]"))
story.append(ans("<b>Most Likely Diagnosis: Septic Shock</b> (secondary to diabetic foot infection)"))
story.append(sp(3))
story.append(h3("Diagnosis: Septic Shock"))
story.append(ans(
"Septic shock is defined as life-threatening organ dysfunction caused by a dysregulated host response "
"to infection, with persisting hypotension requiring vasopressors to maintain MAP ≥65 mmHg despite "
"adequate fluid resuscitation, and a serum lactate >2 mmol/L."
))
story.append(ans("<b>Evidence in this case:</b>"))
data = [
["Parameter", "Finding", "Significance"],
["Temp", "39.5°C", "Fever – SIRS criterion"],
["Pulse", "124/min (thready)", "Tachycardia – SIRS + poor perfusion"],
["BP", "80/50 mmHg", "Hypotension – shock"],
["RR", "30/min", "Tachypnoea – SIRS + respiratory failure"],
["SpO2", "88% on room air", "Hypoxia – early ARDS/respiratory failure"],
["CRT", ">5 seconds", "Severe peripheral hypoperfusion"],
["Urine output", "10 mL/hr", "Oliguria – renal hypoperfusion (<0.5 mL/kg/hr)"],
["Lactate", "5.2 mmol/L", "Lactic acidosis – tissue hypoperfusion"],
["GCS", "Altered sensorium", "Cerebral hypoperfusion / organ dysfunction"],
["Source", "Foot wound (5 days)", "Focus of infection – diabetic foot"],
]
t = Table(data, colWidths=[3.2*cm, 4*cm, 7.5*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1a237e')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#e8eaf6'), colors.white]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#9fa8da')),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
]))
story.append(t)
story.append(sp(4))
story.append(ans(
"The patient meets criteria for <b>qSOFA ≥ 2</b> (altered mentation, RR ≥22, SBP ≤100) "
"and <b>SOFA score elevation</b>, confirming sepsis progressing to septic shock. "
"The underlying source is a <b>diabetic foot infection</b> – a polymicrobial infection "
"(Gram-positive cocci, Gram-negatives, anaerobes) in an immunocompromised host."
))
# (b)
story.append(subq("(b) Immediate Management – First Hour (Golden Hour) [5 Marks]"))
story.append(h3("The Golden Hour in Septic Shock"))
story.append(ans(
"The <b>'Golden Hour'</b> refers to the first 60 minutes from recognition of septic shock during which "
"rapid, aggressive intervention dramatically improves survival. The Surviving Sepsis Campaign (SSC) "
"1-Hour Bundle (Hour-1 Bundle) mandates:"
))
bundles = [
("<b>1. Blood cultures × 2</b> – before antibiotics (peripheral + central line sites)",),
("<b>2. Broad-spectrum antibiotics</b> – within 1 hour of diagnosis. Cover Gram-positives (MRSA if risk), "
"Gram-negatives, and anaerobes. E.g., Piperacillin-tazobactam + Vancomycin",),
("<b>3. IV Fluid Resuscitation</b> – 30 mL/kg crystalloid (Normal Saline or Ringer's Lactate) within 3 hours. "
"Reassess after each 500 mL bolus",),
("<b>4. Vasopressors</b> – if MAP <65 mmHg after initial fluids: Norepinephrine first-line",),
("<b>5. Measure serum lactate</b> – if >2 mmol/L, remeasure within 2 hours to target clearance >10%",),
("<b>6. Source Control</b> – debridement / drainage of foot wound as soon as clinically feasible",),
("<b>7. Airway & Oxygen</b> – high-flow O2, consider early intubation if SpO2 not improving",),
("<b>8. IV Access</b> – 2 large-bore IV lines; consider central venous access for vasopressors",),
("<b>9. Urinary catheter</b> – for urine output monitoring",),
("<b>10. Monitor & reassess</b> – BP, HR, SpO2, GCS every 15 minutes",),
]
for b in bundles:
story.append(bullet(b[0]))
story.append(note(
"SSC Guidelines 2021: The 1-Hour Bundle is: Measure lactate → Blood cultures → Broad-spectrum "
"antibiotics → 30 mL/kg crystalloid for hypotension or lactate ≥4 mmol/L → Vasopressors if MAP <65 mmHg"
))
# (c)
story.append(subq("(c) Choice of Fluid & Vasopressin in Septic Shock [3 Marks]"))
story.append(h3("Fluid Choice"))
story.append(ans(
"<b>Crystalloids are first-line</b> (SSC 2021 Grade 1A). <b>Normal Saline (0.9% NaCl)</b> or "
"<b>Balanced crystalloids</b> (Ringer's Lactate / Plasmalyte) are used. "
"Balanced crystalloids are preferred over NS to avoid hyperchloraemic metabolic acidosis. "
"<b>Colloids</b> (albumin 4-5%) may be used as adjunct after large crystalloid volumes "
"(evidence from ALBIOS trial). <b>Starches (HES)</b> are contraindicated in sepsis (↑ mortality, AKI). "
"<b>Gelatins</b> are not recommended as primary fluid."
))
story.append(h3("Vasopressor Choice"))
story.append(ans(
"<b>Norepinephrine (Noradrenaline)</b> is the <b>first-line vasopressor</b> in septic shock (SSC Grade 1B). "
"It has predominantly α1-adrenergic activity, increasing SVR and MAP. "
"Target MAP ≥65 mmHg."
))
story.append(ans("<b>Add-on vasopressors (escalation):</b>"))
story.append(bullet("<b>Vasopressin</b> (0.03–0.04 units/min IV) – added if norepinephrine dose is rising; "
"acts on V1 receptors → vasoconstriction; V2 receptors → water retention. "
"Mechanism: direct smooth muscle constriction independent of adrenergic pathway. "
"Useful in refractory septic shock. Vasopressin deficiency occurs in septic shock."))
story.append(bullet("<b>Epinephrine</b> – second-line if MAP target not achieved."))
story.append(bullet("<b>Dopamine</b> – no longer recommended in septic shock (↑ arrhythmia, ↑ mortality vs. NE)."))
story.append(bullet("<b>Dobutamine</b> – if myocardial dysfunction/low cardiac output (add to vasopressor)."))
story.append(bullet("<b>Hydrocortisone</b> 200 mg/day IV – if refractory shock despite adequate fluids + vasopressors."))
# (d)
story.append(subq("(d) Monitoring Adequacy of Resuscitation [2 Marks]"))
story.append(h3("Endpoints of Resuscitation"))
endpoints = [
("Clinical", "MAP ≥65 mmHg; HR <100/min; warm extremities; CRT <2 sec; improving mentation"),
("Urine output", "≥0.5 mL/kg/hr (in this patient: currently 10 mL/hr → needs ≥35 mL/hr)"),
("Lactate clearance", "≥10% reduction every 2 hours; target lactate <2 mmol/L"),
("ScvO2", "Central venous O2 saturation ≥70% (mixed venous SvO2 ≥65%)"),
("CVP", "8–12 mmHg (ventilated: 12–15 mmHg) – limited utility alone"),
("Pulse pressure variation (PPV)", "<13% predicts fluid responsiveness (if ventilated)"),
("Bedside ECHO (POCUS)", "Assess cardiac function, IVC collapsibility index"),
("Arterial blood gas", "Improving pH, base excess, normalising lactate"),
]
t2 = Table(endpoints, colWidths=[4.5*cm, 10.2*cm])
t2.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#2e7d32')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('ROWBACKGROUNDS', (0,0), (-1,-1), [colors.HexColor('#e8f5e9'), colors.white]),
('GRID', (0,0), (-1,-1), 0.4, colors.grey),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
]))
story.append(t2)
# (e)
story.append(subq("(e) Complications & Prognosis [2 Marks]"))
story.append(h3("Complications"))
comps = [
"Acute Respiratory Distress Syndrome (ARDS) – already suggested by SpO2 88%, B/L crepitations",
"Acute Kidney Injury (AKI) – oliguria, already present; may progress to need dialysis",
"Disseminated Intravascular Coagulation (DIC) – coagulation failure from endotoxaemia",
"Septic cardiomyopathy – cardiac dysfunction from inflammatory mediators",
"Multi-Organ Dysfunction Syndrome (MODS) – involving brain, liver, coagulation cascade",
"Limb amputation – diabetic foot infection with osteomyelitis may necessitate amputation",
"Hospital-acquired infections – VAP, CLABSI, C. difficile",
]
for c in comps:
story.append(bullet(c))
story.append(h3("Prognosis"))
story.append(ans(
"<b>Mortality in septic shock is 30–50%.</b> Adverse prognostic factors in this patient: "
"Lactate ≥5.2 mmol/L (>4 = high mortality), MODS (renal, neurological, respiratory), "
"underlying diabetes + hypertension (immunocompromised), delayed presentation (5 days). "
"The patient and family should be counselled that this is a <b>critical illness with guarded prognosis</b>. "
"If source control (debridement/amputation) is delayed, mortality significantly increases."
))
story.append(hr())
# ── Q22 SHORT QUESTIONS ──────────────────────────────────────────────────────
story += qheader(["<b>Q22 – Short Questions (5 × 2 = 10 Marks)</b>"])
story.append(subq("Q1: Management of TNBC Paradox & Contraindications to BCS"))
story.append(h3("TNBC Paradox"))
story.append(ans(
"Triple-Negative Breast Cancer (TNBC) is defined by lack of ER, PR, and HER2 expression. "
"The <b>'TNBC Paradox'</b> describes an apparent contradiction:"
))
story.append(bullet("<b>Paradox:</b> TNBC has a high pathological complete response (pCR) rate to neoadjuvant chemotherapy (~30–40%) – suggesting chemo-sensitivity."))
story.append(bullet("<b>Yet:</b> Despite this chemo-sensitivity and pCR, <b>long-term outcomes are worse</b> than hormone receptor-positive or HER2+ cancers. Patients who do NOT achieve pCR have a very poor prognosis."))
story.append(bullet("Survival is dependent on achieving pCR; residual disease after NACT carries very poor prognosis (<i>\"all or nothing\" phenomenon</i>)"))
story.append(h3("Management of TNBC"))
story.append(bullet("Neoadjuvant chemotherapy (NACT): Anthracycline + taxane regimen (AC-T)"))
story.append(bullet("If residual disease post-NACT: Capecitabine (CREATE-X trial)"))
story.append(bullet("PD-L1 positive: Add Pembrolizumab (KEYNOTE-522)"))
story.append(bullet("BRCA1/2 mutation: Olaparib (PARP inhibitor)"))
story.append(bullet("Antibody-drug conjugates: Sacituzumab govitecan (metastatic setting)"))
story.append(bullet("No role for anti-HER2 or hormonal therapy"))
story.append(h3("Contraindications to Breast Conserving Surgery (BCS)"))
story.append(ans("<b>Absolute Contraindications:</b>"))
abs_contra = [
"Diffuse malignant or indeterminate microcalcifications on mammography",
"Multi-centricity (tumor in ≥2 quadrants – not same quadrant as index lesion)",
"Inflammatory breast cancer",
"Prior breast irradiation (unable to give further RT)",
"Pregnancy (relative – 3rd trimester may allow BCS with deferred RT)",
"Positive margins despite repeated re-excision",
"Large tumor with unfavourable tumor:breast size ratio (poor cosmesis)",
]
for a in abs_contra:
story.append(bullet(a))
story.append(ans("<b>Relative Contraindications:</b>"))
rel_contra = [
"Active connective tissue disease (scleroderma, lupus) – poor RT tolerance",
"BRCA1/2 mutation – higher recurrence risk; mastectomy preferred",
"Tumors >5 cm (T3) – NACT to downstage first",
"Patient preference for mastectomy",
]
for r in rel_contra:
story.append(bullet(r))
story.append(sp(6))
story.append(subq("Q2: Mediators of Wound Healing & Phases"))
story.append(h3("Phases of Wound Healing"))
phase_data = [
["Phase", "Timing", "Key Cells", "Key Mediators & Events"],
["1. Haemostasis", "Immediate\n(0–minutes)", "Platelets, endothelium",
"Vasoconstriction → platelet plug → thrombin cascade → fibrin clot\nPDGF, TGF-β released from platelets"],
["2. Inflammatory", "Day 0–4",
"Neutrophils (0–3 days)\nMacrophages (day 2 onwards)",
"Neutrophils: kill bacteria, debride (via ROS, proteases)\nMacrophages: key orchestrators → release:\n• IL-1, IL-6, TNF-α (pro-inflammatory)\n• PDGF, TGF-β, VEGF, bFGF (growth factors)\n• MMPs (matrix remodelling)\nLeukotriene B4, PGE2, thromboxane A2"],
["3. Proliferative", "Day 4 – 3 weeks",
"Fibroblasts, keratinocytes, endothelial cells",
"Fibroblasts: collagen III synthesis, ECM deposition\nKeratinocytes: re-epithelialisation (EGF, KGF)\nAngiogenesis: VEGF, bFGF, angiopoietins\nGranulation tissue formation (collagen + capillaries)\nMyofibroblasts: wound contraction (TGF-β)"],
["4. Remodelling\n(Maturation)", "3 weeks –\n2 years",
"Fibroblasts,\nMMPs, TIMPs",
"Collagen III → Collagen I (type III replaced by type I)\nCross-linking by lysyl oxidase\nTensile strength increases to 80% of original\nScar matures (red → white, raised → flat)"],
]
t3 = Table(phase_data, colWidths=[2.5*cm, 2.2*cm, 3*cm, 7*cm])
t3.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#4a148c')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8.5),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#f3e5f5'), colors.white]),
('GRID', (0,0), (-1,-1), 0.4, colors.grey),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('WORDWRAP', (0,0), (-1,-1), True),
]))
story.append(t3)
story.append(sp(3))
story.append(ans(
"<b>Key growth factor summary:</b> PDGF (platelet-derived) – earliest, recruits inflammatory cells; "
"TGF-β – fibrosis, collagen, scar; VEGF – angiogenesis; bFGF (FGF-2) – fibroblast proliferation; "
"EGF/KGF – epithelial regeneration; IGF-1 – fibroblast and keratinocyte growth."
))
story.append(PageBreak())
# ════════════════════════════════════════════════════════════
# PART C
# ════════════════════════════════════════════════════════════
story += part_header("PART C – 40 Marks")
# ── Q23: AETCOM ──────────────────────────────────────────────────────────────
story += qheader(["<b>Q23 (10 Marks) – AETCOM: Ethics in Surgical Consent</b>"])
story.append(ans(
"<i>Case: 35-year-old female, conscious and oriented, needs emergency laparotomy for perforation peritonitis. "
"Husband wants risks withheld from patient.</i>"
))
story.append(subq("(a) Ethical Principles Involved [3 Marks]"))
ethics_data = [
["Principle", "Application in this Case"],
["1. Autonomy", "Patient is conscious, oriented, and legally competent. She has the RIGHT to make her own medical decisions. No one (including spouse) can override her autonomy. Her question 'Doctor, is it serious?' demonstrates she WANTS information."],
["2. Beneficence", "The surgeon must act in the patient's best interest. Withholding information is NOT beneficence – it prevents informed decision-making. Early surgery is in her interest."],
["3. Non-Maleficence", "Withholding information (therapeutic privilege) or proceeding without valid consent causes harm. Lying or omission violates non-maleficence."],
["4. Justice", "Equal treatment regardless of gender or marital status. Her rights as a patient cannot be subordinated to the husband's preferences."],
["5. Truthfulness / Veracity", "Doctor has a duty to be truthful with the patient. Deception, even 'benevolent', breaches trust and the doctor-patient relationship."],
["6. Confidentiality", "Patient's medical information is hers first. Husband should not receive information the patient has not consented to share."],
]
t4 = Table(ethics_data, colWidths=[4*cm, 10.7*cm])
t4.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#bf360c')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#fbe9e7'), colors.white]),
('GRID', (0,0), (-1,-1), 0.4, colors.grey),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
]))
story.append(t4)
story.append(subq("(b) Communication with Patient & Husband [3 Marks]"))
story.append(h3("With the Patient:"))
story.append(bullet("Speak to her <b>privately</b> (without husband initially)."))
story.append(bullet("Use <b>empathetic, simple language</b>: 'Yes, this is serious. You have a perforation in your abdomen which is life-threatening without surgery.'"))
story.append(bullet("Explain: nature of condition, proposed operation (laparotomy), risks (stoma, wound infection, re-operation, death), benefits (life-saving), alternatives (no surgery = certain death)."))
story.append(bullet("Assess her understanding (teach-back method)."))
story.append(bullet("Respect her emotional state – provide reassurance while being truthful."))
story.append(bullet("Allow her to ask questions and ensure consent is <b>voluntary, uncoerced</b>."))
story.append(h3("With the Husband:"))
story.append(bullet("Acknowledge his concern and fear for his wife."))
story.append(bullet("Explain that <b>legally and ethically</b>, a competent adult patient must be fully informed – you cannot withhold risks from her."))
story.append(bullet("Reassure him: 'Informing her will not make her refuse – she needs this surgery to survive.'"))
story.append(bullet("He may be present during the consent discussion <b>only if the patient consents to this</b>."))
story.append(bullet("Document the husband's objection and your response in the medical record."))
story.append(subq("(c) Essential Elements of Valid Informed Consent in Surgical Practice [4 Marks]"))
story.append(h3("7 Essential Elements of Valid Informed Consent"))
consent_elements = [
("1. Disclosure", "Patient must be told: diagnosis, proposed procedure, purpose and nature of operation, material risks and benefits, alternative treatments, consequences of no treatment."),
("2. Comprehension", "Patient must understand the information in a language and manner they can comprehend. Use interpreters if needed. Confirm understanding."),
("3. Competence / Capacity", "Patient must be legally and mentally competent (conscious, oriented, free of drugs/alcohol, not under coercion). In this case – patient IS competent."),
("4. Voluntariness", "Decision must be free from coercion, duress, or undue influence. Husband's pressure does NOT invalidate patient's voluntary decision."),
("5. Specificity", "Consent must be specific to the procedure being performed (general consent is insufficient for surgery)."),
("6. Documentation", "Written consent form signed by patient, surgeon, and witness. Must be documented in medical records with date, time, and content of discussion."),
("7. Right to withdraw", "Patient can withdraw consent at any time before surgery, without penalty or prejudice to care."),
]
t5 = Table(consent_elements, colWidths=[3.5*cm, 11.2*cm])
t5.setStyle(TableStyle([
('BACKGROUND', (0,0), (0,-1), colors.HexColor('#e3f2fd')),
('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('GRID', (0,0), (-1,-1), 0.4, colors.grey),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('ROWBACKGROUNDS', (0,0), (-1,-1), [colors.white, colors.HexColor('#f5f5f5')]),
]))
story.append(t5)
story.append(note(
"Emergency Exception: If patient is unconscious or lacks capacity in an emergency, the surgeon may "
"proceed without consent under the doctrine of 'necessity' to preserve life – but this does NOT apply here "
"as the patient is conscious and competent."
))
story.append(PageBreak())
# ── Q24: STRUCTURED LONG QUESTIONS ──────────────────────────────────────────
story += qheader(["<b>Q24 (2 × 10 = 20 Marks) – Structured Long Questions</b>"])
story.append(subq("Q24.1: Cervical Lymphadenitis – 22-year-old male with neck swelling"))
story.append(h3("(a) Stages of Cervical Tuberculous Lymphadenitis [6 Marks]"))
story.append(ans(
"The presented clinical picture – matted 4×3 cm upper deep cervical lymph node, fluctuant, "
"mild tenderness, low-grade evening fever, progressive 3-month history – is classic for "
"<b>Tuberculous Cervical Lymphadenitis</b> (Scrofula). Staging follows Beedham & Hudson classification:"
))
stages_tb = [
["Stage", "Name", "Features"],
["I", "Lymphadenitis\n(Reactive)", "Firm, discrete, mobile enlarged lymph nodes. Reactive hyperplasia. No necrosis. Nodes NOT matted. ESR elevated."],
["II", "Periadenitis", "Nodes become matted (adherent to each other and surrounding tissue due to capsular inflammation). Still firm. No fluctuation."],
["III", "Central Caseation\n(Caseous Softening)", "Central necrosis/caseation. Node becomes fluctuant on palpation. Still confined by deep fascia. 'Cold abscess' beginning to form."],
["IV", "Collar-Stud Abscess\n(Subacute Abscess)", "Caseous material bursts through deep cervical fascia → bilocular abscess above and below deep fascia connected by narrow neck ('collar-stud' appearance). Cross-fluctuation present."],
["V", "Sinus / Ulceration", "Collar-stud abscess ruptures through skin → chronic discharging sinus. Watery pus with undermined edges (TB destroys subcutaneous tissue). Calcification may occur in healed lesions."],
]
t6 = Table(stages_tb, colWidths=[1.3*cm, 3.5*cm, 9.9*cm])
t6.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#006064')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#e0f7fa'), colors.white]),
('GRID', (0,0), (-1,-1), 0.4, colors.grey),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
]))
story.append(t6)
story.append(ans(
"<b>This patient is in Stage III–IV</b> (fluctuant, matted nodes, overlying skin induration → "
"beginning collar-stud formation). Management includes FNAC/biopsy for confirmation, "
"ATT (HRZE × 2 months → HR × 4 months), aspiration of abscess if needed."
))
story.append(h3("(b) Classification of Cervical Lymph Nodes – Nodal Levels [4 Marks]"))
story.append(ans(
"The Memorial Sloan Kettering / Robbins classification divides cervical lymph nodes into "
"<b>6 Levels (I–VI)</b> with subdivisions:"
))
level_data = [
["Level", "Sub-level", "Location", "Drains From"],
["I", "IA – Submental\nIB – Submandibular", "Below chin / Under mandible", "Lip, floor of mouth, anterior tongue, cheek, submandibular gland"],
["II", "IIA – Anterior to SAN\nIIB – Posterior to SAN", "Upper jugular (jugulodigastric) – from skull base to hyoid bone", "Oral cavity, nasal cavity, nasopharynx, oropharynx, parotid, hypopharynx, larynx"],
["III", "–", "Middle jugular – hyoid to cricoid cartilage", "Oral cavity, nasopharynx, oropharynx, hypopharynx, larynx"],
["IV", "–", "Lower jugular – cricoid to clavicle", "Hypopharynx, larynx, thyroid, oesophagus, trachea"],
["V", "VA – Superior\nVB – Inferior", "Posterior triangle (along SAN and transverse cervical vessels)", "Nasopharynx, oropharynx, posterior scalp/neck"],
["VI", "–", "Central compartment (pretracheal, paratracheal, Delphian)", "Thyroid, subglottis, trachea, cervical oesophagus, pyriform fossa"],
["VII*", "–", "Superior mediastinum (below sternal notch)", "Thyroid, oesophagus, trachea"],
]
t7 = Table(level_data, colWidths=[1.2*cm, 3.5*cm, 4.3*cm, 5.7*cm])
t7.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#006064')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8.5),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#e0f7fa'), colors.white]),
('GRID', (0,0), (-1,-1), 0.4, colors.grey),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 2),
('BOTTOMPADDING', (0,0), (-1,-1), 2),
]))
story.append(t7)
story.append(note("SAN = Spinal Accessory Nerve. *Level VII is sometimes added separately."))
story.append(PageBreak())
# Q24.2 – POLYTRAUMA
story.append(subq("Q24.2: Polytrauma – 28-year-old motorcycle accident victim"))
story.append(h3("(A) Initial Assessment [4 Marks]"))
story.append(ans("<b>1. Define Polytrauma:</b>"))
story.append(ans(
"Polytrauma is defined as the simultaneous presence of <b>two or more injuries</b>, at least one of which "
"is life-threatening. The commonly used definition (Berlin 2014) requires: <b>ISS (Injury Severity Score) "
"≥16</b> PLUS at least one of: SBP ≤90 mmHg, GCS ≤8, BD ≤−6 mEq/L, lactate ≥2.5 mmol/L, or age ≥70 years."
))
story.append(ans("<b>2. Primary Survey – ABCDE Principles (ATLS):</b>"))
abcde = [
("<b>A – Airway with C-spine protection:</b>",
"Talking incoherently, blood in oral cavity → clear airway (suction, jaw thrust), "
"maintain cervical spine immobilisation. Assume C-spine injury until excluded."),
("<b>B – Breathing & Ventilation:</b>",
"RR 32/min, SpO2 88%, decreased air entry left + tracheal deviation right → "
"Suspect left-sided TENSION PNEUMOTHORAX → immediate needle decompression (2nd ICS, MCL) "
"then chest drain. Give high-flow O2."),
("<b>C – Circulation & Haemorrhage Control:</b>",
"BP 80/50, HR 132, cold clammy, active bleeding right thigh, FAST+ → "
"2 large-bore IV lines, blood samples, activate MTP. Direct pressure on thigh wound, "
"pelvic binder if pelvic instability. Transfuse (1:1:1 blood:FFP:platelets)."),
("<b>D – Disability (Neurological):</b>",
"GCS E3V4M5 = 12 (moderate TBI). Restless, confused. Assess pupils. "
"Maintain MAP ≥80 mmHg for traumatic brain injury."),
("<b>E – Exposure & Environment:</b>",
"Log roll – inspect back for injuries. Keep warm (prevent hypothermia). "
"Splint open femur fracture, control bleeding."),
]
for item, detail in abcde:
story.append(ans(f"{item} {detail}"))
story.append(ans("<b>3. Life-Threatening Injuries in this Case:</b>"))
lti = [
"Tension pneumothorax (left) – decreased air entry + tracheal deviation right",
"Haemoperitoneum – FAST shows free fluid in Morrison's pouch (likely splenic/hepatic/mesenteric injury)",
"Pelvic fracture with instability – major arterial haemorrhage source",
"Open femur fracture – active bleeding + fat embolism risk",
"Traumatic Brain Injury – GCS 12, potential intracranial haemorrhage",
"Haemorrhagic shock – Hb 7.8, lactate 5.2, BP 80/50",
]
for l in lti:
story.append(bullet(l))
story.append(h3("(C) Circulation and Shock [4 Marks]"))
story.append(ans("<b>1. Type of Shock:</b>"))
story.append(ans(
"This is <b>Class III–IV Haemorrhagic Shock (Hypovolaemic)</b>: "
"HR 132/min, BP 80/50, cold clammy extremities, CRT >3 sec, Hb 7.8, lactate 5.2 (tissue hypoperfusion). "
"Estimated blood loss >1500–2000 mL (>30–40% of blood volume). "
"<b>Justification:</b> Multiple sources of haemorrhage (femur, pelvis, abdomen), FAST positive."
))
story.append(ans("<b>2. Causes of Shock in Polytrauma (4 H's):</b>"))
shock_causes = [
"Haemorrhagic (hypovolaemic) – most common (external + internal bleeding)",
"Haemothorax/Tension pneumothorax → obstructive/distributive",
"Cardiac tamponade (obstructive shock) – if penetrating injury/deceleration",
"Neurogenic shock – spinal cord injury (bradycardia + hypotension)",
"Septic shock – late complication (not here initially)",
"Hypothermia → myocardial depression → cardiogenic component",
]
for s in shock_causes:
story.append(bullet(s))
story.append(ans("<b>3. Damage Control Resuscitation (DCR):</b>"))
story.append(ans(
"DCR is a strategy for severely injured, coagulopathic patients that aims to rapidly restore "
"perfusion while limiting the lethal triad (hypothermia + acidosis + coagulopathy). "
"Key principles:"
))
dcr = [
"Permissive hypotension (target SBP 80–90 mmHg until haemostasis) – EXCEPT TBI",
"Haemostatic resuscitation: balanced blood products 1:1:1 ratio (pRBC:FFP:platelets)",
"Avoid crystalloid excess ('crystalloid kills' – dilutes clotting factors, worsens acidosis)",
"Early administration of Tranexamic acid (TXA) within 3 hours of injury",
"Damage control surgery: abbreviated laparotomy for haemorrhage control, avoid definitive repair",
"Warm all fluids and blood products, keep patient warm",
"Goal: correct coagulopathy, restore perfusion, then definitive surgery in ICU-stabilised patient",
]
for d in dcr:
story.append(bullet(d))
story.append(ans("<b>4. Indications for Massive Transfusion Protocol (MTP):</b>"))
story.append(ans("MTP is activated when predicted need for ≥10 units pRBC in 24 hours. Triggers:"))
mtp = [
"Clinical: HR >120 + SBP <90 + penetrating mechanism (ABC score ≥2)",
"FAST positive + haemodynamic instability",
"Shock Index (HR/SBP) >1.0 (here: 132/80 = 1.65)",
"Base deficit <−6 or lactate >5 mmol/L (present in this case)",
"Estimated blood loss >1.5 L in field",
"Hb <8 g/dL with ongoing haemorrhage",
"INR >1.5 or PTT >35 sec (INR mildly elevated in this patient)",
]
for m in mtp:
story.append(bullet(m))
story.append(h3("Short Notes [2 Marks]"))
story.append(ans("<b>1. Trauma Triad of Death (Lethal Triad):</b>"))
story.append(ans(
"Three interrelated, mutually perpetuating physiological derangements that form a vicious cycle "
"in trauma patients, leading to death if not corrected:"
))
triad_data = [
["Component", "Cause in Trauma", "Effect"],
["Hypothermia\n(<35°C)", "Haemorrhage, cold fluids, exposure", "Impairs coagulation enzyme function, cardiac dysfunction, ↑ O2 demand"],
["Acidosis\n(pH <7.35)", "Hypoperfusion → lactic acidosis", "Impairs coagulation, myocardial depression, vasodilation → more hypotension"],
["Coagulopathy\n(INR >1.5, PT/aPTT ↑)", "Dilution, hypothermia, acidosis, consumption", "Uncontrolled haemorrhage → more hypoperfusion → worsening triad"],
]
t8 = Table(triad_data, colWidths=[3*cm, 4.8*cm, 6.9*cm])
t8.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#b71c1c')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#ffebee'), colors.white]),
('GRID', (0,0), (-1,-1), 0.4, colors.grey),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
]))
story.append(t8)
story.append(note("Prevent/correct: Warm fluids → address hypothermia | DCR with blood products → address coagulopathy | Haemostasis → correct acidosis"))
story.append(ans("<b>2. Secondary Survey in Trauma:</b>"))
story.append(ans(
"Performed AFTER primary survey and initial resuscitation. "
"A thorough <b>head-to-toe examination</b> to identify ALL injuries:"
))
ss = [
"Head: Scalp lacerations, skull fractures, facial fractures, eye injuries",
"Neck: Tracheal position, veins, C-spine tenderness (hard collar until cleared)",
"Chest: Rib fractures, haemothorax, aortic injury (widened mediastinum on CXR)",
"Abdomen: Log roll, rectal exam, DRE",
"Pelvis: Repeat assessment, urethrogram if blood at meatus",
"Extremities: Neurovascular assessment, open fractures",
"Neurological: Full GCS, cranial nerves, motor/sensory",
"AMPLE History: Allergies, Medications, PMH, Last meal, Events/mechanism",
"Adjuncts: Trauma CT (pan-CT), repeat vitals",
]
for s in ss:
story.append(bullet(s))
story.append(PageBreak())
# ── Q25: SHORT ONE-LINE ANSWERS ───────────────────────────────────────────────
story += qheader(["<b>Q25 (5 × 2 = 10 Marks) – Short Questions: One-line Answer Type</b>"])
story.append(subq("1. Most Common Cause of Peripheral Arterial Disease & Clinical Manifestations"))
story.append(h3("Most Common Cause: Atherosclerosis"))
story.append(ans(
"<b>Atherosclerosis</b> is the most common cause of peripheral arterial disease (PAD), "
"accounting for >95% of cases. Risk factors: diabetes (most important in lower limb PAD), "
"smoking (strongest modifiable risk factor), hypertension, dyslipidaemia, obesity, age >50."
))
story.append(h3("Typical Clinical Manifestations (Fontaine Classification):"))
fontaine = [
["Stage", "Manifestation"],
["I", "Asymptomatic – ABI <0.9 but no symptoms"],
["II", "Intermittent claudication – reproducible calf/thigh/buttock pain on walking, relieved by rest\n(IIa: walking distance >200m; IIb: <200m)"],
["III", "Rest pain – burning pain in foot at rest, worse at night, relieved by hanging leg down"],
["IV", "Critical Limb Ischaemia – gangrene, non-healing ulcers (typically on toes/heels/pressure points)"],
]
t9 = Table(fontaine, colWidths=[1.5*cm, 13.2*cm])
t9.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#37474f')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#eceff1'), colors.white]),
('GRID', (0,0), (-1,-1), 0.4, colors.grey),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
]))
story.append(t9)
story.append(ans("Other features: absent/weak pedal pulses, cold limb, pallor, atrophic skin, hair loss, nail changes (Buerger's test positive)."))
story.append(sp(6))
story.append(subq("2. Virchow's Triad & Deep Vein Thrombosis"))
story.append(h3("Virchow's Triad (1856)"))
story.append(ans(
"Rudolf Virchow described three factors that predispose to intravascular thrombus formation:"
))
virchow_data = [
["Component", "Definition", "Examples relevant to DVT"],
["1. Endothelial Injury\n(Vessel wall damage)", "Disruption of vascular endothelium exposes subendothelial collagen, activating coagulation cascade", "Surgery, trauma, IV catheters, varicose veins, chemical irritants"],
["2. Hypercoagulability\n(Altered coagulation)", "Imbalance towards pro-coagulant state – excess clotting factors, decreased anticoagulants", "Factor V Leiden, antiphospholipid syndrome, malignancy, pregnancy, OCP, protein C/S deficiency"],
["3. Stasis\n(Abnormal blood flow)", "Venous stasis allows coagulation factors to accumulate without dilution/clearance", "Immobility (bed rest, long flights), heart failure, obesity, varicose veins, paralysis"],
]
t10 = Table(virchow_data, colWidths=[3.5*cm, 4.5*cm, 6.7*cm])
t10.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1565c0')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#e3f2fd'), colors.white]),
('GRID', (0,0), (-1,-1), 0.4, colors.grey),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
]))
story.append(t10)
story.append(ans(
"<b>Contribution to DVT:</b> In DVT, all three elements may be present. Stasis in deep leg veins (especially "
"soleal veins) during immobilisation, combined with hypercoagulability from surgery or malignancy, and "
"endothelial damage from trauma or catheterisation leads to thrombus formation in the deep venous system."
))
story.append(sp(6))
story.append(subq("3. Aortic Aneurysm – Definition & Risk Factors for Rupture"))
story.append(h3("Definition"))
story.append(ans(
"An <b>aortic aneurysm</b> is a permanent, localised, pathological dilatation of the aorta to "
"<b>≥150% (1.5 times) of its normal diameter</b>. Normal infrarenal aorta diameter = 2 cm; "
"therefore AAA is defined as ≥3 cm. True aneurysms involve all three layers (intima, media, adventitia). "
"Fusiform (circumferential) >> saccular (asymmetric). Most common location: infrarenal aorta (90%)."
))
story.append(h3("Factors Increasing Risk of Rupture"))
rupture_factors = [
("Aneurysm size", "Risk rises steeply: 5–6 cm = 3–15%/yr; 6–7 cm = 10–20%/yr; >7 cm = >20%/yr. Elective repair at ≥5.5 cm in men, ≥5 cm in women."),
("Rate of expansion", "Rapid growth (>1 cm/year or >0.5 cm in 6 months) – high rupture risk regardless of size"),
("Shape", "Saccular aneurysms rupture more than fusiform; eccentric aneurysms at higher risk"),
("Hypertension", "Raised wall stress (T = P × r, Laplace's law) → increased risk"),
("Smoking", "Active smoking – strongest independent risk factor for rupture (3× risk)"),
("COPD", "Associated with rapid expansion and rupture (shared pathogenesis: elastin degradation)"),
("Female sex", "Women have higher rupture risk at smaller diameters (repair threshold 5 cm vs. 5.5 cm)"),
("Family history", "First-degree relative with AAA – 4× risk"),
]
t11 = Table(rupture_factors, colWidths=[3.5*cm, 11.2*cm])
t11.setStyle(TableStyle([
('BACKGROUND', (0,0), (0,-1), colors.HexColor('#fce4ec')),
('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('GRID', (0,0), (-1,-1), 0.4, colors.grey),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('ROWBACKGROUNDS', (0,0), (-1,-1), [colors.white, colors.HexColor('#fce4ec')]),
]))
story.append(t11)
story.append(sp(6))
story.append(subq("4. Chronic Venous Insufficiency – Pathophysiology & Clinical Features"))
story.append(h3("Pathophysiology"))
story.append(ans(
"CVI results from sustained <b>venous hypertension</b> in the lower limb due to valve incompetence "
"(primary: degeneration; secondary: post-DVT). The mechanism:"
))
story.append(bullet("Valvular incompetence → retrograde blood flow (reflux) → venous hypertension"))
story.append(bullet("Venous HTN → capillary hypertension → oedema (protein-rich fluid in interstitium)"))
story.append(bullet("Leucocyte trapping in capillaries → inflammatory mediators → tissue damage"))
story.append(bullet("Fibrin cuff theory: periCapillary fibrin deposition → O2/nutrient barrier → skin ischaemia"))
story.append(bullet("Lipodermosclerosis: fibrosis of skin and fat → haemosiderin deposition (haemosiderin from RBC degradation)"))
story.append(bullet("End result: venous ulceration in gaiter zone (above medial malleolus)"))
story.append(h3("Clinical Features (CEAP Classification C0–C6):"))
ceap = [
["CEAP", "Feature"],
["C0", "No visible or palpable signs of venous disease"],
["C1", "Telangiectasia (spider veins <1 mm) or reticular veins (1–3 mm)"],
["C2", "Varicose veins >3 mm (tortuous, dilated superficial veins)"],
["C3", "Oedema – ankle/lower leg, pitting, worsens with prolonged standing"],
["C4a", "Pigmentation (haemosiderin) + eczema (venous eczema/stasis dermatitis)"],
["C4b", "Lipodermatosclerosis (LDS) + atrophie blanche (white sclerotic areas)"],
["C5", "Healed venous ulcer"],
["C6", "Active venous ulcer – shallow, irregular, gaiter zone, sloping edges, moist base, painless"],
]
t12 = Table(ceap, colWidths=[1.8*cm, 12.9*cm])
t12.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#880e4f')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#fce4ec'), colors.white]),
('GRID', (0,0), (-1,-1), 0.4, colors.grey),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 2),
('BOTTOMPADDING', (0,0), (-1,-1), 2),
]))
story.append(t12)
story.append(sp(6))
story.append(subq("5. Six P's of Acute Limb Ischaemia & Why It is a Surgical Emergency"))
story.append(h3("Classical Six P's of Acute Limb Ischaemia"))
six_p = [
["'P'", "Description"],
["Pain", "Sudden, severe, distal → proximal (initially sharp, then may decrease as ischaemia progresses and nerves die)"],
["Pallor", "Limb appears pale/white (lack of blood flow). Later mottling (fixed staining = irreversible ischaemia)"],
["Pulselessness", "Absent pulses distal to occlusion (confirms vascular occlusion)"],
["Paraesthesia", "Pins and needles → numbness (ischaemia of sensory nerve fibres – early warning sign)"],
["Paralysis", "Inability to move the limb (motor paralysis = advanced ischaemia – ominous sign, near-irreversible)"],
["Perishing cold\n(Poikilothermia)", "Limb cold to touch (absence of warm arterial blood). Temperature demarcation helps localise level of occlusion."],
]
t13 = Table(six_p, colWidths=[3.5*cm, 11.2*cm])
t13.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#4a148c')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#f3e5f5'), colors.white]),
('GRID', (0,0), (-1,-1), 0.4, colors.grey),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
]))
story.append(t13)
story.append(h3("Why It Is a Surgical Emergency:"))
story.append(ans(
"Skeletal muscle can withstand ischaemia for only <b>4–6 hours</b> before irreversible necrosis occurs. "
"Beyond this, reperfusion causes <b>reperfusion injury</b> (myonecrosis → hyperkalaemia, myoglobinuria → "
"acute tubular necrosis). Paralysis/paraesthesia indicate impending irreversibility. "
"Treatment (embolectomy/thrombectomy/bypass) must occur within the ischaemic window. "
"<b>Delay = limb loss and/or death.</b>"
))
story.append(bullet("Rutherford I (viable): No sensory/motor loss → urgent but less critical"))
story.append(bullet("Rutherford IIa (threatened, marginally): Sensory loss, no motor → emergency"))
story.append(bullet("Rutherford IIb (threatened, immediately): Sensory + motor loss → IMMEDIATE surgery"))
story.append(bullet("Rutherford III (irreversible): Paralysis, fixed staining, rigor → primary amputation"))
# Build PDF
doc.build(story)
print(f"PDF created at: {OUTPUT}")
cd /tmp/workspace/mbbs-proff-answers && python generate_answers.py 2>&1
~/mbbs-proff-answers/generate_answers.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/mbbs-proff-answers/generate_answers.py'
cd /tmp/workspace/mbbs-proff-answers && python generate_answers.py 2>&1
ls -lh /tmp/workspace/mbbs-proff-answers/MBBS_Proff_Answers.pdf
MBBS Proff Answers
PDF Document · PDF
The words are overlapping Correct that with diagrams and flow charts with belly and love
~/mbbs-proff-answers/make_diagrams.py
"""
Generate all diagram/flowchart images as PNG files for embedding in PDF.
Uses matplotlib only – no overlapping text.
"""
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch
import numpy as np
import os
OUT = "/tmp/workspace/mbbs-proff-answers/diagrams"
os.makedirs(OUT, exist_ok=True)
# ──────────────────────────────────────────────────────────────────────────────
# Helper: draw a rounded box
# ──────────────────────────────────────────────────────────────────────────────
def rbox(ax, x, y, w, h, text, fc, ec='#444', fontsize=9, tc='black', style='round,pad=0.1'):
box = FancyBboxPatch((x - w/2, y - h/2), w, h,
boxstyle=style, facecolor=fc, edgecolor=ec, linewidth=1.2)
ax.add_patch(box)
ax.text(x, y, text, ha='center', va='center', fontsize=fontsize,
color=tc, fontweight='bold', wrap=True,
multialignment='center',
bbox=dict(boxstyle='square,pad=0', fc='none', ec='none'))
def arrow(ax, x1, y1, x2, y2, color='#555', lw=1.5):
ax.annotate('', xy=(x2, y2), xytext=(x1, y1),
arrowprops=dict(arrowstyle='->', color=color, lw=lw))
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 1 – Septic Shock: Golden Hour 1-Hour Bundle Flowchart
# ══════════════════════════════════════════════════════════════════════════════
fig, ax = plt.subplots(figsize=(9, 10))
ax.set_xlim(0, 9); ax.set_ylim(0, 10)
ax.axis('off')
ax.set_facecolor('#f8f9fa')
fig.patch.set_facecolor('#f8f9fa')
ax.text(4.5, 9.6, 'SEPTIC SHOCK – Golden Hour Management (SSC 1-Hour Bundle)',
ha='center', va='center', fontsize=11, fontweight='bold', color='#b71c1c')
ax.text(4.5, 9.25, '(Bailey & Love / Surviving Sepsis Campaign 2021)',
ha='center', va='center', fontsize=8, color='#555')
# Start box
rbox(ax, 4.5, 8.7, 5.5, 0.55, 'RECOGNISE SEPTIC SHOCK\n(Infection + MAP<65 + Lactate>2 + Vasopressors needed)',
'#b71c1c', tc='white', fontsize=8.5)
arrow(ax, 4.5, 8.4, 4.5, 8.05)
# 5 parallel steps
steps = [
(1.0, 7.5, '① Blood Cultures\n× 2 sets\n(before antibiotics)', '#1565c0'),
(2.7, 7.5, '② Broad-spectrum\nAntibiotics\nwithin 1 HOUR', '#1b5e20'),
(4.5, 7.5, '③ 30 mL/kg IV\nCrystalloid\nwithin 3 hrs', '#4a148c'),
(6.3, 7.5, '④ Measure\nSerum Lactate\n(remeasure if >2)', '#e65100'),
(8.0, 7.5, '⑤ Vasopressors\nif MAP<65\n(Noradrenaline)', '#880e4f'),
]
for (x, y, txt, col) in steps:
rbox(ax, x, y, 1.55, 0.95, txt, col, tc='white', fontsize=7.5)
arrow(ax, 4.5, 8.05, x, y+0.48)
# Source control
arrow(ax, 4.5, 7.02, 4.5, 6.45)
rbox(ax, 4.5, 6.15, 5.5, 0.55, '⑥ SOURCE CONTROL – Debridement/drainage of foot wound\nas soon as medically feasible',
'#37474f', tc='white', fontsize=8.5)
# Monitoring
arrow(ax, 4.5, 5.87, 4.5, 5.35)
rbox(ax, 4.5, 5.05, 5.5, 0.55, 'MONITOR RESUSCITATION ADEQUACY',
'#006064', tc='white', fontsize=9)
monitors = [
(1.5, 4.1, 'MAP ≥65 mmHg\nHR <100/min\nWarm extremities'),
(3.7, 4.1, 'Urine output\n≥0.5 mL/kg/hr\n(aim >35 mL/hr)'),
(5.8, 4.1, 'Lactate clearance\n≥10% per 2 hrs\nTarget <2 mmol/L'),
(7.8, 4.1, 'ScvO2 ≥70%\nPOCUS\nBedside ECHO'),
]
for (x, y, txt) in monitors:
rbox(ax, x, y, 1.9, 0.85, txt, '#e0f7fa', ec='#006064', fontsize=7.5)
arrow(ax, 4.5, 4.77, x, y+0.43)
# Not improving
arrow(ax, 4.5, 3.68, 4.5, 3.18)
rbox(ax, 4.5, 2.9, 5.5, 0.55, 'IF REFRACTORY: Add Vasopressin 0.03 U/min\n+ Hydrocortisone 200 mg/day IV + ICU Admission',
'#4e342e', tc='white', fontsize=8.5)
ax.text(4.5, 0.2, 'Bailey & Love\'s Short Practice of Surgery 28e – Chapter 2: Shock',
ha='center', fontsize=7, color='#888', style='italic')
plt.tight_layout()
plt.savefig(f'{OUT}/01_septic_shock_golden_hour.png', dpi=150, bbox_inches='tight')
plt.close()
print("Diagram 1 done")
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 2 – Wound Healing Phases (Timeline + Mediators)
# ══════════════════════════════════════════════════════════════════════════════
fig, ax = plt.subplots(figsize=(11, 7))
ax.set_xlim(0, 11); ax.set_ylim(0, 7)
ax.axis('off')
ax.set_facecolor('#fafafa')
fig.patch.set_facecolor('#fafafa')
ax.text(5.5, 6.7, 'WOUND HEALING – Phases & Key Mediators',
ha='center', fontsize=12, fontweight='bold', color='#1a237e')
ax.text(5.5, 6.4, '(Bailey & Love\'s Chapter 3 | Sabiston Surgery Chapter 23)',
ha='center', fontsize=8, color='#666', style='italic')
# Timeline bar
ax.barh(5.5, 10, left=0.5, height=0.4, color='#e0e0e0', edgecolor='#bbb')
# Phase bars
phases = [
(0.5, 0.3, '#ef9a9a', 'HAEMOSTASIS\n0–mins'),
(0.5, 3.5, '#ffcc80', 'INFLAMMATION\nDays 0–4'),
(3.5, 4.5, '#a5d6a7', 'PROLIFERATION\nDays 4–21'),
(7.5, 3.0, '#90caf9', 'REMODELLING\nWks 3–2yrs'),
]
for (start, width, col, label) in phases:
ax.barh(5.5, width, left=start, height=0.4, color=col, edgecolor='#888', alpha=0.9)
ax.text(start + width/2, 5.5, label, ha='center', va='center',
fontsize=7.5, fontweight='bold', color='#222')
ax.set_xticks([0.5, 1, 2, 3.5, 5, 7.5, 10.5])
ax.set_xticklabels(['0', '1d', '2d', '4d', '1wk', '3wk', '2yr'], fontsize=7.5)
ax.tick_params(axis='x', which='both', length=4)
ax.spines['bottom'].set_visible(True)
ax.spines['bottom'].set_bounds(0.5, 10.5)
ax.yaxis.set_visible(False)
# Detail boxes for each phase
box_data = [
(1.0, 3.8, 1.8, 1.3, '#ffebee', '#c62828',
'HAEMOSTASIS',
['• Vascular injury', '• Vasoconstriction', '• Platelet plug', '• Fibrin clot scaffold',
'• Growth factors released:', ' TGF-β, PDGF, VEGF, EGF', ' FGF (from platelets)']),
(3.2, 3.8, 2.4, 1.3, '#fff3e0', '#e65100',
'INFLAMMATION (Day 0–4)',
['Early (0–3d): Neutrophils', ' → Kill bacteria via ROS', ' → Release IL-8, proteases',
'Late (Day 2+): Macrophages', ' → Release IL-1, IL-6, TNF-α',
' → PDGF, TGF-β, VEGF, bFGF',
' → MMPs (matrix remodelling)',
'Clinical: Rubor, Tumor, Calor, Dolor']),
(6.2, 3.8, 2.4, 1.3, '#e8f5e9', '#2e7d32',
'PROLIFERATION (Day 4–21)',
['• Fibroblasts: Collagen III synthesis', '• Granulation tissue formation',
' (collagen + new capillaries)',
'• Angiogenesis: VEGF, FGF',
'• Keratinocytes: Re-epithelialise', ' (EGF, KGF)',
'• Myofibroblasts: Wound contraction', ' (TGF-β mediated)']),
(9.0, 3.8, 1.8, 1.3, '#e3f2fd', '#1565c0',
'REMODELLING (3wk–2yr)',
['• Collagen III → Collagen I', '• Lysyl oxidase crosslinking',
'• Tensile strength → 80%', '• MMPs vs TIMPs balance',
'• Scar maturation:', ' Red → White', ' Raised → Flat']),
]
for (cx, cy, bw, bh, fc, hc, title, items) in box_data:
# Box
rect = FancyBboxPatch((cx - bw/2, cy - bh/2), bw, bh,
boxstyle='round,pad=0.05', facecolor=fc,
edgecolor=hc, linewidth=1.5)
ax.add_patch(rect)
# Header
hrect = FancyBboxPatch((cx - bw/2, cy + bh/2 - 0.22), bw, 0.22,
boxstyle='round,pad=0', facecolor=hc, edgecolor=hc)
ax.add_patch(hrect)
ax.text(cx, cy + bh/2 - 0.11, title, ha='center', va='center',
fontsize=7, fontweight='bold', color='white')
# Content
y_start = cy + bh/2 - 0.28
for item in items:
ax.text(cx - bw/2 + 0.06, y_start, item, ha='left', va='top',
fontsize=6.5, color='#222')
y_start -= 0.135
# Arrow from timeline to boxes
for cx in [1.0, 3.2+0.2, 6.2+0.2, 9.0]:
arrow(ax, cx, 5.28, cx, cy + bh/2 + 0.02 if cx != 1.0 else 3.8 + 1.3/2)
ax.text(5.5, 0.15, 'Bailey & Love\'s Short Practice of Surgery 28e, Chapter 3 (Normal Wound Healing in Skin)',
ha='center', fontsize=6.5, color='#888', style='italic')
plt.tight_layout()
plt.savefig(f'{OUT}/02_wound_healing.png', dpi=150, bbox_inches='tight')
plt.close()
print("Diagram 2 done")
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 3 – Cervical Lymph Node Levels (Schematic)
# ══════════════════════════════════════════════════════════════════════════════
fig, ax = plt.subplots(figsize=(10, 7))
ax.set_xlim(0, 10); ax.set_ylim(0, 7)
ax.axis('off')
ax.set_facecolor('#f5f5f5')
fig.patch.set_facecolor('#f5f5f5')
ax.text(5, 6.75, 'CERVICAL LYMPH NODE LEVELS – Robbins Classification',
ha='center', fontsize=12, fontweight='bold', color='#1a237e')
ax.text(5, 6.45, '(Bailey & Love\'s / Memorial Sloan Kettering Classification)',
ha='center', fontsize=8, color='#666', style='italic')
# Simple head/neck outline
from matplotlib.patches import Ellipse, Arc
head = Ellipse((5, 4.5), 2.2, 2.8, color='#ffe0b2', zorder=1)
ax.add_patch(head)
# Neck
neck = plt.Polygon([[4.1, 3.1], [5.9, 3.1], [6.1, 1.5], [3.9, 1.5]],
closed=True, facecolor='#ffcc80', edgecolor='#e65100', lw=1, zorder=1)
ax.add_patch(neck)
ax.text(5, 5.5, 'HEAD', ha='center', va='center', fontsize=9, fontweight='bold', color='#5d4037')
ax.text(5, 2.3, 'NECK', ha='center', va='center', fontsize=9, fontweight='bold', color='#5d4037')
# Level boxes on LEFT side
levels_left = [
(1.2, 5.8, 'Level I\nSubmental (IA)\nSubmandibular (IB)', '#ef9a9a', '#c62828'),
(1.2, 4.6, 'Level II\nUpper Jugular\n(Jugulodigastric)', '#ffcc80', '#e65100'),
(1.2, 3.4, 'Level III\nMiddle Jugular\n(Hyoid→Cricoid)', '#a5d6a7', '#2e7d32'),
(1.2, 2.2, 'Level IV\nLower Jugular\n(Cricoid→Clavicle)', '#90caf9', '#1565c0'),
]
for (x, y, txt, fc, ec) in levels_left:
rbox(ax, x, y, 2.0, 0.7, txt, fc, ec=ec, fontsize=7.5)
ax.annotate('', xy=(3.7, y), xytext=(2.2, y),
arrowprops=dict(arrowstyle='->', color=ec, lw=1.2))
# Level boxes on RIGHT side
levels_right = [
(8.8, 4.6, 'Level V\nPosterior Triangle\n(SAN region)', '#ce93d8', '#6a1b9a'),
(8.8, 3.4, 'Level VI\nCentral Compartment\n(Pretracheal, Paratracheal)', '#80deea', '#006064'),
(8.8, 2.2, 'Level VII\nSuperior Mediastinum\n(Below sternal notch)', '#bcaaa4', '#4e342e'),
]
for (x, y, txt, fc, ec) in levels_right:
rbox(ax, x, y, 2.0, 0.7, txt, fc, ec=ec, fontsize=7.5)
ax.annotate('', xy=(6.3, y), xytext=(7.8, y),
arrowprops=dict(arrowstyle='->', color=ec, lw=1.2))
# Drainage legend
ax.text(5, 0.6, 'I → Lip/Floor of mouth | II → Oral/Nasopharynx | III → Oropharynx | IV → Thyroid/Larynx | V → Nasopharynx/Posterior | VI → Thyroid/Trachea',
ha='center', fontsize=6.8, color='#444', style='italic',
bbox=dict(boxstyle='round,pad=0.3', fc='white', ec='#bbb'))
ax.text(5, 0.15, 'Bailey & Love\'s Short Practice of Surgery 28e – Cervical Lymphadenitis (Chapter 6)',
ha='center', fontsize=6.5, color='#888', style='italic')
plt.tight_layout()
plt.savefig(f'{OUT}/03_cervical_nodes.png', dpi=150, bbox_inches='tight')
plt.close()
print("Diagram 3 done")
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 4 – Damage Control Resuscitation + Lethal Triad
# ══════════════════════════════════════════════════════════════════════════════
fig, axes = plt.subplots(1, 2, figsize=(13, 7))
fig.patch.set_facecolor('#fafafa')
# ─── LEFT: Lethal Triad ───
ax = axes[0]
ax.set_xlim(0, 6); ax.set_ylim(0, 7)
ax.axis('off')
ax.set_facecolor('#fafafa')
ax.text(3, 6.75, 'TRAUMA LETHAL TRIAD\n("Triad of Death")', ha='center',
fontsize=11, fontweight='bold', color='#b71c1c')
# Triangle
triangle_pts = np.array([[3, 5.7], [0.7, 1.5], [5.3, 1.5]])
triangle = plt.Polygon(triangle_pts, fill=False, edgecolor='#b71c1c', lw=2.5, linestyle='--')
ax.add_patch(triangle)
# Three corners
rbox(ax, 3, 5.9, 2.2, 0.65, 'HYPOTHERMIA\n(< 35°C)', '#1565c0', tc='white', fontsize=9)
rbox(ax, 0.7, 1.2, 2.0, 0.65, 'ACIDOSIS\n(pH < 7.35)', '#e65100', tc='white', fontsize=9)
rbox(ax, 5.3, 1.2, 2.0, 0.65, 'COAGULOPATHY\n(INR > 1.5)', '#1b5e20', tc='white', fontsize=9)
# Centre
rbox(ax, 3, 3.5, 1.8, 0.65, '💀 DEATH\n(if uncorrected)', '#b71c1c', tc='white', fontsize=9)
# Arrows around triangle (vicious cycle)
ax.annotate('', xy=(1.5, 2.0), xytext=(2.2, 5.5),
arrowprops=dict(arrowstyle='->', color='#555', lw=1.5))
ax.text(1.3, 3.8, '↓ Coag\nenzymes', ha='center', fontsize=7, color='#555')
ax.annotate('', xy=(4.5, 2.0), xytext=(3.8, 5.5),
arrowprops=dict(arrowstyle='->', color='#555', lw=1.5))
ax.text(4.7, 3.8, '↑ Lactic\nacid', ha='center', fontsize=7, color='#555')
ax.annotate('', xy=(4.4, 1.5), xytext=(1.6, 1.5),
arrowprops=dict(arrowstyle='->', color='#555', lw=1.5))
ax.text(3, 1.0, 'Dilution + consumption of clotting factors', ha='center', fontsize=7, color='#555')
# Causes
ax.text(3, 0.4, 'Causes: Haemorrhage → cold fluids → haemostatic failure\nCorrect with: Warming + 1:1:1 blood products + TXA',
ha='center', fontsize=7.5, color='#444',
bbox=dict(boxstyle='round,pad=0.3', fc='#fff3e0', ec='#e65100'))
# ─── RIGHT: DCR Flowchart ───
ax = axes[1]
ax.set_xlim(0, 7); ax.set_ylim(0, 7)
ax.axis('off')
ax.set_facecolor('#fafafa')
ax.text(3.5, 6.75, 'DAMAGE CONTROL RESUSCITATION (DCR)', ha='center',
fontsize=11, fontweight='bold', color='#1a237e')
dcr_steps = [
(3.5, 6.1, 3.5, 'POLYTRAUMA + HAEMORRHAGIC SHOCK', '#b71c1c', 'white'),
(3.5, 5.2, 3.5, 'PERMISSIVE HYPOTENSION\nTarget SBP 80–90 mmHg (until haemostasis)\n(EXCEPT if TBI: maintain MAP ≥80)', '#1565c0', 'white'),
(3.5, 4.1, 3.5, 'HAEMOSTATIC RESUSCITATION\n1:1:1 pRBC : FFP : Platelets\n+ Early Tranexamic Acid (within 3 hrs)\nAVOID excess crystalloids', '#2e7d32', 'white'),
(3.5, 3.0, 3.5, 'DAMAGE CONTROL SURGERY\nAbbreviated laparotomy (pack + clamp)\nPelvic binder, splint long bones\nTemporary closure – ICU stabilise', '#4a148c', 'white'),
(3.5, 1.9, 3.5, 'ICU RESUSCITATION\nRewarm – correct acidosis\nCorrect coagulopathy\nDefinitive organ assessment', '#006064', 'white'),
(3.5, 0.9, 3.5, 'DEFINITIVE SURGERY\n(After physiological stabilisation)', '#37474f', 'white'),
]
for i, (x, y, w, txt, fc, tc) in enumerate(dcr_steps):
rbox(ax, x, y, w, 0.72, txt, fc, tc=tc, fontsize=7.8)
if i < len(dcr_steps) - 1:
arrow(ax, x, y - 0.36, x, dcr_steps[i+1][1] + 0.36)
plt.tight_layout(pad=1.5)
plt.savefig(f'{OUT}/04_lethal_triad_dcr.png', dpi=150, bbox_inches='tight')
plt.close()
print("Diagram 4 done")
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 5 – Virchow's Triad + Six P's of ALI
# ══════════════════════════════════════════════════════════════════════════════
fig, axes = plt.subplots(1, 2, figsize=(13, 6.5))
fig.patch.set_facecolor('#fafafa')
# ─── LEFT: Virchow's Triad ───
ax = axes[0]
ax.set_xlim(0, 6); ax.set_ylim(0, 6.5)
ax.axis('off')
ax.text(3, 6.3, "VIRCHOW'S TRIAD – DVT Pathogenesis", ha='center',
fontsize=11, fontweight='bold', color='#1a237e')
# Three circles
from matplotlib.patches import Circle
c_positions = [(1.5, 3.5), (4.5, 3.5), (3.0, 1.5)]
c_colors = ['#bbdefb', '#ffe0b2', '#e8f5e9']
c_labels = ['Endothelial\nInjury', 'Hypercoagu-\nlability', 'Stasis']
c_ec = ['#1565c0', '#e65100', '#2e7d32']
for (cx, cy), fc, label, ec in zip(c_positions, c_colors, c_labels, c_ec):
circ = Circle((cx, cy), 1.3, facecolor=fc, edgecolor=ec, lw=2, alpha=0.85, zorder=2)
ax.add_patch(circ)
ax.text(cx, cy, label, ha='center', va='center', fontsize=9.5,
fontweight='bold', color=ec, zorder=3, multialignment='center')
# DVT in centre
rbox(ax, 3, 2.9, 1.5, 0.52, 'DVT', '#b71c1c', tc='white', fontsize=11)
# Examples for each
examples = [
(0.15, 5.1, 'Surgery, trauma\nIV catheters\nVaricose veins', '#1565c0'),
(4.8, 5.1, 'Factor V Leiden\nMalignancy, OCP\nProtein C/S deficiency', '#e65100'),
(3, 0.35, 'Immobility (bed rest, long flights)\nHeart failure, obesity, paralysis', '#2e7d32'),
]
for (x, y, txt, col) in examples:
ax.text(x, y, txt, ha='center', fontsize=7, color=col,
bbox=dict(boxstyle='round,pad=0.25', fc='white', ec=col, lw=0.8))
# ─── RIGHT: Six P's ───
ax = axes[1]
ax.set_xlim(0, 7); ax.set_ylim(0, 6.5)
ax.axis('off')
ax.text(3.5, 6.3, "SIX P's – Acute Limb Ischaemia", ha='center',
fontsize=11, fontweight='bold', color='#b71c1c')
ax.text(3.5, 6.0, "(Rutherford Classification + Urgency)", ha='center',
fontsize=8, color='#666', style='italic')
p_data = [
('Pain', 'Sudden severe distal pain; may decrease as nerves die', '#ef9a9a', '#c62828'),
('Pallor', 'Pale/white limb; later mottling (fixed = irreversible)', '#fff9c4', '#f57f17'),
('Pulselessness', 'Absent pulses distal to occlusion – confirms vascular block', '#ffe0b2', '#e65100'),
('Paraesthesia', 'Pins & needles → numbness (sensory nerve ischaemia – EARLY sign)', '#c8e6c9', '#2e7d32'),
('Paralysis', 'Motor loss = ADVANCED ischaemia – near-irreversible ⚠️', '#b3e5fc', '#0277bd'),
('Perishing cold', 'Cold limb from absent warm arterial flow; demarcates level', '#e1bee7', '#6a1b9a'),
]
y_pos = 5.4
for (p, desc, fc, ec) in p_data:
rbox(ax, 1.0, y_pos, 1.6, 0.45, p, fc, ec=ec, fontsize=9, tc=ec)
ax.text(2.0, y_pos, desc, ha='left', va='center', fontsize=7.5, color='#333')
y_pos -= 0.75
# Rutherford
ax.text(3.5, 0.9, 'Rutherford: I = Viable (urgent) | IIa = Threatened marginal (emergency)\nIIb = Threatened immediate (IMMEDIATE surgery) | III = Irreversible (amputation)',
ha='center', fontsize=7, color='#444',
bbox=dict(boxstyle='round,pad=0.3', fc='#fff3e0', ec='#e65100'))
plt.tight_layout(pad=1.5)
plt.savefig(f'{OUT}/05_virchow_sixPs.png', dpi=150, bbox_inches='tight')
plt.close()
print("Diagram 5 done")
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 6 – TB Lymphadenitis Stages
# ══════════════════════════════════════════════════════════════════════════════
fig, ax = plt.subplots(figsize=(11, 4.5))
ax.set_xlim(0, 11); ax.set_ylim(0, 4.5)
ax.axis('off')
ax.set_facecolor('#e8f5e9')
fig.patch.set_facecolor('#e8f5e9')
ax.text(5.5, 4.25, 'TUBERCULOUS CERVICAL LYMPHADENITIS – Stages (Beedham & Hudson)',
ha='center', fontsize=11, fontweight='bold', color='#1b5e20')
stages = [
(0.9, 'Stage I\nLymphadenitis\n(Reactive)',
'Firm, discrete\nmobile nodes\nNo necrosis\nNot matted', '#fff9c4', '#f9a825'),
(2.9, 'Stage II\nPeriadenitis',
'Nodes become\nMATTED\nCapsular inflammation\nStill firm', '#ffe0b2', '#e65100'),
(4.9, 'Stage III\nCaseous\nSoftening',
'Central CASEATION\nFluctuant node\nCold abscess forming\nDeep to fascia', '#ffccbc', '#bf360c'),
(6.9, 'Stage IV\nCollar-Stud\nAbscess',
'Bursts through\ndeep fascia\nBilocular abscess\nCross-fluctuation', '#ce93d8', '#6a1b9a'),
(8.9, 'Stage V\nSinus /\nUlceration',
'Ruptures skin\nDischarging sinus\nUnderMINED edges\nWatery pus', '#b0bec5', '#37474f'),
]
for i, (cx, title, detail, fc, ec) in enumerate(stages):
rbox(ax, cx, 2.8, 1.75, 0.8, title, ec, tc='white', fontsize=8)
rbox(ax, cx, 1.4, 1.75, 1.4, detail, fc, ec=ec, fontsize=7.5)
arrow(ax, cx, 2.4, cx, 2.12)
if i < len(stages) - 1:
arrow(ax, cx + 0.875, 2.8, stages[i+1][0] - 0.875, 2.8, color=ec)
# Progression label
ax.text(5.5, 0.25, 'Progression: weeks to months | Treatment: ATT (HRZE×2m → HR×4m) + Aspiration if fluctuant',
ha='center', fontsize=7.5, color='#1b5e20', fontweight='bold',
bbox=dict(boxstyle='round,pad=0.3', fc='white', ec='#2e7d32'))
ax.text(5.5, 3.9, '← This case is Stage III–IV →', ha='center', fontsize=8, color='#b71c1c',
fontweight='bold')
plt.tight_layout()
plt.savefig(f'{OUT}/06_tb_lymphadenitis_stages.png', dpi=150, bbox_inches='tight')
plt.close()
print("Diagram 6 done")
# ══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 7 – TNBC Paradox + BCS contraindications
# ══════════════════════════════════════════════════════════════════════════════
fig, axes = plt.subplots(1, 2, figsize=(13, 6))
fig.patch.set_facecolor('#fafafa')
# ─── LEFT: TNBC Paradox flowchart ───
ax = axes[0]
ax.set_xlim(0, 7); ax.set_ylim(0, 7)
ax.axis('off')
ax.text(3.5, 6.75, 'TNBC PARADOX', ha='center', fontsize=12, fontweight='bold', color='#4a148c')
rbox(ax, 3.5, 6.1, 5.5, 0.6, 'TNBC – ER(-) PR(-) HER2(-)\n~10–15% of all breast cancers', '#4a148c', tc='white', fontsize=9)
arrow(ax, 3.5, 5.8, 3.5, 5.3)
rbox(ax, 3.5, 5.0, 5.5, 0.55, 'Neoadjuvant Chemotherapy (NACT)\nAnthracycline + Taxane (AC-T)', '#1565c0', tc='white', fontsize=9)
arrow(ax, 3.5, 4.72, 2.0, 4.2)
arrow(ax, 3.5, 4.72, 5.0, 4.2)
rbox(ax, 2.0, 3.85, 2.8, 0.65, 'pCR Achieved\n(~30–40%)', '#2e7d32', tc='white', fontsize=9)
rbox(ax, 5.0, 3.85, 2.8, 0.65, 'Residual Disease\n(~60–70%)', '#c62828', tc='white', fontsize=9)
ax.text(1.7, 3.1, '✓ Good short-term\nresponse', ha='center', fontsize=8, color='#2e7d32')
ax.text(5.3, 3.1, '✗ Very poor\nprognosis\n("All or Nothing")', ha='center', fontsize=8, color='#c62828', fontweight='bold')
# PARADOX label
rbox(ax, 3.5, 2.3, 5.5, 0.5, '⚠ THE PARADOX: High chemosensitivity\nYET overall worse outcome than ER+/HER2+ disease', '#880e4f', tc='white', fontsize=8.5)
arrow(ax, 3.5, 2.05, 3.5, 1.6)
rbox(ax, 3.5, 1.25, 5.5, 0.6,
'Residual disease → Capecitabine (CREATE-X)\nPD-L1+: Pembrolizumab (KEYNOTE-522)\nBRCA mut: Olaparib\nMetastatic: Sacituzumab govitecan',
'#37474f', tc='white', fontsize=8)
# ─── RIGHT: BCS Contraindications ───
ax = axes[1]
ax.set_xlim(0, 7); ax.set_ylim(0, 7)
ax.axis('off')
ax.text(3.5, 6.75, 'CONTRAINDICATIONS TO BCS', ha='center', fontsize=12, fontweight='bold', color='#b71c1c')
rbox(ax, 3.5, 6.1, 6.0, 0.55, 'ABSOLUTE CONTRAINDICATIONS', '#b71c1c', tc='white', fontsize=10)
abs_ci = [
'Diffuse malignant/indeterminate microcalcifications',
'Multicentricity (tumour in ≥2 quadrants)',
'Inflammatory breast cancer',
'Prior breast irradiation (cannot re-irradiate)',
'Positive margins despite repeated re-excision',
'Large tumour: unfavourable tumour-to-breast ratio',
]
y = 5.55
for item in abs_ci:
ax.text(0.3, y, f'✗ {item}', ha='left', va='top', fontsize=8.5, color='#c62828')
y -= 0.45
rbox(ax, 3.5, 2.7, 6.0, 0.55, 'RELATIVE CONTRAINDICATIONS', '#e65100', tc='white', fontsize=10)
rel_ci = [
'Active collagen vascular disease (scleroderma, SLE)',
'BRCA1/2 mutation (↑ recurrence risk – mastectomy preferred)',
'Large tumour T3 >5cm (NACT first to downstage)',
'Pregnancy (1st/2nd trimester – RT deferred)',
'Patient preference for mastectomy',
]
y = 2.15
for item in rel_ci:
ax.text(0.3, y, f'△ {item}', ha='left', va='top', fontsize=8.5, color='#e65100')
y -= 0.42
plt.tight_layout(pad=1.5)
plt.savefig(f'{OUT}/07_tnbc_bcs.png', dpi=150, bbox_inches='tight')
plt.close()
print("Diagram 7 done")
print("\nAll diagrams generated successfully!")
cd /tmp/workspace/mbbs-proff-answers && python make_diagrams.py 2>&1
PDF?
ls /tmp/workspace/mbbs-proff-answers/ && ls /tmp/workspace/mbbs-proff-answers/diagrams/
mkdir -p /tmp/workspace/mbbs-proff-answers/diagrams && python3 -c "import matplotlib, reportlab; print('libs ok')"
~/mbbs-proff-answers/build_pdf.py
"""
MBBS Proff Surgery – Complete Answer PDF
Diagrams + ReportLab PDF, no overlapping text.
"""
import os, textwrap
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyBboxPatch, Ellipse, Circle
import numpy as np
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,
HRFlowable, Table, TableStyle,
PageBreak, Image, KeepTogether)
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
DIAG = "/tmp/workspace/mbbs-proff-answers/diagrams"
OUT = "/tmp/workspace/mbbs-proff-answers/MBBS_Proff_Answers.pdf"
os.makedirs(DIAG, exist_ok=True)
PW = A4[0] - 3.6*cm # usable page width
# ─────────────────────────────── DIAGRAM HELPERS ──────────────────────────────
def rbox(ax, x, y, w, h, text, fc, ec='#444', fs=9, tc='black'):
p = FancyBboxPatch((x-w/2, y-h/2), w, h,
boxstyle='round,pad=0.08',
facecolor=fc, edgecolor=ec, linewidth=1.2, zorder=3)
ax.add_patch(p)
ax.text(x, y, text, ha='center', va='center', fontsize=fs,
color=tc, fontweight='bold', multialignment='center', zorder=4)
def arr(ax, x1, y1, x2, y2, col='#555', lw=1.4):
ax.annotate('', xy=(x2,y2), xytext=(x1,y1),
arrowprops=dict(arrowstyle='->', color=col, lw=lw), zorder=5)
def save(fig, name):
fig.savefig(f'{DIAG}/{name}', dpi=150, bbox_inches='tight')
plt.close(fig)
# ══════════════════════════════════════════════════════════════
# DIAGRAM 1 Septic Shock – Golden Hour Flowchart
# ══════════════════════════════════════════════════════════════
def make_d1():
fig,ax = plt.subplots(figsize=(9,10))
ax.set_xlim(0,9); ax.set_ylim(0,10); ax.axis('off')
fig.patch.set_facecolor('#fafafa'); ax.set_facecolor('#fafafa')
ax.text(4.5,9.7,'SEPTIC SHOCK – Golden Hour Management',ha='center',
fontsize=12,fontweight='bold',color='#b71c1c')
ax.text(4.5,9.35,'SSC 1-Hour Bundle | Bailey & Love Ch. 2',ha='center',
fontsize=8,color='#555',style='italic')
rbox(ax,4.5,8.8,7.5,0.65,
'RECOGNISE SEPTIC SHOCK\nInfection + MAP <65 mmHg + Lactate >2 mmol/L + Vasopressors needed',
'#b71c1c',ec='#7f0000',fs=9,tc='white')
arr(ax,4.5,8.47,4.5,8.12)
# 5 parallel bundles
bx=[1.0,2.7,4.5,6.3,8.0]
btxt=['Blood\nCultures x2\n(before Abx)','Broad-spectrum\nAntibiotics\nWithin 1 HOUR',
'30 mL/kg IV\nCrystalloid\nwithin 3 hrs','Measure\nSerum Lactate\n(remeasure if>2)',
'Noradrenaline\nif MAP<65\n(1st-line VP)']
bcol=['#1565c0','#1b5e20','#4a148c','#e65100','#880e4f']
for x,t,c in zip(bx,btxt,bcol):
arr(ax,4.5,8.12,x,7.65,col=c)
rbox(ax,x,7.2,1.55,0.82,t,c,ec=c,fs=7.5,tc='white')
arr(ax,4.5,6.79,4.5,6.35)
rbox(ax,4.5,6.05,7.5,0.55,
'SOURCE CONTROL – Debridement / drainage of focus as soon as medically feasible',
'#37474f',ec='#263238',fs=9,tc='white')
arr(ax,4.5,5.77,4.5,5.32)
rbox(ax,4.5,5.05,7.5,0.5,'MONITORING ADEQUACY OF RESUSCITATION',
'#006064',ec='#004d40',fs=10,tc='white')
mon=[('MAP\n≥65 mmHg\nHR<100/min','#e0f7fa'),
('Urine output\n≥0.5 mL/kg/hr\n(aim >35 mL/hr)','#e0f7fa'),
('Lactate clearance\n≥10% per 2 hrs\nTarget <2 mmol/L','#e0f7fa'),
('ScvO2 ≥70%\nPOCUS / ECHO\nBedside','#e0f7fa')]
mx=[1.2,3.4,5.6,7.8]
for x,( t,fc) in zip(mx,mon):
arr(ax,4.5,4.8,x,4.35,col='#006064')
rbox(ax,x,3.95,1.9,0.72,t,fc,ec='#006064',fs=7.5,tc='#004d40')
arr(ax,4.5,3.59,4.5,3.1)
rbox(ax,4.5,2.8,7.5,0.55,
'REFRACTORY SHOCK: Add Vasopressin 0.03 U/min IV + Hydrocortisone 200 mg/day',
'#4e342e',ec='#3e2723',fs=9,tc='white')
arr(ax,4.5,2.52,4.5,2.07)
rbox(ax,4.5,1.8,7.5,0.5,'ICU ADMISSION + Organ Support + Definitive Source Control',
'#263238',ec='#000',fs=9,tc='white')
ax.text(4.5,0.2,'Bailey & Love\'s Short Practice of Surgery 28e – Chapter 2 | Surviving Sepsis Campaign 2021',
ha='center',fontsize=7,color='#888',style='italic')
save(fig,'d1_septic.png')
# ══════════════════════════════════════════════════════════════
# DIAGRAM 2 Wound Healing Phases
# ══════════════════════════════════════════════════════════════
def make_d2():
fig,ax = plt.subplots(figsize=(11,8))
ax.set_xlim(0,11); ax.set_ylim(0,8); ax.axis('off')
fig.patch.set_facecolor('#fafafa'); ax.set_facecolor('#fafafa')
ax.text(5.5,7.75,'WOUND HEALING – Phases & Mediators',ha='center',
fontsize=12,fontweight='bold',color='#1a237e')
ax.text(5.5,7.45,'Bailey & Love Ch. 3 | Sabiston Ch. 23',ha='center',
fontsize=8,color='#666',style='italic')
# Timeline bar
bar_y=6.85
ax.barh(bar_y,10,left=0.5,height=0.38,color='#e0e0e0',edgecolor='#bbb',zorder=2)
phases_bar=[
(0.5,0.4,'#ef9a9a','HAEMOSTASIS'),
(0.5,3.2,'#ffcc80','INFLAMMATION'),
(3.5,4.0,'#a5d6a7','PROLIFERATION'),
(7.5,3.0,'#90caf9','REMODELLING'),
]
for start,width,col,lbl in phases_bar:
ax.barh(bar_y,width,left=start,height=0.38,color=col,
edgecolor='#888',alpha=0.9,zorder=3)
ax.text(start+width/2,bar_y,lbl,ha='center',va='center',
fontsize=7.5,fontweight='bold',color='#333',zorder=4)
# Time labels
for xv,lbl in [(0.5,'0'),(0.9,'1d'),(1.7,'3d'),(3.5,'5d'),(7.5,'3wk'),(10.5,'2yr')]:
ax.text(xv,6.55,lbl,ha='center',fontsize=7,color='#555')
# 4 detail boxes
box_specs=[
(1.1, 4.9, 1.9, 2.0, '#ffebee','#c62828',
'HAEMOSTASIS',
['Vascular injury','Vasoconstriction','Platelet plug','Fibrin clot scaffold',
'Growth factors released:','TGF-b, PDGF, VEGF', 'EGF, FGF (platelets)']),
(3.4, 4.9, 2.5, 2.0, '#fff3e0','#e65100',
'INFLAMMATION (Day 0-4)',
['Neutrophils (Day 0-3):',' Kill bacteria (ROS)',' IL-8, proteases',
'Macrophages (Day 2+):',' IL-1, IL-6, TNF-a',' PDGF, TGF-b, VEGF',' MMPs (matrix debride)',
'Rubor Tumor Calor Dolor']),
(6.4, 4.9, 2.5, 2.0, '#e8f5e9','#2e7d32',
'PROLIFERATION (Day 4-21)',
['Fibroblasts: Collagen III','Granulation tissue forms','Angiogenesis: VEGF, FGF',
'Keratinocytes: re-epithel.',' (EGF, KGF)','Myofibroblasts: contraction',' (TGF-b)']),
(9.3, 4.9, 1.9, 2.0, '#e3f2fd','#1565c0',
'REMODELLING (3wk-2yr)',
['Collagen III->Collagen I','Lysyl oxidase crosslinks','Tensile strength->80%',
'MMPs vs TIMPs balance','Scar: Red->White','Raised->Flat']),
]
for cx,cy,bw,bh,fc,hc,title,items in box_specs:
rect=FancyBboxPatch((cx-bw/2,cy-bh/2),bw,bh,
boxstyle='round,pad=0.05',facecolor=fc,edgecolor=hc,lw=1.5,zorder=3)
ax.add_patch(rect)
# header band
hrect=FancyBboxPatch((cx-bw/2,cy+bh/2-0.28),bw,0.28,
boxstyle='round,pad=0',facecolor=hc,edgecolor=hc,zorder=4)
ax.add_patch(hrect)
ax.text(cx,cy+bh/2-0.14,title,ha='center',va='center',
fontsize=7,fontweight='bold',color='white',zorder=5)
ys=cy+bh/2-0.38
for item in items:
ax.text(cx-bw/2+0.08,ys,item,ha='left',va='top',fontsize=6.5,color='#222',zorder=4)
ys-=0.2
# Arrows from timeline to boxes
for cx in [1.1,3.4,6.4,9.3]:
arr(ax,cx,6.66,cx,5.9+0.02)
ax.text(5.5,0.15,
'Bailey & Love\'s Short Practice of Surgery 28e, Chapter 3 (Normal Wound Healing in Skin)',
ha='center',fontsize=6.5,color='#888',style='italic')
save(fig,'d2_wound.png')
# ══════════════════════════════════════════════════════════════
# DIAGRAM 3 Cervical Lymph Node Levels
# ══════════════════════════════════════════════════════════════
def make_d3():
fig,ax=plt.subplots(figsize=(10,6.5))
ax.set_xlim(0,10);ax.set_ylim(0,6.5);ax.axis('off')
fig.patch.set_facecolor('#f5f5f5');ax.set_facecolor('#f5f5f5')
ax.text(5,6.3,'CERVICAL LYMPH NODE LEVELS – Robbins Classification',ha='center',
fontsize=11,fontweight='bold',color='#1a237e')
ax.text(5,6.0,'(Memorial Sloan Kettering) | Bailey & Love Ch. 6',ha='center',
fontsize=8,color='#666',style='italic')
# Simple head/neck silhouette
head=Ellipse((5,3.9),2.0,2.6,facecolor='#ffe0b2',edgecolor='#e65100',lw=1.5,zorder=1)
ax.add_patch(head)
neck=plt.Polygon([[4.2,2.6],[5.8,2.6],[5.9,1.2],[4.1,1.2]],
closed=True,facecolor='#ffcc80',edgecolor='#e65100',lw=1.2,zorder=1)
ax.add_patch(neck)
ax.text(5,4.5,'HEAD',ha='center',fontsize=9,fontweight='bold',color='#5d4037',zorder=2)
ax.text(5,1.9,'NECK',ha='center',fontsize=9,fontweight='bold',color='#5d4037',zorder=2)
# Left levels
left_levels=[
(1.3,5.1,'Level I\nIA Submental\nIB Submandibular','#ef9a9a','#c62828'),
(1.3,3.9,'Level II\nUpper Jugular\nJugulodigastric','#ffcc80','#e65100'),
(1.3,2.9,'Level III\nMiddle Jugular\nHyoid to Cricoid','#a5d6a7','#2e7d32'),
(1.3,1.9,'Level IV\nLower Jugular\nCricoid to Clavicle','#90caf9','#1565c0'),
]
for x,y,txt,fc,ec in left_levels:
rbox(ax,x,y,2.2,0.65,txt,fc,ec=ec,fs=7.5,tc='#222')
ax.annotate('',xy=(3.8,y),xytext=(2.4,y),
arrowprops=dict(arrowstyle='->',color=ec,lw=1.2))
# Right levels
right_levels=[
(8.7,4.5,'Level V\nPosterior Triangle\n(SAN region)','#ce93d8','#6a1b9a'),
(8.7,3.4,'Level VI\nCentral Compartment\nPretracheal/Paratracheal','#80deea','#006064'),
(8.7,2.3,'Level VII\nSuperior Mediastinum\nBelow sternal notch','#bcaaa4','#4e342e'),
]
for x,y,txt,fc,ec in right_levels:
rbox(ax,x,y,2.2,0.65,txt,fc,ec=ec,fs=7.5,tc='#222')
ax.annotate('',xy=(6.2,y),xytext=(7.6,y),
arrowprops=dict(arrowstyle='->',color=ec,lw=1.2))
ax.text(5,0.25,
'I: Lip/Floor mouth | II: Oral/Nasopharynx | III: Oropharynx '
'| IV: Thyroid/Larynx | V: Nasopharynx/Posterior | VI: Thyroid/Trachea',
ha='center',fontsize=6.8,color='#444',style='italic',
bbox=dict(boxstyle='round,pad=0.3',fc='white',ec='#bbb'))
save(fig,'d3_nodes.png')
# ══════════════════════════════════════════════════════════════
# DIAGRAM 4 Lethal Triad + DCR
# ══════════════════════════════════════════════════════════════
def make_d4():
fig,axes=plt.subplots(1,2,figsize=(13,7))
fig.patch.set_facecolor('#fafafa')
# LEFT – Lethal Triad
ax=axes[0]
ax.set_xlim(0,6);ax.set_ylim(0,7);ax.axis('off');ax.set_facecolor('#fafafa')
ax.text(3,6.75,'TRAUMA LETHAL TRIAD',ha='center',fontsize=12,fontweight='bold',color='#b71c1c')
ax.text(3,6.45,'(Triad of Death)',ha='center',fontsize=9,color='#555',style='italic')
tri=np.array([[3,5.6],[0.7,1.5],[5.3,1.5]])
triangle=plt.Polygon(tri,fill=False,edgecolor='#b71c1c',lw=2,linestyle='--',zorder=1)
ax.add_patch(triangle)
rbox(ax,3,5.85,2.4,0.65,'HYPOTHERMIA\n< 35 deg C','#1565c0',ec='#0d47a1',fs=9.5,tc='white')
rbox(ax,0.7,1.2,2.2,0.65,'ACIDOSIS\npH < 7.35','#e65100',ec='#bf360c',fs=9.5,tc='white')
rbox(ax,5.3,1.2,2.2,0.65,'COAGULOPATHY\nINR > 1.5','#2e7d32',ec='#1b5e20',fs=9.5,tc='white')
rbox(ax,3,3.5,1.9,0.6,'DEATH\nif uncorrected','#b71c1c',ec='#7f0000',fs=9,tc='white')
ax.annotate('',xy=(1.6,2.0),xytext=(2.2,5.5),
arrowprops=dict(arrowstyle='->',color='#666',lw=1.3))
ax.text(1.35,3.85,'Impairs\ncoag enzymes',ha='center',fontsize=7,color='#1565c0')
ax.annotate('',xy=(4.4,2.0),xytext=(3.8,5.5),
arrowprops=dict(arrowstyle='->',color='#666',lw=1.3))
ax.text(4.65,3.85,'Lactic\nacid',ha='center',fontsize=7,color='#e65100')
ax.annotate('',xy=(4.3,1.5),xytext=(1.7,1.5),
arrowprops=dict(arrowstyle='->',color='#666',lw=1.3))
ax.text(3,1.1,'Dilution + consumption of clotting factors',ha='center',fontsize=7,color='#2e7d32')
ax.text(3,0.35,
'Correct with: Warming + 1:1:1 blood products + TXA',
ha='center',fontsize=8,color='#333',
bbox=dict(boxstyle='round,pad=0.3',fc='#fff3e0',ec='#e65100'))
# RIGHT – DCR flowchart
ax=axes[1]
ax.set_xlim(0,7);ax.set_ylim(0,7);ax.axis('off');ax.set_facecolor('#fafafa')
ax.text(3.5,6.75,'DAMAGE CONTROL RESUSCITATION (DCR)',ha='center',
fontsize=11,fontweight='bold',color='#1a237e')
steps=[
('POLYTRAUMA + HAEMORRHAGIC SHOCK','#b71c1c',6.15),
('PERMISSIVE HYPOTENSION\nTarget SBP 80-90 mmHg until haemostasis\n(EXCEPT TBI: MAP >= 80)','#1565c0',5.2),
('HAEMOSTATIC RESUSCITATION\n1:1:1 pRBC : FFP : Platelets\nEarly Tranexamic Acid (within 3 hrs)\nAVOID excess crystalloids','#2e7d32',4.1),
('DAMAGE CONTROL SURGERY\nAbbreviated laparotomy (pack + clamp)\nPelvic binder, splint femur\nTemporary closure','#4a148c',3.0),
('ICU RESUSCITATION\nRewarm, correct acidosis & coagulopathy\nDefinitive organ assessment','#006064',1.95),
('DEFINITIVE SURGERY\n(After physiological stabilisation)','#37474f',1.05),
]
prev_y=None
for txt,col,y in steps:
rbox(ax,3.5,y,6.5,0.65,txt,col,ec=col,fs=8,tc='white')
if prev_y is not None:
arr(ax,3.5,prev_y-0.325,3.5,y+0.325,col='#777')
prev_y=y
plt.tight_layout(pad=1.5)
save(fig,'d4_lethal_dcr.png')
# ══════════════════════════════════════════════════════════════
# DIAGRAM 5 Virchow's Triad + Six P's
# ══════════════════════════════════════════════════════════════
def make_d5():
fig,axes=plt.subplots(1,2,figsize=(13,6.5))
fig.patch.set_facecolor('#fafafa')
# LEFT – Virchow's Triad
ax=axes[0]
ax.set_xlim(0,6);ax.set_ylim(0,7);ax.axis('off');ax.set_facecolor('#fafafa')
ax.text(3,6.75,"VIRCHOW'S TRIAD – DVT Pathogenesis",ha='center',
fontsize=11,fontweight='bold',color='#1a237e')
cpos=[(1.5,3.8),(4.5,3.8),(3.0,1.8)]
cfill=['#bbdefb','#ffe0b2','#c8e6c9']
clbl=['Endothelial\nInjury','Hypercoagu-\nlability','Stasis']
cec=['#1565c0','#e65100','#2e7d32']
for (cx,cy),fc,lbl,ec in zip(cpos,cfill,clbl,cec):
c=Circle((cx,cy),1.25,facecolor=fc,edgecolor=ec,lw=2,alpha=0.85,zorder=2)
ax.add_patch(c)
ax.text(cx,cy,lbl,ha='center',va='center',fontsize=10,fontweight='bold',
color=ec,zorder=3,multialignment='center')
rbox(ax,3,2.95,1.6,0.52,'DVT','#b71c1c',ec='#7f0000',fs=12,tc='white')
eg=[
(0.25,5.4,'Surgery, trauma\nIV catheters\nVaricose veins','#1565c0'),
(5.0,5.4,'Factor V Leiden\nMalignancy, OCP\nProtein C/S deficiency','#e65100'),
(3.0,0.45,'Immobility (bed rest, long flights)\nHeart failure, obesity, paralysis','#2e7d32'),
]
for x,y,txt,col in eg:
ax.text(x,y,txt,ha='center',fontsize=7.5,color=col,
bbox=dict(boxstyle='round,pad=0.25',fc='white',ec=col,lw=0.8))
# RIGHT – Six P's
ax=axes[1]
ax.set_xlim(0,7);ax.set_ylim(0,7);ax.axis('off');ax.set_facecolor('#fafafa')
ax.text(3.5,6.75,"SIX P's – Acute Limb Ischaemia",ha='center',
fontsize=11,fontweight='bold',color='#b71c1c')
ax.text(3.5,6.45,'(Rutherford Classification)',ha='center',
fontsize=8,color='#666',style='italic')
rows=[
('Pain', 'Sudden severe distal pain; may decrease as nerves die', '#ef9a9a','#c62828'),
('Pallor', 'Pale/white limb; mottling = fixed staining = irreversible', '#fff9c4','#f57f17'),
('Pulselessness', 'Absent pulses distal to occlusion; confirms vascular block','#ffe0b2','#e65100'),
('Paraesthesia', 'Pins & needles then numbness (sensory ischaemia - EARLY)', '#c8e6c9','#2e7d32'),
('Paralysis', 'Motor loss = ADVANCED ischaemia - near-irreversible (!)', '#b3e5fc','#0277bd'),
('Perishing cold','Absent warm arterial flow; temperature demarcates level', '#e1bee7','#6a1b9a'),
]
y=5.9
for p,desc,fc,ec in rows:
rbox(ax,0.9,y,1.5,0.47,p,fc,ec=ec,fs=9,tc=ec)
# wrap description text
ax.text(1.75,y,desc,ha='left',va='center',fontsize=8,color='#333',
wrap=True)
y-=0.77
ax.text(3.5,0.8,
'I=Viable(urgent) IIa=Threatened marginal(emergency)\n'
'IIb=Threatened immediate(IMMEDIATE surgery) III=Irreversible(amputation)',
ha='center',fontsize=7.5,color='#444',
bbox=dict(boxstyle='round,pad=0.3',fc='#fff3e0',ec='#e65100'))
plt.tight_layout(pad=1.5)
save(fig,'d5_virchow_6p.png')
# ══════════════════════════════════════════════════════════════
# DIAGRAM 6 TB Lymphadenitis Stages
# ══════════════════════════════════════════════════════════════
def make_d6():
fig,ax=plt.subplots(figsize=(12,4.5))
ax.set_xlim(0,12);ax.set_ylim(0,4.5);ax.axis('off')
fig.patch.set_facecolor('#e8f5e9');ax.set_facecolor('#e8f5e9')
ax.text(6,4.3,'TB CERVICAL LYMPHADENITIS – Beedham & Hudson Staging',
ha='center',fontsize=11,fontweight='bold',color='#1b5e20')
stages=[
(1.1, 'Stage I\nLymphadenitis','Firm, discrete\nmobile nodes\nNo necrosis','#fff9c4','#f9a825'),
(3.3, 'Stage II\nPeriadenitis','Nodes MATTED\nCapsular inflam.\nStill firm','#ffe0b2','#e65100'),
(5.5, 'Stage III\nCaseous Softening','CASEATION\nFluctuant node\nCold abscess\ndeep to fascia','#ffccbc','#bf360c'),
(7.7, 'Stage IV\nCollar-Stud Abscess','Bursts deep fascia\nBilocular abscess\nCross-fluctuation','#ce93d8','#6a1b9a'),
(9.9, 'Stage V\nSinus/Ulceration','Ruptures skin\nDischarging sinus\nUndermined edges\nWatery pus','#b0bec5','#37474f'),
]
for i,(cx,title,detail,fc,ec) in enumerate(stages):
rbox(ax,cx,3.4,2.0,0.72,title,ec,ec=ec,fs=8.5,tc='white')
rbox(ax,cx,1.9,2.0,1.4,detail,fc,ec=ec,fs=8)
arr(ax,cx,3.04,cx,2.62,col=ec)
if i<len(stages)-1:
arr(ax,cx+1.0,3.4,stages[i+1][0]-1.0,3.4,col=ec)
ax.text(5.5,3.87,'<-- THIS CASE = STAGE III to IV -->',ha='center',
fontsize=8.5,color='#b71c1c',fontweight='bold')
ax.text(6,0.25,
'Treatment: ATT (HRZE x 2 months -> HR x 4 months) | Aspiration if fluctuant',
ha='center',fontsize=8,color='#1b5e20',fontweight='bold',
bbox=dict(boxstyle='round,pad=0.3',fc='white',ec='#2e7d32'))
save(fig,'d6_tb_stages.png')
# ══════════════════════════════════════════════════════════════
# DIAGRAM 7 TNBC Paradox + BCS Contraindications
# ══════════════════════════════════════════════════════════════
def make_d7():
fig,axes=plt.subplots(1,2,figsize=(13,7))
fig.patch.set_facecolor('#fafafa')
# LEFT – TNBC
ax=axes[0]
ax.set_xlim(0,7);ax.set_ylim(0,7);ax.axis('off');ax.set_facecolor('#fafafa')
ax.text(3.5,6.8,'TNBC PARADOX',ha='center',fontsize=13,fontweight='bold',color='#4a148c')
rbox(ax,3.5,6.15,6.2,0.6,'TNBC: ER(-) PR(-) HER2(-)\n~10-15% of all breast cancers',
'#4a148c',tc='white',fs=9)
arr(ax,3.5,5.85,3.5,5.4)
rbox(ax,3.5,5.1,6.2,0.55,'Neoadjuvant Chemo (NACT)\nAnthracycline + Taxane (AC-T)',
'#1565c0',tc='white',fs=9)
arr(ax,3.5,4.82,1.8,4.4,col='#2e7d32')
arr(ax,3.5,4.82,5.2,4.4,col='#c62828')
rbox(ax,1.8,4.1,2.8,0.58,'pCR Achieved\n~30-40%','#2e7d32',tc='white',fs=9)
rbox(ax,5.2,4.1,2.8,0.58,'Residual Disease\n~60-70%','#c62828',tc='white',fs=9)
ax.text(1.8,3.6,'Good short-term response',ha='center',fontsize=7.5,color='#2e7d32')
ax.text(5.2,3.5,'Very POOR prognosis\n("All or Nothing")',ha='center',
fontsize=8,color='#c62828',fontweight='bold')
rbox(ax,3.5,2.9,6.2,0.6,
'THE PARADOX: High chemo-sensitivity\nYET overall WORSE outcome than ER+/HER2+ disease',
'#880e4f',tc='white',fs=8.5)
arr(ax,3.5,2.6,3.5,2.2)
rbox(ax,3.5,1.7,6.2,0.8,
'Residual disease: Capecitabine (CREATE-X)\nPD-L1+: Pembrolizumab (KEYNOTE-522)\nBRCA mut: Olaparib | Metastatic: Sacituzumab',
'#37474f',tc='white',fs=8)
# RIGHT – BCS Contraindications
ax=axes[1]
ax.set_xlim(0,7);ax.set_ylim(0,7);ax.axis('off');ax.set_facecolor('#fafafa')
ax.text(3.5,6.8,'BCS CONTRAINDICATIONS',ha='center',fontsize=13,fontweight='bold',color='#b71c1c')
rbox(ax,3.5,6.2,6.4,0.52,'ABSOLUTE CONTRAINDICATIONS','#b71c1c',tc='white',fs=10)
abs_list=[
'Diffuse malignant / indeterminate microcalcifications',
'Multi-centricity (tumour in 2+ quadrants)',
'Inflammatory breast cancer',
'Prior breast irradiation (cannot re-irradiate)',
'Positive margins despite repeated re-excision',
'Large tumour: unfavourable tumour-to-breast ratio',
]
y=5.75
for item in abs_list:
ax.text(0.3,y,f'X {item}',ha='left',va='top',fontsize=8.5,color='#c62828')
y-=0.46
rbox(ax,3.5,2.8,6.4,0.52,'RELATIVE CONTRAINDICATIONS','#e65100',tc='white',fs=10)
rel_list=[
'Active collagen vascular disease (scleroderma, SLE)',
'BRCA1/2 mutation (prefer mastectomy - higher recurrence risk)',
'Large tumour T3 >5 cm (NACT first to downstage)',
'Pregnancy 1st/2nd trimester (RT deferred)',
'Patient preference for mastectomy',
]
y=2.35
for item in rel_list:
ax.text(0.3,y,f'~ {item}',ha='left',va='top',fontsize=8.5,color='#e65100')
y-=0.45
plt.tight_layout(pad=1.5)
save(fig,'d7_tnbc_bcs.png')
# ══════════════════════════════════════════════════════════════
# RUN ALL DIAGRAMS
# ══════════════════════════════════════════════════════════════
print("Generating diagrams...")
make_d1(); print(" d1 done")
make_d2(); print(" d2 done")
make_d3(); print(" d3 done")
make_d4(); print(" d4 done")
make_d5(); print(" d5 done")
make_d6(); print(" d6 done")
make_d7(); print(" d7 done")
print("All diagrams done.\n")
# ══════════════════════════════════════════════════════════════
# REPORTLAB PDF
# ══════════════════════════════════════════════════════════════
doc = SimpleDocTemplate(OUT, pagesize=A4,
rightMargin=1.8*cm, leftMargin=1.8*cm,
topMargin=1.8*cm, bottomMargin=1.8*cm)
S = getSampleStyleSheet()
def ps(name, parent='Normal', **kw):
return ParagraphStyle(name, parent=S[parent], **kw)
TITLE = ps('T', 'Title', fontSize=16, textColor=colors.HexColor('#1a237e'),
spaceAfter=4, alignment=TA_CENTER)
SUB = ps('S', 'Normal', fontSize=10, textColor=colors.HexColor('#37474f'),
spaceAfter=8, alignment=TA_CENTER)
PART = ps('P', 'Normal', fontSize=13, textColor=colors.white,
backColor=colors.HexColor('#1a237e'), spaceBefore=10, spaceAfter=6,
borderPad=5, fontName='Helvetica-Bold', leading=18)
QH = ps('Q', 'Heading2',fontSize=11, textColor=colors.HexColor('#1a237e'),
spaceBefore=10, spaceAfter=4)
SQH = ps('SQ', 'Normal', fontSize=10, textColor=colors.HexColor('#b71c1c'),
spaceBefore=6, spaceAfter=2, fontName='Helvetica-Bold')
BODY = ps('B', 'Normal', fontSize=9.5, leading=14, spaceAfter=3,
alignment=TA_JUSTIFY)
BUL = ps('BL', 'Normal', fontSize=9, leading=13, spaceAfter=1,
leftIndent=14, bulletIndent=4)
H3 = ps('H3', 'Heading3',fontSize=9.5,textColor=colors.HexColor('#2e7d32'),
spaceBefore=5, spaceAfter=2)
NOTE = ps('N', 'Normal', fontSize=8.5, leading=12, spaceAfter=4,
leftIndent=10, rightIndent=10,
backColor=colors.HexColor('#e8f5e9'), borderPad=4,
fontName='Helvetica-Oblique')
def hr():
return HRFlowable(width='100%', thickness=0.5,
color=colors.HexColor('#90a4ae'), spaceAfter=4, spaceBefore=4)
def sp(h=4): return Spacer(1, h)
def b(t): return Paragraph(f'• {t}', BUL)
def h3(t): return Paragraph(t, H3)
def ans(t): return Paragraph(t, BODY)
def sq(t): return Paragraph(t, SQH)
def note(t): return Paragraph(t, NOTE)
def qh(t): return Paragraph(t, QH)
def img(fname, width=PW):
path = f'{DIAG}/{fname}'
if not os.path.exists(path):
return Spacer(1, 4)
return Image(path, width=width, height=None) # height auto-scales
# ── Compact table helper ──────────────────────────────────────
def tbl(data, cw, hdr_col='#1a237e', row_cols=None):
"""data: list of lists. cw: list of column widths in cm (floats)."""
col_widths = [x*cm for x in cw]
if row_cols is None:
row_cols = [colors.HexColor('#e8eaf6'), colors.white]
t = Table(data, colWidths=col_widths, repeatRows=1)
n = len(data)
style = [
('BACKGROUND', (0,0), (-1,0), colors.HexColor(hdr_col)),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8.5),
('LEADING', (0,0), (-1,-1), 12),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#9e9e9e')),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING',(0,0),(-1,-1), 3),
('LEFTPADDING', (0,0), (-1,-1), 4),
('RIGHTPADDING',(0,0), (-1,-1), 4),
('WORDWRAP', (0,0), (-1,-1), True),
]
for i in range(1, n):
style.append(('BACKGROUND', (0,i), (-1,i),
row_cols[(i-1) % len(row_cols)]))
t.setStyle(TableStyle(style))
return t
# ══════════════════════════════════════════════════════════════
# BUILD STORY
# ══════════════════════════════════════════════════════════════
story = []
# ─── COVER ────────────────────────────────────────────────────
story += [sp(20), Paragraph('MBBS PROFESSIONAL EXAMINATION', TITLE),
Paragraph('Surgery – Model Answers', SUB),
Paragraph('Parts B & C | Based on Standard Surgical Textbooks', SUB),
hr(), sp(6)]
# ═══════════════ PART B ═══════════════════════════════════════
story += [Paragraph('PART B – 25 Marks', PART)]
# ── Q21 Septic Shock ──────────────────────────────────────────
story += [qh('Q21 (15 Marks) – Septic Shock: 62-year-old diabetic')]
story += [sq('(a) Most Likely Diagnosis & Elaboration [1+2 Marks]'),
ans('<b>Diagnosis: Septic Shock</b> (secondary to diabetic foot infection)')]
story.append(tbl(
[['Parameter','Finding','Significance'],
['Temperature','39.5 °C','Fever – SIRS criterion'],
['Pulse','124/min (thready)','Tachycardia – SIRS + poor cardiac output'],
['BP','80/50 mmHg','Hypotension – shock'],
['RR','30/min','Tachypnoea – SIRS + early respiratory failure'],
['SpO2','88% on room air','Hypoxia – impending respiratory failure / early ARDS'],
['CRT','> 5 seconds','Severe peripheral hypoperfusion'],
['Urine output','10 mL/hr','Oliguria – renal hypoperfusion (target ≥0.5 mL/kg/hr)'],
['Lactate','5.2 mmol/L','Lactic acidosis – anaerobic metabolism / tissue hypoperfusion'],
['Mental status','Altered sensorium','Cerebral hypoperfusion – organ dysfunction'],
['Source','Foot wound × 5 days','Focus of infection – polymicrobial diabetic foot']],
[3.2, 4.0, 8.5]))
story += [sp(4),
ans('<b>qSOFA ≥ 2</b> (altered mentation + RR ≥22 + SBP ≤100) confirms sepsis. '
'Persisting hypotension despite fluids + vasopressor requirement = '
'<b>septic shock</b> (Sepsis-3 definition). Lactate >2 mmol/L confirms tissue '
'hypoperfusion. Underlying focus: <b>diabetic foot</b> – polymicrobial '
'(Gram-positives, Gram-negatives, anaerobes).')]
story += [sq('(b) Immediate Management – First Hour / Golden Hour [5 Marks]'),
img('d1_septic.png'),
note('SSC 2021 – 1-Hour Bundle: Cultures → Antibiotics → 30 mL/kg fluid → '
'Lactate → Vasopressors if MAP <65 mmHg')]
story += [sq('(c) Fluid & Vasopressin Choice in Septic Shock [3 Marks]'),
h3('Fluid Choice'),
ans('<b>Crystalloids first-line</b> (SSC 2021, Grade 1A). Balanced crystalloids '
'(Ringer\'s Lactate / Plasmalyte) preferred over 0.9% saline to avoid '
'hyperchloraemic acidosis. Albumin 4–5% as adjunct after large volumes. '
'<b>Starches (HES) are CONTRAINDICATED</b> in sepsis (↑ mortality, AKI – VISEP/6S trials).'),
h3('Vasopressor Choice & Vasopressin'),
ans('<b>Norepinephrine (Noradrenaline) – First-line vasopressor</b> (SSC Grade 1B). '
'Alpha-1 dominant → ↑SVR → ↑MAP. Target MAP ≥65 mmHg.'),
b('<b>Vasopressin</b> (0.03–0.04 units/min IV) – add-on when norepinephrine dose is escalating. '
'Mechanism: V1 receptor → direct smooth muscle constriction (adrenergic-independent). '
'V2 receptor → water retention. Septic shock = relative vasopressin deficiency. '
'Does not increase cardiac output; spares norepinephrine dose.'),
b('<b>Epinephrine</b> – second-line if MAP target not achieved'),
b('<b>Dobutamine</b> – if myocardial depression / low cardiac output'),
b('<b>Hydrocortisone 200 mg/day IV</b> – refractory shock despite adequate fluids + vasopressors'),
b('<b>Dopamine</b> – no longer recommended (↑ arrhythmia vs noradrenaline)')]
story += [sq('(d) Monitoring Adequacy of Resuscitation [2 Marks]'),
tbl(
[['Endpoint','Target / Method'],
['MAP','≥65 mmHg continuously'],
['Urine output','≥0.5 mL/kg/hr (this patient needs ≥35 mL/hr)'],
['Lactate clearance','≥10% reduction every 2 hours; target <2 mmol/L'],
['ScvO2','Central venous O2 ≥70% (mixed venous SvO2 ≥65%)'],
['Pulse pressure variation','<13% predicts fluid responsiveness (mechanically ventilated)'],
['POCUS / Bedside ECHO','IVC collapsibility, cardiac function, fluid responsiveness'],
['ABG','Improving pH, normalising base excess, falling lactate'],
['CVP','8–12 mmHg (not standalone – use with other parameters)']],
[4.0, 11.7], hdr_col='#2e7d32',
row_cols=[colors.HexColor('#e8f5e9'), colors.white])]
story += [sq('(e) Complications & Prognosis [2 Marks]'),
h3('Complications'),
b('ARDS – already suggested: SpO2 88%, bilateral crepitations, PaO2/FiO2 <300'),
b('Acute Kidney Injury (AKI) – oliguria present; may progress to require dialysis'),
b('Disseminated Intravascular Coagulation (DIC) – coagulation failure from endotoxaemia'),
b('Septic cardiomyopathy – myocardial depression from inflammatory mediators'),
b('Multi-Organ Dysfunction Syndrome (MODS) – brain, liver, renal, haematological'),
b('Diabetic foot amputation – osteomyelitis may necessitate below-knee amputation'),
h3('Prognosis'),
ans('<b>Mortality in septic shock: 30–50%.</b> Adverse factors in this patient: '
'lactate ≥5.2 mmol/L (>4 = high mortality), MODS (renal + neuro + respiratory), '
'diabetes + hypertension (immunocompromised host), delayed presentation (5 days). '
'Counsel patient & family: <b>critical illness with guarded prognosis.</b>')]
story.append(hr())
# ── Q22 ──────────────────────────────────────────────────────
story += [qh('Q22 – Short Questions (5 × 2 = 10 Marks)'),
sq('Q1: TNBC Paradox & Contraindications to BCS'),
img('d7_tnbc_bcs.png'),
note('TNBC paradox: high pCR rate to NACT yet worse 5-year survival than ER+/HER2+ cancers. '
'"All or nothing" – residual disease after NACT carries very poor prognosis.')]
story += [sq('Q2: Mediators of Wound Healing & Phases'),
img('d2_wound.png'),
tbl(
[['Phase','Timing','Key Cells','Key Mediators'],
['Haemostasis','0 – minutes','Platelets, endothelium',
'TGF-β, PDGF, VEGF, EGF, FGF (platelet α-granules)\nFibrin scaffold formation'],
['Inflammation','Day 0–4',
'Neutrophils (0–3d)\nMacrophages (day 2+)',
'IL-1, IL-6, TNF-α (pro-inflammatory)\nPDGF, TGF-β, VEGF, bFGF (growth)\nMMPs, Leukotriene B4, PGE2'],
['Proliferation','Day 4–21',
'Fibroblasts\nKeratinocytes\nEndothelial cells',
'Collagen III synthesis (fibroblasts)\nVEGF, FGF (angiogenesis)\nEGF, KGF (re-epithelialisation)\nTGF-β → myofibroblast contraction'],
['Remodelling','3wk – 2yr',
'Fibroblasts\nMMPs / TIMPs',
'Collagen III → Collagen I (lysyl oxidase)\nTensile strength → 80% of original\nScar maturation: raised/red → flat/white']],
[2.3, 2.1, 3.0, 8.3], hdr_col='#4a148c',
row_cols=[colors.HexColor('#f3e5f5'), colors.white])]
story.append(PageBreak())
# ═══════════════ PART C ═══════════════════════════════════════
story += [Paragraph('PART C – 40 Marks', PART)]
# ── Q23 AETCOM ────────────────────────────────────────────────
story += [qh('Q23 (10 Marks) – AETCOM: Ethics in Surgical Consent'),
ans('<i>35-year-old female, conscious & oriented, needs emergency laparotomy. '
'Husband wants risks withheld.</i>'),
sq('(a) Ethical Principles Involved [3 Marks]'),
tbl(
[['Principle','Application in this Case'],
['Autonomy','Patient is conscious, oriented, legally competent. She has the RIGHT to make her '
'own decisions. No one (including spouse) can override her autonomy. Her question '
'"Doctor, is it serious?" shows she WANTS information.'],
['Beneficence','Act in the patient\'s best interest. Withholding information is NOT beneficence – '
'it prevents informed decision-making. Early surgery is clearly in her interest.'],
['Non-Maleficence','Withholding material risks causes harm by preventing valid consent. '
'Deception (even benevolent) violates this principle.'],
['Justice','Equal treatment regardless of gender or marital status. Her rights cannot be '
'subordinated to the husband\'s preferences.'],
['Veracity','Doctor has a duty of truthfulness. Omission of material risks breaches trust '
'and the therapeutic relationship.'],
['Confidentiality','Medical information belongs to the patient first. Husband should only '
'receive information the patient consents to share.']],
[3.8, 11.9], hdr_col='#bf360c',
row_cols=[colors.HexColor('#fbe9e7'), colors.white])]
story += [sq('(b) Communication with Patient & Husband [3 Marks]'),
h3('With the Patient:'),
b('Speak privately first (without husband).'),
b('Use empathetic, simple language: "Yes, this is serious. You have a perforation in your '
'abdomen that is life-threatening without surgery."'),
b('Explain: nature of condition, proposed operation, risks (stoma, wound infection, '
're-operation, death), benefits (life-saving), consequences of no treatment.'),
b('Assess understanding (teach-back method). Allow questions. Ensure consent is voluntary.'),
h3('With the Husband:'),
b('Acknowledge his concern and fear.'),
b('Explain: legally and ethically a competent adult must be fully informed – risks cannot be withheld.'),
b('Reassure: "Informing her will not make her refuse – she needs surgery to survive."'),
b('He may be present only if the patient consents. Document his objection in the medical record.'),
sq('(c) Essential Elements of Valid Informed Consent [4 Marks]'),
tbl(
[['Element','Requirement'],
['1. Disclosure','Diagnosis, proposed procedure, nature of operation, material risks & '
'benefits, alternatives, consequences of no treatment'],
['2. Comprehension','Patient must understand in a language/manner she can follow. Confirm '
'understanding; use interpreter if needed.'],
['3. Capacity','Patient must be mentally and legally competent (conscious, oriented, no '
'drugs/alcohol, not under coercion). – MET here.'],
['4. Voluntariness','Decision free from coercion, duress, or undue influence. Husband\'s '
'pressure does NOT invalidate her voluntary decision.'],
['5. Specificity','Consent must be specific to the procedure being performed.'],
['6. Documentation','Written form: patient signature, surgeon signature, witness, date/time, '
'content of discussion – all recorded.'],
['7. Right to withdraw','Patient can withdraw consent at any time before surgery without '
'penalty or prejudice to her ongoing care.']],
[3.5, 12.2], hdr_col='#1565c0',
row_cols=[colors.HexColor('#e3f2fd'), colors.white]),
note('Emergency exception: If patient were unconscious/incapacitated the surgeon may proceed '
'under necessity to preserve life – does NOT apply here as she is conscious and competent.')]
story.append(PageBreak())
# ── Q24.1 Cervical Lymphadenitis ──────────────────────────────
story += [qh('Q24.1 (10 Marks) – Cervical Lymphadenitis: 22-year-old male')]
story += [sq('(a) Stages of Tuberculous Cervical Lymphadenitis [6 Marks]'),
img('d6_tb_stages.png'),
tbl(
[['Stage','Name','Features'],
['I','Lymphadenitis\n(Reactive)',
'Firm, discrete, MOBILE enlarged nodes. Reactive hyperplasia. No necrosis. '
'Not matted. ESR/CRP elevated.'],
['II','Periadenitis',
'Nodes become MATTED (adherent to each other and surrounding tissue). '
'Capsular inflammation. Still firm. No fluctuation.'],
['III','Caseous Softening',
'Central necrosis/caseation. Node becomes FLUCTUANT. Still confined deep '
'to deep cervical fascia. Cold abscess beginning to form.'],
['IV','Collar-Stud Abscess',
'Caseous material bursts through deep fascia → bilocular abscess above and '
'below fascia connected by a narrow neck. Cross-fluctuation present. '
'"Collar-stud" shape on examination.'],
['V','Sinus / Ulceration',
'Collar-stud abscess ruptures through skin → chronic discharging SINUS. '
'Watery pus, undermined edges (TB bacilli destroy subcutaneous tissue). '
'Calcification may occur in healed lesions.']],
[1.3, 3.8, 10.6], hdr_col='#006064',
row_cols=[colors.HexColor('#e0f7fa'), colors.white]),
note('This patient = Stage III–IV: matted, fluctuant, overlying skin induration (collar-stud forming). '
'Investigations: FNAC/biopsy, IGRA/Mantoux, ESR, CRP, CXR. '
'Treatment: ATT (HRZE × 2 months → HR × 4 months) + aspiration if fluctuant.')]
story += [sq('(b) Cervical Lymph Node Levels – Nodal Stations [4 Marks]'),
img('d3_nodes.png'),
tbl(
[['Level','Sub-level','Location','Drains From'],
['I','IA – Submental\nIB – Submandibular',
'Below chin /\nUnder mandible',
'Lip, floor of mouth, anterior tongue, cheek, submandibular gland'],
['II','IIA – Anterior to SAN\nIIB – Posterior to SAN',
'Upper jugular\n(Jugulodigastric)\nSkull base → hyoid',
'Oral cavity, nasopharynx, oropharynx, parotid, hypopharynx, larynx'],
['III','–','Middle jugular\nHyoid → cricoid',
'Oral cavity, nasopharynx, oropharynx, hypopharynx, larynx'],
['IV','–','Lower jugular\nCricoid → clavicle',
'Hypopharynx, larynx, thyroid, oesophagus, trachea'],
['V','VA – Superior\nVB – Inferior',
'Posterior triangle\n(SAN + transverse\ncervical vessels)',
'Nasopharynx, oropharynx, posterior scalp and neck'],
['VI','–','Central compartment\n(pretracheal,\nparatracheal, Delphian)',
'Thyroid, subglottis, trachea, cervical oesophagus, pyriform fossa'],
['VII*','–','Superior mediastinum\n(below sternal notch)',
'Thyroid, oesophagus, trachea']],
[1.2, 3.2, 3.8, 7.5], hdr_col='#006064',
row_cols=[colors.HexColor('#e0f7fa'), colors.white]),
note('SAN = Spinal Accessory Nerve. *Level VII sometimes listed separately.')]
story.append(PageBreak())
# ── Q24.2 Polytrauma ──────────────────────────────────────────
story += [qh('Q24.2 (10 Marks) – Polytrauma: 28-year-old RTA victim')]
story += [sq('(A) Initial Assessment [4 Marks]'),
h3('1. Define Polytrauma'),
ans('Polytrauma = simultaneous presence of <b>two or more injuries, at least one '
'life-threatening</b>. Berlin Definition (2014): ISS ≥16 PLUS at least one of: '
'SBP ≤90 mmHg, GCS ≤8, base deficit ≤−6 mEq/L, lactate ≥2.5 mmol/L, or age ≥70 years.'),
h3('2. Primary Survey – ABCDE (ATLS)')]
story.append(tbl(
[['ABCDE','Findings in this Case','Immediate Action'],
['A – Airway\n(C-spine)','Talking incoherently, blood in oral cavity',
'Suction oropharynx, jaw thrust, C-spine immobilisation.\nAssume C-spine injury until cleared.'],
['B – Breathing','RR 32/min, SpO2 88%,\nDecreased air entry LEFT\nTrachea deviated RIGHT',
'TENSION PNEUMOTHORAX suspected:\nNeedle decompression 2nd ICS MCL LEFT\nChest drain, high-flow O2'],
['C – Circulation','BP 80/50, HR 132, cold clammy\nActive bleeding right thigh\nFAST+ free fluid',
'2x large-bore IV, blood samples\nActivate MTP, pRBC:FFP:PLT 1:1:1\nDirect pressure, pelvic binder'],
['D – Disability','GCS E3V4M5 = 12\nRestless, confused','Pupils assess, maintain MAP ≥80 for TBI\nAVOID hypotension'],
['E – Exposure','Open femur fracture, active bleeding\nMultiple abrasions, pelvic instability',
'Keep warm (prevent hypothermia)\nSplint femur, log roll, inspect back']],
[2.0, 4.5, 9.2], hdr_col='#263238',
row_cols=[colors.HexColor('#eceff1'), colors.white]))
story += [h3('3. Life-Threatening Injuries'),
b('Tension pneumothorax (left) – decreased air entry + tracheal deviation right'),
b('Haemoperitoneum – FAST+ in Morrison\'s pouch (splenic/hepatic/mesenteric injury)'),
b('Pelvic fracture with instability – major haemorrhage source'),
b('Open femur fracture mid-shaft – active external haemorrhage + fat embolism risk'),
b('Traumatic Brain Injury – GCS 12, potential intracranial haemorrhage'),
b('Haemorrhagic shock – Hb 7.8, lactate 5.2, BP 80/50, INR elevated'),
sq('(C) Circulation & Shock [4 Marks]'),
h3('1. Type of Shock'),
ans('<b>Class III–IV Haemorrhagic (Hypovolaemic) Shock.</b> Justification: HR 132/min, '
'BP 80/50, cold clammy extremities, CRT >3 sec, Hb 7.8 g/dL, lactate 5.2 mmol/L. '
'Shock Index (HR/SBP) = 132/80 = 1.65 (normal <0.9). '
'Multiple haemorrhage sources: femur + pelvis + abdomen. Estimated blood loss >1500 mL.'),
h3('2. Causes of Shock in Polytrauma'),
b('Haemorrhagic / hypovolaemic – most common (external + internal bleeding)'),
b('Obstructive – tension pneumothorax or cardiac tamponade'),
b('Neurogenic – spinal cord injury (bradycardia + hypotension)'),
b('Cardiogenic – myocardial contusion (blunt chest trauma)'),
b('Septic – late complication (not in the acute phase)')]
story += [h3('3. Damage Control Resuscitation (DCR)'),
img('d4_lethal_dcr.png'),
note('DCR = Permissive hypotension + Haemostatic resuscitation (1:1:1) + '
'Damage control surgery + ICU stabilisation + Definitive repair')]
story += [h3('4. Indications for Massive Transfusion Protocol (MTP)'),
b('Shock Index > 1.0 (this patient: 132/80 = 1.65)'),
b('ABC Score ≥2: HR >120 + SBP <90 + FAST+ + penetrating/blunt mechanism'),
b('Base deficit < −6 or lactate > 5 mmol/L (present)'),
b('Hb < 8 g/dL with ongoing haemorrhage (Hb 7.8 here)'),
b('INR > 1.5 or aPTT > 35 sec (INR elevated in this patient)'),
b('Estimated blood loss > 1.5 L in prehospital setting'),
sq('Short Notes [2 Marks]'),
h3('1. Trauma Lethal Triad (Triad of Death)')]
story += [img('d4_lethal_dcr.png', width=PW*0.55),
tbl(
[['Component','Cause in Trauma','Consequence'],
['Hypothermia\n(<35 °C)','Haemorrhage, cold IV fluids,\nexposure',
'Impairs coagulation enzyme function;\nmyocardial depression; ↑O2 demand'],
['Acidosis\n(pH <7.35)','Hypoperfusion → lactic acidosis',
'Impairs coagulation; myocardial\ndepression; vasodilation → more hypotension'],
['Coagulopathy\n(INR >1.5)','Dilution, hypothermia, acidosis,\nfactor consumption',
'Uncontrolled haemorrhage → more\nhypoperfusion → worsening triad']],
[2.8, 4.8, 8.1], hdr_col='#b71c1c',
row_cols=[colors.HexColor('#ffebee'), colors.white]),
note('Correct: Warm all fluids + 1:1:1 blood products → correct coagulopathy + '
'haemostasis → correct acidosis + rewarm → break the vicious cycle.')]
story += [h3('2. Secondary Survey in Trauma'),
ans('Performed AFTER primary survey and initial resuscitation. '
'Head-to-toe examination to identify ALL injuries:'),
b('Head: Scalp lacerations, skull fractures, facial fractures, eye injuries'),
b('Neck: Tracheal position, veins, C-spine tenderness (keep hard collar until cleared)'),
b('Chest: Rib fractures, haemothorax, aortic injury (widened mediastinum on CXR)'),
b('Abdomen: Log roll, rectal examination (DRE), urethrogram if blood at meatus'),
b('Pelvis: Stability, FAST repeat, consider pelvic angioembolisation'),
b('Extremities: Neurovascular examination, open fractures documentation'),
b('Neuro: Full GCS, cranial nerves, motor and sensory assessment'),
b('AMPLE history: Allergies, Medications, Past medical history, Last meal, Events/mechanism'),
b('Adjuncts: Pan-CT trauma scan, repeat vitals, reassess primary survey')]
story.append(PageBreak())
# ── Q25 Short One-line Answers ────────────────────────────────
story += [qh('Q25 (5 × 2 = 10 Marks) – Short One-line Answer Type')]
# Q25.1 PAD
story += [sq('1. Most Common Cause of Peripheral Arterial Disease & Clinical Manifestations'),
ans('<b>Atherosclerosis</b> is the most common cause of PAD (>95% of cases). '
'Risk factors: diabetes (most important for lower limb), smoking (strongest '
'modifiable), hypertension, dyslipidaemia, age >50.'),
tbl(
[['Fontaine Stage','Manifestation'],
['I – Asymptomatic','ABI <0.9 but no symptoms; detected on screening'],
['II – Claudication','Reproducible calf/thigh pain on walking, relieved by rest.\n'
'IIa: >200 m | IIb: <200 m'],
['III – Rest Pain','Burning foot pain at rest, worse at night, eased by hanging leg down'],
['IV – Tissue Loss','Gangrene, non-healing ulcers (toes/heels/pressure points)\n'
'= Critical Limb-Threatening Ischaemia (CLTI)']],
[2.5, 13.2], hdr_col='#37474f',
row_cols=[colors.HexColor('#eceff1'), colors.white]),
ans('Other features: absent pedal pulses, cold limb, pallor, atrophic skin, '
'hair loss, nail changes, positive Buerger\'s test.')]
# Q25.2 Virchow
story += [sq("2. Virchow's Triad & DVT"),
img('d5_virchow_6p.png'),
note("Virchow's Triad (1856): Endothelial Injury + Hypercoagulability + Stasis. "
"All three promote intravascular thrombus formation. In DVT: stasis in soleal "
"veins (immobility) + hypercoagulability (surgery/cancer) + endothelial injury "
"(trauma/catheter) → deep vein thrombus formation.")]
# Q25.3 AAA
story += [sq('3. Aortic Aneurysm – Definition & Risk Factors for Rupture'),
ans('<b>Definition:</b> Permanent, localised, pathological dilatation of the aorta '
'to <b>≥150% (1.5×) of its normal diameter.</b> Normal infrarenal aorta = 2 cm; '
'therefore AAA ≥3 cm. True aneurysm involves all 3 layers. '
'Commonest: infrarenal aorta (90%). Fusiform >> saccular.'),
tbl(
[['Risk Factor','Detail'],
['Aneurysm size','Strongest predictor. 5–6 cm = 3–15%/year; 6–7 cm = 10–20%/year; '
'>7 cm = >20%/year. Elective repair: ≥5.5 cm (men), ≥5 cm (women)'],
['Rate of expansion','>1 cm/year or >0.5 cm in 6 months = high rupture risk regardless of size'],
['Shape','Saccular > fusiform rupture risk; eccentric aneurysms higher risk'],
['Hypertension','Raised wall stress (Law of Laplace: T = P × r); increases risk'],
['Smoking','Active smoking – strongest independent modifiable risk factor (3× risk)'],
['COPD','Associated with rapid expansion; shared elastin degradation pathogenesis'],
['Female sex','Higher rupture risk at smaller diameters → lower threshold for repair'],
['Family history','First-degree relative with AAA → 4× risk']],
[3.8, 11.9], hdr_col='#880e4f',
row_cols=[colors.HexColor('#fce4ec'), colors.white])]
# Q25.4 CVI
story += [sq('4. Chronic Venous Insufficiency – Pathophysiology & Clinical Features'),
h3('Pathophysiology'),
b('Valvular incompetence (primary degeneration or post-DVT) → reflux → venous hypertension'),
b('Venous HTN → capillary hypertension → protein-rich oedema in interstitium'),
b('Leucocyte trapping in capillaries → inflammatory mediators → tissue damage'),
b('Fibrin cuff theory: pericapillary fibrin deposition → O2/nutrient barrier → skin ischaemia'),
b('Lipodermosclerosis: fibrosis of skin + fat → haemosiderin deposition'),
b('End result: venous ulceration in the gaiter zone (above medial malleolus)'),
tbl(
[['CEAP','Clinical Feature'],
['C0','No visible or palpable signs of venous disease'],
['C1','Telangiectasia (spider veins <1 mm) or reticular veins (1–3 mm)'],
['C2','Varicose veins >3 mm – tortuous, dilated superficial veins'],
['C3','Oedema – ankle/lower leg pitting, worsens with prolonged standing'],
['C4a','Pigmentation (haemosiderin) + venous eczema / stasis dermatitis'],
['C4b','Lipodermatosclerosis (LDS) + atrophie blanche (white sclerotic plaques)'],
['C5','Healed venous ulcer'],
['C6','Active venous ulcer – shallow, irregular, gaiter zone, sloping edges, moist base']],
[1.8, 13.9], hdr_col='#880e4f',
row_cols=[colors.HexColor('#fce4ec'), colors.white])]
# Q25.5 Six Ps
story += [sq("5. Six P's of Acute Limb Ischaemia & Why It Is a Surgical Emergency"),
tbl(
[["'P'", 'Description', 'Clinical Significance'],
['Pain','Sudden severe distal pain; may decrease as nerves die',
'First symptom; decreasing pain = progressing ischaemia'],
['Pallor','Pale/white limb; later fixed mottling','Fixed mottling = irreversible ischaemia'],
['Pulselessness','Absent pulses distal to occlusion',
'Confirms vascular occlusion; localises level'],
['Paraesthesia','Pins & needles → numbness (sensory nerve ischaemia)',
'EARLY warning sign; nerve most sensitive to ischaemia'],
['Paralysis','Inability to move the limb (motor ischaemia)',
'ADVANCED ischaemia; near-irreversible – ominous sign'],
['Perishing cold\n(Poikilothermia)','Cold limb (absent warm arterial blood)',
'Temperature demarcation localises occlusion level']],
[2.8, 5.5, 7.4], hdr_col='#4a148c',
row_cols=[colors.HexColor('#f3e5f5'), colors.white]),
h3('Why It Is a Surgical Emergency'),
ans('Skeletal muscle tolerates ischaemia for only <b>4–6 hours</b> before irreversible '
'necrosis. Paralysis and paraesthesia signal impending irreversibility. '
'Delay beyond the ischaemic window = limb loss. Reperfusion beyond this window '
'causes <b>reperfusion injury</b> (myonecrosis → hyperkalaemia → AKI).'),
b('Rutherford I (viable): no sensory/motor loss – urgent revascularisation'),
b('Rutherford IIa (threatened, marginal): sensory loss, no motor – emergency'),
b('Rutherford IIb (threatened, immediate): sensory + motor loss – IMMEDIATE surgery'),
b('Rutherford III (irreversible): paralysis + fixed staining – primary amputation')]
# ─────────────────────────────── BUILD ───────────────────────
print("Building PDF...")
doc.build(story)
print(f"PDF saved: {OUT}")
cd /tmp/workspace/mbbs-proff-answers && python build_pdf.py 2>&1
"def img(" in ~/mbbs-proff-answers/build_pdf.py
~/mbbs-proff-answers/build_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/mbbs-proff-answers/build_pdf.py'
"d4_lethal_dcr" in ~/mbbs-proff-answers/build_pdf.py
~/mbbs-proff-answers/build_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/mbbs-proff-answers/build_pdf.py'
cd /tmp/workspace/mbbs-proff-answers && python build_pdf.py 2>&1
ls -lh /tmp/workspace/mbbs-proff-answers/MBBS_Proff_Answers.pdf
MBBS Proff Answers
PDF Document · PDF
WORDWRAP)leading and spaceAfter to prevent paragraph crowding| Diagram | Content |
|---|---|
| 1 | Septic shock Golden Hour flowchart (SSC 1-Hour Bundle) |
| 2 | Wound healing phases timeline with mediators (Bailey & Love Ch. 3) |
| 3 | Cervical lymph node levels schematic (head/neck anatomy) |
| 4 | Lethal Triad (triangle) + DCR step-by-step flowchart |
| 5 | Virchow's Triad (Venn) + Six P's of acute limb ischaemia |
| 6 | TB lymphadenitis – all 5 stages with arrows (Beedham & Hudson) |
| 7 | TNBC Paradox flowchart + BCS contraindications side-by-side |