Create a ppt for the seminar topic renal stone

Asking for Preferences
Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Finding Sources
Reading File
Finding Sources
Finding Sources
Finding Sources
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Running Command

mkdir -p /tmp/workspace/renal-stone-ppt && ls /tmp/workspace/

Writing File

~/renal-stone-ppt/build_ppt.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
import copy

prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)

blank = prs.slide_layouts[6]

# ─── Color Palette ────────────────────────────────────────────────────────────
DARK_BLUE   = RGBColor(0x0D, 0x2B, 0x55)   # deep navy
MED_BLUE    = RGBColor(0x16, 0x5B, 0xAA)   # header blue
ACCENT_TEAL = RGBColor(0x00, 0xB4, 0xD8)   # accent / highlight
LIGHT_BG    = RGBColor(0xF0, 0xF6, 0xFF)   # slide background
WHITE       = RGBColor(0xFF, 0xFF, 0xFF)
TEXT_DARK   = RGBColor(0x1A, 0x1A, 0x2E)
YELLOW_HL   = RGBColor(0xFF, 0xD1, 0x66)   # warm accent
GRAY_LINE   = RGBColor(0xCC, 0xDD, 0xEE)
SOFT_GREEN  = RGBColor(0x2D, 0x9C, 0x6B)

def add_rect(slide, left, top, width, height, fill_color=None, line_color=None, line_width=None):
    shape = slide.shapes.add_shape(1, Inches(left), Inches(top), Inches(width), Inches(height))
    fill = shape.fill
    if fill_color:
        fill.solid()
        fill.fore_color.rgb = fill_color
    else:
        fill.background()
    line = shape.line
    if line_color:
        line.color.rgb = line_color
        if line_width:
            line.width = Pt(line_width)
    else:
        line.fill.background()
    return shape

def add_text(slide, text, left, top, width, height,
             font_size=18, bold=False, color=TEXT_DARK,
             align=PP_ALIGN.LEFT, italic=False, wrap=True):
    tb = slide.shapes.add_textbox(Inches(left), Inches(top), Inches(width), Inches(height))
    tf = tb.text_frame
    tf.word_wrap = wrap
    tf.margin_left = Pt(4)
    tf.margin_right = Pt(4)
    tf.margin_top = Pt(2)
    tf.margin_bottom = Pt(2)
    p = tf.paragraphs[0]
    p.alignment = align
    p.text = text
    r = p.runs[0]
    r.font.name = "Calibri"
    r.font.size = Pt(font_size)
    r.font.bold = bold
    r.font.italic = italic
    r.font.color.rgb = color
    return tb

def add_multiline_text(slide, lines, left, top, width, height,
                       font_size=16, color=TEXT_DARK, bold_first=False,
                       line_spacing_pt=4):
    tb = slide.shapes.add_textbox(Inches(left), Inches(top), Inches(width), Inches(height))
    tf = tb.text_frame
    tf.word_wrap = True
    tf.margin_left = Pt(4)
    tf.margin_right = Pt(4)
    tf.margin_top = Pt(2)
    tf.margin_bottom = Pt(2)
    for i, line in enumerate(lines):
        if i == 0:
            p = tf.paragraphs[0]
        else:
            p = tf.add_paragraph()
        p.space_before = Pt(line_spacing_pt)
        r = p.add_run()
        r.text = line
        r.font.name = "Calibri"
        r.font.size = Pt(font_size)
        r.font.color.rgb = color
        r.font.bold = (bold_first and i == 0)
    return tb

def slide_bg(slide, color=LIGHT_BG):
    add_rect(slide, 0, 0, 13.333, 7.5, fill_color=color)

def header_bar(slide, title, subtitle=None):
    # Top bar
    add_rect(slide, 0, 0, 13.333, 1.3, fill_color=DARK_BLUE)
    # Accent strip
    add_rect(slide, 0, 1.3, 13.333, 0.07, fill_color=ACCENT_TEAL)
    add_text(slide, title, 0.35, 0.1, 11, 0.8,
             font_size=30, bold=True, color=WHITE, align=PP_ALIGN.LEFT)
    if subtitle:
        add_text(slide, subtitle, 0.35, 0.85, 10, 0.45,
                 font_size=16, color=ACCENT_TEAL, align=PP_ALIGN.LEFT)

def footer(slide, text="Renal Stone Disease  |  Seminar Presentation", page_num=None):
    add_rect(slide, 0, 7.1, 13.333, 0.4, fill_color=DARK_BLUE)
    label = text + (f"    {page_num}" if page_num else "")
    add_text(slide, label, 0.3, 7.12, 12.5, 0.35,
             font_size=11, color=RGBColor(0xCC, 0xDD, 0xFF), align=PP_ALIGN.LEFT)

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 1 – TITLE SLIDE
# ══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
# Full gradient-style background
add_rect(slide, 0, 0, 13.333, 7.5, fill_color=DARK_BLUE)
add_rect(slide, 0, 0, 6.5, 7.5, fill_color=MED_BLUE)
add_rect(slide, 6.5, 0, 0.08, 7.5, fill_color=ACCENT_TEAL)

# Decorative circles
for cx, cy, r in [(10, 1.5, 1.2), (11.5, 5.5, 1.8), (9.5, 6.2, 0.6)]:
    shape = slide.shapes.add_shape(9, Inches(cx-r), Inches(cy-r), Inches(r*2), Inches(r*2))
    shape.fill.solid()
    shape.fill.fore_color.rgb = RGBColor(0x1A, 0x4A, 0x80)
    shape.line.fill.background()

# Kidney icon substitute – stylised text block
add_rect(slide, 7.5, 1.8, 4.5, 3.5, fill_color=RGBColor(0x12, 0x3A, 0x6A))
add_text(slide, "🫘", 9.2, 2.1, 1.5, 1.5, font_size=60, color=ACCENT_TEAL, align=PP_ALIGN.CENTER)
add_text(slide, "NEPHROLITHIASIS", 7.6, 3.6, 4.3, 0.6,
         font_size=13, bold=True, color=ACCENT_TEAL, align=PP_ALIGN.CENTER)
add_text(slide, "Kidney Stone Disease", 7.6, 4.05, 4.3, 0.5,
         font_size=11, italic=True, color=WHITE, align=PP_ALIGN.CENTER)

# Title block
add_text(slide, "RENAL STONE", 0.5, 1.8, 5.7, 1.1,
         font_size=46, bold=True, color=WHITE, align=PP_ALIGN.LEFT)
add_text(slide, "DISEASE", 0.5, 2.75, 5.7, 0.9,
         font_size=46, bold=True, color=YELLOW_HL, align=PP_ALIGN.LEFT)
add_rect(slide, 0.5, 3.65, 3.5, 0.06, fill_color=ACCENT_TEAL)
add_text(slide, "A Comprehensive Seminar for Medical Students", 0.5, 3.8, 5.7, 0.55,
         font_size=15, italic=True, color=RGBColor(0xCC, 0xDD, 0xFF), align=PP_ALIGN.LEFT)
add_text(slide, "Topics Covered: Epidemiology • Pathophysiology • Types\nDiagnosis • Clinical Features • Management • Prevention",
         0.5, 4.45, 5.7, 0.9,
         font_size=12, color=RGBColor(0xAA, 0xCC, 0xFF), align=PP_ALIGN.LEFT)

add_rect(slide, 0, 7.05, 13.333, 0.45, fill_color=RGBColor(0x08, 0x1A, 0x38))
add_text(slide, "References: Tintinalli's Emergency Medicine  •  Campbell-Walsh Urology  •  Bailey & Love Surgery  •  Brenner & Rector's Kidney",
         0.4, 7.1, 12.5, 0.35,
         font_size=9.5, color=RGBColor(0x88, 0xAA, 0xCC), align=PP_ALIGN.LEFT)

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 2 – OVERVIEW / CONTENTS
# ══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
slide_bg(slide)
header_bar(slide, "Overview", "What We Will Cover Today")

topics = [
    ("01", "Definition & Epidemiology", "Prevalence, risk groups, trends"),
    ("02", "Pathophysiology",           "Stone formation mechanisms"),
    ("03", "Types of Renal Stones",     "Calcium, uric acid, struvite, cystine"),
    ("04", "Clinical Features",         "Renal colic, haematuria, symptoms"),
    ("05", "Investigations",            "Imaging, urinalysis, blood tests"),
    ("06", "Management",                "Conservative, medical, surgical"),
    ("07", "Complications",             "Obstruction, infection, CKD"),
    ("08", "Prevention & Diet",         "Fluids, dietary changes, medications"),
]

cols = 2
rows = 4
box_w = 5.7
box_h = 1.2
gap_x = 0.35
start_x = 0.45
start_y = 1.55

for i, (num, title, desc) in enumerate(topics):
    col = i % cols
    row = i // cols
    x = start_x + col * (box_w + gap_x)
    y = start_y + row * (box_h + 0.1)

    # Card background
    add_rect(slide, x, y, box_w, box_h - 0.05, fill_color=WHITE,
             line_color=GRAY_LINE, line_width=0.8)
    # Left accent bar
    add_rect(slide, x, y, 0.22, box_h - 0.05, fill_color=MED_BLUE)
    # Number
    add_text(slide, num, x + 0.02, y + 0.05, 0.22, 0.55,
             font_size=14, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
    # Topic title
    add_text(slide, title, x + 0.3, y + 0.06, box_w - 0.4, 0.45,
             font_size=15, bold=True, color=DARK_BLUE)
    # Description
    add_text(slide, desc, x + 0.3, y + 0.52, box_w - 0.4, 0.45,
             font_size=11.5, color=RGBColor(0x44, 0x55, 0x77), italic=True)

footer(slide, page_num="2 / 12")

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 3 – DEFINITION & EPIDEMIOLOGY
# ══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
slide_bg(slide)
header_bar(slide, "Definition & Epidemiology", "Understanding the Burden of Renal Stone Disease")

# Definition box (left)
add_rect(slide, 0.4, 1.55, 5.9, 2.1, fill_color=MED_BLUE)
add_text(slide, "DEFINITION", 0.55, 1.6, 5.6, 0.45,
         font_size=14, bold=True, color=YELLOW_HL)
add_multiline_text(slide, [
    "Nephrolithiasis (renal stone / urolithiasis) refers to",
    "the formation of calculi (stones) within the urinary",
    "tract — kidneys, ureters, bladder, or urethra.",
    "",
    "Stones form when dissolved salts in the urine become",
    "supersaturated and precipitate into a solid phase.",
], 0.55, 2.0, 5.7, 1.6, font_size=13.5, color=WHITE)

# Epidemiology box (right)
add_rect(slide, 6.7, 1.55, 6.0, 2.1, fill_color=WHITE,
         line_color=GRAY_LINE, line_width=1)
add_rect(slide, 6.7, 1.55, 6.0, 0.42, fill_color=ACCENT_TEAL)
add_text(slide, "EPIDEMIOLOGY KEY FACTS", 6.8, 1.58, 5.8, 0.38,
         font_size=13, bold=True, color=WHITE)
epi_facts = [
    "• Prevalence in US: 5.2% (1994) → 8.8% (2010)",
    "• Men: 10.6%  |  Women: 7.1%",
    "• Increasing trend in Europe & Southeast Asia",
    "• Recurrence: 11% at 2 yrs, 20% at 5 yrs, 39% at 15 yrs",
    "• Strongly associated with obesity and diabetes",
]
add_multiline_text(slide, epi_facts, 6.8, 2.0, 5.7, 1.6, font_size=12.5, color=TEXT_DARK)

# Risk factors row
add_rect(slide, 0.4, 3.8, 12.3, 2.05, fill_color=RGBColor(0xE8, 0xF1, 0xFF),
         line_color=GRAY_LINE, line_width=0.8)
add_text(slide, "RISK FACTORS", 0.6, 3.85, 5, 0.4,
         font_size=13, bold=True, color=MED_BLUE)
risk_cols = [
    ["Metabolic", "• Hypercalciuria", "• Hyperoxaluria", "• Hyperuricosuria", "• Hypocitraturia"],
    ["Systemic Disease", "• Hyperparathyroidism", "• Gout / chemotherapy", "• Inflammatory bowel disease", "• Renal tubular acidosis"],
    ["Lifestyle & Diet", "• Low fluid intake", "• High sodium / protein diet", "• Obesity & diabetes", "• Immobilisation"],
    ["Medications", "• Indinavir (HIV therapy)", "• Carbonic anhydrase inhibitors", "• Triamterene", "• Laxative abuse"],
]
for i, col in enumerate(risk_cols):
    x = 0.5 + i * 3.05
    add_rect(slide, x, 4.25, 2.85, 1.5, fill_color=WHITE, line_color=GRAY_LINE, line_width=0.5)
    add_multiline_text(slide, col, x + 0.1, 4.28, 2.65, 1.45, font_size=11, color=TEXT_DARK, bold_first=True)

footer(slide, page_num="3 / 12")

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 4 – PATHOPHYSIOLOGY
# ══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
slide_bg(slide)
header_bar(slide, "Pathophysiology", "How Renal Stones Form")

# Flow diagram – 5 steps
steps = [
    ("SUPERSATURATION", "Urine becomes\noversaturated with\ncalcium, oxalate,\nuric acid, etc."),
    ("NUCLEATION", "Crystal seeds form\nwhen solute\nconcentration exceeds\nsolubility product"),
    ("CRYSTAL GROWTH", "Crystals grow by\naggregation;\nanchored to\nrenal tubular cells"),
    ("STONE FORMATION", "Crystals enlarge\ninto macroscopic\nstones within\nrenal pelvis/calyx"),
    ("OBSTRUCTION", "Stone migrates\nto ureter → colic,\nobstruction,\nhydronephrosis"),
]
arrow_color = ACCENT_TEAL
step_w = 2.0
step_h = 2.6
gap = 0.3
total = len(steps) * step_w + (len(steps)-1) * (gap + 0.25)
start = (13.333 - total) / 2

for i, (title, body) in enumerate(steps):
    x = start + i * (step_w + gap + 0.25)
    # Box
    bg = MED_BLUE if i % 2 == 0 else DARK_BLUE
    add_rect(slide, x, 1.6, step_w, step_h, fill_color=bg)
    # Step number circle
    add_rect(slide, x + 0.72, 1.5, 0.55, 0.55, fill_color=ACCENT_TEAL)
    add_text(slide, str(i+1), x + 0.72, 1.5, 0.55, 0.55,
             font_size=14, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
    add_text(slide, title, x + 0.05, 2.1, step_w - 0.1, 0.55,
             font_size=11.5, bold=True, color=YELLOW_HL, align=PP_ALIGN.CENTER)
    add_text(slide, body, x + 0.08, 2.65, step_w - 0.16, 1.45,
             font_size=11, color=WHITE, align=PP_ALIGN.CENTER)
    # Arrow (except after last)
    if i < len(steps) - 1:
        ax = x + step_w + 0.03
        add_text(slide, "▶", ax, 2.5, 0.22, 0.5,
                 font_size=18, bold=True, color=ACCENT_TEAL, align=PP_ALIGN.CENTER)

# Inhibitors panel
add_rect(slide, 0.4, 4.4, 12.3, 1.5, fill_color=RGBColor(0xE3, 0xF5, 0xEB),
         line_color=SOFT_GREEN, line_width=1)
add_text(slide, "NATURAL INHIBITORS of Stone Formation:", 0.6, 4.45, 8, 0.4,
         font_size=13, bold=True, color=SOFT_GREEN)
inhib = [
    "Citrate – complexes with calcium, reduces supersaturation",
    "Magnesium – binds oxalate, reduces absorption",
    "Tamm-Horsfall protein – inhibits crystal aggregation",
    "Pyrophosphate – inhibits calcium phosphate crystallisation",
    "Nephrocalcin – inhibits calcium oxalate crystal growth",
]
add_multiline_text(slide, ["• " + x for x in inhib[:3]], 0.6, 4.88, 6, 0.95, font_size=11.5, color=TEXT_DARK)
add_multiline_text(slide, ["• " + x for x in inhib[3:]], 7.0, 4.88, 5.5, 0.95, font_size=11.5, color=TEXT_DARK)

footer(slide, page_num="4 / 12")

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 5 – TYPES OF RENAL STONES
# ══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
slide_bg(slide)
header_bar(slide, "Types of Renal Stones", "Classification by Composition")

stone_types = [
    {
        "name": "Calcium Oxalate /\nPhosphate",
        "pct":  "~80%",
        "color": MED_BLUE,
        "points": [
            "Most common type",
            "Opaque on X-ray",
            "Associated with hypercalciuria,",
            "  hyperoxaluria, hypocitraturia",
            "Paradox: low Ca diet ↑ risk",
            "(more oxalate absorbed from gut)",
        ],
    },
    {
        "name": "Struvite\n(Infection Stone)",
        "pct":  "~10%",
        "color": RGBColor(0x8E, 0x44, 0xAD),
        "points": [
            "Magnesium-ammonium-phosphate",
            "Associated with urease-producing",
            "  bacteria (Proteus, Klebsiella)",
            "Forms STAGHORN CALCULI",
            "Opaque, antler-shaped on imaging",
            "Risk: urosepsis; poor antibiotic",
            "  penetration into stone",
        ],
    },
    {
        "name": "Uric Acid",
        "pct":  "~10%",
        "color": RGBColor(0xC0, 0x39, 0x2B),
        "points": [
            "More common in men",
            "Associated with gout,",
            "  chemotherapy, acidic urine",
            "RADIOLUCENT on plain X-ray",
            "Visible on CT / ultrasound",
            "Responsive to urine alkalinisation",
        ],
    },
    {
        "name": "Cystine",
        "pct":  "~1%",
        "color": SOFT_GREEN,
        "points": [
            "Autosomal recessive disorder",
            "(Cystinuria): COLA mnemonic",
            "  Cystine, Ornithine, Lysine,",
            "  Arginine excess in urine",
            "Faint opacity on X-ray",
            "Recurrent, difficult to treat",
        ],
    },
]

card_w = 3.0
card_h = 4.55
gap = 0.18
start_x = 0.4

for i, st in enumerate(stone_types):
    x = start_x + i * (card_w + gap)
    add_rect(slide, x, 1.5, card_w, card_h, fill_color=WHITE,
             line_color=st["color"], line_width=1.5)
    add_rect(slide, x, 1.5, card_w, 0.9, fill_color=st["color"])
    add_text(slide, st["name"], x + 0.08, 1.52, card_w - 0.16, 0.6,
             font_size=13, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
    # Percent badge
    add_rect(slide, x + card_w - 0.88, 1.55, 0.8, 0.4,
             fill_color=YELLOW_HL)
    add_text(slide, st["pct"], x + card_w - 0.88, 1.55, 0.8, 0.4,
             font_size=12, bold=True, color=DARK_BLUE, align=PP_ALIGN.CENTER)
    add_multiline_text(slide, ["• " + p for p in st["points"]],
                       x + 0.1, 2.45, card_w - 0.2, 3.5,
                       font_size=11, color=TEXT_DARK)

footer(slide, page_num="5 / 12")

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 6 – CLINICAL FEATURES
# ══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
slide_bg(slide)
header_bar(slide, "Clinical Features", "Symptoms & Signs of Renal Stone Disease")

# Left: Renal Colic description
add_rect(slide, 0.4, 1.55, 6.1, 4.0, fill_color=WHITE,
         line_color=GRAY_LINE, line_width=1)
add_rect(slide, 0.4, 1.55, 6.1, 0.5, fill_color=MED_BLUE)
add_text(slide, "⚡  RENAL COLIC – Cardinal Symptom", 0.55, 1.58, 5.8, 0.44,
         font_size=14, bold=True, color=WHITE)
colic_points = [
    "Sudden onset severe, colicky loin pain",
    "Radiates from flank → groin / genitalia (along ureter)",
    "Comes in waves; patient cannot find a comfortable position",
    "Accompanied by nausea, vomiting, restlessness",
    "Pain is due to obstruction of the ureter (hollow viscus)",
    "Ureteric peristalsis proximal to stone increases pain",
    "",
    "PAIN LOCATION BY STONE POSITION:",
    "  • Pelvi-ureteric junction → loin / upper ureter",
    "  • Mid-ureter → lateral abdomen",
    "  • Lower ureter / VUJ → suprapubic, groin, scrotum/labia",
    "  • Intravesical stone → dysuria, frequency",
]
add_multiline_text(slide, colic_points, 0.55, 2.1, 5.8, 3.35,
                   font_size=12, color=TEXT_DARK)

# Right: Other features
add_rect(slide, 6.9, 1.55, 5.9, 4.0, fill_color=WHITE,
         line_color=GRAY_LINE, line_width=1)
add_rect(slide, 6.9, 1.55, 5.9, 0.5, fill_color=ACCENT_TEAL)
add_text(slide, "OTHER CLINICAL FEATURES", 7.05, 1.58, 5.6, 0.44,
         font_size=14, bold=True, color=WHITE)
other = [
    ("Haematuria", "Gross or microscopic; present in ~80%"),
    ("Fever/Rigors", "Suggests superadded infection; EMERGENCY"),
    ("Nausea/Vomiting", "Due to autonomic response to pain"),
    ("Oliguria/Anuria", "Bilateral obstruction or solitary kidney"),
    ("Pyuria/Dysuria", "Suggest concurrent UTI"),
    ("Passage of stone", "Gravel in urine confirms diagnosis"),
    ("Silent stone", "Incidental finding on imaging (calyceal)"),
]
for i, (hd, tx) in enumerate(other):
    y = 2.15 + i * 0.5
    add_rect(slide, 6.9, y - 0.02, 1.65, 0.44, fill_color=LIGHT_BG)
    add_text(slide, hd, 6.96, y, 1.55, 0.4,
             font_size=11.5, bold=True, color=MED_BLUE)
    add_text(slide, tx, 8.6, y, 4.1, 0.4,
             font_size=11.5, color=TEXT_DARK)

# Emergency banner
add_rect(slide, 0.4, 5.65, 12.4, 0.65, fill_color=RGBColor(0xFF, 0xEB, 0xEB),
         line_color=RGBColor(0xCC, 0x22, 0x22), line_width=1)
add_text(slide,
         "⚠  EMERGENCY SIGNS: Fever + Rigors + Obstruction = Obstructed Infected Kidney → Urgent decompression (nephrostomy/stenting)",
         0.55, 5.68, 12.1, 0.55,
         font_size=12, bold=True, color=RGBColor(0xAA, 0x11, 0x11))

footer(slide, page_num="6 / 12")

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 7 – INVESTIGATIONS
# ══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
slide_bg(slide)
header_bar(slide, "Investigations", "Diagnosis & Metabolic Evaluation")

invest = [
    {
        "cat": "URINALYSIS",
        "color": MED_BLUE,
        "items": [
            "Dipstick: haematuria in ~80%",
            "pH < 5.5 → uric acid; pH > 7.0 → struvite",
            "Nitrites / leucocytes → UTI / infected stone",
            "Crystal microscopy: oxalate (envelope), uric acid (rhomboid), cystine (hexagonal)",
            "24-hr urine: calcium, oxalate, uric acid, citrate, creatinine",
        ],
    },
    {
        "cat": "BLOOD TESTS",
        "color": SOFT_GREEN,
        "items": [
            "FBC: leukocytosis suggests infection",
            "U&E, creatinine: renal function",
            "Serum Ca²⁺, uric acid, PTH",
            "Serum electrolytes: bicarbonate (RTA?)",
            "CRP / ESR if infective stone suspected",
        ],
    },
    {
        "cat": "IMAGING",
        "color": RGBColor(0xE67, 0xE22, 0x00),
        "color": RGBColor(0xD3, 0x54, 0x00),
        "items": [
            "NCCT KUB: Gold standard; detects 95-99% of stones; size, site, density (HU)",
            "Ultrasound: First-line in pregnancy & children; shows hydronephrosis, twinkle artifact",
            "Plain X-ray (KUB): Detects radio-opaque stones; misses uric acid (radiolucent)",
            "IVU/IVP: Largely replaced by NCCT; shows anatomy & function",
            "MRI: Pregnancy; poor stone characterisation",
        ],
    },
]

col_w = 4.0
for i, inv in enumerate(invest):
    x = 0.4 + i * (col_w + 0.2)
    add_rect(slide, x, 1.55, col_w, 4.85, fill_color=WHITE,
             line_color=GRAY_LINE, line_width=1)
    add_rect(slide, x, 1.55, col_w, 0.5, fill_color=inv["color"])
    add_text(slide, inv["cat"], x + 0.1, 1.58, col_w - 0.2, 0.44,
             font_size=14, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
    add_multiline_text(slide, ["• " + it for it in inv["items"]],
                       x + 0.15, 2.1, col_w - 0.25, 4.2,
                       font_size=11.5, color=TEXT_DARK)

# Stone analysis note
add_rect(slide, 0.4, 6.45, 12.4, 0.55, fill_color=RGBColor(0xFFF, 0xF8, 0xE1),
         line_color=YELLOW_HL, line_width=1)
add_rect(slide, 0.4, 6.45, 12.4, 0.55, fill_color=RGBColor(0xFF, 0xF8, 0xE1),
         line_color=YELLOW_HL, line_width=1)
add_text(slide,
         "💡  Stone Analysis: All retrieved stones should be sent for crystallographic analysis (infrared spectroscopy / X-ray diffraction) to guide targeted prevention.",
         0.6, 6.48, 12.0, 0.5,
         font_size=11.5, color=RGBColor(0x55, 0x44, 0x00))

footer(slide, page_num="7 / 12")

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 8 – MANAGEMENT OVERVIEW
# ══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
slide_bg(slide)
header_bar(slide, "Management", "Conservative, Medical & Surgical Approaches")

# 3 columns
mgmt = [
    {
        "title": "CONSERVATIVE",
        "subtitle": "(Expectant / MET)",
        "color": SOFT_GREEN,
        "items": [
            "Indications:",
            "  • Stones ≤ 5 mm (pass spontaneously ~90%)",
            "  • Stones 5-10 mm (pass ~50%)",
            "",
            "Measures:",
            "  • Analgesia: NSAIDs (diclofenac) first-line",
            "     (↓ ureteral spasm, anti-inflammatory)",
            "  • Opioids if NSAIDs contra-indicated",
            "  • IV fluids for hydration",
            "  • Anti-emetics (metoclopramide)",
            "",
            "Medical Expulsive Therapy (MET):",
            "  • α-Blockers (tamsulosin 0.4 mg od)",
            "  • Calcium channel blockers (nifedipine)",
            "  • ↑ ureteral relaxation, aid stone passage",
        ],
    },
    {
        "title": "SURGICAL / PROCEDURES",
        "subtitle": "(Stones > 10 mm or failed MET)",
        "color": MED_BLUE,
        "items": [
            "ESWL (Extracorporeal SWL):",
            "  • Stones < 2 cm, upper ureter",
            "  • Non-invasive; high-energy shock waves",
            "  • Requires patent distal ureter",
            "  • Contra: pregnancy, coagulopathy, aortic aneurysm",
            "",
            "Ureteroscopy (URS) + Laser:",
            "  • Any ureteral stone; lower pole < 2 cm",
            "  • Holmium:YAG laser lithotripsy",
            "  • Stone-free rate ~90-95%",
            "",
            "PCNL (Percutaneous Nephrolithotomy):",
            "  • Stones > 2 cm; staghorn calculi",
            "  • Best stone-free rates for large stones",
            "  • Requires GA and fluoroscopy guidance",
        ],
    },
    {
        "title": "SPECIFIC STONE TYPE",
        "subtitle": "(Targeted Medical Treatment)",
        "color": RGBColor(0xD3, 0x54, 0x00),
        "items": [
            "Uric Acid Stones:",
            "  • Alkalinise urine: potassium citrate",
            "    (target pH 6.5-7.0)",
            "  • Allopurinol if hyperuricosuria",
            "  • High fluid intake (> 2.5 L/day)",
            "",
            "Struvite Stones:",
            "  • Complete surgical removal critical",
            "  • Targeted antibiotics post-op",
            "  • Acetohydroxamic acid (urease inhibitor)",
            "",
            "Calcium Stones (Hypercalciuria):",
            "  • Thiazide diuretics (↓ urinary Ca)",
            "  • Potassium citrate (↑ urinary citrate)",
            "",
            "Cystine Stones:",
            "  • High fluid intake, urine alkalinisation",
            "  • D-penicillamine, tiopronin",
        ],
    },
]

col_w = 4.0
for i, m in enumerate(mgmt):
    x = 0.4 + i * (col_w + 0.2)
    add_rect(slide, x, 1.55, col_w, 5.3, fill_color=WHITE,
             line_color=GRAY_LINE, line_width=1)
    add_rect(slide, x, 1.55, col_w, 0.65, fill_color=m["color"])
    add_text(slide, m["title"], x + 0.1, 1.57, col_w - 0.2, 0.4,
             font_size=13, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
    add_text(slide, m["subtitle"], x + 0.1, 1.95, col_w - 0.2, 0.32,
             font_size=10, italic=True, color=RGBColor(0xDD, 0xFF, 0xEE), align=PP_ALIGN.CENTER)
    add_multiline_text(slide, m["items"], x + 0.12, 2.27, col_w - 0.22, 4.45,
                       font_size=10.5, color=TEXT_DARK)

footer(slide, page_num="8 / 12")

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 9 – SURGICAL SIZE GUIDE
# ══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
slide_bg(slide)
header_bar(slide, "Surgical Decision Guide", "Stone Size & Location → Treatment Choice")

# Visual size bar
add_rect(slide, 1.0, 1.7, 11.333, 0.7, fill_color=RGBColor(0xE0, 0xEE, 0xFF),
         line_color=GRAY_LINE, line_width=0.5)
add_text(slide, "← Smaller Stone", 1.1, 1.72, 4, 0.4,
         font_size=11, italic=True, color=RGBColor(0x44, 0x66, 0x99))
add_text(slide, "Larger Stone →", 9.0, 1.72, 3, 0.4,
         font_size=11, italic=True, color=RGBColor(0x44, 0x66, 0x99), align=PP_ALIGN.RIGHT)

# Gradient blocks representing size
sizes = [("≤ 5 mm", SOFT_GREEN), ("5-10 mm", ACCENT_TEAL), ("10-20 mm", MED_BLUE), ("> 20 mm", DARK_BLUE)]
sw = 11.333 / 4
for i, (lbl, col) in enumerate(sizes):
    x = 1.0 + i * sw
    add_rect(slide, x, 2.55, sw - 0.05, 0.55, fill_color=col)
    add_text(slide, lbl, x + 0.05, 2.57, sw - 0.1, 0.5,
             font_size=14, bold=True, color=WHITE, align=PP_ALIGN.CENTER)

# Decision table
decisions = [
    ("≤ 5 mm",   "Renal Pelvis/\nCalyx",  "Conservative + Fluids\n+ MET (alpha-blocker)",      "~90% pass\nspontaneously",    SOFT_GREEN),
    ("5-10 mm",  "Ureter",               "MET + Ureteroscopy if\nfailed (4-6 weeks)",          "~50% pass;\nURS if needed",   ACCENT_TEAL),
    ("10-20 mm", "Upper Ureter",         "ESWL or Ureteroscopy\n+ Holmium laser",              "Stone-free\n~90-95%",         MED_BLUE),
    ("10-20 mm", "Lower Pole\nKidney",   "Ureteroscopy preferred\n(ESWL less effective)",      "URS stone-free\n~90%",        MED_BLUE),
    ("> 20 mm",  "Kidney (large)",       "PCNL — gold standard\nfor large stone burden",       "Stone-free\n~80-90%",         DARK_BLUE),
    ("Staghorn", "Renal Pelvis\n(cast)", "PCNL ± multiple\nstages; antibiotics",               "Complex;\nmultiple sessions", DARK_BLUE),
]

headers = ["Stone Size", "Location", "Recommended Treatment", "Expected Outcome"]
col_ws = [1.5, 2.0, 4.5, 3.2]
xs = [0.5]
for w in col_ws[:-1]:
    xs.append(xs[-1] + w + 0.05)
y_start = 3.25

# Header row
add_rect(slide, 0.5, y_start, sum(col_ws) + 0.15*(len(col_ws)-1), 0.48, fill_color=DARK_BLUE)
for j, (h, w, x) in enumerate(zip(headers, col_ws, xs)):
    add_text(slide, h, x + 0.05, y_start + 0.04, w, 0.4,
             font_size=12, bold=True, color=WHITE)

for i, (sz, loc, tx, out, col) in enumerate(decisions):
    y = y_start + 0.52 + i * 0.58
    bg = RGBColor(0xF5, 0xF9, 0xFF) if i % 2 == 0 else WHITE
    add_rect(slide, 0.5, y, sum(col_ws) + 0.15*(len(col_ws)-1), 0.55, fill_color=bg,
             line_color=GRAY_LINE, line_width=0.3)
    add_rect(slide, 0.5, y, 0.08, 0.55, fill_color=col)
    vals = [sz, loc, tx, out]
    for j, (v, w, x) in enumerate(zip(vals, col_ws, xs)):
        add_text(slide, v, x + 0.1, y + 0.04, w - 0.1, 0.5,
                 font_size=10.5, color=TEXT_DARK)

footer(slide, page_num="9 / 12")

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 10 – COMPLICATIONS
# ══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
slide_bg(slide)
header_bar(slide, "Complications", "Short-term & Long-term Consequences")

complications = [
    {
        "title": "Acute Complications",
        "color": RGBColor(0xCC, 0x22, 0x22),
        "icon": "⚡",
        "items": [
            "Ureteral Obstruction → Hydronephrosis",
            "Obstructed Infected Kidney (Pyonephrosis) → Urosepsis",
            "Acute Kidney Injury (AKI) from obstruction",
            "Forniceal rupture → urinoma",
            "Severe uncontrolled pain requiring hospitalisation",
        ],
    },
    {
        "title": "Chronic Complications",
        "color": RGBColor(0xE6, 0x74, 0x00),
        "icon": "🔄",
        "items": [
            "Chronic Kidney Disease (CKD)",
            "  • Stone formers at ↑ risk of ESKD",
            "  • Risk ↑ with urologic abnormalities",
            "Recurrent UTIs (especially struvite)",
            "Hypertension (renal scarring)",
            "Renal tubular damage from repeated episodes",
        ],
    },
    {
        "title": "Bone & Metabolic",
        "color": SOFT_GREEN,
        "icon": "🦴",
        "items": [
            "Reduced Bone Mineral Density (BMD)",
            "Vertebral & hip fractures (4x higher incidence)",
            "Osteoporosis (calcium resorption from bone)",
            "Hypercalciuria → negative calcium balance",
            "NHANES III: association of stone history",
            "  with low BMD confirmed",
        ],
    },
    {
        "title": "Neoplastic Association",
        "color": MED_BLUE,
        "icon": "⚠",
        "items": [
            "Chronic irritation → ↑ risk of:",
            "  • Renal pelvis cancer",
            "  • Ureteral cancer",
            "  • Bladder transitional cell carcinoma",
            "Beyond 10 years of stone history",
            "Infection/irritation may be pathogenic",
        ],
    },
]

for i, comp in enumerate(complications):
    col = i % 2
    row = i // 2
    x = 0.4 + col * 6.4
    y = 1.55 + row * 2.55
    add_rect(slide, x, y, 6.1, 2.4, fill_color=WHITE,
             line_color=comp["color"], line_width=1.5)
    add_rect(slide, x, y, 6.1, 0.5, fill_color=comp["color"])
    add_text(slide, comp["icon"] + "  " + comp["title"], x + 0.1, y + 0.04, 5.8, 0.44,
             font_size=14, bold=True, color=WHITE)
    add_multiline_text(slide, ["• " + it for it in comp["items"]],
                       x + 0.15, y + 0.56, 5.8, 1.78,
                       font_size=11, color=TEXT_DARK)

footer(slide, page_num="10 / 12")

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 11 – PREVENTION & DIET
# ══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
slide_bg(slide)
header_bar(slide, "Prevention & Diet", "Reducing Recurrence Risk")

# Left panel – Diet & Lifestyle
add_rect(slide, 0.4, 1.55, 6.0, 5.35, fill_color=WHITE,
         line_color=GRAY_LINE, line_width=1)
add_rect(slide, 0.4, 1.55, 6.0, 0.5, fill_color=SOFT_GREEN)
add_text(slide, "🥗  DIETARY & LIFESTYLE MEASURES", 0.55, 1.58, 5.7, 0.44,
         font_size=14, bold=True, color=WHITE)

diet_items = [
    ("💧 Fluid Intake", "Drink > 2.5 L/day; target urine output > 2 L/day; reduces supersaturation"),
    ("🧂 Reduce Sodium", "↓ Na intake → ↓ urinary calcium excretion; aim < 2.3 g Na/day"),
    ("🥛 Normal Calcium", "Do NOT restrict calcium! Low Ca diet paradoxically ↑ oxalate absorption → more stones"),
    ("🥩 Reduce Animal Protein", "↑ protein → ↑ urinary uric acid & calcium; promotes acidic urine"),
    ("🍋 Citrus Fruits", "Lemon juice/orange juice ↑ urinary citrate → natural stone inhibitor"),
    ("🌿 Low Oxalate Foods", "Avoid spinach, nuts, chocolate, tea (for calcium oxalate stone formers)"),
    ("⚖️ Maintain BMI", "Obesity ↑ stone risk; weight normalisation reduces incidence"),
]
for i, (hd, tx) in enumerate(diet_items):
    y = 2.12 + i * 0.65
    add_text(slide, hd, 0.55, y, 2.1, 0.55, font_size=12, bold=True, color=SOFT_GREEN)
    add_text(slide, tx, 2.65, y, 3.6, 0.55, font_size=11, color=TEXT_DARK)

# Right panel – Medical Prevention
add_rect(slide, 6.8, 1.55, 6.0, 5.35, fill_color=WHITE,
         line_color=GRAY_LINE, line_width=1)
add_rect(slide, 6.8, 1.55, 6.0, 0.5, fill_color=MED_BLUE)
add_text(slide, "💊  PHARMACOLOGICAL PREVENTION", 6.95, 1.58, 5.7, 0.44,
         font_size=14, bold=True, color=WHITE)

pharm_items = [
    ("Thiazide Diuretics", "Hypercalciuria → ↓ urinary Ca, ↓ stone recurrence"),
    ("Potassium Citrate", "↑ urinary citrate; alkalinises urine for uric acid stones;\nfirst-line for hypocitraturia"),
    ("Allopurinol", "Hyperuricosuria → ↓ uric acid production; gout-related stones"),
    ("Tamsulosin (MET)", "Alpha-blocker → relaxes ureteric smooth muscle; aids expulsion of 5-10 mm stones"),
    ("Acetohydroxamic Acid", "Urease inhibitor; adjunct for struvite stones (poorly tolerated)"),
    ("D-Penicillamine /\nTiopronin", "Cystinuria → chelates cystine; reduces cystine supersaturation"),
    ("Pyridoxine (B6)", "Primary hyperoxaluria type 1 → reduces endogenous oxalate production"),
]
for i, (drug, desc) in enumerate(pharm_items):
    y = 2.12 + i * 0.65
    add_rect(slide, 6.85, y - 0.02, 2.2, 0.55, fill_color=RGBColor(0xE8, 0xF0, 0xFF))
    add_text(slide, drug, 6.92, y, 2.1, 0.5, font_size=11.5, bold=True, color=MED_BLUE)
    add_text(slide, desc, 9.1, y, 3.55, 0.55, font_size=11, color=TEXT_DARK)

footer(slide, page_num="11 / 12")

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 12 – SUMMARY & KEY POINTS
# ══════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, fill_color=DARK_BLUE)
add_rect(slide, 0, 0, 13.333, 1.3, fill_color=RGBColor(0x08, 0x1A, 0x38))
add_rect(slide, 0, 1.3, 13.333, 0.07, fill_color=YELLOW_HL)

add_text(slide, "KEY TAKE-HOME POINTS", 0.5, 0.15, 12, 0.85,
         font_size=32, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, "Renal Stone Disease — Summary for Medical Students", 0.5, 0.95, 12, 0.38,
         font_size=15, italic=True, color=YELLOW_HL, align=PP_ALIGN.CENTER)

key_points = [
    ("01", "80% of stones are calcium oxalate/phosphate; urinary supersaturation is the key mechanism of formation."),
    ("02", "Renal colic — severe loin-to-groin pain with haematuria — is the classic presentation; fever suggests infected obstruction → emergency."),
    ("03", "NCCT KUB is the gold standard for diagnosis; ultrasound is preferred in pregnancy and children."),
    ("04", "Stones ≤ 5 mm: conservative + MET (alpha-blockers). Stones 5-20 mm: ESWL or ureteroscopy. Stones > 20 mm: PCNL."),
    ("05", "Uric acid stones are radiolucent but dissolve with urine alkalinisation (potassium citrate); struvite stones require surgical clearance."),
    ("06", "Prevention: > 2.5 L fluid/day, normal calcium intake, low sodium & protein diet, potassium citrate, thiazides for hypercalciuria."),
    ("07", "Complications include CKD, ESKD, bone fractures, recurrent UTI, and long-term risk of urothelial malignancy."),
]

for i, (num, pt) in enumerate(key_points):
    y = 1.52 + i * 0.73
    col = i % 2
    # Alternating accent colours
    bar_col = ACCENT_TEAL if col == 0 else YELLOW_HL
    add_rect(slide, 0.35, y, 0.55, 0.58, fill_color=bar_col)
    add_text(slide, num, 0.35, y + 0.04, 0.55, 0.5,
             font_size=16, bold=True, color=DARK_BLUE, align=PP_ALIGN.CENTER)
    add_text(slide, pt, 1.0, y + 0.04, 11.9, 0.58,
             font_size=13, color=WHITE)

add_rect(slide, 0, 7.1, 13.333, 0.4, fill_color=RGBColor(0x04, 0x0E, 0x20))
add_text(slide,
         "References: Tintinalli's Emergency Medicine  •  Campbell-Walsh Urology  •  Bailey & Love's Surgery  •  Brenner & Rector's Kidney  •  Goldman-Cecil Medicine",
         0.4, 7.13, 12.5, 0.35,
         font_size=9, color=RGBColor(0x88, 0xAA, 0xCC))

# ── SAVE ──────────────────────────────────────────────────────────────────────
out_path = "/tmp/workspace/renal-stone-ppt/Renal_Stone_Disease_Seminar.pptx"
prs.save(out_path)
print(f"Saved: {out_path}")
Running Command

cd /tmp/workspace/renal-stone-ppt && python build_ppt.py 2>&1

Editing File

~/renal-stone-ppt/build_ppt.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/renal-stone-ppt/build_ppt.py'
Running Command

cd /tmp/workspace/renal-stone-ppt && python build_ppt.py 2>&1

Editing File

~/renal-stone-ppt/build_ppt.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/renal-stone-ppt/build_ppt.py'
Running Command

cd /tmp/workspace/renal-stone-ppt && python build_ppt.py 2>&1

Running Command

ls -lh /tmp/workspace/renal-stone-ppt/Renal_Stone_Disease_Seminar.pptx

Your presentation is ready for download:

Renal Stone Disease Seminar

Presentation · PPTX


What's inside — 12 slides, professional design (navy/teal/yellow palette):
SlideContent
1Title Slide — with visual design and textbook references
2Overview / Contents — 8-topic card layout
3Definition & Epidemiology — prevalence trends, recurrence rates, risk factor table
4Pathophysiology — 5-step flow diagram (supersaturation → nucleation → growth → stone → obstruction) + natural inhibitors
5Types of Renal Stones — 4 cards: Calcium (80%), Struvite (10%), Uric Acid (10%), Cystine (1%) with key features
6Clinical Features — renal colic detail, pain localisation by stone position, emergency signs banner
7Investigations — urinalysis, blood tests, imaging (NCCT gold standard, ultrasound, plain KUB)
8Management — 3 columns: conservative + MET, surgical (ESWL/URS/PCNL), stone-specific medical therapy
9Surgical Decision Guide — size/location table (≤5 mm → conservative, 5-10 mm → MET/URS, >20 mm → PCNL)
10Complications — acute obstruction/sepsis, CKD/ESKD, bone fractures, urothelial malignancy
11Prevention & Diet — fluids, sodium/protein reduction, citrus, pharmacological agents (thiazides, potassium citrate, allopurinol)
12Key Take-Home Points — 7 summary points in dark branded style
Content is sourced from Tintinalli's Emergency Medicine, Campbell-Walsh Urology, Bailey & Love's Surgery, and Brenner & Rector's Kidney.

Generate ppt

The presentation on Renal Stone Disease was already generated in our previous session! You can download it right here:

Renal Stone Disease Seminar

Presentation · PPTX

12 slides included:
  1. Title Slide
  2. Overview / Contents
  3. Definition & Epidemiology
  4. Pathophysiology (5-step flow diagram)
  5. Types of Renal Stones (Calcium, Struvite, Uric Acid, Cystine)
  6. Clinical Features & Renal Colic
  7. Investigations (NCCT, Ultrasound, Labs)
  8. Management (Conservative / Surgical / Stone-Specific)
  9. Surgical Decision Guide (stone size vs. treatment)
  10. Complications
  11. Prevention & Diet
  12. Key Take-Home Points
If you meant a different topic, please let me know what you'd like and I'll build it right away!
This is a shared conversation. Sign in to Orris to start your own chat.