Make a checklist PDF of all these 4 system examination findings, it’s definition, grades if necessary, normal vs abnormal findings and the clinical significance to rule out the disease
This one
cd /tmp/workspace/attachments/e0c8124f-02e9-45d1-9f1c-69440da6b4ba/ && python3 -c " import pdfplumber with pdfplumber.open('PDF.pdf') as pdf: for i, page in enumerate(pdf.pages): print(f'=== PAGE {i+1} ===') print(page.extract_text()) "
mkdir -p /tmp/workspace/system-exam-checklist && ls /tmp/workspace/system-exam-checklist/
~/system-exam-checklist/build_checklist.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import Flowable
# ─── Color Palette ──────────────────────────────────────────────────────────
GIT_COLOR = colors.HexColor("#1A6B3C") # Deep green
CNS_COLOR = colors.HexColor("#6B3EA6") # Purple
RS_COLOR = colors.HexColor("#1565C0") # Deep blue
CVS_COLOR = colors.HexColor("#B71C1C") # Deep red
HEADER_BG = colors.HexColor("#1C2833") # Dark slate
LIGHT_GRAY = colors.HexColor("#F4F6F7")
MID_GRAY = colors.HexColor("#D5D8DC")
NORMAL_BG = colors.HexColor("#E8F5E9")
ABNORMAL_BG = colors.HexColor("#FFEBEE")
GRADES_BG = colors.HexColor("#E3F2FD")
SIG_BG = colors.HexColor("#FFF8E1")
WHITE = colors.white
BLACK = colors.black
PAGE_W, PAGE_H = A4
# ─── Checkbox Flowable ──────────────────────────────────────────────────────
class Checkbox(Flowable):
def __init__(self, size=9):
Flowable.__init__(self)
self.size = size
self.width = size
self.height = size
def draw(self):
self.canv.setStrokeColor(colors.HexColor("#555555"))
self.canv.setLineWidth(0.8)
self.canv.rect(0, 0, self.size, self.size, fill=0)
# ─── Document Setup ─────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
"/tmp/workspace/system-exam-checklist/System_Exam_Checklist.pdf",
pagesize=A4,
rightMargin=1.5*cm,
leftMargin=1.5*cm,
topMargin=2*cm,
bottomMargin=2*cm,
title="System Examination Findings Checklist",
author="Clinical Reference"
)
styles = getSampleStyleSheet()
def make_style(name, parent='Normal', **kwargs):
s = ParagraphStyle(name, parent=styles[parent], **kwargs)
return s
# ─── Custom Paragraph Styles ────────────────────────────────────────────────
cover_title = make_style('CoverTitle',
fontSize=26, leading=32, textColor=WHITE, alignment=TA_CENTER, fontName='Helvetica-Bold')
cover_sub = make_style('CoverSub',
fontSize=13, leading=18, textColor=colors.HexColor("#BDC3C7"), alignment=TA_CENTER, fontName='Helvetica')
sys_header = make_style('SysHeader',
fontSize=15, leading=20, textColor=WHITE, fontName='Helvetica-Bold', alignment=TA_CENTER)
finding_title = make_style('FindingTitle',
fontSize=11, leading=14, textColor=WHITE, fontName='Helvetica-Bold')
finding_def = make_style('FindingDef',
fontSize=9, leading=13, textColor=colors.HexColor("#2C3E50"), fontName='Helvetica',
spaceAfter=3)
cell_label = make_style('CellLabel',
fontSize=8, leading=10, textColor=colors.HexColor("#555555"), fontName='Helvetica-Bold',
spaceAfter=2)
cell_body = make_style('CellBody',
fontSize=8, leading=11, textColor=colors.HexColor("#1A1A1A"), fontName='Helvetica',
spaceAfter=2)
bullet_body = make_style('BulletBody',
fontSize=8, leading=11, textColor=colors.HexColor("#1A1A1A"), fontName='Helvetica',
leftIndent=8, bulletIndent=0)
normal_label = make_style('NormalLabel',
fontSize=8, leading=10, textColor=colors.HexColor("#1B5E20"), fontName='Helvetica-Bold')
abnormal_label = make_style('AbnormalLabel',
fontSize=8, leading=10, textColor=colors.HexColor("#B71C1C"), fontName='Helvetica-Bold')
# ─── Helper to make bullet list ─────────────────────────────────────────────
def bullets(items):
return "\n".join(f"• {i}" for i in items)
# ─── Finding Block builder ───────────────────────────────────────────────────
def finding_block(sys_color, finding_name, definition, grades, normal, abnormal, clinical_sig):
"""Build a complete finding block as a KeepTogether table."""
inner_rows = []
# Header row: finding name + checkbox
header_data = [[
Paragraph(finding_name, finding_title),
Paragraph("☐ Assessed", make_style('ChkLabel', fontSize=8, textColor=WHITE, fontName='Helvetica'))
]]
header_table = Table(header_data, colWidths=[13*cm, 3.5*cm])
header_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), sys_color),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('LEFTPADDING', (0,0), (0,0), 8),
('RIGHTPADDING', (-1,0), (-1,0), 6),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('ROUNDEDCORNERS', [4, 4, 0, 0]),
]))
# Definition row
def_data = [[Paragraph("<b>Definition:</b> " + definition, cell_body)]]
def_table = Table(def_data, colWidths=[16.5*cm])
def_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor("#F8F9FA")),
('LEFTPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('BOX', (0,0), (-1,-1), 0.3, MID_GRAY),
]))
# Grades row (only if grades provided)
content_rows = []
if grades:
grades_data = [[Paragraph("<b>Grades / Classification:</b>", cell_label)],
[Paragraph(bullets(grades), cell_body)]]
grades_table = Table(grades_data, colWidths=[16.5*cm])
grades_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), GRADES_BG),
('LEFTPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('BOX', (0,0), (-1,-1), 0.3, colors.HexColor("#90CAF9")),
]))
content_rows.append(grades_table)
content_rows.append(Spacer(1, 2))
# Normal / Abnormal side-by-side
norm_para = [Paragraph("NORMAL FINDINGS", normal_label)] + [Paragraph("• "+n, cell_body) for n in normal]
abn_para = [Paragraph("ABNORMAL FINDINGS", abnormal_label)] + [Paragraph("• "+a, cell_body) for a in abnormal]
def stackparas(paras):
trows = [[p] for p in paras]
t = Table(trows, colWidths=[7.8*cm])
t.setStyle(TableStyle([
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 4),
('TOPPADDING', (0,0), (-1,-1), 2),
('BOTTOMPADDING', (0,0), (-1,-1), 2),
]))
return t
na_data = [[stackparas(norm_para), stackparas(abn_para)]]
na_table = Table(na_data, colWidths=[8.25*cm, 8.25*cm])
na_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (0,-1), NORMAL_BG),
('BACKGROUND', (1,0), (1,-1), ABNORMAL_BG),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('BOX', (0,0), (-1,-1), 0.3, MID_GRAY),
('LINEBEFORE', (1,0), (1,-1), 0.5, MID_GRAY),
('TOPPADDING', (0,0), (-1,-1), 3),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
]))
# Clinical significance
sig_data = [[Paragraph("<b>Clinical Significance:</b>", cell_label)],
[Paragraph(bullets(clinical_sig), cell_body)]]
sig_table = Table(sig_data, colWidths=[16.5*cm])
sig_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), SIG_BG),
('LEFTPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('BOX', (0,0), (-1,-1), 0.3, colors.HexColor("#FFD54F")),
('ROUNDEDCORNERS', [0, 0, 4, 4]),
]))
wrapper_data = [
[header_table],
[def_table],
]
for cr in content_rows:
wrapper_data.append([cr])
wrapper_data.append([na_table])
wrapper_data.append([Spacer(1,1)])
wrapper_data.append([sig_table])
wrapper = Table(wrapper_data, colWidths=[16.5*cm])
wrapper.setStyle(TableStyle([
('LEFTPADDING', (0,0), (-1,-1), 0),
('RIGHTPADDING', (0,0), (-1,-1), 0),
('TOPPADDING', (0,0), (-1,-1), 0),
('BOTTOMPADDING', (0,0), (-1,-1), 0),
('BOX', (0,0), (-1,-1), 1, sys_color),
]))
return KeepTogether([wrapper, Spacer(1, 8)])
# ─── System Section Header ───────────────────────────────────────────────────
def sys_section_header(title, subtitle, color):
data = [[Paragraph(title, sys_header)],
[Paragraph(subtitle, make_style('SysSub', fontSize=9, textColor=colors.HexColor("#BDC3C7"),
alignment=TA_CENTER, fontName='Helvetica'))]]
t = Table(data, colWidths=[16.5*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), color),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
('LEFTPADDING', (0,0), (-1,-1), 10),
('ROUNDEDCORNERS', [6, 6, 6, 6]),
]))
return KeepTogether([t, Spacer(1, 10)])
# ═══════════════════════════════════════════════════════════════════════════════
# DATA
# ═══════════════════════════════════════════════════════════════════════════════
findings_data = {
# ─────────────────────────────────────────────────────────────────────────────
"GIT": {
"title": "1. GASTROINTESTINAL SYSTEM",
"subtitle": "Examination Findings Checklist",
"color": GIT_COLOR,
"findings": [
("PALLOR",
"Pallor refers to abnormal paleness of the skin, mucous membranes, conjunctiva, or nail beds due to reduced haemoglobin concentration or decreased cutaneous blood flow.",
["Grade 1 (Mild): Pallor of conjunctiva only",
"Grade 2 (Moderate): Pallor of conjunctiva + palmar creases",
"Grade 3 (Severe): Pallor of conjunctiva + palms + tongue/lips",
"Grade 4 (Very Severe): All of above + signs of decompensation (tachycardia, dyspnoea at rest)"],
["Pink-red conjunctiva, tongue, and nail beds", "Haemoglobin: >/=12 g/dL (F), >/=13 g/dL (M)", "Palmar creases pink and flushed"],
["Pale/white conjunctiva and mucous membranes", "Loss of colour in palmar creases", "Pale tongue and nail beds"],
["GI blood loss: peptic ulcer, varices, colonic malignancy, IBD",
"Haemolytic anaemia in liver disease (e.g. hypersplenism)",
"Chronic disease anaemia in cirrhosis, malignancy, Crohn's disease",
"Iron/B12/folate deficiency malabsorption (coeliac, Crohn's)"]),
("ICTERUS (JAUNDICE)",
"Yellow discolouration of sclera, skin, and mucous membranes due to elevated serum bilirubin (>2-3 mg/dL). Best seen in sclera in natural light.",
["Pre-hepatic: haemolysis - indirect bilirubin dominant",
"Hepatic (hepatocellular): both fractions elevated - liver cell failure",
"Post-hepatic (obstructive/cholestatic): direct bilirubin dominant - dark urine, pale stool"],
["Scleral colour white/cream (bilirubin <1 mg/dL)", "Normal urine colour (straw yellow)", "Normal stool colour (brown)"],
["Yellow sclera (scleral icterus is earliest sign)", "Yellow skin especially face, palms", "Dark (cola-coloured) urine in obstructive/hepatic", "Clay/pale stool in cholestasis"],
["Viral hepatitis (A, B, C, E)", "Alcoholic liver disease / cirrhosis",
"Obstructive jaundice: cholelithiasis, cholangiocarcinoma, pancreatic head carcinoma",
"Haemolytic disorders: hereditary spherocytosis, G6PD deficiency",
"Liver failure: fulminant hepatic failure - check for flapping tremors, ascites"]),
("ASCITES (SHIFTING DULLNESS / FLUID THRILL)",
"Accumulation of free fluid in the peritoneal cavity. Detected by percussion (shifting dullness >500 mL) and fluid thrill (>1000 mL) on examination.",
["Grade 1: Detected only on ultrasound",
"Grade 2: Moderate - flanks full on inspection, shifting dullness positive",
"Grade 3: Tense/large - grossly distended abdomen, fluid thrill positive"],
["Flanks resonant on percussion", "No shifting dullness", "Umbilicus inverted and central", "Flat/scaphoid abdomen"],
["Full flanks on inspection", "Shifting dullness positive (dullness shifts with position change)", "Fluid thrill positive in gross ascites", "Everted umbilicus", "Stretched, shiny skin"],
["Cirrhosis with portal hypertension (80% of cases)",
"Malignant ascites: hepatocellular carcinoma, peritoneal metastases, ovarian carcinoma",
"Tuberculous peritonitis: exudative, may have doughy feel",
"Cardiac causes: right heart failure, constrictive pericarditis",
"Hypoalbuminaemia: nephrotic syndrome, protein malnutrition",
"Check SAAG (serum-ascites albumin gradient): >/=1.1 = portal hypertension"]),
("HEPATOMEGALY",
"Enlargement of the liver, palpable below the right costal margin in the right midclavicular line during deep inspiration, or liver span >12 cm on percussion.",
["Mild: <3 cm below costal margin",
"Moderate: 3-7 cm below costal margin",
"Gross: >7 cm below costal margin",
"Note: edge (sharp/round), surface (smooth/nodular), consistency (soft/firm/hard), tenderness, pulsatility"],
["Liver not palpable below right costal margin in adults", "Liver span 6-12 cm (percussion)", "Upper border of liver dullness at 5th ICS (right midclavicular line)"],
["Liver palpable >1 cm below costal margin", "Liver span >12 cm", "Hard, nodular surface", "Pulsatile liver (tricuspid regurgitation)", "Tender liver"],
["Smooth, tender: viral hepatitis, congestive cardiac failure, early cirrhosis",
"Smooth, non-tender: fatty liver, early hepatitis",
"Hard, nodular: cirrhosis (late), hepatocellular carcinoma, metastatic liver disease",
"Pulsatile: tricuspid regurgitation",
"Hepatospleno-megaly: portal hypertension, haematological malignancies (lymphoma, CML)"]),
("SPLENOMEGALY",
"Enlargement of the spleen, palpable below the left costal margin. Spleen enlarges towards the right iliac fossa. Has a notched edge and a medial notch; cannot be balloted or have finger insinuated above it.",
["Mild (Hackney grade 1): tip just palpable on deep inspiration",
"Moderate (grade 2-3): up to the umbilicus",
"Gross (grade 4 - Massive/Tropical): extends to or below the umbilicus / right iliac fossa"],
["Spleen not palpable", "Traube's space resonant on percussion", "No dullness at Castell's point"],
["Palpable spleen with notched medial border", "Dullness in Traube's space / positive Castell's sign", "Cannot insinuate fingers between mass and left costal margin"],
["Massive splenomegaly: malaria (tropical), kala-azar, CML, myelofibrosis, Gaucher's disease",
"Moderate: portal hypertension, lymphoma, haemolytic anaemias, infective endocarditis",
"Mild: viral hepatitis, typhoid, EBV mononucleosis, SLE, RA (Felty syndrome)",
"Hepatosplenomegaly together: cirrhosis with portal hypertension, lymphoproliferative disorders"]),
("BOWEL SOUNDS",
"Intestinal sounds produced by peristaltic movement of gas and fluid through the bowel, auscultated with a stethoscope over the abdomen.",
None,
["3-5 sounds per minute (small bowel)", "Gurgling/bubbling quality", "Present in all quadrants"],
["Absent bowel sounds (>3 min silence): paralytic ileus, peritonitis",
"High-pitched, tinkling/rushing sounds: early mechanical obstruction",
"Succussion splash: >7 hours after food - pyloric stenosis or gastric outlet obstruction",
"Venous hum at umbilicus: portal hypertension (caput medusae)"],
["Absent: paralytic ileus (post-surgery, peritonitis, electrolyte imbalance)",
"High-pitched tinkling: intestinal obstruction",
"Succussion splash: pyloric obstruction / gastric outlet obstruction",
"Venous hum: portal hypertension with portosystemic collaterals",
"Arterial bruit over aorta: aneurysm; over renal area: renal artery stenosis"]),
]
},
# ─────────────────────────────────────────────────────────────────────────────
"CNS": {
"title": "2. CENTRAL NERVOUS SYSTEM",
"subtitle": "Examination Findings Checklist",
"color": CNS_COLOR,
"findings": [
("MUSCLE TONE",
"Resistance felt by the examiner when a joint is passively moved through its range of motion with the patient relaxed. Reflects the baseline activity of the stretch reflex arc.",
["Hypotonia: decreased resistance - LMN lesion, cerebellar disease, acute spinal shock",
"Spasticity (hypertonia): velocity-dependent increased resistance with 'clasp-knife' release - UMN (corticospinal) lesion",
"Rigidity: non-velocity-dependent, uniform resistance throughout range - extrapyramidal lesion",
" - Lead-pipe rigidity: uniform throughout range (Parkinsonism)",
" - Cogwheel rigidity: ratchet-like due to tremor superimposed on rigidity (Parkinsonism)",
"Paratonia (Gegenhalten): variable resistance - frontal lobe disease"],
["Normal muscle tone: slight resistance to passive movement, equal bilaterally", "Muscle bulk normal"],
["Hypotonia: flaccid, floppy limb - LMN, cerebellar, spinal shock",
"Spasticity: clasp-knife, velocity-dependent (pyramidal tract disease)",
"Lead-pipe/cogwheel rigidity (extrapyramidal disease)",
"Asymmetric tone suggests focal lesion"],
["UMN lesion (spasticity): stroke, MS, tumour, cervical myelopathy",
"LMN lesion (hypotonia/flaccidity): peripheral neuropathy, polio, Guillain-Barre, nerve root compression",
"Extrapyramidal (rigidity): Parkinson's disease, drug-induced parkinsonism, Wilson's disease",
"Cerebellar (hypotonia): cerebellar stroke, multiple sclerosis, alcoholic cerebellar degeneration"]),
("MUSCLE POWER (MRC GRADING)",
"Assessment of voluntary muscle strength using the Medical Research Council (MRC) scale. Test individual muscle groups systematically from proximal to distal in upper and lower limbs.",
["Grade 0: No contraction",
"Grade 1: Flicker of contraction only",
"Grade 2: Movement with gravity eliminated",
"Grade 3: Movement against gravity but not resistance",
"Grade 4: Movement against gravity with some resistance (4- / 4 / 4+)",
"Grade 5: Normal power against full resistance"],
["MRC Grade 5 in all muscle groups tested", "Symmetric power bilaterally", "Normal for age"],
["MRC Grade <5 - any reduction in power from normal",
"Monoplegia: one limb",
"Hemiplegia: arm + leg on same side - opposite cerebral hemisphere or internal capsule",
"Paraplegia: both legs - spinal cord (thoracic or below)",
"Quadriplegia: all four limbs - cervical cord, brainstem, bilateral cortex"],
["Hemiplegia/hemiparesis: contralateral cortical stroke, internal capsule lacunar infarct, space-occupying lesion",
"Paraplegia: spinal cord compression (disc, TB spine, tumour), transverse myelitis, MS",
"Proximal weakness (getting up from chair, combing hair): myopathy, polymyositis, myasthenia gravis",
"Distal weakness (buttoning, gripping): peripheral neuropathy (diabetic, CMT)",
"Bilateral distal ascending weakness: Guillain-Barre syndrome"]),
("DEEP TENDON REFLEXES (DTR)",
"Monosynaptic stretch reflexes elicited by tendon percussion. Assess the integrity of the reflex arc (sensory afferent, spinal cord segment, motor efferent) and upper motor neuron control.",
["0: Absent (areflexia)",
"+1: Diminished / trace (with reinforcement)",
"+2: Normal",
"+3: Brisk (without clonus)",
"+4: Very brisk with clonus",
"Key reflexes: Jaw jerk (V), Biceps (C5-C6), Supinator (C5-C6), Triceps (C7-C8), Knee (L2-L4), Ankle (S1-S2)"],
["Grade +2 bilaterally and symmetrically in all reflexes", "Plantar response: flexor (downgoing)"],
["Hyperreflexia (3+/4+): UMN lesion - stroke, MS, cervical myelopathy, ALS",
"Hyporeflexia/areflexia (0/1+): LMN lesion - peripheral neuropathy, nerve root lesion, myopathy",
"Extensor plantar (Babinski's sign positive): UMN lesion",
"Inverted reflexes: C5/C6 cord lesion - loss of biceps/supinator reflex with brisk triceps",
"Clonus (sustained): significant UMN lesion (stroke, myelopathy)"],
["Hyperreflexia + Babinski: pyramidal tract disease (stroke, MS, motor neuron disease, tumour)",
"Areflexia: peripheral neuropathy (diabetic, GBS, hereditary), nerve root compression, hypothyroidism",
"Mixed UMN+LMN: motor neuron disease (ALS) - fasciculations with brisk reflexes",
"Absent ankle reflex + extensor plantar: conus medullaris or cauda equina lesion",
"Pendular reflexes: cerebellar disease"]),
("PLANTAR RESPONSE (BABINSKI SIGN)",
"Tested by stroking the outer border of the sole from heel to little toe and across to the ball of the foot with a blunt instrument. Assesses integrity of the corticospinal (pyramidal) tract.",
["Flexor response (normal): downward curling of toes - normal in adults",
"Extensor response - Babinski positive (pathological in adults): dorsiflexion of hallux with fanning of other toes",
"Note: Chaddock (stroke lateral malleolus), Oppenheim (tibial crest), Gordon (calf squeeze) are equivalent tests"],
["Plantar flexion of great toe (downgoing plantar) = NORMAL in adults", "No fanning of toes"],
["Extension (dorsiflexion) of great toe (upgoing plantar)", "Fanning (abduction) of other toes", "Bilateral extensor = significant bilateral UMN lesion"],
["Unilateral extensor plantar: contralateral corticospinal tract lesion (stroke, tumour, MS, head injury)",
"Bilateral extensor: spinal cord disease, bilateral hemisphere lesion, coma (metabolic/structural)",
"Normal in infants <18 months (incomplete myelination)",
"Absent plantar response with absent ankle jerk: peripheral neuropathy or cord lesion at conus"]),
("CEREBELLAR SIGNS",
"Signs indicating dysfunction of the cerebellum or its connections. Cerebellum coordinates smooth, accurate voluntary movement and maintains balance.",
["DANISH mnemonic: Dysdiadochokinesia, Ataxia (gait), Nystagmus, Intention tremor, Slurred (scanning) speech, Hypotonia",
"Additional: Rebound phenomenon, Past-pointing (finger-nose test), Titubation, Heel-knee-shin test abnormality"],
["Smooth finger-nose-finger test", "Normal tandem (heel-toe) gait", "No nystagmus at rest or on lateral gaze", "Normal rapid alternating movements", "Romberg's sign negative (cerebellar ataxia worsens with eyes open too)"],
["Intention tremor on FNF (increases near target)",
"Dysdiadochokinesia: irregular rapid alternating movements",
"Heel-shin ataxia: irregular heel placement",
"Nystagmus: fast phase to side of lesion",
"Scanning/staccato speech",
"Wide-based cerebellar gait",
"Rebound phenomenon positive"],
["Unilateral cerebellar signs (ipsilateral to lesion): cerebellar infarction, haemorrhage, tumour, MS plaque",
"Bilateral cerebellar signs: multiple sclerosis, alcoholic cerebellar degeneration, paraneoplastic (lung/breast/ovarian carcinoma), spinocerebellar ataxia",
"Midline cerebellar (vermis) disease: truncal ataxia, gait ataxia - medulloblastoma, alcohol",
"Distinguish from sensory ataxia: Romberg's positive (worse with eyes closed) = posterior column disease"]),
("MENINGEAL SIGNS",
"Signs indicating irritation of the meninges (meninges surrounding the brain and spinal cord). Result from meningeal inflammation, infection, or haemorrhage causing pain with movement.",
["Neck stiffness: inability to flex neck - chin cannot touch chest",
"Kernig's sign: with hip flexed 90°, inability to extend knee beyond 135° due to pain/spasm",
"Brudzinski's sign: passive neck flexion causes involuntary bilateral hip and knee flexion",
"Jolt accentuation: worsening of headache on horizontal rotation of head (2-3x/sec) - sensitive for meningitis"],
["Free neck flexion - chin touches chest", "Kernig's sign negative", "Brudzinski's sign negative", "No photophobia or phonophobia"],
["Neck stiffness (resistance to passive neck flexion)",
"Kernig's sign positive",
"Brudzinski's sign positive",
"Photophobia, phonophobia",
"Opisthotonos in severe cases"],
["Bacterial meningitis: Streptococcus pneumoniae, Neisseria meningitidis, Listeria monocytogenes",
"Tuberculous meningitis: subacute onset, cranial nerve palsies, high CSF protein",
"Viral meningitis (aseptic): enteroviruses, HSV2, HIV seroconversion",
"Subarachnoid haemorrhage (SAH): sudden 'thunderclap' headache, neck stiffness, normal CT in 10-15%",
"Note: neck stiffness may be absent in elderly, immunocompromised, or early disease"]),
]
},
# ─────────────────────────────────────────────────────────────────────────────
"RS": {
"title": "3. RESPIRATORY SYSTEM",
"subtitle": "Examination Findings Checklist",
"color": RS_COLOR,
"findings": [
("CLUBBING",
"Painless enlargement of the terminal segments of the fingers (or toes) due to soft tissue proliferation under the nail bed, causing loss of the normal angle between the nail and nail fold.",
["Grade 1: Loss of nail fold angle (Lovibond angle >180°) - fluctuation/sponginess of nail bed",
"Grade 2: Grade 1 + increased curvature of nail (watch-glass deformity)",
"Grade 3: Grade 2 + soft tissue enlargement of finger tip (drumstick/bulbous appearance)",
"Grade 4: Grade 3 + periosteal new bone formation (hypertrophic osteoarthropathy) - painful wrists",
"Schamroth's sign: loss of diamond-shaped window when dorsa of opposite index fingers apposed"],
["Lovibond angle <180° (normal profile angle)", "Nail bed non-fluctuant", "Schamroth's window present"],
["Lovibond angle >/=180° (loss of angle)",
"Nail bed fluctuation (spongy feel)",
"Watch-glass/curved nail",
"Drumstick appearance of terminal phalanx",
"Schamroth's sign positive"],
["Respiratory (most common): bronchogenic carcinoma, bronchiectasis, lung abscess, empyema, fibrosing alveolitis (IPF), mesothelioma",
"Cardiovascular: cyanotic congenital heart disease, infective endocarditis, atrial myxoma",
"GI: cirrhosis, IBD (Crohn's/UC), coeliac disease, GI lymphoma",
"Unilateral clubbing: subclavian artery aneurysm, AV fistula in arm, brachial arteriovenous malformation",
"Idiopathic/familial: hereditary pachydermoperiostosis"]),
("CYANOSIS",
"Bluish discolouration of skin and mucous membranes due to >5 g/dL of deoxygenated haemoglobin in capillary blood. Best seen in lips, tongue, and fingertips.",
["Central cyanosis: tongue/mucous membranes blue - indicates systemic arterial desaturation (SpO2 <85%)",
" - Causes: respiratory failure, right-to-left cardiac shunt, high altitude",
"Peripheral cyanosis: fingertips/toes only, tongue spared - reduced peripheral perfusion",
" - Causes: cold exposure, shock, cardiac failure, Raynaud's phenomenon",
"Differential cyanosis (feet blue, hands pink): patent ductus arteriosus with Eisenmenger syndrome"],
["Pink tongue and mucous membranes", "Pink nail beds", "SpO2 >95% (normal)"],
["Bluish tongue (central cyanosis)", "Bluish fingertips (peripheral cyanosis)", "SpO2 <90% (concerning)", "Differential cyanosis: feet more cyanosed than hands"],
["Central cyanosis: respiratory failure (COPD, pneumonia, pulmonary oedema, pneumothorax, PE)",
"Central cyanosis + clubbing: cyanotic congenital heart disease (Tetralogy of Fallot, Eisenmenger), pulmonary AV malformation",
"Peripheral cyanosis alone: heart failure, peripheral vascular disease, cold exposure",
"Differential cyanosis (upper pink, lower blue): patent ductus arteriosus + pulmonary hypertension (Eisenmenger)",
"Methaemoglobinaemia: cyanosis not corrected by O2 - check co-oximetry"]),
("CHEST EXPANSION AND TACTILE VOCAL FREMITUS",
"Chest expansion measures symmetry and degree of lung inflation. Tactile Vocal Fremitus (TVF) is the vibration felt over the chest wall when the patient says '99/99' (or 'one-one-one'), transmitted through lung parenchyma.",
["TVF increased: consolidation (lung compressed/solidified transmits vibration better)",
"TVF decreased/absent: pleural effusion (fluid dampens vibration), pneumothorax (air gap), pleural thickening, bronchial obstruction",
"Chest expansion reduced on one side: any unilateral lung pathology"],
["Symmetrical chest expansion >5 cm bilaterally (2-3 cm each side)", "TVF equal bilaterally", "No lag in expansion on either side"],
["Reduced expansion on affected side: effusion, collapse, consolidation, pneumothorax, fibrosis",
"TVF increased: consolidation/hepatisation",
"TVF decreased: pleural effusion (most pronounced reduction), pneumothorax, emphysema, fibrosis (upper lobe)"],
["Reduced expansion + absent TVF + stony dull percussion + absent breath sounds: pleural effusion",
"Reduced expansion + absent TVF + hyper-resonant percussion + absent breath sounds: pneumothorax",
"Reduced expansion + increased TVF + dull percussion + bronchial breathing + bronchophony: lobar consolidation/pneumonia",
"Bilateral reduced expansion: COPD/emphysema (barrel chest), bilateral pleural effusions, pulmonary fibrosis"]),
("BREATH SOUNDS AND ADVENTITIOUS SOUNDS",
"Normal breath sounds arise from turbulent airflow in large airways and are modified by transmission through lung parenchyma and chest wall. Adventitious (added) sounds are abnormal sounds superimposed on breath sounds.",
["Normal: Vesicular breath sounds - soft, low-pitched, inspiration > expiration (3:1), no gap between phases",
"Bronchial breath sounds (abnormal in peripheral lung): harsh, high-pitched, equal inspiration and expiration with gap, heard over consolidation, above effusion, or cavitation",
"Crepitations (crackles): Fine (late inspiratory, high-pitched): pulmonary oedema, fibrosing alveolitis; Coarse (early inspiratory): COPD, bronchiectasis, secretions",
"Rhonchi (wheeze): continuous, musical - widespread: asthma, COPD; localised: foreign body, tumour",
"Pleural rub: leathery, creaking, both phases - pleuritis, PE, pneumonia"],
["Vesicular breath sounds over all zones bilaterally", "No adventitious sounds", "Vocal resonance normal and equal bilaterally"],
["Diminished breath sounds: effusion (stony dull), pneumothorax (hyperresonant), emphysema",
"Bronchial breathing: consolidation, above effusion, fibrosis",
"Fine crepitations: pulmonary oedema, IPF, cryptogenic organising pneumonia",
"Coarse crepitations: bronchiectasis, COPD, aspiration pneumonia",
"Wheeze: asthma (bilateral), COPD; monophonic = partial bronchial obstruction (tumour/FB)",
"Pleural rub: pleuritis, pulmonary embolism, parapneumonic pleuritis"],
["Fine end-inspiratory crepitations (bilateral basal): pulmonary oedema (cardiac failure), IPF (bilateral basal 'Velcro' crackles)",
"Bronchial breathing + increased TVF + dull percussion: lobar consolidation (pneumonia)",
"Absent/markedly reduced sounds + hyper-resonance: pneumothorax (emergency)",
"Stony dull percussion + absent BS + absent TVF: pleural effusion - exudate vs transudate (Light's criteria)",
"Post-tussive crackles: tuberculosis (upper zone), bronchiectasis",
"Wheezes (widespread): acute severe asthma, COPD exacerbation"]),
("TRACHEAL POSITION AND MEDIASTINAL SHIFT",
"The trachea is palpated in the suprasternal notch to assess midline position. Deviation indicates mediastinal displacement toward or away from the lesion, an important sign distinguishing causes of unilateral lung pathology.",
None,
["Trachea central in suprasternal notch", "Equal space between trachea and sternocleidomastoid on both sides", "No tracheal tug"],
["Trachea deviated to affected (diseased) side: collapse, fibrosis, pneumonectomy",
"Trachea deviated away from affected side: large pleural effusion, tension pneumothorax (emergency)",
"Tracheal tug: aortic aneurysm or fixed mediastinal mass"],
["Trachea pulled to same side as lesion: lobar/whole lung collapse, pulmonary fibrosis (upper lobe), post-surgical (pneumonectomy)",
"Trachea pushed away from lesion: large pleural effusion (exudate or transudate), tension pneumothorax",
"Tension pneumothorax: tracheal deviation + absent breath sounds + hypoxia + haemodynamic compromise = life-threatening emergency",
"No significant tracheal shift despite effusion: may indicate simultaneous collapse (blocked bronchus)"]),
("PERCUSSION NOTE",
"Percussion generates sound waves through the chest wall into lung tissue. The quality of the note reflects underlying tissue density. Indirect (mediate) percussion is standard.",
["Resonant: normal aerated lung",
"Hyper-resonant: increased air content - emphysema, pneumothorax",
"Stony dull: fluid - pleural effusion (most dull note in clinical examination)",
"Dull: consolidation, collapse, pleural thickening, tumour",
"Tympanic: air under pressure - rare, large pneumothorax cavity"],
["Resonant over all lung zones", "Cardiac dullness confined to normal borders", "Liver dullness beginning at 5th ICS (R midclavicular)", "Traube's space (LLZ) tympanic"],
["Stony dullness: pleural effusion",
"Dullness: consolidation, collapse, pleural thickening",
"Hyper-resonance: pneumothorax, emphysema (bilateral hyperresonance)",
"Obliteration of Traube's space: splenomegaly, left pleural effusion, gastric dilatation",
"Loss of Kronig's isthmus: upper lobe fibrosis/collapse (TB)"],
["Unilateral stony dull percussion: pleural effusion (confirm with CXR, ultrasound - Light's criteria for exudate/transudate)",
"Unilateral dullness + bronchial breathing: lobar consolidation (pneumonia)",
"Unilateral hyper-resonance: pneumothorax (confirm with CXR/ultrasound - if tension, treat immediately)",
"Bilateral hyper-resonance + barrel chest: emphysema/COPD",
"Upper zone dullness: post-TB fibrosis, Pancoast tumour (apical)"]),
]
},
# ─────────────────────────────────────────────────────────────────────────────
"CVS": {
"title": "4. CARDIOVASCULAR SYSTEM",
"subtitle": "Examination Findings Checklist",
"color": CVS_COLOR,
"findings": [
("JUGULAR VENOUS PRESSURE (JVP)",
"JVP reflects right atrial pressure and is assessed at the internal jugular vein. Measured as vertical height above the sternal angle at 45° inclination. Normal JVP is 1-3 cm above sternal angle (equivalent to CVP of 6-8 cmH2O).",
["Normal waveforms: a wave (atrial contraction), c wave (tricuspid valve closure), x descent, v wave (venous filling), y descent",
"Elevated JVP: right heart failure, SVC obstruction, tamponade, constrictive pericarditis",
"Non-pulsatile elevated JVP: SVC obstruction (no 'a' or 'v' waves)",
"Kussmaul's sign: paradoxical rise of JVP on inspiration - constrictive pericarditis, cardiac tamponade, RV infarction",
"Hepatojugular reflux: JVP rises >3 cm and stays elevated for >10 seconds on hepatic pressure - right heart failure"],
["JVP 1-3 cm above sternal angle at 45°", "Pulsatile with two visible waves (a and v)", "Falls with inspiration", "Hepatojugular reflux negative"],
["JVP >4 cm above sternal angle: elevated",
"Absent 'a' wave: atrial fibrillation",
"Prominent 'a' wave: tricuspid stenosis, pulmonary hypertension, complete heart block (cannon a waves)",
"Prominent 'v' wave: tricuspid regurgitation",
"Non-pulsatile elevated JVP: SVC obstruction",
"Kussmaul's sign positive: constrictive pericarditis"],
["Elevated + pulsatile + tender hepatomegaly: right heart failure (CCF)",
"Elevated + non-pulsatile: SVC obstruction (malignancy, thrombosis) - no hepatojugular reflex",
"Cannon a waves (irregular): complete heart block, ventricular tachycardia",
"Giant v waves: tricuspid regurgitation (look for pulsatile liver)",
"Elevated JVP + hypotension + muffled heart sounds: cardiac tamponade (Beck's triad)",
"Kussmaul's sign: constrictive pericarditis (JVP rises on inspiration)"]),
("APEX BEAT",
"The apex beat is the outermost and lowermost point where the cardiac impulse is palpable on the chest wall. Normally located in the 5th intercostal space just medial to (or at) the left midclavicular line.",
["Normal: localised tapping impulse, 5th ICS, medial to midclavicular line",
"Displaced (outside 5th ICS MCL): cardiomegaly (LVH, dilated cardiomyopathy)",
"Tapping apex: palpable S1 - mitral stenosis",
"Heaving/sustained impulse: pressure overload - aortic stenosis, systemic hypertension (LVH)",
"Hyperdynamic/thrusting (displaced): volume overload - mitral/aortic regurgitation, dilated cardiomyopathy",
"Impalpable: obesity, COPD/emphysema, pericardial effusion, dextrocardia"],
["5th ICS in left midclavicular line or just medial to it", "Localised (coin-sized), brief systolic impulse", "Not displaced", "Non-heaving, non-thrusting"],
["Displaced laterally/inferiorly: cardiomegaly",
"Tapping: mitral stenosis",
"Heaving (sustained, not displaced): LVH from pressure overload (AS, HTN)",
"Thrusting/hyperdynamic (displaced): volume overload (MR, AR, dilated CMP)",
"Diffuse: dilated cardiomyopathy",
"Right-sided apex: dextrocardia or right pneumothorax/effusion"],
["Tapping apex: suggests mitral stenosis (palpable loud S1)",
"Heaving undisplaced apex: aortic stenosis, systemic hypertension",
"Displaced + thrusting: mitral or aortic regurgitation, dilated cardiomyopathy, ischaemic cardiomyopathy",
"Right ventricular heave (left parasternal lift): pulmonary hypertension, ASD, mitral stenosis",
"Impalpable apex + elevated JVP + ascites: constrictive pericarditis or pericardial effusion"]),
("HEART SOUNDS (S1, S2, S3, S4)",
"S1 is closure of mitral and tricuspid valves (onset of systole). S2 is closure of aortic and pulmonary valves (onset of diastole). S3 and S4 are added/extra heart sounds heard in pathological states (or physiologically in young).",
["S1: 'Lub' - loud in MS (tapping), soft in MR, PR prolongation; best at apex with bell",
"S2: 'Dub' - loud P2 in pulmonary hypertension; split A2-P2 on inspiration (normal ≤30ms); fixed split in ASD; paradoxical split (P2 before A2) in LBBB/AS",
"S3 (ventricular gallop, low-pitched, early diastolic): rapid ventricular filling - pathological in adults = LV failure, dilated CMP; physiological in children/athletes/pregnancy",
"S4 (atrial gallop, low-pitched, pre-systolic): forceful atrial contraction against stiff ventricle - LVH (AS, HTN), ischaemia, HOCM; absent in AF"],
["S1 and S2 audible in all areas", "No S3 or S4 in adults (over 30)", "Normal splitting of S2 on inspiration (≤30ms)", "No murmurs, clicks, or rubs"],
["Loud S1: mitral stenosis", "Soft S1: MR, LBBB, PR prolongation, poor LV function",
"Loud P2: pulmonary hypertension",
"Fixed split S2: ASD",
"S3 in adults: heart failure, dilated CMP, MR (severe)",
"S4: LVH, acute MI, AS, HOCM",
"Muffled heart sounds: pericardial effusion"],
["S3 gallop (apex, bell, LLD position): LV systolic dysfunction - key finding in heart failure and dilated CMP",
"S4 gallop: LV diastolic dysfunction, acute MI, hypertensive heart disease, HOCM",
"Loud P2: pulmonary arterial hypertension (look for RV heave, elevated JVP, TR murmur)",
"Fixed split S2: atrial septal defect (confirm with echocardiography)",
"Pericardial friction rub (three-component, scratchy, changes with position): pericarditis",
"Opening snap (after S2): mitral stenosis (short S2-OS interval = severe MS)"]),
("PERIPHERAL PULSES AND PULSE CHARACTER",
"Assessment of the peripheral pulses evaluates heart rate, rhythm, volume, and character of blood flow. The radial pulse is examined first; character is best assessed at the carotid or brachial artery.",
["Rate: bradycardia <60/min; normal 60-100/min; tachycardia >100/min",
"Rhythm: regular, irregularly irregular (AF), regularly irregular (heart block, bigeminy)",
"Volume/Character:",
" - Normal: medium amplitude",
" - Small-volume/weak/thready: low cardiac output, shock, severe AS, tamponade",
" - Large-volume/bounding: aortic regurgitation, patent ductus arteriosus, thyrotoxicosis, fever, anaemia",
" - Pulsus paradoxus: >10 mmHg drop in SBP on inspiration - cardiac tamponade, severe asthma, COPD",
" - Pulsus alternans: alternating strong-weak - severe LV failure",
" - Bisferiens pulse: two systolic peaks - severe AR, HOCM",
" - Pulsus parvus et tardus: slow-rising, plateau - aortic stenosis",
"Radiofemoral delay: coarctation of aorta",
"Radio-radial delay: subclavian artery pathology, aortic dissection"],
["Rate 60-100/min, regular rhythm", "Equal volume bilaterally", "No radio-radial or radiofemoral delay", "Vessel wall supple (non-calcified)", "All peripheral pulses palpable"],
["Irregularly irregular: atrial fibrillation",
"Slow-rising, low amplitude: aortic stenosis",
"Collapsing (water-hammer) pulse: aortic regurgitation",
"Radiofemoral delay: coarctation of aorta",
"Absent peripheral pulses: peripheral arterial disease, arterial occlusion",
"Pulsus paradoxus (>10 mmHg): cardiac tamponade, severe asthma"],
["Irregularly irregular + apex-radial deficit: atrial fibrillation - rule out valvular disease (MS, MR)",
"Collapsing/water-hammer pulse (corrigan's): aortic regurgitation - check for wide pulse pressure, de Musset's sign, Quincke's sign, Duroziez's sign, Hill's sign (popliteal SBP > brachial SBP by >20 mmHg)",
"Slow-rising low-volume pulse: aortic stenosis (look for heaving apex, ejection systolic murmur radiating to carotids)",
"Radiofemoral delay: coarctation of aorta (check BP in all four limbs)",
"Pulsus paradoxus (>10 mmHg): cardiac tamponade (Beck's triad: hypotension, elevated JVP, muffled heart sounds)",
"Absent femoral pulses + hypertension in arms: coarctation of aorta"]),
("PARASTERNAL HEAVE AND PALPABLE SOUNDS",
"A parasternal (left sternal border) heave indicates right ventricular enlargement/hypertrophy. Palpable sounds (thrills) are murmurs intense enough to be felt; systolic thrills are graded >/= Grade 4.",
["Parasternal heave grading:",
" - Grade 1: barely felt - fingers slightly lifted",
" - Grade 2: fingers lifted off the chest",
" - Grade 3: whole hand lifted",
"Thrills: systolic (palpable at apex - MS; at base - AS/PS), diastolic (rare - severe MS)",
"Palpable P2: pulmonary hypertension",
"Palpable A2: systemic hypertension"],
["No parasternal heave palpable", "No thrills palpable", "Apex beat in normal position"],
["Parasternal heave (left sternal border): RV enlargement/pressure overload",
"Apical thrill: severe mitral stenosis or mitral regurgitation",
"Basal systolic thrill: severe aortic stenosis or pulmonary stenosis",
"Palpable P2: pulmonary hypertension",
"Palpable S3 at apex: severe LV failure"],
["Left parasternal heave + loud P2 + raised JVP: pulmonary hypertension (secondary to mitral stenosis, COPD, or primary PAH)",
"Left parasternal heave + ASD: right heart volume overload",
"Apical systolic thrill: significant mitral regurgitation or VSD",
"Basal systolic thrill + slow-rising pulse: severe aortic stenosis",
"Suprasternal thrill: aortic stenosis with carotid radiation",
"Parasternal heave resolves after valve repair/replacement: confirms RV pressure overload aetiology"]),
("CARDIAC MURMURS",
"Turbulent blood flow through cardiac valves or chambers produces audible sounds. Murmurs are graded by intensity, timing (systolic/diastolic), location, radiation, quality, and effect of posture/respiration.",
["Levine Grading (Systolic):",
" Grade 1/6: heard only with special techniques / experienced examiner",
" Grade 2/6: soft, easily audible",
" Grade 3/6: moderately loud, no thrill",
" Grade 4/6: loud with palpable thrill",
" Grade 5/6: very loud, heard with stethoscope edge off chest",
" Grade 6/6: audible without stethoscope",
"Diastolic murmurs graded 1-4 (always pathological)",
"Key timing: Systolic (ESM, PSM/HSM) vs Diastolic (EDM, MDM) vs Continuous"],
["No murmurs audible (S1 and S2 only)", "Physiological flow murmurs: soft, Grade 1-2 ESM, no radiation, no thrill"],
["Pansystolic murmur (apex to axilla): MR",
"Mid-diastolic murmur (apex, bell, LLD): MS",
"Ejection systolic murmur (aortic area to carotids): AS",
"Early diastolic murmur (Erb's area, sitting forward): AR",
"Continuous machinery murmur (left infraclavicular): PDA",
"Ejection systolic murmur (pulmonary area, louder on inspiration): PS"],
["Pansystolic murmur (apex to axilla) + tapping apex + AF: mitral regurgitation",
"Mid-diastolic rumble + opening snap + tapping apex: mitral stenosis (rheumatic)",
"Ejection systolic murmur (aortic area) + slow-rising pulse + LVH: aortic stenosis",
"Early diastolic murmur (Erb's area) + collapsing pulse + wide pulse pressure: aortic regurgitation",
"Continuous machinery murmur (left infraclavicular/Gibson's area): patent ductus arteriosus",
"Holosystolic murmur (lower left sternal edge) + RV heave: ventricular septal defect (VSD)",
"Ejection systolic murmur (pulmonary area, louder on inspiration) + fixed split S2: atrial septal defect (ASD) or pulmonary stenosis"]),
]
}
}
# ═══════════════════════════════════════════════════════════════════════════════
# BUILD DOCUMENT
# ═══════════════════════════════════════════════════════════════════════════════
story = []
# ── Cover Page ──────────────────────────────────────────────────────────────
cover_bg_data = [[Paragraph("SYSTEM EXAMINATION FINDINGS", cover_title)],
[Paragraph("Clinical Checklist", cover_sub)],
[Spacer(1, 10)],
[Paragraph("GIT • CNS • RESPIRATORY • CARDIOVASCULAR", make_style('CoverSystems',
fontSize=11, textColor=colors.HexColor("#F39C12"), alignment=TA_CENTER, fontName='Helvetica-Bold'))],
[Spacer(1, 8)],
[Paragraph("Definition • Grading • Normal vs Abnormal • Clinical Significance",
make_style('CoverDesc', fontSize=9, textColor=colors.HexColor("#BDC3C7"),
alignment=TA_CENTER, fontName='Helvetica'))],
]
cover_table = Table(cover_bg_data, colWidths=[16.5*cm])
cover_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), HEADER_BG),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 12),
('RIGHTPADDING', (0,0), (-1,-1), 12),
('ROWBACKGROUNDS', (0,0), (-1,-1), [HEADER_BG]),
('ROUNDEDCORNERS', [8, 8, 8, 8]),
]))
story.append(Spacer(1, 50))
story.append(cover_table)
story.append(Spacer(1, 20))
# Usage note
usage_data = [[Paragraph(
"<b>How to use:</b> Tick ☐ each finding as assessed. Review grades, normal/abnormal findings, "
"and clinical significance to guide differential diagnosis and management decisions.",
make_style('UsageNote', fontSize=8.5, textColor=colors.HexColor("#2C3E50"), fontName='Helvetica',
borderPadding=8))]]
usage_t = Table(usage_data, colWidths=[16.5*cm])
usage_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor("#EBF5FB")),
('BOX', (0,0), (-1,-1), 1, colors.HexColor("#2E86C1")),
('LEFTPADDING', (0,0), (-1,-1), 10),
('RIGHTPADDING', (0,0), (-1,-1), 10),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
('ROUNDEDCORNERS', [4, 4, 4, 4]),
]))
story.append(usage_t)
story.append(PageBreak())
# ── Systems ──────────────────────────────────────────────────────────────────
sys_order = ["GIT", "CNS", "RS", "CVS"]
for sys_key in sys_order:
sd = findings_data[sys_key]
story.append(sys_section_header(sd["title"], sd["subtitle"], sd["color"]))
for f in sd["findings"]:
name, defn, grades, normal, abnormal, sig = f
story.append(finding_block(sd["color"], name, defn, grades, normal, abnormal, sig))
story.append(PageBreak())
# ── Build PDF ─────────────────────────────────────────────────────────────────
doc.build(story)
print("PDF created successfully!")
cd /tmp/workspace/system-exam-checklist && python3 build_checklist.py 2>&1
ls -lh /tmp/workspace/system-exam-checklist/System_Exam_Checklist.pdf
System Exam Checklist
PDF Document · PDF
| # | System | Color | Findings Covered |
|---|---|---|---|
| 1 | GIT | Green | Pallor, Icterus/Jaundice, Ascites, Hepatomegaly, Splenomegaly, Bowel Sounds |
| 2 | CNS | Purple | Muscle Tone, Muscle Power (MRC), Deep Tendon Reflexes, Plantar Response (Babinski), Cerebellar Signs, Meningeal Signs |
| 3 | Respiratory | Blue | Clubbing, Cyanosis, Chest Expansion & TVF, Breath Sounds & Adventitious Sounds, Tracheal Position, Percussion Note |
| 4 | CVS | Red | JVP, Apex Beat, Heart Sounds (S1-S4), Peripheral Pulses & Character, Parasternal Heave, Cardiac Murmurs |
Make a pdf for the medicine practical exam all the viva questions
cd /tmp/workspace/attachments/e0c8124f-02e9-45d1-9f1c-69440da6b4ba/ && python3 -c " import pdfplumber with pdfplumber.open('PDF (1).pdf') as pdf: print(f'Total pages: {len(pdf.pages)}') for i, page in enumerate(pdf.pages): print(f'=== PAGE {i+1} ===') print(page.extract_text()) print() "
~/system-exam-checklist/build_viva.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
# ── Palette ──────────────────────────────────────────────────────────────────
GIT_C = colors.HexColor("#1A6B3C")
CNS_C = colors.HexColor("#6B3EA6")
RS_C = colors.HexColor("#1565C0")
CVS_C = colors.HexColor("#B71C1C")
HDR_BG = colors.HexColor("#1C2833")
Q_BG = colors.HexColor("#EAF4FB")
A_BG = colors.HexColor("#FDFEFE")
Q_BORDER= colors.HexColor("#2E86C1")
A_BORDER= colors.HexColor("#27AE60")
TIP_BG = colors.HexColor("#FFFDE7")
TIP_BDR = colors.HexColor("#F9A825")
WHITE = colors.white
MID_GRAY= colors.HexColor("#D5D8DC")
PAGE_W, PAGE_H = A4
doc = SimpleDocTemplate(
"/tmp/workspace/system-exam-checklist/Medicine_Viva_Questions.pdf",
pagesize=A4,
rightMargin=1.6*cm,
leftMargin=1.6*cm,
topMargin=2*cm,
bottomMargin=2*cm,
title="Medicine Practical Exam - Viva Questions & Answers",
author="Clinical Reference"
)
styles = getSampleStyleSheet()
def S(name, parent='Normal', **kw):
return ParagraphStyle(name, parent=styles[parent], **kw)
cover_title = S('CT', fontSize=24, leading=30, textColor=WHITE,
alignment=TA_CENTER, fontName='Helvetica-Bold')
cover_sub = S('CS', fontSize=11, leading=16, textColor=colors.HexColor("#BDC3C7"),
alignment=TA_CENTER, fontName='Helvetica')
sys_hdr_sty = S('SH', fontSize=14, leading=18, textColor=WHITE,
fontName='Helvetica-Bold', alignment=TA_CENTER)
sec_sty = S('SEC', fontSize=11, leading=14, textColor=WHITE,
fontName='Helvetica-Bold')
q_num_sty = S('QN', fontSize=9, leading=12, textColor=colors.HexColor("#1A5276"),
fontName='Helvetica-Bold')
q_sty = S('QQ', fontSize=9, leading=13, textColor=colors.HexColor("#1A1A2E"),
fontName='Helvetica-Bold')
a_sty = S('AA', fontSize=8.5, leading=12.5, textColor=colors.HexColor("#1A1A1A"),
fontName='Helvetica')
tip_sty = S('TIP', fontSize=8, leading=11, textColor=colors.HexColor("#6D4C00"),
fontName='Helvetica-Oblique')
bullet_sty = S('BUL', fontSize=8.5, leading=12, textColor=colors.HexColor("#1A1A1A"),
fontName='Helvetica', leftIndent=10)
def b(items):
return "\n".join(f"• {i}" for i in items)
# ── QA block ─────────────────────────────────────────────────────────────────
def qa(number, question, answer_items, tip=None, sys_color=None):
"""Renders a single Q&A block."""
color = sys_color or Q_BORDER
q_data = [[
Paragraph(f"Q{number}.", q_num_sty),
Paragraph(question, q_sty)
]]
q_t = Table(q_data, colWidths=[1*cm, 15.3*cm])
q_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), Q_BG),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('LEFTPADDING', (0,0), (0,0), 6),
('LEFTPADDING', (1,0), (1,0), 2),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LINEABOVE', (0,0), (-1,0), 1.2, color),
('LINEBELOW', (0,0), (-1,-1), 0.3, MID_GRAY),
]))
ans_rows = [[Paragraph("Ans:", S('ANSL', fontSize=8, fontName='Helvetica-Bold',
textColor=colors.HexColor("#1E8449"))),
Paragraph(b(answer_items), a_sty)]]
a_t = Table(ans_rows, colWidths=[1*cm, 15.3*cm])
a_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), A_BG),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('LEFTPADDING', (0,0), (0,0), 6),
('LEFTPADDING', (1,0), (1,0), 2),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LINEBELOW', (0,0), (-1,-1), 0.5, colors.HexColor("#A9DFBF")),
]))
parts = [q_t, a_t]
if tip:
tip_t = Table([[Paragraph(f"★ Examiner tip: {tip}", tip_sty)]],
colWidths=[16.3*cm])
tip_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), TIP_BG),
('BOX', (0,0), (-1,-1), 0.5, TIP_BDR),
('LEFTPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
]))
parts.append(tip_t)
parts.append(Spacer(1, 5))
return KeepTogether(parts)
# ── Section header ────────────────────────────────────────────────────────────
def sec_header(text, color):
t = Table([[Paragraph(text, sec_sty)]], colWidths=[16.3*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), color),
('LEFTPADDING', (0,0), (-1,-1), 10),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('ROUNDEDCORNERS', [4, 4, 4, 4]),
]))
return KeepTogether([t, Spacer(1, 6)])
def sys_header(title, subtitle, color):
t = Table([
[Paragraph(title, sys_hdr_sty)],
[Paragraph(subtitle, S('SSUB', fontSize=9, textColor=colors.HexColor("#BDC3C7"),
alignment=TA_CENTER, fontName='Helvetica'))]
], colWidths=[16.3*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), color),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
('LEFTPADDING', (0,0), (-1,-1), 10),
('ROUNDEDCORNERS', [6, 6, 6, 6]),
]))
return KeepTogether([t, Spacer(1, 8)])
# ═══════════════════════════════════════════════════════════════════════════════
# VIVA DATA
# ═══════════════════════════════════════════════════════════════════════════════
story = []
# ── COVER ────────────────────────────────────────────────────────────────────
cov = Table([
[Paragraph("MEDICINE PRACTICAL EXAM", cover_title)],
[Paragraph("Viva Questions & Answers", S('CS2', fontSize=14, leading=18, textColor=colors.HexColor("#F39C12"),
alignment=TA_CENTER, fontName='Helvetica-Bold'))],
[Spacer(1,6)],
[Paragraph("GIT • CNS • RESPIRATORY • CARDIOVASCULAR", cover_sub)],
[Spacer(1,4)],
[Paragraph("Based on the 4-System Case Proforma", S('CSD', fontSize=9,
textColor=colors.HexColor("#7F8C8D"), alignment=TA_CENTER, fontName='Helvetica-Oblique'))],
], colWidths=[16.3*cm])
cov.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), HDR_BG),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
('LEFTPADDING', (0,0), (-1,-1), 12),
('ROUNDEDCORNERS', [8, 8, 8, 8]),
]))
story.append(Spacer(1, 40))
story.append(cov)
story.append(Spacer(1, 16))
how = Table([[Paragraph(
"<b>How to use:</b> Cover the answer and attempt each question before revealing. "
"Examiner tips (★) highlight what examiners specifically probe in viva. "
"Questions are grouped by section matching your proforma.",
S('HW', fontSize=8.5, textColor=colors.HexColor("#1A252F"), fontName='Helvetica')
)]], colWidths=[16.3*cm])
how.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor("#EBF5FB")),
('BOX', (0,0), (-1,-1), 1, Q_BORDER),
('LEFTPADDING', (0,0), (-1,-1), 10),
('RIGHTPADDING', (0,0), (-1,-1), 10),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
('ROUNDEDCORNERS', [4, 4, 4, 4]),
]))
story.append(how)
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# SYSTEM 1 — GIT
# ═══════════════════════════════════════════════════════════════════════════════
story.append(sys_header("SYSTEM 1: GASTROINTESTINAL SYSTEM",
"GIT Viva Questions — History, Examination & Diagnosis", GIT_C))
story.append(sec_header("A. HISTORY-TAKING VIVA", GIT_C))
q = 1
story.append(qa(q, "How do you characterise abdominal pain in history-taking?",
["Site, onset (sudden/gradual), duration, character (colicky/burning/dull/stabbing)",
"Radiation (to back - pancreatitis; to shoulder - hepatobiliary)",
"Severity (scale 1-10), aggravating and relieving factors",
"Association with meals, defaecation, posture",
"Associated symptoms: vomiting, fever, jaundice, weight loss"],
"Examiners often ask 'what is the difference between colicky pain and continuous pain?' — Colicky = intermittent visceral (bowel, ureter); Continuous = peritoneal/somatic inflammation", GIT_C)); q+=1
story.append(qa(q, "How do you take a history of jaundice? What are the three types?",
["Duration, onset (sudden/insidious), progression (deepening/fluctuating/static)",
"Pre-hepatic (haemolytic): pallor, dark urine, family history, NO pale stools",
"Hepatic (hepatocellular): prodrome, alcohol use, drug history, risk of viral hepatitis",
"Post-hepatic (obstructive/cholestatic): pale clay stools, dark urine, pruritus, RHC pain",
"Associated: fever, chills (cholangitis = Charcot's triad), weight loss (malignancy)"],
"Always ask for urine and stool colour — this distinguishes pre-hepatic from obstructive jaundice instantly", GIT_C)); q+=1
story.append(qa(q, "What is the difference between haematemesis and melaena? How do you differentiate from haemoptysis?",
["Haematemesis: vomiting of blood — bright red (fresh) or coffee-ground (altered), mixed with food, pH acidic, preceded by nausea, no cough",
"Melaena: black tarry offensive stools — digested blood from upper GI bleed (>50 mL), source proximal to ligament of Treitz",
"Haematochezia: fresh blood PR — usually lower GI source",
"Haemoptysis: coughed up blood — frothy, bright red, mixed with mucus, alkaline, preceded by cough/chest symptoms",
"Blood >200 mL from stomach may cause both haematemesis AND melaena"],
"Key distinction: haemoptysis is frothy and alkaline; haematemesis is coffee-ground and acidic", GIT_C)); q+=1
story.append(qa(q, "What is dysphagia? How do you differentiate oropharyngeal from oesophageal dysphagia?",
["Dysphagia: difficulty in swallowing food/liquids",
"Oropharyngeal (transfer) dysphagia: difficulty initiating swallow, nasal regurgitation, choking — neuromuscular cause (stroke, MND, myasthenia)",
"Oesophageal dysphagia: food sticks after swallowing is initiated",
"Solids only first → progressing to liquids: mechanical obstruction (carcinoma, stricture, external compression)",
"Solids AND liquids from onset: motility disorder (achalasia, diffuse oesophageal spasm)",
"Intermittent dysphagia with solids only: benign — Schatzki ring, web"],
"Progressive dysphagia solids → liquids with weight loss = carcinoma oesophagus until proven otherwise", GIT_C)); q+=1
story.append(qa(q, "What is the CAGE questionnaire for alcohol? How do you calculate pack-year history?",
["CAGE (Alcohol screening): Cut down? / Annoyed by criticism? / Guilty about drinking? / Eye-opener drink in morning?",
"2 or more 'yes' answers = likely alcohol dependence",
"Pack-years (smoking) = Number of packs per day × Number of years smoked",
"Smoking Index (bidis/cigarettes) = Number per day × Number of years",
"Always quantify alcohol in units/day (1 unit = 10 mL pure ethanol; 1 peg whisky ≈ 1.5 units)"],
"CAGE score of 2+ is 93% sensitive, 76% specific for alcohol use disorder", GIT_C)); q+=1
story.append(sec_header("B. GENERAL EXAMINATION — GIT", GIT_C))
story.append(qa(q, "What are the signs of chronic liver disease/liver failure that you look for on general examination?",
["Skin: jaundice, spider naevi (>5 = significant), palmar erythema, Dupuytren's contracture, leukonychia (white nails), Terry's nails",
"Endocrine: gynaecomastia (anti-oestrogen), testicular atrophy, loss of axillary/pubic hair, alopecia",
"Parotid gland enlargement (alcoholic liver disease)",
"Eyes: icterus, Kayser-Fleischer rings (Wilson's disease — look for by slit lamp)",
"Hands: clubbing (cirrhosis), flapping tremors (asterixis — hepatic encephalopathy), muscle wasting",
"Abdomen: caput medusae, ascites, splenomegaly"],
"Spider naevi are in the SVC territory (face, neck, upper chest, arms). Press the centre — they blanch and refill from centre outwards", GIT_C)); q+=1
story.append(qa(q, "What are the external markers of HIV infection you check?",
["Oral hairy leukoplakia (white plaques on lateral tongue — cannot be scraped off; EBV related)",
"Oral candidiasis (white plaques, easily scraped — Candida albicans)",
"Molluscum contagiosum: umbilicated papules on face",
"Generalised lymphadenopathy: bilateral, non-tender, rubbery",
"Recurrent herpetic infections: oro-labial herpes simplex, herpes zoster in young patients",
"Kaposi's sarcoma: purple/brown skin plaques",
"Skin: seborrhoeic dermatitis, prurigo"],
"Oral candidiasis in a young patient without antibiotics or steroids = immunocompromise until proven otherwise", GIT_C)); q+=1
story.append(sec_header("C. ABDOMINAL EXAMINATION VIVA", GIT_C))
story.append(qa(q, "What is the normal shape of the abdomen? What does each abnormal shape suggest?",
["Normal: scaphoid (slightly concave) or flat in adults",
"Distended uniform: ascites, gaseous distension, obesity, intestinal obstruction",
"Distended localised: organomegaly, cyst, tumour",
"Full flanks: ascites",
"Scaphoid/boat-shaped (very concave): cachexia, tuberculosis, dehydration",
"Pendulous abdomen: obesity, lax muscles in multiparous women"],
"A scaphoid abdomen with visible peristalsis and hyperactive bowel sounds = pyloric stenosis or high obstruction", GIT_C)); q+=1
story.append(qa(q, "How do you elicit shifting dullness? What does it indicate?",
["Patient supine. Percuss from umbilicus laterally until dullness is found",
"Mark the dull-resonant border. Ask patient to turn onto their side (45°)",
"Wait 30 seconds. Percuss again — previously dull area becomes resonant",
"Positive shifting dullness = ascites (>500 mL of free fluid)",
"Fluid thrill (for massive ascites >1L): one hand on one flank, assistant places edge of hand on midline (to block fat transmission), tap the other flank — fluid wave felt by receiving hand",
"False positive shifting dullness: large ovarian cyst (dullness does NOT shift)"],
"Shifting dullness detects ascites more reliably than fluid thrill. Fluid thrill only positive in tense ascites", GIT_C)); q+=1
story.append(qa(q, "How do you examine for hepatomegaly? How do you differentiate it from other RHC masses?",
["Start palpation from RIF, work superiorly toward right costal margin",
"Ask patient to breathe deeply — liver moves DOWN with inspiration",
"Feel for lower border: sharp or round edge, smooth or nodular surface",
"Percussion: confirm upper border at 5th ICS (RMC line), measure liver span",
"Liver span >12 cm = hepatomegaly",
"Characteristics: cannot get above it, moves with respiration, resonant on percussion (unless very large), dull to percussion over it",
"Pulsatile liver = tricuspid regurgitation",
"Differentiate from kidney: kidney is ballotable, has resonant band over it (colonic), bimanually palpable"],
"Examiners ask: 'What is the significance of a nodular liver edge?' — Cirrhosis or hepatic metastases", GIT_C)); q+=1
story.append(qa(q, "What are the features of splenomegaly on examination? How do you differentiate spleen from kidney?",
["Spleen enlarges toward RIGHT iliac fossa (not down)",
"Has a notch on its medial (inferomedial) border",
"Cannot insinuate fingers between spleen and left costal margin (not bimanually palpable)",
"Moves with respiration (diagonally, toward RIF)",
"Resonant band of colonic gas NOT present (unlike kidney)",
"Traube's space (left 6th–10th rib, MCL) — dull = splenomegaly",
"Kidney: ballotable, bimanually palpable, resonant band of colon over it, moves vertically",
"Renal angle palpation positive for kidney"],
"Nixon's method: patient right lateral, percuss from midpoint of left costal margin downward — dullness >8 cm = splenomegaly", GIT_C)); q+=1
story.append(qa(q, "What are the causes of massive splenomegaly (spleen crosses the midline)?",
["Tropical causes (most common in India): Kala-azar (Visceral leishmaniasis), Hyperreactive malarial splenomegaly (Big Spleen Disease)",
"Haematological: Chronic Myeloid Leukaemia (CML) — most common haematological cause, Myelofibrosis",
"Gaucher's disease (lipid storage disorder)",
"Thalassaemia major",
"Remember mnemonic: CATCH — CML/CLL, All haemolytic, Thalassaemia, Congestion (portal hypertension is usually moderate), Hyperreactive malaria/Kala-azar"],
"CML is the commonest haematological cause of massive splenomegaly. Check for sternal tenderness (BCR-ABL positive)", GIT_C)); q+=1
story.append(qa(q, "What are the causes of portal hypertension? What is SAAG?",
["Portal hypertension: portal vein pressure >10 mmHg (normal 5-10 mmHg)",
"Pre-hepatic: portal vein thrombosis, splenic vein thrombosis",
"Hepatic (sinusoidal): cirrhosis (commonest), alcoholic hepatitis, schistosomiasis",
"Post-hepatic: Budd-Chiari syndrome (hepatic vein thrombosis), constrictive pericarditis, right heart failure",
"SAAG (Serum-Ascites Albumin Gradient) = Serum albumin − Ascites albumin",
"SAAG ≥1.1 g/dL = Portal hypertension (cirrhosis, CCF, Budd-Chiari)",
"SAAG <1.1 g/dL = Non-portal hypertension (TB peritonitis, malignant ascites, nephrotic syndrome)"],
"SAAG replaces the old exudate/transudate classification for ascites. Always remember the cutoff: 1.1 g/dL", GIT_C)); q+=1
story.append(qa(q, "What is Courvoisier's law? When does it apply?",
["Courvoisier's law: In the presence of jaundice, if the gallbladder is palpable and non-tender, the cause is unlikely to be gallstones",
"Palpable + non-tender GB = carcinoma head of pancreas / cholangiocarcinoma / periampullary carcinoma",
"Gallstones cause chronic inflammation → fibrotic, shrunken, non-distensible gallbladder → NOT palpable even when blocked",
"Exceptions (law not applicable): double impaction, Mirizzi syndrome, cholangiocarcinoma on top of stones",
"Murphy's sign: tender at gallbladder fossa on deep inspiration (acute cholecystitis)"],
"Classic exam question: 'Painless progressive jaundice + palpable GB' = carcinoma head of pancreas (Courvoisier's sign)", GIT_C)); q+=1
story.append(qa(q, "What are the clinical features of peritonitis? How do you elicit rebound tenderness?",
["Symptoms: sudden severe diffuse abdominal pain, nausea, vomiting, fever, inability to move",
"Signs on inspection: rigid board-like abdomen, reduced/absent respiratory movements of abdomen",
"Guarding: voluntary contraction of abdominal muscles on palpation",
"Rigidity: involuntary (reflex) board-like hardness — indicates peritoneal inflammation",
"Rebound tenderness (Blumberg's sign): press slowly and deeply, then release suddenly — pain worse on release",
"Bowel sounds: absent (paralytic ileus secondary to peritonitis)",
"Tenderness in right iliac fossa + rebound = appendicitis (McBurney's point tender)"],
"Rebound tenderness should be elicited gently (or by percussion) — examiner may ask you to demonstrate without causing unnecessary pain", GIT_C)); q+=1
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# SYSTEM 2 — CNS
# ═══════════════════════════════════════════════════════════════════════════════
story.append(sys_header("SYSTEM 2: CENTRAL NERVOUS SYSTEM",
"CNS Viva Questions — History, Examination & Neurological Assessment", CNS_C))
story.append(sec_header("A. HISTORY-TAKING — CNS", CNS_C))
q = 1
story.append(qa(q, "How do you classify weakness (paresis/plegia) based on the area involved?",
["Monoplegia: one limb only",
"Hemiplegia: upper + lower limb on same side (lesion in contralateral hemisphere/internal capsule/brainstem)",
"Paraplegia: both lower limbs (spinal cord thoracic or below, or bilateral cortex)",
"Quadriplegia/tetraplegia: all four limbs (cervical cord lesion, bilateral cortex, brainstem)",
"Diplegia: bilateral but legs > arms (cerebral palsy)",
"Ask about: onset (sudden = vascular, gradual = tumour/demyelination), progression (stepwise = lacunar, waxing-waning = MS), recovery"],
"A pure motor hemiplegia (face + arm + leg, no cortical signs) = internal capsule lacunar infarct", CNS_C)); q+=1
story.append(qa(q, "What is the difference between UMN and LMN lesion?",
["UMN lesion (above anterior horn cell): Increased tone (spasticity), increased reflexes, extensor plantar (Babinski +), NO fasciculations, NO significant wasting, weakness in pyramidal pattern (extensors weak in UL, flexors weak in LL)",
"LMN lesion (anterior horn cell, nerve root, peripheral nerve, NMJ, muscle): Decreased tone (flaccidity), decreased/absent reflexes, flexor plantar, fasciculations, significant wasting/atrophy",
"UMN signs: clasp-knife spasticity, clonus, Babinski positive",
"LMN signs: hypotonia, areflexia, fasciculations, wasting",
"Mixed UMN + LMN: Motor Neuron Disease (ALS/ALS spectrum)"],
"Most important viva question in CNS: 'What is your localization?' — always state UMN/LMN, then segment/level", CNS_C)); q+=1
story.append(qa(q, "How do you assess sensory disturbance? What are the types of sensory loss patterns?",
["Glove and stocking (distal symmetric): peripheral neuropathy (DM, alcohol, B12 deficiency)",
"Hemi-anaesthesia (one half of body): thalamic or cortical lesion — contralateral to side of lesion",
"Dissociated sensory loss (pain/temp lost, vibration/JPS intact): syringomyelia (central cord)",
"Dermatomal (root pain): radiculopathy — ask for band-like sensation, dermatomal distribution",
"Brown-Séquard syndrome: ipsilateral loss of vibration/JPS + contralateral loss of pain/temperature",
"Sensory level on trunk: spinal cord lesion",
"Wash-basin attacks (lhermitte's): electric shock sensation down spine on neck flexion = cervical cord demyelination (MS)"],
"Ask patient: 'Does sensation feel the same on both sides?' Use a pin/cotton on identical areas bilaterally and ask the patient to compare", CNS_C)); q+=1
story.append(qa(q, "What are the cerebellar symptoms a patient complains of?",
["Difficulty taking food to mouth (intention tremor worsens near target)",
"Difficulty buttoning (dysmetria, limb ataxia)",
"Swaying while walking / reeling sensation (gait ataxia)",
"Slurred speech (scanning speech — each syllable equal stress)",
"Blurring of vision that is worse with eye movement (nystagmus)",
"Apraxia (dyspraxia): inability to perform purposeful movements despite intact power and sensation",
"Titubation: head/trunk oscillation at rest"],
"Cerebellar signs are IPSILATERAL to the lesion — unlike cortical lesions which cause contralateral deficits", CNS_C)); q+=1
story.append(sec_header("B. HIGHER MENTAL FUNCTIONS & CRANIAL NERVES", CNS_C))
story.append(qa(q, "How do you assess higher mental functions (HMF) in a CNS examination?",
["Consciousness: GCS (Eye 4 + Verbal 5 + Motor 6 = 15), AVPU scale",
"Orientation: Time (day/date/month/year) / Place (where are you?) / Person (who is the examiner?)",
"Memory: Immediate (digit span forward/backward), Recent (what did you eat for breakfast?), Remote (past events — childhood, marriage)",
"Attention/Concentration: serial 7s, spell WORLD backward",
"Language/Speech: Fluency / Comprehension / Naming / Repetition / Writing / Reading",
"Calculation: 100-7 serially",
"Praxis: demonstrate how to comb hair, brush teeth",
"Gnosis: identify objects by touch (stereognosis)"],
"Dominant hemisphere (usually left): Broca's area (frontal) = non-fluent aphasia; Wernicke's area (temporal) = fluent aphasia with poor comprehension", CNS_C)); q+=1
story.append(qa(q, "How do you examine the optic nerve (2nd CN)? What are the visual field defects?",
["Visual acuity: Snellen chart (distant), near vision chart (near) — each eye separately",
"Colour vision: Ishihara plates (optic neuritis causes red desaturation early)",
"Visual fields by confrontation: sit opposite patient, cover one eye each, bring finger from periphery",
"Fundoscopy: disc (colour, margins, cup-disc ratio), vessels (A:V ratio), macula, retina",
"Visual field defects: Monocular blindness = ipsilateral optic nerve; Bitemporal hemianopia = optic chiasm (pituitary tumour); Homonymous hemianopia = optic tract/radiation/cortex; Homonymous quadrantanopia — upper quadrant (temporal lobe = Meyer's loop); lower quadrant (parietal lobe)"],
"Papilloedema = bilateral disc swelling, loss of venous pulsations, blurred margins — indicates raised ICP (examine fundus in every CNS case)", CNS_C)); q+=1
story.append(qa(q, "How do you test the 7th (facial) nerve? How do you differentiate UMN from LMN facial palsy?",
["Upper face: Ask patient to raise eyebrows, wrinkle forehead, close eyes tightly",
"Lower face: puff cheeks, show teeth, whistle",
"Taste: anterior 2/3 of tongue (chorda tympani — branch of facial nerve)",
"UMN facial palsy: forehead SPARED (bilateral cortical representation of upper face) — only lower face drooping; caused by stroke, tumour",
"LMN facial palsy (Bell's palsy): forehead INVOLVED — cannot close eye, complete ipsilateral facial weakness; involves entire half of face",
"Bell's phenomenon: when trying to close eye in LMN palsy, eyeball rolls upward (normal protective reflex)"],
"Key exam: 'In forehead sparing — it is UMN; in forehead involvement — it is LMN.' Ask to wrinkle the forehead first!", CNS_C)); q+=1
story.append(qa(q, "What is Rinne's test and Weber's test? How do you interpret them?",
["Rinne's test: Vibrating 512 Hz tuning fork on mastoid (bone conduction) then near ear (air conduction)",
"Rinne positive (normal): Air > Bone conduction",
"Rinne negative (abnormal): Bone > Air = Conductive hearing loss",
"Weber's test: Vibrating fork on vertex/forehead midline — ask where sound is louder",
"Weber central (equal): Normal OR bilateral symmetrical hearing loss",
"Weber lateralises to AFFECTED ear: Conductive hearing loss (ipsilateral)",
"Weber lateralises to NORMAL (BETTER) ear: Sensorineural hearing loss",
"Absolute bone conduction (ABC) test: patient's bone conduction compared to examiner's (with normal hearing)"],
"Mnemonic: SNAD — Sensorineural = Weber to Normal side, Air conduction lost; DULL Bone lateralises in Conductive", CNS_C)); q+=1
story.append(sec_header("C. MOTOR SYSTEM & REFLEXES", CNS_C))
story.append(qa(q, "How do you assess muscle power? What is the MRC grade scale?",
["Grade 0: No muscle contraction visible",
"Grade 1: Flicker / trace of contraction only",
"Grade 2: Full ROM with gravity eliminated (limb moves horizontally)",
"Grade 3: Full ROM against gravity but no resistance",
"Grade 4: Movement against gravity with some resistance (subdivide 4-, 4, 4+)",
"Grade 5: Normal power against full resistance",
"Test systematically: proximal (shoulder abduction, hip flexion) then distal (grip, ankle dorsiflexion)",
"Proximal weakness: myopathy, polymyositis, Cushing's syndrome, osteomalacia",
"Distal weakness: peripheral neuropathy, Charcot-Marie-Tooth"],
"Always compare both sides. Functional/psychogenic weakness: variable, give-way weakness, normal tone and reflexes", CNS_C)); q+=1
story.append(qa(q, "What are the deep tendon reflexes and their cord levels?",
["Jaw jerk: V (trigeminal) — brisk jaw jerk = bilateral UMN above pons",
"Biceps jerk: C5, C6 (musculocutaneous nerve)",
"Supinator jerk: C5, C6 (radial nerve)",
"Triceps jerk: C7, C8 (radial nerve)",
"Knee jerk (patellar): L2, L3, L4 (femoral nerve)",
"Ankle jerk (Achilles): S1, S2 (sciatic/tibial nerve)",
"Grading: 0 (absent), 1+ (diminished), 2+ (normal), 3+ (brisk), 4+ (clonus)",
"Inverted reflexes: suggest cord lesion at that level (e.g., absent biceps + brisk triceps = C5/C6 lesion)"],
"Pendular reflexes (swing back and forth multiple times) = cerebellar disease — loss of damping", CNS_C)); q+=1
story.append(qa(q, "What is Babinski's sign? How is it elicited? What does it indicate?",
["Elicited by: firmly stroking the outer (lateral) border of the sole from heel to ball of the foot with a blunt object",
"Normal (negative): plantar flexion (downward curling) of all toes",
"Positive Babinski: dorsiflexion (extension) of great toe ± fanning (abduction) of other toes",
"Indicates: UMN (corticospinal tract) lesion — ALWAYS pathological in adults",
"Normal in infants <18 months (incomplete myelination of pyramidal tracts)",
"Equivalent tests: Chaddock (stroke lateral malleolus), Oppenheim (stroke tibial crest), Gordon (squeeze calf)"],
"Important: 'Upgoing plantar' = Babinski positive = corticospinal tract lesion. Ipsilateral to the side of the response, contralateral to the lesion", CNS_C)); q+=1
story.append(sec_header("D. COORDINATION, GAIT & MENINGEAL SIGNS", CNS_C))
story.append(qa(q, "What is the DANISH mnemonic for cerebellar signs?",
["D — Dysdiadochokinesia (inability to perform rapid alternating movements, e.g., pronation-supination)",
"A — Ataxia of gait (wide-based, staggering, cerebellar gait — does NOT worsen in dark unlike sensory ataxia)",
"N — Nystagmus (fast phase to side of lesion, most prominent on lateral gaze toward lesion)",
"I — Intention tremor (FNF test — tremor worsens near target, unlike resting tremor of Parkinsonism)",
"S — Scanning (staccato) speech (dysarthria — each syllable equally stressed, explosive)",
"H — Hypotonia (decreased tone on same side as lesion)",
"Additional: Rebound phenomenon, Titubation, Past-pointing"],
"All cerebellar signs are ipsilateral to the lesion (unlike cortical lesions). This is because cerebellar pathways cross twice", CNS_C)); q+=1
story.append(qa(q, "What is the difference between cerebellar ataxia and sensory (posterior column) ataxia?",
["Cerebellar ataxia: Wide-based gait, titubation, nystagmus, intention tremor, dysdiadochokinesia, scanning speech; Romberg's test NEGATIVE (ataxia present with eyes OPEN too)",
"Sensory/posterior column ataxia: Stamping gait (feet slap ground to feel position); Romberg's test POSITIVE (stable with eyes open, falls with eyes closed); Loss of vibration and joint position sense",
"Romberg's test: stand feet together, arms by side. Close eyes. Positive = significant sway/fall on eye closure",
"Vestibular ataxia: similar to cerebellar but with vertigo, nausea, vomiting"],
"Romberg positive = posterior column disease (B12 deficiency, tabes dorsalis, Friedreich's ataxia, MS). Romberg negative with ataxia = cerebellar", CNS_C)); q+=1
story.append(qa(q, "What are meningeal signs? How do you elicit Kernig's and Brudzinski's signs?",
["Neck stiffness: involuntary resistance to passive neck flexion — cannot touch chin to chest",
"Kernig's sign: Patient supine, flex hip to 90°, then try to extend the knee — positive if >135° causes pain/spasm in hamstrings",
"Brudzinski's sign: Passive neck flexion → causes involuntary bilateral hip and knee flexion",
"Jolt accentuation: rotate head horizontally 2-3x/sec — headache worsens = meningeal irritation (sensitive for meningitis)",
"Causes: bacterial meningitis, viral meningitis, subarachnoid haemorrhage (SAH), tuberculous meningitis",
"SAH: sudden 'thunderclap' headache, worst of life, neck stiffness, CT head may be normal in 15% → LP"],
"Meningism without fever: think SAH. With fever: think meningitis. Perform fundoscopy first — if papilloedema → DO NOT do LP (risk of herniation)", CNS_C)); q+=1
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# SYSTEM 3 — RESPIRATORY
# ═══════════════════════════════════════════════════════════════════════════════
story.append(sys_header("SYSTEM 3: RESPIRATORY SYSTEM",
"Respiratory Viva Questions — History, Examination & Diagnosis", RS_C))
story.append(sec_header("A. HISTORY-TAKING — RS", RS_C))
q = 1
story.append(qa(q, "How do you characterise a cough in history-taking?",
["Duration, onset, progression; dry vs productive",
"If productive — sputum quantity (in mL/24 hrs), colour (white = viral/bronchitis; yellow/green = bacterial; rust-coloured = pneumococcal pneumonia; pink frothy = pulmonary oedema; black = coal workers)",
"Blood-stained sputum vs haemoptysis",
"Timing: morning (COPD, bronchiectasis), nocturnal (asthma, GERD, cardiac failure)",
"Diurnal/postural variation: worse lying down = post-nasal drip, GERD; better on lying on one side = unilateral lung disease",
"Aggravating factors: cold air, exercise, allergens (asthma); dust (COPD)",
"Associated: wheeze, dyspnoea, fever, weight loss, haemoptysis"],
"3 hallmarks of bronchiectasis: chronic productive cough (>3 tablespoons/day), postural variation, finger clubbing", RS_C)); q+=1
story.append(qa(q, "How do you classify breathlessness using NYHA and MRC scales?",
["NYHA (New York Heart Association) — cardiac dyspnoea:",
"Class I: No limitation, ordinary activity does not cause symptoms",
"Class II: Slight limitation — comfortable at rest, symptoms on ordinary activity",
"Class III: Marked limitation — comfortable at rest, symptoms on less-than-ordinary activity",
"Class IV: Unable to carry on any activity without discomfort; symptoms at rest",
"MRC (Medical Research Council) Dyspnoea Scale — respiratory dyspnoea:",
"Grade 1: Only on strenuous exercise; Grade 2: Hurrying on level or slight hill; Grade 3: Slower than peers on level; Grade 4: Stops after 100 metres; Grade 5: Too breathless to leave house"],
"Use NYHA for cardiac causes and MRC for respiratory (COPD) assessment. Both are examiners' favourites", RS_C)); q+=1
story.append(qa(q, "What is the occupational history relevant in respiratory diseases?",
["Mining/quarrying (silica dust): silicosis — bilateral upper zone nodular fibrosis",
"Coal mining: coal workers' pneumoconiosis (progressive massive fibrosis)",
"Asbestos exposure (lagging, shipbuilding): asbestosis (basal fibrosis), mesothelioma, pleural plaques",
"Animal husbandry/farming: Farmer's lung (extrinsic allergic alveolitis — thermophilic actinomycetes)",
"Pigeon/bird breeders: Bird fancier's lung (EAA)",
"Textile workers/cotton: Byssinosis",
"Welding fumes, spray painting: occupational asthma"],
"Always ask occupation in chronic respiratory disease — dust exposure history is frequently tested in viva", RS_C)); q+=1
story.append(sec_header("B. EXAMINATION — INSPECTION, PALPATION, PERCUSSION, AUSCULTATION", RS_C))
story.append(qa(q, "What chest shapes do you look for on inspection? What does each suggest?",
["Normal: Anteroposterior:Transverse diameter = 1:2",
"Barrel chest (AP = Transverse, AP:T = 1:1): COPD/emphysema, ageing",
"Pigeon chest (pectus carinatum): childhood respiratory illness, rickets, Marfan syndrome",
"Funnel chest (pectus excavatum): Marfan, congenital; may compress heart",
"Harrison's sulcus: bilateral horizontal groove at level of diaphragm — rickets, chronic asthma in childhood",
"Kyphosis/scoliosis: reduces lung volume, causes restrictive defect",
"Flail chest: paradoxical movement (sucked in on inspiration) — multiple rib fractures",
"Flat chest: collapse, fibrosis on that side"],
"Harrison's sulcus = mark of chronic childhood hyperinflation/asthma. If you see it, mention rickets as a cause", RS_C)); q+=1
story.append(qa(q, "What are the causes of tracheal deviation? How do you assess it?",
["Palpate in the suprasternal notch — feel for equal space on both sides",
"Trachea deviated TOWARD the lesion: lung collapse, pulmonary fibrosis (upper lobe), post-pneumonectomy",
"Trachea deviated AWAY from the lesion: large pleural effusion, tension pneumothorax (emergency!)",
"No significant deviation despite effusion: complete bronchial obstruction with simultaneous collapse",
"Tracheal tug (downward movement on inspiration): aortic aneurysm",
"Tracheal deviation = mediastinal shift — always note its direction relative to the abnormal side"],
"Tension pneumothorax: tracheal deviation + absent breath sounds + hypotension + tachycardia = EMERGENCY — decompress immediately", RS_C)); q+=1
story.append(qa(q, "What is Tactile Vocal Fremitus (TVF)? How is it performed?",
["TVF = palpable vibration of chest wall when patient says '99' (or 'one-one-one') — transmitted from larynx through lung",
"Method: place ulnar border of both hands symmetrically on chest wall; compare both sides",
"Increased TVF: consolidation (airless lung transmits vibration better than normal aerated lung)",
"Decreased/absent TVF: pleural effusion (fluid damps vibration), pneumothorax (air gap), pleural thickening, bronchial obstruction (sound cannot reach periphery), emphysema",
"TVF changes correspond to vocal resonance (VR) changes on auscultation",
"Aegophony: bleating, nasal quality of voice above pleural effusion"],
"Consolidation triad: increased TVF + dull percussion + bronchial breathing + bronchophony. Effusion triad: absent TVF + stony dull + absent BS", RS_C)); q+=1
story.append(qa(q, "What are the different percussion notes and their causes?",
["Resonant: normal aerated lung",
"Hyper-resonant (hollow): pneumothorax (most hyper-resonant), emphysema (bilateral)",
"Stony dull (absolute dullness, very flat): pleural effusion — most dull note in clinical practice",
"Dull: consolidation, collapse, pleural thickening, tumour, raised hemidiaphragm",
"Liver dullness: upper border normally at 5th ICS right midclavicular line; loss = pneumoperitoneum or lung hyperinflation",
"Kronig's isthmus: band of resonance over apex between neck and shoulder — obliteration = apical fibrosis (TB, Pancoast)",
"Traube's space: left 6th–10th rib, MCL, AAL — normally tympanic; dull = splenomegaly, left pleural effusion"],
"The word 'stony dull' is used ONLY for pleural effusion. For consolidation use 'dull' or 'impaired resonance'", RS_C)); q+=1
story.append(qa(q, "What are the differences between vesicular and bronchial breathing?",
["Vesicular breath sounds: soft, low-pitched, rustling; inspiration LONGER than expiration (3:1); no pause between phases; heard over normal lung periphery",
"Bronchial breath sounds: loud, high-pitched, blowing/tubular; inspiration = expiration with distinct pause; heard normally over trachea and manubrium",
"Bronchial breathing at periphery indicates: consolidation (direct transmission), cavity, above pleural effusion (Garland's area), large area of fibrosis",
"Bronchovesicular: intermediate — heard over right upper lobe and hilar areas (normal); peripheral = abnormal",
"Diminished breath sounds: effusion, pneumothorax, emphysema, pleural thickening, poor respiratory effort"],
"Bronchial breathing over peripheral lung = ALWAYS pathological. Check for consolidation (fever, dull percussion, increased TVF)", RS_C)); q+=1
story.append(qa(q, "What are crepitations (crackles)? How do you classify them?",
["Crepitations = discontinuous crackling sounds; produced by sudden opening of collapsed alveoli/small airways",
"Fine end-inspiratory crepitations: late inspiratory, high-pitched, bilateral basal — pulmonary oedema (cardiac failure), fibrosing alveolitis (IPF = 'Velcro' crackles, bilateral basal, non-clearing)",
"Medium crepitations: mid-inspiratory — bronchiectasis, resolving pneumonia",
"Coarse crepitations: early inspiratory, low-pitched — COPD, retained secretions; clear with coughing",
"Post-tussive crackles (appear after coughing): tuberculosis (upper zone), bronchiectasis",
"Crepitations in upper zones: TB, post-TB fibrosis, extrinsic allergic alveolitis"],
"IPF: bilateral basal fine crepitations (Velcro crackles) + clubbing + progressive breathlessness in older patient = typical presentation", RS_C)); q+=1
story.append(qa(q, "What is vocal resonance and whispering pectoriloquy?",
["Vocal resonance (VR): auscultate while patient says '99' — increased in consolidation (same as increased TVF), decreased in effusion/pneumothorax",
"Bronchophony: abnormally loud and clear voice transmission (consolidation)",
"Whispering pectoriloquy: whispered '99' heard clearly through stethoscope over consolidated area — sounds like 'one-two-three' clearly",
"Aegophony (egophony): nasal/bleating quality of voice, especially at upper border of pleural effusion; 'eee' sounds like 'aaa'",
"Pleural rub: leathery, creaking sound in both phases (like walking on fresh snow) — pleuritis, PE, parapneumonic"],
"Whispering pectoriloquy is the most specific sign of consolidation — whispered speech is usually inaudible through stethoscope unless lung is solid", RS_C)); q+=1
story.append(qa(q, "What is the complete percussion-auscultation pattern for pleural effusion, pneumothorax, and consolidation?",
["PLEURAL EFFUSION: Trachea deviated AWAY (large) or central; Reduced expansion; TVF ABSENT; Percussion STONY DULL; Breath sounds ABSENT (or bronchial above); VR absent; Aegophony at upper border",
"PNEUMOTHORAX: Trachea deviated AWAY (tension); Reduced expansion; TVF ABSENT; Percussion HYPER-RESONANT; Breath sounds ABSENT; VR absent",
"CONSOLIDATION: Trachea central (or toward lesion if associated collapse); Reduced expansion; TVF INCREASED; Percussion DULL; Bronchial breathing; Crepitations; VR increased; Bronchophony; Whispering pectoriloquy",
"COLLAPSE: Trachea toward lesion; Reduced expansion; TVF ABSENT/reduced; Dull; Absent BS; Silent"],
"These 4 patterns are the most tested in Medicine practical viva. Practice them until automatic!", RS_C)); q+=1
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# SYSTEM 4 — CVS
# ═══════════════════════════════════════════════════════════════════════════════
story.append(sys_header("SYSTEM 4: CARDIOVASCULAR SYSTEM",
"CVS Viva Questions — History, Examination & Cardiac Diagnosis", CVS_C))
story.append(sec_header("A. HISTORY-TAKING — CVS", CVS_C))
q = 1
story.append(qa(q, "How do you characterise chest pain in CVS history?",
["Site: retrosternal (ischaemic); left infra-mammary (musculoskeletal); positional (pericarditis/pleuritis)",
"Radiation: to left arm, jaw, neck (IHD); between scapulae (aortic dissection); shoulder (pericarditis)",
"Character: crushing/heavy/tight (IHD); tearing/ripping (dissection); sharp/pleuritic (pericarditis, PE); burning (oesophageal/GERD)",
"Aggravating: exertion (stable angina), cold, stress; at rest (unstable/NSTEMI)",
"Relieving: GTN relief in <5 min (angina); not relieved by GTN (MI, dissection)",
"Duration: <20 min (angina); >20 min (MI); constant (pericarditis, dissection)",
"Associated: sweating, nausea, vomiting, dyspnoea, palpitations (MI); syncope (AS, HCM)"],
"Levine's sign: patient places clenched fist over sternum to describe pain — highly specific for angina/MI", CVS_C)); q+=1
story.append(qa(q, "What is the Jones criteria for Rheumatic Fever? What is its relevance to CVS?",
["Major criteria (JONES): J — Joints (migratory polyarthritis); O — 'Oh my heart' (carditis); N — Nodules (subcutaneous); E — Erythema marginatum; S — Sydenham's chorea",
"Minor criteria: fever, elevated ESR/CRP, prolonged PR interval, previous rheumatic fever/RHD",
"Diagnosis: 2 major OR 1 major + 2 minor criteria + evidence of prior streptococcal infection (raised ASOT, throat culture)",
"Relevance: rheumatic fever → rheumatic carditis → mitral stenosis (commonest valvular lesion in India)",
"Prevention: monthly benzathine penicillin G (secondary prophylaxis) for 10 years or until 25 years (longer if carditis)"],
"Mitral stenosis is the most common long-term complication of rheumatic fever — always ask about childhood sore throats and fleeting joint pains", CVS_C)); q+=1
story.append(qa(q, "What are the Osler-Weber-Rendu signs of Infective Endocarditis?",
["Osler's nodes: painful, tender, red nodules on finger/toe pulps — immune complex deposition",
"Janeway lesions: non-tender, flat, erythematous macules/papules on palms and soles — septic emboli",
"Roth spots: oval retinal haemorrhages with pale centres — immune complex retinal vasculitis",
"Splinter haemorrhages: linear haemorrhages under nails (middle third = IE; distal = trauma)",
"Other findings: fever (most common), new regurgitant murmur, splenomegaly, haematuria, clubbing, anaemia",
"Duke's criteria: 2 major OR 1 major + 3 minor OR 5 minor",
"Major Duke's criteria: positive blood cultures (×2), echocardiographic evidence (vegetation/abscess/new dehiscence/new regurgitation)"],
"Osler's nodes = PAINFUL (immune), Janeway lesions = PAINLESS (embolic). Mnemonic: Osler = Ouch (painful)", CVS_C)); q+=1
story.append(sec_header("B. JVP, PULSE & VITAL SIGNS", CVS_C))
story.append(qa(q, "How do you measure JVP? What are the normal waveforms?",
["Patient at 45° head elevation. Look at the internal jugular vein (medial to SCM) — NOT external jugular",
"Measure vertical height of JVP above sternal angle (Lewis method) — normal: 1-3 cm above sternal angle",
"JVP is pulsatile (distinguishes from arterial pulsation — press at base, JVP disappears; arterial does not)",
"Normal waveforms: a-wave (atrial systole), c-wave (tricuspid closure), x-descent (atrial relaxation + RV contraction), v-wave (venous filling with closed tricuspid), y-descent (tricuspid opening)",
"Absent 'a' wave: atrial fibrillation (no atrial contraction)",
"Giant 'a' waves: tricuspid stenosis, pulmonary hypertension, complete heart block",
"Prominent 'v' waves: tricuspid regurgitation (systolic pulsation of neck veins)",
"Kussmaul's sign: paradoxical RISE in JVP on inspiration — constrictive pericarditis, RV infarction, tamponade"],
"JVP is VENOUS — falls on inspiration (negative intrathoracic pressure sucks blood into RA). Kussmaul's = opposite = pathological", CVS_C)); q+=1
story.append(qa(q, "What is a collapsing (water-hammer) pulse? How do you elicit it?",
["Collapsing pulse: rapid upstroke followed by rapid collapse — caused by wide pulse pressure",
"Method: grasp patient's wrist firmly, raise arm above heart level — you feel the sharp knock",
"Cause: aortic regurgitation (most classic), patent ductus arteriosus, severe anaemia, thyrotoxicosis, arteriovenous fistula, pregnancy",
"Other signs of severe AR: Corrigan's sign (visible carotid pulsation), de Musset's sign (head nodding), Quincke's sign (capillary pulsation in nail bed), Duroziez's murmur (to and fro femoral artery murmur), Hill's sign (popliteal SBP > brachial SBP by >20 mmHg = severe AR)"],
"Raise the arm to detect collapsing pulse — gravity makes the diastolic collapse more pronounced and the knock more palpable", CVS_C)); q+=1
story.append(qa(q, "What is pulsus paradoxus? How do you measure it?",
["Definition: exaggerated fall in systolic BP >10 mmHg during normal inspiration",
"Physiology: on inspiration, BP normally drops slightly (≤10 mmHg); in pericardial tamponade, exaggerated",
"Measurement: inflate cuff above systolic, deflate slowly; first note when Korotkoff sounds heard only on expiration; continue deflating until sounds heard in both phases. Difference >10 mmHg = pulsus paradoxus",
"Causes: cardiac tamponade (most important), severe asthma/COPD (large swings in intrathoracic pressure), constrictive pericarditis (mild), tension pneumothorax",
"Beck's triad of tamponade: hypotension + elevated JVP + muffled heart sounds"],
"Pulsus paradoxus is best detected clinically by feeling the radial pulse — pulse disappears on deep inspiration in severe tamponade", CVS_C)); q+=1
story.append(qa(q, "What is the significance of radio-radial delay and radio-femoral delay?",
["Radio-radial delay: right radial pulse arrives BEFORE left radial pulse — suggests thoracic aortic aneurysm/dissection involving left subclavian, subclavian artery stenosis, aortic arch abnormality",
"Radio-femoral delay: radial pulse arrives BEFORE femoral pulse — coarctation of the aorta (narrowing distal to left subclavian), aortic dissection",
"Coarctation features: hypertension in arms + normal/low BP in legs, radiofemoral delay, weak femoral pulses, rib notching on CXR (3rd-8th ribs = collateral erosion)",
"Always feel all peripheral pulses: radial, brachial, carotid, femoral, popliteal, posterior tibial, dorsalis pedis"],
"Radio-femoral delay = coarctation until proven otherwise. Always check BP in all four limbs if suspected", CVS_C)); q+=1
story.append(sec_header("C. APEX BEAT & CARDIAC AUSCULTATION", CVS_C))
story.append(qa(q, "What are the characters of the apex beat? What does each character indicate?",
["Normal: 5th ICS, medial to MCL — localised, brief, tapping impulse",
"Displaced (outside MCL or below 5th ICS): cardiomegaly (LV dilatation) — dilated CMP, volume overload (MR, AR, CCF)",
"Tapping: palpable S1 — mitral stenosis (loud S1 snapping shut)",
"Heaving/sustained (undisplaced): LV pressure overload/hypertrophy — aortic stenosis, systemic HTN, HOCM",
"Hyperdynamic/thrusting (displaced): volume overload — mitral regurgitation, aortic regurgitation, dilated CMP",
"Diffuse/tumultuous: dilated cardiomyopathy",
"Double impulse: HOCM (atrial kick + systolic movement)",
"Impalpable: COPD, obesity, pericardial effusion, dextrocardia"],
"Tapping apex = the only way to clinically diagnose mitral stenosis before auscultation. The loud S1 is palpable as a tap", CVS_C)); q+=1
story.append(qa(q, "What is a left parasternal heave? What does it indicate?",
["Place heel of hand at left sternal border (3rd-4th ICS) — if it is lifted with each systole = RV heave",
"Indicates right ventricular enlargement due to pressure or volume overload",
"Causes: pulmonary arterial hypertension (PAH), mitral stenosis (secondary PAH), ASD (volume overload), pulmonary stenosis, chronic cor pulmonale (COPD/ILD)",
"Grading: Grade 1 = barely felt; Grade 2 = fingers lifted; Grade 3 = whole hand lifted",
"Often associated with: loud P2 (palpable P2), elevated JVP, peripheral oedema",
"Epigastric pulsation (beneath xiphoid): RV hypertrophy — better felt on deep inspiration"],
"Left parasternal heave + loud P2 + elevated JVP = pulmonary hypertension complex — look for the underlying cause (MS, COPD, primary PAH)", CVS_C)); q+=1
story.append(qa(q, "How do you describe a cardiac murmur completely?",
["Timing: systolic (during S1-S2) or diastolic (during S2-S1), or continuous (both)",
"Grade (Levine scale): I–VI (for systolic); I–IV (for diastolic)",
"Quality: harsh/rough (AS), soft/blowing (MR, AR), rumbling (MS), machinery (PDA)",
"Location: mitral area, tricuspid area, aortic area, pulmonary area, Erb's area",
"Radiation: to axilla (MR), to carotids (AS), to back (PDA), no radiation (MS, TR)",
"Position: left lateral for mitral (MS, MR); sitting forward for AR; supine for TR, PS",
"Respiration: louder on inspiration = right-sided (Carvallo's sign for TR, PS); louder on expiration = left-sided (MS, MR, AS, AR)"],
"Complete murmur description: 'A grade 3/6 mid-diastolic rumbling murmur, best heard at the apex with the bell, in the left lateral position on expiration, with presystolic accentuation' = Mitral Stenosis", CVS_C)); q+=1
story.append(qa(q, "What are the clinical features of mitral stenosis?",
["Symptoms: dyspnoea, haemoptysis, palpitations (AF), embolic events",
"General: malar flush (mitral facies) — dusky reddish-blue discolouration of cheeks",
"Pulse: low volume; irregularly irregular if AF (50% of severe MS)",
"JVP: elevated if RHF/pulmonary hypertension",
"Apex beat: tapping (palpable S1), not displaced, left parasternal heave",
"Auscultation: loud S1, opening snap (short S2-OS interval = severe), mid-diastolic rumbling murmur (bell, LLD position, expiration), presystolic accentuation (if sinus rhythm)",
"Signs of severity: short S2-OS interval, long diastolic murmur, pulmonary hypertension, AF"],
"MS mnemonic: MALAR FLUSH, TAPPING APEX, LOUD S1, OPENING SNAP, MDM = perfect viva answer for MS", CVS_C)); q+=1
story.append(qa(q, "What are the clinical features of aortic stenosis?",
["Classic triad of symptoms: syncope, angina, dyspnoea (SAD) — syncope is the most ominous",
"Pulse: slow-rising, low volume, plateau pulse (pulsus parvus et tardus) — weak and late upstroke",
"BP: narrow pulse pressure",
"Apex: heaving (pressure-loaded LVH), undisplaced",
"Thrill: systolic thrill at aortic area (2nd RICS) and carotids",
"Auscultation: soft/absent A2, ejection systolic click, harsh ejection systolic murmur (crescendo-decrescendo) loudest at 2nd RICS, radiates to carotids",
"Severity markers: soft/absent A2, narrow pulse pressure, reverse split of S2, S4 gallop, LVH"],
"Progression of AS symptoms predicts prognosis: Syncope → 3 years survival; Angina → 5 years; Dyspnoea → 2 years without surgery", CVS_C)); q+=1
story.append(qa(q, "What are the clinical features and causes of atrial fibrillation (AF)?",
["Features on examination: pulse — irregularly irregular, variable volume; apex-radial pulse deficit",
"Symptoms: palpitations, dyspnoea, fatigue, presyncope, embolic events (stroke)",
"Causes (PIRATES mnemonic): P = Pulmonary (PE, pneumonia, COPD); I = Ischaemia; R = Rheumatic heart disease (MS); A = Anaemia, Alcohol; T = Thyrotoxicosis (most reversible); E = Electrolytes; S = Sick sinus syndrome",
"Valvular AF: mitral stenosis or MR (higher embolic risk)",
"Management principles: rate control (digoxin, beta-blocker, CCB) OR rhythm control; anticoagulation (warfarin/NOAC) for CHA₂DS₂-VASc score ≥2",
"Electrocardiogram: absent P waves, irregularly irregular RR intervals, fibrillatory baseline"],
"Irregularly irregular pulse = AF until proven otherwise. Always check for thyroid disease (thyrotoxicosis causes AF even at normal heart rate)", CVS_C)); q+=1
story.append(qa(q, "What is the Gibson's murmur (Continuous murmur)? When and where do you hear it?",
["Continuous machinery murmur: begins in systole, peaks around S2, continues into diastole (does not stop at S2)",
"Best heard: left infraclavicular area (Gibson's area) / left 1st-2nd ICS just below left clavicle",
"With diaphragm, patient supine",
"Cause: Patent Ductus Arteriosus (PDA) — left-to-right shunt from aorta to pulmonary artery throughout cardiac cycle",
"Quality: high-pitched, machinery/humming, crescendo-decrescendo around S2",
"Eisenmenger syndrome: when PAP exceeds systemic → shunt reverses → differential cyanosis (lower limbs more cyanosed); machinery murmur disappears",
"Other continuous murmurs: venous hum (neck, disappears on lying), AV fistula, coronary AV fistula"],
"PDA is the classic cause of a continuous murmur. 'Machinery murmur' is the key phrase. Complications: Eisenmenger's, IE, CCF", CVS_C)); q+=1
story.append(qa(q, "What are the features of congestive cardiac failure (CCF) on examination?",
["Left heart failure (LVF): dyspnoea, orthopnoea, PND, bilateral basal fine crepitations, S3 gallop (best indicator of LV dysfunction), displaced thrusting apex",
"Right heart failure (RHF): elevated JVP, peripheral oedema (bilateral pitting, dependent), tender hepatomegaly, ascites, hepatojugular reflex positive",
"Congestive (biventricular): features of both LHF + RHF",
"Tachycardia, cold peripheries, low-volume pulse (low CO state)",
"Pulsus alternans: alternating strong-weak pulse = severe LV dysfunction",
"CXR findings: cardiomegaly (CTR >0.5), bat-wing pulmonary oedema, Kerley B lines, upper lobe blood diversion, pleural effusion"],
"S3 gallop at apex (bell, LLD position) = the most specific sign of LV systolic dysfunction in CCF. Also called 'ventricular gallop'", CVS_C)); q+=1
# Final pages
story.append(PageBreak())
story.append(sys_header("QUICK REVISION TABLES", "Summary of Key Clinical Patterns for Rapid Viva Recall", HDR_BG))
# Table 1: Lung signs
story.append(sec_header("Respiratory Examination Pattern Summary", RS_C))
t1_data = [
[Paragraph("<b>Condition</b>", S('TH', fontSize=8, fontName='Helvetica-Bold', textColor=WHITE)),
Paragraph("<b>TVF</b>", S('TH', fontSize=8, fontName='Helvetica-Bold', textColor=WHITE)),
Paragraph("<b>Percussion</b>", S('TH', fontSize=8, fontName='Helvetica-Bold', textColor=WHITE)),
Paragraph("<b>Breath Sounds</b>", S('TH', fontSize=8, fontName='Helvetica-Bold', textColor=WHITE)),
Paragraph("<b>Trachea</b>", S('TH', fontSize=8, fontName='Helvetica-Bold', textColor=WHITE))],
["Consolidation", "↑ Increased", "Dull", "Bronchial + creps", "Central"],
["Pleural Effusion", "↓ Absent", "Stony Dull", "Absent (bronchial above)", "Away (large)"],
["Pneumothorax", "↓ Absent", "Hyper-resonant", "Absent", "Away (tension)"],
["Collapse", "↓/Absent", "Dull", "Absent/↓", "Toward lesion"],
["Fibrosis", "↑/Normal", "Dull", "Bronchial/bronchov.", "Toward lesion"],
["Emphysema", "↓ Decreased", "Hyper-resonant (bilat)", "Vesicular ↓", "Central"],
]
t1 = Table(t1_data, colWidths=[3.8*cm, 2.4*cm, 3*cm, 4.2*cm, 2.9*cm])
row_colors = [RS_C] + [colors.HexColor("#EBF5FB"), colors.HexColor("#FDFFFE")]*3
t1.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), RS_C),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#EBF5FB"), colors.HexColor("#FDFFFE")]),
('GRID', (0,0), (-1,-1), 0.5, MID_GRAY),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 5),
]))
story.append(t1)
story.append(Spacer(1, 10))
# Table 2: Cardiac valvular lesions
story.append(sec_header("Cardiac Valvular Lesion Summary", CVS_C))
t2_data = [
[Paragraph("<b>Lesion</b>", S('TH2', fontSize=8, fontName='Helvetica-Bold', textColor=WHITE)),
Paragraph("<b>Pulse</b>", S('TH2', fontSize=8, fontName='Helvetica-Bold', textColor=WHITE)),
Paragraph("<b>Apex</b>", S('TH2', fontSize=8, fontName='Helvetica-Bold', textColor=WHITE)),
Paragraph("<b>Murmur</b>", S('TH2', fontSize=8, fontName='Helvetica-Bold', textColor=WHITE)),
Paragraph("<b>Key Feature</b>", S('TH2', fontSize=8, fontName='Helvetica-Bold', textColor=WHITE))],
["Mitral Stenosis", "Low vol / AF", "Tapping, undisplaced", "MDM + OS, bell, LLD, exp", "Loud S1, malar flush"],
["Mitral Regurgitation", "Normal/AF", "Displaced, thrusting", "PSM → axilla, diaphragm, LLD, exp", "Soft S1, S3"],
["Aortic Stenosis", "Slow-rising, plateau", "Heaving, undisplaced", "ESM → carotids, sitting, exp", "Soft/absent A2, narrow PP"],
["Aortic Regurgitation", "Collapsing, bounding", "Displaced, thrusting", "EDM, Erb's/sit forward, exp", "Wide PP, Hill's sign, Duroziez"],
["Tricuspid Regurgitation", "Irreg (AF)", "Parasternal heave", "PSM, LLSE, inspiration ↑", "Giant v waves, pulsatile liver"],
["Pulmonary Stenosis", "Normal", "Parasternal heave", "ESM, pulmonary area, insp ↑", "Loud P2 absent, ejection click"],
["PDA", "Collapsing", "Displaced", "Continuous machinery, L-infraclavicular", "Differential cyanosis"],
]
t2 = Table(t2_data, colWidths=[2.8*cm, 2.5*cm, 2.6*cm, 4.8*cm, 3.6*cm])
t2.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), CVS_C),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 7.5),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#FEF9F9"), colors.HexColor("#FDFFFE")]),
('GRID', (0,0), (-1,-1), 0.5, MID_GRAY),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 4),
]))
story.append(t2)
story.append(Spacer(1, 10))
# Table 3: UMN vs LMN
story.append(sec_header("UMN vs LMN Lesion Summary", CNS_C))
t3_data = [
[Paragraph("<b>Feature</b>", S('TH3', fontSize=8.5, fontName='Helvetica-Bold', textColor=WHITE)),
Paragraph("<b>UMN Lesion</b>", S('TH3', fontSize=8.5, fontName='Helvetica-Bold', textColor=WHITE)),
Paragraph("<b>LMN Lesion</b>", S('TH3', fontSize=8.5, fontName='Helvetica-Bold', textColor=WHITE))],
["Tone", "Increased (spasticity)", "Decreased (flaccidity)"],
["Power", "Weakness (pyramidal pattern)", "Weakness (myotomal)"],
["Reflexes", "Hyperreflexia, clonus", "Hyporeflexia / areflexia"],
["Plantar", "Extensor (Babinski +)", "Flexor (downgoing)"],
["Wasting", "Mild (disuse)", "Significant atrophy"],
["Fasciculations", "Absent", "Present"],
["Examples", "Stroke, MS, tumour, myelopathy", "Peripheral neuropathy, GBS, motor nerve injury"],
]
t3 = Table(t3_data, colWidths=[4*cm, 6*cm, 6.3*cm])
t3.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), CNS_C),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8.5),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor("#F5EEF8"), colors.HexColor("#FDFFFE")]),
('GRID', (0,0), (-1,-1), 0.5, MID_GRAY),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 6),
]))
story.append(t3)
story.append(Spacer(1, 10))
# Final footer note
footer = Table([[Paragraph(
"<b>Note:</b> This viva question booklet is based on the 4-system Medicine Practical Case Proforma. "
"All answers are for examination purposes. Clinical decisions should always be based on complete patient assessment.",
S('FT', fontSize=7.5, textColor=colors.HexColor("#5D6D7E"), fontName='Helvetica-Oblique')
)]], colWidths=[16.3*cm])
footer.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor("#F2F3F4")),
('BOX', (0,0), (-1,-1), 0.5, MID_GRAY),
('LEFTPADDING', (0,0), (-1,-1), 8),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
]))
story.append(footer)
# ── BUILD ─────────────────────────────────────────────────────────────────────
doc.build(story)
print("Viva PDF created successfully!")
cd /tmp/workspace/system-exam-checklist && python3 build_viva.py 2>&1
ls -lh /tmp/workspace/system-exam-checklist/Medicine_Viva_Questions.pdf
Medicine Viva Questions
PDF Document · PDF