Made a simple presentation on thyroid investigations in tabular and flow chart manner at mbbs level
mkdir -p /tmp/workspace/thyroid-pptx && ls /tmp/workspace/thyroid-pptx/
~/thyroid-pptx/create_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.oxml.ns import qn
from pptx.oxml import parse_xml
from lxml import etree
from io import BytesIO
# ---- Color Palette ----
NAVY = RGBColor(0x1A, 0x3A, 0x5C) # deep navy (headers, title)
TEAL = RGBColor(0x00, 0x7B, 0x8A) # teal accent
LIGHT_BLU = RGBColor(0xD9, 0xEF, 0xF5) # light blue (table alt rows)
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
DARK_TXT = RGBColor(0x1C, 0x1C, 0x1C)
ORANGE = RGBColor(0xE8, 0x7A, 0x1A) # highlight / arrows
GREEN = RGBColor(0x27, 0x8B, 0x44)
RED = RGBColor(0xC0, 0x39, 0x2B)
YELLOW_BG = RGBColor(0xFF, 0xF3, 0xCD)
GRAY_BG = RGBColor(0xF4, 0xF6, 0xF9)
HEADER_ROW= RGBColor(0x1A, 0x3A, 0x5C)
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank_layout = prs.slide_layouts[6]
# ===== HELPER FUNCTIONS =====
def add_rect(slide, x, y, w, h, fill_color=None, line_color=None, line_width=Pt(1)):
shape = slide.shapes.add_shape(1, Inches(x), Inches(y), Inches(w), Inches(h))
shape.line.width = line_width
if fill_color:
shape.fill.solid()
shape.fill.fore_color.rgb = fill_color
else:
shape.fill.background()
if line_color:
shape.line.color.rgb = line_color
else:
shape.line.fill.background()
return shape
def add_textbox(slide, x, y, w, h, text, font_size=16, bold=False, color=DARK_TXT,
align=PP_ALIGN.LEFT, italic=False, wrap=True):
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
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
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 tb
def add_labeled_box(slide, x, y, w, h, text, bg_color, text_color=WHITE,
font_size=13, bold=True, align=PP_ALIGN.CENTER, border_color=None):
shape = add_rect(slide, x, y, w, h, fill_color=bg_color,
line_color=border_color if border_color else bg_color)
tf = shape.text_frame
tf.word_wrap = True
tf.vertical_anchor = MSO_ANCHOR.MIDDLE
tf.margin_left = Pt(6)
tf.margin_right = Pt(6)
tf.margin_top = Pt(2)
tf.margin_bottom = Pt(2)
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.color.rgb = text_color
run.font.name = "Calibri"
return shape
def add_arrow_down(slide, cx, y_top, h=0.25, color=NAVY):
"""Draw a downward triangle arrow."""
from pptx.util import Emu
# Use a connector line
line = slide.shapes.add_connector(1,
Inches(cx), Inches(y_top),
Inches(cx), Inches(y_top + h))
line.line.color.rgb = color
line.line.width = Pt(2)
return line
def add_arrow_right(slide, x_start, y_mid, length=0.5, color=NAVY):
line = slide.shapes.add_connector(1,
Inches(x_start), Inches(y_mid),
Inches(x_start + length), Inches(y_mid))
line.line.color.rgb = color
line.line.width = Pt(2)
return line
def add_slide_header(slide, title, subtitle=None):
"""Add a colored header bar with title."""
add_rect(slide, 0, 0, 13.333, 1.0, fill_color=NAVY)
add_textbox(slide, 0.3, 0.1, 12.7, 0.75, title,
font_size=28, bold=True, color=WHITE, align=PP_ALIGN.LEFT)
if subtitle:
add_textbox(slide, 0.3, 0.72, 12.7, 0.3, subtitle,
font_size=13, bold=False, color=RGBColor(0xAA, 0xCC, 0xDD),
align=PP_ALIGN.LEFT)
# Bottom accent line
add_rect(slide, 0, 1.0, 13.333, 0.06, fill_color=TEAL)
def add_footer(slide, page_num, total=8):
add_rect(slide, 0, 7.2, 13.333, 0.3, fill_color=NAVY)
add_textbox(slide, 0.3, 7.22, 9, 0.25,
"Thyroid Investigations | MBBS Level",
font_size=9, color=RGBColor(0xAA, 0xCC, 0xDD))
add_textbox(slide, 11.5, 7.22, 1.7, 0.25,
f"Slide {page_num} / {total}",
font_size=9, color=RGBColor(0xAA, 0xCC, 0xDD), align=PP_ALIGN.RIGHT)
# =====================================================================
# SLIDE 1 – TITLE SLIDE
# =====================================================================
slide1 = prs.slides.add_slide(blank_layout)
# Full bg
add_rect(slide1, 0, 0, 13.333, 7.5, fill_color=NAVY)
# Accent strip
add_rect(slide1, 0, 3.5, 13.333, 0.08, fill_color=TEAL)
# Decorative side bar
add_rect(slide1, 0, 0, 0.4, 7.5, fill_color=TEAL)
add_textbox(slide1, 1.0, 1.4, 11, 1.0,
"THYROID INVESTIGATIONS",
font_size=44, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_textbox(slide1, 1.0, 2.5, 11, 0.6,
"A Comprehensive Guide for MBBS Students",
font_size=20, bold=False, color=RGBColor(0xAA, 0xDD, 0xEE),
align=PP_ALIGN.CENTER)
add_textbox(slide1, 1.0, 3.7, 11, 0.5,
"TSH | Free T4 | Free T3 | Antibodies | Imaging | Uptake Studies",
font_size=14, bold=False, color=RGBColor(0x88, 0xBB, 0xCC),
align=PP_ALIGN.CENTER)
add_textbox(slide1, 1.0, 5.5, 11, 0.4,
"Includes: Tables • Diagnostic Flowcharts • Normal Reference Ranges",
font_size=13, italic=True, color=RGBColor(0x77, 0xAA, 0xBB),
align=PP_ALIGN.CENTER)
add_textbox(slide1, 1.0, 6.3, 11, 0.4,
"Based on: Henry's Clinical Diagnosis | Quick Compendium of Clinical Pathology | Washington Manual",
font_size=11, italic=True, color=RGBColor(0x66, 0x99, 0xAA),
align=PP_ALIGN.CENTER)
# =====================================================================
# SLIDE 2 – OVERVIEW / HPT AXIS
# =====================================================================
slide2 = prs.slides.add_slide(blank_layout)
add_rect(slide2, 0, 0, 13.333, 7.5, fill_color=GRAY_BG)
add_slide_header(slide2, "Hypothalamus-Pituitary-Thyroid (HPT) Axis",
"Basis of all thyroid tests")
add_footer(slide2, 2)
# Axis boxes (left column)
axis_items = [
("HYPOTHALAMUS", "Releases TRH\n(Thyrotropin Releasing Hormone)", RGBColor(0x6A, 0x0D, 0xAD)),
("ANTERIOR PITUITARY", "Releases TSH\n(Thyroid Stimulating Hormone)", TEAL),
("THYROID GLAND", "Releases T3 & T4\n(Active hormones)", NAVY),
]
ay = 1.3
for title, desc, col in axis_items:
add_labeled_box(slide2, 0.5, ay, 3.2, 0.7, title, col, font_size=12)
add_textbox(slide2, 3.85, ay + 0.05, 4.0, 0.6, desc, font_size=12, color=DARK_TXT)
if ay < 3.3:
add_arrow_down(slide2, 2.1, ay + 0.7, 0.3, color=col)
ay += 1.05
# Negative feedback arrow label
add_rect(slide2, 4.5, 1.3, 2.5, 2.5, fill_color=None, line_color=ORANGE, line_width=Pt(1.5))
add_textbox(slide2, 4.6, 1.4, 2.3, 0.35, "Negative Feedback", font_size=11, bold=True,
color=ORANGE, align=PP_ALIGN.CENTER)
add_textbox(slide2, 4.6, 1.7, 2.3, 0.9,
"High T3/T4 \u2192 inhibits TRH & TSH\nLow T3/T4 \u2192 stimulates TRH & TSH",
font_size=11, color=ORANGE)
# Key concept box
add_labeled_box(slide2, 7.3, 1.3, 5.7, 2.0,
"Key Concept for Thyroid Tests",
NAVY, font_size=13)
add_textbox(slide2, 7.4, 1.7, 5.5, 1.5,
"• TSH is the MOST SENSITIVE single test\n"
"• TSH \u2191 = Primary Hypothyroidism\n"
"• TSH \u2193 = Primary Hyperthyroidism\n"
"• Free T4 confirms and quantifies\n"
"• Free T3 used in special situations",
font_size=13, color=DARK_TXT)
# T3/T4 metabolism info
add_labeled_box(slide2, 0.5, 3.8, 5.5, 0.45, "T4 Metabolism", TEAL, font_size=12)
add_textbox(slide2, 0.5, 4.25, 5.5, 1.6,
"T4 (Thyroxine) – prohormone, 4 iodines\n"
"T3 (Triiodothyronine) – active hormone, 3 iodines\n"
"rT3 (Reverse T3) – inactive metabolite\n"
"~99.98% of T4 and ~99.8% of T3 are protein-bound (TBG)\n"
"ONLY FREE fractions are biologically active",
font_size=12, color=DARK_TXT)
add_labeled_box(slide2, 7.3, 3.8, 5.7, 0.45, "TBG – Thyroid Binding Globulin", TEAL, font_size=12)
tbg_data = [
("TBG INCREASED by:", "Pregnancy, OCP/Estrogen, Active hepatitis, Hypothyroidism"),
("TBG DECREASED by:", "Hypoproteinemia, Androgens, Corticosteroids, Nephrotic syndrome"),
]
ty = 4.25
for label, val in tbg_data:
add_textbox(slide2, 7.3, ty, 2.3, 0.55, label, font_size=11, bold=True, color=NAVY)
add_textbox(slide2, 9.6, ty, 3.4, 0.55, val, font_size=11, color=DARK_TXT)
ty += 0.6
# =====================================================================
# SLIDE 3 – TESTS OVERVIEW TABLE
# =====================================================================
slide3 = prs.slides.add_slide(blank_layout)
add_rect(slide3, 0, 0, 13.333, 7.5, fill_color=GRAY_BG)
add_slide_header(slide3, "Thyroid Function Tests – Overview Table",
"All major investigations at a glance")
add_footer(slide3, 3)
headers = ["Test", "What It Measures", "Normal Range", "Clinical Use", "Priority"]
col_widths = [2.0, 2.8, 2.2, 4.6, 1.3]
rows = [
["TSH\n(Thyrotropin)", "Pituitary TSH secretion\n(reflects thyroid status)", "0.4 – 4.0 mIU/L", "FIRST-LINE test; most sensitive\nscreening for all thyroid disorders", "1st"],
["Free T4\n(fT4)", "Unbound (active) T4\n(biologically relevant)", "0.8 – 1.8 ng/dL\n(10–23 pmol/L)", "Confirms hypothyroidism/hyperthyroidism;\ndosing thyroxine therapy", "2nd"],
["Free T3\n(fT3)", "Unbound (active) T3", "2.3 – 4.2 pg/mL\n(3.5–6.5 pmol/L)", "T3 toxicosis; severe hyperthyroid;\npituitary disease", "3rd"],
["Total T4", "Bound + free T4", "5 – 12 μg/dL\n(64–155 nmol/L)", "Affected by TBG changes;\nless preferred than fT4", "Supplementary"],
["Total T3", "Bound + free T3", "80 – 200 ng/dL\n(1.2–3.1 nmol/L)", "T3 toxicosis diagnosis", "Supplementary"],
["Anti-TPO Ab", "Thyroid peroxidase antibodies\n(autoimmune marker)", "< 34 IU/mL", "Hashimoto's thyroiditis;\nAITD diagnosis", "Autoimmune"],
["Anti-Tg Ab", "Thyroglobulin antibodies", "< 115 IU/mL", "Hashimoto's; PTC surveillance\n(interferes with Tg assay)", "Autoimmune"],
["TSI / TRAb", "TSH receptor antibodies\n(stimulating)", "< 1.75 IU/L", "Graves' disease diagnosis;\nneonatal thyrotoxicosis risk", "Autoimmune"],
["Thyroglobulin", "Thyroid tissue marker", "1.5 – 38 ng/mL", "Differentiated thyroid cancer\npost-thyroidectomy surveillance", "Tumour marker"],
["Calcitonin", "C-cell secretion marker", "< 10 pg/mL (F)\n< 18 pg/mL (M)", "Medullary thyroid carcinoma\nscreening / follow-up", "Tumour marker"],
]
# Draw table
start_x = 0.3
start_y = 1.15
row_h = 0.55
header_h = 0.45
# Header row
cx = start_x
for i, h in enumerate(headers):
add_labeled_box(slide3, cx, start_y, col_widths[i], header_h, h,
HEADER_ROW, WHITE, font_size=11, bold=True)
cx += col_widths[i]
row_colors = [LIGHT_BLU, WHITE]
for ri, row in enumerate(rows):
cy = start_y + header_h + ri * row_h
cx = start_x
bg = row_colors[ri % 2]
for ci, cell in enumerate(row):
add_rect(slide3, cx, cy, col_widths[ci], row_h,
fill_color=bg, line_color=RGBColor(0xCC, 0xDD, 0xEE), line_width=Pt(0.5))
fsize = 9 if ci == 3 else 10
add_textbox(slide3, cx + 0.03, cy + 0.04, col_widths[ci] - 0.06, row_h - 0.08,
cell, font_size=fsize, color=DARK_TXT)
cx += col_widths[ci]
# =====================================================================
# SLIDE 4 – TSH/T4/T3 PATTERN TABLE
# =====================================================================
slide4 = prs.slides.add_slide(blank_layout)
add_rect(slide4, 0, 0, 13.333, 7.5, fill_color=GRAY_BG)
add_slide_header(slide4, "TSH + fT4 + fT3 Pattern Recognition Table",
"Interpret thyroid function test combinations")
add_footer(slide4, 4)
# Main pattern table
p_headers = ["Condition", "TSH", "Free T4", "Free T3", "Site of Disease", "Notes"]
p_widths = [2.8, 1.2, 1.2, 1.2, 2.4, 4.3]
p_rows = [
["Euthyroid (Normal)", "Normal\n(0.4–4.0)", "Normal", "Normal", "None", "All values within reference range"],
["Primary Hypothyroidism", "\u2191 HIGH", "\u2193 Low", "\u2193 Low/Normal", "Thyroid gland", "Most common: Hashimoto's, post-RAI, post-surgical"],
["Subclinical Hypothyroidism", "\u2191 HIGH", "Normal", "Normal", "Thyroid gland", "Early; TSH elevated, fT4 still normal; treat if TSH >10 or symptomatic"],
["Primary Hyperthyroidism", "\u2193 LOW\n(<0.1)", "\u2191 High", "\u2191 High", "Thyroid gland", "Graves', toxic MNG, toxic adenoma"],
["T3 Toxicosis", "\u2193 LOW", "Normal", "\u2191 High", "Thyroid gland", "Early Graves'; important – fT4 normal, only fT3 elevated"],
["Subclinical Hyperthyroidism", "\u2193 LOW", "Normal", "Normal", "Thyroid gland", "Suppressed TSH, normal fT4/fT3; risk: AF, osteoporosis"],
["Secondary Hypothyroidism", "\u2193 Low/Normal", "\u2193 Low", "\u2193 Low", "Pituitary", "Pituitary failure; TSH unhelpful; use fT4"],
["Secondary Hyperthyroidism", "\u2191 HIGH", "\u2191 High", "\u2191 High", "Pituitary (adenoma)", "Rare TSH-secreting pituitary adenoma"],
["Euthyroid Sick Syndrome", "Variable", "\u2193 Low", "\u2193 LOW", "Non-thyroidal illness", "Low T3 in any severe illness; adaptive response; do NOT treat"],
["Pregnancy / High TBG", "Normal", "\u2191 Total T4\n(fT4 normal)", "Normal", "Physiological", "Total T4 rises; free T4 normal; TSH may be low in 1st trimester"],
]
px = 0.3
py = 1.15
ph = 0.47
add_labeled_box(slide4, px, py, sum(p_widths), 0.4, None, HEADER_ROW) # spacer
cx = px
for h, w in zip(p_headers, p_widths):
add_labeled_box(slide4, cx, py, w, 0.4, h, HEADER_ROW, WHITE, font_size=11)
cx += w
condition_colors = {
"Euthyroid": GREEN,
"Primary Hypothyroidism": NAVY,
"Subclinical Hypothyroidism": TEAL,
"Primary Hyperthyroidism": RED,
"T3 Toxicosis": RED,
"Subclinical Hyperthyroidism": ORANGE,
"Secondary": RGBColor(0x6A, 0x0D, 0xAD),
"Euthyroid Sick": ORANGE,
"Pregnancy": RGBColor(0x2E, 0x86, 0xAB),
}
row_bgs = [LIGHT_BLU, WHITE]
for ri, row in enumerate(p_rows):
cy = py + 0.4 + ri * ph
cx = px
bg = row_bgs[ri % 2]
for ci, (cell, w) in enumerate(zip(row, p_widths)):
clr = bg
txt_clr = DARK_TXT
if ci == 0:
clr = bg
elif ci in (1, 2, 3): # TSH, fT4, fT3 cells
if "\u2191" in cell:
clr = RGBColor(0xFF, 0xE5, 0xE5)
txt_clr = RED
elif "\u2193" in cell:
clr = RGBColor(0xE5, 0xF0, 0xFF)
txt_clr = NAVY
else:
clr = RGBColor(0xE8, 0xF8, 0xE8)
txt_clr = GREEN
add_rect(slide4, cx, cy, w, ph, fill_color=clr,
line_color=RGBColor(0xCC, 0xDD, 0xEE), line_width=Pt(0.5))
fsize = 9 if ci == 5 else 10
bold = (ci == 0)
add_textbox(slide4, cx + 0.03, cy + 0.03, w - 0.06, ph - 0.06,
cell, font_size=fsize, bold=bold, color=txt_clr)
cx += w
# Color legend
add_textbox(slide4, 0.3, 6.85, 12, 0.3,
"\u2191 = Elevated (red) \u2193 = Decreased (blue) Normal = Green Note: fT4 = free T4 is preferred over total T4",
font_size=10, color=DARK_TXT, italic=True)
# =====================================================================
# SLIDE 5 – DIAGNOSTIC FLOWCHART: Approach to Thyroid Disease
# =====================================================================
slide5 = prs.slides.add_slide(blank_layout)
add_rect(slide5, 0, 0, 13.333, 7.5, fill_color=GRAY_BG)
add_slide_header(slide5, "Diagnostic Flowchart: Step-by-Step Approach",
"Start with TSH → then fT4 → then specific tests")
add_footer(slide5, 5)
# ---- FLOWCHART ----
BOX_W = 2.4
BOX_H = 0.55
# Step 1: Clinical Suspicion
add_labeled_box(slide5, 5.0, 1.15, 3.333, 0.55,
"CLINICAL SUSPICION OF THYROID DISEASE", ORANGE, WHITE, font_size=11)
add_arrow_down(slide5, 6.666, 1.7, 0.2, ORANGE)
# Step 2: TSH
add_labeled_box(slide5, 4.7, 1.9, 3.9, 0.6,
"STEP 1: Measure Serum TSH\n(Most sensitive screening test)", NAVY, WHITE, font_size=11)
add_arrow_down(slide5, 6.666, 2.5, 0.2, NAVY)
# Branch: Low / Normal / High
add_labeled_box(slide5, 0.4, 2.7, 2.8, 0.55, "TSH LOW\n(< 0.4 mIU/L)", RED, WHITE, font_size=11)
add_labeled_box(slide5, 5.2, 2.7, 2.9, 0.55, "TSH NORMAL\n(0.4 – 4.0 mIU/L)", GREEN, WHITE, font_size=11)
add_labeled_box(slide5, 10.0, 2.7, 2.9, 0.55, "TSH HIGH\n(> 4.0 mIU/L)", NAVY, WHITE, font_size=11)
# Arrows from TSH to branches
add_arrow_right(slide5, 4.7, 3.0, -1.5) # left
# right arrow
line = slide5.shapes.add_connector(1, Inches(8.1), Inches(3.0), Inches(10.0), Inches(3.0))
line.line.color.rgb = NAVY
line.line.width = Pt(2)
# Normal branch -> Euthyroid / recheck
add_arrow_down(slide5, 6.65, 3.25, 0.2, GREEN)
add_labeled_box(slide5, 5.0, 3.45, 3.3, 0.65,
"EUTHYROID\nNo thyroid disease\n(monitor if symptoms persist)", GREEN, WHITE, font_size=10)
# LOW TSH branch
add_arrow_down(slide5, 1.8, 3.25, 0.25, RED)
add_labeled_box(slide5, 0.3, 3.5, 3.0, 0.55, "STEP 2: Measure Free T4 + Free T3", TEAL, WHITE, font_size=11)
add_arrow_down(slide5, 1.8, 4.05, 0.2, TEAL)
add_labeled_box(slide5, 0.2, 4.25, 1.5, 0.55, "fT4 \u2191 & fT3 \u2191", RED, WHITE, font_size=11)
add_textbox(slide5, 0.2, 4.85, 1.5, 0.5, "Overt\nHyperthyroidism", font_size=10, color=RED, bold=True)
add_labeled_box(slide5, 1.8, 4.25, 1.6, 0.55, "fT4 Normal\nfT3 \u2191", ORANGE, WHITE, font_size=10)
add_textbox(slide5, 1.82, 4.85, 1.55, 0.5, "T3 Toxicosis\n(early Graves')", font_size=10, color=ORANGE, bold=True)
add_arrow_down(slide5, 1.8, 5.4, 0.25, TEAL)
add_labeled_box(slide5, 0.2, 5.65, 3.1, 0.55,
"STEP 3: TRAb / TSI + Thyroid Scan + RAIU", TEAL, WHITE, font_size=10)
add_textbox(slide5, 0.3, 6.25, 3.0, 0.65,
"Graves' (+ TRAb, diffuse uptake)\nToxic MNG (patchy uptake)\nToxic Adenoma (hot nodule)",
font_size=9, color=DARK_TXT)
# HIGH TSH branch
add_arrow_down(slide5, 11.45, 3.25, 0.25, NAVY)
add_labeled_box(slide5, 9.9, 3.5, 3.0, 0.55, "STEP 2: Measure Free T4", TEAL, WHITE, font_size=11)
add_arrow_down(slide5, 11.45, 4.05, 0.2, TEAL)
add_labeled_box(slide5, 9.8, 4.25, 1.55, 0.55, "fT4 \u2193 Low", NAVY, WHITE, font_size=11)
add_textbox(slide5, 9.82, 4.85, 1.5, 0.5, "Primary\nHypothyroidism", font_size=10, color=NAVY, bold=True)
add_labeled_box(slide5, 11.45, 4.25, 1.55, 0.55, "fT4 Normal", GREEN, WHITE, font_size=11)
add_textbox(slide5, 11.47, 4.85, 1.5, 0.5, "Subclinical\nHypothyroidism", font_size=10, color=GREEN, bold=True)
add_arrow_down(slide5, 11.45, 5.4, 0.25, NAVY)
add_labeled_box(slide5, 9.9, 5.65, 3.1, 0.55,
"STEP 3: Anti-TPO Ab + Anti-Tg Ab", TEAL, WHITE, font_size=10)
add_textbox(slide5, 10.0, 6.25, 3.0, 0.65,
"Anti-TPO + \u2192 Hashimoto's thyroiditis\nCheck TSH yearly if subclinical\nThyroxine if TSH > 10 or symptomatic",
font_size=9, color=DARK_TXT)
# =====================================================================
# SLIDE 6 – ANTIBODY / AUTOIMMUNE TABLE
# =====================================================================
slide6 = prs.slides.add_slide(blank_layout)
add_rect(slide6, 0, 0, 13.333, 7.5, fill_color=GRAY_BG)
add_slide_header(slide6, "Thyroid Antibodies & Autoimmune Tests",
"Key serological markers for autoimmune thyroid disease")
add_footer(slide6, 6)
ab_headers = ["Antibody", "Full Name", "Target", "Normal", "Positive in", "Key Clinical Use"]
ab_widths = [1.8, 2.8, 2.2, 1.5, 2.5, 2.3]
ab_rows = [
["Anti-TPO\n(TPOAb)", "Anti-thyroid peroxidase antibody", "Thyroid peroxidase enzyme", "< 34 IU/mL",
"Hashimoto's (>90%)\nGraves' (60-80%)", "Best single autoimmune marker;\npredicts hypothyroidism risk"],
["Anti-Tg\n(TgAb)", "Anti-thyroglobulin antibody", "Thyroglobulin protein", "< 115 IU/mL",
"Hashimoto's (80%)\nGraves' (50-70%)", "Interferes with Tg tumour marker;\nmeasure alongside Tg"],
["TRAb\n(TSHRAb)", "TSH receptor antibody\n(blocking or stimulating)", "TSH receptor on thyroid cells", "< 1.75 IU/L",
"Graves' disease (95%+)\nNeonatal thyrotoxicosis", "Confirms Graves';\nmonitor during anti-thyroid therapy"],
["TSI", "Thyroid stimulating immunoglobulin", "TSH receptor\n(stimulating type only)", "< 140%\n(% of baseline)",
"Graves' disease (specific)", "More specific than TRAb;\npredicts neonatal disease"],
["Thyroglobulin\n(Tg)", "Tumour marker (not antibody)", "Thyroid follicular cells", "1.5–38 ng/mL\n(varies by lab)",
"After total thyroidectomy\nfor DTC (should be undetectable)", "Surveillance for papillary/\nfollicular thyroid cancer recurrence"],
["Calcitonin", "C-cell hormone (not antibody)", "Parafollicular C-cells", "< 10 pg/mL (F)\n< 18 pg/mL (M)",
"Medullary thyroid carcinoma\n(MTC); MEN2", "Screening in thyroid nodules;\nMTC diagnosis & follow-up"],
]
ax2 = 0.3; ay2 = 1.15; ah = 0.77
cx = ax2
for h, w in zip(ab_headers, ab_widths):
add_labeled_box(slide6, cx, ay2, w, 0.4, h, HEADER_ROW, WHITE, font_size=11)
cx += w
for ri, row in enumerate(ab_rows):
cy = ay2 + 0.4 + ri * ah
cx = ax2
bg = [LIGHT_BLU, WHITE][ri % 2]
for ci, (cell, w) in enumerate(zip(row, ab_widths)):
add_rect(slide6, cx, cy, w, ah, fill_color=bg,
line_color=RGBColor(0xCC, 0xDD, 0xEE), line_width=Pt(0.5))
fs = 9 if ci in (5, 4) else 10
bold = (ci == 0)
add_textbox(slide6, cx + 0.04, cy + 0.04, w - 0.08, ah - 0.08,
cell, font_size=fs, bold=bold, color=DARK_TXT)
cx += w
# =====================================================================
# SLIDE 7 – IMAGING & SPECIAL INVESTIGATIONS TABLE
# =====================================================================
slide7 = prs.slides.add_slide(blank_layout)
add_rect(slide7, 0, 0, 13.333, 7.5, fill_color=GRAY_BG)
add_slide_header(slide7, "Imaging & Special Thyroid Investigations",
"Ultrasound, RAIU, Scan, FNAC, and more")
add_footer(slide7, 7)
im_headers = ["Investigation", "Principle", "What It Shows", "Main Indications", "Notes / Limitations"]
im_widths = [2.2, 2.2, 2.8, 3.0, 2.8]
im_rows = [
["Thyroid Ultrasound\n(USG)", "High-frequency sound waves",
"Size, nodules, echotexture,\nvascularization (Doppler)",
"Nodule characterization\nGoitre evaluation\nGuide FNAC",
"First-line imaging; no radiation;\nTIRADS scoring for malignancy risk"],
["Radioactive Iodine Uptake\n(RAIU / RAIU-24h)", "131I or 123I uptake\nmeasured at 2h & 24h",
"Thyroid iodine uptake\n(% of administered dose)",
"Hyperthyroidism workup\nGraves' vs. thyroiditis\nvs. toxic nodule",
"Normal: 5-25% at 24h\nHigh in Graves', toxic nodule\nLow in thyroiditis, exogenous T4"],
["Thyroid Scintigraphy\n(Tc-99m or I-123 Scan)", "Gamma camera imaging\nafter isotope injection",
"Nodule function:\nHot (hyperfunctioning)\nWarm / Cold nodule",
"Solitary thyroid nodule\nEctopic thyroid\nPost-thyroidectomy remnant",
"Cold nodule: 15-20% malignant risk;\nrequires FNAC\nHot nodule: rarely malignant"],
["FNAC / FNA Biopsy\n(Thyroid)", "Fine needle aspiration\ncytology",
"Cell morphology;\nBethesda classification\n(I–VI)",
"All clinically/USG suspicious\nnodules > 1 cm",
"Bethesda III-VI warrants\nsurgical referral;\ngold standard for nodule Dx"],
["CT / MRI Thyroid", "X-ray (CT) or\nMRI imaging",
"Extent, retrosternal\ngoitre, tracheal compression,\nLN involvement",
"Large/substernal goitre\nSurgical planning\nMalignancy staging",
"CT: risk of iodinated contrast\ndelaying RAI therapy\nMRI preferred pre-RAI"],
["PET Scan\n(FDG-PET/CT)", "Fluorodeoxyglucose\nuptake",
"Metabolically active\nmetastases",
"Radioiodine-negative\nrecurrent/metastatic DTC",
"Used when RAI scan negative\nbut Tg rising;\nnot routine"],
]
ix = 0.3; iy = 1.15; irh = 0.88
cx = ix
for h, w in zip(im_headers, im_widths):
add_labeled_box(slide7, cx, iy, w, 0.4, h, HEADER_ROW, WHITE, font_size=11)
cx += w
for ri, row in enumerate(im_rows):
cy = iy + 0.4 + ri * irh
cx = ix
bg = [LIGHT_BLU, WHITE][ri % 2]
for ci, (cell, w) in enumerate(zip(row, im_widths)):
add_rect(slide7, cx, cy, w, irh, fill_color=bg,
line_color=RGBColor(0xCC, 0xDD, 0xEE), line_width=Pt(0.5))
fs = 9 if ci in (2, 3, 4) else 10
bold = (ci == 0)
add_textbox(slide7, cx + 0.04, cy + 0.04, w - 0.08, irh - 0.08,
cell, font_size=fs, bold=bold, color=DARK_TXT)
cx += w
# =====================================================================
# SLIDE 8 – SUMMARY / QUICK REFERENCE
# =====================================================================
slide8 = prs.slides.add_slide(blank_layout)
add_rect(slide8, 0, 0, 13.333, 7.5, fill_color=GRAY_BG)
add_slide_header(slide8, "Quick Summary & Clinical Pearls",
"Remember these for MBBS exams and clinical practice")
add_footer(slide8, 8)
# Left column: Quick Reference Flowchart
add_labeled_box(slide8, 0.3, 1.15, 6.0, 0.4, "QUICK DIAGNOSTIC SUMMARY", NAVY, WHITE, font_size=13)
quick_items = [
(ORANGE, "1. TSH ALONE is sufficient for initial screening."),
(NAVY, "2. TSH \u2191 + fT4 \u2193 = Primary Hypothyroidism (treat with Levothyroxine)"),
(NAVY, "3. TSH \u2191 + fT4 Normal = Subclinical Hypothyroidism (monitor TSH 6-monthly)"),
(RED, "4. TSH \u2193 + fT4 \u2191 + fT3 \u2191 = Overt Hyperthyroidism (carbimazole/RAI/surgery)"),
(RED, "5. TSH \u2193 + fT4 Normal + fT3 \u2191 = T3 Toxicosis (Graves' - early)"),
(RED, "6. TSH \u2193 + fT4 Normal + fT3 Normal = Subclinical Hyperthyroidism"),
(RGBColor(0x6A, 0x0D, 0xAD), "7. TSH \u2193 + fT4 \u2193 = Secondary Hypothyroidism (pituitary disease)"),
(TEAL, "8. Anti-TPO Ab+ = Hashimoto's | TRAb+ = Graves' disease"),
(ORANGE, "9. Cold nodule on scan + suspicious FNAC = Refer surgery"),
(GREEN, "10. Post-thyroidectomy: monitor Thyroglobulin for cancer recurrence"),
]
qy = 1.6
for col, txt in quick_items:
add_labeled_box(slide8, 0.3, qy, 0.3, 0.36, "\u25cf", col, WHITE, font_size=14)
add_textbox(slide8, 0.7, qy + 0.02, 5.5, 0.36, txt, font_size=11, color=DARK_TXT)
qy += 0.41
# Right column: Drugs affecting TFT
add_labeled_box(slide8, 6.8, 1.15, 6.2, 0.4, "DRUGS AFFECTING THYROID FUNCTION TESTS", TEAL, WHITE, font_size=12)
drug_rows = [
["Drug / Substance", "Effect on Tests"],
["Amiodarone, Radiocontrast", "Can cause hypo- OR hyperthyroidism (iodine overload)"],
["Lithium", "Blocks thyroid hormone release \u2192 Hypothyroidism"],
["Glucocorticoids, Dopamine", "Suppress TSH secretion \u2192 Falsely low TSH"],
["Estrogen / OCP / Pregnancy", "Increase TBG \u2192 Raise total T4 (free T4 normal)"],
["Androgens, Nephrotic syn.", "Decrease TBG \u2192 Lower total T4 (free T4 normal)"],
["Phenytoin, Carbamazepine", "Increase T4 metabolism \u2192 Lower total T4"],
["Furosemide (high dose)", "Displaces T4 from TBG \u2192 Lower total T4"],
["Aspirin / Salicylates", "Displaces T4 from TBG \u2192 Lower total T4"],
]
dy = 1.6
for ri, (drug, effect) in enumerate(drug_rows):
bg = HEADER_ROW if ri == 0 else [LIGHT_BLU, WHITE][ri % 2]
tc = WHITE if ri == 0 else DARK_TXT
bold = (ri == 0)
add_rect(slide8, 6.8, dy, 2.8, 0.38, fill_color=bg,
line_color=RGBColor(0xCC, 0xDD, 0xEE), line_width=Pt(0.5))
add_textbox(slide8, 6.85, dy + 0.03, 2.7, 0.32, drug, font_size=10, bold=bold, color=tc)
add_rect(slide8, 9.6, dy, 3.4, 0.38, fill_color=bg,
line_color=RGBColor(0xCC, 0xDD, 0xEE), line_width=Pt(0.5))
add_textbox(slide8, 9.65, dy + 0.03, 3.3, 0.32, effect, font_size=10, bold=bold, color=tc)
dy += 0.38
# Memory tip box
add_labeled_box(slide8, 6.8, 5.2, 6.2, 0.4, "MEMORY TIPS", ORANGE, WHITE, font_size=12)
tips = [
"\"TSH is the BOSS\" - always start with TSH",
"\"Free is Better\" - free T4 > total T4 (not affected by TBG changes)",
"\"High TSH = Hypo, Low TSH = Hyper\" (for PRIMARY disease)",
"\"Cold nodule = Worried\" - needs FNAC to rule out malignancy",
"\"TRAb = Graves' proof\" - highly specific",
]
ty2 = 5.65
for tip in tips:
add_textbox(slide8, 7.0, ty2, 5.9, 0.36, f"\u2022 {tip}", font_size=10, color=DARK_TXT)
ty2 += 0.3
# Save
out_path = "/tmp/workspace/thyroid-pptx/Thyroid_Investigations_MBBS.pptx"
buf = BytesIO()
prs.save(buf)
with open(out_path, "wb") as f:
f.write(buf.getvalue())
print(f"Saved: {out_path}")
cd /tmp/workspace/thyroid-pptx && python create_pptx.py 2>&1
~/thyroid-pptx/create_pptx.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/thyroid-pptx/create_pptx.py'
cd /tmp/workspace/thyroid-pptx && python create_pptx.py 2>&1
ls -lh /tmp/workspace/thyroid-pptx/Thyroid_Investigations_MBBS.pptx
Thyroid Investigations MBBS
Presentation · PPTX
| Slide | Content |
|---|---|
| 1 - Title | Professional cover with all major test categories listed |
| 2 - HPT Axis | Hypothalamus-Pituitary-Thyroid axis diagram + TBG concepts |
| 3 - Tests Overview Table | All 10 tests (TSH, fT4, fT3, Anti-TPO, TRAb, Tg, Calcitonin, etc.) with normal ranges, clinical use and priority |
| 4 - Pattern Recognition Table | TSH + fT4 + fT3 combinations for 10 conditions (color coded: red = high, blue = low, green = normal) |
| 5 - Diagnostic Flowchart | Step-by-step approach: start with TSH → branch low/normal/high → specific second-line tests |
| 6 - Antibody Table | All 6 antibody/marker tests with targets, normals, and clinical use |
| 7 - Imaging & Special Tests | USG, RAIU, Scintigraphy, FNAC, CT/MRI, PET scan |
| 8 - Quick Summary | 10 clinical pearls + drugs affecting TFTs + memory tips |