You haven’t prepared the ortho pdf notes yet
UPSC cms previous year question paper notes pdf from ortho
UPSC CMS previous year question papers orthopaedics questions
mkdir -p /tmp/workspace/upsc-cms-ortho && ls /tmp/workspace/upsc-cms-ortho/
~/upsc-cms-ortho/generate_ortho_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch, cm
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable, PageBreak
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import KeepTogether
OUTPUT = "/tmp/workspace/upsc-cms-ortho/UPSC_CMS_Orthopaedics_PYQ_Notes.pdf"
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=1.8*cm,
leftMargin=1.8*cm,
topMargin=2*cm,
bottomMargin=2*cm,
)
styles = getSampleStyleSheet()
# Custom styles
title_style = ParagraphStyle(
'Title', parent=styles['Title'],
fontSize=22, textColor=colors.HexColor('#1a237e'),
spaceAfter=6, spaceBefore=0, alignment=TA_CENTER,
fontName='Helvetica-Bold'
)
subtitle_style = ParagraphStyle(
'Subtitle', parent=styles['Normal'],
fontSize=11, textColor=colors.HexColor('#37474f'),
spaceAfter=4, spaceBefore=0, alignment=TA_CENTER,
fontName='Helvetica'
)
chapter_style = ParagraphStyle(
'Chapter', parent=styles['Heading1'],
fontSize=14, textColor=colors.white,
spaceBefore=14, spaceAfter=6,
fontName='Helvetica-Bold',
backColor=colors.HexColor('#1a237e'),
leftIndent=-10, rightIndent=-10,
borderPad=6
)
section_style = ParagraphStyle(
'Section', parent=styles['Heading2'],
fontSize=11, textColor=colors.HexColor('#1565c0'),
spaceBefore=10, spaceAfter=4,
fontName='Helvetica-Bold',
)
q_style = ParagraphStyle(
'Question', parent=styles['Normal'],
fontSize=10, textColor=colors.HexColor('#212121'),
spaceBefore=8, spaceAfter=3,
fontName='Helvetica-Bold',
leading=14
)
opt_style = ParagraphStyle(
'Option', parent=styles['Normal'],
fontSize=10, textColor=colors.HexColor('#424242'),
spaceBefore=1, spaceAfter=1,
fontName='Helvetica',
leftIndent=16, leading=13
)
ans_style = ParagraphStyle(
'Answer', parent=styles['Normal'],
fontSize=10, textColor=colors.HexColor('#1b5e20'),
spaceBefore=3, spaceAfter=1,
fontName='Helvetica-Bold',
leftIndent=8
)
exp_style = ParagraphStyle(
'Explanation', parent=styles['Normal'],
fontSize=9.5, textColor=colors.HexColor('#37474f'),
spaceBefore=2, spaceAfter=5,
fontName='Helvetica',
leftIndent=8, leading=13,
borderPad=4,
backColor=colors.HexColor('#f1f8e9'),
)
note_style = ParagraphStyle(
'Note', parent=styles['Normal'],
fontSize=9.5, textColor=colors.HexColor('#bf360c'),
spaceBefore=2, spaceAfter=4,
fontName='Helvetica-Oblique',
leftIndent=8
)
body_style = ParagraphStyle(
'Body', parent=styles['Normal'],
fontSize=10, textColor=colors.HexColor('#212121'),
spaceBefore=3, spaceAfter=3,
fontName='Helvetica',
leading=14
)
def ch(text):
return Paragraph(text, chapter_style)
def sec(text):
return Paragraph(text, section_style)
def q(num, text):
return Paragraph(f"Q{num}. {text}", q_style)
def opts(*options):
items = []
labels = ['(A)', '(B)', '(C)', '(D)']
for i, o in enumerate(options):
items.append(Paragraph(f"{labels[i]} {o}", opt_style))
return items
def ans(letter, text):
return Paragraph(f"✓ Answer: ({letter}) {text}", ans_style)
def exp(text):
return Paragraph(f"Explanation: {text}", exp_style)
def note(text):
return Paragraph(f"★ High-Yield: {text}", note_style)
def body(text):
return Paragraph(text, body_style)
def hr():
return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor('#bdbdbd'), spaceAfter=4, spaceBefore=4)
story = []
# ──────────────── COVER ────────────────
story.append(Spacer(1, 1*cm))
story.append(Paragraph("UPSC CMS ORTHOPAEDICS", title_style))
story.append(Paragraph("Previous Year Questions – Notes & Explanations", subtitle_style))
story.append(Paragraph("Paper II – Surgery (Orthopaedic Surgery)", subtitle_style))
story.append(Spacer(1, 0.3*cm))
story.append(HRFlowable(width="80%", thickness=2, color=colors.HexColor('#1a237e'), spaceAfter=6, spaceBefore=6))
story.append(Paragraph("Compiled from UPSC CMS 2010–2025 | Campbell's Operative Orthopaedics 15e | Miller's Review of Orthopaedics 9e", subtitle_style))
story.append(Spacer(1, 0.4*cm))
# Exam pattern box
exam_data = [
['UPSC CMS Exam Pattern – Paper II', ''],
['Paper II covers', 'Surgery, Gynaecology & Obstetrics, PSM'],
['Total Questions', '120 MCQs (40 Surgery, 40 OBG, 40 PSM)'],
['Orthopaedics in Surgery', '~8–12 questions per paper'],
['Marks per question', '2 marks; −0.66 for wrong answer'],
['Duration', '2 Hours'],
]
t = Table(exam_data, colWidths=[7*cm, 9.5*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1a237e')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('SPAN', (0,0), (-1,0)),
('ALIGN', (0,0), (-1,-1), 'LEFT'),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 10),
('BACKGROUND', (0,1), (-1,-1), colors.HexColor('#e8eaf6')),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#e8eaf6'), colors.HexColor('#f3f4ff')]),
('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#9fa8da')),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 8),
]))
story.append(t)
story.append(Spacer(1, 0.5*cm))
story.append(PageBreak())
# ──────────────── TOPIC OVERVIEW ────────────────
story.append(ch(" UPSC CMS ORTHOPAEDICS – HIGH YIELD TOPICS"))
story.append(Spacer(1, 0.2*cm))
topic_data = [
['#', 'Topic', 'Avg Qs/Year', 'Priority'],
['1', 'Fractures & Dislocations', '3–4', '★★★★★'],
['2', 'Bone Tumours', '1–2', '★★★★☆'],
['3', 'Congenital Disorders (CTEV, DDH, CDH)', '1–2', '★★★★★'],
['4', 'Infections (Osteomyelitis, Septic Arthritis)', '1–2', '★★★★☆'],
['5', 'Arthritis (OA, RA, Gout)', '1–2', '★★★★☆'],
['6', 'Metabolic Bone Disease', '1', '★★★☆☆'],
['7', 'Spine (Scoliosis, PID, TB Spine)', '1–2', '★★★★☆'],
['8', 'Regional Disorders (Shoulder, Knee, Hand)', '1–2', '★★★★☆'],
['9', 'Nerve Injuries', '1', '★★★☆☆'],
['10', 'General Principles', '1', '★★★☆☆'],
]
tt = Table(topic_data, colWidths=[0.8*cm, 8.5*cm, 3.2*cm, 4*cm])
tt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#283593')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 9.5),
('ALIGN', (0,0), (-1,-1), 'CENTER'),
('ALIGN', (0,1), (1,-1), 'LEFT'),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.white, colors.HexColor('#e8eaf6')]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#9fa8da')),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
]))
story.append(tt)
story.append(PageBreak())
# ──────────────── SECTION 1: FRACTURES ────────────────
story.append(ch(" SECTION 1: FRACTURES & DISLOCATIONS"))
story.append(sec("Key Concepts"))
story.append(body("<b>Colles Fracture:</b> Extra-articular fracture of distal radius within 2.5 cm of wrist. Distal fragment: dorsal displacement + radial shift + supination (dinner fork deformity). Classic in elderly osteoporotic women after fall on outstretched hand (FOOSH)."))
story.append(body("<b>Smith Fracture:</b> Reverse Colles – volar displacement. 'Garden spade' deformity. Fall on flexed wrist."))
story.append(body("<b>Barton Fracture:</b> Intra-articular fracture of distal radius with carpal dislocation."))
story.append(body("<b>Monteggia Fracture:</b> Fracture of proximal 1/3 ulna + dislocation of radial head. (Mnemonic: MUDRA – Monteggia = Upper ulna + Dislocation of Radial head Anteriorly)"))
story.append(body("<b>Galeazzi Fracture:</b> Fracture of lower 1/3 radius + dislocation of distal radio-ulnar joint. 'Reverse Monteggia'. More common than Monteggia."))
story.append(body("<b>Bennett's Fracture:</b> Intra-articular fracture at base of 1st metacarpal with subluxation of CMC joint."))
story.append(body("<b>Rolando Fracture:</b> Comminuted Bennett's fracture (T or Y shaped)."))
story.append(Spacer(1, 0.1*cm))
# Q1
story += [q(1, "A 60-year-old woman falls on an outstretched hand. X-ray shows dorsal displacement of distal radial fragment. The most likely diagnosis is:")]
story += opts("Smith fracture", "Colles fracture", "Barton fracture", "Monteggia fracture")
story.append(ans("B", "Colles fracture"))
story.append(exp("Colles fracture = fracture of distal radius with DORSAL displacement of the distal fragment, occurring within 2.5 cm of the wrist joint. It is the most common fracture in elderly women (osteoporosis + FOOSH). Produces 'dinner fork deformity' on lateral view. Smith fracture = volar (anterior) displacement."))
story.append(hr())
story += [q(2, "The 'Dinner Fork' deformity is seen in:")]
story += opts("Smith fracture", "Monteggia fracture", "Colles fracture", "Galeazzi fracture")
story.append(ans("C", "Colles fracture"))
story.append(exp("The dorsal displacement of the distal fragment in Colles fracture produces the 'dinner fork' or 'bayonet' deformity on lateral view."))
story.append(hr())
story += [q(3, "Fracture of the proximal one-third of ulna with anterior dislocation of the radial head is:")]
story += opts("Galeazzi fracture", "Monteggia fracture", "Essex-Lopresti injury", "Both bone forearm fracture")
story.append(ans("B", "Monteggia fracture"))
story.append(exp("Monteggia fracture = ulnar shaft fracture (proximal 1/3) + dislocation of radial head. Bado classification: Type I (most common) = anterior dislocation of radial head. Galeazzi = distal radius fracture + distal RU joint dislocation (reverse Monteggia)."))
story.append(note("UPSC CMS loves asking which is more common: Galeazzi > Monteggia in adults."))
story.append(hr())
story += [q(4, "Bennett's fracture involves which bone?")]
story += opts("Distal radius", "Scaphoid", "Base of 1st metacarpal", "Calcaneum")
story.append(ans("C", "Base of 1st metacarpal"))
story.append(exp("Bennett's fracture = intra-articular fracture at the base of the 1st metacarpal with subluxation of the carpometacarpal joint. The APL tendon pulls the shaft proximally. Rolando fracture = comminuted (T or Y-shaped) variant."))
story.append(hr())
story += [q(5, "The most common carpal bone fractured is:")]
story += opts("Lunate", "Scaphoid", "Triquetrum", "Capitate")
story.append(ans("B", "Scaphoid"))
story.append(exp("Scaphoid is the most commonly fractured carpal bone (70% of carpal fractures). Occurs after FOOSH. Key: Avascular necrosis of proximal pole is a dreaded complication (blood supply enters distally). X-ray may be normal initially – need MRI/bone scan. Tender in anatomical snuffbox."))
story.append(note("Most common site: waist of scaphoid. AVN risk highest with proximal pole fractures."))
story.append(hr())
story += [q(6, "Avascular necrosis is a known complication of all EXCEPT:")]
story += opts("Neck of femur fracture", "Scaphoid fracture", "Fracture neck of talus", "Fracture shaft of tibia")
story.append(ans("D", "Fracture shaft of tibia"))
story.append(exp("AVN occurs when blood supply to a bone is disrupted. Sites prone: (1) Head of femur – after neck of femur fracture, (2) Scaphoid proximal pole, (3) Talus (Hawkins sign = subchondral lucency indicates vascularity is preserved), (4) Lunate (Kienbock disease). Tibial shaft fracture does NOT cause AVN."))
story.append(hr())
story.append(sec("Femur & Hip Fractures"))
story.append(body("<b>Garden Classification (NOF Fractures):</b> Grade I – incomplete/impacted; Grade II – complete undisplaced; Grade III – complete + partial displacement; Grade IV – complete + full displacement. Grades III & IV have high AVN risk."))
story.append(body("<b>Treatment of NOF fractures:</b> Undisplaced (Garden I/II) – cannulated screws; Displaced in elderly (Garden III/IV) – hemiarthroplasty/THR; Young patient – ORIF."))
story.append(body("<b>Intertrochanteric fractures:</b> Treated with DHS (Dynamic Hip Screw). Stable = medial buttress intact. Tip-Apex Distance (TAD) < 25 mm prevents cut-out."))
story += [q(7, "Garden Grade IV fracture of neck of femur in an elderly patient is best treated by:")]
story += opts("Cannulated cancellous screws", "Dynamic hip screw", "Bipolar hemiarthroplasty", "Total knee replacement")
story.append(ans("C", "Bipolar hemiarthroplasty"))
story.append(exp("Displaced NOF fractures (Garden III & IV) in elderly patients (>60–65 years) are treated with arthroplasty (hemi or total hip replacement) because: (1) High AVN risk with internal fixation, (2) Better functional outcomes, (3) Earlier mobilisation. Young patients (<50 years) → ORIF to preserve native hip."))
story.append(hr())
story += [q(8, "Which fracture is treated with Dynamic Hip Screw (DHS)?")]
story += opts("Subtrochanteric fracture", "Intertrochanteric fracture", "Intracapsular neck of femur", "Acetabular fracture")
story.append(ans("B", "Intertrochanteric fracture"))
story.append(exp("DHS (Dynamic Hip Screw/Sliding Hip Screw) is the implant of choice for intertrochanteric fractures. It allows controlled collapse at the fracture site. NOT suitable for subtrochanteric fractures (use intramedullary nail) or intracapsular fractures (use screws/arthroplasty)."))
story.append(hr())
story.append(sec("Spine Fractures"))
story += [q(9, "Jefferson fracture (burst fracture of atlas) is best diagnosed by:")]
story += opts("AP X-ray", "Lateral X-ray", "Open mouth (odontoid) view", "CT scan")
story.append(ans("D", "CT scan"))
story.append(exp("Jefferson fracture = burst fracture of C1 (atlas) from axial compression. Open mouth view shows lateral mass spreading (Rule of Spence: >7 mm bilateral overhang = transverse ligament rupture). CT is best for diagnosis and surgical planning. Stable if transverse ligament intact; unstable if ruptured."))
story.append(hr())
story += [q(10, "Chance fracture (seat-belt fracture) involves:")]
story += opts("Cervical spine flexion injury", "Lumbar spine flexion-distraction injury", "Thoracic spine compression", "Sacral fracture")
story.append(ans("B", "Lumbar spine flexion-distraction injury"))
story.append(exp("Chance fracture = horizontal fracture through ALL three columns of the lumbar vertebra (L1–L4). Mechanism: flexion-distraction (seat belt injury in MVC). Associated with bowel/intra-abdominal injuries in 40–50% cases. Treatment: extension casting if purely bony; surgery if ligamentous."))
story.append(hr())
story.append(PageBreak())
# ──────────────── SECTION 2: BONE TUMOURS ────────────────
story.append(ch(" SECTION 2: BONE TUMOURS"))
story.append(sec("Classification – Quick Reference"))
tumor_data = [
['Tumour', 'Nature', 'Peak Age', 'Common Site', 'Key Feature'],
['Osteosarcoma', 'Malignant', '10–20 yr', 'Distal femur/prox tibia', 'Codman triangle, sunburst'],
['Ewing Sarcoma', 'Malignant', '5–15 yr', 'Diaphysis (femur)', 'Onion peel, t(11;22)'],
['Chondrosarcoma', 'Malignant', '>40 yr', 'Pelvis, proximal femur', 'Slow growing, no chemo'],
['GCT', 'Locally aggressive', '20–40 yr', 'Distal femur (epiphysis)', 'Soap bubble, extends to articular surface'],
['Osteoid Osteoma', 'Benign', '10–30 yr', 'Femur, tibia (cortex)', 'Night pain relieved by NSAIDs, nidus <1.5 cm'],
['Osteoblastoma', 'Benign', '10–30 yr', 'Spine (posterior elements)', 'Like osteoid osteoma, nidus >2 cm'],
['Enchondroma', 'Benign', 'Any', 'Short tubular bones (hand)', 'Ollier disease if multiple'],
['Osteochondroma', 'Benign', '<20 yr', 'Distal femur', 'Most common benign bone tumour'],
['ABC', 'Benign', '<20 yr', 'Long bones, spine', 'Fluid-fluid levels on MRI'],
['Simple Bone Cyst', 'Benign', '5–15 yr', 'Proximal humerus', 'Fallen leaf sign, unilocular'],
]
bt = Table(tumor_data, colWidths=[3.5*cm, 2.5*cm, 2*cm, 3.5*cm, 5*cm])
bt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1a237e')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8),
('ALIGN', (0,0), (-1,-1), 'LEFT'),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.white, colors.HexColor('#e8eaf6')]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#9fa8da')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
]))
story.append(bt)
story.append(Spacer(1, 0.3*cm))
story += [q(11, "The most common malignant primary bone tumour in children is:")]
story += opts("Chondrosarcoma", "Osteosarcoma", "Ewing sarcoma", "Multiple myeloma")
story.append(ans("B", "Osteosarcoma"))
story.append(exp("Osteosarcoma is the most common PRIMARY malignant bone tumour in children/young adults. Second most common overall (after multiple myeloma which is in adults). Peak: 10–20 years. Classic site: metaphysis around knee (distal femur > proximal tibia > proximal humerus). X-ray: Codman triangle (periosteal reaction) + sunburst pattern + soft tissue mass."))
story.append(note("Mnemonic: Osteo-SARCOMA: Sunburst, Age 10-20, RB1/P53 genes, Codman triangle, Osteoid production by malignant cells, Metaphysis, Around knee."))
story.append(hr())
story += [q(12, "Codman's triangle and sunburst appearance on X-ray is characteristic of:")]
story += opts("Giant cell tumour", "Osteosarcoma", "Ewing sarcoma", "Chondrosarcoma")
story.append(ans("B", "Osteosarcoma"))
story.append(exp("Codman triangle = periosteal new bone formation at the edge of a tumour, creating a triangular shadow. Sunburst/hair-on-end pattern = spicules of new bone radiating perpendicular to cortex. Both are hallmarks of OSTEOSARCOMA. Ewing sarcoma = onion-peel (laminated periosteal reaction) + diaphysis."))
story.append(hr())
story += [q(13, "Onion peel appearance on X-ray of a long bone in a 12-year-old is most likely:")]
story += opts("Osteosarcoma", "Ewing sarcoma", "Osteomyelitis", "Giant cell tumour")
story.append(ans("B", "Ewing sarcoma"))
story.append(exp("Ewing sarcoma: Diaphysis of long bones; Peak age 5–15 years; t(11;22) translocation (EWS-FLI1); EWSR1 gene; X-ray = onion-peel periosteal reaction; PAS-positive small round blue cells; Systemic features (fever, raised ESR/CRP) mimic osteomyelitis. Treatment: chemotherapy + surgery/radiotherapy."))
story.append(hr())
story += [q(14, "Giant cell tumour (GCT) characteristically involves:")]
story += opts("Diaphysis of long bone", "Metaphysis with epiphyseal extension", "Epiphysis extending to articular surface", "Flat bones only")
story.append(ans("C", "Epiphysis extending to articular surface"))
story.append(exp("GCT = locally aggressive tumour of osteoclast-like giant cells. Key features: (1) Epiphyseal location – extends to subchondral bone (articular surface), (2) Age: 20–40 yr (skeletally mature), (3) X-ray: eccentric lytic lesion with 'soap bubble' or 'blown out' appearance, (4) NO periosteal reaction, (5) Campanacci Grade I–III. Most common site: distal femur > proximal tibia > distal radius."))
story.append(hr())
story += [q(15, "Night pain relieved by aspirin/NSAIDs is pathognomonic of:")]
story += opts("Ewing sarcoma", "Osteoblastoma", "Osteoid osteoma", "Bone abscess")
story.append(ans("C", "Osteoid osteoma"))
story.append(exp("Osteoid osteoma: Nidus <1.5 cm, surrounded by dense reactive bone sclerosis. Night pain (prostaglandin E2 produced by nidus) dramatically relieved by NSAIDs (aspirin). CT is investigation of choice to identify nidus. Treatment: Radiofrequency ablation (RFA) – minimally invasive, >90% success. Osteoblastoma = same histology but nidus >2 cm, NOT consistently relieved by NSAIDs, more common in spine."))
story.append(note("Mnemonic: Osteoid Osteoma – NAN (Nidus <1.5 cm, Aspirin relieves, Night pain)"))
story.append(hr())
story += [q(16, "Chemotherapy is NOT effective in:")]
story += opts("Osteosarcoma", "Ewing sarcoma", "Chondrosarcoma", "Multiple myeloma")
story.append(ans("C", "Chondrosarcoma"))
story.append(exp("Chondrosarcoma is resistant to both chemotherapy and radiotherapy. The ONLY effective treatment is wide surgical resection. It is a slow-growing tumour, most common in adults >40 years, arising in pelvis, proximal femur, scapula. Grade I = low grade (best prognosis); Grade III = high grade. Enchondroma can undergo malignant transformation to chondrosarcoma."))
story.append(hr())
story.append(PageBreak())
# ──────────────── SECTION 3: CONGENITAL ────────────────
story.append(ch(" SECTION 3: CONGENITAL DISORDERS"))
story.append(sec("CTEV – Congenital Talipes Equinovarus (Club Foot)"))
story.append(body("<b>Deformities (mnemonic CAVE):</b> C – Cavus; A – Adduction of forefoot; V – Varus of hindfoot; E – Equinus. All are rigid (not correctable passively in true CTEV)."))
story.append(body("<b>Ponseti Method:</b> Gold standard for idiopathic CTEV. Serial casting for 6–8 weeks (CAVE correction in reverse order: Cavus → Adduction → Varus → Equinus). Percutaneous tenotomy of Achilles tendon in 80–90% cases. Then Denis Browne splint (foot abduction brace) until age 4–5 years. Success rate > 95%."))
story.append(body("<b>Pirani Score:</b> Assesses severity (0–6 points). Dimeglio Score: 0–20 points."))
story += [q(17, "The Ponseti method for clubfoot correction involves serial casting followed by:")]
story += opts("Posteromedial release surgery", "Percutaneous Achilles tenotomy + Denis Browne splint", "Ilizarov frame application", "Triple arthrodesis")
story.append(ans("B", "Percutaneous Achilles tenotomy + Denis Browne splint"))
story.append(exp("After serial Ponseti casting corrects C-A-V deformities, 80–90% of children require a percutaneous Achilles tendon tenotomy to correct equinus. The Denis Browne splint (foot abduction orthosis at 60–70° external rotation) must be worn full-time for 3 months then at night until age 4–5 years. Compliance with bracing prevents relapse."))
story.append(hr())
story += [q(18, "The deformities in CTEV in correct order from most to least easily corrected are:")]
story += opts("Equinus → Varus → Adductus → Cavus", "Cavus → Adductus → Varus → Equinus", "Varus → Equinus → Adductus → Cavus", "Adductus → Cavus → Equinus → Varus")
story.append(ans("B", "Cavus → Adductus → Varus → Equinus"))
story.append(exp("Ponseti correction follows CAVE in reverse: Cavus first (forefoot supination corrected by finger under first metatarsal), then forefoot Adduction, then hindfoot Varus, finally Equinus (last – via tenotomy). Remember: CAVE reversed = EVAC."))
story.append(hr())
story.append(sec("DDH – Developmental Dysplasia of the Hip"))
story.append(body("<b>Risk factors:</b> Female (6:1), breech presentation, first-born, family history, oligohydramnios."))
story.append(body("<b>Clinical tests:</b> <0–3 months: Ortolani (reduce dislocated hip – 'clunk') and Barlow (dislocate reducible hip); >3 months: Galeazzi sign (apparent limb shortening with knees bent – unilateral); Trendelenburg sign (older children)."))
story.append(body("<b>Imaging:</b> Ultrasound (Graf method) up to age 6 months (cartilaginous femoral head); X-ray after 4–6 months. Hilgenreiner, Perkin lines; acetabular index >30°."))
story.append(body("<b>Treatment by age:</b> 0–6 mo → Pavlik harness (first line); 6–18 mo → Closed reduction + spica cast; >18 mo → Open reduction ± osteotomy."))
story += [q(19, "Ortolani's test for DDH – the 'clunk' felt on abduction signifies:")]
story += opts("Dislocation of normal hip", "Reduction of a dislocated hip", "Subluxation of the hip", "Acetabular dysplasia only")
story.append(ans("B", "Reduction of a dislocated hip"))
story.append(exp("Ortolani test: Start with hips flexed 90° and adducted. Abduct the hip while applying anterior pressure on the greater trochanter. A 'clunk' = reduction of a dislocated hip back into socket = POSITIVE Ortolani. Barlow test = opposite: adduct hip to dislocate a potentially unstable hip."))
story.append(note("'Ortolani Out → In (reduces the dislocation)'; 'Barlow In → Out (dislocates it)'"))
story.append(hr())
story += [q(20, "Pavlik harness is used for DDH in children up to age:")]
story += opts("3 months", "6 months", "18 months", "3 years")
story.append(ans("B", "6 months"))
story.append(exp("Pavlik harness is the first-line treatment for DDH in children up to 6 months of age. It maintains hips in flexion-abduction (safe zone position). Success rate 80–95% for dislocatable/dislocated hips <6 months. Failure → closed reduction under GA + hip spica cast."))
story.append(hr())
story.append(sec("Other Congenital Conditions"))
story += [q(21, "Torticollis (wry neck) in a neonate due to SCM muscle fibrosis is caused by:")]
story += opts("Atlantoaxial instability", "Birth trauma to sternocleidomastoid", "Cervical hemivertebra", "Klippel-Feil syndrome")
story.append(ans("B", "Birth trauma to sternocleidomastoid"))
story.append(exp("Muscular torticollis = SCM fibrosis from birth trauma (difficult delivery, forceps). A firm, non-tender, fusiform swelling in SCM appears 2–4 weeks after birth. Head tilts to affected side, face rotates to opposite side. Treatment: Physiotherapy (stretching); if no improvement by 12–18 months → SCM release. Klippel-Feil = congenital fusion of cervical vertebrae = SHORT NECK."))
story.append(hr())
story.append(PageBreak())
# ──────────────── SECTION 4: INFECTIONS ────────────────
story.append(ch(" SECTION 4: BONE & JOINT INFECTIONS"))
story.append(sec("Acute Haematogenous Osteomyelitis"))
story.append(body("<b>Most common organism:</b> Staphylococcus aureus (all ages). Exceptions: Neonates – Group B Streptococcus, E. coli; Sickle cell – Salmonella; Puncture wound foot – Pseudomonas; IV drug users – Pseudomonas/Candida."))
story.append(body("<b>Most common site in children:</b> Metaphysis of long bones (distal femur > proximal tibia > proximal humerus) – rich vascular sinusoids, sluggish blood flow, lack of phagocytes."))
story.append(body("<b>Radiological changes:</b> X-ray shows changes only after 10–21 days (25–30% bone loss needed). Earliest sign on X-ray = soft tissue swelling. Earliest overall = MRI. Bone scan positive within 24–48 hours."))
story.append(body("<b>Brodie's abscess:</b> Subacute osteomyelitis. Well-defined sclerotic lesion in metaphysis. Treated with curettage + antibiotics."))
story += [q(22, "Most common organism causing acute haematogenous osteomyelitis in a child is:")]
story += opts("Streptococcus pyogenes", "Staphylococcus aureus", "Haemophilus influenzae", "Pseudomonas aeruginosa")
story.append(ans("B", "Staphylococcus aureus"))
story.append(exp("Staphylococcus aureus is the most common cause of osteomyelitis across all age groups. Remember exceptions: Sickle cell disease → Salmonella (equals or exceeds Staph in prevalence in this group); Neonates (<1 month) → Group B Strep, E. coli; Puncture wound through shoe → Pseudomonas."))
story.append(hr())
story += [q(23, "In osteomyelitis, the earliest radiological change seen on plain X-ray is:")]
story += opts("Periosteal reaction", "Bony destruction (lytic lesion)", "Soft tissue swelling", "Sequestrum formation")
story.append(ans("C", "Soft tissue swelling"))
story.append(exp("X-ray changes in osteomyelitis: Day 3–5 = soft tissue swelling (earliest X-ray sign); Day 10–21 = periosteal reaction; Day 21+ = bony destruction (lytic lesion); Late = sequestrum and involucrum. MRI (earliest overall investigation) shows changes within 24–48 hours. Bone scan positive within 24–48 hours."))
story.append(note("Sequestrum = dead bone; Involucrum = new bone surrounding sequestrum; Cloaca = opening in involucrum through which pus drains."))
story.append(hr())
story += [q(24, "In sickle cell disease, the most common organism causing osteomyelitis is:")]
story += opts("Staphylococcus aureus", "Streptococcus pneumoniae", "Salmonella typhi", "Pseudomonas")
story.append(ans("C", "Salmonella typhi"))
story.append(exp("In sickle cell disease, although Staph aureus remains important, Salmonella species (particularly S. typhi and S. paratyphi) are CLASSICALLY associated with osteomyelitis and is the most frequently asked organism in this context. The infarcted bone in sickle cell disease provides a good nidus for Salmonella."))
story.append(hr())
story += [q(25, "Septic arthritis is most commonly caused by:")]
story += opts("E. coli", "N. gonorrhoeae", "Staphylococcus aureus", "Haemophilus influenzae")
story.append(ans("C", "Staphylococcus aureus"))
story.append(exp("Staphylococcus aureus is the most common cause of septic arthritis in ALL age groups except: sexually active young adults where Neisseria gonorrhoeae is most common. The hip is the most commonly affected joint in children (emergency – avascular necrosis if not drained urgently). Kocher criteria for septic hip: fever >38.5°C, non-weight-bearing, ESR >40 mm/hr, WBC >12,000/mm³."))
story.append(hr())
story.append(PageBreak())
# ──────────────── SECTION 5: ARTHRITIS ────────────────
story.append(ch(" SECTION 5: ARTHRITIS"))
story.append(sec("Comparison Table"))
arth_data = [
['Feature', 'Osteoarthritis', 'Rheumatoid Arthritis', 'Gout'],
['Age', '>40 yr', '30–50 yr', '40–50 yr (M)'],
['Gender', 'F > M', 'F > M (3:1)', 'M >> F'],
['Joints', 'Weight-bearing (hip, knee)', 'Small joints (MCP, PIP, wrist)', 'First MTP (podagra)'],
['Pattern', 'Asymmetric', 'Bilateral symmetric', 'Asymmetric'],
['Pathology', 'Cartilage loss', 'Synovial inflammation', 'Urate crystal deposition'],
['X-ray', 'Joint space ↓, osteophytes, subchondral sclerosis', 'Periarticular erosions, osteopenia, joint space ↓', 'Punched-out erosions, overhanging edge'],
['Special', 'Heberden (DIP), Bouchard (PIP)', 'Pannus, Swan neck, Boutonniere', 'Tophi, negatively birefringent crystals'],
]
at = Table(arth_data, colWidths=[3.2*cm, 4.2*cm, 4.5*cm, 4.5*cm])
at.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1a237e')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8),
('ALIGN', (0,0), (-1,-1), 'LEFT'),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.white, colors.HexColor('#e8eaf6')]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#9fa8da')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(at)
story.append(Spacer(1, 0.2*cm))
story += [q(26, "Heberden's nodes are characteristically seen in:")]
story += opts("Rheumatoid arthritis", "Gout", "Osteoarthritis", "Psoriatic arthritis")
story.append(ans("C", "Osteoarthritis"))
story.append(exp("Heberden's nodes = osteophytes at DIP joints (Distal InterPhalangeal) – seen in OA. Bouchard's nodes = osteophytes at PIP joints – also in OA. RA affects MCP and PIP joints (DIP joints spared). Gout → tophi (urate crystal deposits). Psoriatic arthritis → DIP joints affected with nail changes."))
story.append(hr())
story += [q(27, "The crystal seen in pseudogout (calcium pyrophosphate disease) is:")]
story += opts("Monosodium urate (negatively birefringent)", "Calcium pyrophosphate (weakly positively birefringent)", "Hydroxyapatite", "Calcium oxalate")
story.append(ans("B", "Calcium pyrophosphate (weakly positively birefringent)"))
story.append(exp("Pseudogout (CPPD disease): Calcium pyrophosphate crystals – weakly positively birefringent (yellow when parallel to compensator). X-ray shows chondrocalcinosis (calcification of cartilage, especially menisci and fibrocartilage). Most common joint: KNEE. Gout: Monosodium urate – negatively birefringent (blue when parallel to compensator)."))
story.append(hr())
story.append(PageBreak())
# ──────────────── SECTION 6: METABOLIC BONE ────────────────
story.append(ch(" SECTION 6: METABOLIC BONE DISEASE"))
story.append(sec("Key Comparisons"))
mbd_data = [
['Disease', 'Pathology', 'Ca²⁺', 'PO₄', 'ALP', 'PTH', 'Characteristic'],
['Osteoporosis', 'Reduced bone mass, normal mineralization', 'N', 'N', 'N', 'N', 'Most common metabolic bone disease'],
['Osteomalacia', 'Failure of bone mineralization (Vit D deficiency)', '↓', '↓', '↑↑', '↑', 'Looser zones (pseudofractures) on X-ray'],
['Paget disease', 'Increased bone turnover (remodeling)', 'N', 'N', '↑↑↑', 'N', 'Mosaic pattern histology; risk of osteosarcoma'],
['Hyperparathyroidism', 'Excess PTH → bone resorption', '↑', '↓', '↑', '↑↑', 'Subperiosteal resorption (radial side middle phalanx)'],
['Rickets', 'Vit D deficiency in children', '↓', '↓', '↑', '↑', 'Widened growth plate, cupping, fraying'],
]
mt = Table(mbd_data, colWidths=[3.2*cm, 4.2*cm, 1*cm, 1*cm, 1*cm, 1*cm, 5*cm])
mt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1a237e')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8),
('ALIGN', (0,0), (-1,-1), 'CENTER'),
('ALIGN', (0,0), (1,-1), 'LEFT'),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.white, colors.HexColor('#e8eaf6')]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#9fa8da')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(mt)
story.append(Spacer(1, 0.2*cm))
story += [q(28, "Looser's zones (pseudofractures) are characteristic of:")]
story += opts("Paget disease", "Hyperparathyroidism", "Osteomalacia", "Multiple myeloma")
story.append(ans("C", "Osteomalacia"))
story.append(exp("Looser zones = transverse linear lucencies (incomplete fractures) in cortical bone – hallmark of OSTEOMALACIA. Common sites: medial femoral neck, pubic rami, scapulae. Caused by vitamin D deficiency in adults (rickets in children). Biochemistry: low Ca, low PO4, high ALP, high PTH (secondary hyperparathyroidism)."))
story.append(hr())
story += [q(29, "Paget's disease of bone increases the risk of developing:")]
story += opts("Osteoid osteoma", "Osteosarcoma", "Ewing sarcoma", "Multiple myeloma")
story.append(ans("B", "Osteosarcoma"))
story.append(exp("Paget's disease (osteitis deformans) has <1% risk of malignant transformation to osteosarcoma (sarcomatous change in pagetic bone). Very poor prognosis when this occurs. ALP is markedly elevated. X-ray: 'cotton wool' skull, 'picture frame' vertebrae, sabre tibia. Histology: mosaic/jigsaw pattern of cement lines."))
story.append(hr())
story.append(PageBreak())
# ──────────────── SECTION 7: NERVE INJURIES ────────────────
story.append(ch(" SECTION 7: NERVE INJURIES"))
story.append(sec("Seddon vs Sunderland Classification"))
nerve_data = [
['Seddon', 'Sunderland', 'Pathology', 'Recovery'],
['Neuropraxia', 'Grade I', 'Conduction block only, no structural damage', 'Complete, weeks'],
['Axonotmesis', 'Grade II', 'Axon disrupted, endoneurium intact', 'Complete, months (1 mm/day)'],
['Axonotmesis', 'Grade III', 'Axon + endoneurium disrupted', 'Incomplete'],
['Axonotmesis', 'Grade IV', 'All disrupted except epineurium', 'Poor, needs surgery'],
['Neurotmesis', 'Grade V', 'Complete nerve division', 'None without surgery'],
]
nt = Table(nerve_data, colWidths=[3.5*cm, 2.5*cm, 6.5*cm, 4*cm])
nt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1a237e')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.white, colors.HexColor('#e8eaf6')]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#9fa8da')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(nt)
story.append(Spacer(1, 0.2*cm))
story.append(sec("Common Nerve Injury Associations"))
nerve2_data = [
['Fracture/Injury', 'Nerve Injured', 'Deformity / Deficit'],
['Clavicle fracture (middle 1/3)', 'Brachial plexus / Subclavian artery', 'Subclavian vessel injury'],
['Shoulder dislocation (anterior)', 'Axillary nerve (circumflex)', 'Loss of deltoid, loss of regimental badge area sensation'],
['Spiral # humerus shaft', 'Radial nerve', 'Wrist drop (Saturday night palsy)'],
['Supracondylar # humerus (child)', 'Anterior Interosseous N (PIN)', 'Loss of FPL + FDP index; OK sign negative'],
['Medial epicondyle fracture', 'Ulnar nerve', 'Claw hand (ring and little finger)'],
['Fracture lateral condyle humerus', 'Radial nerve (PIN)', 'Wrist/finger drop'],
['Hip dislocation (posterior)', 'Sciatic nerve', 'Foot drop + sensory loss'],
['Knee dislocation / fibula # neck', 'Common peroneal nerve', 'Foot drop (dorsiflexion/eversion weak)'],
['Wrist (carpal tunnel)', 'Median nerve', 'Ape hand, Thenar wasting, Tinel/Phalen +ve'],
]
nt2 = Table(nerve2_data, colWidths=[5.5*cm, 4*cm, 7*cm])
nt2.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#283593')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8.5),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.white, colors.HexColor('#e8eaf6')]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#9fa8da')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(nt2)
story.append(Spacer(1, 0.2*cm))
story += [q(30, "Wrist drop following fracture of the shaft of humerus is due to injury to:")]
story += opts("Ulnar nerve", "Median nerve", "Radial nerve", "Musculocutaneous nerve")
story.append(ans("C", "Radial nerve"))
story.append(exp("The radial nerve winds around the spiral groove (radial groove) of the humerus in the middle third. Fracture at this level = radial nerve injury = WRIST DROP (inability to extend wrist and fingers). Also: weakened brachioradialis, loss of finger extension. Sensation lost over anatomical snuffbox (first dorsal web space). Known as 'Saturday night palsy' when due to compression."))
story.append(hr())
story += [q(31, "Claw hand deformity after medial epicondyle fracture is due to injury to:")]
story += opts("Radial nerve", "Median nerve", "Ulnar nerve", "Anterior interosseous nerve")
story.append(ans("C", "Ulnar nerve"))
story.append(exp("Ulnar nerve passes posterior to medial epicondyle and is vulnerable in medial epicondyle fractures or cubital tunnel compression. Ulnar nerve palsy = Claw hand (ring and little finger most affected – intrinsic minus hand). Froment's sign (compensates for weak adductor pollicis), Wartenberg's sign (abducted little finger). Hypothenar wasting."))
story.append(hr())
story.append(PageBreak())
# ──────────────── SECTION 8: SPINE ────────────────
story.append(ch(" SECTION 8: SPINE DISORDERS"))
story.append(sec("Disc Herniation"))
story.append(body("<b>Most common level:</b> L4-L5 and L5-S1 (90% of all lumbar disc herniations)."))
story.append(body("<b>L4-L5 disc → L5 nerve root:</b> Foot drop (EHL weak), numbness first web space dorsum of foot. SLR positive."))
story.append(body("<b>L5-S1 disc → S1 nerve root:</b> Weak plantar flexion (gastrocnemius), absent ankle jerk, numbness lateral border of foot."))
story.append(body("<b>C5-C6 disc → C6 root:</b> Biceps weakness, reduced biceps jerk, sensory loss lateral forearm."))
story.append(body("<b>C6-C7 disc → C7 root:</b> Triceps weakness, reduced triceps jerk."))
story += [q(32, "L5-S1 disc herniation typically produces:")]
story += opts("Absent knee jerk + quadriceps weakness", "Absent ankle jerk + plantar flexion weakness", "Foot drop + first web space numbness", "Absent biceps jerk")
story.append(ans("B", "Absent ankle jerk + plantar flexion weakness"))
story.append(exp("L5-S1 → S1 nerve root compression: weak plantar flexion (calf muscles/gastrocnemius), ABSENT ankle jerk, sensory loss on lateral border of foot and sole. L4-L5 → L5 root: weak foot dorsiflexion (especially EHL), foot drop, numbness first web space (dorsum of foot), ankle jerk may be present."))
story.append(hr())
story.append(sec("Tuberculosis of Spine (Pott's Disease)"))
story.append(body("<b>Most common site:</b> Thoracolumbar junction (T10-L2)."))
story.append(body("<b>Pathology:</b> Disc + vertebral body involvement → disc space destruction → paradiscal/central/anterior lesion. Cold abscess (psoas abscess tracks along psoas sheath to inguinal region/groin). Angular kyphosis (Gibbus). Spinal cord compression → Pott's paraplegia."))
story.append(body("<b>Treatment:</b> ATT (HRZE × 2 months → HR × 7 months). Surgery (anterior debridement + fusion) for progressive neurological deficit, unstable deformity, or failed medical treatment."))
story += [q(33, "Pott's disease most commonly affects:")]
story += opts("Cervical spine", "Thoracic spine", "Thoracolumbar junction", "Lumbar spine")
story.append(ans("C", "Thoracolumbar junction"))
story.append(exp("TB spine (Pott's disease) most commonly affects the thoracolumbar junction (T10-L2). Unlike pyogenic osteomyelitis, TB has relative sparing of the disc early in the disease (avascular disc lacks blood supply for haematogenous spread). MRI is the investigation of choice. Cold psoas abscess is a classic feature."))
story.append(hr())
story.append(PageBreak())
# ──────────────── SECTION 9: REGIONAL ────────────────
story.append(ch(" SECTION 9: REGIONAL DISORDERS"))
story += [q(34, "Painful arc syndrome (painful arc 60°–120°) is due to impingement of:")]
story += opts("Biceps tendon", "Supraspinatus tendon", "Subscapularis tendon", "Infraspinatus tendon")
story.append(ans("B", "Supraspinatus tendon"))
story.append(exp("Painful arc (60–120°) = impingement of SUPRASPINATUS tendon under the acromion. Full arc 0–60° painless (deltoid elevates), 60–120° painful (supraspinatus impinged), >120° painless (deltoid + trapezius take over). Neer test and Hawkins test positive. Treatment: physiotherapy, corticosteroid injection, acromioplasty."))
story.append(hr())
story += [q(35, "The most common cause of knee pain in a young active adult presenting with anterior knee pain is:")]
story += opts("Osteoarthritis", "Meniscal tear", "Patellofemoral pain syndrome", "Osgood-Schlatter disease")
story.append(ans("C", "Patellofemoral pain syndrome"))
story.append(exp("Patellofemoral pain syndrome (PFPS / 'runner's knee') = most common cause of anterior knee pain in young adults. Pain behind/around patella, worsened by stairs, squatting, prolonged sitting ('theatre sign'). Clarke's test (patellar grind) positive. Osgood-Schlatter = tibial tubercle apophysitis in adolescents during growth spurts."))
story.append(hr())
story += [q(36, "McMurray test is used to diagnose:")]
story += opts("ACL tear", "PCL tear", "Meniscal tear", "Patellar instability")
story.append(ans("C", "Meniscal tear"))
story.append(exp("McMurray test: Flex knee fully, externally rotate foot + extend = medial meniscus tear (pain/click on medial side). Internally rotate foot + extend = lateral meniscus tear. MRI is investigation of choice for meniscal pathology. Medial meniscus torn more than lateral (4:1) because it is less mobile (attached to MCL)."))
story.append(hr())
story += [q(37, "De Quervain's tenosynovitis affects the tendons in the first dorsal compartment of the wrist. The pathognomonic test is:")]
story += opts("Tinel's sign", "Finkelstein's test", "Froment's sign", "Phalen's test")
story.append(ans("B", "Finkelstein's test"))
story.append(exp("De Quervain's tenosynovitis = stenosing tenosynovitis of Abductor Pollicis Longus (APL) and Extensor Pollicis Brevis (EPB) in the first dorsal compartment. Finkelstein's test: close fingers over thumb, then ulnar deviate the wrist – PAIN over radial styloid = positive. Treatment: rest, NSAIDs, corticosteroid injection; surgery if conservative fails."))
story.append(hr())
story.append(PageBreak())
# ──────────────── SECTION 10: QUICK REVISION ────────────────
story.append(ch(" SECTION 10: RAPID REVISION – HIGH-YIELD FACTS"))
facts = [
("Most common fracture in elderly women", "Colles fracture (distal radius)"),
("Most common carpal fracture", "Scaphoid (waist)"),
("Dinner fork deformity", "Colles fracture"),
("Garden spade deformity", "Smith fracture"),
("Most common malignant bone tumour overall", "Multiple myeloma (metastatic bone disease)"),
("Most common primary malignant bone tumour in children", "Osteosarcoma"),
("Codman triangle + Sunburst", "Osteosarcoma"),
("Onion peel periosteal reaction", "Ewing sarcoma"),
("Soap bubble lytic epiphyseal lesion", "Giant cell tumour (GCT)"),
("Night pain relieved by aspirin", "Osteoid osteoma"),
("No chemotherapy/radiotherapy effective", "Chondrosarcoma"),
("Paget's disease → sarcoma", "Osteosarcoma"),
("Most common benign bone tumour", "Osteochondroma (exostosis)"),
("CTEV deformities (CAVE)", "Cavus, Adductus, Varus, Equinus"),
("Gold standard CTEV treatment", "Ponseti method"),
("DDH clinical test 0–3 months", "Ortolani (reduces) + Barlow (dislocates)"),
("DDH treatment 0–6 months", "Pavlik harness"),
("Most common organism – osteomyelitis", "Staphylococcus aureus"),
("Osteomyelitis in sickle cell", "Salmonella species"),
("Brodie's abscess", "Subacute osteomyelitis (S. aureus)"),
("Pott's disease most common site", "Thoracolumbar junction (T10-L2)"),
("Radial nerve injury → fracture site", "Spiral groove (mid-shaft humerus)"),
("Anterior shoulder dislocation → nerve", "Axillary nerve"),
("Medial epicondyle fracture → nerve", "Ulnar nerve → claw hand"),
("Looser's zones", "Osteomalacia (Vitamin D deficiency)"),
("Subperiosteal bone resorption (radial side of middle phalanx)", "Hyperparathyroidism"),
("L5-S1 → S1 root", "Absent ankle jerk, plantar flexion weak"),
("Finkelstein test +ve", "De Quervain tenosynovitis"),
("McMurray test +ve", "Meniscal tear"),
("Painful arc 60–120°", "Supraspinatus tendon impingement"),
("Kocher criteria (septic hip) – 4 features", "Fever, non-WB, ESR >40, WBC >12000"),
("DHS (Dynamic Hip Screw) – for", "Intertrochanteric femur fracture"),
("Intertrochanteric vs Subcapital fracture – blood supply", "NOF fracture → AVN risk (retinacular vessels)"),
("Garden classification for", "Intracapsular neck of femur fractures"),
("Chance fracture", "Lumbar flexion-distraction, seat belt injury"),
("Jefferson fracture", "C1 burst fracture from axial compression"),
]
# Display as 2-column table
qr_data = [['High-Yield Fact', 'Answer']]
for f, a in facts:
qr_data.append([f, a])
qrt = Table(qr_data, colWidths=[8.5*cm, 8*cm])
qrt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1a237e')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8.5),
('ALIGN', (0,0), (-1,-1), 'LEFT'),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.white, colors.HexColor('#e8eaf6')]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#9fa8da')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
]))
story.append(qrt)
story.append(PageBreak())
# ──────────────── FINAL PAGE ────────────────
story.append(Spacer(1, 1*cm))
story.append(Paragraph("UPSC CMS 2026 – ORTHOPAEDICS EXAM STRATEGY", title_style))
story.append(Spacer(1, 0.3*cm))
strategy_items = [
"Focus on FRACTURES (3–4 Qs per paper) – know the classic X-ray findings and nerve injuries.",
"BONE TUMOURS are consistent favourites – memorise the tumour table.",
"CTEV + DDH appear almost every year – Ponseti method and Pavlik harness are key.",
"Know the organisms for osteomyelitis (especially Salmonella in sickle cell).",
"Nerve injury associations with fractures – very commonly asked.",
"Metabolic bone disease labs table – one factual question guaranteed.",
"Pott's disease (TB spine) – site, complications, cold abscess.",
"Arthritis comparison: OA vs RA vs Gout – know the crystals!",
"Solve 5 years of UPSC CMS PYQs (2020–2025) under timed conditions.",
"UPSC CMS 2026 exam is on 2 August 2026 – focus on accuracy, not speed.",
]
for i, item in enumerate(strategy_items, 1):
story.append(body(f"{i}. {item}"))
story.append(Spacer(1, 0.5*cm))
story.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor('#1a237e'), spaceAfter=6))
story.append(Paragraph("Reference: Campbell's Operative Orthopaedics 15th Ed 2026 | Miller's Review of Orthopaedics 9th Ed | UPSC CMS PYQ Analysis 2010–2025", subtitle_style))
# Build PDF
doc.build(story)
print(f"PDF generated: {OUTPUT}")
cd /tmp/workspace/upsc-cms-ortho && python generate_ortho_pdf.py
ls -lh /tmp/workspace/upsc-cms-ortho/UPSC_CMS_Orthopaedics_PYQ_Notes.pdf
UPSC CMS Orthopaedics PYQ Notes
PDF Document · PDF
| Section | Topics Covered |
|---|---|
| 1. Fractures & Dislocations | Colles, Smith, Barton, Monteggia, Galeazzi, Bennett, Scaphoid, NOF, Intertrochanteric, Spine fractures |
| 2. Bone Tumours | Full classification table: Osteosarcoma, Ewing, Chondrosarcoma, GCT, Osteoid osteoma, ABC, SBC |
| 3. Congenital Disorders | CTEV (Ponseti method, CAVE deformities), DDH (Ortolani/Barlow, Pavlik), Torticollis |
| 4. Infections | Acute osteomyelitis (organisms, X-ray timeline, Brodie's abscess), Septic arthritis, Kocher criteria |
| 5. Arthritis | OA vs RA vs Gout comparison table, Pseudogout, crystals |
| 6. Metabolic Bone Disease | Osteoporosis, Osteomalacia, Paget, Hyperparathyroidism, Rickets - with Ca/PO4/ALP/PTH table |
| 7. Nerve Injuries | Seddon-Sunderland classification, fracture-to-nerve injury association table |
| 8. Spine | PID disc levels (L4-5, L5-S1), Pott's disease (TB spine) |
| 9. Regional Disorders | Painful arc, Patellofemoral pain, McMurray test, De Quervain's |
| 10. Rapid Revision | 36-row one-liner table of the most frequently tested ortho facts |