Mbbs 1st year upper limb 10 marks questions guess
MBBS 1st year upper limb anatomy 10 marks important questions exam
https://anatomyqa.com/upper-limb-anatomy-important-questions
| Clinical Scenario | Underlying Anatomy |
|---|---|
| Wrist drop after fracture shaft humerus | Radial nerve injury at spiral groove |
| Claw hand after medial epicondyle fracture | Ulnar nerve injury |
| Ape thumb deformity | Median nerve (thenar wasting) |
| Winged scapula | Long thoracic nerve (serratus anterior paralysis) |
| Erb's palsy (waiter's tip) | C5-C6 injury (upper trunk) |
| Klumpke's palsy (claw hand) | C8-T1 injury (lower trunk) |
| Peau d'orange in breast carcinoma | Lymphatic obstruction of superficial lymphatics |
| Scaphoid fracture - avascular necrosis | Blood supply enters distal fragment first |
| Painful arc (60-120°) | Supraspinatus tear/impingement |
| Carpal tunnel syndrome | Median nerve compression under flexor retinaculum |
Make a quick pdf reference on upper limb 10 marks clinical applied reasoning
ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or not accessible"
mkdir -p /home/daytona/workspace/upper-limb-pdf && python3 -c "import reportlab; print('reportlab ok')"
~/upper-limb-pdf/generate_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 cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.lib.colors import HexColor
OUTPUT = "/home/daytona/workspace/upper-limb-pdf/Upper_Limb_Clinical_Applied_Reasoning.pdf"
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=1.8*cm, leftMargin=1.8*cm,
topMargin=2*cm, bottomMargin=2*cm
)
# ── Colours ──────────────────────────────────────────────────────────────────
NAVY = HexColor("#1a2e4a")
TEAL = HexColor("#1d7874")
AMBER = HexColor("#e07b39")
LIGHT_BG = HexColor("#f0f6fb")
YELLOW_BG = HexColor("#fff8e7")
GREEN_BG = HexColor("#eaf7f0")
RED_BG = HexColor("#fff0f0")
TABLE_HDR = HexColor("#1d7874")
ROW_ALT = HexColor("#f4faf9")
WHITE = colors.white
BLACK = colors.black
styles = getSampleStyleSheet()
def S(name, **kw):
"""Create a named ParagraphStyle."""
return ParagraphStyle(name, **kw)
cover_title = S("CoverTitle", fontSize=26, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, leading=32)
cover_sub = S("CoverSub", fontSize=13, textColor=HexColor("#cce8ff"),
fontName="Helvetica", alignment=TA_CENTER, leading=18)
cover_note = S("CoverNote", fontSize=10, textColor=HexColor("#a8d8ea"),
fontName="Helvetica-Oblique", alignment=TA_CENTER, leading=14)
sec_title = S("SecTitle", fontSize=15, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_LEFT, leading=20,
spaceAfter=4, spaceBefore=6)
sub_title = S("SubTitle", fontSize=11, textColor=NAVY,
fontName="Helvetica-Bold", alignment=TA_LEFT,
spaceBefore=8, spaceAfter=2)
body = S("Body", fontSize=9.5, textColor=HexColor("#222222"),
fontName="Helvetica", leading=14, alignment=TA_JUSTIFY,
spaceAfter=4)
bullet = S("Bullet", fontSize=9.5, textColor=HexColor("#1a2e4a"),
fontName="Helvetica", leading=13, leftIndent=14,
firstLineIndent=-10, spaceAfter=2)
bold_bullet = S("BoldBullet", fontSize=9.5, textColor=NAVY,
fontName="Helvetica-Bold", leading=13, leftIndent=14,
firstLineIndent=-10, spaceAfter=1)
answer_key = S("AnswerKey", fontSize=9, textColor=HexColor("#155724"),
fontName="Helvetica", leading=13, leftIndent=10)
# ── Helper: section header banner ────────────────────────────────────────────
def section_header(title, color=NAVY):
data = [[Paragraph(title, sec_title)]]
t = Table(data, colWidths=[17.4*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), 12),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [5]),
]))
return t
def tip_box(text, bg=YELLOW_BG, border=AMBER):
data = [[Paragraph(text, body)]]
t = Table(data, colWidths=[17.4*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING",(0,0), (-1,-1), 7),
("BOX", (0,0), (-1,-1), 1.5, border),
("ROUNDEDCORNERS", [4]),
]))
return t
def two_col_table(rows, col1=8.5*cm, col2=8.9*cm):
data = [["Injury / Scenario", "Anatomical Explanation"]]
data += rows
t = Table(data, colWidths=[col1, col2])
ts = TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HDR),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 9.5),
("FONTNAME", (0,1), (-1,-1), "Helvetica"),
("FONTSIZE", (0,1), (-1,-1), 9),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, ROW_ALT]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#c0dbd9")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 7),
("RIGHTPADDING", (0,0), (-1,-1), 7),
])
t.setStyle(ts)
return t
# ═══════════════════════════════════════════════════════════════════════════════
# BUILD STORY
# ═══════════════════════════════════════════════════════════════════════════════
story = []
# ── COVER ─────────────────────────────────────────────────────────────────────
cover_data = [[
Paragraph("UPPER LIMB", cover_title),
Paragraph("Clinical Applied Reasoning", cover_sub),
Paragraph("10-Mark Questions Reference Guide", cover_sub),
Spacer(1, 0.3*cm),
Paragraph("MBBS 1st Year • Anatomy", cover_note),
Paragraph("Based on past-paper trends & standard curriculum", cover_note),
]]
cover_table = Table([[item] for item in [
Paragraph("UPPER LIMB", cover_title),
Spacer(1, 0.2*cm),
Paragraph("Clinical Applied Reasoning", cover_sub),
Paragraph("10-Mark Questions | Reference Guide", cover_sub),
Spacer(1, 0.4*cm),
Paragraph("MBBS 1st Year • Anatomy", cover_note),
Paragraph("Based on past-paper trends & standard curriculum", cover_note),
]], colWidths=[17.4*cm])
cover_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("TOPPADDING", (0,0), (-1,-1), 14),
("BOTTOMPADDING", (0,0), (-1,-1), 14),
("LEFTPADDING", (0,0), (-1,-1), 20),
("RIGHTPADDING", (0,0), (-1,-1), 20),
("ROUNDEDCORNERS", [8]),
]))
story.append(cover_table)
story.append(Spacer(1, 0.5*cm))
story.append(tip_box(
"<b>How to use this guide:</b> Each section covers one high-yield topic. "
"For every clinical scenario, first state <i>which nerve/structure is injured</i>, "
"then explain <i>why</i> anatomically, then give the <i>sign/deformity</i>. "
"That structure = guaranteed marks.",
bg=LIGHT_BG, border=TEAL
))
story.append(Spacer(1, 0.4*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# 1. NERVE INJURIES MASTER TABLE
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("1. Nerve Injuries - Master Clinical Table", NAVY))
story.append(Spacer(1, 0.2*cm))
nerve_rows = [
["Fracture of surgical neck of humerus",
"Axillary nerve (C5,C6) injured. Deltoid paralysis → loss of abduction 15°-90°. "
"Loss of sensation: regimental badge area (upper lateral arm)."],
["Fracture of shaft / mid-humerus (spiral groove)",
"Radial nerve injured. Wrist drop (extensors paralysed). Spared: triceps (branch given above groove). "
"Lost: ECRL, ECRB, finger extensors. Sensory loss: dorsal 1st web space."],
["Axillary nerve injury (shoulder dislocation)",
"Anterior-inferior dislocation stretches axillary nerve. Deltoid wasting + sensory loss over regimental badge area."],
["Fracture of medial epicondyle",
"Ulnar nerve (C7,C8,T1) compressed/injured. Claw hand (ring+little fingers). "
"Wasting of hypothenar + interossei. Froment's sign positive. Sensory: medial 1.5 fingers."],
["Supracondylar fracture of humerus (child)",
"Anterior interosseous nerve (branch of median) OR median nerve proper. "
"Anterior AIN: cannot flex distal phalanx of index + thumb → 'OK sign' absent. "
"High median: hand of benediction (index+middle cannot flex)."],
["Carpal tunnel syndrome",
"Median nerve compressed under flexor retinaculum. Thenar wasting, ape thumb. "
"Tingling/numbness: lateral 3.5 fingers. Night pain. Positive Tinel's + Phalen's test."],
["Ulnar nerve at wrist (Guyon's canal)",
"Only deep branch: pure motor loss (interossei, hypothenar, adductor pollicis). "
"No sensory loss (dorsal cutaneous branch leaves proximal to wrist)."],
["Mastectomy / stab wound to lateral chest wall",
"Long thoracic nerve (C5,C6,C7) to serratus anterior. Winging of scapula: medial border lifts when pushing against wall."],
["Saturday night palsy (crutch palsy)",
"Radial nerve compressed in axilla (against humerus). Complete wrist drop + triceps paralysis + sensory loss entire radial distribution."],
["Klumpke's palsy (C8,T1) - difficult labour",
"Lower trunk brachial plexus. Total claw hand. Intrinsic muscle wasting. "
"If T1 sympathetics involved: Horner's syndrome (ptosis, miosis, anhidrosis)."],
["Erb's palsy (C5,C6) - birth / shoulder injury",
"Upper trunk brachial plexus. Waiter's tip: arm adducted+medially rotated, elbow extended, forearm pronated. "
"Deltoid, supraspinatus, biceps, brachioradialis paralysed."],
]
story.append(two_col_table(nerve_rows))
story.append(Spacer(1, 0.4*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# 2. BRACHIAL PLEXUS CLINICAL REASONING
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("2. Brachial Plexus - Applied Anatomy (10-Mark Framework)", TEAL))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("Formation at a glance:", sub_title))
story.append(Paragraph("• Roots: Ventral rami C5, C6, C7, C8, T1", bullet))
story.append(Paragraph("• Trunks: Upper (C5+C6), Middle (C7), Lower (C8+T1)", bullet))
story.append(Paragraph("• Divisions: Each trunk → anterior + posterior", bullet))
story.append(Paragraph("• Cords: Lateral (ant. upper+middle), Medial (ant. lower), Posterior (all post. divisions)", bullet))
story.append(Paragraph("• Terminal branches: Musculocutaneous, Median (both heads), Ulnar, Radial, Axillary", bullet))
story.append(Spacer(1, 0.2*cm))
story.append(tip_box(
"<b>Memory trick:</b> 'Robert Taylor Drinks Cold Beer' = Roots, Trunks, Divisions, Cords, Branches.<br/>"
"<b>Lateral cord branches:</b> 'LLC' = Lateral pectoral, Lateral root of median, musculoCutaneous.<br/>"
"<b>Medial cord branches:</b> 'MMMMU' = Medial pectoral, Medial cutaneous of arm/forearm, Medial root of Median, Ulnar.",
bg=YELLOW_BG, border=AMBER
))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("Injury levels and signs:", sub_title))
bp_rows = [
["Upper trunk (C5,C6) - Erb's", "Waiter's tip deformity. Deltoid/supraspinatus paralysis. Sensory: lateral arm+forearm."],
["Lower trunk (C8,T1) - Klumpke's", "Claw hand. All intrinsics lost. Horner's if T1 sympathetics involved."],
["Lateral cord", "Musculocutaneous + lateral root median lost. Weak flexion at elbow; median motor half lost."],
["Medial cord", "Ulnar + medial root median lost. Claw hand + thenar wasting."],
["Posterior cord", "Axillary + radial lost. Wrist drop + deltoid paralysis. Sensory: whole posterior limb."],
]
bp_table = Table([["Injury Level", "Clinical Features"]] + bp_rows, colWidths=[6*cm, 11.4*cm])
bp_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("FONTNAME", (0,1), (-1,-1), "Helvetica"),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, ROW_ALT]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#c0dbd9")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 7),
]))
story.append(bp_table)
story.append(Spacer(1, 0.4*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# 3. DEFORMITIES EXPLAINED
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("3. Deformities - Why They Occur (Explain-Why Questions)", NAVY))
story.append(Spacer(1, 0.2*cm))
deformity_data = [
["<b>Wrist Drop</b>",
"Radial nerve in spiral groove. All wrist/finger extensors paralysed (ECRL, ECRB, EDC, EPL). "
"Flexors unopposed → wrist drops. Triceps spared (branch above groove)."],
["<b>Claw Hand (Ulnar)</b>",
"Ulnar nerve at elbow. Interossei + lumbricals 3&4 lost. Cannot extend IP joints. "
"Paradox: more claw in wrist injury (FDP intact) than elbow injury."],
["<b>Ape Thumb / Ape Hand</b>",
"Median nerve (carpal tunnel or high lesion). Thenar muscles (APB, FPB, OP) wasted. "
"Thumb falls in plane of palm (adducted). Opposition lost."],
["<b>Waiter's Tip (Erb's)</b>",
"C5,C6 injury. Deltoid+supraspinatus: abduction lost. Biceps+brachialis: flexion+supination lost. "
"Pectoralis+subscapularis: adduction+medial rotation maintained → classic posture."],
["<b>Winged Scapula</b>",
"Long thoracic nerve (C5,6,7). Serratus anterior paralysed. Cannot hold medial border against thorax. "
"Winging worst when pushing forward against resistance."],
["<b>Painful Arc (60°-120°)</b>",
"Supraspinatus tendon impinges under coracoacromial arch in this range only. "
"Below 60°: supraspinatus not yet under arch. Above 120°: tendon rotates clear."],
["<b>Total Claw Hand</b>",
"Median + Ulnar nerve both injured (combined lesion). All lumbricals + interossei lost. "
"All 4 fingers claw. Both thenar and hypothenar wasted."],
]
for row in deformity_data:
story.append(KeepTogether([
Table([[Paragraph(row[0], bold_bullet), Paragraph(row[1], body)]],
colWidths=[4.5*cm, 12.9*cm],
style=TableStyle([
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 4),
("LINEBELOW", (0,0), (-1,0), 0.3, HexColor("#d0e8e8")),
])),
]))
story.append(Spacer(1, 0.4*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# 4. BREAST CARCINOMA APPLIED
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("4. Breast Carcinoma - Applied Anatomy (Favourite 10-Marker)", TEAL))
story.append(Spacer(1, 0.2*cm))
story.append(tip_box(
"<b>Lymphatic drainage of breast:</b> 75% → axillary nodes (mainly anterior/pectoral group). "
"25% → parasternal (internal thoracic) nodes along internal thoracic artery. "
"Also: posterior intercostal, infraclavicular, supraclavicular nodes.",
bg=GREEN_BG, border=TEAL
))
story.append(Spacer(1, 0.2*cm))
breast_data = [
["Peau d'orange\n(orange peel skin)",
"Carcinoma invades superficial lymphatics → lymphoedema of skin. Cooper's ligaments tether skin dimples appear. Skin looks like orange peel."],
["Skin dimpling / retraction",
"Tumour invades and shortens Cooper's (suspensory) ligaments. These ligaments attach skin to underlying breast tissue. Shortening pulls skin inward."],
["Nipple retraction",
"Tumour invades lactiferous sinuses or ducts beneath nipple. Fibrous reaction shortens ducts → nipple pulled inward."],
["Axillary lymph node enlargement",
"75% drainage to axilla. Upper outer quadrant carcinoma → anterior (pectoral) group first. "
"Fixed, hard, matted nodes = metastatic spread."],
["Paget's disease of nipple",
"Intraductal carcinoma extending up lactiferous ducts to skin of nipple. Eczema-like appearance of nipple. "
"Always indicates underlying malignancy."],
["Arm oedema post-mastectomy",
"Axillary node clearance + radiotherapy blocks lymphatic drainage of whole upper limb → "
"intractable lymphoedema of arm."],
]
breast_table = Table([["Sign", "Anatomical Basis"]] + breast_data, colWidths=[4.5*cm, 12.9*cm])
breast_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("FONTNAME", (0,1), (-1,-1), "Helvetica"),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREEN_BG]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#c0dbd9")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 7),
]))
story.append(breast_table)
story.append(Spacer(1, 0.4*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# 5. SHOULDER & JOINTS
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("5. Shoulder Joint & Rotator Cuff - Applied", NAVY))
story.append(Spacer(1, 0.2*cm))
story.append(tip_box(
"<b>\"Shoulder joint sacrifices stability for mobility\"</b> - This statement is the most asked explain-why "
"in upper limb. Key points: shallow glenoid fossa (only covers 1/3 of head), "
"lax capsule (allows wide movement), rotator cuff provides dynamic stability instead of bony stability.",
bg=YELLOW_BG, border=AMBER
))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph("Rotator Cuff (SITS) - Origin, Insertion, Nerve, Action:", sub_title))
sits_data = [
["Supraspinatus", "Supraspinous fossa", "Greater tubercle (upper facet)", "Suprascapular n.", "Initiates abduction 0-15°; holds head in glenoid"],
["Infraspinatus", "Infraspinous fossa", "Greater tubercle (middle facet)", "Suprascapular n.", "Lateral rotation"],
["Teres Minor", "Lateral border scapula", "Greater tubercle (lower facet)", "Axillary n.", "Lateral rotation"],
["Subscapularis", "Subscapular fossa", "Lesser tubercle", "Upper+lower subscapular n.", "Medial rotation; prevents anterior dislocation"],
]
sits_table = Table(
[["Muscle","Origin","Insertion","Nerve","Action"]] + sits_data,
colWidths=[3.2*cm, 3.5*cm, 3.5*cm, 3*cm, 4.2*cm]
)
sits_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("FONTNAME", (0,1), (-1,-1), "Helvetica"),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LIGHT_BG]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#b0c8d8")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
]))
story.append(sits_table)
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph("Applied:", sub_title))
story.append(Paragraph("• Supraspinatus most commonly torn (avascular zone near insertion; impingement under coracoacromial arch).", bullet))
story.append(Paragraph("• Anterior-inferior dislocation most common → axillary nerve stretched → deltoid paralysis.", bullet))
story.append(Paragraph("• Bankart lesion: tear of anterior glenoid labrum after dislocation.", bullet))
story.append(Paragraph("• Hill-Sachs lesion: compression fracture of posterior head of humerus after anterior dislocation.", bullet))
story.append(Spacer(1, 0.4*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# 6. CARPAL TUNNEL + ANATOMICAL SNUFF BOX
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("6. Carpal Tunnel & Anatomical Snuff Box", TEAL))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("Carpal Tunnel - Contents (9+1):", sub_title))
story.append(Paragraph(
"Roof: Flexor retinaculum (transverse carpal ligament). Floor: carpal bones.", body))
story.append(Paragraph("Contents:", sub_title))
story.append(Paragraph("• <b>9 tendons:</b> 4 FDS + 4 FDP + 1 FPL", bullet))
story.append(Paragraph("• <b>1 nerve:</b> Median nerve (most superficial; most vulnerable)", bullet))
story.append(Spacer(1, 0.15*cm))
story.append(tip_box(
"<b>Carpal Tunnel Syndrome clinical points:</b><br/>"
"Symptoms: Tingling/numbness in lateral 3.5 fingers (median distribution). Worse at night. "
"Relieved by shaking hand (flick sign).<br/>"
"Signs: Tinel's (tap on flexor retinaculum → tingling). Phalen's (wrist flexion 60 sec → symptoms).<br/>"
"Thenar wasting (APB, OP, FPB superficial head). Ape thumb (opposition lost).<br/>"
"Causes: Pregnancy, rheumatoid arthritis, hypothyroidism, acromegaly, repetitive use.",
bg=RED_BG, border=AMBER
))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("Anatomical Snuff Box:", sub_title))
story.append(Paragraph("• <b>Medial boundary:</b> Extensor pollicis longus", bullet))
story.append(Paragraph("• <b>Lateral boundary:</b> Abductor pollicis longus + Extensor pollicis brevis", bullet))
story.append(Paragraph("• <b>Floor:</b> Scaphoid (proximal) + Trapezium (distal) + Radial artery (deep)", bullet))
story.append(Paragraph("• <b>Roof:</b> Cephalic vein + Superficial branch of radial nerve", bullet))
story.append(Paragraph("• <b>Applied:</b> Tenderness in snuff box = suspect scaphoid fracture. "
"Scaphoid blood supply enters distally → proximal fragment undergoes avascular necrosis.", bullet))
story.append(Spacer(1, 0.4*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# 7. QUICK REVISION - EXPLAIN WHY TABLE
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("7. Quick Revision - 'Explain Why' Clinical Statements", NAVY))
story.append(Spacer(1, 0.2*cm))
why_rows = [
["Fracture shaft humerus → wrist drop",
"Radial nerve in spiral groove is tethered; fracture directly injures it."],
["Medial epicondyle fracture → claw hand",
"Ulnar nerve lies in groove behind medial epicondyle; avulsion/compression."],
["Shoulder joint dislocates anteriorly most often",
"Weakest capsule area is anterior-inferior (no muscle cover below subscapularis); shallow socket."],
["Scaphoid fracture → avascular necrosis of proximal pole",
"Radial artery enters scaphoid distally; fracture cuts off blood to proximal fragment."],
["Supraspinatus most commonly torn rotator cuff muscle",
"Critical avascular zone 1 cm from insertion. Constant friction under coracoacromial arch during abduction."],
["Winging of scapula on pushing against wall",
"Serratus anterior (long thoracic nerve) paralysed; no longer holds medial border against thorax."],
["Ulnar paradox: more claw at wrist than elbow",
"At elbow: FDP also paralysed, so IP joints cannot flex = less claw. "
"At wrist: FDP intact, IP joints flex maximally = full claw."],
["Peau d'orange in breast carcinoma",
"Cancer blocks superficial lymphatics; lymphoedema tethers skin at sweat gland pits."],
["Carpal tunnel symptoms worse at night",
"Recumbent position: venous congestion increases. Wrist flexion during sleep increases compression."],
["Lymphoedema of arm after mastectomy",
"Axillary node clearance removes lymphatic drainage routes for entire upper limb."],
]
story.append(two_col_table(why_rows,
col1=7.5*cm, col2=9.9*cm))
story.append(Spacer(1, 0.4*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# 8. 10-MARK ANSWER WRITING FRAMEWORK
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("8. How to Write a 10-Mark Answer (Template)", TEAL))
story.append(Spacer(1, 0.2*cm))
templates = [
("Nerve Question", [
"1. Introduction: root value, cord of origin",
"2. Course: axilla → arm → forearm → hand (segment by segment)",
"3. Branches at each level (named muscles supplied)",
"4. Sensory distribution (draw dermatome)",
"5. Applied anatomy: injury at each level + sign/deformity",
"6. Diagram: always draw and label",
]),
("Joint Question", [
"1. Type of joint (synovial ball-and-socket etc.)",
"2. Articular surfaces",
"3. Fibrous capsule + synovial membrane",
"4. Ligaments (name + attachment)",
"5. Movements + muscles producing each",
"6. Blood supply + nerve supply (Hilton's law)",
"7. Applied: common injuries, dislocations, age-related changes",
]),
("Region Question (Axilla/Cubital fossa)", [
"1. Definition + shape",
"2. Boundaries (walls: anterior, posterior, medial, lateral; apex, base)",
"3. Contents (listed and described)",
"4. Applied anatomy",
"5. Diagram with labels",
]),
("Muscle Group Question", [
"1. Introduction: group name + location",
"2. For each muscle: Origin - Insertion - Nerve supply - Action",
"3. Table format preferred (saves time, looks organized)",
"4. Applied: paralysis/lesion effects",
]),
]
for name, steps in templates:
story.append(Paragraph(f"Template: {name}", sub_title))
for s in steps:
story.append(Paragraph(f"• {s}", bullet))
story.append(Spacer(1, 0.1*cm))
story.append(Spacer(1, 0.2*cm))
story.append(tip_box(
"<b>Exam strategy:</b> Always begin with a one-line definition. Draw a diagram early "
"(even rough) — examiners award marks for labeled diagrams. End with applied anatomy — "
"that is where 'explain why' marks live. 10-mark questions are graded on breadth + clinical relevance.",
bg=GREEN_BG, border=TEAL
))
story.append(Spacer(1, 0.4*cm))
# ═══════════════════════════════════════════════════════════════════════════════
# 9. HIGH-YIELD TOPIC CHECKLIST
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("9. High-Yield Topic Checklist (10-Mark Probability)", NAVY))
story.append(Spacer(1, 0.2*cm))
checklist = [
("★★★ Must Prepare", [
"Brachial plexus (formation + injuries + Erb's + Klumpke's)",
"Radial nerve (course + wrist drop + Saturday night palsy)",
"Median nerve (course + carpal tunnel + hand of benediction + ape thumb)",
"Axilla (boundaries + contents + axillary lymph nodes)",
"Female breast (structure + lymphatics + carcinoma applied)",
]),
("★★ Highly Likely", [
"Ulnar nerve (course + claw hand + ulnar paradox + Froment's sign)",
"Shoulder joint (SITS + dislocation + Bankart + Hill-Sachs)",
"Cubital fossa (boundaries + contents + applied)",
"Carpal tunnel (contents + CTS + Tinel's + Phalen's)",
"Rotator cuff (SITS table + painful arc + supraspinatus tear)",
]),
("★ Good to Know", [
"Axillary artery (3 parts + branches)",
"Anatomical snuff box (boundaries + scaphoid fracture)",
"Intrinsic muscles of hand (thenar + hypothenar + lumbricals + interossei)",
"Long thoracic nerve (C5,6,7 + serratus anterior + winged scapula)",
"Musculocutaneous nerve (coracobrachialis + biceps + brachialis + lateral cutaneous nerve of forearm)",
]),
]
for level, topics in checklist:
data = [[Paragraph(f"<b>{level}</b>", bold_bullet)]]
for t in topics:
data.append([Paragraph(f"☐ {t}", bullet)])
t_widget = Table(data, colWidths=[17.4*cm])
bg = HexColor("#fff3f3") if "★★★" in level else (YELLOW_BG if "★★" in level else LIGHT_BG)
t_widget.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), bg),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 10),
("BOX", (0,0), (-1,-1), 1, HexColor("#cccccc")),
]))
story.append(t_widget)
story.append(Spacer(1, 0.15*cm))
story.append(Spacer(1, 0.3*cm))
story.append(HRFlowable(width="100%", thickness=1, color=TEAL))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph(
"Reference: Gray's Anatomy for Students | BD Chaurasia's Human Anatomy | Last's Anatomy",
S("Footer", fontSize=8, textColor=HexColor("#666666"),
fontName="Helvetica-Oblique", alignment=TA_CENTER)
))
# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF created: {OUTPUT}")
python3 /home/daytona/workspace/upper-limb-pdf/generate_pdf.py
Upper Limb Clinical Applied Reasoning
PDF Document · PDF
| Section | Content |
|---|---|
| 1 | Nerve Injuries Master Table - 11 clinical scenarios with anatomical explanations |
| 2 | Brachial Plexus - formation mnemonic + injury level table |
| 3 | Deformities Explained - wrist drop, claw hand, ape thumb, waiter's tip, winged scapula, painful arc |
| 4 | Breast Carcinoma Applied - peau d'orange, nipple retraction, peau d'orange, Paget's disease |
| 5 | Shoulder Joint & Rotator Cuff - SITS table (origin/insertion/nerve/action) + dislocations |
| 6 | Carpal Tunnel & Anatomical Snuff Box - contents, CTS signs, scaphoid fracture |
| 7 | "Explain Why" Quick Revision Table - 10 classic explain-why questions with answers |
| 8 | 10-Mark Answer Writing Templates - nerve/joint/region/muscle frameworks |
| 9 | High-Yield Checklist - ★★★ / ★★ / ★ priority topics to revise |