What are all the expected viva questions in a case presentation topic of benign swelling from history to examination in a pdf form
viva questions benign swelling case presentation history examination surgery MBBS
https://m56bookstore.com/wp-content/uploads/2025/01/GENERAL-…
mkdir -p /tmp/workspace/benign-swelling-viva && ls /tmp/workspace/benign-swelling-viva/
~/benign-swelling-viva/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, PageBreak
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.pdfbase import pdfmetrics
OUTPUT_PATH = "/tmp/workspace/benign-swelling-viva/Benign_Swelling_Viva_Questions.pdf"
doc = SimpleDocTemplate(
OUTPUT_PATH,
pagesize=A4,
rightMargin=2*cm,
leftMargin=2*cm,
topMargin=2.5*cm,
bottomMargin=2*cm
)
styles = getSampleStyleSheet()
# Custom styles
title_style = ParagraphStyle(
'CustomTitle',
parent=styles['Title'],
fontSize=20,
textColor=colors.HexColor('#1a3a5c'),
spaceAfter=6,
alignment=TA_CENTER,
fontName='Helvetica-Bold'
)
subtitle_style = ParagraphStyle(
'Subtitle',
parent=styles['Normal'],
fontSize=11,
textColor=colors.HexColor('#4a4a4a'),
spaceAfter=12,
alignment=TA_CENTER,
fontName='Helvetica-Oblique'
)
section_header_style = ParagraphStyle(
'SectionHeader',
parent=styles['Heading1'],
fontSize=13,
textColor=colors.white,
backColor=colors.HexColor('#1a3a5c'),
spaceBefore=14,
spaceAfter=6,
leftIndent=-8,
rightIndent=-8,
leading=18,
fontName='Helvetica-Bold'
)
subsection_style = ParagraphStyle(
'Subsection',
parent=styles['Heading2'],
fontSize=11,
textColor=colors.HexColor('#1a3a5c'),
spaceBefore=10,
spaceAfter=4,
fontName='Helvetica-Bold',
borderPad=2
)
question_style = ParagraphStyle(
'Question',
parent=styles['Normal'],
fontSize=10,
textColor=colors.HexColor('#1a1a1a'),
leftIndent=14,
spaceAfter=4,
spaceBefore=2,
leading=15,
fontName='Helvetica'
)
answer_hint_style = ParagraphStyle(
'AnswerHint',
parent=styles['Normal'],
fontSize=9,
textColor=colors.HexColor('#2e7d32'),
leftIndent=28,
spaceAfter=6,
spaceBefore=0,
leading=13,
fontName='Helvetica-Oblique'
)
note_style = ParagraphStyle(
'Note',
parent=styles['Normal'],
fontSize=9,
textColor=colors.HexColor('#7b1fa2'),
leftIndent=14,
spaceAfter=4,
leading=13,
fontName='Helvetica-Oblique'
)
story = []
# ─── TITLE PAGE ────────────────────────────────────────────────────────────────
story.append(Spacer(1, 1.5*cm))
story.append(Paragraph("BENIGN SWELLING", title_style))
story.append(Paragraph("Comprehensive Viva Questions", ParagraphStyle('sub1', parent=subtitle_style, fontSize=14, fontName='Helvetica-Bold', textColor=colors.HexColor('#2e7d32'))))
story.append(Paragraph("Case Presentation · History to Examination", subtitle_style))
story.append(Spacer(1, 0.4*cm))
story.append(HRFlowable(width="100%", thickness=2, color=colors.HexColor('#1a3a5c')))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("General Surgery Clinical Viva Preparation | MBBS / MS Surgery", ParagraphStyle('meta', parent=styles['Normal'], fontSize=9, textColor=colors.grey, alignment=TA_CENTER)))
story.append(Spacer(1, 1*cm))
def section(title):
story.append(Spacer(1, 0.3*cm))
story.append(Table(
[[Paragraph(f" {title}", ParagraphStyle('sh', parent=styles['Normal'], fontSize=12, textColor=colors.white, fontName='Helvetica-Bold', leading=16))]],
colWidths=[doc.width],
style=TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor('#1a3a5c')),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
('LEFTPADDING', (0,0), (-1,-1), 10),
])
))
story.append(Spacer(1, 0.2*cm))
def subsection(title):
story.append(Spacer(1, 0.15*cm))
story.append(Table(
[[Paragraph(f" {title}", ParagraphStyle('ssh', parent=styles['Normal'], fontSize=10.5, textColor=colors.HexColor('#1a3a5c'), fontName='Helvetica-Bold', leading=15))]],
colWidths=[doc.width],
style=TableStyle([
('BACKGROUND', (0,0), (-1,-1), colors.HexColor('#e3f2fd')),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 10),
('LINEBELOW', (0,0), (-1,-1), 1, colors.HexColor('#1a3a5c')),
])
))
story.append(Spacer(1, 0.1*cm))
def q(num, text, hint=None):
story.append(Paragraph(f"<b>Q{num}.</b> {text}", question_style))
if hint:
story.append(Paragraph(f"<i>Ans hint: {hint}</i>", answer_hint_style))
def note(text):
story.append(Paragraph(f"★ {text}", note_style))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 1: INTRODUCTION & DEFINITIONS
# ─────────────────────────────────────────────────────────────────────────────
section("SECTION 1: INTRODUCTION & DEFINITIONS")
q(1, "What is a swelling?", "Any abnormal enlargement or protuberance in any part of the body; it can be a lump, mass, or tumour.")
q(2, "How do you classify swellings?", "Congenital vs Acquired; Benign vs Malignant; Inflammatory vs Non-inflammatory; Cystic vs Solid; Superficial vs Deep.")
q(3, "What is the difference between a benign and malignant swelling?", "Benign: slow growing, well-defined, mobile, no infiltration, no metastasis. Malignant: rapid growth, ill-defined, fixed, infiltrates surrounding structures, metastasises.")
q(4, "Name 5 common benign soft tissue swellings.", "Lipoma, Sebaceous cyst (Epidermoid cyst), Dermoid cyst, Fibroma, Neurofibroma, Ganglion, Haemangioma, Lymphangioma.")
q(5, "What are the '5Fs' or common mnemonics taught for swelling?", "Fat (lipoma), Fluid (cyst/abscess), Flatus, Foetus (if abdomen), Fibrous tissue – varies by region.")
q(6, "What is the rule of 10 for thyroid swellings?", "Relevant only for thyroid; in general swellings, emphasise the classical 10-point examination of a lump.")
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 2: HISTORY TAKING
# ─────────────────────────────────────────────────────────────────────────────
section("SECTION 2: HISTORY TAKING")
subsection("A. Chief Complaint")
q(7, "How do you record the chief complaint for a swelling?", "Site of swelling + duration (e.g., 'Painless swelling on the left forearm for 3 years').")
q(8, "What are the key points to elicit in the history of a swelling?", "Duration, mode of onset, rate of progress, pain, changes in size, associated features, past/family/treatment history.")
subsection("B. History of Present Illness (HOPI)")
q(9, "How long has the swelling been present? Why is duration important?", "Duration helps determine acuity. Long duration (years) suggests benign; rapid onset raises suspicion for malignancy or infection.")
q(10, "What was the mode of onset of the swelling?", "Spontaneous vs post-traumatic. Sudden onset post-trauma may suggest haematoma; spontaneous slow growth suggests lipoma/cyst.")
q(11, "How has the swelling changed in size over time?", "Slow progressive growth – benign (lipoma). Rapid increase – malignancy. Fluctuating size – ganglion, hygroma. Spontaneous regression – lymph node, lipoma sometimes.")
q(12, "Is the swelling painful?", "Benign swellings are usually painless. Pain suggests inflammation, infection, pressure on nerve, or malignant infiltration.")
q(13, "If painful, characterise the pain.", "Onset, character (throbbing = infection; aching = pressure), radiation, severity (VAS 0-10), relieving/aggravating factors.")
q(14, "Has the patient noticed any change in the overlying skin?", "Skin changes: redness (infection), punctum (sebaceous cyst), ulceration (malignancy), dilated veins (vascular tumour), peau d'orange.")
q(15, "Does the size of the swelling change with position or Valsalva manoeuvre?", "Increase on Valsalva/coughing – varix, varicocele, hernial sac. Reduce on lying down – lipoma (subcutaneous) unaffected; varicocele reduces.")
q(16, "Is there any associated discharge from the swelling?", "Purulent – abscess; Cheesy material via punctum – sebaceous cyst; Straw-coloured – cyst; Bloody – vascular/malignant.")
q(17, "Is there any associated numbness or tingling?", "Suggests nerve involvement or pressure by the swelling on adjacent nerve – raises concern for malignancy or neurofibroma.")
q(18, "Has the patient noticed any other swellings elsewhere in the body?", "Multiple swellings – lipomatosis, neurofibromatosis (NF1), lymphoma, metastatic disease.")
q(19, "Are there any systemic features like fever, weight loss, night sweats, anorexia?", "Presence of B-symptoms raises suspicion of malignancy (lymphoma) or TB lymphadenopathy. Their absence supports benign diagnosis.")
q(20, "Is there any difficulty in movement or function related to the swelling?", "Suggests deep involvement, nerve or vessel compression, or joint involvement.")
subsection("C. Past History")
q(21, "Has the patient had any similar swelling in the past?", "Recurrent sebaceous cyst, recurrent lipoma, ganglion, or possibly a malignant tumour that was inadequately excised.")
q(22, "Has the patient undergone any surgery for a swelling previously?", "Important to assess recurrence risk and any histopathological diagnosis of the previous swelling.")
q(23, "Any history of diabetes, tuberculosis, or immunocompromised state?", "Diabetes predisposes to abscess and poor healing. TB can cause cold abscess/lymphadenopathy. Immunosuppression increases risk of unusual infections.")
q(24, "Any history of trauma to the site?", "Post-traumatic haematoma, myositis ossificans, traumatic dermoid.")
q(25, "Any prior radiation to the area?", "Radiation-induced fibrosis or sarcoma (rare, long-term complication).")
subsection("D. Family History")
q(26, "Is there a family history of similar swellings?", "Familial lipomatosis (AD), Gardner's syndrome (polyps + desmoid tumours), Neurofibromatosis type 1 (NF1) – AD.")
q(27, "Family history of malignancy?", "Relevant if swelling is suspected to be malignant or if patient has multiple swellings; e.g., BRCA for breast, FAP for colorectal.")
subsection("E. Personal / Social History")
q(28, "What is the patient's occupation?", "Relevant for repetitive trauma (ganglion in typists), occupational carcinogens, or physical demands affecting treatment plan.")
q(29, "Habits – smoking, alcohol, tobacco chewing?", "Tobacco chewing and smoking associated with oral/neck malignancies. Alcohol with liver disease (relevant if abdominal swelling).")
q(30, "Dietary habits?", "Relevant in nutritional deficiencies (e.g., vitamin C deficiency causing bleeding gums/swelling).")
subsection("F. Treatment History")
q(31, "Has the patient received any treatment for this swelling? What was the effect?", "Previous aspiration, incision, or excision. Did the swelling recur? Any biopsy result available? Steroid injection for keloid/ganglion?")
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 3: GENERAL EXAMINATION
# ─────────────────────────────────────────────────────────────────────────────
section("SECTION 3: GENERAL EXAMINATION")
q(32, "What do you look for in general examination before examining the swelling?", "Build/nourishment, pallor (anaemia in malignancy), jaundice, cyanosis, clubbing, lymphadenopathy (generalised), pedal oedema, vital signs.")
q(33, "Why is the patient's general appearance important?", "Cachexia/weight loss suggests malignancy; healthy appearance supports benign aetiology.")
q(34, "What is the significance of generalised lymphadenopathy in a patient with a lump?", "Raises suspicion of lymphoma, metastatic malignancy, TB, infectious mononucleosis, HIV.")
q(35, "How do you assess nutritional status in a patient with a swelling?", "BMI, skin turgor, muscle wasting, hair/nail changes, weight loss history – significant weight loss (>10% in 6 months) is a red flag.")
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 4: LOCAL EXAMINATION – INSPECTION
# ─────────────────────────────────────────────────────────────────────────────
section("SECTION 4: LOCAL EXAMINATION – INSPECTION")
subsection("The 6 S's of Inspection")
q(36, "What are the 6 S's of inspection of a swelling?", "Site, Size, Shape, Surface, Skin over the swelling, Surroundings (scar, sinuses, veins).")
q(37, "What is the significance of the exact SITE of the swelling?", "Site suggests origin: midline neck – thyroglossal; lateral neck – branchial cyst; scalp – sebaceous cyst/dermoid; subcutaneous – lipoma.")
q(38, "How do you describe the SIZE of a swelling on inspection?", "Estimate in centimetres; compare to common objects (pea, walnut, egg, fist). Note whether it is increasing in inspection position vs at rest.")
q(39, "What shapes can swellings have and what do they suggest?", "Spherical – cyst; ovoid – lipoma; irregular lobulated – malignancy or lipomatosis; fusiform – nerve sheath tumour.")
q(40, "What does the SURFACE appearance tell you?", "Smooth – cyst, lipoma, benign tumour; Irregular/nodular – malignancy, fibroma; Ulcerated surface – malignancy.")
q(41, "What SKIN changes do you look for over a swelling?", "Normal skin – lipoma; Punctum (blackhead) – sebaceous cyst; Redness/warmth – infection/inflammation; Peau d'orange – breast carcinoma; Dilated veins – vascular tumour/AV malformation; Scar – previous surgery; Pigmentation – melanocytic lesions.")
q(42, "What is a punctum?", "A small central opening on the skin surface overlying a sebaceous cyst, through which cheesy keratin material can be expressed; its presence is pathognomonic of a sebaceous/epidermoid cyst.")
q(43, "What does pulsation on inspection suggest?", "Pulsatile swelling – vascular tumour (aneurysm, AV malformation, carotid body tumour) or a swelling transmitting pulsations from an underlying vessel.")
q(44, "How do you differentiate a pulsatile swelling from one that is merely transmitted?", "Pulsatile: expansile in all directions (aneurysm). Transmitted: moves in one direction only (e.g., lymph node over aorta).")
q(45, "What do you note about the SURROUNDINGS of the swelling?", "Scars (previous surgery/trauma), sinuses (TB/chronic abscess), dilated veins (vascular tumour), oedema of limb (lymph node obstruction), skin tethering.")
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 5: LOCAL EXAMINATION – PALPATION
# ─────────────────────────────────────────────────────────────────────────────
section("SECTION 5: LOCAL EXAMINATION – PALPATION")
subsection("Mandatory Points of Palpation")
q(46, "What are the mandatory points of palpation for ANY swelling?", "1. Temperature 2. Tenderness 3. Site & extent 4. Size (measured) 5. Shape 6. Surface 7. Edge/margin 8. Consistency 9. Fluctuation 10. Transillumination 11. Compressibility/reducibility 12. Pulsatility 13. Relations to skin 14. Relations to underlying structures 15. Regional lymph nodes.")
subsection("Temperature & Tenderness")
q(47, "How do you assess temperature of a swelling?", "Use the dorsum of the fingers (more sensitive to temperature than palm). Compare with the opposite normal side. Hot = inflammatory/vascular.")
q(48, "What does increased warmth over a swelling suggest?", "Acute inflammation (abscess, infected cyst), vascular swelling (haemangioma, AV malformation), rarely rapidly growing malignancy.")
q(49, "What does tenderness on palpation indicate?", "Infection/inflammation (abscess), nerve involvement (neurofibroma on pressure), or malignant infiltration. Benign lipoma/sebaceous cyst is typically non-tender.")
subsection("Consistency")
q(50, "How do you grade consistency of a swelling?", "Soft (lipoma, cyst) → Firm (fibroma, lymph node, neurofibroma) → Hard (bone, calcified) → Stony hard (bone, calcification).")
q(51, "What consistency do you expect in a lipoma?", "Soft, doughy, fluctuant-like but does not truly fluctuate. The characteristic 'slip sign' – the edge slips away under the finger.")
q(52, "What is the slip sign in a lipoma?", "When examining a lipoma, the edge slips under the finger due to its lobulated smooth surface and soft consistency – characteristic of lipoma.")
q(53, "What consistency suggests malignancy?", "Stony hard or hard, irregular consistency with ill-defined margins fixed to surrounding structures.")
subsection("Fluctuation Test")
q(54, "How do you perform the fluctuation test?", "Two fingers (index and middle) of one hand are placed on either side of the swelling; the third finger of the same or other hand presses in the centre. Positive if the two fingers are pushed apart.")
q(55, "What does a positive fluctuation test indicate?", "Fluid content within the swelling (cyst, abscess, haematoma). It must be performed in two planes at right angles to confirm true fluctuation.")
q(56, "Why must fluctuation be tested in two planes?", "To distinguish true fluid fluctuation from simple yielding/bouncing of a soft solid tumour. True fluctuation is positive in both planes.")
q(57, "Is fluctuation positive in a lipoma?", "A lipoma may give a false fluctuation due to soft consistency, but true fluctuation (in two planes) is NOT positive in a lipoma.")
subsection("Transillumination Test")
q(58, "How do you perform the transillumination test?", "In a dark room, a torch/pen light is pressed firmly against one side of the swelling. If light transilluminates (glows through) the swelling, the test is positive.")
q(59, "What does positive transillumination indicate?", "The swelling contains clear, translucent fluid (e.g., cystic hygroma, hydrocoele, ranula, ganglion, meningocele). Turbid fluid (pus/blood) – may not transilluminate.")
q(60, "Name swellings where transillumination is positive.", "Cystic hygroma (brilliantly transilluminant), Hydrocoele, Ganglion, Ranula, Meningocele, Lymphangioma.")
q(61, "Name swellings where transillumination is negative.", "Lipoma, Sebaceous cyst (cheesy content), Solid tumours, Haematoma, Pus-filled abscess.")
subsection("Compressibility & Reducibility")
q(62, "What is the difference between compressible and reducible swellings?", "Compressible: swelling decreases in size on pressure but returns on release (no anatomical communication) – e.g., haemangioma. Reducible: swelling is pushed into a cavity and does not return unless provoked – e.g., hernia.")
q(63, "Give examples of compressible swellings.", "Haemangioma (venous), cystic hygroma, meningocele.")
q(64, "Give examples of reducible swellings.", "Inguinal hernia (reduces into abdomen on pressure with cough impulse), varicocele (reduces on lying down).")
subsection("Pulsatility")
q(65, "How do you test for pulsatility of a swelling?", "Place two index fingers on either side of the swelling. If the swelling is expansile, the fingers are pushed apart in all directions (aneurysm). If transmitted, fingers move in one direction.")
q(66, "What is an expansile pulsatile swelling?", "One that expands outwards in all directions with each heartbeat – characteristic of an arterial aneurysm (e.g., popliteal, femoral, aortic).")
subsection("Relations to Skin & Deep Structures")
q(67, "How do you test whether a swelling is attached to the overlying skin?", "Pinch the skin over the swelling; if the skin can be lifted separately = not attached. If the skin moves with the swelling = skin involvement (malignancy, sebaceous cyst).")
q(68, "How do you test the relationship of a swelling to underlying deep structures?", "Ask the patient to contract the muscle below the swelling. If mobility is reduced on muscle contraction, the swelling lies deep to or within the muscle/fascia.")
q(69, "Give examples of swellings that become fixed on muscle contraction.", "Lipoma deep to fascia, soft tissue sarcoma infiltrating muscle – reduced mobility in one or both directions on contraction.")
q(70, "How do you test skin mobility over a swelling?", "Gently pinch the skin overlying the swelling and attempt to move it separately. Tethering = skin involvement (indicates deeper infiltration or sebaceous cyst).")
subsection("Regional Lymph Nodes")
q(71, "Why do you palpate regional lymph nodes when examining a benign swelling?", "To rule out lymphadenopathy suggesting malignancy, metastasis, or infection draining to regional nodes. Enlarged, hard, matted nodes are red flags.")
q(72, "If the swelling is on the forearm, which lymph nodes do you examine?", "Epitrochlear lymph nodes and axillary lymph nodes (anterior, posterior, medial groups and apical nodes).")
q(73, "How do you characterise lymph nodes on examination?", "Number, size, consistency (soft/firm/hard/rubbery), tenderness, surface (smooth/nodular), mobility (free/fixed/matted), relation to overlying skin.")
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 6: LOCAL EXAMINATION – PERCUSSION & AUSCULTATION
# ─────────────────────────────────────────────────────────────────────────────
section("SECTION 6: PERCUSSION & AUSCULTATION")
q(74, "When is percussion useful in examining a swelling?", "Abdominal/thoracic swellings: dull = solid/fluid; resonant = air-filled (pneumatocele, hernia containing bowel). Also to define the upper border of an abdominal swelling.")
q(75, "What does a dull note on percussion of a swelling suggest?", "Solid swelling (tumour, fibroma) or fluid-filled cyst/abscess with no air.")
q(76, "What does a resonant note over a swelling suggest?", "Air-containing structure (intestinal hernia, pneumatocele) or bowel displaced over the swelling.")
q(77, "When do you auscultate a swelling?", "To detect bruit (vascular swelling – AV malformation, carotid body tumour, aneurysm) or bowel sounds (hernia sac containing gut).")
q(78, "What does a bruit over a swelling indicate?", "Turbulent blood flow suggesting arteriovenous malformation, aneurysm, carotid body tumour, or a highly vascular tumour (e.g., thyroid in Graves' disease).")
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 7: SPECIFIC BENIGN SWELLINGS – VIVA CLASSICS
# ─────────────────────────────────────────────────────────────────────────────
section("SECTION 7: SPECIFIC BENIGN SWELLINGS – VIVA CLASSICS")
subsection("Lipoma")
q(79, "What is a lipoma?", "A benign tumour of adipose (fatty) tissue. The most common benign soft tissue tumour.")
q(80, "What are the clinical features of a lipoma?", "Soft, doughy, non-tender, mobile, lobulated, well-circumscribed swelling with pseudo-fluctuation and the characteristic slip sign.")
q(81, "What is the slip sign?", "The edge of a lipoma slips away from under the examining finger due to its smooth lobulated surface – pathognomonic of lipoma.")
q(82, "Is transillumination positive in a lipoma?", "No. Lipoma contains fat (not clear fluid), so transillumination is negative.")
q(83, "Where are lipomas commonly found?", "Upper back, shoulders, neck, trunk, forearm. Can occur anywhere that fat is present. Rarely in palms/soles.")
q(84, "Can a lipoma become malignant?", "Rare. Liposarcoma is the malignant counterpart, but true malignant transformation of a lipoma is extremely rare. Sites notorious for liposarcoma: retroperitoneum, thigh.")
q(85, "What are the indications for excision of a lipoma?", "Cosmetic concern, rapidly increasing size, pain/pressure symptoms, diagnostic uncertainty (deep/large lipoma), sites notorious for liposarcoma.")
q(86, "What is multiple lipomatosis?", "A condition with multiple lipomas; can be familial (autosomal dominant) or associated with Dercum's disease (painful lipomas), Madelung's disease (cervical lipomatosis).")
subsection("Sebaceous Cyst (Epidermoid Cyst)")
q(87, "What is a sebaceous cyst?", "A benign cyst formed by the obstruction of the sebaceous gland duct; filled with cheesy keratin material (not true sebum – hence better called epidermoid cyst).")
q(88, "What is the pathognomonic sign of a sebaceous cyst?", "A punctum – a small central black opening (blocked duct) on the skin surface; the cyst is attached to the overlying skin at the punctum.")
q(89, "What are the clinical features of a sebaceous cyst?", "Smooth, well-defined, non-tender swelling attached to skin (punctum present), freely mobile over deep structures, spherical, variable consistency (soft to tense), transillumination negative.")
q(90, "What is the content of a sebaceous cyst?", "Cheesy, paste-like whitish material composed of keratin and dead skin cells, with an offensive odour when released.")
q(91, "What are the complications of a sebaceous cyst?", "Infection (most common), horn formation (if contents project out), calcification, ulceration, and very rarely malignant change to squamous cell carcinoma (cock's peculiar tumour).")
q(92, "What is cock's peculiar tumour?", "Squamous cell carcinoma arising in a sebaceous cyst of the scalp – described by Edward Cock.")
q(93, "What is the treatment of a sebaceous cyst?", "Complete surgical excision including the entire cyst wall and punctum to prevent recurrence. If infected, treat infection first, then excise.")
q(94, "Where are sebaceous cysts NOT found?", "Palms and soles – there are no sebaceous glands there. Common on face, scalp, scrotum, trunk.")
subsection("Dermoid Cyst")
q(95, "What is a dermoid cyst?", "A cystic benign tumour lined by skin (epidermis + all skin appendages) containing keratin, hair, sebum, and sometimes teeth/bone (teratoma type).")
q(96, "What are the types of dermoid cysts?", "1. Sequestration dermoid (at lines of fusion) 2. Implantation/traumatic dermoid 3. Tubulodermoid (from abnormal tube fusion) 4. Ovarian dermoid (teratoma).")
q(97, "Where are sequestration dermoid cysts found?", "At lines of embryonic fusion: external angular dermoid (outer canthus of eye), internal angular dermoid (inner canthus), post-auricular dermoid, sublingual dermoid, pre-sternal dermoid.")
q(98, "How does a dermoid cyst differ from a sebaceous cyst on examination?", "Dermoid: no punctum, NOT attached to skin, attached to deeper structures (bone/periosteum), doughy consistency, contains hair/teeth. Sebaceous: has punctum, attached to skin, mobile over deeper structures.")
subsection("Ganglion")
q(99, "What is a ganglion?", "A cystic swelling arising from a joint capsule or tendon sheath, filled with thick gelatinous fluid (synovial fluid). Commonest benign swelling of the hand and wrist.")
q(100, "What are the clinical features of a ganglion?", "Smooth, tense, transilluminant cystic swelling near a joint or tendon (wrist dorsum most common), non-tender, variable in size, may fluctuate in size.")
q(101, "What is the treatment of a ganglion?", "Reassurance (many resolve spontaneously), aspiration (high recurrence ~50%), surgical excision (definitive; must remove the neck/stalk to prevent recurrence).")
subsection("Neurofibroma / Neurilemmoma")
q(102, "What are the clinical features of a neurofibroma?", "Firm, fusiform (spindle-shaped) swelling along the course of a nerve, non-tender at rest but tender on pressure; limited lateral mobility but free longitudinal movement along the nerve; may show Tinel's sign.")
q(103, "What is Tinel's sign in the context of a nerve swelling?", "Tapping over the swelling produces tingling/paraesthesia in the distribution of the nerve – indicates nerve origin of the swelling.")
q(104, "What is neurofibromatosis type 1 (NF1)?", "Von Recklinghausen's disease: autosomal dominant; multiple neurofibromas + café-au-lait spots (>6, >1.5 cm), axillary freckling (Crowe's sign), Lisch nodules (iris hamartomas).")
subsection("Haemangioma")
q(105, "What are the types of haemangioma?", "Capillary (port-wine stain, strawberry naevus), Cavernous (deep, compressible, bluish, bruit possible), AV malformation (compressible + bruit).")
q(106, "What are the clinical features of a cavernous haemangioma?", "Compressible, bluish-coloured swelling that empties on compression and refills on release; may have a bruit/thrill; warms on palpation; positive fluctuation.")
q(107, "What is Sturge-Weber syndrome?", "Port-wine stain of the face (trigeminal distribution) + ipsilateral leptomeningeal angioma + epilepsy + glaucoma.")
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 8: DIAGNOSIS & SUMMARY
# ─────────────────────────────────────────────────────────────────────────────
section("SECTION 8: DIAGNOSIS – PROVISIONAL & DIFFERENTIAL")
q(108, "How do you arrive at a provisional diagnosis of a benign swelling?", "Integrate site, age, duration, mode of onset, inspection findings, consistency, fluctuation, transillumination, and skin/deep relations to formulate the most likely diagnosis.")
q(109, "What are the features that favour a benign swelling over malignant?", "History: slow growth, painless, no B-symptoms, no rapid size increase. Examination: well-defined margins, smooth surface, mobile (not fixed), soft/cystic consistency, no skin/deep fixity, no regional lymphadenopathy.")
q(110, "What is your differential diagnosis for a soft, painless, mobile subcutaneous swelling?", "Lipoma (1st), Sebaceous cyst (if skin attached + punctum), Dermoid cyst (if near line of fusion), Fibroma (firm), Ganglion (near joint), Lymph node (if oval, regional node site).")
q(111, "How do you summarise your case presentation of a benign swelling?", "\"This is [age] [sex] who presented with [duration] of painless/painful [site] swelling which is [onset], [progress], [size], [consistency], [relation to skin and deep], [fluctuation], [transillumination], without B-symptoms. My provisional diagnosis is [X] because [key positive and negative findings].\"")
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 9: INVESTIGATIONS
# ─────────────────────────────────────────────────────────────────────────────
section("SECTION 9: INVESTIGATIONS FOR A BENIGN SWELLING")
q(112, "What is the first-line investigation for a soft tissue swelling?", "Ultrasound – distinguishes cystic from solid, identifies origin, detects vascularity (Doppler), guides FNAC/biopsy.")
q(113, "When do you order an MRI for a swelling?", "Large, deep-seated swelling (>5 cm), suspicion of malignancy, retroperitoneal lipoma/liposarcoma, nerve sheath tumours, prior to surgery for detailed anatomy.")
q(114, "What is FNAC and when is it used?", "Fine Needle Aspiration Cytology: a 22-24G needle aspirates cells for cytological diagnosis. Useful for solid/suspicious lumps, lymph nodes, thyroid, breast, parotid swellings.")
q(115, "What are the limitations of FNAC?", "Gives cytology (not histology), cannot assess capsular invasion or architecture, false negatives, sampling error.")
q(116, "What is the difference between FNAC and core needle biopsy?", "FNAC: thin needle, cytology only. Core needle biopsy: thick needle, provides histological tissue core, better for definitive diagnosis including architecture.")
q(117, "What is the role of X-ray in a swelling?", "To detect calcification (phlebolith in haemangioma, calcified cyst), bone involvement/erosion, periosteal reaction (bone tumour), gas (gas-forming infection).")
q(118, "What is a phlebolith?", "A calcified thrombus within a venous (cavernous) haemangioma; its presence on plain X-ray is diagnostic of haemangioma.")
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 10: TREATMENT PRINCIPLES
# ─────────────────────────────────────────────────────────────────────────────
section("SECTION 10: TREATMENT PRINCIPLES")
q(119, "What are the general principles of treatment of a benign swelling?", "Observation if asymptomatic and definitely benign (small lipoma). Surgical excision if: symptomatic, increasing in size, diagnostic uncertainty, cosmetic concern, site (retroperitoneal lipoma). Aspiration for cysts (ganglion) – high recurrence.")
q(120, "What is the surgical principle for excision of a sebaceous cyst?", "Complete excision of the entire cyst wall with the punctum in one piece (avoid rupture); if contents spill, risk of recurrence and inflammation.")
q(121, "What is the surgical principle for excision of a lipoma?", "Blunt dissection through the capsule; the lobulated fat tumour shells out along its natural plane. Avoid cutting through the tumour.")
q(122, "What is the surgical principle for excision of a ganglion?", "Excise the ganglion along with its neck/stalk down to the joint capsule or tendon sheath. Incomplete excision of the stalk causes recurrence.")
q(123, "What is Dercum's disease?", "A rare condition (adiposis dolorosa) characterised by multiple painful lipomas, predominantly in women; associated with obesity and fatigue.")
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 11: EXAMINER'S CLASSIC TRICKY QUESTIONS
# ─────────────────────────────────────────────────────────────────────────────
section("SECTION 11: EXAMINER'S CLASSIC TRICKY VIVA QUESTIONS")
q(124, "Why is a lipoma said to show 'pseudo-fluctuation'?", "A lipoma is soft and deformable, giving the impression of fluid fluctuation, but true fluctuation (positive in two planes perpendicular to each other) is NOT genuinely positive. The feeling is due to fat deformability.")
q(125, "A patient has a swelling that is soft, mobile, non-tender, and the skin cannot be pinched separately. What is your diagnosis?", "This suggests the skin is attached (tethered) to the swelling. Combined with the other features, suspect a sebaceous cyst with skin attachment (punctum).")
q(126, "A swelling is brilliantly transilluminant. What is the most likely diagnosis?", "Cystic hygroma (lymphangioma). It transilluminates brilliantly due to clear lymph fluid with very thin walls.")
q(127, "What is the significance of a swelling becoming smaller on lying down?", "Suggests varicocele (drains on lying) or a soft haemangioma. Hernias may also reduce on lying down.")
q(128, "Can a sebaceous cyst occur on the palm?", "No. Sebaceous glands are absent on the palms and soles, so sebaceous cysts do NOT occur there.")
q(129, "What is the difference between a ganglion and a bursa?", "Ganglion: from joint capsule or tendon sheath, contains thick gelatinous fluid, solitary. Bursa: protective sac between tendons/bone at pressure points, contains clear fluid, related to bony prominences.")
q(130, "A young woman has a tense, transilluminant swelling near the outer canthus of the eye. Diagnosis?", "External angular dermoid cyst – a sequestration dermoid at the outer angle of the orbit (fronto-zygomatic suture line).")
q(131, "How do you tell if a swelling is arising from the skin, subcutaneous tissue, fascia, or muscle?", "Skin: moves with skin pinch. Subcutaneous: mobile in all directions; moves freely, not affected by muscle contraction. Fascial: slightly limited. Muscle: mobility reduced in one direction on muscle contraction (against the plane of fibres). Deep to muscle: immobile on contraction.")
q(132, "What is Madelung's disease?", "Benign symmetric lipomatosis of the neck – multiple confluent lipomas around the neck/shoulders causing a 'horse-collar' appearance; associated with alcohol excess.")
q(133, "A lipoma is found in the retroperitoneum. What is your concern?", "Retroperitoneal lipomas are notorious for harbouring liposarcoma (malignant). All retroperitoneal fatty tumours should be considered liposarcoma until proven otherwise by histopathology.")
q(134, "What is Gardner's syndrome?", "Autosomal dominant condition: familial adenomatous polyposis (FAP) + desmoid tumours + osteomas + epidermoid cysts + dental anomalies.")
q(135, "What is the 'bag of worms' feeling?", "Classic description of a varicocele – a collection of dilated veins in the pampiniform plexus of the scrotum, which feels like a 'bag of worms' on palpation.")
# ─────────────────────────────────────────────────────────────────────────────
# CLOSING
# ─────────────────────────────────────────────────────────────────────────────
story.append(Spacer(1, 0.5*cm))
story.append(HRFlowable(width="100%", thickness=1.5, color=colors.HexColor('#1a3a5c')))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
"Total Questions: 135 | Sections: 11 | Covers: History → General Examination → Inspection → Palpation → Percussion → Auscultation → Specific Swellings → Investigations → Treatment",
ParagraphStyle('footer', parent=styles['Normal'], fontSize=8.5, textColor=colors.grey, alignment=TA_CENTER)
))
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph(
"Prepared for MBBS/MS Surgery Viva Examination Preparation | Based on S Das Clinical Surgery & Standard Surgical Texts",
ParagraphStyle('footer2', parent=styles['Normal'], fontSize=8, textColor=colors.grey, alignment=TA_CENTER, fontName='Helvetica-Oblique')
))
doc.build(story)
print(f"PDF generated successfully: {OUTPUT_PATH}")
cd /tmp/workspace/benign-swelling-viva && python generate_pdf.py
ls -lh /tmp/workspace/benign-swelling-viva/Benign_Swelling_Viva_Questions.pdf
Benign Swelling Viva Questions
PDF Document · PDF
Create a comparison table (cyst vs lipoma vs dermoid) in Excel
mkdir -p /tmp/workspace/benign-swelling-viva && ls /tmp/workspace/benign-swelling-viva/
~/benign-swelling-viva/generate_comparison.py
import openpyxl
from openpyxl.styles import (
Font, PatternFill, Alignment, Border, Side, GradientFill
)
from openpyxl.utils import get_column_letter
from openpyxl.styles.numbers import FORMAT_TEXT
OUTPUT_PATH = "/tmp/workspace/benign-swelling-viva/Benign_Swelling_Comparison.xlsx"
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "Comparison Table"
# ─── COLOUR PALETTE ──────────────────────────────────────────────────────────
COL_HEADER_BG = "1A3A5C" # deep navy – column headers
COL_HEADER_FG = "FFFFFF" # white
COL_PARAM_BG = "E3F2FD" # light blue – parameter column
COL_PARAM_FG = "1A3A5C" # navy text
COL_CYST_BG = "FFF8E1" # warm amber – sebaceous cyst
COL_LIPOMA_BG = "E8F5E9" # mint green – lipoma
COL_DERMOID_BG = "FCE4EC" # soft pink – dermoid cyst
COL_TITLE_BG = "1A3A5C"
COL_TITLE_FG = "FFFFFF"
COL_ALT1 = "FAFAFA" # alternate row 1
COL_ALT2 = "F0F7FF" # alternate row 2
COL_BORDER = "BDBDBD"
# ─── BORDERS ─────────────────────────────────────────────────────────────────
thin = Side(style="thin", color=COL_BORDER)
thick = Side(style="medium", color=COL_HEADER_BG)
outer = Border(left=thick, right=thick, top=thick, bottom=thick)
inner = Border(left=thin, right=thin, top=thin, bottom=thin)
def make_border(left=thin, right=thin, top=thin, bottom=thin):
return Border(left=left, right=right, top=top, bottom=bottom)
# ─── HELPER ──────────────────────────────────────────────────────────────────
def style(ws, row, col,
value="", bold=False, italic=False, font_size=10,
fg=None, bg=None, wrap=True, halign="left", valign="top",
border=None, font_color="000000"):
cell = ws.cell(row=row, column=col, value=value)
cell.font = Font(
name="Arial", size=font_size,
bold=bold, italic=italic,
color=font_color
)
if bg:
cell.fill = PatternFill("solid", fgColor=bg)
cell.alignment = Alignment(
wrap_text=wrap, horizontal=halign, vertical=valign
)
if border:
cell.border = border
return cell
# ─── TITLE ROW ───────────────────────────────────────────────────────────────
ws.merge_cells("A1:D1")
t = ws.cell(row=1, column=1,
value="BENIGN SWELLINGS – COMPARATIVE VIVA TABLE")
t.font = Font(name="Arial", size=15, bold=True, color=COL_TITLE_FG)
t.fill = PatternFill("solid", fgColor=COL_TITLE_BG)
t.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
t.border = outer
ws.row_dimensions[1].height = 34
# subtitle
ws.merge_cells("A2:D2")
sub = ws.cell(row=2, column=1,
value="Sebaceous Cyst vs Lipoma vs Dermoid Cyst | General Surgery Viva Preparation")
sub.font = Font(name="Arial", size=10, italic=True, color="555555")
sub.fill = PatternFill("solid", fgColor="E8EDF2")
sub.alignment = Alignment(horizontal="center", vertical="center")
sub.border = make_border()
ws.row_dimensions[2].height = 18
# blank spacer
ws.row_dimensions[3].height = 6
# ─── COLUMN HEADER ROW (row 4) ───────────────────────────────────────────────
headers = ["PARAMETER", "SEBACEOUS CYST\n(Epidermoid Cyst)", "LIPOMA", "DERMOID CYST"]
bg_cols = [COL_PARAM_BG, COL_CYST_BG, COL_LIPOMA_BG, COL_DERMOID_BG]
emoji_cols = ["", "🟡", "🟢", "🔴"] # visual indicator per swelling type
for c, (h, bg) in enumerate(zip(headers, bg_cols), start=1):
cell = ws.cell(row=4, column=c, value=h)
cell.font = Font(name="Arial", size=11, bold=True, color=COL_HEADER_FG)
cell.fill = PatternFill("solid", fgColor=COL_HEADER_BG)
cell.alignment = Alignment(horizontal="center", vertical="center",
wrap_text=True)
cell.border = make_border(left=thick, right=thick, top=thick, bottom=thick)
ws.row_dimensions[4].height = 36
# ─── TABLE DATA ──────────────────────────────────────────────────────────────
# Each row: (Parameter, Sebaceous Cyst, Lipoma, Dermoid Cyst)
rows = [
# ── DEFINITION ──
("DEFINITION",
"Retention cyst from blocked sebaceous gland duct; lined by stratified squamous epithelium",
"Benign tumour of mature adipose (fat) tissue; most common benign soft tissue tumour",
"Cystic tumour lined by skin with ALL skin appendages (hair follicles, sweat glands, sebaceous glands)"),
# ── AETIOLOGY ──
("AETIOLOGY / CAUSE",
"Obstruction of sebaceous gland duct → keratin accumulation",
"Unknown; possibly local proliferation of fat cells; familial forms (AD)",
"Sequestration dermoid: entrapment of ectoderm at embryonic fusion lines\nImplantation dermoid: post-traumatic\nOvarian dermoid: teratoma"),
# ── AGE / SEX ──
("AGE & SEX",
"Any age, more common in adults (20–50 yrs); M = F",
"Most common in adults (40–60 yrs); M = F; multiple in familial lipomatosis",
"Sequestration: present from birth; detected in children/young adults\nOvarian: 20–40 yrs (women)"),
# ── SITE ──
("COMMON SITES",
"Face, scalp, neck, scrotum, trunk\nNOT on palms/soles (no sebaceous glands)",
"Back, shoulders, trunk, forearm, neck\nCan occur anywhere fat is present\nNOT on palms/soles",
"Sequestration: External angular (outer canthus), inner canthus, post-auricular, sublingual, pre-sternal\nImplantation: fingertips, palm\nNOT related to sebaceous glands"),
# ── CONTENTS ──
("CONTENTS",
"Cheesy, paste-like keratin with dead skin cells; offensive odour when released",
"Mature adipose (fat) tissue within a thin fibrous capsule; lobulated",
"Hair, keratin, sebum, teeth, bone (in ovarian dermoid/teratoma); cheesy material"),
# ── ONSET ──
("ONSET & PROGRESS",
"Slow, insidious; may remain static for years; rapid if infected",
"Slow, insidious growth over years; usually remains stable",
"Slow, congenital (sequestration type present at birth); implantation after trauma"),
# ── PAIN ──
("PAIN",
"Usually painless unless infected (then acutely painful, red, tender)",
"Painless; can rarely be painful in Dercum's disease (adiposis dolorosa)",
"Usually painless; painful if infected or causing pressure (e.g., intracranial dermoid)"),
# ── INSPECTION – SKIN ──
("SKIN OVER SWELLING (Inspection)",
"Skin attached at PUNCTUM (black central opening); skin moves with cyst;\nmay show redness if infected",
"Normal overlying skin; skin is NOT attached; no punctum;\nSlip sign visible on inspection",
"Skin NOT attached (unlike sebaceous cyst); no punctum;\nnormal overlying skin in most types"),
# ── PUNCTUM ──
("PUNCTUM",
"✅ PRESENT – pathognomonic sign\n(Blocked sebaceous duct opening)",
"❌ ABSENT",
"❌ ABSENT"),
# ── CONSISTENCY ──
("CONSISTENCY (Palpation)",
"Soft to tense (depending on fluid content); tense in scalp (pilar cysts)",
"Soft, doughy, 'putty-like'; characteristic slip sign on palpation",
"Doughy/cheesy consistency; may feel doughy like lipoma but attached to deeper structures"),
# ── SLIP SIGN ──
("SLIP SIGN",
"❌ ABSENT",
"✅ PRESENT – pathognomonic for lipoma\n(Edge slips away under examining finger)",
"❌ ABSENT"),
# ── FLUCTUATION ──
("FLUCTUATION TEST",
"✅ Positive (if large enough)\n(Fluid/semi-solid content allows true fluctuation)",
"❌ Pseudo-fluctuation only\n(NOT truly positive in 2 perpendicular planes; due to soft fat)",
"✅ Positive (tense fluctuant doughy swelling;\ncontents somewhat solid/semi-solid)"),
# ── TRANSILLUMINATION ──
("TRANSILLUMINATION",
"❌ NEGATIVE\n(Cheesy opaque keratin content; does not allow light through)",
"❌ NEGATIVE\n(Fat is not translucent)",
"❌ NEGATIVE\n(Opaque cheesy/hair-containing content; does not transilluminate)"),
# ── MOBILITY ──
("MOBILITY",
"Mobile over DEEP structures\nFIXED to overlying SKIN (at punctum)\nNot fixed to deep structures",
"Freely mobile in ALL directions\nNot attached to skin\nNot attached to deep structures",
"NOT attached to overlying skin\nAttached to DEEPER structures (bone/periosteum)\ne.g., external angular dermoid attached to frontozygomatic suture"),
# ── RELATION DEEP ──
("RELATION TO DEEP STRUCTURES",
"FREE from underlying muscles/fascia;\nmobile from deep structures",
"Subcutaneous lipoma: free from deep\nDeep/intermuscular lipoma: reduced mobility on muscle contraction",
"Attached to periosteum/bone at embryonic fusion lines;\ncannot be separated from deeper bony structure"),
# ── COMPRESSIBILITY ──
("COMPRESSIBILITY / REDUCIBILITY",
"❌ Not compressible or reducible",
"❌ Not compressible or reducible\n(Soft but does not compress away)",
"❌ Not compressible or reducible"),
# ── TEMPERATURE ──
("TEMPERATURE",
"Normal unless infected (then warm)",
"Normal",
"Normal"),
# ── TENDERNESS ──
("TENDERNESS",
"Non-tender (unless infected – then acutely tender, warm, red)",
"Non-tender\n(Painful in Dercum's disease)",
"Non-tender (unless complicated)"),
# ── COMPLICATIONS ──
("COMPLICATIONS",
"1. Infection (most common)\n2. Abscess formation\n3. Horn formation\n4. Calcification\n5. Cock's peculiar tumour (SCC – rare)",
"1. Cosmetic deformity\n2. Pressure symptoms\n3. Liposarcomatous change (very rare; retroperitoneal sites)\n4. Multiple lipomatosis",
"1. Infection\n2. Rupture → chemical peritonitis (ovarian dermoid)\n3. Intracranial extension (external angular dermoid)\n4. Malignant change (very rare; squamous cell carcinoma)"),
# ── COCK'S ──
("SPECIAL EPONYMS",
"Cock's Peculiar Tumour:\nSCC arising in scalp sebaceous cyst (Described by Edward Cock)",
"Madelung's Disease:\nBenign symmetric lipomatosis of neck ('horse collar')\nDercum's Disease:\nMultiple painful lipomas; adiposis dolorosa",
"External Angular Dermoid:\nMost common dermoid cyst in head/neck region;\nat outer canthus of eye (fronto-zygomatic suture)"),
# ── SYNDROMES ──
("ASSOCIATED SYNDROMES",
"Gardner's Syndrome:\nFAP + epidermoid cysts + osteomas + desmoid tumours\n(Autosomal Dominant)",
"NF1 (Von Recklinghausen's):\nMultiple neurofibromas + café-au-lait spots\nFamilial Multiple Lipomatosis: AD",
"NF1 may have plexiform neurofibromas (not dermoid)\nGardner's syndrome: epidermoid cysts (not true dermoid)"),
# ── DIAGNOSIS ──
("KEY DIAGNOSTIC FEATURE (Clinical)",
"Punctum on overlying skin +\nSkin attachment +\nCheesy content",
"Slip sign +\nSoft/doughy +\nNo punctum, no skin attachment",
"No punctum +\nNo skin attachment +\nDeep attachment to bone/periosteum +\nContains hair/teeth (on imaging)"),
# ── INVESTIGATIONS ──
("INVESTIGATIONS",
"Clinical diagnosis usually sufficient\nUSG: confirms cystic nature\nFNAC: keratin squames\nHistology after excision: stratified squamous epithelium",
"Clinical diagnosis usually sufficient\nUSG: echogenic fatty mass\nMRI: if large/retroperitoneal (to exclude liposarcoma)\nHistology: mature adipocytes",
"USG: heterogeneous mass with calcification/hair\nMRI: mixed signal – fat, calcium, hair\nCT: useful for intracranial/orbital dermoids\nHistology: skin + all appendages"),
# ── X-RAY ──
("PLAIN X-RAY / RADIOLOGICAL CLUE",
"Calcification may occur (rare)\nNo specific X-ray finding",
"No calcification\nMRI shows well-defined fatty mass (hyperintense on T1)",
"Calcification, teeth, bone fragments visible on X-ray/CT\n(Pathognomonic for ovarian/teratomatous dermoid)"),
# ── TREATMENT ──
("TREATMENT",
"Complete surgical EXCISION including entire cyst wall + punctum\n(avoid rupture – spill causes recurrence)\nIf infected: treat infection first, then delayed excision",
"Surgical EXCISION: blunt dissection along capsule\n(shell out along natural plane)\nObs. if asymptomatic + small\nExcise if: large, deep, symptomatic, cosmetic concern, retroperitoneal",
"Complete surgical EXCISION including cyst wall +\nattachment to periosteum\nOvarian dermoid: laparoscopic/open cystectomy"),
# ── RECURRENCE ──
("RECURRENCE RISK",
"High if cyst wall ruptured or punctum not removed\nLow if completely excised",
"Low if completely shelled out\nHigher in multiple/familial lipomatosis",
"Moderate if periosteal attachment/stalk not removed\nLow if complete excision"),
# ── PROGNOSIS ──
("PROGNOSIS",
"Excellent with complete excision\nCock's peculiar tumour has poor prognosis (SCC)",
"Excellent; benign\nRetroperitoneal site: rule out liposarcoma",
"Excellent for sequestration/implantation types\nOvarian dermoid: excellent with cystectomy\nMalignant transformation very rare"),
# ── PATHOLOGY ──
("HISTOPATHOLOGY",
"Wall: stratified squamous epithelium\nContent: keratin, cholesterol crystals\nNo skin appendages in wall",
"Mature adipocytes in lobules\nThin fibrous capsule\nNo atypia in benign lipoma",
"Wall: EPIDERMIS + ALL skin appendages\n(hair follicles, sweat glands, sebaceous glands)\nContent: hair, keratin, sebum; teeth/bone in teratoma"),
# ── DIFFERENTIALS ──
("DIFFERENTIAL DIAGNOSIS",
"Lipoma (no punctum)\nDermoid cyst (deep attachment)\nAbscess (if infected)\nHydradenitis suppurativa (axilla/groin)\nBranchial cyst (neck)",
"Sebaceous cyst (has punctum)\nDermoid (deep attachment)\nFibroma (firmer)\nNeurofibroma (along nerve course)\nSoft tissue sarcoma (if large/deep)",
"Sebaceous cyst (punctum, no deep attachment)\nLipoma (no deep attachment)\nEncephalocele (trans-sutural; pulsatile)\nTeratoma (solid elements on imaging)"),
# ── VIVA SUMMARY ──
("VIVA ONE-LINE SUMMARY",
"\"Sebaceous cyst = skin attached at punctum, cheesy content, no transillumination, mobile over deep structures\"",
"\"Lipoma = slip sign, soft/doughy, no punctum, no skin attachment, pseudo-fluctuation only\"",
"\"Dermoid = no punctum, no skin attachment, attached to bone/periosteum, hair/teeth in content, at embryonic fusion lines\""),
]
# ─── WRITE DATA ROWS ─────────────────────────────────────────────────────────
START_ROW = 5
for i, (param, cyst, lipoma, dermoid) in enumerate(rows):
r = START_ROW + i
# Alternate row backgrounds
alt = COL_ALT1 if i % 2 == 0 else COL_ALT2
# Parameter cell
pc = ws.cell(row=r, column=1, value=param)
pc.font = Font(name="Arial", size=9.5, bold=True, color=COL_PARAM_FG)
pc.fill = PatternFill("solid", fgColor=COL_PARAM_BG)
pc.alignment = Alignment(horizontal="left", vertical="center",
wrap_text=True)
pc.border = make_border(left=thick, right=thin, top=thin, bottom=thin)
# Sebaceous Cyst cell
cc = ws.cell(row=r, column=2, value=cyst)
cc.font = Font(name="Arial", size=9)
cc.fill = PatternFill("solid", fgColor=COL_CYST_BG)
cc.alignment = Alignment(horizontal="left", vertical="top", wrap_text=True)
cc.border = make_border(top=thin, bottom=thin)
# Lipoma cell
lc = ws.cell(row=r, column=3, value=lipoma)
lc.font = Font(name="Arial", size=9)
lc.fill = PatternFill("solid", fgColor=COL_LIPOMA_BG)
lc.alignment = Alignment(horizontal="left", vertical="top", wrap_text=True)
lc.border = make_border(top=thin, bottom=thin)
# Dermoid cell
dc = ws.cell(row=r, column=4, value=dermoid)
dc.font = Font(name="Arial", size=9)
dc.fill = PatternFill("solid", fgColor=COL_DERMOID_BG)
dc.alignment = Alignment(horizontal="left", vertical="top", wrap_text=True)
dc.border = make_border(top=thin, bottom=thin, right=thick)
# Slightly taller rows for denser content
ws.row_dimensions[r].height = 65
# Special heights for busy rows
busy_rows = {
"COMPLICATIONS": 90,
"ASSOCIATED SYNDROMES": 80,
"TREATMENT": 80,
"INVESTIGATIONS": 80,
"DIFFERENTIAL DIAGNOSIS": 80,
"COMMON SITES": 80,
"AETIOLOGY / CAUSE": 75,
}
for i, (param, *_) in enumerate(rows):
if param in busy_rows:
ws.row_dimensions[START_ROW + i].height = busy_rows[param]
# ─── COLUMN WIDTHS ───────────────────────────────────────────────────────────
ws.column_dimensions["A"].width = 28
ws.column_dimensions["B"].width = 40
ws.column_dimensions["C"].width = 40
ws.column_dimensions["D"].width = 42
# ─── FREEZE PANES (header + param) ──────────────────────────────────────────
ws.freeze_panes = "B5"
# ─── ADD A LEGEND ROW AT THE BOTTOM ─────────────────────────────────────────
last_row = START_ROW + len(rows)
ws.merge_cells(f"A{last_row}:D{last_row}")
leg = ws.cell(row=last_row, column=1,
value="🟡 Sebaceous Cyst (Amber) | 🟢 Lipoma (Green) | 🔴 Dermoid Cyst (Pink) | ✅ = Present | ❌ = Absent")
leg.font = Font(name="Arial", size=9, italic=True, color="555555")
leg.fill = PatternFill("solid", fgColor="E8EDF2")
leg.alignment = Alignment(horizontal="center", vertical="center")
leg.border = make_border(left=thick, right=thick, top=thin, bottom=thick)
ws.row_dimensions[last_row].height = 22
# ─── SAVE ────────────────────────────────────────────────────────────────────
wb.save(OUTPUT_PATH)
print(f"Excel file saved: {OUTPUT_PATH}")
print(f"Rows of data: {len(rows)}")
cd /tmp/workspace/benign-swelling-viva && python generate_comparison.py
ls -lh /tmp/workspace/benign-swelling-viva/Benign_Swelling_Comparison.xlsx
Benign Swelling Comparison
Spreadsheet · XLSX
| Column | Colour | Entity |
|---|---|---|
| Parameter | Light blue | Row label |
| Sebaceous Cyst | Amber | Epidermoid cyst |
| Lipoma | Mint green | Fatty tumour |
| Dermoid Cyst | Soft pink | Skin appendage cyst |
Create a quick reference PDF pocket guide from the comparison table
ls /tmp/workspace/benign-swelling-viva/
~/benign-swelling-viva/generate_pocket_guide.py
from reportlab.lib.pagesizes import A5
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
from reportlab.platypus.flowables import HRFlowable
from reportlab.lib.colors import HexColor
OUTPUT = "/tmp/workspace/benign-swelling-viva/Pocket_Guide_Benign_Swellings.pdf"
# ── A5 landscape for a true pocket card feel ─────────────────────────────────
W, H = A5[1], A5[0] # landscape A5: 210 × 148 mm → 595 × 420 pt
doc = SimpleDocTemplate(
OUTPUT,
pagesize=(W, H),
leftMargin=0.9*cm, rightMargin=0.9*cm,
topMargin=0.8*cm, bottomMargin=0.8*cm,
)
CW = W - 1.8*cm # usable content width
# ── PALETTE ──────────────────────────────────────────────────────────────────
NAVY = HexColor("#1A3A5C")
AMBER = HexColor("#FFF8E1")
AMBER_H = HexColor("#F9A825") # header accent
GREEN = HexColor("#E8F5E9")
GREEN_H = HexColor("#2E7D32")
PINK = HexColor("#FCE4EC")
PINK_H = HexColor("#AD1457")
PARAM = HexColor("#E3F2FD")
PARAM_T = HexColor("#0D47A1")
WHITE = colors.white
LGRAY = HexColor("#F5F5F5")
MGRAY = HexColor("#9E9E9E")
DKGRAY = HexColor("#333333")
TICK = HexColor("#2E7D32")
CROSS = HexColor("#C62828")
# ── BORDER SIDES ─────────────────────────────────────────────────────────────
from reportlab.platypus.tables import TableStyle
from reportlab.lib.styles import ParagraphStyle
def ts(*args):
return TableStyle(list(args))
def cell(text, bold=False, size=7, color=DKGRAY, bg=None,
align="LEFT", valign="TOP", italic=False):
"""Return a styled Paragraph for use inside a table cell."""
style = ParagraphStyle(
"c",
fontName="Helvetica-Bold" if bold else ("Helvetica-Oblique" if italic else "Helvetica"),
fontSize=size,
textColor=color,
leading=size * 1.35,
spaceAfter=0,
spaceBefore=0,
)
return Paragraph(str(text), style)
def hcell(text, size=7.5, color=WHITE, bg=NAVY, bold=True):
return cell(text, bold=bold, size=size, color=color)
# ── STORY ────────────────────────────────────────────────────────────────────
story = []
# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 1 – COVER CARD
# ═══════════════════════════════════════════════════════════════════════════════
cover_data = [[
Paragraph(
"<font size=18><b>BENIGN SWELLINGS</b></font><br/>"
"<font size=10 color='#90CAF9'>Quick Reference Pocket Guide</font><br/><br/>"
"<font size=8 color='#B0BEC5'>Sebaceous Cyst · Lipoma · Dermoid Cyst</font><br/>"
"<font size=7 color='#78909C'>General Surgery | MBBS / MS Viva Prep</font>",
ParagraphStyle("cv", fontName="Helvetica-Bold", fontSize=18,
textColor=WHITE, alignment=TA_CENTER, leading=22)
)
]]
cover_tbl = Table(cover_data, colWidths=[CW], rowHeights=[H - 1.6*cm])
cover_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 18),
("BOTTOMPADDING",(0,0), (-1,-1), 18),
("BOX", (0,0), (-1,-1), 2, HexColor("#90CAF9")),
]))
story.append(cover_tbl)
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# HELPER – build a compact comparison table
# ═══════════════════════════════════════════════════════════════════════════════
# Column widths: param | cyst | lipoma | dermoid
PW = 3.2 * cm
COL = (CW - PW) / 3
def section_title(text):
story.append(Spacer(1, 2*mm))
tbl = Table([[
Paragraph(f"<b>{text}</b>",
ParagraphStyle("st", fontName="Helvetica-Bold", fontSize=8,
textColor=WHITE, leading=11))
]], colWidths=[CW])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), NAVY),
("LEFTPADDING", (0,0),(-1,-1), 6),
("RIGHTPADDING", (0,0),(-1,-1), 6),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING", (0,0),(-1,-1), 4),
]))
story.append(tbl)
story.append(Spacer(1, 1*mm))
def comparison_table(rows_data, row_heights=None):
"""
rows_data: list of (param, cyst_val, lipoma_val, dermoid_val)
"""
# Header row
header = [
hcell("PARAMETER", size=7),
hcell("SEBACEOUS CYST", size=7, bg=AMBER_H),
hcell("LIPOMA", size=7, bg=GREEN_H),
hcell("DERMOID CYST", size=7, bg=PINK_H),
]
def pstyle(bg):
return ParagraphStyle("v", fontName="Helvetica", fontSize=6.5,
textColor=DKGRAY, leading=9, spaceAfter=0)
def tick(v):
"""Colour ✅/❌ markers."""
if v.startswith("✅"):
return Paragraph(
"<font color='#2E7D32'><b>✅</b></font>" + v[1:],
ParagraphStyle("vt", fontName="Helvetica", fontSize=6.5,
textColor=DKGRAY, leading=9))
if v.startswith("❌"):
return Paragraph(
"<font color='#C62828'><b>❌</b></font>" + v[1:],
ParagraphStyle("vx", fontName="Helvetica", fontSize=6.5,
textColor=DKGRAY, leading=9))
return Paragraph(v, pstyle(None))
data = [header]
for row in rows_data:
param, c, l, d = row
data.append([
Paragraph(f"<b>{param}</b>",
ParagraphStyle("p", fontName="Helvetica-Bold", fontSize=6.5,
textColor=PARAM_T, leading=9)),
tick(c), tick(l), tick(d)
])
n = len(data)
rh = row_heights or ([14] + [None] * (n - 1))
tbl = Table(data, colWidths=[PW, COL, COL, COL], rowHeights=rh,
repeatRows=1)
style_cmds = [
# Global
("FONTNAME", (0,0), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 6.5),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING", (0,0), (-1,-1), 2),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("VALIGN", (0,0), (-1,-1), "TOP"),
# Header
("BACKGROUND", (0,0), (-1,0), NAVY),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 7),
("ALIGN", (0,0), (-1,0), "CENTER"),
("VALIGN", (0,0), (-1,0), "MIDDLE"),
# Col header colours
("BACKGROUND", (1,0), (1,0), AMBER_H),
("BACKGROUND", (2,0), (2,0), GREEN_H),
("BACKGROUND", (3,0), (3,0), PINK_H),
# Param column
("BACKGROUND", (0,1), (0,-1), PARAM),
# Data columns – alternate
]
for i in range(1, n):
bg_c = AMBER if i % 2 == 1 else HexColor("#FFF3CD")
bg_l = GREEN if i % 2 == 1 else HexColor("#DCEDC8")
bg_d = PINK if i % 2 == 1 else HexColor("#F8BBD9")
style_cmds += [
("BACKGROUND", (1,i), (1,i), bg_c),
("BACKGROUND", (2,i), (2,i), bg_l),
("BACKGROUND", (3,i), (3,i), bg_d),
]
style_cmds += [
("GRID", (0,0), (-1,-1), 0.4, HexColor("#BDBDBD")),
("BOX", (0,0), (-1,-1), 1.2, NAVY),
]
tbl.setStyle(TableStyle(style_cmds))
story.append(tbl)
# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 2 – AT A GLANCE: Definition, Site, Onset, Skin Signs
# ═══════════════════════════════════════════════════════════════════════════════
section_title("AT A GLANCE — Basic Identity")
comparison_table([
("Definition",
"Retention cyst; blocked sebaceous duct; keratin-filled",
"Benign fat tumour; most common benign soft tissue tumour",
"Cyst lined by skin + ALL appendages; at embryonic fusion lines"),
("Age",
"Any age; adults 20–50 yrs",
"Adults 40–60 yrs; familial forms",
"Congenital; detected in children/young adults"),
("Sex",
"M = F",
"M = F",
"M = F (ovarian dermoid: ♀)"),
("Common Sites",
"Face, scalp, neck, scrotum\n✅ NOT palms/soles",
"Back, shoulder, forearm, trunk\n✅ NOT palms/soles",
"Outer canthus eye, post-auricular\nsublingual, pre-sternal"),
("Contents",
"Cheesy keratin; offensive odour",
"Mature fat; lobulated; capsule",
"Hair, keratin, sebum\n± teeth/bone (teratoma type)"),
("Onset",
"Slow; rapid if infected",
"Very slow; years",
"Congenital; slow growth"),
])
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 3 – CLINICAL SIGNS (History + Inspection)
# ═══════════════════════════════════════════════════════════════════════════════
section_title("HISTORY — Key Differentiating Points")
comparison_table([
("Pain",
"Painless (unless infected)",
"Painless (painful = Dercum's)",
"Painless (unless infected)"),
("Growth",
"Slow; rapid if infected",
"Very slow / static",
"Slow; congenital"),
("B-symptoms\n(fever, wt loss)",
"❌ Absent in benign state",
"❌ Absent",
"❌ Absent"),
("Multiple\nswellings",
"Gardner's syndrome",
"Familial lipomatosis / NF1",
"Rarely multiple"),
("Discharge",
"Cheesy material via punctum",
"❌ No discharge",
"❌ No discharge"),
])
story.append(Spacer(1, 3*mm))
section_title("INSPECTION — What You See")
comparison_table([
("Overlying skin",
"ATTACHED at punctum\n(tethered; skin moves with cyst)",
"Normal; freely mobile\nNOT attached",
"Normal; NOT attached\nto skin"),
("Punctum",
"✅ PRESENT — PATHOGNOMONIC\n(black central opening)",
"❌ ABSENT",
"❌ ABSENT"),
("Skin changes",
"Redness if infected;\nno ulceration in benign phase",
"No skin changes",
"No skin changes"),
("Pulsation",
"❌ Not pulsatile",
"❌ Not pulsatile",
"❌ Not pulsatile"),
])
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 4 – PALPATION SIGNS (the viva gold zone)
# ═══════════════════════════════════════════════════════════════════════════════
section_title("PALPATION — The Viva Gold Zone")
comparison_table([
("Consistency",
"Soft → tense (variable)\nDepends on keratin tension",
"Soft, DOUGHY, putty-like",
"Doughy / cheesy\n(may feel like lipoma)"),
("SLIP SIGN",
"❌ ABSENT",
"✅ PRESENT — PATHOGNOMONIC\n(edge slips under finger)",
"❌ ABSENT"),
("Fluctuation",
"✅ TRUE fluctuation\n(positive in 2 planes)",
"❌ PSEUDO-fluctuation only\n(not truly +ve in 2 planes)",
"✅ Positive (tense/doughy)"),
("Transillumination",
"❌ NEGATIVE\n(opaque keratin content)",
"❌ NEGATIVE\n(fat ≠ translucent)",
"❌ NEGATIVE\n(hair/keratin = opaque)"),
("Compressibility",
"❌ Not compressible",
"❌ Not compressible",
"❌ Not compressible"),
("Mobility\n– skin",
"FIXED to skin at punctum",
"Skin FREE;\nmoves over skin freely",
"Skin FREE\n(no skin attachment)"),
("Mobility\n– deep",
"FREE from deep structures;\nmobile from underlying tissue",
"Subcutaneous: free\nDeep: reduced on contraction",
"FIXED to periosteum/bone\nat fusion line"),
("Temperature",
"Normal (hot if infected)",
"Normal",
"Normal"),
("Tenderness",
"Non-tender (tender if infected)",
"Non-tender",
"Non-tender"),
("Regional LN",
"Enlarged if infected",
"Not enlarged (benign)",
"Not enlarged (benign)"),
])
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 5 – DIAGNOSIS, INVESTIGATIONS, TREATMENT
# ═══════════════════════════════════════════════════════════════════════════════
section_title("KEY DIAGNOSTIC CLUE — Viva One-Liner")
one_liner_data = [
[hcell("SEBACEOUS CYST", size=7, bg=AMBER_H),
hcell("LIPOMA", size=7, bg=GREEN_H),
hcell("DERMOID CYST", size=7, bg=PINK_H)],
[
Paragraph("Punctum present + skin attached + cheesy content + no transillumination + no slip sign",
ParagraphStyle("ol", fontName="Helvetica", fontSize=6.5, leading=9, textColor=DKGRAY)),
Paragraph("Slip sign + soft/doughy + no punctum + no skin attachment + pseudo-fluctuation ONLY",
ParagraphStyle("ol", fontName="Helvetica", fontSize=6.5, leading=9, textColor=DKGRAY)),
Paragraph("No punctum + no skin attachment + FIXED to bone/periosteum + hair/teeth on imaging",
ParagraphStyle("ol", fontName="Helvetica", fontSize=6.5, leading=9, textColor=DKGRAY)),
]
]
ol_tbl = Table(one_liner_data, colWidths=[COL+PW/3, COL+PW/3, COL+PW/3],
rowHeights=[14, None])
ol_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0),(0,0), AMBER_H),
("BACKGROUND", (1,0),(1,0), GREEN_H),
("BACKGROUND", (2,0),(2,0), PINK_H),
("BACKGROUND", (0,1),(0,1), AMBER),
("BACKGROUND", (1,1),(1,1), GREEN),
("BACKGROUND", (2,1),(2,1), PINK),
("FONTNAME", (0,0),(-1,0), "Helvetica-Bold"),
("TEXTCOLOR", (0,0),(-1,0), WHITE),
("ALIGN", (0,0),(-1,0), "CENTER"),
("VALIGN", (0,0),(-1,-1), "TOP"),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING", (0,0),(-1,-1), 3),
("LEFTPADDING", (0,0),(-1,-1), 4),
("RIGHTPADDING", (0,0),(-1,-1), 4),
("GRID", (0,0),(-1,-1), 0.4, HexColor("#BDBDBD")),
("BOX", (0,0),(-1,-1), 1.2, NAVY),
]))
story.append(ol_tbl)
story.append(Spacer(1, 3*mm))
section_title("INVESTIGATIONS")
comparison_table([
("First-line",
"Clinical Dx usually sufficient\nUSG: confirms cystic nature",
"Clinical Dx usually sufficient\nUSG: echogenic fatty mass",
"USG: heterogeneous mass\n± calcification / hair"),
("Advanced",
"FNAC: keratin squames\nHistology: stratified sq. epi.",
"MRI if large/retroperitoneal\n(exclude liposarcoma)",
"MRI/CT: fat + Ca++ + hair\nHistology: skin + appendages"),
("X-ray clue",
"No specific finding\n(rare calcification)",
"No specific finding\n(MRI: T1 hyperintense fat)",
"✅ Teeth / bone / Ca++ on X-ray\n(pathognomonic in teratoma)"),
])
story.append(Spacer(1, 3*mm))
section_title("TREATMENT")
comparison_table([
("Surgery",
"Complete excision WITH cyst wall + punctum\n(avoid rupture → recurrence)",
"Blunt dissection; shell out along capsule\nObs if small + asymptomatic",
"Excision with periosteal attachment/stalk\nOvarian: laparoscopic cystectomy"),
("If infected",
"Treat infection first → delayed excision",
"N/A (rarely infects)",
"Treat infection → delayed excision"),
("Recurrence",
"High if punctum/wall not fully removed",
"Low; higher in familial type",
"Moderate if stalk not removed"),
])
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 6 – COMPLICATIONS, SYNDROMES, EPONYMS
# ═══════════════════════════════════════════════════════════════════════════════
section_title("COMPLICATIONS")
comparison_table([
("Common",
"Infection → abscess (most common)",
"Cosmetic deformity; pressure",
"Infection; rupture (ovarian)"),
("Rare /\nSerious",
"Cock's Peculiar Tumour\n(SCC in scalp sebaceous cyst)",
"Liposarcoma (retroperitoneum)\n— very rare transformation",
"Malignant change (SCC) – rare\nIntracranial extension (dermoid)"),
("Benign\ncomplications",
"Horn formation; calcification",
"Multiple lipomatosis; disfigurement",
"Chemical peritonitis (rupture)"),
])
story.append(Spacer(1, 3*mm))
section_title("SYNDROMES & EPONYMS — High-Yield Viva")
eponym_data = [
[hcell("EPONYM / SYNDROME"), hcell("ENTITY"), hcell("ASSOCIATION")],
[cell("Cock's Peculiar Tumour", bold=True, size=6.5),
cell("SCC in scalp sebaceous cyst", size=6.5),
cell("Edward Cock; malignant change", size=6.5)],
[cell("Madelung's Disease", bold=True, size=6.5),
cell("Benign symmetric lipomatosis", size=6.5),
cell("'Horse collar' neck; alcohol", size=6.5)],
[cell("Dercum's Disease", bold=True, size=6.5),
cell("Multiple painful lipomas", size=6.5),
cell("Adiposis dolorosa; women", size=6.5)],
[cell("External Angular Dermoid", bold=True, size=6.5),
cell("Sequestration dermoid at outer canthus", size=6.5),
cell("Fronto-zygomatic suture; children", size=6.5)],
[cell("Gardner's Syndrome", bold=True, size=6.5),
cell("FAP + epidermoid cysts + osteomas", size=6.5),
cell("Autosomal Dominant; desmoid tumours", size=6.5)],
[cell("NF1 (Von Recklinghausen)", bold=True, size=6.5),
cell("Multiple neurofibromas", size=6.5),
cell("Café-au-lait spots; Lisch nodules", size=6.5)],
]
ep_tbl = Table(eponym_data, colWidths=[4.5*cm, 5.5*cm, CW-10*cm],
repeatRows=1)
ep_tbl.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), 6.5),
("TOPPADDING", (0,0),(-1,-1), 2),
("BOTTOMPADDING", (0,0),(-1,-1), 2),
("LEFTPADDING", (0,0),(-1,-1), 4),
("RIGHTPADDING", (0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
("ROWBACKGROUNDS",(0,1),(-1,-1), [LGRAY, WHITE]),
("GRID", (0,0),(-1,-1), 0.4, HexColor("#BDBDBD")),
("BOX", (0,0),(-1,-1), 1.2, NAVY),
]))
story.append(ep_tbl)
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 7 – QUICK MEMORY AIDS (Mnemonics / Memory Hooks)
# ═══════════════════════════════════════════════════════════════════════════════
section_title("RAPID MEMORY AIDS — Mnemonics & Hooks")
story.append(Spacer(1, 2*mm))
memo_items = [
("SEBACEOUS CYST → 'S.P.A.C.E'",
[("S", "Skin ATTACHED at Punctum"),
("P", "Punctum = PATHOGNOMONIC"),
("A", "Abscess = most common complication"),
("C", "Cheesy (keratin) content"),
("E", "Excise ENTIRE wall + punctum to prevent recurrence")]),
("LIPOMA → 'S.L.I.P'",
[("S", "Slip sign = PATHOGNOMONIC"),
("L", "Lobulated soft fatty tumour"),
("I", "Innocent (benign); no punctum, no skin attachment"),
("P", "Pseudo-fluctuation only (NOT true fluctuation)")]),
("DERMOID → 'D.E.E.P'",
[("D", "Deep attachment to periosteum / bone"),
("E", "Embryonic fusion line origin (sequestration type)"),
("E", "Everything in wall: hair, glands, sebum (all skin appendages)"),
("P", "Plain X-ray may show teeth / bone (teratoma)")]),
]
for title_m, items in memo_items:
# Title bar
tb = Table([[Paragraph(f"<b>{title_m}</b>",
ParagraphStyle("mt", fontName="Helvetica-Bold",
fontSize=8, textColor=NAVY, leading=11))]],
colWidths=[CW])
tb.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), PARAM),
("LEFTPADDING", (0,0),(-1,-1), 6),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING", (0,0),(-1,-1), 3),
("BOX", (0,0),(-1,-1), 0.8, NAVY),
]))
story.append(tb)
# Items
rows_m = []
for letter, meaning in items:
rows_m.append([
Paragraph(f"<b>{letter}</b>",
ParagraphStyle("ml", fontName="Helvetica-Bold",
fontSize=8, textColor=WHITE, leading=10)),
Paragraph(meaning,
ParagraphStyle("mm", fontName="Helvetica",
fontSize=7, textColor=DKGRAY, leading=10))
])
mt = Table(rows_m, colWidths=[0.7*cm, CW - 0.7*cm])
mt.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,-1), NAVY),
("BACKGROUND", (1,0), (1,-1), WHITE),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING", (0,0), (-1,-1), 2),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("ALIGN", (0,0), (0,-1), "CENTER"),
("GRID", (0,0), (-1,-1), 0.3, HexColor("#E0E0E0")),
("BOX", (0,0), (-1,-1), 0.8, NAVY),
]))
story.append(mt)
story.append(Spacer(1, 3*mm))
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 8 – MUST-KNOW VIVA TRAPS (common examiner tricks)
# ═══════════════════════════════════════════════════════════════════════════════
section_title("MUST-KNOW VIVA TRAPS")
story.append(Spacer(1, 2*mm))
traps = [
("Q: Can a sebaceous cyst occur on the palm?",
"NO. Sebaceous glands are ABSENT on palms and soles. Sebaceous cysts CANNOT occur there."),
("Q: Lipoma shows pseudo-fluctuation — what does that mean?",
"A lipoma is soft/deformable so it mimics fluctuation, but TRUE fluctuation (positive in TWO perpendicular planes) is NOT present. It is a false/pseudo-fluctuation."),
("Q: You find a swelling near the outer canthus in a child. Diagnosis?",
"External Angular Dermoid — sequestration dermoid at the fronto-zygomatic suture; no punctum, fixed to periosteum."),
("Q: What is special about a retroperitoneal 'lipoma'?",
"Retroperitoneal fatty tumours are considered LIPOSARCOMA until proven otherwise by histopathology. Always excise and send for HPE."),
("Q: Name one location where lipoma is notorious for malignant change.",
"Retroperitoneum (liposarcoma) and deep thigh — sites notorious for liposarcoma."),
("Q: Sebaceous cyst on scrotum — any special feature?",
"Scrotal sebaceous cysts are often MULTIPLE; they can calcify (scrotal calcinosis). Treat with excision."),
("Q: All three swellings show NEGATIVE transillumination — why?",
"All contain OPAQUE material: sebaceous cyst (keratin), lipoma (fat), dermoid (hair/keratin). Only clear fluid (water, lymph) transilluminates."),
("Q: Dermoid vs sebaceous cyst — single best differentiator?",
"SKIN ATTACHMENT + PUNCTUM = Sebaceous cyst. DEEP (bone/periosteal) ATTACHMENT + no punctum = Dermoid cyst."),
]
trap_rows = []
for i, (q_text, a_text) in enumerate(traps):
bg = LGRAY if i % 2 == 0 else WHITE
trap_rows.append([
Paragraph(q_text, ParagraphStyle("tq", fontName="Helvetica-Bold",
fontSize=6.5, textColor=NAVY, leading=9)),
Paragraph(a_text, ParagraphStyle("ta", fontName="Helvetica",
fontSize=6.5, textColor=DKGRAY, leading=9)),
])
trap_tbl = Table(trap_rows, colWidths=[6*cm, CW - 6*cm])
trap_style = [
("VALIGN", (0,0),(-1,-1), "TOP"),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING", (0,0),(-1,-1), 3),
("LEFTPADDING", (0,0),(-1,-1), 5),
("RIGHTPADDING", (0,0),(-1,-1), 5),
("GRID", (0,0),(-1,-1), 0.4, HexColor("#BDBDBD")),
("BOX", (0,0),(-1,-1), 1.2, NAVY),
]
for i in range(len(traps)):
bg = LGRAY if i % 2 == 0 else WHITE
trap_style.append(("BACKGROUND", (0,i),(0,i), HexColor("#E8EDF5")))
trap_style.append(("BACKGROUND", (1,i),(1,i), bg))
trap_tbl.setStyle(TableStyle(trap_style))
story.append(trap_tbl)
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 9 – DIFFERENTIAL DIAGNOSIS QUICK GUIDE
# ═══════════════════════════════════════════════════════════════════════════════
section_title("DIFFERENTIAL DIAGNOSIS — When to Think What?")
story.append(Spacer(1, 2*mm))
diff_data = [
[hcell("CLINICAL FINDING"), hcell("THINK FIRST"), hcell("RULE OUT")],
[cell("Skin attached + punctum", size=6.5),
cell("Sebaceous Cyst", bold=True, size=6.5, color=AMBER_H),
cell("Dermoid (no punctum, no skin attachment)", size=6.5)],
[cell("Slip sign + doughy + no punctum", size=6.5),
cell("Lipoma", bold=True, size=6.5, color=GREEN_H),
cell("Sebaceous cyst (check for punctum)", size=6.5)],
[cell("Deep attachment to bone/periosteum", size=6.5),
cell("Dermoid Cyst", bold=True, size=6.5, color=PINK_H),
cell("Sebaceous cyst (not fixed to bone)", size=6.5)],
[cell("Tense fluctuant, outer canthus, child", size=6.5),
cell("External Angular Dermoid", bold=True, size=6.5, color=PINK_H),
cell("Encephalocele (pulsatile; trans-sutural)", size=6.5)],
[cell("Multiple soft swellings all over body", size=6.5),
cell("Familial Lipomatosis / NF1", bold=True, size=6.5, color=GREEN_H),
cell("Gardner's syndrome (check family Hx)", size=6.5)],
[cell("Cheesy discharge from scalp swelling", size=6.5),
cell("Sebaceous Cyst", bold=True, size=6.5, color=AMBER_H),
cell("Cock's Peculiar Tumour (SCC) if ulcerated", size=6.5)],
[cell("Soft swelling near wrist, transilluminant", size=6.5),
cell("Ganglion (NOT lipoma/cyst)", bold=True, size=6.5, color=NAVY),
cell("Lipoma (not transilluminant)", size=6.5)],
[cell("Large retroperitoneal fatty mass", size=6.5),
cell("Liposarcoma (malignant) until proven otherwise", bold=True, size=6.5, color=HexColor("#C62828")),
cell("Benign lipoma (always biopsy retroperitoneal fat)", size=6.5)],
]
diff_tbl = Table(diff_data,
colWidths=[5.5*cm, 5.5*cm, CW - 11*cm],
repeatRows=1)
diff_style = [
("BACKGROUND", (0,0),(-1,0), NAVY),
("TEXTCOLOR", (0,0),(-1,0), WHITE),
("FONTNAME", (0,0),(-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0),(-1,-1), 6.5),
("TOPPADDING", (0,0),(-1,-1), 2),
("BOTTOMPADDING", (0,0),(-1,-1), 2),
("LEFTPADDING", (0,0),(-1,-1), 4),
("RIGHTPADDING", (0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
("GRID", (0,0),(-1,-1), 0.4, HexColor("#BDBDBD")),
("BOX", (0,0),(-1,-1), 1.2, NAVY),
]
for i in range(1, len(diff_data)):
bg = LGRAY if i % 2 == 0 else WHITE
diff_style.append(("BACKGROUND", (0,i),(0,i), HexColor("#E8EDF5")))
diff_style.append(("BACKGROUND", (1,i),(2,i), bg))
diff_tbl.setStyle(TableStyle(diff_style))
story.append(diff_tbl)
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 10 – BACK COVER (summary card)
# ═══════════════════════════════════════════════════════════════════════════════
section_title("MASTER COMPARISON — KEY SIGNS AT A GLANCE")
story.append(Spacer(1, 2*mm))
master = [
[hcell("SIGN"),
hcell("SEBACEOUS\nCYST", bg=AMBER_H),
hcell("LIPOMA", bg=GREEN_H),
hcell("DERMOID\nCYST", bg=PINK_H)],
[cell("Punctum", bold=True, size=7),
cell("✅ YES\n(PATHOGNOMONIC)", size=7, color=HexColor("#2E7D32")),
cell("❌ NO", size=7, color=HexColor("#C62828")),
cell("❌ NO", size=7, color=HexColor("#C62828"))],
[cell("Slip Sign", bold=True, size=7),
cell("❌ NO", size=7, color=HexColor("#C62828")),
cell("✅ YES\n(PATHOGNOMONIC)", size=7, color=HexColor("#2E7D32")),
cell("❌ NO", size=7, color=HexColor("#C62828"))],
[cell("Skin Attached", bold=True, size=7),
cell("✅ YES\n(at punctum)", size=7, color=HexColor("#2E7D32")),
cell("❌ NO", size=7, color=HexColor("#C62828")),
cell("❌ NO", size=7, color=HexColor("#C62828"))],
[cell("Deep (Bone) Attachment", bold=True, size=7),
cell("❌ NO", size=7, color=HexColor("#C62828")),
cell("❌ NO\n(subcutaneous free)", size=7, color=HexColor("#C62828")),
cell("✅ YES\n(periosteum/bone)", size=7, color=HexColor("#2E7D32"))],
[cell("True Fluctuation", bold=True, size=7),
cell("✅ YES", size=7, color=HexColor("#2E7D32")),
cell("❌ Pseudo only", size=7, color=HexColor("#C62828")),
cell("✅ YES (tense)", size=7, color=HexColor("#2E7D32"))],
[cell("Transillumination", bold=True, size=7),
cell("❌ NEG\n(keratin)", size=7, color=HexColor("#C62828")),
cell("❌ NEG\n(fat)", size=7, color=HexColor("#C62828")),
cell("❌ NEG\n(hair/keratin)", size=7, color=HexColor("#C62828"))],
[cell("Content", bold=True, size=7),
cell("Cheesy keratin", size=7),
cell("Fat (lobules)", size=7),
cell("Hair / teeth / sebum", size=7)],
[cell("Key Complication", bold=True, size=7),
cell("Infection → Abscess\nCock's Peculiar Tumour (SCC)", size=7),
cell("Liposarcoma\n(retroperitoneal sites)", size=7),
cell("Rupture → peritonitis\nIntracranial extension", size=7)],
[cell("Treatment", bold=True, size=7),
cell("Excise wall + punctum\n(en bloc)", size=7),
cell("Shell out along capsule\n(blunt dissection)", size=7),
cell("Excise + periosteal\nattachment / stalk", size=7)],
]
m_style = [
("FONTSIZE", (0,0),(-1,-1), 7),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING", (0,0),(-1,-1), 3),
("LEFTPADDING", (0,0),(-1,-1), 4),
("RIGHTPADDING", (0,0),(-1,-1), 4),
("VALIGN", (0,0),(-1,-1), "TOP"),
# Header
("BACKGROUND", (0,0),(-1,0), NAVY),
("TEXTCOLOR", (0,0),(-1,0), WHITE),
("FONTNAME", (0,0),(-1,0), "Helvetica-Bold"),
("ALIGN", (0,0),(-1,0), "CENTER"),
("VALIGN", (0,0),(-1,0), "MIDDLE"),
("BACKGROUND", (1,0),(1,0), AMBER_H),
("BACKGROUND", (2,0),(2,0), GREEN_H),
("BACKGROUND", (3,0),(3,0), PINK_H),
# Param column
("BACKGROUND", (0,1),(0,-1), PARAM),
("FONTNAME", (0,1),(0,-1), "Helvetica-Bold"),
# Grid
("GRID", (0,0),(-1,-1), 0.4, HexColor("#BDBDBD")),
("BOX", (0,0),(-1,-1), 1.5, NAVY),
]
for i in range(1, len(master)):
bg_c = AMBER if i % 2 == 1 else HexColor("#FFF3CD")
bg_l = GREEN if i % 2 == 1 else HexColor("#DCEDC8")
bg_d = PINK if i % 2 == 1 else HexColor("#F8BBD9")
m_style += [
("BACKGROUND", (1,i),(1,i), bg_c),
("BACKGROUND", (2,i),(2,i), bg_l),
("BACKGROUND", (3,i),(3,i), bg_d),
]
master_tbl = Table(master, colWidths=[PW, COL, COL, COL], repeatRows=1)
master_tbl.setStyle(TableStyle(m_style))
story.append(master_tbl)
story.append(Spacer(1, 3*mm))
story.append(HRFlowable(width="100%", thickness=1, color=NAVY))
story.append(Spacer(1, 1*mm))
story.append(Paragraph(
"General Surgery Quick Reference · MBBS / MS Viva Preparation · Based on S Das Clinical Surgery & Standard Surgical Texts",
ParagraphStyle("ft", fontName="Helvetica-Oblique", fontSize=6,
textColor=MGRAY, alignment=TA_CENTER)
))
# ─── BUILD ────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"Pocket guide generated: {OUTPUT}")
cd /tmp/workspace/benign-swelling-viva && python generate_pocket_guide.py 2>&1
~/benign-swelling-viva/generate_pocket_guide.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/benign-swelling-viva/generate_pocket_guide.py'
cd /tmp/workspace/benign-swelling-viva && python generate_pocket_guide.py 2>&1
ls -lh /tmp/workspace/benign-swelling-viva/Pocket_Guide_Benign_Swellings.pdf
Pocket Guide Benign Swellings
PDF Document · PDF
| Page | Content |
|---|---|
| 1 | Cover card — navy blue title card |
| 2 | At a Glance — Definition, Age, Sex, Sites, Contents, Onset |
| 3 | History key points + Inspection (6 S's, Punctum, Skin) |
| 4 | Palpation — The Viva Gold Zone (Slip sign, Fluctuation, Transillumination, Mobility, all 10 signs) |
| 5 | Key Diagnostic Clue (one-liner per swelling) + Investigations + Treatment |
| 6 | Complications + Syndromes & Eponyms table (Cock's Tumour, Madelung's, Dercum's, Gardner's, NF1) |
| 7 | Memory Mnemonics — S.P.A.C.E (Sebaceous Cyst) · S.L.I.P (Lipoma) · D.E.E.P (Dermoid) |
| 8 | Must-Know Viva Traps — 8 classic examiner trick questions with answers |
| 9 | Differential Diagnosis quick guide — "when to think what" |
| 10 | Master Comparison grid — all key signs (✅/❌) in a single colour-coded table |