Hi make a ppt presentation on this pdf I have to present it before the reasearch head in my department.ppt should be simple explanatory and have around 40-50 slides .don't deviate from topic
Have you finished
python3 << 'EOF' import pdfplumber pdf_path = "/tmp/workspace/attachments/91764f46-a821-4866-b7db-84900d745cd3/Precocious_Puberty_Thesis_Final (12).pdf" with pdfplumber.open(pdf_path) as pdf: print(f"Total pages: {len(pdf.pages)}") # Extract first 20 pages to understand structure for i, page in enumerate(pdf.pages[:20]): text = page.extract_text() if text: print(f"\n===== PAGE {i+1} =====") print(text[:2000]) EOF
python3 << 'EOF' import pdfplumber pdf_path = "/tmp/workspace/attachments/91764f46-a821-4866-b7db-84900d745cd3/Precocious_Puberty_Thesis_Final (12).pdf" with pdfplumber.open(pdf_path) as pdf: for i, page in enumerate(pdf.pages[20:], start=21): text = page.extract_text() if text: print(f"\n===== PAGE {i} =====") print(text[:2500]) EOF
Finished?
mkdir -p /tmp/workspace/precocious-puberty-ppt && ls /tmp/workspace/precocious-puberty-ppt/
~/precocious-puberty-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
from io import BytesIO
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]
# Color palette
DARK_BLUE = RGBColor(0x1A, 0x3A, 0x6C) # header bg
TEAL = RGBColor(0x00, 0x87, 0x8A) # accent bar
LIGHT_TEAL = RGBColor(0xE0, 0xF4, 0xF5) # body bg
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
DARK_TEXT = RGBColor(0x1E, 0x1E, 0x2E)
ORANGE = RGBColor(0xE8, 0x72, 0x22)
GREY_BG = RGBColor(0xF4, 0xF6, 0xF9)
MID_BLUE = RGBColor(0x2E, 0x6D, 0xA4)
LIGHT_GREY = RGBColor(0xD0, 0xD8, 0xE8)
def add_rect(slide, l, t, w, h, color, transparency=0):
shape = slide.shapes.add_shape(1, Inches(l), Inches(t), Inches(w), Inches(h))
shape.fill.solid()
shape.fill.fore_color.rgb = color
shape.line.fill.background()
return shape
def add_text(slide, text, l, t, w, h, size=18, bold=False, color=DARK_TEXT,
align=PP_ALIGN.LEFT, italic=False, wrap=True):
tb = slide.shapes.add_textbox(Inches(l), Inches(t), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = wrap
p = tf.paragraphs[0]
p.alignment = align
run = p.add_run()
run.text = text
run.font.size = Pt(size)
run.font.bold = bold
run.font.italic = italic
run.font.color.rgb = color
return tb
def add_multiline(slide, lines, l, t, w, h, size=16, color=DARK_TEXT, bold_first=False, bullet=False):
tb = slide.shapes.add_textbox(Inches(l), Inches(t), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = True
for i, line in enumerate(lines):
if i == 0:
p = tf.paragraphs[0]
else:
p = tf.add_paragraph()
p.space_before = Pt(2)
prefix = "• " if bullet else ""
run = p.add_run()
run.text = prefix + line
run.font.size = Pt(size)
run.font.color.rgb = color
if bold_first and i == 0:
run.font.bold = True
return tb
def slide_header(slide, title, subtitle=None):
# Top dark bar
add_rect(slide, 0, 0, 13.333, 1.35, DARK_BLUE)
# Teal accent line
add_rect(slide, 0, 1.35, 13.333, 0.07, TEAL)
# Grey body background
add_rect(slide, 0, 1.42, 13.333, 6.08, GREY_BG)
# Title text
add_text(slide, title, 0.4, 0.08, 12.5, 0.9, size=30, bold=True,
color=WHITE, align=PP_ALIGN.LEFT)
if subtitle:
add_text(slide, subtitle, 0.4, 0.95, 12.5, 0.38, size=14,
color=LIGHT_TEAL, align=PP_ALIGN.LEFT, italic=True)
def section_divider(slide, section_num, section_title, description=""):
add_rect(slide, 0, 0, 13.333, 7.5, DARK_BLUE)
add_rect(slide, 0, 3.0, 13.333, 0.1, TEAL)
add_text(slide, f"SECTION {section_num}", 1, 1.8, 11, 0.7, size=18,
bold=True, color=TEAL, align=PP_ALIGN.CENTER)
add_text(slide, section_title, 1, 2.5, 11, 1.2, size=40,
bold=True, color=WHITE, align=PP_ALIGN.CENTER)
if description:
add_text(slide, description, 1.5, 4.0, 10, 0.8, size=18,
color=LIGHT_TEAL, align=PP_ALIGN.CENTER, italic=True)
def info_box(slide, title, content_lines, l, t, w, h,
header_color=MID_BLUE, body_color=WHITE, text_size=15):
add_rect(slide, l, t, w, 0.45, header_color)
add_rect(slide, l, t+0.45, w, h-0.45, body_color)
add_text(slide, title, l+0.1, t+0.05, w-0.2, 0.38,
size=14, bold=True, color=WHITE)
add_multiline(slide, content_lines, l+0.15, t+0.52, w-0.25, h-0.6,
size=text_size, bullet=True, color=DARK_TEXT)
# ─────────────────────────────────────────────
# SLIDE 1 – TITLE SLIDE
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, DARK_BLUE)
add_rect(slide, 0, 4.5, 13.333, 0.08, TEAL)
add_rect(slide, 0, 4.58, 13.333, 2.92, RGBColor(0x10, 0x28, 0x50))
add_text(slide, "PREVALENCE OF PRECOCIOUS PUBERTY", 0.6, 1.1, 12, 1.0,
size=36, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, "AMONG SCHOOL GIRLS", 0.6, 2.0, 12, 0.8,
size=32, bold=True, color=TEAL, align=PP_ALIGN.CENTER)
add_text(slide,
"A Cross-Sectional Study in Manjeri and Anakkayam, Malappuram District, Kerala, India",
0.8, 2.9, 11.5, 0.6, size=17, color=LIGHT_TEAL, align=PP_ALIGN.CENTER, italic=True)
add_rect(slide, 2.5, 3.7, 8.333, 0.05, TEAL)
add_text(slide, "Department of Community Medicine", 0.6, 4.7, 12, 0.45,
size=16, color=WHITE, align=PP_ALIGN.CENTER, bold=True)
add_text(slide, "Government Medical College Manjeri | Academic Year 2025–2026",
0.6, 5.15, 12, 0.4, size=14, color=LIGHT_TEAL, align=PP_ALIGN.CENTER)
add_text(slide, "IEC Ref. No.: IEC/GMCM/204/2026 | IRC Approval No.: IRC/GMCM/313",
0.6, 5.6, 12, 0.4, size=13, color=LIGHT_TEAL, align=PP_ALIGN.CENTER)
add_text(slide, "Principal Investigator: Sariga M G | Guides: Dr. Sabitha Rose Jacob & Dr. Remiza Rayikkal Answar",
0.6, 6.1, 12, 0.4, size=12, color=LIGHT_GREY, align=PP_ALIGN.CENTER)
# ─────────────────────────────────────────────
# SLIDE 2 – OUTLINE
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Presentation Outline")
sections = [
"01 Introduction & Background",
"02 Problem Statement & Objectives",
"03 Review of Literature",
"04 Methods & Materials",
"05 Results – Sample Characteristics",
"06 Results – Prevalence & Risk Factors",
"07 Results – Statistical Analysis",
"08 Discussion",
"09 Conclusion & Recommendations",
"10 Limitations & Future Research",
]
for i, s in enumerate(sections):
col = 0 if i < 5 else 6.8
row = 1.6 + (i % 5) * 0.9
add_rect(slide, col+0.3, row, 5.8, 0.72, WHITE)
add_rect(slide, col+0.3, row, 0.18, 0.72, TEAL)
add_text(slide, s, col+0.6, row+0.12, 5.3, 0.5, size=15, color=DARK_TEXT, bold=(i % 5 == 0))
# ─────────────────────────────────────────────
# SLIDE 3 – SECTION DIVIDER: INTRODUCTION
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
section_divider(slide, "01", "Introduction & Background",
"Understanding Precocious Puberty in Context")
# ─────────────────────────────────────────────
# SLIDE 4 – WHAT IS PUBERTY?
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "What is Normal Puberty?")
add_text(slide, "Normal pubertal sequence in girls:", 0.5, 1.6, 12, 0.45,
size=18, bold=True, color=DARK_BLUE)
stages = [
("Thelarche", "Breast development — earliest sign of puberty"),
("Pubarche", "Pubic hair appearance"),
("Adrenarche","Axillary (underarm) hair development"),
("Menarche", "First menstrual period"),
]
for i, (s, d) in enumerate(stages):
x = 0.5 + i * 3.2
add_rect(slide, x, 2.2, 2.9, 2.2, MID_BLUE)
add_text(slide, s, x+0.1, 2.25, 2.7, 0.5, size=17, bold=True, color=WHITE)
add_text(slide, d, x+0.1, 2.8, 2.7, 1.4, size=14, color=LIGHT_TEAL, wrap=True)
add_text(slide, str(i+1), x+1.1, 4.25, 0.7, 0.5, size=22, bold=True,
color=TEAL, align=PP_ALIGN.CENTER)
add_rect(slide, 0.5, 4.8, 12.3, 0.05, TEAL)
add_text(slide,
"Normal onset: Ages 8–13 years in girls | Typical completion within 2–5 years",
0.5, 4.9, 12, 0.5, size=16, color=DARK_BLUE, bold=True)
# ─────────────────────────────────────────────
# SLIDE 5 – DEFINITION OF PRECOCIOUS PUBERTY
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Defining Precocious Puberty (PP)")
add_rect(slide, 0.5, 1.6, 12.3, 1.2, DARK_BLUE)
add_text(slide,
"Precocious Puberty: Development of secondary sexual characteristics BEFORE age 8 in girls"
" (before age 9 in boys)",
0.7, 1.7, 11.9, 1.0, size=19, bold=True, color=WHITE, wrap=True)
types = [
("Central PP (CPP)",
"Premature activation of the\nhypothalamic-pituitary-gonadal\n(HPG) axis\n\nMost cases in girls are IDIOPATHIC"),
("Peripheral PP",
"Sex hormone secretion\nINDEPENDENT of gonadotropins\n\nCaused by ovarian cysts,\ntumours, or exogenous estrogens"),
("Gonadotropin-dependent",
"LH/FSH-driven\n\nResponds to GnRH analogue\ntreatment (GnRHa)"),
]
for i, (t, d) in enumerate(types):
x = 0.5 + i * 4.2
add_rect(slide, x, 3.0, 3.9, 3.5, WHITE)
add_rect(slide, x, 3.0, 3.9, 0.5, TEAL)
add_text(slide, t, x+0.1, 3.05, 3.7, 0.42, size=15, bold=True, color=WHITE)
add_text(slide, d, x+0.15, 3.6, 3.65, 2.8, size=14, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 6 – PROBLEM STATEMENT
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Problem Statement")
bullets = [
"Secular trend toward earlier pubertal onset documented globally over recent decades",
"Rising prevalence of PP in India linked to rapid urbanisation, nutrition transition & environmental exposures",
"Public health consequences: shortened childhood, psychosocial stress, early sexual activity risks",
"Long-term sequelae: hormone-sensitive cancers, metabolic syndrome, cardiovascular disease",
"Kerala: high female literacy, above-average nutrition, diverse urban-rural gradient — ideal study setting",
"District-level data from Malappuram remain SCARCE — this study addresses that evidence gap",
]
for i, b in enumerate(bullets):
add_rect(slide, 0.5, 1.6 + i*0.82, 0.35, 0.55, TEAL)
add_text(slide, b, 1.0, 1.6 + i*0.82, 11.8, 0.72, size=16, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 7 – OBJECTIVES
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Study Objectives")
add_rect(slide, 0.4, 1.6, 12.5, 0.6, MID_BLUE)
add_text(slide, "PRIMARY OBJECTIVE", 0.5, 1.65, 12, 0.5, size=16, bold=True, color=WHITE)
add_text(slide,
"To estimate the prevalence of precocious puberty among school girls aged 10–15 years"
" in Manjeri and Anakkayam, Malappuram District, Kerala",
0.5, 2.25, 12.3, 0.7, size=16, color=DARK_BLUE, bold=True, wrap=True)
add_text(slide, "SECONDARY OBJECTIVES", 0.5, 3.05, 12, 0.4, size=15, bold=True, color=TEAL)
sec_obj = [
"Identify socio-demographic risk factors (age, residence, family type, parental education, income)",
"Examine association of dietary patterns, screen time, physical activity & pesticide exposure with PP",
"Assess the role of BMI and family history in precocious puberty",
"Describe and compare age at menarche and puberty indicators between PP and non-PP groups",
]
for i, o in enumerate(sec_obj):
add_rect(slide, 0.5, 3.5 + i*0.72, 0.12, 0.5, ORANGE)
add_text(slide, o, 0.75, 3.5 + i*0.72, 12, 0.65, size=15, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 8 – SECTION DIVIDER: LITERATURE REVIEW
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
section_divider(slide, "02", "Review of Literature",
"Global & Indian Evidence on Precocious Puberty")
# ─────────────────────────────────────────────
# SLIDE 9 – GLOBAL EPIDEMIOLOGY
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Global Epidemiology of PP", subtitle="Prevalence & Secular Trends")
stats = [
("0.2% – >10%", "Global PP prevalence\nrange across studies"),
("10:1", "Girls:Boys ratio\nfor CPP"),
("0.5–1 yr", "Earlier breast onset in\nUS girls since 1960s"),
("50–80%", "Heritability of\npubertal timing"),
]
for i, (val, lab) in enumerate(stats):
x = 0.5 + i * 3.2
add_rect(slide, x, 1.6, 3.0, 1.9, DARK_BLUE)
add_text(slide, val, x+0.1, 1.7, 2.8, 0.9, size=26, bold=True,
color=TEAL, align=PP_ALIGN.CENTER)
add_text(slide, lab, x+0.1, 2.55, 2.8, 0.85, size=13,
color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, "Key Literature Findings:", 0.5, 3.7, 12, 0.4, size=16, bold=True, color=DARK_BLUE)
lit = [
"Wang et al. (2025) – Meta-analysis: elevated BMI, maternal menarche age & breastfeeding duration are significant PP risk factors",
"Cheuiche et al. (2021) – CPP far more common in girls; MKRN3 & DLK1 gene mutations identified in familial cases",
"Kentistou et al. (2024) – Multiple genetic loci including KISS1R identified as key regulators of puberty onset",
"Dinkelbach et al. (2025) – CPP significantly associated with psychiatric disorders (depression, ADHD)",
]
for i, l in enumerate(lit):
add_rect(slide, 0.5, 4.15 + i*0.71, 0.12, 0.5, ORANGE)
add_text(slide, l, 0.75, 4.15 + i*0.71, 12, 0.65, size=13, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 10 – PP IN INDIA
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Precocious Puberty in India", subtitle="Regional Context & Kerala Data")
info_box(slide, "Indian Prevalence Data",
["Urban centres (Delhi, Mumbai, Kolkata): PP prevalence 5–12% in schoolgirls",
"Urban areas consistently show higher rates than rural counterparts",
"Binu et al. (Kerala/Kollam): PP prevalence 10.4% — closest comparable study",
"Girls in school settings particularly vulnerable"],
0.4, 1.6, 6.0, 3.0)
info_box(slide, "Kerala Epidemiological Context",
["High female literacy & healthcare access",
"Above-average nutrition indices",
"Rapid urbanisation in districts like Malappuram",
"Significant pesticide use in agricultural peri-urban areas",
"District-level Malappuram data: SCARCE before this study"],
6.8, 1.6, 6.1, 3.0)
add_rect(slide, 0.4, 4.8, 12.5, 1.6, WHITE)
add_rect(slide, 0.4, 4.8, 0.15, 1.6, ORANGE)
add_text(slide, "Why This Study Matters",
0.7, 4.85, 12, 0.4, size=15, bold=True, color=DARK_BLUE)
add_text(slide,
"Malappuram district represents a rapidly urbanising area with significant agricultural activity,"
" creating a unique dual-exposure milieu for EDCs and nutritional shifts."
" This study provides the first systematic district-level prevalence data.",
0.7, 5.25, 12, 1.0, size=14, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 11 – BMI & ADIPOSITY (LIT REVIEW)
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "BMI, Obesity & PP – Evidence Base")
add_rect(slide, 0.4, 1.6, 12.5, 1.0, DARK_BLUE)
add_text(slide,
"Mechanistic Pathway: Adipose tissue → Leptin → Hypothalamic GnRH pulsatility → Premature HPG axis activation",
0.6, 1.7, 12, 0.8, size=16, bold=True, color=WHITE, wrap=True)
evidence = [
("Shi et al.\n(2022)", "Childhood obesity & CPP:\nBody fat %, especially\nvisceral adiposity —\nstronger predictor than\nBMI alone"),
("Gonc & Kandemir\n(2022)", "Body composition in PP:\nElevated leptin lowers\nthreshold for HPG axis\nactivation in overweight\nchildren"),
("Oliveira et al.\n(2026)", "Bidirectional relationship:\nObesity accelerates puberty\nAND PP promotes fat\naccumulation — creating\na reinforcing cycle"),
("Wang et al.\n(2025)", "Systematic review:\nBMI identified as one of\nthe major independent\nrisk factors for PP\nacross populations"),
]
for i, (ref, text) in enumerate(evidence):
x = 0.4 + i * 3.2
add_rect(slide, x, 2.75, 3.0, 3.8, WHITE)
add_rect(slide, x, 2.75, 3.0, 0.55, MID_BLUE)
add_text(slide, ref, x+0.1, 2.8, 2.8, 0.45, size=13, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, text, x+0.1, 3.35, 2.8, 3.1, size=13, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 12 – ENDOCRINE DISRUPTORS (LIT REVIEW)
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Environmental Endocrine Disruptors (EDCs) & PP")
add_text(slide, "What are EDCs?", 0.4, 1.6, 12, 0.4, size=17, bold=True, color=DARK_BLUE)
add_text(slide,
"Exogenous chemicals that interfere with the endocrine system — implicated in earlier pubertal onset",
0.4, 2.0, 12.5, 0.5, size=15, color=DARK_TEXT, wrap=True)
edcs = [
("Phthalates", "Plastic packaging,\npersonal care products"),
("Bisphenol A\n(BPA)", "Food containers,\nbottle linings"),
("PCBs", "Industrial chemicals,\nold electrical equipment"),
("Organochlorine\nPesticides", "Agricultural use,\nperi-urban exposure"),
]
for i, (name, source) in enumerate(edcs):
x = 0.4 + i * 3.2
add_rect(slide, x, 2.65, 3.0, 1.8, TEAL)
add_text(slide, name, x+0.1, 2.7, 2.8, 0.65, size=15, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, source, x+0.1, 3.3, 2.8, 1.0, size=13, color=LIGHT_TEAL, align=PP_ALIGN.CENTER)
bullets2 = [
"Lopez-Rodriguez et al. (2021): EDCs disrupt GnRH neuronal network during sensitive developmental windows",
"Calcaterra et al. (2024): Dietary phthalate & BPA exposure through food packaging correlates with early pubertal onset",
"Symeonides et al. (2024): Umbrella review confirms EDC-endocrine outcome associations across meta-analyses",
"In this study: 14.1% of participants had pesticide/chemical exposure — monitored but non-significant (p=1.000)",
]
for i, b in enumerate(bullets2):
add_rect(slide, 0.4, 4.6 + i*0.65, 0.12, 0.5, ORANGE)
add_text(slide, b, 0.65, 4.6 + i*0.65, 12.3, 0.6, size=13, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 13 – PSYCHOSOCIAL CONSEQUENCES
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Psychosocial & Long-Term Health Consequences of PP")
short_term = [
"Body image concerns and anxiety",
"Early sexual activity risks",
"Psychosocial stress and peer difficulties",
"Inadequate preparation due to poor sex education",
"Depression and attention issues (ADHD)",
]
long_term = [
"Increased risk of breast and ovarian cancer",
"Type 2 diabetes and metabolic syndrome",
"Polycystic ovarian syndrome (PCOS)",
"Osteoporosis",
"Cardiovascular disease",
]
info_box(slide, "Short-Term Consequences", short_term, 0.4, 1.6, 6.0, 4.5, header_color=ORANGE)
info_box(slide, "Long-Term Health Consequences", long_term, 6.8, 1.6, 6.1, 4.5, header_color=DARK_BLUE)
add_text(slide,
"Source: Soliman et al. 2023 (Acta Biomed) | Dinkelbach et al. 2025 (JAMA Network Open)",
0.4, 6.3, 12.5, 0.4, size=12, color=MID_BLUE, italic=True)
# ─────────────────────────────────────────────
# SLIDE 14 – SECTION DIVIDER: METHODS
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
section_divider(slide, "03", "Methods & Materials",
"Study Design, Setting, Population & Tools")
# ─────────────────────────────────────────────
# SLIDE 15 – STUDY DESIGN & SETTING
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Study Design & Setting")
add_rect(slide, 0.4, 1.6, 12.5, 0.65, DARK_BLUE)
add_text(slide, "STUDY DESIGN: School-based Cross-Sectional Study",
0.6, 1.67, 12, 0.52, size=17, bold=True, color=WHITE)
info_box(slide, "Study Sites (3 Schools)",
["Benchmark International School, Manjeri (URBAN)",
"Government HSS (Girls), Manjeri (URBAN)",
"Government HSS, Irumbuzhi, Anakkayam (SEMI-URBAN/RURAL)"],
0.4, 2.4, 6.0, 2.5, header_color=MID_BLUE)
info_box(slide, "Geographic Context",
["Malappuram District, Kerala, India",
"Manjeri: rapidly urbanising town",
"Anakkayam: semi-urban with significant\nagricultural activity & pesticide use",
"Urban-semi-urban comparison design"],
6.8, 2.4, 6.1, 2.5, header_color=MID_BLUE)
add_text(slide, "Why Cross-Sectional?", 0.4, 5.05, 12, 0.38, size=15, bold=True, color=DARK_BLUE)
add_text(slide,
"Appropriate for prevalence estimation at a single time point | Resource-efficient for large N | "
"No longitudinal follow-up required | Suitable for identifying associations",
0.4, 5.42, 12.5, 0.7, size=14, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 16 – STUDY POPULATION & SAMPLING
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Study Population & Sampling Strategy")
add_rect(slide, 0.4, 1.6, 5.8, 2.4, WHITE)
add_rect(slide, 0.4, 1.6, 5.8, 0.48, MID_BLUE)
add_text(slide, "Inclusion Criteria", 0.55, 1.63, 5.5, 0.42, size=14, bold=True, color=WHITE)
add_multiline(slide,
["Female students aged 10–15 years",
"Enrolled in Standards 6–9 in selected schools",
"Parent/guardian written informed consent",
"Student verbal assent obtained"],
0.55, 2.15, 5.6, 1.7, size=14, bullet=True)
add_rect(slide, 7.0, 1.6, 5.9, 2.4, WHITE)
add_rect(slide, 7.0, 1.6, 5.9, 0.48, ORANGE)
add_text(slide, "Exclusion Criteria", 7.15, 1.63, 5.6, 0.42, size=14, bold=True, color=WHITE)
add_multiline(slide,
["Girls whose parents refused consent",
"Girls who themselves declined assent",
"No categorical exclusions — full spectrum captured",
"Even girls with chronic illness included"],
7.15, 2.15, 5.65, 1.7, size=14, bullet=True)
add_rect(slide, 0.4, 4.1, 12.5, 2.8, WHITE)
add_rect(slide, 0.4, 4.1, 12.5, 0.48, DARK_BLUE)
add_text(slide, "Multi-Stage Random Sampling", 0.6, 4.13, 12, 0.42, size=15, bold=True, color=WHITE)
sampling_steps = [
"STAGE 1\nPurposive school selection representing\nurban & semi-urban strata",
"STAGE 2\nSystematic random sampling from\nclass rolls within each school",
"ADJUSTMENT\nSampling fraction adjusted proportionally\nto school enrolment size",
"FINAL N\n427 girls with complete data\nacross all 3 schools",
]
for i, s in enumerate(sampling_steps):
x = 0.6 + i * 3.1
add_rect(slide, x, 4.65, 2.8, 2.1, GREY_BG)
add_rect(slide, x, 4.65, 2.8, 0.08, TEAL)
add_text(slide, s, x+0.1, 4.72, 2.6, 2.0, size=13, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 17 – SAMPLE SIZE CALCULATION
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Sample Size Calculation")
add_rect(slide, 2.5, 1.65, 8.333, 1.4, DARK_BLUE)
add_text(slide, "Formula: n = Z²α/2 × P(1−P) / d²",
2.5, 1.72, 8.333, 0.65, size=22, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
params = [
("Z (95% CI)", "1.96"),
("Expected P", "10%\n(0.10)"),
("Precision (d)", "3%\n(0.03)"),
("Base n", "≈ 384"),
("10% non-response", "+38"),
("Final N", "≈ 427"),
]
for i, (lbl, val) in enumerate(params):
x = 0.5 + i * 2.1
add_rect(slide, x, 3.3, 1.9, 1.7, WHITE)
add_rect(slide, x, 3.3, 1.9, 0.55, MID_BLUE if i < 4 else TEAL)
add_text(slide, lbl, x+0.05, 3.32, 1.8, 0.5, size=13, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, val, x+0.05, 3.88, 1.8, 0.9, size=18, bold=True, color=DARK_BLUE, align=PP_ALIGN.CENTER)
add_rect(slide, 0.5, 5.2, 12.3, 0.08, TEAL)
add_text(slide, "All 427 enrolled participants had complete primary outcome data — 100% completion rate",
0.5, 5.35, 12.3, 0.5, size=16, bold=True, color=DARK_BLUE, align=PP_ALIGN.CENTER)
# ─────────────────────────────────────────────
# SLIDE 18 – DATA COLLECTION TOOLS
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Data Collection Tools")
tools = [
("Parent/Guardian\nQuestionnaire",
"Socio-demographics\nMedical & family history\nDietary patterns\nScreen time & lifestyle\nPesticide exposure\nAge at menarche\nDoctor confirmation of PP"),
("Student\nQuestionnaire",
"Self-reported physical changes\nOutdoor activity & screen time\nMenstrual history\nDiet & lifestyle\nFamily history\nAdministered with teacher assistance"),
("Healthcare Professional\nData Sheet",
"Height (cm)\nWeight (kg)\nBMI = kg/m²\nMeasured by trained personnel\nStandardised protocol"),
]
for i, (title, content) in enumerate(tools):
x = 0.4 + i * 4.3
add_rect(slide, x, 1.6, 4.0, 4.8, WHITE)
add_rect(slide, x, 1.6, 4.0, 0.72, [DARK_BLUE, TEAL, ORANGE][i])
add_text(slide, title, x+0.1, 1.65, 3.8, 0.65, size=15, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_multiline(slide, content.split("\n"), x+0.15, 2.4, 3.7, 3.8, size=14, bullet=True)
add_text(slide,
"All questionnaires pre-tested in a pilot of 20 girls | Administered in Malayalam (local language) with English alongside",
0.4, 6.55, 12.5, 0.5, size=13, color=MID_BLUE, italic=True)
# ─────────────────────────────────────────────
# SLIDE 19 – OPERATIONAL DEFINITIONS
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Operational Definitions")
defs = [
("Precocious Puberty (Primary Outcome)",
"Questionnaire-assessed onset of secondary sexual characteristics (breast development, pubic hair, axillary hair, menarche) before age 8, reported by parent AND confirmed by a registered medical practitioner"),
("Early Menarche",
"First menstrual period occurring before age 12 years"),
("Overweight/Obese",
"BMI ≥ 25 kg/m² per WHO growth reference for age"),
("Urban Residence",
"Residing within Manjeri municipal limits (Schools 1 & 2)"),
("Semi-Urban Residence",
"Residing in Irumbuzhi panchayat area (School 3)"),
("Family History of Early Puberty",
"Mother or sister experiencing puberty/menarche before age 10"),
]
for i, (term, defn) in enumerate(defs):
y = 1.6 + i * 0.9
add_rect(slide, 0.4, y, 3.5, 0.75, MID_BLUE)
add_text(slide, term, 0.5, y+0.05, 3.3, 0.65, size=13, bold=True, color=WHITE, wrap=True)
add_rect(slide, 3.9, y, 9.0, 0.75, WHITE)
add_text(slide, defn, 4.0, y+0.07, 8.8, 0.65, size=13, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 20 – ETHICAL CONSIDERATIONS
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Ethical Considerations")
ethics = [
("IEC Approval", "IEC/GMCM/204/2026 — Institutional Ethics Committee, GMC Manjeri"),
("IRC Approval", "IRC/GMCM/313 — Institutional Research Committee approval"),
("Informed Consent", "Written informed consent from all parents/guardians before data collection"),
("Student Assent", "Verbal assent obtained from all participating girls"),
("Confidentiality", "Unique participant IDs assigned; datasets anonymised; stored on password-protected devices"),
("Voluntary Participation", "Right to withdraw at any time without consequence — no coercion"),
("ICMR Compliance", "All forms compliant with ICMR Ethical Guidelines for Biomedical Research (2017) & NMC UG guidelines"),
]
for i, (head, body) in enumerate(ethics):
y = 1.6 + i * 0.72
add_rect(slide, 0.4, y, 2.8, 0.6, DARK_BLUE)
add_text(slide, head, 0.5, y+0.07, 2.65, 0.5, size=13, bold=True, color=WHITE)
add_text(slide, body, 3.35, y+0.07, 9.7, 0.55, size=14, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 21 – SECTION DIVIDER: RESULTS
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
section_divider(slide, "04", "Results", "Sample Characteristics & Prevalence")
# ─────────────────────────────────────────────
# SLIDE 22 – SAMPLE CHARACTERISTICS: OVERVIEW
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Sample Characteristics – Overview (N=427)")
metrics = [
("427", "Total\nParticipants"),
("13.01 ± 1.35\nyears", "Mean Age"),
("50.1% / 49.9%", "Urban /\nSemi-urban"),
("65.1%", "Nuclear\nFamily"),
("10–15 yrs", "Age\nRange"),
]
for i, (val, lbl) in enumerate(metrics):
x = 0.5 + i * 2.55
add_rect(slide, x, 1.6, 2.3, 1.8, DARK_BLUE)
add_text(slide, val, x+0.1, 1.68, 2.1, 0.95, size=19, bold=True,
color=TEAL, align=PP_ALIGN.CENTER)
add_text(slide, lbl, x+0.1, 2.6, 2.1, 0.7, size=13,
color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, "Age Distribution by Year:", 0.5, 3.6, 12, 0.4, size=15, bold=True, color=DARK_BLUE)
age_data = [("10 yrs", "36 (8.4%)"), ("11 yrs", "76 (17.8%)"), ("12 yrs", "88 (20.6%)"),
("13 yrs", "88 (20.6%)"), ("14 yrs", "102 (23.9%)"), ("15 yrs", "37 (8.7%)")]
for i, (age, n) in enumerate(age_data):
x = 0.5 + i * 2.1
add_rect(slide, x, 4.05, 1.9, 1.2, WHITE)
add_rect(slide, x, 4.05, 1.9, 0.4, MID_BLUE)
add_text(slide, age, x+0.05, 4.07, 1.8, 0.37, size=13, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, n, x+0.05, 4.47, 1.8, 0.65, size=14, color=DARK_TEXT, align=PP_ALIGN.CENTER)
add_text(slide,
"Standard 9: 49.4% | Standard 8: 32.6% | Standard 7: 10.5% | Standard 6: 7.5%",
0.5, 5.4, 12.5, 0.5, size=14, color=DARK_BLUE, bold=True)
# ─────────────────────────────────────────────
# SLIDE 23 – SOCIO-DEMOGRAPHIC TABLE
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Socio-Demographic Profile – Table 1 (N=427)")
# Draw table
rows = [
("Father's Education", "Illiterate 4.2% | Primary 16.4% | Secondary 33.3% | Graduate 31.1% | PG 15.0%"),
("Mother's Education", "Illiterate 3.5% | Primary 13.8% | Secondary 31.6% | Graduate 34.7% | PG 16.4%"),
("Monthly Income", "< ₹10K: 10.5% | ₹10K–30K: 29.3% | ₹30K–50K: 39.8% | > ₹50K: 20.4%"),
("Residence", "Urban: 214 (50.1%) | Semi-urban: 213 (49.9%)"),
("Family Type", "Nuclear: 278 (65.1%) | Joint: 149 (34.9%)"),
]
add_rect(slide, 0.4, 1.6, 3.5, 0.5, DARK_BLUE)
add_rect(slide, 3.9, 1.6, 9.0, 0.5, DARK_BLUE)
add_text(slide, "Variable", 0.5, 1.63, 3.3, 0.4, size=14, bold=True, color=WHITE)
add_text(slide, "Distribution", 4.0, 1.63, 8.8, 0.4, size=14, bold=True, color=WHITE)
for i, (var, dist) in enumerate(rows):
bg = WHITE if i % 2 == 0 else GREY_BG
y = 2.15 + i * 0.75
add_rect(slide, 0.4, y, 3.5, 0.7, bg)
add_rect(slide, 3.9, y, 9.0, 0.7, bg)
add_text(slide, var, 0.5, y+0.07, 3.3, 0.58, size=13, bold=True, color=DARK_BLUE)
add_text(slide, dist, 4.0, y+0.07, 8.8, 0.58, size=13, color=DARK_TEXT)
add_text(slide,
"Most participants came from families with secondary/graduate education and middle-income households (₹30K–50K: 39.8%)",
0.4, 5.95, 12.5, 0.55, size=14, color=MID_BLUE, italic=True, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 24 – MEDICAL & FAMILY HISTORY
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Medical & Family History Profile")
items = [
("Chronic Illness", "43 girls (10.1%)", ORANGE),
("Family History of Early Puberty", "79 girls (18.5%)", MID_BLUE),
("Pesticide/Chemical Exposure", "60 girls (14.1%)", TEAL),
("Doctor Confirmed PP", "39 girls (9.1%)", DARK_BLUE),
]
for i, (lbl, val, col) in enumerate(items):
x = 0.5 + (i % 2) * 6.4
y = 1.7 + (i // 2) * 2.2
add_rect(slide, x, y, 5.9, 1.9, WHITE)
add_rect(slide, x, y, 5.9, 0.12, col)
add_text(slide, lbl, x+0.2, y+0.2, 5.5, 0.6, size=15, bold=True, color=DARK_BLUE)
add_text(slide, val, x+0.2, y+0.8, 5.5, 0.8, size=26, bold=True, color=col, align=PP_ALIGN.CENTER)
add_rect(slide, 0.5, 6.1, 12.3, 0.08, TEAL)
add_text(slide,
"Family history of early puberty present in 18.5% of total participants — a critical screening marker",
0.5, 6.25, 12.3, 0.5, size=14, color=DARK_BLUE, align=PP_ALIGN.CENTER)
# ─────────────────────────────────────────────
# SLIDE 25 – DIETARY & LIFESTYLE PROFILE
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Dietary & Lifestyle Characteristics – Table 7")
diet_items = [
("Home-cooked meals (primary diet)", "340 (79.6%)", "Yes"),
("Fast food > 3×/week", "197 (46.1%)", "High"),
("Processed food consumption", "220 (51.5%)", "High"),
("High protein diet", "216 (50.6%)", "Moderate"),
("Traditional Kerala diet", "277 (64.9%)", "Yes"),
("Screen time > 2h/day (parent report)", "252 (59.0%)", "High"),
("Pesticide/chemical exposure", "60 (14.1%)", "Low"),
]
add_rect(slide, 0.4, 1.6, 7.0, 0.5, DARK_BLUE)
add_rect(slide, 7.4, 1.6, 2.5, 0.5, DARK_BLUE)
add_rect(slide, 9.9, 1.6, 3.0, 0.5, DARK_BLUE)
add_text(slide, "Variable", 0.5, 1.63, 6.8, 0.4, size=14, bold=True, color=WHITE)
add_text(slide, "n (%)", 7.5, 1.63, 2.3, 0.4, size=14, bold=True, color=WHITE)
add_text(slide, "Concern Level", 10.0, 1.63, 2.8, 0.4, size=14, bold=True, color=WHITE)
for i, (var, n, level) in enumerate(diet_items):
bg = WHITE if i % 2 == 0 else GREY_BG
y = 2.15 + i * 0.62
add_rect(slide, 0.4, y, 7.0, 0.58, bg)
add_rect(slide, 7.4, y, 2.5, 0.58, bg)
add_rect(slide, 9.9, y, 3.0, 0.58, bg)
add_text(slide, var, 0.5, y+0.07, 6.8, 0.5, size=13, color=DARK_TEXT)
add_text(slide, n, 7.5, y+0.07, 2.3, 0.5, size=13, bold=True, color=DARK_BLUE)
lcolor = ORANGE if level == "High" else (TEAL if level == "Yes" else MID_BLUE)
add_text(slide, level, 10.0, y+0.07, 2.8, 0.5, size=13, bold=True, color=lcolor)
add_text(slide,
"Mean outdoor hours/day: 1.54 ± 0.82 (Range: 0–5)",
0.5, 6.5, 12, 0.4, size=14, bold=True, color=DARK_BLUE)
# ─────────────────────────────────────────────
# SLIDE 26 – MAIN PREVALENCE FINDING
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Prevalence of Precocious Puberty – Key Finding")
add_rect(slide, 2.5, 1.7, 8.333, 2.5, DARK_BLUE)
add_text(slide, "9.1%", 2.5, 1.8, 8.333, 1.5, size=80, bold=True,
color=TEAL, align=PP_ALIGN.CENTER)
add_text(slide, "Overall PP Prevalence (n=39/427)",
2.5, 3.1, 8.333, 0.65, size=20, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, "95% Confidence Interval: 6.5% – 12.3%",
2.5, 3.72, 8.333, 0.48, size=16, color=LIGHT_TEAL, align=PP_ALIGN.CENTER)
sub = [
("Urban (n=214)", "24 cases", "11.2%", "95% CI: 7.4–16.4%"),
("Semi-urban (n=213)", "15 cases", "7.0%", "95% CI: 4.1–11.5%"),
]
for i, (grp, n, pct, ci) in enumerate(sub):
x = 1.0 + i * 5.8
add_rect(slide, x, 4.4, 5.0, 2.0, WHITE)
add_rect(slide, x, 4.4, 5.0, 0.45, MID_BLUE)
add_text(slide, grp, x+0.1, 4.43, 4.8, 0.4, size=14, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, pct, x+0.1, 4.9, 4.8, 0.8, size=32, bold=True, color=DARK_BLUE, align=PP_ALIGN.CENTER)
add_text(slide, n + " | " + ci, x+0.1, 5.72, 4.8, 0.5, size=13, color=DARK_TEXT, align=PP_ALIGN.CENTER)
add_text(slide, "Urban vs Semi-urban difference NOT statistically significant (χ²=1.765; p=0.184)",
0.5, 6.55, 12.3, 0.45, size=14, italic=True, color=ORANGE, align=PP_ALIGN.CENTER)
# ─────────────────────────────────────────────
# SLIDE 27 – PREVALENCE TABLE
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Prevalence by Residence – Table 3")
headers = ["Category", "Total (N)", "PP Cases (n)", "Prevalence (%)", "95% CI"]
rows_t = [
["Overall", "427", "39", "9.1%", "6.5 – 12.3"],
["Urban", "214", "24", "11.2%", "7.4 – 16.4"],
["Semi-urban", "213", "15", "7.0%", "4.1 – 11.5"],
]
col_widths = [3.0, 2.2, 2.4, 2.5, 2.9]
col_starts = [0.5]
for w in col_widths[:-1]:
col_starts.append(col_starts[-1] + w + 0.05)
# header row
for j, (h, cw, cx) in enumerate(zip(headers, col_widths, col_starts)):
add_rect(slide, cx, 2.0, cw, 0.55, DARK_BLUE)
add_text(slide, h, cx+0.07, 2.04, cw-0.1, 0.47, size=14, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
for i, row in enumerate(rows_t):
bg = GREY_BG if i % 2 == 0 else WHITE
row_color = TEAL if i == 0 else bg
for j, (val, cw, cx) in enumerate(zip(row, col_widths, col_starts)):
add_rect(slide, cx, 2.6 + i*0.75, cw, 0.7, row_color)
fc = WHITE if i == 0 else DARK_TEXT
add_text(slide, val, cx+0.07, 2.65 + i*0.75, cw-0.1, 0.58,
size=16, bold=(i == 0), color=fc, align=PP_ALIGN.CENTER)
add_text(slide,
"Wilson score method used for 95% CI computation\n"
"PP = Precocious Puberty | Pearson Chi-square (2-tailed) for residence comparison",
0.5, 5.0, 12.3, 0.7, size=13, color=MID_BLUE, italic=True)
add_rect(slide, 0.5, 5.8, 12.3, 1.0, WHITE)
add_rect(slide, 0.5, 5.8, 0.15, 1.0, ORANGE)
add_text(slide,
"\"Nearly 1 in 10 school girls in Malappuram has questionnaire-assessed PP — "
"consistent with Kerala studies (Binu et al., 10.4%) and Indian urban range (5–12%)\"",
0.8, 5.88, 11.8, 0.85, size=15, color=DARK_BLUE, italic=True, bold=True, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 28 – SECTION DIVIDER: BIVARIATE ANALYSIS
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
section_divider(slide, "05", "Bivariate Analysis", "Risk Factor Associations with PP")
# ─────────────────────────────────────────────
# SLIDE 29 – FAMILY HISTORY
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Family History of Early Puberty – Strongest Categorical Risk Factor")
add_rect(slide, 0.5, 1.6, 12.3, 0.72, DARK_BLUE)
add_text(slide, "Chi-square: X² = 12.845 (df=1) | p < 0.001 *** | HIGHLY SIGNIFICANT",
0.7, 1.68, 11.9, 0.55, size=17, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
# PP+ family history group
add_rect(slide, 0.5, 2.5, 5.9, 3.5, WHITE)
add_rect(slide, 0.5, 2.5, 5.9, 0.5, ORANGE)
add_text(slide, "POSITIVE Family History (n=79)", 0.6, 2.53, 5.7, 0.45, size=14, bold=True, color=WHITE)
add_text(slide, "20.3%", 0.6, 3.1, 5.7, 1.2, size=52, bold=True, color=ORANGE, align=PP_ALIGN.CENTER)
add_text(slide, "had PP", 0.6, 4.25, 5.7, 0.5, size=18, color=DARK_BLUE, align=PP_ALIGN.CENTER)
add_text(slide, "(16 out of 79 girls)", 0.6, 4.75, 5.7, 0.45, size=14, color=DARK_TEXT, align=PP_ALIGN.CENTER, italic=True)
# PP- family history group
add_rect(slide, 7.0, 2.5, 5.9, 3.5, WHITE)
add_rect(slide, 7.0, 2.5, 5.9, 0.5, MID_BLUE)
add_text(slide, "NEGATIVE Family History (n=348)", 7.1, 2.53, 5.7, 0.45, size=14, bold=True, color=WHITE)
add_text(slide, "6.6%", 7.1, 3.1, 5.7, 1.2, size=52, bold=True, color=MID_BLUE, align=PP_ALIGN.CENTER)
add_text(slide, "had PP", 7.1, 4.25, 5.7, 0.5, size=18, color=DARK_BLUE, align=PP_ALIGN.CENTER)
add_text(slide, "(23 out of 348 girls)", 7.1, 4.75, 5.7, 0.45, size=14, color=DARK_TEXT, align=PP_ALIGN.CENTER, italic=True)
add_rect(slide, 0.5, 6.15, 12.3, 0.85, LIGHT_TEAL)
add_text(slide,
"Girls with positive family history are ~3× more likely to have PP | Adjusted OR = 3.31 (p=0.002)\n"
"Genetic basis: MKRN3, DLK1, KISS1R mutations | Heritability of pubertal timing: 50–80%",
0.7, 6.2, 11.9, 0.75, size=14, color=DARK_BLUE, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 30 – BMI AS RISK FACTOR
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "BMI – Strongest Continuous Risk Factor")
add_rect(slide, 0.5, 1.6, 12.3, 0.65, DARK_BLUE)
add_text(slide, "t-test: t = 5.670 | p < 0.001 *** (Independent samples, 2-tailed)",
0.7, 1.67, 11.9, 0.5, size=16, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
# BMI comparison boxes
for i, (grp, bmi, sd, n) in enumerate([
("PP Group", "21.24", "±3.33", "(n=39)"),
("Non-PP Group", "18.89", "±2.35", "(n=388)"),
]):
x = 0.8 + i * 6.1
col = ORANGE if i == 0 else MID_BLUE
add_rect(slide, x, 2.4, 5.5, 2.8, WHITE)
add_rect(slide, x, 2.4, 5.5, 0.55, col)
add_text(slide, grp, x+0.1, 2.44, 5.3, 0.48, size=16, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, bmi + " kg/m²", x+0.1, 3.0, 5.3, 1.0, size=32, bold=True, color=col, align=PP_ALIGN.CENTER)
add_text(slide, "Mean BMI " + sd, x+0.1, 3.97, 5.3, 0.5, size=15, color=DARK_TEXT, align=PP_ALIGN.CENTER)
add_text(slide, n, x+0.1, 4.48, 5.3, 0.45, size=14, color=DARK_TEXT, align=PP_ALIGN.CENTER, italic=True)
add_text(slide, "BMI Classification & PP:", 0.5, 5.4, 12, 0.4, size=15, bold=True, color=DARK_BLUE)
bmi_class = [
("Underweight\n(BMI < 18.5)", "187 girls", "10 PP cases", "5.3% PP rate"),
("Normal\n(18.5–24.9)", "233 girls", "24 PP cases", "10.3% PP rate"),
("Overweight/Obese\n(≥25.0)", "7 girls", "5 PP cases", "71.4% PP rate"),
]
for i, (cls, n, pp, rate) in enumerate(bmi_class):
x = 0.5 + i * 4.2
add_rect(slide, x, 5.85, 3.9, 1.4, WHITE)
add_rect(slide, x, 5.85, 3.9, 0.12, [MID_BLUE, TEAL, ORANGE][i])
add_text(slide, cls, x+0.1, 5.88, 3.7, 0.6, size=12, bold=True, color=DARK_BLUE, wrap=True)
add_text(slide, n + " | " + rate, x+0.1, 6.5, 3.7, 0.55, size=13, color=[MID_BLUE, TEAL, ORANGE][i], bold=True)
add_text(slide, "χ² = 26.08; p < 0.001", 11.5, 6.95, 1.8, 0.4, size=12, color=DARK_TEXT, italic=True)
# ─────────────────────────────────────────────
# SLIDE 31 – AGE AT MENARCHE
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Age at Menarche – Critical Discriminator")
add_rect(slide, 0.5, 1.6, 12.3, 0.65, DARK_BLUE)
add_text(slide, "t = -13.067 | p < 0.001 *** — Largest effect size in the study",
0.7, 1.67, 11.9, 0.5, size=16, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
for i, (grp, age, sd, col) in enumerate([
("PP Group", "10.00", "±0.63 years", ORANGE),
("Non-PP Group", "12.39", "±1.12 years", MID_BLUE),
]):
x = 0.8 + i * 6.1
add_rect(slide, x, 2.4, 5.5, 2.7, WHITE)
add_rect(slide, x, 2.4, 5.5, 0.55, col)
add_text(slide, grp, x+0.1, 2.44, 5.3, 0.48, size=16, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, age + " yrs", x+0.1, 3.0, 5.3, 0.95, size=34, bold=True, color=col, align=PP_ALIGN.CENTER)
add_text(slide, "Mean age at menarche " + sd, x+0.1, 3.95, 5.3, 0.5, size=14, color=DARK_TEXT, align=PP_ALIGN.CENTER)
add_text(slide, "Mean age difference: 2.39 years earlier in PP group",
0.5, 5.25, 12.3, 0.5, size=18, bold=True, color=DARK_BLUE, align=PP_ALIGN.CENTER)
add_multiline(slide, [
"Early menarche defined as first period before age 12 years",
"66.6% of menstruating girls in the sample had early menarche (age < 12 years)",
"Student-reported mean age at first period: 11.72 ± 0.86 years",
"Correlation between age at puberty signs & age at menarche: r = 0.482 (p=0.003) — biologically coherent",
], 0.5, 5.85, 12.3, 1.5, size=14, bullet=True, color=DARK_TEXT)
# ─────────────────────────────────────────────
# SLIDE 32 – FULL CHI-SQUARE TABLE
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Bivariate Analysis – Table 4: All Categorical Risk Factors (N=427)")
headers = ["Risk Factor", "PP Cases", "No PP", "χ² (df)", "p-value", "Result"]
col_w = [3.5, 1.8, 1.8, 2.0, 1.7, 2.1]
col_x = [0.3]
for w in col_w[:-1]:
col_x.append(col_x[-1] + w + 0.05)
for j, (h, cw, cx) in enumerate(zip(headers, col_w, col_x)):
add_rect(slide, cx, 1.6, cw, 0.5, DARK_BLUE)
add_text(slide, h, cx+0.05, 1.62, cw-0.08, 0.45, size=12, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
table_rows = [
("Family Hx Early Puberty", "20.3% (n=79+)", "6.6% (n=348-)", "12.845 (1)", "< 0.001", "***"),
("Residence (Urban vs Semi-urban)", "11.2% Urban", "7.0% Semi-urban", "1.765 (1)", "0.184", "NS"),
("Overweight BMI (≥25)", "71.4%", "~9%", "26.08 (2)", "< 0.001", "***"),
("Screen Time > 2h/day", "8.7% Yes", "9.7% No", "0.031 (1)", "0.860", "NS"),
("Fast Food > 3×/week", "10.2% Yes", "8.3% No", "0.258 (1)", "0.611", "NS"),
("Pesticide Exposure", "8.3% Yes", "9.3% No", "0.000 (1)", "1.000", "NS"),
("Nuclear vs Joint Family", "N/A", "N/A", "1.12 (1)", "0.290", "NS"),
]
sig_colors = {"***": ORANGE, "NS": DARK_TEXT}
for i, row in enumerate(table_rows):
bg = WHITE if i % 2 == 0 else GREY_BG
y = 2.15 + i * 0.63
for j, (val, cw, cx) in enumerate(zip(row, col_w, col_x)):
add_rect(slide, cx, y, cw, 0.6, bg)
fc = sig_colors.get(val, DARK_TEXT) if j == 5 else DARK_TEXT
bld = (j == 5 and val == "***") or (j == 0)
add_text(slide, val, cx+0.05, y+0.06, cw-0.08, 0.5,
size=12, bold=bld, color=fc, align=PP_ALIGN.CENTER, wrap=True)
add_text(slide, "*** p < 0.001 = Significant | NS = Not Significant (p > 0.05)",
0.3, 6.6, 12.5, 0.4, size=12, color=MID_BLUE, italic=True)
# ─────────────────────────────────────────────
# SLIDE 33 – T-TEST TABLE
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Continuous Variables – Independent Samples T-Test (Table 5)")
t_headers = ["Variable", "PP Group (n=39)\nMean ± SD", "No-PP Group (n=388)\nMean ± SD", "t-statistic", "p-value", "Result"]
t_col_w = [2.8, 2.8, 2.8, 1.8, 1.6, 1.6]
t_col_x = [0.3]
for w in t_col_w[:-1]:
t_col_x.append(t_col_x[-1] + w + 0.05)
for j, (h, cw, cx) in enumerate(zip(t_headers, t_col_w, t_col_x)):
add_rect(slide, cx, 1.6, cw, 0.65, DARK_BLUE)
add_text(slide, h, cx+0.05, 1.62, cw-0.08, 0.6, size=11, bold=True, color=WHITE, align=PP_ALIGN.CENTER, wrap=True)
t_rows = [
("Age (years)", "13.28 ± 1.45", "12.98 ± 1.33", "1.316", "0.189", "NS"),
("Age at Menarche (years)", "10.00 ± 0.63", "12.39 ± 1.12", "−13.067", "< 0.001", "***"),
("BMI (kg/m²)", "21.24 ± 3.33", "18.89 ± 2.35", "5.670", "< 0.001", "***"),
("Height (cm)", "147.8 ± 8.1", "145.1 ± 7.1", "1.980", "0.048", "*"),
("Hours Outdoors/Day", "1.65 ± 0.80", "1.52 ± 0.82", "0.946", "0.345", "NS"),
]
sig_col = {"***": ORANGE, "*": MID_BLUE, "NS": DARK_TEXT}
for i, row in enumerate(t_rows):
bg = WHITE if i % 2 == 0 else GREY_BG
y = 2.3 + i * 0.78
for j, (val, cw, cx) in enumerate(zip(row, t_col_w, t_col_x)):
add_rect(slide, cx, y, cw, 0.74, bg)
fc = sig_col.get(val, DARK_TEXT) if j == 5 else DARK_TEXT
bld = j in [0, 5]
add_text(slide, val, cx+0.05, y+0.08, cw-0.08, 0.6,
size=13, bold=bld, color=fc, align=PP_ALIGN.CENTER)
add_text(slide, "*** p<0.001 | * p<0.05 | NS = Not Significant | Independent samples t-test, 2-tailed",
0.3, 6.58, 12.5, 0.42, size=12, color=MID_BLUE, italic=True)
# ─────────────────────────────────────────────
# SLIDE 34 – ANTHROPOMETRIC PROFILE
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Anthropometric Profile – Table 8")
metrics2 = [
("Mean Height", "145.3 ± 7.2 cm", "Range: 125–168 cm"),
("Mean Weight", "40.5 ± 7.0 kg", "Range: 26–62 kg"),
("Mean BMI", "19.11 ± 2.55 kg/m²", "Range: 13.0–28.4 kg/m²"),
]
for i, (lbl, val, rng) in enumerate(metrics2):
x = 0.5 + i * 4.2
add_rect(slide, x, 1.6, 3.9, 2.3, WHITE)
add_rect(slide, x, 1.6, 3.9, 0.5, DARK_BLUE)
add_text(slide, lbl, x+0.1, 1.63, 3.7, 0.44, size=14, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, val, x+0.1, 2.18, 3.7, 0.85, size=17, bold=True, color=DARK_BLUE, align=PP_ALIGN.CENTER)
add_text(slide, rng, x+0.1, 3.02, 3.7, 0.5, size=13, color=MID_BLUE, align=PP_ALIGN.CENTER, italic=True)
add_text(slide, "BMI Classification:", 0.5, 4.1, 12, 0.4, size=15, bold=True, color=DARK_BLUE)
bmi_rows = [
("Underweight (< 18.5 kg/m²)", "187", "43.8%", "10", "5.3%"),
("Normal (18.5 – 24.9 kg/m²)", "233", "54.6%", "24", "10.3%"),
("Overweight/Obese (≥ 25.0 kg/m²)", "7", "1.6%", "5", "71.4% ← alarming"),
]
bmi_headers = ["BMI Category", "Total n", "% of Total", "PP Cases", "PP Rate"]
bmi_col_w = [4.0, 1.6, 1.8, 1.9, 3.6]
bmi_col_x = [0.4]
for w in bmi_col_w[:-1]:
bmi_col_x.append(bmi_col_x[-1] + w + 0.05)
for j, (h, cw, cx) in enumerate(zip(bmi_headers, bmi_col_w, bmi_col_x)):
add_rect(slide, cx, 4.55, cw, 0.45, MID_BLUE)
add_text(slide, h, cx+0.05, 4.57, cw-0.08, 0.4, size=12, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
for i, row in enumerate(bmi_rows):
bg = WHITE if i % 2 == 0 else GREY_BG
y = 5.05 + i * 0.6
for j, (val, cw, cx) in enumerate(zip(row, bmi_col_w, bmi_col_x)):
add_rect(slide, cx, y, cw, 0.56, bg)
fc = ORANGE if "alarming" in val else DARK_TEXT
add_text(slide, val.replace(" ← alarming", ""), cx+0.05, y+0.07, cw-0.08, 0.45,
size=12, bold=(j == 0 or "alarming" in val), color=fc, align=PP_ALIGN.CENTER)
add_text(slide, "χ²(2) = 26.08; p < 0.001 | 71.4% PP rate in overweight/obese group — clinically significant",
0.4, 6.85, 12.5, 0.4, size=12, color=ORANGE, bold=True, italic=True)
# ─────────────────────────────────────────────
# SLIDE 35 – STUDENT-REPORTED OUTCOMES
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Student-Reported Outcomes – Table 9 (N=427)")
items_sr = [
("Body changes noticed", "316 (74.0%)", "Mean age: 11.38 ± 1.18 yrs", DARK_BLUE),
("First menstrual period", "296 (69.3%)", "Mean age: 11.72 ± 0.86 yrs", MID_BLUE),
("Age at first period < 12 yrs\n(early menarche)", "197 (66.6% of those\nmenstruating)", "High burden of early menarche", ORANGE),
("Daily outdoor play", "241 (56.4%)", "< WHO recommendations", TEAL),
("Screen time > 2h/day", "267 (62.5%)", "Exceeds WHO 2 hr guideline", ORANGE),
]
for i, (lbl, val, note, col) in enumerate(items_sr):
x = 0.4 + (i % 3) * 4.3
y = 1.7 + (i // 3) * 2.3
add_rect(slide, x, y, 4.0, 2.0, WHITE)
add_rect(slide, x, y, 4.0, 0.12, col)
add_text(slide, lbl, x+0.1, y+0.17, 3.8, 0.65, size=13, bold=True, color=DARK_BLUE, wrap=True)
add_text(slide, val, x+0.1, y+0.85, 3.8, 0.65, size=15, bold=True, color=col, wrap=True)
add_text(slide, note, x+0.1, y+1.5, 3.8, 0.45, size=11, color=DARK_TEXT, italic=True, wrap=True)
add_rect(slide, 0.4, 6.1, 12.5, 0.7, LIGHT_TEAL)
add_text(slide,
"Pearson correlation between age at puberty signs & age at menarche: r = 0.482 (p=0.003, n=57) — confirms biological coherence of sequential pubertal events",
0.6, 6.18, 12.1, 0.55, size=13, color=DARK_BLUE, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 36 – SUMMARY STATISTICS TABLE
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Summary of All Statistical Test Results – Table 11")
sum_headers = ["Variable", "Test Used", "Statistic", "p-value", "Significance"]
sum_col_w = [4.2, 2.5, 2.5, 1.9, 1.9]
sum_col_x = [0.3]
for w in sum_col_w[:-1]:
sum_col_x.append(sum_col_x[-1] + w + 0.05)
for j, (h, cw, cx) in enumerate(zip(sum_headers, sum_col_w, sum_col_x)):
add_rect(slide, cx, 1.6, cw, 0.5, DARK_BLUE)
add_text(slide, h, cx+0.05, 1.62, cw-0.08, 0.45, size=13, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
sum_rows = [
("Family history of early puberty", "Chi-square", "X²=12.845", "< 0.001", "***"),
("BMI (continuous)", "t-test", "t=5.67", "< 0.001", "***"),
("Age at menarche", "t-test", "t=−13.07", "< 0.001", "***"),
("Overweight (BMI ≥ 25)", "Chi-square", "X²=26.08", "< 0.001", "***"),
("Urban vs Semi-urban", "Chi-square", "X²=1.765", "0.184", "NS"),
("Screen time > 2h/day", "Chi-square", "X²=0.031", "0.860", "NS"),
("Fast food > 3×/week", "Chi-square", "X²=0.258", "0.611", "NS"),
("Pesticide exposure", "Chi-square", "X²=0.000", "1.000", "NS"),
("Nuclear vs Joint family", "Chi-square", "X²=1.12", "0.290", "NS"),
("Height (cm)", "t-test", "t=1.980", "0.048", "*"),
]
for i, row in enumerate(sum_rows):
bg = WHITE if i % 2 == 0 else GREY_BG
y = 2.15 + i * 0.5
for j, (val, cw, cx) in enumerate(zip(row, sum_col_w, sum_col_x)):
add_rect(slide, cx, y, cw, 0.47, bg)
fc = ORANGE if val == "***" else (MID_BLUE if val == "*" else DARK_TEXT)
bld = (j == 0 or j == 4)
add_text(slide, val, cx+0.05, y+0.06, cw-0.08, 0.38,
size=12, bold=bld, color=fc, align=PP_ALIGN.CENTER)
add_text(slide, "*** p < 0.001 | * p < 0.05 | NS = Not Significant",
0.3, 7.1, 12.5, 0.35, size=11, color=MID_BLUE, italic=True)
# ─────────────────────────────────────────────
# SLIDE 37 – SECTION DIVIDER: DISCUSSION
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
section_divider(slide, "06", "Discussion",
"Interpreting Our Findings in the Broader Evidence Context")
# ─────────────────────────────────────────────
# SLIDE 38 – DISCUSSION: PREVALENCE
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Discussion – Prevalence Findings")
add_rect(slide, 0.4, 1.65, 12.5, 0.65, DARK_BLUE)
add_text(slide, "Our finding: 9.1% (95% CI: 6.5–12.3%) — How does it compare?",
0.6, 1.7, 12.1, 0.55, size=18, bold=True, color=WHITE)
comparisons = [
("This Study\n(Malappuram, 2026)", "9.1%", TEAL),
("Binu et al.\n(Kollam, Kerala)", "10.4%", MID_BLUE),
("Indian urban studies\n(Delhi/Mumbai)", "5–12%", DARK_BLUE),
("Western clinical series\n(population-adjusted)", "0.2%", ORANGE),
]
for i, (src, val, col) in enumerate(comparisons):
x = 0.5 + i * 3.2
add_rect(slide, x, 2.45, 3.0, 2.3, WHITE)
add_rect(slide, x, 2.45, 3.0, 0.5, col)
add_text(slide, src, x+0.1, 2.48, 2.8, 0.45, size=12, bold=True, color=WHITE, align=PP_ALIGN.CENTER, wrap=True)
add_text(slide, val, x+0.1, 3.0, 2.8, 0.9, size=28, bold=True, color=col, align=PP_ALIGN.CENTER)
discussion_pts = [
"The non-significance of urban vs semi-urban difference (p=0.184) may reflect insufficient power or genuine attenuation in a rapidly urbanising area",
"Higher urban prevalence (11.2%) aligns with urbanisation as a PP risk amplifier via diet, sedentary lifestyle & EDC exposure",
"Our prevalence is notably higher than Western clinical figures primarily because clinical series underestimate population prevalence",
]
for i, pt in enumerate(discussion_pts):
add_rect(slide, 0.4, 4.95 + i*0.68, 0.12, 0.5, TEAL)
add_text(slide, pt, 0.65, 4.95 + i*0.68, 12.3, 0.62, size=14, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 39 – DISCUSSION: BMI & FAMILY HISTORY
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Discussion – BMI & Family History as Independent Predictors")
info_box(slide, "BMI – Mechanism & Evidence",
["Adipose tissue → elevated Leptin → Hypothalamic GnRH pulsatility",
"Elevated insulin & IGF-1 signaling promote early HPG axis activation",
"Peripheral estrogen synthesis in adipose tissue",
"Adjusted OR = 1.40 per kg/m² unit (p < 0.001) in our study",
"Consistent with Wang et al. 2025 meta-analysis & Shi et al. 2022",
"71.4% PP rate in overweight group — clinically striking despite small n"],
0.4, 1.65, 6.0, 4.2, header_color=ORANGE)
info_box(slide, "Family History – Genetic Basis",
["Heritability of pubertal timing: 50–80% (literature consensus)",
"Adjusted OR = 3.31 (p=0.002) — strongest independent predictor",
"Genes: MKRN3, DLK1, KISS1R (Kentistou et al. 2024)",
"20.3% PP in positive Fam Hx group vs only 6.6% in negative",
"Non-modifiable BUT actionable as a screening criterion",
"Girls with family history warrant earlier monitoring & referral"],
6.8, 1.65, 6.1, 4.2, header_color=MID_BLUE)
add_rect(slide, 0.4, 6.0, 12.5, 0.8, LIGHT_TEAL)
add_text(slide,
"Both BMI and family history were identified as the TWO strongest independent predictors in logistic regression."
" Together they account for the majority of attributable risk in this sample.",
0.6, 6.07, 12.1, 0.68, size=14, bold=True, color=DARK_BLUE, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 40 – DISCUSSION: DIET, SCREEN TIME, PESTICIDES
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Discussion – Diet, Screen Time & Pesticide Exposure")
boxes = [
("Dietary Patterns\n(Non-significant, p=0.61)",
["Fast food > 3×/week: 46.1% of sample",
"Processed food: 51.5% — alarming prevalence",
"Study underpowered for dietary subgroup analysis",
"Binary coding fails to capture dose-response",
"Phthalate/BPA exposure through packaging — needs future urinary measurement"],
ORANGE),
("Screen Time\n(Non-significant, p=0.86)",
["59.0% had screen time > 2 hrs/day (parent report)",
"62.5% by student self-report — exceeds WHO guidelines",
"Pathway: obesity promotion, circadian melatonin disruption",
"Binary measurement insufficient to capture dose-response",
"Public health concern regardless of significance"],
MID_BLUE),
("Pesticide Exposure\n(Non-significant, p=1.00)",
["14.1% pesticide/chemical exposure",
"Binary variable without type/duration/quantity",
"Irumbuzhi (semi-urban) site has active agriculture",
"Future: urinary organochlorine & phthalate levels",
"Exposure likely underestimated with current tool"],
TEAL),
]
for i, (title, pts, col) in enumerate(boxes):
x = 0.4 + i * 4.3
add_rect(slide, x, 1.65, 4.0, 5.4, WHITE)
add_rect(slide, x, 1.65, 4.0, 0.62, col)
add_text(slide, title, x+0.1, 1.68, 3.8, 0.58, size=13, bold=True, color=WHITE, wrap=True)
add_multiline(slide, pts, x+0.1, 2.35, 3.8, 4.5, size=12, bullet=True)
add_text(slide,
"Absence of significance ≠ Absence of effect | Study was powered for prevalence estimation, not for dietary subgroup analyses",
0.4, 7.1, 12.5, 0.38, size=12, color=ORANGE, italic=True, bold=True)
# ─────────────────────────────────────────────
# SLIDE 41 – SECTION DIVIDER: CONCLUSIONS
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
section_divider(slide, "07", "Conclusion & Recommendations",
"Evidence-Based Action Plan")
# ─────────────────────────────────────────────
# SLIDE 42 – CONCLUSION
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Conclusion – Key Takeaways")
conclusions = [
("9.1%", "Questionnaire-assessed PP prevalence in Malappuram — nearly 1 in 10 school girls"),
("OR 3.31", "Positive family history — strongest predictor (p=0.002)"),
("OR 1.40", "BMI per unit — key modifiable risk factor (p < 0.001)"),
("10.0 yrs", "Mean age at menarche in PP cases vs 12.39 yrs in controls — 2.39 yr difference"),
("71.4%", "PP rate in overweight/obese girls — highest proportional burden"),
]
for i, (stat, desc) in enumerate(conclusions):
add_rect(slide, 0.4, 1.65 + i*0.96, 2.2, 0.8, [DARK_BLUE, TEAL, ORANGE, MID_BLUE, ORANGE][i])
add_text(slide, stat, 0.5, 1.7 + i*0.96, 2.0, 0.7, size=22, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
add_rect(slide, 2.65, 1.65 + i*0.96, 10.2, 0.8, WHITE)
add_text(slide, desc, 2.8, 1.7 + i*0.96, 9.9, 0.7, size=15, color=DARK_TEXT, wrap=True)
add_rect(slide, 0.4, 6.55, 12.5, 0.7, DARK_BLUE)
add_text(slide,
"Findings are consistent with international literature and underscore an urgent public health need"
" for school-based screening & intervention in Malappuram district.",
0.6, 6.62, 12.1, 0.58, size=14, bold=True, color=WHITE, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 43 – RECOMMENDATIONS: SCHOOLS
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Recommendations – School Health Programs")
add_rect(slide, 0.4, 1.6, 12.5, 0.55, MID_BLUE)
add_text(slide, "TARGET: SCHOOLS & EDUCATIONAL INSTITUTIONS",
0.6, 1.65, 12.1, 0.45, size=16, bold=True, color=WHITE)
recs = [
("Annual Anthropometric\nMonitoring",
"Mandatory annual height, weight & BMI measurement from Standard 5 onwards in all government and private schools"),
("Puberty Education\nCurriculum",
"Age-appropriate puberty education modules targeting both students AND parents; address body changes, nutrition, and when to seek help"),
("School Health\nNurse Training",
"Train school health nurses & teachers to identify early pubertal signs and facilitate timely medical referral pathways"),
("Nutritional\nInterventions",
"Promote healthy school canteen policies; restrict ultra-processed food & fast food; encourage physical activity during school hours"),
]
for i, (title, desc) in enumerate(recs):
x = 0.4 + (i % 2) * 6.4
y = 2.3 + (i // 2) * 2.2
add_rect(slide, x, y, 6.0, 2.0, WHITE)
add_rect(slide, x, y, 6.0, 0.55, [TEAL, MID_BLUE, ORANGE, DARK_BLUE][i])
add_text(slide, title, x+0.1, y+0.05, 5.8, 0.5, size=14, bold=True, color=WHITE, align=PP_ALIGN.CENTER, wrap=True)
add_text(slide, desc, x+0.15, y+0.65, 5.7, 1.25, size=13, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 44 – RECOMMENDATIONS: CLINICIANS & POLICY
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Recommendations – Clinicians & Policy Makers")
info_box(slide, "For Clinicians & Healthcare Providers",
["Girls with BMI ≥ 23 kg/m² or positive family history → proactive paediatric endocrinology screening",
"Standardised PP evaluation: Tanner staging + bone age X-ray + LH/FSH assessment",
"Incorporate into district-level child health programmes",
"Systematic early referral pathways from primary care to paediatric endocrinology"],
0.4, 1.65, 6.0, 3.2, header_color=TEAL)
info_box(slide, "For Policy Makers",
["Strengthen regulation of food marketing to children — especially in school canteens",
"Restrict fast food & ultra-processed food advertising targeting children",
"Promote reduction of agrochemical use in peri-urban areas near schools",
"Fund longitudinal cohort study: PP, BMI trajectories & long-term reproductive/metabolic outcomes in Kerala"],
6.8, 1.65, 6.1, 3.2, header_color=DARK_BLUE)
info_box(slide, "For Future Research",
["Hormonal profiling (LH, FSH, estradiol) of screen-positive cases to confirm HPG axis activation",
"Urinary phthalate & BPA measurement to quantify EDC exposure",
"Qualitative research on family perceptions of early puberty & healthcare-seeking behaviour",
"Multi-district Kerala study for generalisable prevalence estimates"],
0.4, 5.05, 12.5, 2.2, header_color=ORANGE, text_size=13)
# ─────────────────────────────────────────────
# SLIDE 45 – LIMITATIONS
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Limitations")
lims = [
("Cross-sectional Design",
"Causal inference not possible — direction of associations between BMI, dietary patterns & PP cannot be definitively established"),
("Self-Reported Dietary Data",
"Parent-reported dietary information subject to recall bias & social desirability bias — limits precision"),
("Binary Exposure Variables",
"Most risk factors coded dichotomously (Yes/No) — reduces statistical power & fails to capture dose-response relationships"),
("No Hormonal Confirmation",
"Laboratory confirmation of HPG axis activation (LH, FSH, estradiol) not performed — limits clinical specificity"),
("Doctor Confirmation Bias",
"Relied on prior doctor confirmation — ascertainment bias if urban/educated families more likely to seek consultation"),
("Pesticide Exposure Classification",
"Binary variable without type, duration or quantity of exposure — limits detection of associations"),
("Generalisability",
"Findings specific to Malappuram district — may not be directly generalisable to other regions of Kerala or India"),
]
for i, (lim, desc) in enumerate(lims):
y = 1.65 + i * 0.72
add_rect(slide, 0.4, y, 3.2, 0.62, [ORANGE, TEAL, MID_BLUE, DARK_BLUE, ORANGE, TEAL, MID_BLUE][i])
add_text(slide, lim, 0.5, y+0.07, 3.05, 0.52, size=12, bold=True, color=WHITE, wrap=True)
add_rect(slide, 3.65, y, 9.3, 0.62, WHITE)
add_text(slide, desc, 3.75, y+0.07, 9.1, 0.52, size=13, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 46 – KEY REFERENCES
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Key References")
refs = [
"Wang Y et al. (2025). Risk factors for precocious puberty: systematic review & meta-analysis. Psychoneuroendocrinology, 167:107427.",
"Cheuiche AV et al. (2021). Diagnosis & management of precocious sexual maturation: updated review. Eur J Pediatr, 180:3073–87.",
"Shi L et al. (2022). Childhood obesity & central precocious puberty. Front Endocrinol, 13:1056871.",
"Lopez-Rodriguez D et al. (2021). EDCs & their effects on puberty. Best Pract Res Clin Endocrinol Metab, 35:101579.",
"Soliman AT et al. (2023). Long-term consequences of CPP. Acta Biomed, 94(6):e2023209.",
"Kentistou KA et al. (2024). Genetic complexity of puberty timing. Nat Genet, 56(7):1209–1219.",
"Calcaterra V et al. (2024). Phthalates, bisphenol & precocious puberty. Nutrients, 16(16):2732.",
"Gonc EN & Kandemir N (2022). Body composition in sexual precocity. Curr Opin Endocrinol Diabetes Obes, 29(1):71–79.",
"Coelho e Oliveira K et al. (2026). Obesity-puberty interaction. Endocr Connect, 15(3):e250052.",
"Dinkelbach L et al. (2025). CPP & psychiatric disorders. JAMA Netw Open, 8(6):e2517004.",
"Binu J et al. Kerala schoolgirls study (Kollam) — PP prevalence 10.4%.",
]
for i, r in enumerate(refs):
add_rect(slide, 0.4, 1.65 + i*0.49, 0.35, 0.42, [TEAL, MID_BLUE, ORANGE, DARK_BLUE][i % 4])
add_text(slide, r, 0.85, 1.65 + i*0.49, 12.0, 0.44, size=11, color=DARK_TEXT, wrap=True)
# ─────────────────────────────────────────────
# SLIDE 47 – STUDY TEAM
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
slide_header(slide, "Study Team")
add_rect(slide, 0.4, 1.65, 12.5, 0.55, MID_BLUE)
add_text(slide, "Principal Investigator", 0.6, 1.68, 4.0, 0.48, size=13, bold=True, color=WHITE)
add_text(slide, "Sariga M G — Third Year MBBS, Government Medical College Manjeri (2023 Batch)",
4.7, 1.7, 8.0, 0.44, size=13, color=WHITE)
add_rect(slide, 0.4, 2.3, 12.5, 0.5, DARK_BLUE)
add_text(slide, "Guides", 0.6, 2.33, 3.5, 0.44, size=13, bold=True, color=WHITE)
add_text(slide,
"Dr. Sabitha Rose Jacob, MD — Associate Professor (CAP) | Dr. Remiza Rayikkal Answar, MD — Assistant Professor",
4.2, 2.34, 8.5, 0.44, size=12, color=WHITE)
add_text(slide, "Co-Investigators (2023 MBBS Batch):", 0.5, 2.95, 12, 0.4, size=14, bold=True, color=DARK_BLUE)
co_inv = ["SP Keerthana", "Krishna N", "Rajkumar Barwal", "Sabah Rahman",
"Nahnu Rinsha P", "Ramgopal K", "Rimjhim Merotha", "Roshani Kumari Jatav",
"Shifana M", "Shifana Nasrin", "Shinsiya Sherin PP", "Sideeque Ali",
"Suman Meena", "Vivek T", "Aiswarya T K"]
for i, name in enumerate(co_inv):
x = 0.5 + (i % 5) * 2.55
y = 3.45 + (i // 5) * 0.65
add_rect(slide, x, y, 2.35, 0.52, GREY_BG)
add_text(slide, name, x+0.07, y+0.07, 2.2, 0.42, size=12, color=DARK_BLUE)
add_rect(slide, 0.5, 5.55, 12.3, 0.08, TEAL)
add_text(slide,
"Department of Community Medicine, Government Medical College Manjeri\n"
"IEC Ref. No.: IEC/GMCM/204/2026 | IRC Approval No.: IRC/GMCM/313",
0.5, 5.7, 12.3, 0.7, size=13, color=MID_BLUE, align=PP_ALIGN.CENTER)
# ─────────────────────────────────────────────
# SLIDE 48 – THANK YOU
# ─────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, DARK_BLUE)
add_rect(slide, 0, 3.2, 13.333, 0.1, TEAL)
add_rect(slide, 0, 3.3, 13.333, 4.2, RGBColor(0x10, 0x28, 0x50))
add_text(slide, "THANK YOU", 0.5, 1.0, 12.333, 1.6, size=64, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide, "for your time and attention",
0.5, 2.6, 12.333, 0.65, size=22, color=TEAL, align=PP_ALIGN.CENTER, italic=True)
add_text(slide,
"\"Nearly 1 in 10 school girls in Malappuram has precocious puberty.\n"
"BMI and family history are the most actionable risk factors.\n"
"School-based screening programs and early referral pathways are urgently needed.\"",
1.0, 3.55, 11.333, 2.0, size=17, color=LIGHT_TEAL, align=PP_ALIGN.CENTER, wrap=True, italic=True)
add_text(slide, "Open for Questions & Discussion",
1.0, 5.7, 11.333, 0.65, size=18, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text(slide,
"Prevalence of Precocious Puberty Among School Girls | GMC Manjeri | 2025–2026",
0.5, 6.8, 12.333, 0.45, size=12, color=LIGHT_GREY, align=PP_ALIGN.CENTER)
# ─────────────────────────────────────────────
# SAVE
# ─────────────────────────────────────────────
out = "/tmp/workspace/precocious-puberty-ppt/Precocious_Puberty_Presentation.pptx"
prs.save(out)
print(f"Saved: {out}")
print(f"Total slides: {len(prs.slides)}")
cd /tmp/workspace/precocious-puberty-ppt && python3 build_ppt.py
Precocious Puberty Presentation
Presentation · PPTX
| Section | Slides | Content |
|---|---|---|
| Title & Outline | 1–2 | Title slide, full roadmap |
| Introduction | 3–7 | Normal puberty, PP definition, problem statement, objectives |
| Literature Review | 8–13 | Global epidemiology, India context, BMI mechanism, EDCs, psychosocial consequences |
| Methods | 14–20 | Design, setting, sampling, sample size, data tools, operational definitions, ethics |
| Results | 21–27 | Sample profile, socio-demographics, dietary/lifestyle table, main prevalence finding (9.1%) |
| Bivariate Analysis | 28–36 | Family history, BMI, age at menarche, full chi-square & t-test tables, anthropometrics, student outcomes, summary statistics |
| Discussion | 37–40 | Prevalence comparison, BMI & family history mechanisms, diet/screen time/pesticides |
| Conclusion | 41–45 | Key takeaways with ORs, recommendations (schools/clinicians/policymakers), limitations |
| Closing | 46–48 | References, study team, Thank You slide |
I don't need dark coloured ppt make it light professional/ acadmic orientated .
I don't need blue colour make it into lighter colour increase font size
~/precocious-puberty-ppt/build_ppt_v2.py
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]
# ── LIGHT ACADEMIC PALETTE ──────────────────────────────────────────
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
CREAM = RGBColor(0xFA, 0xF8, 0xF4) # slide background
HEADER_BG = RGBColor(0xE8, 0xF5, 0xE9) # very light green header band
ACCENT1 = RGBColor(0x2E, 0x7D, 0x32) # deep forest green (headings, accents)
ACCENT2 = RGBColor(0x66, 0xBB, 0x6A) # medium green (sub-accents)
ACCENT3 = RGBColor(0xA5, 0xD6, 0xA7) # light green (soft fills)
ORANGE = RGBColor(0xE6, 0x5C, 0x00) # warm orange (highlights / sig)
DARK_TEXT = RGBColor(0x1C, 0x1C, 0x1C) # near-black text
MID_TEXT = RGBColor(0x37, 0x47, 0x4F) # dark grey-green text
LIGHT_LINE = RGBColor(0xC8, 0xE6, 0xC9) # very light green lines/dividers
TABLE_ALT = RGBColor(0xF1, 0xF8, 0xE9) # table alternating row
# ── HELPERS ─────────────────────────────────────────────────────────
def rect(slide, l, t, w, h, color):
s = slide.shapes.add_shape(1, Inches(l), Inches(t), Inches(w), Inches(h))
s.fill.solid(); s.fill.fore_color.rgb = color
s.line.fill.background()
return s
def txt(slide, text, l, t, w, h, size=18, bold=False, color=DARK_TEXT,
align=PP_ALIGN.LEFT, italic=False, wrap=True):
tb = slide.shapes.add_textbox(Inches(l), Inches(t), Inches(w), Inches(h))
tf = tb.text_frame; tf.word_wrap = wrap
p = tf.paragraphs[0]; p.alignment = align
r = p.add_run(); r.text = text
r.font.size = Pt(size); r.font.bold = bold
r.font.italic = italic; r.font.color.rgb = color
return tb
def multiline(slide, lines, l, t, w, h, size=17, color=DARK_TEXT,
bold_first=False, bullet=True):
tb = slide.shapes.add_textbox(Inches(l), Inches(t), Inches(w), Inches(h))
tf = tb.text_frame; tf.word_wrap = True
for i, line in enumerate(lines):
p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
p.space_before = Pt(3)
r = p.add_run()
r.text = ("• " if bullet else "") + line
r.font.size = Pt(size); r.font.color.rgb = color
if bold_first and i == 0: r.font.bold = True
def slide_bg(slide):
"""Light cream background for every content slide."""
rect(slide, 0, 0, 13.333, 7.5, CREAM)
def header(slide, title, subtitle=None):
slide_bg(slide)
rect(slide, 0, 0, 13.333, 1.3, HEADER_BG)
rect(slide, 0, 1.3, 13.333, 0.07, ACCENT1)
txt(slide, title, 0.4, 0.08, 12.5, 0.85, size=32, bold=True,
color=ACCENT1, align=PP_ALIGN.LEFT)
if subtitle:
txt(slide, subtitle, 0.4, 0.92, 12.5, 0.38, size=16,
color=MID_TEXT, italic=True)
def section_div(slide, num, title, sub=""):
rect(slide, 0, 0, 13.333, 7.5, ACCENT3)
rect(slide, 0, 2.95, 13.333, 0.08, ACCENT1)
txt(slide, f"SECTION {num}", 1, 1.7, 11, 0.6, size=18,
bold=True, color=ACCENT1, align=PP_ALIGN.CENTER)
txt(slide, title, 1, 2.35, 11, 1.1, size=42,
bold=True, color=DARK_TEXT, align=PP_ALIGN.CENTER)
if sub:
txt(slide, sub, 1.5, 3.65, 10, 0.7, size=19,
color=MID_TEXT, align=PP_ALIGN.CENTER, italic=True)
def info_box(slide, title, lines, l, t, w, h, hcol=ACCENT1, ts=15):
rect(slide, l, t, w, 0.48, hcol)
rect(slide, l, t+0.48, w, h-0.48, WHITE)
txt(slide, title, l+0.12, t+0.06, w-0.2, 0.38,
size=15, bold=True, color=WHITE)
multiline(slide, lines, l+0.18, t+0.56, w-0.28, h-0.65,
size=ts, color=DARK_TEXT)
# ════════════════════════════════════════════════════════════════════
# SLIDE 1 – TITLE
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
rect(slide, 0, 0, 13.333, 7.5, WHITE)
rect(slide, 0, 0, 13.333, 4.6, ACCENT3)
rect(slide, 0, 4.6, 13.333, 0.1, ACCENT1)
txt(slide, "PREVALENCE OF PRECOCIOUS PUBERTY",
0.5, 0.65, 12.3, 1.0, size=36, bold=True, color=ACCENT1, align=PP_ALIGN.CENTER)
txt(slide, "AMONG SCHOOL GIRLS",
0.5, 1.6, 12.3, 0.75, size=30, bold=True, color=DARK_TEXT, align=PP_ALIGN.CENTER)
txt(slide, "A Cross-Sectional Study in Manjeri and Anakkayam, Malappuram District, Kerala, India",
0.8, 2.45, 11.7, 0.6, size=18, color=MID_TEXT, align=PP_ALIGN.CENTER, italic=True)
rect(slide, 2.5, 3.2, 8.333, 0.05, ACCENT1)
txt(slide, "Department of Community Medicine | Government Medical College Manjeri | 2025–2026",
0.5, 4.75, 12.3, 0.5, size=16, bold=True, color=DARK_TEXT, align=PP_ALIGN.CENTER)
txt(slide, "IEC Ref. No.: IEC/GMCM/204/2026 | IRC Approval No.: IRC/GMCM/313",
0.5, 5.28, 12.3, 0.4, size=14, color=MID_TEXT, align=PP_ALIGN.CENTER)
txt(slide, "Principal Investigator: Sariga M G | Guides: Dr. Sabitha Rose Jacob & Dr. Remiza Rayikkal Answar",
0.5, 5.72, 12.3, 0.4, size=13, color=MID_TEXT, align=PP_ALIGN.CENTER)
# ════════════════════════════════════════════════════════════════════
# SLIDE 2 – OUTLINE
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Presentation Outline")
sections = [
"01 Introduction & Background",
"02 Problem Statement & Objectives",
"03 Review of Literature",
"04 Methods & Materials",
"05 Results – Sample Characteristics",
"06 Results – Prevalence & Risk Factors",
"07 Results – Statistical Analysis",
"08 Discussion",
"09 Conclusion & Recommendations",
"10 Limitations & Future Research",
]
for i, s in enumerate(sections):
col = 0 if i < 5 else 6.8
row = 1.55 + (i % 5) * 0.9
rect(slide, col+0.3, row, 5.8, 0.75, WHITE)
rect(slide, col+0.3, row, 0.18, 0.75, ACCENT1)
txt(slide, s, col+0.6, row+0.12, 5.2, 0.52, size=16, color=DARK_TEXT)
# ════════════════════════════════════════════════════════════════════
# SLIDE 3 – SECTION DIVIDER
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
section_div(slide, "01", "Introduction & Background",
"Understanding Precocious Puberty in Context")
# ════════════════════════════════════════════════════════════════════
# SLIDE 4 – NORMAL PUBERTY
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "What is Normal Puberty?")
stages = [
("1. Thelarche", "Breast development\n(earliest sign)"),
("2. Pubarche", "Pubic hair\nappearance"),
("3. Adrenarche", "Axillary hair\ndevelopment"),
("4. Menarche", "First menstrual\nperiod"),
]
for i, (s, d) in enumerate(stages):
x = 0.5 + i * 3.2
rect(slide, x, 1.55, 2.95, 3.0, WHITE)
rect(slide, x, 1.55, 2.95, 0.55, ACCENT1)
txt(slide, s, x+0.1, 1.6, 2.75, 0.48, size=17, bold=True, color=WHITE)
txt(slide, d, x+0.1, 2.2, 2.75, 2.2, size=17, color=DARK_TEXT, wrap=True)
rect(slide, 0.5, 4.7, 12.3, 0.06, ACCENT2)
txt(slide, "Normal onset in girls: Ages 8–13 years | Completion within 2–5 years",
0.5, 4.82, 12.3, 0.5, size=18, bold=True, color=ACCENT1)
# ════════════════════════════════════════════════════════════════════
# SLIDE 5 – DEFINITION OF PP
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Defining Precocious Puberty (PP)")
rect(slide, 0.4, 1.55, 12.5, 1.1, ACCENT1)
txt(slide,
"Precocious Puberty = Development of secondary sexual characteristics BEFORE age 8 in girls (before age 9 in boys)",
0.6, 1.65, 12.1, 0.9, size=20, bold=True, color=WHITE, wrap=True)
types = [
("Central PP (CPP)",
"Premature activation of\nhypothalamic-pituitary-gonadal\n(HPG) axis\n\nMost cases in girls are IDIOPATHIC\n\nGnRHa is standard treatment"),
("Peripheral PP",
"Sex hormone secretion\nINDEPENDENT of gonadotropins\n\nCaused by ovarian cysts,\ntumours, or exogenous estrogens"),
("Genetic Factors",
"MKRN3, DLK1, KISS1R mutations\nidentified in familial cases\n\nHeritability of pubertal timing:\n50–80%"),
]
for i, (t, d) in enumerate(types):
x = 0.4 + i * 4.3
rect(slide, x, 2.85, 4.0, 4.2, WHITE)
rect(slide, x, 2.85, 4.0, 0.52, ACCENT2)
txt(slide, t, x+0.12, 2.89, 3.76, 0.45, size=17, bold=True, color=WHITE)
txt(slide, d, x+0.12, 3.45, 3.76, 3.5, size=16, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 6 – PROBLEM STATEMENT
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Problem Statement")
bullets = [
"Secular trend toward earlier pubertal onset documented globally over recent decades",
"Rising PP prevalence in India linked to rapid urbanisation, nutrition transition & environmental exposures",
"Public health consequences: shortened childhood, psychosocial stress, early sexual activity risks",
"Long-term sequelae: hormone-sensitive cancers, metabolic syndrome, cardiovascular disease",
"Kerala offers an ideal study setting: high female literacy, above-average nutrition, diverse urban-rural gradient",
"District-level data from Malappuram remain SCARCE — this study addresses that evidence gap directly",
]
for i, b in enumerate(bullets):
rect(slide, 0.5, 1.58 + i*0.82, 0.32, 0.6, ACCENT1)
txt(slide, b, 1.0, 1.58 + i*0.82, 11.9, 0.74, size=17, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 7 – OBJECTIVES
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Study Objectives")
rect(slide, 0.4, 1.55, 12.5, 0.65, ACCENT1)
txt(slide, "PRIMARY OBJECTIVE", 0.55, 1.6, 12.1, 0.55, size=17, bold=True, color=WHITE)
txt(slide,
"To estimate the prevalence of precocious puberty among school girls aged 10–15 years "
"in Manjeri and Anakkayam, Malappuram District, Kerala",
0.4, 2.28, 12.5, 0.7, size=18, bold=True, color=ACCENT1, wrap=True)
txt(slide, "SECONDARY OBJECTIVES", 0.4, 3.08, 12, 0.42, size=17, bold=True, color=ACCENT1)
sec = [
"Identify socio-demographic risk factors (age, residence, family type, parental education, income)",
"Examine association of dietary patterns, screen time, physical activity & pesticide exposure with PP",
"Assess the role of BMI and family history in precocious puberty",
"Describe and compare age at menarche & puberty indicators between PP and non-PP groups",
]
for i, o in enumerate(sec):
rect(slide, 0.5, 3.58 + i*0.72, 0.12, 0.55, ORANGE)
txt(slide, o, 0.78, 3.58 + i*0.72, 12.1, 0.65, size=16, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 8 – SECTION DIVIDER
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
section_div(slide, "02", "Review of Literature",
"Global & Indian Evidence on Precocious Puberty")
# ════════════════════════════════════════════════════════════════════
# SLIDE 9 – GLOBAL EPIDEMIOLOGY
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Global Epidemiology of PP", subtitle="Prevalence & Secular Trends")
stats = [
("0.2% – >10%", "Global PP prevalence\nrange across studies"),
("10 : 1", "Girls : Boys ratio\nfor CPP"),
("0.5–1 yr", "Earlier breast onset\nin US girls since 1960s"),
("50–80%", "Heritability of\npubertal timing"),
]
for i, (val, lab) in enumerate(stats):
x = 0.4 + i * 3.2
rect(slide, x, 1.55, 3.0, 2.0, WHITE)
rect(slide, x, 1.55, 3.0, 0.08, ACCENT1)
txt(slide, val, x+0.1, 1.65, 2.8, 0.95, size=26, bold=True,
color=ACCENT1, align=PP_ALIGN.CENTER)
txt(slide, lab, x+0.1, 2.6, 2.8, 0.8, size=15,
color=MID_TEXT, align=PP_ALIGN.CENTER)
txt(slide, "Key Literature Findings:", 0.4, 3.72, 12, 0.42, size=17, bold=True, color=ACCENT1)
lit = [
"Wang et al. (2025) – Meta-analysis: elevated BMI, maternal menarche age & breastfeeding duration are key PP risk factors",
"Cheuiche et al. (2021) – CPP far more common in girls; MKRN3 & DLK1 gene mutations in familial cases; GnRHa is standard care",
"Kentistou et al. (2024) – Multiple genetic loci including KISS1R identified as key regulators of puberty onset",
"Dinkelbach et al. (2025) – CPP significantly associated with psychiatric disorders (depression, ADHD) — JAMA Network Open",
]
for i, l in enumerate(lit):
rect(slide, 0.5, 4.2 + i*0.68, 0.12, 0.52, ORANGE)
txt(slide, l, 0.78, 4.2 + i*0.68, 12.1, 0.62, size=15, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 10 – PP IN INDIA
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Precocious Puberty in India", subtitle="Regional Context & Kerala Data")
info_box(slide, "Indian Prevalence Data",
["Urban centres (Delhi, Mumbai, Kolkata): PP prevalence 5–12% in schoolgirls",
"Urban areas consistently show higher rates than rural counterparts",
"Binu et al. (Kerala/Kollam): PP prevalence 10.4% — closest comparable study",
"Girls in school settings particularly vulnerable"],
0.4, 1.55, 6.0, 3.2, hcol=ACCENT1)
info_box(slide, "Kerala Epidemiological Context",
["High female literacy & healthcare access",
"Above-average nutrition indices",
"Rapid urbanisation in districts like Malappuram",
"Significant pesticide use in agricultural peri-urban areas",
"District-level Malappuram data: SCARCE before this study"],
6.8, 1.55, 6.1, 3.2, hcol=ACCENT2)
rect(slide, 0.4, 4.9, 12.5, 1.8, WHITE)
rect(slide, 0.4, 4.9, 0.15, 1.8, ORANGE)
txt(slide, "Why This Study Matters", 0.7, 4.97, 12, 0.4, size=16, bold=True, color=ACCENT1)
txt(slide,
"Malappuram represents a rapidly urbanising area with significant agricultural activity, "
"creating a unique dual-exposure milieu for EDCs and nutritional shifts. "
"This study provides the first systematic district-level prevalence data.",
0.7, 5.42, 12, 1.0, size=16, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 11 – BMI & ADIPOSITY (LIT)
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "BMI, Obesity & PP – Evidence Base")
rect(slide, 0.4, 1.55, 12.5, 0.95, ACCENT1)
txt(slide,
"Mechanistic Pathway: Adipose tissue → Leptin → Hypothalamic GnRH pulsatility → Premature HPG axis activation",
0.6, 1.65, 12.1, 0.78, size=18, bold=True, color=WHITE, wrap=True)
evidence = [
("Shi et al. (2022)",
"Childhood obesity & CPP\n\nBody fat % especially visceral\nadipose tissue — stronger\npredictor than BMI alone"),
("Gonc & Kandemir (2022)",
"Body composition in PP\n\nElevated leptin lowers\nthreshold for HPG axis\nactivation in overweight children"),
("Oliveira et al. (2026)",
"Bidirectional relationship\n\nObesity accelerates puberty\nAND PP promotes fat\naccumulation — reinforcing cycle"),
("Wang et al. (2025)",
"Systematic review\n\nBMI identified as one of\nthe major independent risk\nfactors for PP across populations"),
]
for i, (ref, text) in enumerate(evidence):
x = 0.4 + i * 3.2
rect(slide, x, 2.65, 3.0, 4.3, WHITE)
rect(slide, x, 2.65, 3.0, 0.52, ACCENT2)
txt(slide, ref, x+0.1, 2.69, 2.8, 0.46, size=15, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
txt(slide, text, x+0.1, 3.24, 2.8, 3.6, size=15, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 12 – EDCs
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Environmental Endocrine Disruptors (EDCs) & PP")
txt(slide,
"Exogenous chemicals that interfere with the endocrine system — implicated in earlier pubertal onset",
0.4, 1.6, 12.5, 0.5, size=17, color=DARK_TEXT, wrap=True)
edcs = [
("Phthalates", "Plastic packaging,\npersonal care products"),
("Bisphenol A (BPA)", "Food containers,\nbottle linings"),
("PCBs", "Industrial chemicals,\nold electrical equipment"),
("Organochlorine\nPesticides", "Agricultural use,\nperi-urban exposure"),
]
for i, (name, source) in enumerate(edcs):
x = 0.4 + i * 3.2
rect(slide, x, 2.2, 3.0, 1.9, ACCENT3)
rect(slide, x, 2.2, 3.0, 0.08, ACCENT1)
txt(slide, name, x+0.1, 2.25, 2.8, 0.65, size=16, bold=True,
color=ACCENT1, align=PP_ALIGN.CENTER)
txt(slide, source, x+0.1, 2.88, 2.8, 1.0, size=15,
color=MID_TEXT, align=PP_ALIGN.CENTER)
bullets2 = [
"Lopez-Rodriguez et al. (2021): EDCs disrupt GnRH neuronal network during sensitive developmental windows",
"Calcaterra et al. (2024): Dietary phthalate & BPA exposure through food packaging correlates with early pubertal onset",
"Symeonides et al. (2024): Umbrella review confirms EDC-endocrine outcome associations",
"In this study: 14.1% pesticide/chemical exposure — monitored but non-significant (p=1.000)",
]
for i, b in enumerate(bullets2):
rect(slide, 0.4, 4.25 + i*0.68, 0.12, 0.52, ORANGE)
txt(slide, b, 0.68, 4.25 + i*0.68, 12.3, 0.62, size=15, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 13 – PSYCHOSOCIAL CONSEQUENCES
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Psychosocial & Long-Term Health Consequences")
info_box(slide, "Short-Term Consequences",
["Body image concerns and anxiety",
"Early sexual activity risks",
"Psychosocial stress & peer difficulties",
"Inadequate preparation due to poor sex education",
"Depression and attention issues (ADHD)"],
0.4, 1.55, 6.0, 4.5, hcol=ORANGE)
info_box(slide, "Long-Term Health Consequences",
["Increased risk of breast and ovarian cancer",
"Type 2 diabetes and metabolic syndrome",
"Polycystic ovarian syndrome (PCOS)",
"Osteoporosis",
"Cardiovascular disease"],
6.8, 1.55, 6.1, 4.5, hcol=ACCENT1)
txt(slide, "Sources: Soliman et al. 2023 (Acta Biomed) | Dinkelbach et al. 2025 (JAMA Network Open)",
0.4, 6.3, 12.5, 0.4, size=13, color=MID_TEXT, italic=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 14 – SECTION DIVIDER
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
section_div(slide, "03", "Methods & Materials",
"Study Design, Setting, Population & Tools")
# ════════════════════════════════════════════════════════════════════
# SLIDE 15 – STUDY DESIGN & SETTING
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Study Design & Setting")
rect(slide, 0.4, 1.55, 12.5, 0.62, ACCENT1)
txt(slide, "STUDY DESIGN: School-based Cross-Sectional Study",
0.6, 1.6, 12.1, 0.52, size=18, bold=True, color=WHITE)
info_box(slide, "Study Sites (3 Schools)",
["Benchmark International School, Manjeri (URBAN)",
"Government HSS (Girls), Manjeri (URBAN)",
"Government HSS, Irumbuzhi, Anakkayam (SEMI-URBAN)"],
0.4, 2.32, 6.0, 2.6, hcol=ACCENT2)
info_box(slide, "Geographic Context",
["Malappuram District, Kerala, India",
"Manjeri: rapidly urbanising town",
"Anakkayam: semi-urban with active agriculture & pesticide use",
"Dual-site design allows urban vs semi-urban comparison"],
6.8, 2.32, 6.1, 2.6, hcol=ACCENT2)
txt(slide, "Why Cross-Sectional?", 0.4, 5.07, 12, 0.38, size=17, bold=True, color=ACCENT1)
txt(slide,
"Appropriate for prevalence estimation at a single time point | Resource-efficient for large N | "
"No longitudinal follow-up required | Suitable for identifying associations",
0.4, 5.5, 12.5, 0.65, size=16, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 16 – STUDY POPULATION & SAMPLING
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Study Population & Sampling Strategy")
rect(slide, 0.4, 1.55, 5.9, 2.5, WHITE)
rect(slide, 0.4, 1.55, 5.9, 0.48, ACCENT1)
txt(slide, "Inclusion Criteria", 0.55, 1.58, 5.7, 0.42, size=15, bold=True, color=WHITE)
multiline(slide,
["Female students aged 10–15 years",
"Enrolled in Standards 6–9 in selected schools",
"Parent/guardian written informed consent",
"Student verbal assent obtained"],
0.55, 2.1, 5.7, 1.8, size=16, bullet=True)
rect(slide, 7.0, 1.55, 5.9, 2.5, WHITE)
rect(slide, 7.0, 1.55, 5.9, 0.48, ORANGE)
txt(slide, "Exclusion Criteria", 7.15, 1.58, 5.7, 0.42, size=15, bold=True, color=WHITE)
multiline(slide,
["Girls whose parents refused consent",
"Girls who declined assent",
"No categorical exclusions — full spectrum captured",
"Girls with chronic illness included"],
7.15, 2.1, 5.7, 1.8, size=16, bullet=True)
rect(slide, 0.4, 4.2, 12.5, 2.9, WHITE)
rect(slide, 0.4, 4.2, 12.5, 0.48, ACCENT1)
txt(slide, "Multi-Stage Random Sampling", 0.6, 4.23, 12.1, 0.42, size=16, bold=True, color=WHITE)
steps = [
"STAGE 1\nPurposive school selection\nrepresenting urban &\nsemi-urban strata",
"STAGE 2\nSystematic random sampling\nfrom class rolls within\neach school",
"ADJUSTMENT\nSampling fraction adjusted\nproportionally to school\nenrolment size",
"FINAL N = 427\nAll enrolled girls had\ncomplete primary\noutcome data",
]
for i, s in enumerate(steps):
x = 0.6 + i * 3.1
rect(slide, x, 4.75, 2.8, 2.2, ACCENT3)
rect(slide, x, 4.75, 2.8, 0.08, ACCENT2)
txt(slide, s, x+0.1, 4.82, 2.6, 2.05, size=14, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 17 – SAMPLE SIZE
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Sample Size Calculation")
rect(slide, 2.5, 1.6, 8.333, 1.3, ACCENT1)
txt(slide, "Formula: n = Z²α/2 × P(1−P) / d²",
2.5, 1.7, 8.333, 0.65, size=24, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
params = [
("Z (95% CI)", "1.96"),
("Expected P", "10%\n(0.10)"),
("Precision (d)", "3%\n(0.03)"),
("Base n", "≈ 384"),
("Non-response\n+10%", "+38"),
("Final N", "427"),
]
for i, (lbl, val) in enumerate(params):
x = 0.5 + i * 2.1
rect(slide, x, 3.1, 1.9, 1.8, WHITE)
rect(slide, x, 3.1, 1.9, 0.52, ACCENT2 if i < 4 else ACCENT1)
txt(slide, lbl, x+0.07, 3.13, 1.76, 0.46, size=13, bold=True,
color=WHITE, align=PP_ALIGN.CENTER, wrap=True)
txt(slide, val, x+0.07, 3.66, 1.76, 1.0, size=20, bold=True,
color=ACCENT1, align=PP_ALIGN.CENTER)
rect(slide, 0.5, 5.1, 12.3, 0.08, ACCENT2)
txt(slide,
"All 427 enrolled participants had complete primary outcome data — 100% completion rate",
0.5, 5.25, 12.3, 0.5, size=18, bold=True, color=ACCENT1, align=PP_ALIGN.CENTER)
# ════════════════════════════════════════════════════════════════════
# SLIDE 18 – DATA COLLECTION TOOLS
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Data Collection Tools")
tools = [
("Parent / Guardian\nQuestionnaire",
"Socio-demographics\nMedical & family history\nDietary patterns\nScreen time & lifestyle\nPesticide exposure\nAge at menarche\nDoctor confirmation of PP"),
("Student\nQuestionnaire",
"Self-reported physical changes\nOutdoor activity & screen time\nMenstrual history\nDiet & lifestyle\nFamily history\nAdministered with teacher assistance"),
("Healthcare Professional\nData Sheet",
"Height (cm)\nWeight (kg)\nBMI calculated as kg/m²\nMeasured by trained personnel\nStandardised protocol"),
]
for i, (title, content) in enumerate(tools):
x = 0.4 + i * 4.3
rect(slide, x, 1.55, 4.0, 5.2, WHITE)
rect(slide, x, 1.55, 4.0, 0.7, [ACCENT1, ACCENT2, ORANGE][i])
txt(slide, title, x+0.1, 1.6, 3.8, 0.65, size=16, bold=True,
color=WHITE, align=PP_ALIGN.CENTER, wrap=True)
multiline(slide, content.split("\n"), x+0.15, 2.35, 3.7, 4.2, size=15, bullet=True)
txt(slide,
"All questionnaires pre-tested on 20 girls (pilot) | Administered in Malayalam with English alongside",
0.4, 6.9, 12.5, 0.42, size=14, color=MID_TEXT, italic=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 19 – OPERATIONAL DEFINITIONS
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Operational Definitions")
defs = [
("Precocious Puberty\n(Primary Outcome)",
"Questionnaire-assessed onset of secondary sexual characteristics before age 8, reported by parent AND confirmed by a registered medical practitioner"),
("Early Menarche",
"First menstrual period occurring before age 12 years"),
("Overweight / Obese",
"BMI ≥ 25 kg/m² per WHO growth reference for age"),
("Urban Residence",
"Residing within Manjeri municipal limits (Schools 1 & 2)"),
("Semi-Urban Residence",
"Residing in Irumbuzhi panchayat area (School 3)"),
("Family History of Early Puberty",
"Mother or sister experiencing puberty/menarche before age 10"),
]
for i, (term, defn) in enumerate(defs):
y = 1.58 + i * 0.9
rect(slide, 0.4, y, 3.4, 0.78, ACCENT1)
txt(slide, term, 0.5, y+0.06, 3.2, 0.68, size=14, bold=True, color=WHITE, wrap=True)
rect(slide, 3.85, y, 9.1, 0.78, WHITE)
txt(slide, defn, 3.95, y+0.08, 8.9, 0.65, size=15, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 20 – ETHICAL CONSIDERATIONS
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Ethical Considerations")
ethics = [
("IEC Approval", "IEC/GMCM/204/2026 — Institutional Ethics Committee, GMC Manjeri"),
("IRC Approval", "IRC/GMCM/313 — Institutional Research Committee approval"),
("Informed Consent", "Written informed consent from all parents/guardians before data collection"),
("Student Assent", "Verbal assent obtained from all participating girls"),
("Confidentiality", "Unique participant IDs; datasets anonymised; stored on password-protected devices only"),
("Voluntary Participation", "Right to withdraw at any time without any consequence"),
("ICMR Compliance", "Compliant with ICMR Ethical Guidelines 2017 & NMC undergraduate research guidelines"),
]
for i, (head, body) in enumerate(ethics):
y = 1.58 + i * 0.72
rect(slide, 0.4, y, 2.9, 0.62, ACCENT1)
txt(slide, head, 0.5, y+0.08, 2.75, 0.5, size=14, bold=True, color=WHITE, wrap=True)
txt(slide, body, 3.45, y+0.08, 9.6, 0.52, size=15, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 21 – SECTION DIVIDER
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
section_div(slide, "04", "Results", "Sample Characteristics & Prevalence")
# ════════════════════════════════════════════════════════════════════
# SLIDE 22 – SAMPLE OVERVIEW
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Sample Characteristics – Overview (N = 427)")
metrics = [
("427", "Total\nParticipants"),
("13.01 ± 1.35", "Mean Age\n(years)"),
("50.1% / 49.9%","Urban /\nSemi-urban"),
("65.1%", "Nuclear\nFamily"),
("10–15 yrs", "Age\nRange"),
]
for i, (val, lbl) in enumerate(metrics):
x = 0.4 + i * 2.55
rect(slide, x, 1.58, 2.3, 2.0, WHITE)
rect(slide, x, 1.58, 2.3, 0.08, ACCENT1)
txt(slide, val, x+0.1, 1.68, 2.1, 0.95, size=20, bold=True,
color=ACCENT1, align=PP_ALIGN.CENTER)
txt(slide, lbl, x+0.1, 2.62, 2.1, 0.8, size=15,
color=MID_TEXT, align=PP_ALIGN.CENTER)
txt(slide, "Age Distribution:", 0.4, 3.75, 12, 0.4, size=17, bold=True, color=ACCENT1)
age_data = [("10 yrs","36 (8.4%)"),("11 yrs","76 (17.8%)"),("12 yrs","88 (20.6%)"),
("13 yrs","88 (20.6%)"),("14 yrs","102 (23.9%)"),("15 yrs","37 (8.7%)")]
for i, (age, n) in enumerate(age_data):
x = 0.4 + i * 2.15
rect(slide, x, 4.2, 2.0, 1.25, WHITE)
rect(slide, x, 4.2, 2.0, 0.42, ACCENT2)
txt(slide, age, x+0.05, 4.22, 1.9, 0.38, size=14, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
txt(slide, n, x+0.05, 4.65, 1.9, 0.7, size=15, color=DARK_TEXT, align=PP_ALIGN.CENTER)
txt(slide, "Standard 9: 49.4% | Standard 8: 32.6% | Standard 7: 10.5% | Standard 6: 7.5%",
0.4, 5.65, 12.5, 0.5, size=16, bold=True, color=DARK_TEXT)
# ════════════════════════════════════════════════════════════════════
# SLIDE 23 – SOCIO-DEMOGRAPHIC TABLE
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Socio-Demographic Profile – Table 1 (N = 427)")
rows = [
("Residence", "Urban: 214 (50.1%) | Semi-urban: 213 (49.9%)"),
("Family Type", "Nuclear: 278 (65.1%) | Joint: 149 (34.9%)"),
("Father's Education", "Illiterate 4.2% | Primary 16.4% | Secondary 33.3% | Graduate 31.1% | PG 15.0%"),
("Mother's Education", "Illiterate 3.5% | Primary 13.8% | Secondary 31.6% | Graduate 34.7% | PG 16.4%"),
("Monthly Income", "< ₹10K: 10.5% | ₹10K–30K: 29.3% | ₹30K–50K: 39.8% | > ₹50K: 20.4%"),
]
rect(slide, 0.4, 1.6, 3.6, 0.5, ACCENT1)
rect(slide, 4.05, 1.6, 9.0, 0.5, ACCENT1)
txt(slide, "Variable", 0.5, 1.63, 3.4, 0.42, size=15, bold=True, color=WHITE)
txt(slide, "Distribution", 4.15, 1.63, 8.8, 0.42, size=15, bold=True, color=WHITE)
for i, (var, dist) in enumerate(rows):
bg = TABLE_ALT if i % 2 == 0 else WHITE
y = 2.15 + i * 0.82
rect(slide, 0.4, y, 3.6, 0.76, bg)
rect(slide, 4.05, y, 9.0, 0.76, bg)
txt(slide, var, 0.5, y+0.08, 3.4, 0.62, size=15, bold=True, color=ACCENT1)
txt(slide, dist, 4.15, y+0.08, 8.8, 0.62, size=15, color=DARK_TEXT)
txt(slide,
"Most participants: secondary/graduate-educated families | Middle-income households most common (₹30K–50K: 39.8%)",
0.4, 6.35, 12.5, 0.55, size=14, color=MID_TEXT, italic=True, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 24 – MEDICAL & FAMILY HISTORY
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Medical & Family History Profile")
items = [
("Chronic Illness", "43 girls\n(10.1%)", ORANGE),
("Family History of Early Puberty","79 girls\n(18.5%)", ACCENT1),
("Pesticide / Chemical Exposure", "60 girls\n(14.1%)", ACCENT2),
("Doctor Confirmed PP", "39 girls\n(9.1%)", ORANGE),
]
for i, (lbl, val, col) in enumerate(items):
x = 0.5 + (i % 2) * 6.4
y = 1.65 + (i // 2) * 2.3
rect(slide, x, y, 5.9, 2.0, WHITE)
rect(slide, x, y, 5.9, 0.1, col)
txt(slide, lbl, x+0.2, y+0.2, 5.5, 0.62, size=17, bold=True, color=DARK_TEXT)
txt(slide, val, x+0.2, y+0.85, 5.5, 0.9, size=28, bold=True,
color=col, align=PP_ALIGN.CENTER)
rect(slide, 0.5, 6.2, 12.3, 0.08, ACCENT2)
txt(slide,
"Family history of early puberty present in 18.5% of total sample — a critical and actionable screening marker",
0.5, 6.35, 12.3, 0.5, size=15, bold=True, color=ACCENT1, align=PP_ALIGN.CENTER)
# ════════════════════════════════════════════════════════════════════
# SLIDE 25 – DIETARY & LIFESTYLE
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Dietary & Lifestyle Characteristics – Table 7")
diet_items = [
("Home-cooked meals (primary diet)", "340 (79.6%)", "Adequate"),
("Fast food > 3×/week", "197 (46.1%)", "High"),
("Processed food consumption", "220 (51.5%)", "High"),
("High protein diet", "216 (50.6%)", "Moderate"),
("Traditional Kerala diet", "277 (64.9%)", "Yes"),
("Screen time > 2 h/day (parent)", "252 (59.0%)", "Exceeds WHO"),
("Pesticide / chemical exposure", "60 (14.1%)", "Low"),
]
cw = [6.0, 2.5, 3.0]
cx = [0.4, 6.45, 9.0]
hdrs = ["Variable", "n (%)", "Concern Level"]
for j, (h, w, x) in enumerate(zip(hdrs, cw, cx)):
rect(slide, x, 1.6, w, 0.5, ACCENT1)
txt(slide, h, x+0.07, 1.63, w-0.1, 0.42, size=15, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
for i, (var, n, level) in enumerate(diet_items):
bg = TABLE_ALT if i % 2 == 0 else WHITE
y = 2.15 + i * 0.62
for w, x in zip(cw, cx):
rect(slide, x, y, w, 0.58, bg)
txt(slide, var, cx[0]+0.1, y+0.08, cw[0]-0.15, 0.48, size=15, color=DARK_TEXT)
txt(slide, n, cx[1]+0.07, y+0.08, cw[1]-0.1, 0.48, size=15, bold=True, color=DARK_TEXT, align=PP_ALIGN.CENTER)
lc = ORANGE if "High" in level or "Exceeds" in level else ACCENT1
txt(slide, level, cx[2]+0.07, y+0.08, cw[2]-0.1, 0.48, size=15, bold=True, color=lc, align=PP_ALIGN.CENTER)
txt(slide, "Mean outdoor hours/day: 1.54 ± 0.82 (Range: 0–5 hours)",
0.4, 6.55, 12.5, 0.42, size=16, bold=True, color=ACCENT1)
# ════════════════════════════════════════════════════════════════════
# SLIDE 26 – MAIN PREVALENCE
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Prevalence of Precocious Puberty – Key Finding")
rect(slide, 2.0, 1.6, 9.333, 2.6, ACCENT1)
txt(slide, "9.1%", 2.0, 1.68, 9.333, 1.5, size=84, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
txt(slide, "Overall PP Prevalence (n = 39 / 427)",
2.0, 3.1, 9.333, 0.62, size=22, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
txt(slide, "95% Confidence Interval: 6.5% – 12.3%",
2.0, 3.72, 9.333, 0.48, size=17, color=ACCENT3, align=PP_ALIGN.CENTER, italic=True)
for i, (grp, n, pct, ci) in enumerate([
("Urban (n=214)", "24 cases", "11.2%", "95% CI: 7.4–16.4%"),
("Semi-urban (n=213)", "15 cases", "7.0%", "95% CI: 4.1–11.5%"),
]):
x = 1.0 + i * 5.8
rect(slide, x, 4.45, 5.0, 2.1, WHITE)
rect(slide, x, 4.45, 5.0, 0.48, ACCENT2)
txt(slide, grp, x+0.1, 4.48, 4.8, 0.42, size=15, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
txt(slide, pct, x+0.1, 4.96, 4.8, 0.85, size=34, bold=True,
color=ACCENT1, align=PP_ALIGN.CENTER)
txt(slide, n + " | " + ci, x+0.1, 5.85, 4.8, 0.48, size=14,
color=DARK_TEXT, align=PP_ALIGN.CENTER)
txt(slide, "Urban vs Semi-urban: NOT statistically significant (χ² = 1.765; p = 0.184)",
0.5, 6.65, 12.3, 0.42, size=15, italic=True, color=ORANGE, align=PP_ALIGN.CENTER)
# ════════════════════════════════════════════════════════════════════
# SLIDE 27 – PREVALENCE TABLE
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Prevalence by Residence – Table 3")
headers = ["Category", "Total (N)", "PP Cases (n)", "Prevalence (%)", "95% CI"]
col_w = [3.2, 2.2, 2.4, 2.5, 2.7]
col_x = [0.4]
for w in col_w[:-1]:
col_x.append(col_x[-1] + w + 0.05)
for j, (h, cw, cx) in enumerate(zip(headers, col_w, col_x)):
rect(slide, cx, 1.6, cw, 0.52, ACCENT1)
txt(slide, h, cx+0.07, 1.63, cw-0.1, 0.45, size=15, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
trows = [
["Overall", "427", "39", "9.1%", "6.5 – 12.3"],
["Urban", "214", "24", "11.2%", "7.4 – 16.4"],
["Semi-urban", "213", "15", "7.0%", "4.1 – 11.5"],
]
for i, row in enumerate(trows):
bg = ACCENT3 if i == 0 else (TABLE_ALT if i % 2 else WHITE)
y = 2.17 + i * 0.82
for j, (val, cw, cx) in enumerate(zip(row, col_w, col_x)):
rect(slide, cx, y, cw, 0.78, bg)
fc = ACCENT1 if i == 0 else DARK_TEXT
txt(slide, val, cx+0.07, y+0.1, cw-0.1, 0.6, size=17, bold=(i==0),
color=fc, align=PP_ALIGN.CENTER)
txt(slide,
"95% CI computed using Wilson score method | PP = Precocious Puberty | Pearson Chi-square (2-tailed) for residence comparison",
0.4, 5.1, 12.5, 0.5, size=13, color=MID_TEXT, italic=True, wrap=True)
rect(slide, 0.4, 5.75, 12.5, 1.1, WHITE)
rect(slide, 0.4, 5.75, 0.15, 1.1, ORANGE)
txt(slide,
"\"Nearly 1 in 10 school girls in Malappuram has questionnaire-assessed PP — "
"consistent with Kerala studies (Binu et al. 10.4%) and Indian urban range (5–12%)\"",
0.7, 5.85, 12, 0.9, size=16, bold=True, color=DARK_TEXT, italic=True, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 28 – SECTION DIVIDER
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
section_div(slide, "05", "Bivariate Analysis", "Risk Factor Associations with PP")
# ════════════════════════════════════════════════════════════════════
# SLIDE 29 – FAMILY HISTORY
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Family History – Strongest Categorical Risk Factor")
rect(slide, 0.4, 1.55, 12.5, 0.68, ACCENT1)
txt(slide, "Chi-square: X² = 12.845 (df=1) | p < 0.001 *** | HIGHLY SIGNIFICANT",
0.6, 1.6, 12.1, 0.58, size=18, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
for i, (grp, pct, n, col) in enumerate([
("POSITIVE Family History\n(n = 79)", "20.3%", "16 of 79 girls had PP", ORANGE),
("NEGATIVE Family History\n(n = 348)", "6.6%", "23 of 348 girls had PP", ACCENT2),
]):
x = 0.8 + i * 6.1
rect(slide, x, 2.4, 5.5, 4.0, WHITE)
rect(slide, x, 2.4, 5.5, 0.55, col)
txt(slide, grp, x+0.1, 2.43, 5.3, 0.5, size=15, bold=True,
color=WHITE, align=PP_ALIGN.CENTER, wrap=True)
txt(slide, pct, x+0.1, 3.0, 5.3, 1.1, size=52, bold=True,
color=col, align=PP_ALIGN.CENTER)
txt(slide, "had PP", x+0.1, 4.08, 5.3, 0.5, size=19, color=DARK_TEXT, align=PP_ALIGN.CENTER)
txt(slide, n, x+0.1, 4.62, 5.3, 0.45, size=15, color=MID_TEXT,
align=PP_ALIGN.CENTER, italic=True)
rect(slide, 0.4, 6.6, 12.5, 0.72, ACCENT3)
txt(slide,
"Girls with positive family history are ~3× more likely to have PP | Adjusted OR = 3.31 (p=0.002)\n"
"Genetic basis: MKRN3, DLK1, KISS1R mutations | Heritability of pubertal timing: 50–80%",
0.6, 6.66, 12.1, 0.62, size=14, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 30 – BMI
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "BMI – Strongest Continuous Risk Factor")
rect(slide, 0.4, 1.55, 12.5, 0.65, ACCENT1)
txt(slide, "Independent Samples t-test: t = 5.670 | p < 0.001 ***",
0.6, 1.6, 12.1, 0.55, size=18, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
for i, (grp, bmi, sd, n, col) in enumerate([
("PP Group", "21.24 kg/m²", "± 3.33", "(n=39)", ORANGE),
("Non-PP Group", "18.89 kg/m²", "± 2.35", "(n=388)", ACCENT2),
]):
x = 0.7 + i * 6.1
rect(slide, x, 2.38, 5.5, 2.8, WHITE)
rect(slide, x, 2.38, 5.5, 0.52, col)
txt(slide, grp, x+0.1, 2.41, 5.3, 0.46, size=17, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
txt(slide, bmi, x+0.1, 2.96, 5.3, 0.95, size=30, bold=True,
color=col, align=PP_ALIGN.CENTER)
txt(slide, "Mean BMI " + sd, x+0.1, 3.9, 5.3, 0.5, size=16, color=DARK_TEXT, align=PP_ALIGN.CENTER)
txt(slide, n, x+0.1, 4.42, 5.3, 0.45, size=14, color=MID_TEXT, align=PP_ALIGN.CENTER)
txt(slide, "BMI Classification vs PP Rate:", 0.4, 5.35, 12, 0.42, size=17, bold=True, color=ACCENT1)
for i, (cls, n, rate, col) in enumerate([
("Underweight\n(< 18.5 kg/m²)", "187 girls", "5.3% PP rate", ACCENT2),
("Normal\n(18.5–24.9 kg/m²)", "233 girls", "10.3% PP rate", ACCENT1),
("Overweight/Obese\n(≥ 25.0)", "7 girls", "71.4% PP rate", ORANGE),
]):
x = 0.4 + i * 4.3
rect(slide, x, 5.85, 4.0, 1.5, WHITE)
rect(slide, x, 5.85, 4.0, 0.1, col)
txt(slide, cls, x+0.1, 5.88, 3.8, 0.6, size=14, bold=True, color=DARK_TEXT, wrap=True)
txt(slide, n + " | " + rate, x+0.1, 6.5, 3.8, 0.55, size=14, bold=True, color=col)
txt(slide, "χ²(2) = 26.08; p < 0.001", 10.5, 7.1, 2.7, 0.35, size=13, color=MID_TEXT, italic=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 31 – AGE AT MENARCHE
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Age at Menarche – Critical Discriminator")
rect(slide, 0.4, 1.55, 12.5, 0.65, ACCENT1)
txt(slide, "t = −13.067 | p < 0.001 *** — Largest Effect Size in the Study",
0.6, 1.6, 12.1, 0.55, size=18, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
for i, (grp, age, sd, col) in enumerate([
("PP Group", "10.00 yrs", "± 0.63 years", ORANGE),
("Non-PP Group", "12.39 yrs", "± 1.12 years", ACCENT2),
]):
x = 0.7 + i * 6.1
rect(slide, x, 2.38, 5.5, 2.8, WHITE)
rect(slide, x, 2.38, 5.5, 0.52, col)
txt(slide, grp, x+0.1, 2.41, 5.3, 0.46, size=17, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
txt(slide, age, x+0.1, 2.95, 5.3, 0.95, size=32, bold=True,
color=col, align=PP_ALIGN.CENTER)
txt(slide, "Mean age at menarche " + sd, x+0.1, 3.9, 5.3, 0.5, size=15,
color=DARK_TEXT, align=PP_ALIGN.CENTER)
txt(slide, "Mean age DIFFERENCE: 2.39 years earlier in PP group",
0.4, 5.4, 12.5, 0.5, size=20, bold=True, color=ACCENT1, align=PP_ALIGN.CENTER)
multiline(slide, [
"Early menarche (< 12 years) defined as the threshold",
"66.6% of menstruating girls in the sample had early menarche",
"Student-reported mean age at first period: 11.72 ± 0.86 years",
"Pearson r = 0.482 (p=0.003) between age at puberty signs & menarche — biologically coherent sequence",
], 0.4, 5.98, 12.5, 1.4, size=16, bullet=True, color=DARK_TEXT)
# ════════════════════════════════════════════════════════════════════
# SLIDE 32 – CHI-SQUARE TABLE
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Bivariate Analysis – Table 4: Categorical Risk Factors (N = 427)")
h_labels = ["Risk Factor", "PP Cases", "No PP", "χ² (df)", "p-value", "Result"]
cw = [3.7, 1.9, 1.9, 2.0, 1.8, 1.7]
cx = [0.3]
for w in cw[:-1]:
cx.append(cx[-1] + w + 0.05)
for j, (h, w, x) in enumerate(zip(h_labels, cw, cx)):
rect(slide, x, 1.6, w, 0.5, ACCENT1)
txt(slide, h, x+0.06, 1.63, w-0.08, 0.44, size=13, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
tdata = [
("Family Hx Early Puberty", "20.3%", "6.6%", "12.845 (1)", "< 0.001", "***"),
("Overweight BMI (≥25 kg/m²)", "71.4%", "~9%", "26.08 (2)", "< 0.001", "***"),
("Residence: Urban vs Semi-urban","11.2%", "7.0%", "1.765 (1)", "0.184", "NS"),
("Screen Time > 2 h/day", "8.7%", "9.7%", "0.031 (1)", "0.860", "NS"),
("Fast Food > 3×/week", "10.2%", "8.3%", "0.258 (1)", "0.611", "NS"),
("Pesticide Exposure", "8.3%", "9.3%", "0.000 (1)", "1.000", "NS"),
("Nuclear vs Joint Family", "N/A", "N/A", "1.12 (1)", "0.290", "NS"),
]
for i, row in enumerate(tdata):
bg = TABLE_ALT if i % 2 == 0 else WHITE
y = 2.15 + i * 0.63
for j, (val, w, x) in enumerate(zip(row, cw, cx)):
rect(slide, x, y, w, 0.6, bg)
fc = ORANGE if val == "***" else DARK_TEXT
bld = j in [0, 5]
txt(slide, val, x+0.06, y+0.07, w-0.08, 0.48, size=13,
bold=bld, color=fc, align=PP_ALIGN.CENTER, wrap=True)
txt(slide, "*** p < 0.001 = Significant | NS = Not Significant (p > 0.05)",
0.3, 6.6, 12.5, 0.4, size=13, color=MID_TEXT, italic=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 33 – T-TEST TABLE
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Continuous Variables – Independent Samples T-Test (Table 5)")
th = ["Variable", "PP Group (n=39)\nMean ± SD", "No-PP (n=388)\nMean ± SD", "t-stat", "p-value", "Result"]
tcw = [3.0, 2.9, 2.9, 1.7, 1.6, 1.5]
tcx = [0.3]
for w in tcw[:-1]:
tcx.append(tcx[-1] + w + 0.05)
for j, (h, w, x) in enumerate(zip(th, tcw, tcx)):
rect(slide, x, 1.6, w, 0.65, ACCENT1)
txt(slide, h, x+0.06, 1.62, w-0.08, 0.6, size=12, bold=True,
color=WHITE, align=PP_ALIGN.CENTER, wrap=True)
trows = [
("Age (years)", "13.28 ± 1.45", "12.98 ± 1.33", "1.316", "0.189", "NS"),
("Age at Menarche (yrs)","10.00 ± 0.63", "12.39 ± 1.12", "−13.067", "< 0.001", "***"),
("BMI (kg/m²)", "21.24 ± 3.33", "18.89 ± 2.35", "5.670", "< 0.001", "***"),
("Height (cm)", "147.8 ± 8.1", "145.1 ± 7.1", "1.980", "0.048", "*"),
("Hrs Outdoors/Day", "1.65 ± 0.80", "1.52 ± 0.82", "0.946", "0.345", "NS"),
]
sc = {"***": ORANGE, "*": ACCENT2, "NS": DARK_TEXT}
for i, row in enumerate(trows):
bg = TABLE_ALT if i % 2 == 0 else WHITE
y = 2.3 + i * 0.82
for j, (val, w, x) in enumerate(zip(row, tcw, tcx)):
rect(slide, x, y, w, 0.78, bg)
fc = sc.get(val, DARK_TEXT) if j == 5 else DARK_TEXT
txt(slide, val, x+0.06, y+0.1, w-0.08, 0.6, size=14,
bold=(j in [0,5]), color=fc, align=PP_ALIGN.CENTER)
txt(slide, "*** p<0.001 | * p<0.05 | NS Not Significant | Independent samples t-test, 2-tailed",
0.3, 6.6, 12.5, 0.4, size=13, color=MID_TEXT, italic=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 34 – ANTHROPOMETRIC PROFILE
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Anthropometric Profile – Table 8")
for i, (lbl, val, rng) in enumerate([
("Mean Height", "145.3 ± 7.2 cm", "Range: 125–168 cm"),
("Mean Weight", "40.5 ± 7.0 kg", "Range: 26–62 kg"),
("Mean BMI", "19.11 ± 2.55 kg/m²","Range: 13.0–28.4 kg/m²"),
]):
x = 0.4 + i * 4.3
rect(slide, x, 1.55, 4.0, 2.3, WHITE)
rect(slide, x, 1.55, 4.0, 0.5, ACCENT1)
txt(slide, lbl, x+0.1, 1.58, 3.8, 0.44, size=15, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
txt(slide, val, x+0.1, 2.1, 3.8, 0.88, size=18, bold=True,
color=ACCENT1, align=PP_ALIGN.CENTER)
txt(slide, rng, x+0.1, 3.0, 3.8, 0.5, size=14, color=MID_TEXT,
align=PP_ALIGN.CENTER, italic=True)
txt(slide, "BMI Classification:", 0.4, 4.0, 12, 0.42, size=17, bold=True, color=ACCENT1)
bmih = ["BMI Category", "Total n", "% of Total", "PP Cases", "PP Rate"]
bmicw = [4.2, 1.7, 1.9, 2.0, 3.3]
bmicx = [0.4]
for w in bmicw[:-1]:
bmicx.append(bmicx[-1] + w + 0.06)
for j, (h, w, x) in enumerate(zip(bmih, bmicw, bmicx)):
rect(slide, x, 4.47, w, 0.46, ACCENT2)
txt(slide, h, x+0.06, 4.5, w-0.08, 0.4, size=13, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
for i, (cls, n, pct, ppc, rate) in enumerate([
("Underweight (< 18.5 kg/m²)", "187", "43.8%", "10", "5.3%"),
("Normal (18.5–24.9 kg/m²)", "233", "54.6%", "24", "10.3%"),
("Overweight/Obese (≥ 25.0 kg/m²)","7", "1.6%", "5", "71.4% ← alarming"),
]):
bg = TABLE_ALT if i % 2 == 0 else WHITE
y = 4.98 + i * 0.62
for val, w, x in zip([cls,n,pct,ppc,rate], bmicw, bmicx):
rect(slide, x, y, w, 0.58, bg)
fc = ORANGE if "alarming" in val else DARK_TEXT
txt(slide, val.replace(" ← alarming",""), x+0.06, y+0.07, w-0.08, 0.47,
size=13, bold=("alarming" in val), color=fc, align=PP_ALIGN.CENTER)
txt(slide, "χ²(2) = 26.08; p < 0.001 | 71.4% PP rate in overweight/obese group — clinically significant",
0.4, 6.85, 12.5, 0.4, size=13, color=ORANGE, bold=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 35 – STUDENT-REPORTED OUTCOMES
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Student-Reported Outcomes – Table 9 (N = 427)")
items_sr = [
("Body changes\nnoticed", "316\n(74.0%)", "Mean age: 11.38 ± 1.18 yrs", ACCENT1),
("First menstrual\nperiod", "296\n(69.3%)", "Mean age: 11.72 ± 0.86 yrs", ACCENT2),
("Early menarche\n(< 12 yrs)", "197\n(66.6%\nof those\nmenstruating)", "High early menarche burden", ORANGE),
("Daily outdoor\nplay", "241\n(56.4%)", "Below WHO recommendations", ACCENT2),
("Screen time\n> 2 h/day", "267\n(62.5%)", "Exceeds WHO 2-hr guideline", ORANGE),
]
for i, (lbl, val, note, col) in enumerate(items_sr):
x = 0.4 + (i % 3) * 4.3
y = 1.6 + (i // 3) * 2.45
rect(slide, x, y, 4.0, 2.2, WHITE)
rect(slide, x, y, 4.0, 0.1, col)
txt(slide, lbl, x+0.12, y+0.17, 3.76, 0.62, size=15, bold=True, color=DARK_TEXT, wrap=True)
txt(slide, val, x+0.12, y+0.85, 3.76, 0.88, size=20, bold=True, color=col, align=PP_ALIGN.CENTER, wrap=True)
txt(slide, note, x+0.12, y+1.75, 3.76, 0.4, size=12, color=MID_TEXT, italic=True, wrap=True)
rect(slide, 0.4, 6.25, 12.5, 0.65, ACCENT3)
txt(slide,
"Pearson r = 0.482 (p=0.003, n=57) between age at puberty signs & age at menarche — confirms biological coherence of sequential pubertal events",
0.6, 6.32, 12.1, 0.52, size=14, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 36 – SUMMARY STATISTICS
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Summary of All Statistical Test Results – Table 11")
sh = ["Variable", "Test Used", "Statistic", "p-value", "Significance"]
scw = [4.4, 2.5, 2.5, 1.9, 1.9]
scx = [0.3]
for w in scw[:-1]:
scx.append(scx[-1] + w + 0.05)
for j, (h, w, x) in enumerate(zip(sh, scw, scx)):
rect(slide, x, 1.6, w, 0.5, ACCENT1)
txt(slide, h, x+0.06, 1.63, w-0.08, 0.44, size=14, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
srows = [
("Family history of early puberty","Chi-square","X²=12.845","< 0.001","***"),
("BMI (continuous)", "t-test", "t=5.67", "< 0.001","***"),
("Age at menarche", "t-test", "t=−13.07", "< 0.001","***"),
("Overweight (BMI ≥ 25)", "Chi-square","X²=26.08", "< 0.001","***"),
("Urban vs Semi-urban", "Chi-square","X²=1.765", "0.184", "NS"),
("Screen time > 2 h/day", "Chi-square","X²=0.031", "0.860", "NS"),
("Fast food > 3×/week", "Chi-square","X²=0.258", "0.611", "NS"),
("Pesticide exposure", "Chi-square","X²=0.000", "1.000", "NS"),
("Nuclear vs Joint family", "Chi-square","X²=1.12", "0.290", "NS"),
("Height (cm)", "t-test", "t=1.980", "0.048", "*"),
]
for i, row in enumerate(srows):
bg = TABLE_ALT if i % 2 == 0 else WHITE
y = 2.15 + i * 0.5
for j, (val, w, x) in enumerate(zip(row, scw, scx)):
rect(slide, x, y, w, 0.47, bg)
fc = ORANGE if val == "***" else (ACCENT2 if val == "*" else DARK_TEXT)
txt(slide, val, x+0.06, y+0.06, w-0.08, 0.38, size=13,
bold=(j in [0,4]), color=fc, align=PP_ALIGN.CENTER)
txt(slide, "*** p < 0.001 | * p < 0.05 | NS = Not Significant (p > 0.05)",
0.3, 7.1, 12.5, 0.35, size=12, color=MID_TEXT, italic=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 37 – SECTION DIVIDER
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
section_div(slide, "06", "Discussion",
"Interpreting Findings in the Broader Evidence Context")
# ════════════════════════════════════════════════════════════════════
# SLIDE 38 – DISCUSSION: PREVALENCE
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Discussion – Prevalence Findings")
rect(slide, 0.4, 1.55, 12.5, 0.65, ACCENT1)
txt(slide, "Our finding: 9.1% (95% CI: 6.5–12.3%) — How does it compare?",
0.6, 1.6, 12.1, 0.55, size=19, bold=True, color=WHITE)
for i, (src, val, col) in enumerate([
("This Study\n(Malappuram, 2026)", "9.1%", ACCENT1),
("Binu et al.\n(Kollam, Kerala)", "10.4%", ACCENT2),
("Indian urban studies\n(Delhi/Mumbai/Kolkata)", "5–12%", ORANGE),
("Western clinical series\n(population-adjusted)", "0.2%", MID_TEXT),
]):
x = 0.4 + i * 3.2
rect(slide, x, 2.38, 3.0, 2.4, WHITE)
rect(slide, x, 2.38, 3.0, 0.52, col)
txt(slide, src, x+0.1, 2.41, 2.8, 0.48, size=13, bold=True,
color=WHITE, align=PP_ALIGN.CENTER, wrap=True)
txt(slide, val, x+0.1, 2.96, 2.8, 0.95, size=30, bold=True,
color=col, align=PP_ALIGN.CENTER)
for i, pt in enumerate([
"Non-significance of urban vs semi-urban (p=0.184) may reflect insufficient power or genuine attenuation in a rapidly urbanising area",
"Higher urban prevalence (11.2%) aligns with urbanisation as a PP risk amplifier via diet, sedentary lifestyle & EDC exposure",
"Higher than Western clinical figures — clinical series underestimate population prevalence",
]):
rect(slide, 0.4, 5.0 + i*0.7, 0.12, 0.55, ORANGE)
txt(slide, pt, 0.68, 5.0 + i*0.7, 12.3, 0.65, size=15, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 39 – DISCUSSION: BMI & FAM HX
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Discussion – BMI & Family History as Independent Predictors")
info_box(slide, "BMI – Mechanism & Evidence",
["Adipose tissue → elevated Leptin → GnRH pulsatility → premature HPG axis activation",
"Elevated insulin & IGF-1 signaling promote early HPG activation",
"Peripheral estrogen synthesis in adipose tissue",
"Adjusted OR = 1.40 per kg/m² unit (p < 0.001) in our study",
"Consistent with Wang et al. 2025 meta-analysis & Shi et al. 2022",
"71.4% PP rate in overweight group — clinically striking despite small n"],
0.4, 1.55, 6.0, 4.3, hcol=ORANGE)
info_box(slide, "Family History – Genetic Basis",
["Heritability of pubertal timing: 50–80% (literature consensus)",
"Adjusted OR = 3.31 (p=0.002) — strongest independent predictor",
"Genes implicated: MKRN3, DLK1, KISS1R (Kentistou et al. 2024)",
"20.3% PP positive vs only 6.6% negative family history",
"Non-modifiable risk factor — BUT highly actionable as a screening criterion",
"Girls with family history warrant earlier monitoring & referral"],
6.8, 1.55, 6.1, 4.3, hcol=ACCENT1)
rect(slide, 0.4, 6.0, 12.5, 0.85, ACCENT3)
txt(slide,
"Both BMI and family history are the TWO strongest independent predictors in logistic regression. "
"Together they account for the majority of attributable risk in this sample.",
0.6, 6.07, 12.1, 0.72, size=15, bold=True, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 40 – DISCUSSION: DIET/SCREEN/PESTICIDES
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Discussion – Diet, Screen Time & Pesticide Exposure")
for i, (title, pts, col) in enumerate([
("Dietary Patterns\n(Non-significant, p=0.61)",
["Fast food > 3×/week: 46.1% of sample",
"Processed food: 51.5% — alarming prevalence",
"Study underpowered for dietary subgroup analysis",
"Binary coding fails to capture dose-response",
"Phthalate/BPA pathway needs future urinary measurement"],
ORANGE),
("Screen Time\n(Non-significant, p=0.86)",
["59.0% had > 2 hrs/day (parent); 62.5% student report",
"Both exceed WHO 2-hr guideline for school-age children",
"Pathway: obesity, circadian melatonin disruption",
"Binary measurement insufficient for dose-response",
"Public health concern regardless of statistical significance"],
ACCENT2),
("Pesticide Exposure\n(Non-significant, p=1.00)",
["14.1% pesticide/chemical exposure reported",
"Binary variable — no type, duration or quantity data",
"Irumbuzhi site has active agricultural activity",
"Future: urinary organochlorine & phthalate measurement",
"Exposure likely underestimated with current tool"],
ACCENT1),
]):
x = 0.4 + i * 4.3
rect(slide, x, 1.55, 4.0, 5.5, WHITE)
rect(slide, x, 1.55, 4.0, 0.62, col)
txt(slide, title, x+0.1, 1.58, 3.8, 0.58, size=14, bold=True,
color=WHITE, wrap=True)
multiline(slide, pts, x+0.1, 2.28, 3.8, 4.65, size=14, bullet=True)
txt(slide,
"Absence of significance ≠ Absence of effect | Study was powered for prevalence estimation, not for dietary subgroup analyses",
0.4, 7.1, 12.5, 0.37, size=13, color=ORANGE, italic=True, bold=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 41 – SECTION DIVIDER
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
section_div(slide, "07", "Conclusion & Recommendations",
"Evidence-Based Action Plan")
# ════════════════════════════════════════════════════════════════════
# SLIDE 42 – CONCLUSION
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Conclusion – Key Takeaways")
for i, (stat, desc, col) in enumerate([
("9.1%", "Questionnaire-assessed PP prevalence — nearly 1 in 10 school girls in Malappuram", ACCENT1),
("OR 3.31", "Positive family history — strongest independent predictor (p=0.002)", ORANGE),
("OR 1.40", "BMI per unit — key modifiable risk factor (p < 0.001)", ACCENT2),
("10.0 yrs","Mean age at menarche in PP cases vs 12.39 yrs in controls — a 2.39-year difference", ORANGE),
("71.4%", "PP rate in overweight/obese girls — highest proportional burden by BMI group", ACCENT1),
]):
rect(slide, 0.4, 1.65 + i*0.96, 2.2, 0.82, col)
txt(slide, stat, 0.5, 1.7 + i*0.96, 2.0, 0.72, size=22, bold=True,
color=WHITE, align=PP_ALIGN.CENTER)
rect(slide, 2.65, 1.65 + i*0.96, 10.3, 0.82, WHITE)
txt(slide, desc, 2.8, 1.73 + i*0.96, 10.0, 0.68, size=16, color=DARK_TEXT, wrap=True)
rect(slide, 0.4, 6.55, 12.5, 0.72, ACCENT1)
txt(slide,
"Findings are consistent with international literature and underscore an urgent public health need "
"for school-based screening & intervention in Malappuram district.",
0.6, 6.62, 12.1, 0.6, size=15, bold=True, color=WHITE, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 43 – RECOMMENDATIONS: SCHOOLS
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Recommendations – School Health Programs")
rect(slide, 0.4, 1.55, 12.5, 0.55, ACCENT2)
txt(slide, "TARGET: SCHOOLS & EDUCATIONAL INSTITUTIONS",
0.6, 1.6, 12.1, 0.46, size=17, bold=True, color=WHITE)
for i, (title, desc, col) in enumerate([
("Annual Anthropometric Monitoring",
"Mandatory annual height, weight & BMI measurement from Standard 5 onwards in all government and private schools",
ACCENT1),
("Puberty Education Curriculum",
"Age-appropriate puberty education modules for both students AND parents; address body changes, nutrition & when to seek medical help",
ACCENT2),
("School Health Nurse Training",
"Train school health nurses & teachers to identify early pubertal signs and facilitate timely medical referral pathways",
ORANGE),
("Nutritional Interventions",
"Promote healthy canteen policies; restrict ultra-processed food & fast food; encourage physical activity during school hours",
ACCENT1),
]):
x = 0.4 + (i % 2) * 6.4
y = 2.25 + (i // 2) * 2.25
rect(slide, x, y, 6.0, 2.1, WHITE)
rect(slide, x, y, 6.0, 0.55, col)
txt(slide, title, x+0.12, y+0.07, 5.76, 0.48, size=16, bold=True, color=WHITE, wrap=True)
txt(slide, desc, x+0.15, y+0.68, 5.7, 1.3, size=15, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 44 – RECOMMENDATIONS: CLINICIANS & POLICY
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Recommendations – Clinicians & Policy Makers")
info_box(slide, "For Clinicians & Healthcare Providers",
["Girls with BMI ≥ 23 kg/m² or positive family history → proactive paediatric endocrinology screening",
"Standardised PP evaluation: Tanner staging + bone age X-ray + LH/FSH assessment",
"Incorporate into district-level child health programmes",
"Systematic early referral from primary care to paediatric endocrinology"],
0.4, 1.55, 6.0, 3.3, hcol=ACCENT1)
info_box(slide, "For Policy Makers",
["Strengthen regulation of food marketing to children in school canteens",
"Restrict fast food & ultra-processed food advertising targeting children",
"Promote reduction of agrochemical use in peri-urban areas near schools",
"Fund longitudinal cohort study — PP, BMI trajectories & long-term outcomes in Kerala"],
6.8, 1.55, 6.1, 3.3, hcol=ACCENT2)
info_box(slide, "For Future Research",
["Hormonal profiling (LH, FSH, estradiol) of screen-positive cases to confirm HPG axis activation",
"Urinary phthalate & BPA measurement to quantify EDC exposure objectively",
"Qualitative research on family perceptions & healthcare-seeking behaviour",
"Multi-district Kerala study for generalisable prevalence estimates"],
0.4, 5.05, 12.5, 2.2, hcol=ORANGE, ts=14)
# ════════════════════════════════════════════════════════════════════
# SLIDE 45 – LIMITATIONS
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Limitations")
lims = [
("Cross-sectional Design", "Causal inference not possible — direction of associations between BMI, dietary patterns & PP cannot be definitively established"),
("Self-Reported Dietary Data", "Parent-reported dietary information subject to recall bias & social desirability bias"),
("Binary Exposure Variables", "Most risk factors coded dichotomously (Yes/No) — reduces power & fails to capture dose-response"),
("No Hormonal Confirmation", "Laboratory confirmation of HPG axis activation (LH, FSH, estradiol) not performed"),
("Doctor Confirmation Bias", "Urban/educated families may be more likely to seek consultation — ascertainment bias"),
("Pesticide Classification", "Binary variable without type, duration or quantity — limits detection of associations"),
("Generalisability", "Findings specific to Malappuram district — may not be generalisable to other regions"),
]
for i, (lim, desc) in enumerate(lims):
y = 1.58 + i * 0.72
col = [ORANGE, ACCENT2, ACCENT1, ORANGE, ACCENT2, ACCENT1, ORANGE][i]
rect(slide, 0.4, y, 3.3, 0.62, col)
txt(slide, lim, 0.5, y+0.07, 3.15, 0.52, size=13, bold=True, color=WHITE, wrap=True)
rect(slide, 3.75, y, 9.2, 0.62, WHITE)
txt(slide, desc, 3.85, y+0.08, 9.0, 0.5, size=14, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 46 – REFERENCES
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Key References")
refs = [
"Wang Y et al. (2025). Risk factors for PP: systematic review & meta-analysis. Psychoneuroendocrinology, 167:107427.",
"Cheuiche AV et al. (2021). Diagnosis & management of precocious sexual maturation. Eur J Pediatr, 180:3073–87.",
"Shi L et al. (2022). Childhood obesity & central precocious puberty. Front Endocrinol, 13:1056871.",
"Lopez-Rodriguez D et al. (2021). EDCs & their effects on puberty. Best Pract Res Clin Endocrinol Metab, 35:101579.",
"Soliman AT et al. (2023). Long-term consequences of CPP. Acta Biomed, 94(6):e2023209.",
"Kentistou KA et al. (2024). Genetic complexity of puberty timing. Nat Genet, 56(7):1209–1219.",
"Calcaterra V et al. (2024). Phthalates, bisphenol & precocious puberty. Nutrients, 16(16):2732.",
"Gonc EN & Kandemir N (2022). Body composition in sexual precocity. Curr Opin Endocrinol, 29(1):71–79.",
"Coelho e Oliveira K et al. (2026). Obesity-puberty interaction. Endocr Connect, 15(3):e250052.",
"Dinkelbach L et al. (2025). CPP & psychiatric disorders. JAMA Netw Open, 8(6):e2517004.",
"Binu J et al. Kerala schoolgirls study (Kollam) — PP prevalence 10.4%.",
]
for i, r in enumerate(refs):
col = [ACCENT1, ACCENT2, ORANGE, ACCENT1][i % 4]
rect(slide, 0.4, 1.6 + i*0.49, 0.32, 0.43, col)
txt(slide, r, 0.82, 1.6 + i*0.49, 12.1, 0.44, size=12, color=DARK_TEXT, wrap=True)
# ════════════════════════════════════════════════════════════════════
# SLIDE 47 – STUDY TEAM
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
header(slide, "Study Team")
rect(slide, 0.4, 1.55, 12.5, 0.56, ACCENT1)
txt(slide, "Principal Investigator", 0.6, 1.58, 3.9, 0.5, size=14, bold=True, color=WHITE)
txt(slide, "Sariga M G — Third Year MBBS, Government Medical College Manjeri (2023 Batch)",
4.6, 1.6, 8.0, 0.46, size=14, color=WHITE)
rect(slide, 0.4, 2.2, 12.5, 0.52, ACCENT2)
txt(slide, "Guides", 0.6, 2.23, 3.0, 0.45, size=14, bold=True, color=WHITE)
txt(slide,
"Dr. Sabitha Rose Jacob, MD — Associate Professor (CAP) | Dr. Remiza Rayikkal Answar, MD — Assistant Professor",
3.8, 2.25, 9.0, 0.44, size=13, color=WHITE)
txt(slide, "Co-Investigators (2023 MBBS Batch):", 0.5, 2.87, 12, 0.42, size=15, bold=True, color=ACCENT1)
co_inv = ["SP Keerthana","Krishna N","Rajkumar Barwal","Sabah Rahman","Nahnu Rinsha P",
"Ramgopal K","Rimjhim Merotha","Roshani Kumari Jatav","Shifana M","Shifana Nasrin",
"Shinsiya Sherin PP","Sideeque Ali","Suman Meena","Vivek T","Aiswarya T K"]
for i, name in enumerate(co_inv):
x = 0.5 + (i % 5) * 2.55
y = 3.38 + (i // 5) * 0.68
rect(slide, x, y, 2.35, 0.55, WHITE)
rect(slide, x, y, 2.35, 0.07, ACCENT2)
txt(slide, name, x+0.08, y+0.1, 2.2, 0.42, size=13, color=DARK_TEXT)
rect(slide, 0.5, 5.6, 12.3, 0.07, ACCENT2)
txt(slide,
"Department of Community Medicine | Government Medical College Manjeri\n"
"IEC Ref. No.: IEC/GMCM/204/2026 | IRC Approval No.: IRC/GMCM/313",
0.5, 5.75, 12.3, 0.72, size=14, color=MID_TEXT, align=PP_ALIGN.CENTER)
# ════════════════════════════════════════════════════════════════════
# SLIDE 48 – THANK YOU
# ════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
rect(slide, 0, 0, 13.333, 7.5, WHITE)
rect(slide, 0, 0, 13.333, 3.2, ACCENT3)
rect(slide, 0, 3.2, 13.333, 0.1, ACCENT1)
txt(slide, "THANK YOU", 0.5, 0.6, 12.333, 1.55, size=70, bold=True,
color=ACCENT1, align=PP_ALIGN.CENTER)
txt(slide, "for your time and attention",
0.5, 2.1, 12.333, 0.62, size=22, color=MID_TEXT, align=PP_ALIGN.CENTER, italic=True)
txt(slide,
"\"Nearly 1 in 10 school girls in Malappuram has precocious puberty.\n"
"BMI and family history are the most actionable risk factors.\n"
"School-based screening programs and early referral pathways are urgently needed.\"",
1.0, 3.55, 11.333, 2.0, size=18, color=DARK_TEXT, align=PP_ALIGN.CENTER, wrap=True, italic=True)
txt(slide, "Open for Questions & Discussion",
1.0, 5.7, 11.333, 0.62, size=20, bold=True, color=ACCENT1, align=PP_ALIGN.CENTER)
txt(slide,
"Prevalence of Precocious Puberty Among School Girls | GMC Manjeri | 2025–2026",
0.5, 6.85, 12.333, 0.42, size=13, color=MID_TEXT, align=PP_ALIGN.CENTER)
# ── SAVE ─────────────────────────────────────────────────────────────
out = "/tmp/workspace/precocious-puberty-ppt/Precocious_Puberty_Light_v2.pptx"
prs.save(out)
print(f"Saved: {out}")
print(f"Total slides: {len(prs.slides)}")
Is it over
cd /tmp/workspace/precocious-puberty-ppt && python3 build_ppt_v2.py
Precocious Puberty Light v2
Presentation · PPTX
| Element | Old (Dark) | New (Light) |
|---|---|---|
| Slide background | Dark navy | White / warm cream |
| Header band | Dark navy fill | Very light green (mint) fill |
| Primary accent | Dark blue | Deep forest green |
| Sub-accent | Teal | Medium green |
| Body text color | White on dark | Near-black on light |
| Table rows | Dark fills | White / light green alternating |
| Section dividers | Full dark navy slide | Soft mint green slide |
| Font sizes | 13–18 pt body | 14–19 pt body (larger throughout) |
| Highlight/significant | Orange (kept) | Orange (kept for contrast) |
I first slide remove principal investigator and guide names ,can you change colour of slide to some other mild colour
python3 << 'EOF' from pptx import Presentation from pptx.util import Inches, Pt from pptx.dml.color import RGBColor from pptx.enum.text import PP_ALIGN prs = Presentation("/tmp/workspace/precocious-puberty-ppt/Precocious_Puberty_Light_v2.pptx") blank = prs.slide_layouts[6] # New mild colour palette for title slide # Soft lavender-blue / dusty mauve academic feel TITLE_TOP = RGBColor(0xE8, 0xEA, 0xF6) # very soft periwinkle/lavender top band TITLE_BOTTOM = RGBColor(0xF5, 0xF5, 0xF0) # warm off-white bottom ACCENT_LINE = RGBColor(0x5C, 0x6B, 0xC0) # muted indigo accent line HEADING_COL = RGBColor(0x3D, 0x4E, 0xAA) # soft indigo for main title SUBTEXT = RGBColor(0x4A, 0x4A, 0x6A) # dark slate for subtitle BODY_TEXT = RGBColor(0x33, 0x33, 0x44) # near-black body WHITE = RGBColor(0xFF, 0xFF, 0xFF) # ── Rebuild slide 1 from scratch ────────────────────────────────── from pptx.util import Inches, Pt from copy import deepcopy # Remove all shapes from slide 1 and rebuild slide = prs.slides[0] sp_list = list(slide.shapes) for sp in sp_list: sp._element.getparent().remove(sp._element) def rect(slide, l, t, w, h, color): s = slide.shapes.add_shape(1, Inches(l), Inches(t), Inches(w), Inches(h)) s.fill.solid(); s.fill.fore_color.rgb = color s.line.fill.background() return s def txt(slide, text, l, t, w, h, size=18, bold=False, color=BODY_TEXT, align=PP_ALIGN.LEFT, italic=False, wrap=True): tb = slide.shapes.add_textbox(Inches(l), Inches(t), Inches(w), Inches(h)) tf = tb.text_frame; tf.word_wrap = wrap p = tf.paragraphs[0]; p.alignment = align r = p.add_run(); r.text = text r.font.size = Pt(size); r.font.bold = bold r.font.italic = italic; r.font.color.rgb = color return tb # Background rect(slide, 0, 0, 13.333, 7.5, TITLE_BOTTOM) # Top band — soft lavender rect(slide, 0, 0, 13.333, 4.2, TITLE_TOP) # Accent divider line rect(slide, 0, 4.2, 13.333, 0.08, ACCENT_LINE) # Left decorative bar rect(slide, 0, 0, 0.18, 4.2, ACCENT_LINE) # Main title txt(slide, "PREVALENCE OF PRECOCIOUS PUBERTY", 0.5, 0.55, 12.3, 1.0, size=36, bold=True, color=HEADING_COL, align=PP_ALIGN.CENTER) txt(slide, "AMONG SCHOOL GIRLS", 0.5, 1.5, 12.3, 0.75, size=30, bold=True, color=SUBTEXT, align=PP_ALIGN.CENTER) # Subtitle txt(slide, "A Cross-Sectional Study in Manjeri and Anakkayam, Malappuram District, Kerala, India", 0.8, 2.38, 11.7, 0.6, size=18, color=SUBTEXT, align=PP_ALIGN.CENTER, italic=True) # Thin separator inside top band rect(slide, 2.0, 3.2, 9.333, 0.04, ACCENT_LINE) # Bottom section — institutional info only (no names) txt(slide, "Department of Community Medicine", 0.5, 4.4, 12.3, 0.52, size=18, bold=True, color=BODY_TEXT, align=PP_ALIGN.CENTER) txt(slide, "Government Medical College Manjeri", 0.5, 4.9, 12.3, 0.48, size=17, bold=True, color=BODY_TEXT, align=PP_ALIGN.CENTER) txt(slide, "Academic Year 2025–2026", 0.5, 5.42, 12.3, 0.42, size=16, color=SUBTEXT, align=PP_ALIGN.CENTER) txt(slide, "IEC Ref. No.: IEC/GMCM/204/2026 | IRC Approval No.: IRC/GMCM/313", 0.5, 5.88, 12.3, 0.4, size=14, color=SUBTEXT, align=PP_ALIGN.CENTER, italic=True) out = "/tmp/workspace/precocious-puberty-ppt/Precocious_Puberty_Light_v3.pptx" prs.save(out) print(f"Saved: {out}") print(f"Total slides: {len(prs.slides)}") EOF
Precocious Puberty Light v3
Presentation · PPTX
If an open defence is asked in my department from my professors what could be the possible questions and it's answers,give it ina downloadable pdf.ibdont know even basic concepts about this study can you explain as a qns answer pdf in detail
python3 << 'PYEOF' 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, HRFlowable, Table, TableStyle, PageBreak) from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY out = "/tmp/workspace/precocious-puberty-ppt/Open_Defence_QA.pdf" doc = SimpleDocTemplate(out, pagesize=A4, leftMargin=2*cm, rightMargin=2*cm, topMargin=2.2*cm, bottomMargin=2*cm) # ── Styles ──────────────────────────────────────────────────────── INDIGO = colors.HexColor("#3D4EAA") DINDIGO = colors.HexColor("#2B3580") ORANGE = colors.HexColor("#E65C00") GREEN = colors.HexColor("#2E7D32") LGREY = colors.HexColor("#F5F5F0") MGREY = colors.HexColor("#EEEEEE") BLACK = colors.HexColor("#1C1C1C") TEAL = colors.HexColor("#00796B") styles = getSampleStyleSheet() cover_title = ParagraphStyle("cover_title", fontSize=22, leading=28, textColor=DINDIGO, alignment=TA_CENTER, fontName="Helvetica-Bold", spaceAfter=6) cover_sub = ParagraphStyle("cover_sub", fontSize=13, leading=18, textColor=colors.HexColor("#444466"), alignment=TA_CENTER, fontName="Helvetica", spaceAfter=4) cover_inst = ParagraphStyle("cover_inst", fontSize=11, leading=16, textColor=colors.HexColor("#555555"), alignment=TA_CENTER, fontName="Helvetica") sec_head = ParagraphStyle("sec_head", fontSize=15, leading=20, textColor=WHITE if False else DINDIGO, fontName="Helvetica-Bold", spaceAfter=4, spaceBefore=14, borderPad=4) q_style = ParagraphStyle("q_style", fontSize=12, leading=17, textColor=DINDIGO, fontName="Helvetica-Bold", spaceAfter=3, spaceBefore=10, leftIndent=0, borderPad=3) a_style = ParagraphStyle("a_style", fontSize=11, leading=17, textColor=BLACK, fontName="Helvetica", spaceAfter=6, spaceBefore=2, alignment=TA_JUSTIFY, leftIndent=14) note_style = ParagraphStyle("note_style", fontSize=10, leading=14, textColor=TEAL, fontName="Helvetica-Oblique", spaceAfter=4, leftIndent=14) bullet_style = ParagraphStyle("bullet_style", fontSize=11, leading=16, textColor=BLACK, fontName="Helvetica", spaceAfter=2, leftIndent=28, bulletIndent=14) label_style = ParagraphStyle("label_style", fontSize=10, leading=14, textColor=GREEN, fontName="Helvetica-Bold", spaceAfter=1, leftIndent=14) WHITE = colors.white def section_header(title): return [ Spacer(1, 0.3*cm), Table([[Paragraph(title, ParagraphStyle("sh", fontSize=14, leading=18, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_LEFT))]], colWidths=[17*cm], style=TableStyle([ ("BACKGROUND", (0,0), (-1,-1), INDIGO), ("TOPPADDING", (0,0), (-1,-1), 7), ("BOTTOMPADDING",(0,0),(-1,-1), 7), ("LEFTPADDING", (0,0), (-1,-1), 10), ("RIGHTPADDING",(0,0), (-1,-1), 10), ])), Spacer(1, 0.2*cm), ] def qna(num, question, answer, tip=None, bullets=None): items = [] items.append(Paragraph(f"Q{num}. {question}", q_style)) items.append(Paragraph(answer, a_style)) if bullets: for b in bullets: items.append(Paragraph(f"• {b}", bullet_style)) if tip: items.append(Paragraph(f"Tip for defence: {tip}", note_style)) items.append(HRFlowable(width="100%", thickness=0.4, color=colors.HexColor("#CCCCDD"), spaceAfter=2)) return items story = [] # ══ COVER PAGE ═════════════════════════════════════════════════════ story.append(Spacer(1, 1.5*cm)) story.append(Paragraph("OPEN DEFENCE PREPARATION GUIDE", cover_title)) story.append(Spacer(1, 0.3*cm)) story.append(Paragraph("Possible Questions & Detailed Answers", cover_sub)) story.append(Spacer(1, 0.4*cm)) story.append(HRFlowable(width="100%", thickness=1.5, color=INDIGO, spaceAfter=10)) story.append(Paragraph( "Prevalence of Precocious Puberty Among School Girls<br/>" "A Cross-Sectional Study — Malappuram District, Kerala", ParagraphStyle("ct2", fontSize=14, leading=20, textColor=DINDIGO, alignment=TA_CENTER, fontName="Helvetica-Bold", spaceAfter=6))) story.append(HRFlowable(width="100%", thickness=1.5, color=INDIGO, spaceAfter=10)) story.append(Paragraph("Department of Community Medicine", cover_inst)) story.append(Paragraph("Government Medical College Manjeri | 2025–2026", cover_inst)) story.append(Spacer(1, 0.6*cm)) story.append(Paragraph( "This document covers 60+ likely defence questions across all major sections of the study — " "from basic concepts to methodology, statistics, results, and critical thinking. " "Each answer is written in plain language so you can understand, learn, and speak confidently.", ParagraphStyle("intro", fontSize=11, leading=16, textColor=colors.HexColor("#333355"), alignment=TA_JUSTIFY, fontName="Helvetica", spaceAfter=6, borderPad=8, backColor=LGREY, leftIndent=8, rightIndent=8))) story.append(PageBreak()) # ══ SECTION 1: BASIC CONCEPTS ══════════════════════════════════════ story += section_header("SECTION 1: Basic Concepts — What is Precocious Puberty?") story += qna(1, "What is puberty? Explain briefly in your own words.", "Puberty is the biological process through which a child's body becomes capable of sexual reproduction. " "It involves a series of physical changes driven by hormones. In girls, these changes include breast development, " "growth of pubic and underarm hair, a growth spurt in height, and the start of menstrual periods (menarche). " "These changes are triggered by the brain releasing hormones that tell the ovaries to produce estrogen.", tip="Keep it simple. Think of puberty as the 'switch-on' of the reproductive system.") story += qna(2, "What is precocious puberty (PP)?", "Precocious puberty means puberty starts TOO EARLY — before the expected age. " "In girls, this is defined as the appearance of secondary sexual characteristics (like breast development, " "pubic hair, or menstruation) before the age of 8 years. In boys, it is before age 9. " "The word 'precocious' simply means 'early.' Think of it as the reproductive system switching on too soon.", tip="Remember the key number: age 8 in girls. Any puberty sign appearing before age 8 = precocious puberty.") story += qna(3, "What are secondary sexual characteristics?", "These are the physical features that develop during puberty, but are NOT directly involved in reproduction. " "In girls they include: (1) Thelarche — breast development, (2) Pubarche — pubic hair growth, " "(3) Axillary hair — underarm hair, (4) Menarche — first menstrual period, and (5) a growth spurt. " "They are called 'secondary' because the primary sexual characteristics (ovaries, uterus) are present from birth.", tip="You can be asked to list them — practise saying: thelarche, pubarche, axillary hair, menarche.") story += qna(4, "What is the normal age range for puberty in girls?", "Normal puberty in girls begins between 8 and 13 years of age. The first sign is usually breast development (thelarche). " "Menarche (first period) typically occurs about 2–3 years after thelarche, usually between ages 10 and 14. " "The entire pubertal process from first sign to completion takes about 2–5 years.", tip="Normal range = 8 to 13 years. Before 8 = precocious. After 13 = delayed puberty.") story += qna(5, "What is thelarche, pubarche, and menarche?", "These are the three key milestones of female puberty:\n" "• Thelarche: The first sign of breast development. It marks the onset of puberty in most girls.\n" "• Pubarche: The appearance of pubic hair (hair in the pubic area). Often appears around the same time as thelarche.\n" "• Menarche: The very first menstrual period. This is usually the LAST major milestone of puberty, " "occurring about 2 years after thelarche.", tip="These are Greek-origin medical terms. 'Arche' means beginning. Professors love asking this.") story += qna(6, "What is the HPG axis? Why is it important in precocious puberty?", "HPG stands for Hypothalamic-Pituitary-Gonadal axis. It is the hormonal control system for puberty and reproduction. " "Here is how it works in sequence: " "(1) The HYPOTHALAMUS (a part of the brain) releases a hormone called GnRH (Gonadotropin-Releasing Hormone). " "(2) GnRH signals the PITUITARY GLAND (also in the brain) to release two hormones: LH (Luteinizing Hormone) and FSH (Follicle-Stimulating Hormone). " "(3) LH and FSH travel through the blood to the GONADS (ovaries in girls), telling them to produce SEX HORMONES like estrogen. " "(4) Estrogen causes the physical changes of puberty. " "In precocious puberty, this entire axis is ACTIVATED TOO EARLY, causing physical changes before age 8.", tip="Draw this as a simple flowchart in your mind: Brain (hypothalamus) → Pituitary → Ovaries → Estrogen → Puberty changes.") story += qna(7, "What is Central Precocious Puberty (CPP)? How is it different from Peripheral PP?", "CENTRAL Precocious Puberty (CPP): The HPG axis is activated prematurely. The brain (hypothalamus) sends the GnRH signal too early. " "This is the most common type. In girls, most CPP is IDIOPATHIC (no identifiable cause found). " "It is GnRH-dependent and responds to treatment with GnRH analogues (GnRHa).\n\n" "PERIPHERAL Precocious Puberty: Sex hormones (estrogen) are produced WITHOUT activation of the HPG axis. " "The ovaries, adrenal glands, or an external source produces estrogen independently. " "This type is GnRH-independent and does NOT respond to GnRHa. Causes include ovarian cysts, tumours, or accidental exposure to estrogen-containing creams.", tip="Key difference: Central = brain switches on early. Peripheral = hormones come from elsewhere, brain not involved.") story += qna(8, "What causes precocious puberty?", "Precocious puberty is multifactorial — many factors can contribute together:", bullets=[ "Genetic factors: Mutations in genes like MKRN3, DLK1, and KISS1R are linked to familial (family-based) PP. Puberty timing is 50-80% heritable.", "Obesity / High BMI: Excess fat tissue produces leptin, which activates the HPG axis prematurely. Fat also produces estrogen.", "Environmental Endocrine Disruptors (EDCs): Chemicals like phthalates (in plastics), Bisphenol A (BPA), and pesticides mimic hormones and disrupt the endocrine system.", "Nutrition transition: High calorie diets, fast food, and processed food accelerate growth and hormonal changes.", "Sedentary lifestyle and high screen time: Promotes obesity, which is a key driver.", "Stress and psychosocial factors: Stressful home environments may trigger early HPG activation.", "Idiopathic: In many girls, especially with Central PP, no specific cause is ever found.", ], tip="Professors often ask 'what are the risk factors?' — BMI and family history are your two strongest answers.") story += qna(9, "What is GnRH? What are GnRH analogues used for?", "GnRH = Gonadotropin-Releasing Hormone. It is the hormone released by the hypothalamus that starts the puberty cascade. " "GnRH analogues (GnRHa) are synthetic drugs that mimic GnRH but, when given continuously, they SUPPRESS the pituitary gland — " "effectively pausing puberty. They are the standard treatment for Central Precocious Puberty. " "Examples include leuprolide and triptorelin, given as monthly injections. When treatment is stopped, puberty resumes normally.", tip="GnRHa = puberty pause button. Very important treatment concept.") story += qna(10, "What are the long-term consequences of untreated precocious puberty?", "If precocious puberty is not identified and managed, several long-term problems can occur:", bullets=[ "Short stature: Bones mature too fast and the growth plates close early, resulting in shorter final adult height.", "Psychosocial problems: Children with PP look older than their peers, leading to body image issues, anxiety, depression, and bullying.", "Early sexual activity risks: Physical maturity ahead of emotional maturity creates vulnerability.", "Increased cancer risk: Early and prolonged estrogen exposure raises the lifetime risk of breast and ovarian cancers.", "Metabolic syndrome: Increased risk of obesity, type 2 diabetes, and cardiovascular disease in adulthood.", "Polycystic Ovarian Syndrome (PCOS): More common in women who had early puberty.", "Psychiatric disorders: Recent 2025 evidence (Dinkelbach et al.) links CPP with depression and ADHD.", ], tip="A very likely exam question. Memorise at least 5 consequences.") story.append(PageBreak()) # ══ SECTION 2: STUDY DESIGN ════════════════════════════════════════ story += section_header("SECTION 2: Study Design & Methodology") story += qna(11, "What type of study did you conduct? Why did you choose this design?", "We conducted a SCHOOL-BASED CROSS-SECTIONAL STUDY. " "A cross-sectional study collects data from a population at ONE SINGLE POINT IN TIME — like a 'snapshot.' " "We chose this design because: " "(1) It is the most appropriate design for estimating the PREVALENCE of a condition in a population. " "(2) It is resource-efficient — we did not need to follow participants over time. " "(3) It allows us to study associations between the disease (PP) and multiple risk factors simultaneously. " "(4) It is ethically suitable — no intervention or follow-up burden on participants.", tip="Cross-sectional = snapshot study = prevalence study. This is the most common design in community medicine.") story += qna(12, "What is prevalence? How is it different from incidence?", "PREVALENCE is the proportion of a population that HAS a disease or condition at a specific point in time. " "Formula: Prevalence = (Number of existing cases) / (Total population studied) × 100. " "In our study: 39/427 × 100 = 9.1%.\n\n" "INCIDENCE is the proportion of a population that DEVELOPS a NEW disease over a period of time. " "It measures the RATE of new cases.\n\n" "Key difference: Prevalence = existing cases (snapshot). Incidence = new cases (over time). " "Cross-sectional studies measure PREVALENCE; cohort studies measure INCIDENCE.", tip="This is a fundamental concept in community medicine. You WILL be asked this.") story += qna(13, "Where was the study conducted? Why were these sites chosen?", "The study was conducted across THREE SCHOOLS in Malappuram District, Kerala:\n" "1. Benchmark International School, Manjeri (Urban)\n" "2. Government Higher Secondary School (Girls), Manjeri (Urban)\n" "3. Government Higher Secondary School, Irumbuzhi, Anakkayam (Semi-urban/Rural)\n\n" "These sites were chosen to represent TWO DIFFERENT SETTINGS — urban and semi-urban — " "allowing us to compare PP prevalence across the urban-rural continuum. " "Malappuram was specifically chosen because district-level data were scarce and it represents a rapidly urbanising area with simultaneous agricultural activity (pesticide exposure).", tip="Know your study setting well — location, type of school, and the rationale for site selection.") story += qna(14, "Who were the study participants? What were the inclusion and exclusion criteria?", "Study population: Female students aged 10–15 years (Standards 6–9) in the selected schools.\n\n" "INCLUSION CRITERIA:\n" "• Female students aged 10–15 years\n" "• Enrolled in Standards 6–9 during the study period\n" "• Parent/guardian written informed consent obtained\n" "• Student verbal assent obtained\n\n" "EXCLUSION CRITERIA:\n" "• Girls whose parents refused consent\n" "• Girls who declined to participate themselves\n" "• No categorical exclusions based on illness — all girls including those with chronic illness were included to capture the full spectrum.", tip="Why age 10–15? Because by 10 years, any PP would already be clinically observable and reportable.") story += qna(15, "How did you calculate the sample size? What formula was used?", "We used the formula for estimating a single proportion:\n" "n = Z²α/2 × P(1−P) / d²\n\n" "Where:\n" "• Z = 1.96 (for 95% confidence level)\n" "• P = 0.10 (expected prevalence of 10%, based on previous Kerala studies)\n" "• d = 0.03 (precision/allowable error of 3%)\n\n" "This gave a base sample size of approximately 384. " "We added 10% for non-response, giving a final calculated sample size of ~422. " "We enrolled 427 girls, exceeding this requirement. All 427 had complete data — 100% completion rate.", tip="Know the formula. Professors will ask what P you used and why. Answer: 10% based on Binu et al. from Kollam, Kerala.") story += qna(16, "What sampling technique did you use? Explain multi-stage sampling.", "We used MULTI-STAGE RANDOM SAMPLING:\n\n" "STAGE 1 — School Selection: Schools were PURPOSIVELY selected to represent urban (Manjeri) and semi-urban (Anakkayam) strata. " "This was purposive, not random, to ensure both settings were represented.\n\n" "STAGE 2 — Student Selection: Within each school, SYSTEMATIC RANDOM SAMPLING was used. " "This means students were selected from class rolls at regular intervals (e.g., every 2nd or 3rd student). " "The sampling fraction was adjusted proportionally to each school's enrolment size so that larger schools contributed more participants.\n\n" "Multi-stage sampling is used when the population is large and geographically spread — it is more practical than simple random sampling of all students.", tip="Know the difference: purposive (Stage 1) vs systematic random (Stage 2). A common trick question.") story += qna(17, "What data collection tools did you use? How many questionnaires were there?", "THREE separate validated questionnaires were used:\n\n" "1. PARENT/GUARDIAN QUESTIONNAIRE: Collected socio-demographic details, family and medical history, " "dietary patterns, screen time, pesticide exposure, age at menarche, and whether a doctor had confirmed PP.\n\n" "2. STUDENT QUESTIONNAIRE: Self-reported data on physical changes noticed, outdoor activity, " "screen time, menstrual history, and diet. Administered with teacher/staff assistance.\n\n" "3. HEALTHCARE PROFESSIONAL DATA SHEET: Anthropometric measurements — height (cm), weight (kg), " "and BMI (calculated as weight in kg divided by height in metres squared).\n\n" "All questionnaires were pre-tested on a PILOT sample of 20 girls not included in the main study. " "They were administered in MALAYALAM (local language) with English alongside.", tip="The three-source triangulation (parent + student + healthcare professional) is a STRENGTH of this study. Mention it.") story += qna(18, "How did you define Precocious Puberty in this study (primary outcome)?", "In this study, Precocious Puberty was defined as QUESTIONNAIRE-ASSESSED PP:\n\n" "A girl was classified as having PP if:\n" "(1) The PARENT reported the onset of secondary sexual characteristics (breast development, pubic hair, axillary hair, or menarche) BEFORE age 8 years, AND\n" "(2) A REGISTERED MEDICAL PRACTITIONER had previously CONFIRMED the diagnosis (Doctor_Confirmed = 1 in our dataset).\n\n" "This is an important limitation: we did not perform clinical examination, hormonal assays, or bone age X-rays ourselves. " "The diagnosis was based on questionnaire responses and prior doctor confirmation.", tip="Be honest about this limitation — it shows intellectual maturity. The lack of hormonal confirmation is a genuine weakness.") story += qna(19, "What is the difference between questionnaire-assessed PP and clinically confirmed PP?", "QUESTIONNAIRE-ASSESSED PP (what our study used): Based on parent and student reports. " "A girl is flagged as having PP if the parent reports early puberty signs before age 8 AND states a doctor confirmed it. " "This method is practical for large-scale community surveys but may miss cases or include false positives.\n\n" "CLINICALLY CONFIRMED PP: Requires physical examination by a paediatrician using Tanner staging " "(a standardised scoring of puberty development), bone age X-ray (to check skeletal maturity), " "and hormonal tests (LH, FSH, estradiol levels after GnRH stimulation). " "This is the gold standard but is not feasible for large community studies.\n\n" "Our prevalence estimate (9.1%) is therefore a PROXY measure — it estimates community-level burden " "but should be validated with clinical studies.", tip="Professors often ask 'what is Tanner staging?' — see Q20 for this.") story += qna(20, "What is Tanner staging?", "Tanner staging (also called SMR — Sexual Maturity Rating) is a system developed by Dr. James Tanner " "to assess the degree of physical development during puberty. It uses a scale from Stage 1 to Stage 5:\n\n" "• Stage 1 = Prepubertal (no development)\n" "• Stage 2 = Early puberty (first signs — e.g., breast budding)\n" "• Stage 3 = Mid-puberty\n" "• Stage 4 = Late puberty\n" "• Stage 5 = Adult development\n\n" "In girls, Tanner staging assesses BREAST development and PUBIC HAIR separately. " "In precocious puberty, a girl reaching Tanner Stage 2 before age 8 warrants investigation. " "We did not perform Tanner staging in our study — it would require clinical examination by a trained clinician.", tip="Tanner staging = a standardised way to objectively score puberty. Stage 2 before age 8 = PP flag.") story.append(PageBreak()) # ══ SECTION 3: RESULTS ═════════════════════════════════════════════ story += section_header("SECTION 3: Results — Understanding the Numbers") story += qna(21, "What was the main finding of your study?", "The main finding was that the PREVALENCE of questionnaire-assessed precocious puberty among school girls " "aged 10–15 years in Malappuram District, Kerala was 9.1% (n=39 out of 427 girls), " "with a 95% Confidence Interval of 6.5% to 12.3%.\n\n" "This means approximately 1 in 10 school girls in our sample had evidence of precocious puberty. " "This is consistent with other Kerala studies (Binu et al., Kollam: 10.4%) and falls within the " "reported Indian urban range of 5–12%.", tip="Memorise: 9.1%, 39/427, 95% CI 6.5–12.3%. These numbers WILL be asked.") story += qna(22, "What does 95% Confidence Interval (CI) mean? How do you interpret 6.5%–12.3%?", "A Confidence Interval (CI) tells us the RANGE within which the TRUE population prevalence is likely to fall. " "A 95% CI means: if we were to repeat this study 100 times on 100 different samples from the same population, " "the true prevalence would fall between 6.5% and 12.3% in 95 of those 100 studies.\n\n" "Interpretation: We are 95% confident that the true prevalence of PP in school girls in Malappuram " "lies between 6.5% and 12.3%. Our best estimate (point estimate) is 9.1%.\n\n" "The CI was calculated using the WILSON SCORE METHOD, which is more accurate than the standard formula " "when the prevalence is small (less than 20%).", tip="CI = a range of plausible true values. A narrower CI = more precision = larger sample size.") story += qna(23, "Was there a difference in PP prevalence between urban and semi-urban girls?", "Yes — numerically there was a difference, but it was NOT statistically significant:\n\n" "• Urban girls: 11.2% (24 out of 214) had PP\n" "• Semi-urban girls: 7.0% (15 out of 213) had PP\n\n" "Statistical test: Chi-square test gave X²(1) = 1.765 with p = 0.184. " "Since p > 0.05, this difference is NOT statistically significant — it could be due to chance.\n\n" "Possible reasons for non-significance: (1) The study may be underpowered to detect this small difference. " "(2) Anakkayam is itself rapidly urbanising, narrowing the true urban-rural gap.", tip="Know the p-value (0.184) and the direction (urban higher). Explain both the number AND the reason.") story += qna(24, "What is a p-value? What does p < 0.001 mean?", "A p-value (probability value) tells us the probability that an observed result occurred by CHANCE, " "assuming there is NO true association (the null hypothesis).\n\n" "• p < 0.05: The result is statistically significant — less than 5% chance it is due to chance. We REJECT the null hypothesis.\n" "• p > 0.05: Not significant — the result could be due to chance. We FAIL TO REJECT the null hypothesis.\n" "• p < 0.001: Very highly significant — less than 0.1% probability this is chance.\n\n" "In our study:\n" "• Family history: p < 0.001 (very highly significant)\n" "• BMI: p < 0.001 (very highly significant)\n" "• Urban vs rural: p = 0.184 (not significant)", tip="p < 0.05 = significant. p > 0.05 = not significant. Simple rule. Never confuse p-value with the effect size.") story += qna(25, "What was the role of BMI in your study? Why is it important?", "BMI (Body Mass Index) was the STRONGEST CONTINUOUS risk factor for PP in our study.\n\n" "Key findings:\n" "• Mean BMI in PP group: 21.24 ± 3.33 kg/m² vs 18.89 ± 2.35 kg/m² in non-PP group\n" "• t-test: t = 5.670, p < 0.001 — highly significant\n" "• Adjusted OR = 1.40 per 1 kg/m² unit increase in BMI (from logistic regression)\n" "• In the overweight/obese group (BMI ≥ 25): 71.4% (5 of 7 girls) had PP\n\n" "Why important? Excess body fat produces LEPTIN, which activates the hypothalamus to release GnRH early. " "Fat tissue also converts other hormones into ESTROGEN (through a process called aromatisation), " "further accelerating puberty. BMI is MODIFIABLE — it can be changed through diet and exercise, " "making it a key target for intervention.", tip="BMI-PP mechanism = Leptin → GnRH → HPG axis activation. Say this clearly in the defence.") story += qna(26, "What was the role of family history in your study?", "Family history was the STRONGEST CATEGORICAL (yes/no) risk factor and the strongest INDEPENDENT predictor of PP:\n\n" "• PP rate in girls WITH positive family history: 20.3% (16 of 79)\n" "• PP rate in girls WITHOUT family history: 6.6% (23 of 348)\n" "• Chi-square: X² = 12.845, p < 0.001 — highly significant\n" "• Adjusted OR = 3.31 (p = 0.002) — girls with family history are 3.3 times more likely to have PP\n\n" "Biological basis: Puberty timing is 50–80% heritable. Specific genes — MKRN3, DLK1, KISS1R — " "regulate the onset of puberty. Mutations in these genes are found in familial PP cases. " "Family history is NON-MODIFIABLE but is highly ACTIONABLE: girls with a mother or sister who " "had early puberty should be monitored more closely.", tip="OR 3.31 = most powerful finding. Know the gene names even if briefly: MKRN3, DLK1, KISS1R.") story += qna(27, "What was the mean age at menarche in PP cases vs controls? Why does this matter?", "This was one of the most striking findings:\n\n" "• PP group: Mean age at menarche = 10.00 ± 0.63 years\n" "• Non-PP group: Mean age at menarche = 12.39 ± 1.12 years\n" "• Difference = 2.39 years earlier in PP cases\n" "• t-test: t = −13.067, p < 0.001 — the LARGEST effect size in the study\n\n" "Why it matters: This confirms that PP girls are experiencing all milestones of puberty — " "including menstruation — significantly earlier than their peers. " "Starting periods at age 10 means prolonged estrogen exposure throughout life, " "increasing the lifetime risk of hormone-sensitive cancers. " "It also means these girls are physiologically mature while still in primary school — " "creating significant psychosocial challenges.", tip="t = -13.067 is a very large t-value — it signals a massive, highly significant difference.") story += qna(28, "Why were dietary factors like fast food not significant despite high prevalence?", "This is a nuanced finding. In our study:\n" "• 46.1% of girls consumed fast food more than 3 times/week\n" "• 51.5% regularly consumed processed food\n" "Yet neither showed a statistically significant association with PP (p = 0.61 and p = 0.38).\n\n" "This does NOT mean diet is unimportant. There are several explanations:\n" "1. The study was POWERED FOR PREVALENCE ESTIMATION, not for dietary subgroup analysis — smaller statistical power for these comparisons.\n" "2. Dietary variables were coded as BINARY (yes/no) — this loses the dose-response information (e.g., eating fast food daily vs 3 times/week both count as 'yes').\n" "3. Dietary exposure to EDCs (phthalates, BPA through packaging) cannot be captured by simple frequency questions — urine tests are needed.\n" "4. The mechanism of dietary EDC exposure on PP is cumulative and long-term, which a cross-sectional study cannot capture.", tip="Key phrase: 'Absence of significance is not absence of effect — the study was not powered for this analysis.'") story += qna(29, "What is an Odds Ratio (OR)? How do you interpret OR = 3.31 for family history?", "An ODDS RATIO (OR) measures the STRENGTH of association between a risk factor and an outcome.\n\n" "• OR = 1: No association\n" "• OR > 1: The risk factor INCREASES the odds of the outcome\n" "• OR < 1: The risk factor DECREASES the odds (protective)\n\n" "OR = 3.31 for family history means: Girls who have a positive family history of early puberty " "have 3.31 TIMES HIGHER ODDS of having PP compared to girls without a family history.\n\n" "This is an ADJUSTED OR — it was calculated using logistic regression, which controls for other factors " "simultaneously (like BMI and residence), so the effect of family history alone is isolated.", tip="Always say 'adjusted OR' because it is from logistic regression. An unadjusted OR would be from simple chi-square.") story += qna(30, "What was the student self-reported prevalence of high screen time and what does it mean?", "By parent report: 59.0% of girls had screen time exceeding 2 hours per day.\n" "By student self-report: 62.5% exceeded 2 hours per day.\n\n" "Both figures EXCEED WHO recommendations of less than 2 hours of recreational screen time per day for school-age children.\n\n" "Despite this high prevalence, screen time was NOT significantly associated with PP in our study (p = 0.860). " "This is likely because: (1) the binary cut-off (>2 hrs yes/no) does not capture true dose, " "(2) screen time affects PP INDIRECTLY through promoting obesity and disrupting melatonin rhythms — " "pathways that require more nuanced measurement to detect. " "The high screen time prevalence is itself a public health concern independent of its PP association.", tip="Show awareness that the finding matters beyond just statistical significance.") story.append(PageBreak()) # ══ SECTION 4: STATISTICS ══════════════════════════════════════════ story += section_header("SECTION 4: Statistics — Methods & Interpretation") story += qna(31, "What statistical tests did you use and why?", "We used THREE main statistical tests:\n\n" "1. DESCRIPTIVE STATISTICS (frequencies, means, standard deviations): To summarise and describe the sample.\n\n" "2. CHI-SQUARE TEST (Pearson, 2-tailed): For CATEGORICAL variables (e.g., family history yes/no, urban/semi-urban). " "It tests whether two categorical variables are associated. The null hypothesis is that there is NO association.\n\n" "3. INDEPENDENT SAMPLES T-TEST: For CONTINUOUS variables (e.g., BMI, age at menarche). " "It compares the MEANS of a continuous variable between two groups (PP vs non-PP). " "The null hypothesis is that there is no difference in means.\n\n" "All analysis was done using SPSS (Statistical Package for the Social Sciences). " "A p-value < 0.05 was set as the threshold for statistical significance.", tip="Chi-square = categorical variables. T-test = continuous variables. Know this distinction perfectly.") story += qna(32, "What is the difference between the chi-square test and t-test?", "CHI-SQUARE TEST:\n" "• Used when BOTH variables are categorical (nominal/ordinal)\n" "• Example: Is family history (yes/no) associated with PP (yes/no)?\n" "• It compares OBSERVED frequencies with EXPECTED frequencies\n" "• Output: X² statistic and p-value\n\n" "INDEPENDENT SAMPLES T-TEST:\n" "• Used when comparing the MEAN of a continuous variable between TWO groups\n" "• Example: Is mean BMI different between PP and non-PP girls?\n" "• It compares the means of two independent groups\n" "• Output: t-statistic and p-value\n" "• Requires the data to be approximately normally distributed", tip="A very common exam question. The simplest answer: chi-square = for counts/proportions; t-test = for means.") story += qna(33, "What is logistic regression and why was it used?", "Logistic regression is a statistical method used when the OUTCOME variable is binary (yes/no — in our case, PP yes/no). " "It allows us to examine the effect of MULTIPLE RISK FACTORS simultaneously.\n\n" "Why it was needed: Simple chi-square tests examine one factor at a time (bivariate analysis). " "But risk factors can be CONFOUNDED — for example, urban girls may also have higher BMI. " "Logistic regression controls for all included factors at the same time, giving us ADJUSTED Odds Ratios " "that isolate the independent effect of each factor.\n\n" "In our study, logistic regression confirmed that FAMILY HISTORY (adjusted OR = 3.31) and " "BMI (adjusted OR = 1.40 per unit) were the two strongest independent predictors of PP, " "after controlling for residence, screen time, and dietary variables.", tip="Logistic regression = multivariate analysis = adjusts for confounders. Say this confidently.") story += qna(34, "What is a confounder? Give an example from your study.", "A CONFOUNDER is a variable that is associated with BOTH the exposure (risk factor) AND the outcome (disease), " "and distorts the apparent relationship between them if not accounted for.\n\n" "Example from our study: URBAN RESIDENCE could be a confounder in the BMI-PP relationship. " "Urban girls tend to have higher BMI (due to sedentary lifestyle and fast food access) AND " "urban residence itself is associated with higher PP prevalence. " "So if we only looked at urban vs. PP without adjusting for BMI, we might overestimate the effect of urban residence.\n\n" "Logistic regression controls for confounders by including all key variables in the model simultaneously.", tip="Always give a concrete example from your own study. This shows you understand confounding in context.") story += qna(35, "What is standard deviation (SD)? Explain 21.24 ± 3.33 kg/m².", "STANDARD DEVIATION (SD) measures the SPREAD or variability of data around the mean.\n\n" "A SMALL SD means most values are close to the mean (data is tightly clustered).\n" "A LARGE SD means values are widely spread.\n\n" "In our finding: Mean BMI in PP group = 21.24 ± 3.33 kg/m²\n" "This means: The average BMI is 21.24 kg/m². Most girls fall within 21.24 − 3.33 = 17.91 and 21.24 + 3.33 = 24.57. " "About 68% of PP girls have BMI between 17.9 and 24.6.\n\n" "Compare with non-PP group: 18.89 ± 2.35 — lower mean AND smaller spread (less variability).", tip="SD = spread around the mean. Smaller SD = more homogeneous group.") story.append(PageBreak()) # ══ SECTION 5: CRITICAL THINKING ══════════════════════════════════ story += section_header("SECTION 5: Critical Thinking — Strengths, Limitations & Beyond") story += qna(36, "What are the strengths of your study?", "Our study has several notable strengths:", bullets=[ "Representative multi-school sample with adequate statistical power (n=427, exceeding calculated requirement)", "Multi-source data triangulation — parent questionnaire, student questionnaire, AND healthcare professional measurements — reducing single-source bias", "Dual-site design covering both urban and semi-urban settings, allowing comparison across settings", "Standardised anthropometric measurements by trained healthcare professionals", "Pre-tested, validated questionnaires administered in the local language (Malayalam)", "Ethical rigour — IEC and IRC approved, with informed consent and student assent", "100% data completion rate for the primary outcome", "SPSS-based analysis with standardised statistical methods", ], tip="Start with 'multi-source triangulation' — it is the most impressive methodological strength.") story += qna(37, "What are the limitations of your study?", "We acknowledge several important limitations:", bullets=[ "Cross-sectional design: Cannot establish cause and effect. We cannot say BMI CAUSED the PP — only that they are associated.", "Questionnaire-based PP diagnosis: No clinical examination, Tanner staging, bone age X-ray, or hormonal assay (LH, FSH, estradiol) was performed. Our 'PP' is a proxy measure.", "Self-reported and parent-reported dietary data: Subject to recall bias and social desirability bias.", "Binary coding of risk factors: Most variables coded as yes/no — loses dose-response information.", "Doctor confirmation bias: Urban and educated families more likely to have previously sought medical consultation — may over-represent PP cases in urban strata.", "Pesticide exposure: Assessed as a binary variable without specifying type, duration, or quantity.", "Limited generalisability: Findings are specific to Malappuram district and may not apply to other parts of Kerala or India.", ], tip="The most important limitation to mention first is the LACK OF HORMONAL CONFIRMATION. Say it confidently.") story += qna(38, "Can you establish causality from your study? Why or why not?", "NO — a cross-sectional study CANNOT establish causality (cause and effect). " "This is one of the fundamental limitations of the cross-sectional design.\n\n" "Reasons why:\n" "1. TEMPORALITY: In a cross-sectional study, we measure the exposure (e.g., BMI) and the outcome (PP) AT THE SAME TIME. " "We cannot know whether high BMI preceded PP or whether PP somehow led to weight gain.\n" "2. NO FOLLOW-UP: We do not follow girls over time to see who develops PP after the baseline measurement.\n\n" "To establish causality, we would need:\n" "• A COHORT STUDY: Follow girls from a young age and see who develops PP — comparing those with high vs low BMI at baseline.\n" "• Or a RANDOMISED CONTROLLED TRIAL: Intervene to reduce BMI and see if PP rates decrease.\n\n" "What we CAN say: There is a STATISTICALLY SIGNIFICANT ASSOCIATION between high BMI and PP in this population.", tip="KEY SENTENCE: 'Association, not causation.' Cross-sectional studies find associations; cohort studies establish temporal relationships.") story += qna(39, "If you were to repeat this study, what would you do differently?", "If given the opportunity to repeat or expand this study, I would make the following changes:\n\n" "1. Include HORMONAL CONFIRMATION: Measure serum LH, FSH, and estradiol after GnRH stimulation test in screen-positive girls — this would give clinically confirmed PP cases.\n\n" "2. Add BONE AGE ASSESSMENT: X-ray of the left wrist to assess skeletal maturity — another standard PP investigation.\n\n" "3. Measure URINARY PHTHALATE and BPA levels: To objectively quantify EDC exposure rather than relying on binary questionnaire responses.\n\n" "4. Use QUANTITATIVE dietary assessment: 24-hour dietary recall or food frequency questionnaire with portion sizes instead of binary yes/no questions.\n\n" "5. EXPAND THE SAMPLE: Include more districts of Kerala for better generalisability.\n\n" "6. LONGITUDINAL FOLLOW-UP: A cohort design would allow us to establish temporal relationships and true causality.", tip="This question tests whether you understand the limitations deeply enough to suggest improvements. Show intellectual honesty.") story += qna(40, "Why is this study clinically and public health-wise important?", "This study has significant public health importance for several reasons:\n\n" "1. PREVALENCE DATA: It provides the first district-level prevalence estimate for Malappuram (9.1% — nearly 1 in 10 girls). " "This data is essential for planning health services and allocating resources.\n\n" "2. ACTIONABLE RISK FACTORS: Both BMI (modifiable) and family history (screenable) are actionable. " "High-risk girls can be identified and referred early for evaluation.\n\n" "3. LONG-TERM HEALTH BURDEN: Early puberty increases lifetime risk of cancer, metabolic disease, and psychiatric disorders — " "identifying cases early allows intervention.\n\n" "4. SCHOOL HEALTH POLICY: Findings directly support advocating for annual anthropometric monitoring in schools, " "puberty education curricula, and canteen nutritional policies.\n\n" "5. UPSTREAM DETERMINANTS: High prevalence of fast food consumption (46.1%) and screen time (59%) in the sample " "highlights modifiable upstream factors for population-level intervention.", tip="Professors appreciate students who connect research findings to REAL-WORLD public health action.") story += qna(41, "What is an endocrine disruptor (EDC)? Give examples.", "An ENDOCRINE DISRUPTOR (EDC) is a chemical substance — natural or synthetic — that interferes with the body's hormonal (endocrine) system. " "They can mimic, block, or alter the production and action of hormones.\n\n" "How they relate to PP: EDCs can mimic estrogen (xenoestrogens) or interfere with the HPG axis, " "potentially triggering early puberty especially during sensitive developmental windows.\n\n" "Examples of EDCs relevant to PP:\n" "• PHTHALATES: Found in plastic packaging, PVC plastics, cosmetics, and food containers\n" "• BISPHENOL A (BPA): Found in polycarbonate plastic bottles and food can linings\n" "• PCBs (Polychlorinated Biphenyls): Industrial chemicals in older electrical equipment\n" "• ORGANOCHLORINE PESTICIDES: Used in agriculture — relevant in Anakkayam/Irumbuzhi\n" "• PARABENS: Preservatives in cosmetics and personal care products\n\n" "In our study, 14.1% of participants had pesticide/chemical exposure, though this was not significantly associated with PP (p = 1.000) — " "likely due to the binary measurement limitation.", tip="EDC = hormone-disrupting chemical. Phthalates and BPA are the most commonly asked examples.") story += qna(42, "What is leptin and what is its role in precocious puberty?", "LEPTIN is a hormone produced by ADIPOSE TISSUE (fat cells). Its primary role is to regulate appetite and energy balance " "by signalling to the brain that the body has adequate fat stores.\n\n" "Role in PP: Leptin receptors are present on hypothalamic neurons that produce GnRH. " "When body fat increases, leptin levels rise. Elevated leptin acts on the hypothalamus to:\n" "1. Stimulate GnRH release\n" "2. Lower the threshold for HPG axis activation\n\n" "This means: OBESE children with HIGH LEPTIN LEVELS have a lower age threshold for puberty onset — " "the puberty switch gets flipped earlier. This is the key biological mechanism linking obesity to PP.\n\n" "Supporting evidence: Shi et al. (2022) confirmed that body fat percentage and visceral adiposity are " "stronger predictors of PP than BMI alone, acting through the leptin-GnRH pathway.", tip="Leptin = fat cell hormone → stimulates brain → early puberty. Learn this pathway by heart.") story += qna(43, "How does your study compare with other Indian and international studies?", "COMPARISON WITH INDIAN STUDIES:\n" "• Our prevalence (9.1%) is consistent with Binu et al. from Kollam, Kerala who found 10.4%\n" "• Our finding falls within the 5–12% range reported from urban centres like Delhi, Mumbai, and Kolkata\n" "• Indian urban rates are consistently higher than rural rates — our urban subgroup (11.2%) follows this pattern\n\n" "COMPARISON WITH INTERNATIONAL STUDIES:\n" "• Western CLINICAL series report rates as low as 0.2% — but this is a clinical diagnosis rate, not a community prevalence\n" "• Population-based studies from the US found that Black American girls show earliest onset; European cohorts show advancing timing\n" "• Global range: 0.2% to >10% depending on case definition, population, and study method\n\n" "WHY OUR RATE IS HIGHER THAN WESTERN CLINICAL SERIES:\n" "Our study captures community prevalence using questionnaires — many mild cases never reach a clinic. " "Clinical series only see children referred by doctors, massively underestimating community burden.", tip="The comparison with Binu et al. (Kollam, 10.4%) is your most important reference — same state, similar findings.") story += qna(44, "What are your recommendations for the health system?", "Our study's findings directly translate into the following recommendations:\n\n" "FOR SCHOOL HEALTH PROGRAMS:\n" "• Mandatory annual anthropometric monitoring (height, weight, BMI) from Standard 5 onwards\n" "• Age-appropriate puberty education modules for students AND parents\n" "• Training of school health nurses to identify early pubertal signs\n" "• Healthy canteen policies restricting ultra-processed and fast foods\n\n" "FOR CLINICIANS:\n" "• Girls with BMI ≥ 23 kg/m² OR positive family history → proactive paediatric endocrinology referral\n" "• Standardised PP evaluation protocol: Tanner staging + bone age X-ray + LH/FSH testing\n\n" "FOR POLICY MAKERS:\n" "• Strengthen regulation of food marketing to children\n" "• Reduce agrochemical use near school populations\n" "• Fund a longitudinal cohort study in Kerala\n\n" "FOR FUTURE RESEARCH:\n" "• Hormonal profiling of screen-positive cases\n" "• Urinary phthalate/BPA measurement", tip="Show you understand the TRANSLATIONAL value of research — from findings to real-world action.") story += qna(45, "What is the Pearson correlation of r=0.482 (p=0.003) that you found?", "We found a PEARSON CORRELATION COEFFICIENT of r = 0.482 between 'age at first puberty signs' " "(parent-reported) and 'age at menarche' (student-reported), with p = 0.003, in a sub-sample of n = 57 girls.\n\n" "INTERPRETATION:\n" "• r = 0.482: A MODERATE POSITIVE correlation — as the age of first puberty signs increases, " "age at menarche also increases (and vice versa — girls who show early signs also tend to have early periods).\n" "• p = 0.003: Statistically significant — not due to chance\n\n" "WHY IT MATTERS: This confirms the BIOLOGICAL COHERENCE of the sequential pubertal events in our sample. " "It validates that girls who started puberty early (early thelarche) also had earlier menarche — " "which is exactly what we expect biologically. This supports the internal validity of our questionnaire data.", tip="r = 0: no correlation. r = 1: perfect positive. r = -1: perfect negative. r = 0.48 = moderate positive.") story.append(PageBreak()) # ══ SECTION 6: TOUGH QUESTIONS ═════════════════════════════════════ story += section_header("SECTION 6: Tough Questions Professors Might Ask") story += qna(46, "You found 9.1% PP prevalence but you did not do hormonal testing. How confident are you in this number?", "This is a fair and important critique. Our 9.1% is a QUESTIONNAIRE-ASSESSED prevalence — " "it is a PROXY measure, not a clinically confirmed prevalence.\n\n" "We are reasonably confident in this estimate because:\n" "1. It was based on DOUBLE CONFIRMATION — parent-reported early signs AND prior doctor confirmation\n" "2. It is consistent with similar questionnaire-based studies in Kerala (Binu et al.: 10.4%) and Indian urban studies\n" "3. Our data collection was triangulated from three sources\n\n" "However, we acknowledge that:\n" "1. Without hormonal assays (LH, FSH, estradiol) or Tanner staging, we cannot rule out false positives\n" "2. Without direct examination, cases with subtle early signs may have been missed (false negatives)\n" "3. The true clinically confirmed PP rate may be somewhat different\n\n" "We clearly state in our limitations that hormonal confirmation would strengthen the study.", tip="Be honest. Show you understand the limitation AND explain what was done to mitigate it.") story += qna(47, "You had only 7 overweight girls. How can you draw conclusions from such a small group?", "This is an excellent methodological challenge. You are correct that the overweight/obese group " "(BMI ≥ 25) was small — only 7 girls, of whom 5 (71.4%) had PP.\n\n" "We explicitly acknowledge this limitation: While the 71.4% PP rate in the overweight group is " "CLINICALLY STRIKING and proportionally alarming, the small group size (n=7) limits our INFERENTIAL CONFIDENCE.\n\n" "What we can say:\n" "1. The TREND is consistent with the global literature (Shi et al., Wang et al.) which strongly links obesity to PP\n" "2. The continuous BMI t-test (t=5.67, p<0.001) with n=427 is statistically robust and is a stronger conclusion\n" "3. The small overweight group likely reflects the general population — only 1.6% of all girls were overweight\n\n" "Better conclusions should come from larger studies specifically targeting overweight children.", tip="Don't be defensive. Agree with the limitation, then explain what evidence you CAN rely on from your data.") story += qna(48, "Why did you choose age 10–15 as the study population? PP is defined as before age 8 — wouldn't younger children be more appropriate?", "A very insightful question. The reason we studied 10–15 year olds rather than children under 8 involves practical and epidemiological considerations:\n\n" "1. RETROSPECTIVE IDENTIFICATION: Girls who experienced PP (onset before age 8) will have already been through it by age 10–15. " "Parents and the girls themselves can RECALL and REPORT whether early puberty signs occurred before age 8. " "Studying 10–15 year olds allows us to CAPTURE this history retrospectively.\n\n" "2. SCHOOL-BASED FEASIBILITY: Standard 6–9 (ages 10–15) students are accessible in schools and can participate meaningfully.\n\n" "3. MENARCHAL DATA: Studying this age group allows us to record age at menarche, which is a key PP indicator.\n\n" "4. LIMITATIONS ACKNOWLEDGED: Recall bias is a genuine risk in this retrospective approach. Parents may not accurately remember the exact age of first puberty signs.", tip="This question tests whether you can think critically about why you chose your study age group.") story += qna(49, "What is the difference between statistical significance and clinical significance?", "STATISTICAL SIGNIFICANCE (p < 0.05): Tells us that an observed difference or association is unlikely to be due to chance. " "It is determined by the p-value.\n\n" "CLINICAL SIGNIFICANCE: Tells us whether the finding is MEANINGFUL OR IMPORTANT IN PRACTICE. " "A finding can be statistically significant but clinically trivial, or vice versa.\n\n" "Example from our study:\n" "• Height was statistically significant (t=1.980, p=0.048) — PP girls were slightly taller (147.8 cm) vs non-PP (145.1 cm). " "But a 2.7 cm mean difference has NO clinical significance in management.\n\n" "• BMI difference (21.24 vs 18.89 kg/m²) is BOTH statistically AND clinically significant — " "it suggests a meaningful nutritional risk that should prompt intervention.\n\n" "The distinction matters: do not over-interpret statistically significant but trivially small differences.", tip="This is a common viva pitfall. Know the difference. P < 0.05 just means 'not likely by chance' — it says nothing about importance.") story += qna(50, "What is the null hypothesis in your study? Was it accepted or rejected?", "The NULL HYPOTHESIS (H₀) is the default assumption that there is NO association between a risk factor and the outcome.\n\n" "For our study, a sample null hypothesis: 'There is no significant association between family history of early puberty and precocious puberty among school girls in Malappuram.'\n\n" "RESULT: We REJECT the null hypothesis because our chi-square test gave p < 0.001 — " "the probability of seeing this result by chance (if H₀ were true) is less than 0.1%. " "We therefore conclude there IS a significant association.\n\n" "For residence (urban vs semi-urban): p = 0.184 — we FAIL TO REJECT the null hypothesis " "(insufficient evidence of a real association).", tip="In statistical testing: p < 0.05 → REJECT null. p > 0.05 → FAIL TO REJECT (do NOT say 'accept' the null).") story += qna(51, "What is bias? Name the types of bias present in your study.", "BIAS is a systematic error in the study design, data collection, or analysis that leads to incorrect results.\n\n" "Types of bias in our study:\n\n" "1. RECALL BIAS (Parent questionnaire): Parents may not accurately remember the exact age at which their daughter showed first puberty signs. " "This is especially likely for events that occurred years ago.\n\n" "2. SOCIAL DESIRABILITY BIAS (Dietary data): Families may underreport 'unhealthy' behaviours like fast food consumption or screen time.\n\n" "3. ASCERTAINMENT BIAS (Doctor confirmation): Urban, educated, and higher-income families are more likely to have previously consulted a doctor about early puberty. " "This may inflate PP prevalence in the urban group.\n\n" "4. SELECTION BIAS (School-based): Only enrolled school girls were included. Girls who dropped out of school " "(possibly due to early puberty or socio-economic problems) are not represented.", tip="Recall bias and ascertainment bias are the most important ones to mention from your study.") story += qna(52, "What is generalisation? Can your findings be generalised?", "GENERALISATION (external validity) refers to how well the findings of a study can be APPLIED to other populations beyond the study sample.\n\n" "Our findings have LIMITED generalisability because:\n" "1. The study is restricted to three schools in Malappuram District — other districts of Kerala may differ\n" "2. The sample includes only enrolled school-going girls — out-of-school girls are excluded\n" "3. Cultural, dietary, and environmental factors specific to Malappuram may not apply elsewhere\n\n" "What CAN be generalised:\n" "• The DIRECTION of associations (BMI and family history as risk factors) is consistent with national and international evidence\n" "• The broad magnitude of prevalence (~9–10%) appears consistent with Kerala data\n\n" "We explicitly state in our limitations: 'Findings are specific to Malappuram district and may not be directly generalisable to other regions of Kerala or India.'", tip="External validity = can you generalise? Internal validity = is the study design sound within its own population?") story.append(PageBreak()) # ══ SECTION 7: FINAL RAPID FIRE ══════════════════════════════════ story += section_header("SECTION 7: Rapid-Fire Facts — Know These Cold") rapid = [ ("What is the prevalence of PP in your study?", "9.1% (39/427); 95% CI: 6.5–12.3%"), ("What age defines PP in girls?", "Before 8 years of age"), ("What does HPG stand for?", "Hypothalamic-Pituitary-Gonadal axis"), ("What is the most common type of PP in girls?", "Central PP (CPP) — and most CPP in girls is idiopathic"), ("What is the treatment for Central PP?", "GnRH analogues (GnRHa) — e.g., leuprolide, triptorelin"), ("Which variable had the largest effect size?", "Age at menarche: t = −13.067, p < 0.001"), ("What were the two strongest independent predictors?", "Family history (OR 3.31) and BMI (OR 1.40 per kg/m²)"), ("What was mean BMI in PP vs non-PP?", "PP: 21.24 ± 3.33 kg/m²; non-PP: 18.89 ± 2.35 kg/m²"), ("What was mean menarche age in PP cases?", "10.00 ± 0.63 years"), ("What was the PP rate in overweight girls?", "71.4% (5 of 7 overweight girls had PP)"), ("What percentage had screen time > 2 h/day?", "59.0% by parent; 62.5% by student self-report"), ("What was the fast food prevalence?", "46.1% consumed fast food > 3 times/week"), ("What sampling method was used?", "Multi-stage random sampling (purposive + systematic random)"), ("What is the IEC reference number?", "IEC/GMCM/204/2026"), ("What is the IRC number?", "IRC/GMCM/313"), ("How many schools were included?", "Three schools — 2 urban, 1 semi-urban"), ("What software was used for analysis?", "SPSS (Statistical Package for the Social Sciences)"), ("What is BMI formula?", "Weight (kg) / Height² (m²)"), ("What is the Pearson correlation found?", "r = 0.482 (p = 0.003, n = 57) between puberty signs age and menarche age"), ("What genes are linked to familial PP?", "MKRN3, DLK1, KISS1R"), ] for q, a in rapid: row = [[ Paragraph(q, ParagraphStyle("rq", fontSize=11, leading=14, textColor=DINDIGO, fontName="Helvetica-Bold")), Paragraph(a, ParagraphStyle("ra", fontSize=11, leading=14, textColor=BLACK, fontName="Helvetica")) ]] t = Table(row, colWidths=[8*cm, 9*cm], style=TableStyle([ ("BACKGROUND", (0,0), (0,0), colors.HexColor("#EEF0FA")), ("BACKGROUND", (1,0), (1,0), colors.white), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING",(0,0),(-1,-1), 5), ("LEFTPADDING", (0,0), (-1,-1), 7), ("RIGHTPADDING",(0,0), (-1,-1), 7), ("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#CCCCDD")), ("VALIGN", (0,0), (-1,-1), "TOP"), ])) story.append(t) story.append(Spacer(1, 0.1*cm)) story.append(Spacer(1, 0.5*cm)) story.append(HRFlowable(width="100%", thickness=1.5, color=INDIGO)) story.append(Spacer(1, 0.3*cm)) story.append(Paragraph( "Best wishes for your open defence! You have done a rigorous, well-designed study " "with an important public health message. Speak confidently, acknowledge limitations honestly, " "and connect every finding back to what it means for real girls in Malappuram.", ParagraphStyle("closing", fontSize=12, leading=18, textColor=DINDIGO, alignment=TA_CENTER, fontName="Helvetica-Oblique"))) doc.build(story) print(f"PDF saved: {out}") PYEOF
Open Defence QA
PDF Document · PDF
| Section | Questions | What it covers |
|---|---|---|
| 1. Basic Concepts | Q1–Q10 | What is puberty, PP, HPG axis, types of PP, causes, long-term effects — explained simply |
| 2. Methodology | Q11–Q20 | Study design, prevalence vs incidence, sampling, sample size, data tools, case definition, Tanner staging |
| 3. Results | Q21–Q30 | Main prevalence finding, confidence intervals, BMI findings, family history, menarche data, why diet was non-significant |
| 4. Statistics | Q31–Q35 | Chi-square, t-test, logistic regression, confounders, standard deviation — explained in plain language |
| 5. Critical Thinking | Q36–Q45 | Strengths, limitations, causality, what you'd do differently, EDCs, leptin mechanism, comparison with other studies |
| 6. Tough Questions | Q46–Q52 | Hard professor-style questions: questioning your PP diagnosis, small overweight group, bias types, null hypothesis, generalisation |
| 7. Rapid Fire Facts | 20 Q&A pairs | All key numbers and facts in a table format — memorise these cold |