Make appt on hydronephrosis for 10 slides
mkdir -p /tmp/workspace/hydronephrosis-ppt && ls /tmp/workspace/hydronephrosis-ppt/
~/hydronephrosis-ppt/build_pptx.py
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.util import Inches, Pt
from io import BytesIO
# Color palette
DARK_BLUE = RGBColor(0x1A, 0x3A, 0x5C) # deep navy
MID_BLUE = RGBColor(0x1E, 0x6D, 0xA0) # medium blue (accents)
LIGHT_BLUE = RGBColor(0xD6, 0xEA, 0xF8) # slide background tint
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
DARK_TEXT = RGBColor(0x1A, 0x1A, 0x2E)
ACCENT = RGBColor(0xE5, 0x4B, 0x2A) # orange-red accent
LIGHT_GRAY = RGBColor(0xF2, 0xF4, 0xF7)
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]
# ─── Helper functions ────────────────────────────────────────────────────────
def bg_rect(slide, color):
"""Full-slide background rectangle."""
shape = slide.shapes.add_shape(
1, # MSO_SHAPE_TYPE.RECTANGLE
0, 0, prs.slide_width, prs.slide_height
)
shape.fill.solid()
shape.fill.fore_color.rgb = color
shape.line.fill.background()
def add_rect(slide, left, top, width, height, fill_color, line=False):
shape = slide.shapes.add_shape(1, Inches(left), Inches(top), Inches(width), Inches(height))
shape.fill.solid()
shape.fill.fore_color.rgb = fill_color
if not line:
shape.line.fill.background()
else:
shape.line.color.rgb = fill_color
return shape
def add_text(slide, text, left, top, width, height,
font_size=18, bold=False, color=DARK_TEXT,
align=PP_ALIGN.LEFT, v_anchor=MSO_ANCHOR.TOP,
italic=False, word_wrap=True):
tb = slide.shapes.add_textbox(Inches(left), Inches(top), Inches(width), Inches(height))
tf = tb.text_frame
tf.word_wrap = word_wrap
tf.vertical_anchor = v_anchor
tf.margin_left = 0; tf.margin_right = 0
tf.margin_top = 0; tf.margin_bottom = 0
p = tf.paragraphs[0]
p.alignment = align
run = p.add_run()
run.text = text
run.font.size = Pt(font_size)
run.font.bold = bold
run.font.italic = italic
run.font.color.rgb = color
run.font.name = "Calibri"
return tf
def add_bullet_textbox(slide, items, left, top, width, height,
font_size=16, color=DARK_TEXT, title_color=MID_BLUE,
bullet="● "):
tb = slide.shapes.add_textbox(Inches(left), Inches(top), Inches(width), Inches(height))
tf = tb.text_frame
tf.word_wrap = True
tf.margin_left = 0; tf.margin_right = 0
tf.margin_top = 0; tf.margin_bottom = 0
first = True
for item in items:
if first:
p = tf.paragraphs[0]
first = False
else:
p = tf.add_paragraph()
p.space_before = Pt(4)
run = p.add_run()
run.text = bullet + item
run.font.size = Pt(font_size)
run.font.color.rgb = color
run.font.name = "Calibri"
return tf
def header_bar(slide, title, subtitle=None):
"""Dark blue top bar with title + optional subtitle."""
add_rect(slide, 0, 0, 13.333, 1.25, DARK_BLUE)
add_text(slide, title, 0.4, 0.1, 12.5, 0.8,
font_size=32, bold=True, color=WHITE,
align=PP_ALIGN.LEFT, v_anchor=MSO_ANCHOR.MIDDLE)
if subtitle:
add_text(slide, subtitle, 0.4, 0.9, 12.5, 0.35,
font_size=14, bold=False, color=LIGHT_BLUE,
align=PP_ALIGN.LEFT)
def footer(slide, text="Hydronephrosis | Medical Education"):
add_rect(slide, 0, 7.15, 13.333, 0.35, DARK_BLUE)
add_text(slide, text, 0.4, 7.16, 12.5, 0.3,
font_size=10, bold=False, color=LIGHT_BLUE,
align=PP_ALIGN.LEFT)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 1 — Title slide
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
bg_rect(slide, DARK_BLUE)
# Blue accent band
add_rect(slide, 0, 2.8, 13.333, 0.08, ACCENT)
add_text(slide, "HYDRONEPHROSIS",
0.8, 1.2, 11.7, 1.4,
font_size=54, bold=True, color=WHITE,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
add_text(slide, "Pathophysiology · Clinical Features · Diagnosis · Management",
0.8, 2.9, 11.7, 0.7,
font_size=20, bold=False, color=LIGHT_BLUE,
align=PP_ALIGN.CENTER)
add_text(slide, "A Comprehensive Overview",
0.8, 3.65, 11.7, 0.55,
font_size=16, bold=False, italic=True, color=RGBColor(0xAA, 0xCC, 0xEE),
align=PP_ALIGN.CENTER)
footer(slide)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 2 — Definition & Overview
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
bg_rect(slide, LIGHT_GRAY)
header_bar(slide, "Definition & Overview")
footer(slide)
add_rect(slide, 0.4, 1.4, 8.2, 5.4, WHITE)
add_rect(slide, 8.8, 1.4, 4.1, 5.4, WHITE)
# Definition box
add_text(slide, "What is Hydronephrosis?",
0.55, 1.5, 7.9, 0.5,
font_size=18, bold=True, color=MID_BLUE)
definition = (
"Hydronephrosis is the dilation of the renal pelvis and calyces, "
"with accompanying atrophy of the parenchyma, caused by obstruction "
"to the outflow of urine."
)
add_text(slide, definition,
0.55, 2.05, 7.9, 1.2,
font_size=15, color=DARK_TEXT, word_wrap=True)
add_text(slide, "Key Characteristics",
0.55, 3.35, 7.9, 0.4,
font_size=16, bold=True, color=MID_BLUE)
chars = [
"Obstruction may be sudden or insidious",
"Can occur at any level: urethra → renal pelvis",
"Bilateral when obstruction is below ureteric level",
"Unilateral when obstruction is at or above ureter",
"May remain clinically silent for long periods",
]
add_bullet_textbox(slide, chars, 0.55, 3.8, 7.9, 2.7, font_size=14)
# Right panel — quick facts
add_text(slide, "Quick Facts",
8.95, 1.5, 3.7, 0.45,
font_size=16, bold=True, color=MID_BLUE)
facts = [
"More common in females",
"Occurs at all ages",
"Fetal hydronephrosis detected in ~1–5% of pregnancies",
"Most obstructions are surgically correctable",
"Early relief → full functional recovery",
]
add_bullet_textbox(slide, facts, 8.95, 2.0, 3.7, 4.5, font_size=13)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 3 — Etiology / Causes
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
bg_rect(slide, LIGHT_GRAY)
header_bar(slide, "Etiology", "Causes of Urinary Outflow Obstruction")
footer(slide)
# Three column boxes
cols = [
("Congenital Causes", [
"Atresia of urethra",
"Valve formations (ureter / urethra)",
"Aberrant renal artery compressing ureter",
"Abnormal kidney position / kinking",
"Idiopathic PUJ stenosis (commonest)",
"Ureterocele",
]),
("Acquired — Intrinsic", [
"Calculi (ureteric / pelvic stones)",
"Sloughed necrotic papillae",
"Tumour of the ureter",
"Prostatitis / ureteritis / urethritis",
"Bladder tumour",
"Schistosomiasis",
]),
("Acquired — Extrinsic", [
"Benign prostatic hyperplasia",
"Carcinoma of the prostate",
"Carcinoma of cervix / uterus",
"Retroperitoneal lymphoma",
"Retroperitoneal fibrosis",
"Neurogenic (spinal cord damage)",
"Pregnancy (mild, physiologic)",
]),
]
col_x = [0.35, 4.6, 8.85]
for i, (title, items) in enumerate(cols):
add_rect(slide, col_x[i], 1.35, 4.0, 5.7, WHITE)
add_rect(slide, col_x[i], 1.35, 4.0, 0.55, MID_BLUE)
add_text(slide, title,
col_x[i]+0.1, 1.38, 3.8, 0.48,
font_size=15, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
add_bullet_textbox(slide, items,
col_x[i]+0.15, 1.95, 3.7, 4.9,
font_size=13)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 4 — Pathophysiology
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
bg_rect(slide, LIGHT_GRAY)
header_bar(slide, "Pathophysiology", "Sequence of Events After Obstruction")
footer(slide)
steps = [
("1", "Obstruction", "Outflow of urine blocked at any level of the urinary tract"),
("2", "Continued Filtration", "Glomerular filtration persists → filtrate diffuses into interstitium & returns via lymphatics/veins"),
("3", "Pelvicalyceal Dilation", "High intrapelvic pressure transmitted back through collecting ducts"),
("4", "Vascular Compromise", "Compression of renal vasculature → arterial insufficiency + venous stasis"),
("5", "Tubular Injury First", "Initial impairment of concentrating ability (papillae most vulnerable)"),
("6", "Glomerular Decline", "Later reduction in GFR → eventual parenchymal atrophy & fibrosis"),
]
box_w = 3.8
box_h = 1.05
col_positions = [(0.3, 1.35), (4.75, 1.35), (9.2, 1.35),
(0.3, 2.55), (4.75, 2.55), (9.2, 2.55)]
for idx, (num, title, desc) in enumerate(steps):
lx, ty = col_positions[idx]
add_rect(slide, lx, ty, box_w, box_h, WHITE)
# Step number circle (simulated as small box)
add_rect(slide, lx, ty, 0.45, box_h, MID_BLUE)
add_text(slide, num, lx+0.02, ty+0.18, 0.42, 0.55,
font_size=22, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, title, lx+0.52, ty+0.04, box_w-0.6, 0.38,
font_size=14, bold=True, color=MID_BLUE)
add_text(slide, desc, lx+0.52, ty+0.42, box_w-0.6, 0.6,
font_size=12, color=DARK_TEXT, word_wrap=True)
# Bottom morphology note
add_rect(slide, 0.3, 3.75, 12.7, 1.5, RGBColor(0xE8, 0xF4, 0xFF))
add_text(slide, "Morphologic Consequences",
0.5, 3.8, 12.4, 0.38,
font_size=14, bold=True, color=DARK_BLUE)
morph_text = (
"• Subtotal obstruction: kidney massively enlarged (up to 20 cm); parenchyma compressed & atrophied; papillae obliterated; pyramids flattened.\n"
"• Complete sudden obstruction: GFR compromised early; dilation comparatively mild.\n"
"• Microscopy: tubular dilation & atrophy → glomerular loss → replacement by fibrous tissue."
)
add_text(slide, morph_text, 0.5, 4.2, 12.4, 1.0,
font_size=12, color=DARK_TEXT, word_wrap=True)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 5 — Grading
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
bg_rect(slide, LIGHT_GRAY)
header_bar(slide, "Grading of Hydronephrosis", "SFU (Society for Fetal Urology) & Ultrasound Grading")
footer(slide)
grades = [
("Grade 0\n(Normal)", WHITE, DARK_TEXT, MID_BLUE,
"No dilation of collecting system; normal renal architecture"),
("Grade I\n(Mild)", RGBColor(0xD5, 0xF5, 0xE3), DARK_TEXT, RGBColor(0x1E, 0x8B, 0x4C),
"Slight dilation of renal pelvis; calyces not dilated; normal parenchymal thickness"),
("Grade II\n(Mild-Moderate)", RGBColor(0xFE, 0xF9, 0xE7), DARK_TEXT, RGBColor(0xD6, 0x8A, 0x10),
"Dilation of renal pelvis + major calyces; parenchyma intact; medullary pyramids visible"),
("Grade III\n(Moderate)", RGBColor(0xFD, 0xF2, 0xE0), DARK_TEXT, RGBColor(0xCA, 0x6F, 0x1E),
"Dilation of pelvis + all calyces; pyramids start to flatten; parenchyma mildly thinned"),
("Grade IV\n(Severe)", RGBColor(0xFD, 0xED, 0xEC), DARK_TEXT, RGBColor(0xC0, 0x39, 0x2B),
"Ballooned pelvis & calyces; corticomedullary differentiation lost; marked parenchymal thinning"),
]
gx = 0.3
for i, (label, bg, tc, lc, desc) in enumerate(grades):
add_rect(slide, gx + i*2.5, 1.4, 2.35, 5.4, bg)
add_rect(slide, gx + i*2.5, 1.4, 2.35, 0.7, lc)
add_text(slide, label,
gx + i*2.5 + 0.1, 1.42, 2.15, 0.65,
font_size=13, bold=True, color=WHITE,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
add_text(slide, desc,
gx + i*2.5 + 0.1, 2.15, 2.15, 4.5,
font_size=12, color=DARK_TEXT, word_wrap=True)
add_text(slide, "On ultrasound: mild = pelvis + calyces dilated, architecture retained | moderate = pyramids flatten | severe = ballooned, cortex thin, CMD lost",
0.3, 6.85, 12.7, 0.4,
font_size=11, italic=True, color=RGBColor(0x55, 0x55, 0x55))
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 6 — Clinical Features
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
bg_rect(slide, LIGHT_GRAY)
header_bar(slide, "Clinical Features", "Symptoms, Signs & Patterns")
footer(slide)
# Left panel — symptoms
add_rect(slide, 0.3, 1.35, 6.1, 5.7, WHITE)
add_rect(slide, 0.3, 1.35, 6.1, 0.5, MID_BLUE)
add_text(slide, "Symptoms",
0.4, 1.38, 5.9, 0.43,
font_size=16, bold=True, color=WHITE)
syms = [
"Dull ache / sense of weight in the loin (most common)",
"Often mistaken for backache — onset is insidious",
"Colicky pain if obstruction develops quickly",
"Pain may radiate to epigastrium (DDx: peptic ulcer)",
"Exacerbated by high fluid intake or diuretics",
"Dietl's crisis: sudden colicky pain → large urine output → swelling reduces",
"Haematuria (macroscopic or microscopic)",
"Polyuria in incomplete bilateral obstruction",
"Symptoms of the underlying cause (e.g., LUTS in BPH)",
]
add_bullet_textbox(slide, syms, 0.4, 1.92, 5.9, 4.9, font_size=13)
# Right panel — signs & unilateral vs bilateral
add_rect(slide, 6.7, 1.35, 6.1, 2.6, WHITE)
add_rect(slide, 6.7, 1.35, 6.1, 0.5, MID_BLUE)
add_text(slide, "Signs on Examination",
6.8, 1.38, 5.9, 0.43,
font_size=16, bold=True, color=WHITE)
signs = [
"Cystic, ballottable renal swelling",
"Bimanually palpable enlarged kidney",
"Tenderness in renal angle",
"Distended bladder if obstruction is distal",
]
add_bullet_textbox(slide, signs, 6.8, 1.92, 5.9, 1.8, font_size=13)
add_rect(slide, 6.7, 4.1, 6.1, 2.95, WHITE)
add_rect(slide, 6.7, 4.1, 6.1, 0.45, ACCENT)
add_text(slide, "Unilateral vs. Bilateral",
6.8, 4.13, 5.9, 0.38,
font_size=14, bold=True, color=WHITE)
uni_bi = [
"Unilateral: may remain silent if other kidney compensates",
"Bilateral: causes anuria and renal failure",
"Distal obstruction: bladder distention dominates",
"Obstruction relief → full recovery if not prolonged",
]
add_bullet_textbox(slide, uni_bi, 6.8, 4.62, 5.9, 2.2, font_size=13)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 7 — Investigations
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
bg_rect(slide, LIGHT_GRAY)
header_bar(slide, "Investigations", "Approach to Diagnosis")
footer(slide)
investig = [
("Ultrasound (USG)", "FIRST-LINE. Detects anechoic dilation of pelvicalyceal system (>95% sensitivity). Grades severity. Rules out pyonephrosis. Use color Doppler to distinguish from vasculature/cysts. Hydroureter may be traced.", MID_BLUE),
("X-ray KUB", "Detects 90% of renal calculi (except pure uric acid stones). Identifies renal outline enlargement. Quick, widely available.", RGBColor(0x27, 0x6E, 0x7C)),
("IVP / Excretory Urogram", "Confirms diagnosis. Early films may not show pelvis; delayed 6-hour films needed. Shows decreasing concavity and clubbing of calyces. Retrograde urography if pelvis/calyces not visualized.", DARK_BLUE),
("CT Urogram", "Best for identifying cause (stone, tumour, external compression). High resolution of entire urinary tract. CT KUB (non-contrast) is gold standard for urolithiasis.", RGBColor(0x6C, 0x35, 0x8D)),
("Isotope Renography (MAG3/DTPA)", "Detects dilatation of collecting system from obstruction. Assesses differential renal function. Diuretic renography distinguishes obstructive from non-obstructive dilation.", RGBColor(0x88, 0x4E, 0x00)),
("MRI Urography", "Best for pregnant patients and children. No radiation. Excellent soft tissue detail for tumour characterization.", RGBColor(0x1A, 0x5C, 0x38)),
("Whitaker Test", "Percutaneous puncture to monitor intrapelvic pressure. Used in specialized units when other tests equivocal.", RGBColor(0x7B, 0x24, 0x1C)),
("Urine Analysis / Culture", "R/O infection (pyonephrosis). Haematuria, pyuria, casts. Urine culture for UTI.", RGBColor(0x2C, 0x3E, 0x50)),
]
row_h = 0.69
top_start = 1.38
for i, (test, detail, col) in enumerate(investig):
row = i % 4
col_idx = i // 4
lx = 0.3 + col_idx * 6.55
ty = top_start + row * (row_h + 0.04)
add_rect(slide, lx, ty, 6.3, row_h, WHITE)
add_rect(slide, lx, ty, 0.18, row_h, col)
add_text(slide, test, lx+0.25, ty+0.02, 6.0, 0.3,
font_size=13, bold=True, color=col)
add_text(slide, detail, lx+0.25, ty+0.31, 6.0, 0.38,
font_size=11, color=DARK_TEXT, word_wrap=True)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 8 — Complications
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
bg_rect(slide, LIGHT_GRAY)
header_bar(slide, "Complications", "If Left Untreated or Recurrent")
footer(slide)
complications = [
("Pyelonephritis", "Superimposed bacterial infection of the hydronephrotic kidney; pyonephrosis (pus in collecting system). Fever + flank pain + sepsis."),
("Chronic Renal Failure", "Progressive parenchymal atrophy and fibrosis → irreversible loss of renal function with prolonged obstruction."),
("Acute Kidney Injury", "Bilateral obstruction → anuria → AKI. US >95% accurate in detecting hydronephrosis as a cause of AKI."),
("Hypertension", "Renal ischemia activates renin-angiotensin system → secondary hypertension."),
("Renal Calculi", "Urinary stasis promotes stone formation, further worsening obstruction — a vicious cycle."),
("Calyceal Rupture", "Rare but recognized complication, especially in physiologic hydronephrosis of pregnancy. Urinoma formation."),
("Renal Atrophy", "End-stage: kidney reduced to thin-walled cystic sac with no functional parenchyma."),
("Post-obstructive Diuresis", "After relief of prolonged bilateral obstruction → massive polyuria. Risk of electrolyte imbalance."),
]
box_w = 5.9
box_h = 1.18
positions = [
(0.3, 1.38), (6.55, 1.38),
(0.3, 2.65), (6.55, 2.65),
(0.3, 3.92), (6.55, 3.92),
(0.3, 5.19), (6.55, 5.19),
]
for idx, ((lx, ty), (title, desc)) in enumerate(zip(positions, complications)):
add_rect(slide, lx, ty, box_w, box_h, WHITE)
add_rect(slide, lx, ty, 0.15, box_h, ACCENT)
add_text(slide, title, lx+0.25, ty+0.05, box_w-0.35, 0.35,
font_size=14, bold=True, color=ACCENT)
add_text(slide, desc, lx+0.25, ty+0.42, box_w-0.35, 0.72,
font_size=12, color=DARK_TEXT, word_wrap=True)
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 9 — Management
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
bg_rect(slide, LIGHT_GRAY)
header_bar(slide, "Management", "Principles of Treatment")
footer(slide)
# Left: General principles
add_rect(slide, 0.3, 1.38, 5.9, 5.7, WHITE)
add_rect(slide, 0.3, 1.38, 5.9, 0.5, DARK_BLUE)
add_text(slide, "General Principles",
0.4, 1.41, 5.7, 0.43,
font_size=16, bold=True, color=WHITE)
principles = [
"Relieve obstruction as early as possible",
"Treat the underlying cause",
"Preserve / restore renal function",
"Prevent / treat infection",
"Monitor renal function (eGFR, imaging)",
]
add_bullet_textbox(slide, principles, 0.4, 1.95, 5.7, 2.2, font_size=14)
add_text(slide, "Temporary Drainage",
0.4, 4.25, 5.7, 0.38,
font_size=14, bold=True, color=MID_BLUE)
drain = [
"Ureteric stent (JJ stent) — bypasses obstruction",
"Percutaneous nephrostomy (PCN) — if stent fails",
"Urethral / suprapubic catheter for bladder outflow obstruction",
]
add_bullet_textbox(slide, drain, 0.4, 4.68, 5.7, 1.7, font_size=13)
add_text(slide, "Conservative (Mild/Antenatal)",
0.4, 6.45, 5.7, 0.35,
font_size=13, bold=True, color=MID_BLUE)
add_text(slide, "Watchful waiting with serial ultrasound for antenatal SFU Grade I–II; many resolve spontaneously",
0.4, 6.83, 5.7, 0.5,
font_size=12, color=DARK_TEXT, word_wrap=True)
# Right: Specific surgical options
add_rect(slide, 6.55, 1.38, 6.4, 5.7, WHITE)
add_rect(slide, 6.55, 1.38, 6.4, 0.5, DARK_BLUE)
add_text(slide, "Specific Surgical Options",
6.65, 1.41, 6.2, 0.43,
font_size=16, bold=True, color=WHITE)
surgeries = [
("Pyeloplasty (Anderson-Hynes)", "Gold standard for UPJ obstruction. Open, laparoscopic or robotic. ~95–97% success rate. Preferred in children and young adults."),
("Endopyelotomy", "Antegrade or retrograde endoscopic incision of UPJ. Less invasive; lower success (75–85%) vs. pyeloplasty. Used in selected cases."),
("Ureterolithiasis", "ESWL / ureteroscopy + laser lithotripsy / PCNL depending on stone size and location."),
("Prostatectomy / TURP", "For BPH/carcinoma causing bladder outflow obstruction with bilateral hydronephrosis."),
("Nephrectomy", "For non-functioning kidney (no recoverable function) or life-threatening sepsis."),
]
sy = 1.95
for title2, desc2 in surgeries:
add_text(slide, title2, 6.65, sy, 6.1, 0.32,
font_size=13, bold=True, color=MID_BLUE)
add_text(slide, desc2, 6.65, sy+0.33, 6.1, 0.52,
font_size=11, color=DARK_TEXT, word_wrap=True)
sy += 0.93
# ═══════════════════════════════════════════════════════════════════════════════
# SLIDE 10 — Summary
# ═══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
bg_rect(slide, DARK_BLUE)
add_text(slide, "Key Takeaways",
0.5, 0.2, 12.3, 0.8,
font_size=34, bold=True, color=WHITE,
align=PP_ALIGN.LEFT)
add_rect(slide, 0.5, 1.0, 3.5, 0.06, ACCENT)
takeaways = [
("Definition", "Dilation of renal pelvis & calyces + parenchymal atrophy from urinary outflow obstruction"),
("Commonest cause", "Idiopathic UPJ stenosis (congenital); calculi, BPH, malignancy (acquired)"),
("Pathophysiology", "Continued filtration → elevated intrapelvic pressure → tubular → then glomerular damage"),
("Grading", "Grade 0–IV by SFU; USG is first-line (>95% sensitive)"),
("Clinical", "Dull loin pain, Dietl's crisis, haematuria; bilateral → anuria + ARF"),
("Investigations", "USG (first-line) → CT Urogram/IVP → isotope renography"),
("Complications", "Pyelonephritis, CRF, AKI, hypertension, renal atrophy"),
("Management", "Relieve obstruction early; pyeloplasty (gold standard for UPJ); JJ stent/PCN as bridge"),
("Prognosis", "Full recovery if obstruction relieved promptly; irreversible damage with prolonged obstruction"),
]
row_y = 1.18
for i, (key, value) in enumerate(takeaways):
row_color = RGBColor(0x1E, 0x4A, 0x6E) if i % 2 == 0 else RGBColor(0x15, 0x3A, 0x5A)
add_rect(slide, 0.5, row_y, 12.3, 0.58, row_color)
add_text(slide, key, 0.6, row_y+0.05, 2.5, 0.45,
font_size=13, bold=True, color=ACCENT)
add_text(slide, value, 3.2, row_y+0.05, 9.4, 0.45,
font_size=13, color=WHITE, word_wrap=True)
row_y += 0.61
footer(slide)
# ─── SAVE ─────────────────────────────────────────────────────────────────────
out_path = "/tmp/workspace/hydronephrosis-ppt/Hydronephrosis.pptx"
buf = BytesIO()
prs.save(buf)
with open(out_path, "wb") as f:
f.write(buf.getvalue())
print(f"Saved: {out_path}")
python /tmp/workspace/hydronephrosis-ppt/build_pptx.py
python -c " from pptx import Presentation prs = Presentation('/tmp/workspace/hydronephrosis-ppt/Hydronephrosis.pptx') print(f'Slides: {len(prs.slides)}') for i, slide in enumerate(prs.slides, 1): texts = [s.text_frame.text.strip()[:60] for s in slide.shapes if s.has_text_frame and s.text_frame.text.strip()] print(f' Slide {i}: {texts[:2]}') "
Hydronephrosis
Presentation · PPTX
| # | Slide Title | Contents |
|---|---|---|
| 1 | Title Slide | Title, subtitle, color-branded cover |
| 2 | Definition & Overview | Definition, key characteristics, quick facts |
| 3 | Etiology | 3-column layout: Congenital / Acquired-Intrinsic / Acquired-Extrinsic causes |
| 4 | Pathophysiology | 6-step flowbox: obstruction → filtration → dilation → vascular → tubular → glomerular; morphology note |
| 5 | Grading | SFU Grade 0-IV with color-coded columns and ultrasound grading criteria |
| 6 | Clinical Features | Symptoms (including Dietl's crisis), Signs, Unilateral vs. Bilateral patterns |
| 7 | Investigations | 8 modalities: USG (first-line), KUB X-ray, IVP, CT Urogram, Isotope renography, MRI, Whitaker test, Urinalysis |
| 8 | Complications | 8 boxes: pyelonephritis, CRF, AKI, hypertension, calculi, calyceal rupture, atrophy, post-obstructive diuresis |
| 9 | Management | General principles + temporary drainage (JJ stent/PCN) + surgical options (pyeloplasty, endopyelotomy, TURP, nephrectomy) |
| 10 | Key Takeaways | Summary table of all key points across the presentation |