can you create a fun and interactive presentation on how fatigue and lazziness are different, reasons behind it, how to overcome it, its effects on health and how exercises helps to overcome it.
mkdir -p /tmp/workspace/fatigue-vs-laziness && ls /tmp/workspace/fatigue-vs-laziness/
~/fatigue-vs-laziness/build_pptx.py
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.oxml.ns import qn
from pptx.util import Inches, Pt
import copy
from lxml import etree
# ── Colour Palette ──────────────────────────────────────────────
C_BG_DARK = RGBColor(0x12, 0x12, 0x2E) # deep navy
C_BG_MID = RGBColor(0x1A, 0x1A, 0x40) # mid navy
C_ACCENT1 = RGBColor(0xFF, 0x6B, 0x6B) # coral-red (fatigue)
C_ACCENT2 = RGBColor(0x4E, 0xC9, 0xB0) # teal-green (laziness)
C_ACCENT3 = RGBColor(0xFF, 0xD1, 0x66) # golden yellow
C_ACCENT4 = RGBColor(0x9B, 0x59, 0xB6) # purple
C_ACCENT5 = RGBColor(0x3A, 0xC9, 0xFF) # sky blue
C_WHITE = RGBColor(0xFF, 0xFF, 0xFF)
C_LIGHT = RGBColor(0xE0, 0xE0, 0xF0)
C_CARD1 = RGBColor(0x20, 0x20, 0x50) # card background
C_CARD2 = RGBColor(0x18, 0x18, 0x44)
W = Inches(13.333)
H = Inches(7.5)
prs = Presentation()
prs.slide_width = W
prs.slide_height = H
blank_layout = prs.slide_layouts[6]
# ── Helpers ─────────────────────────────────────────────────────
def add_slide():
return prs.slides.add_slide(blank_layout)
def fill_bg(slide, color):
bg = slide.background
fill = bg.fill
fill.solid()
fill.fore_color.rgb = color
def add_rect(slide, x, y, w, h, color, alpha=None):
shape = slide.shapes.add_shape(1, x, y, w, h) # MSO_SHAPE_TYPE.RECTANGLE = 1
shape.fill.solid()
shape.fill.fore_color.rgb = color
shape.line.fill.background()
return shape
def add_textbox(slide, text, x, y, w, h,
font_name="Calibri", size=20, bold=False, italic=False,
color=None, align=PP_ALIGN.LEFT, v_anchor=MSO_ANCHOR.TOP,
wrap=True):
if color is None:
color = C_WHITE
tb = slide.shapes.add_textbox(x, y, w, h)
tf = tb.text_frame
tf.word_wrap = wrap
tf.vertical_anchor = v_anchor
tf.margin_left = 0
tf.margin_right = 0
tf.margin_top = 0
tf.margin_bottom = 0
p = tf.paragraphs[0]
p.alignment = align
run = p.add_run()
run.text = text
run.font.name = font_name
run.font.size = Pt(size)
run.font.bold = bold
run.font.italic = italic
run.font.color.rgb = color
return tb
def add_multiline_textbox(slide, lines, x, y, w, h,
font_name="Calibri", size=18, bold=False,
color=None, align=PP_ALIGN.LEFT,
v_anchor=MSO_ANCHOR.TOP, line_space=None):
"""lines: list of (text, bold_override, size_override, color_override)"""
if color is None:
color = C_WHITE
tb = slide.shapes.add_textbox(x, y, w, h)
tf = tb.text_frame
tf.word_wrap = True
tf.vertical_anchor = v_anchor
tf.margin_left = 0
tf.margin_right = 0
tf.margin_top = 0
tf.margin_bottom = 0
first = True
for item in lines:
if isinstance(item, str):
text, b, s, c = item, bold, size, color
else:
text = item[0]
b = item[1] if len(item) > 1 else bold
s = item[2] if len(item) > 2 else size
c = item[3] if len(item) > 3 else color
if first:
p = tf.paragraphs[0]
first = False
else:
p = tf.add_paragraph()
p.alignment = align
run = p.add_run()
run.text = text
run.font.name = font_name
run.font.size = Pt(s)
run.font.bold = b
run.font.color.rgb = c
if line_space:
from pptx.util import Pt as Pt2
from pptx.oxml.ns import qn
pPr = p._p.get_or_add_pPr()
lnSpc = etree.SubElement(pPr, qn('a:lnSpc'))
spcPts = etree.SubElement(lnSpc, qn('a:spcPts'))
spcPts.set('val', str(int(line_space * 100)))
return tb
def rounded_rect(slide, x, y, w, h, color, radius_emu=200000):
"""Add a rounded rectangle."""
from pptx.util import Emu
sp = slide.shapes.add_shape(5, x, y, w, h) # 5 = ROUNDED_RECTANGLE
sp.fill.solid()
sp.fill.fore_color.rgb = color
sp.line.fill.background()
# Adjust corner radius via XML
sp_elem = sp._element
spPr = sp_elem.find(qn('p:spPr'))
prstGeom = spPr.find(qn('a:prstGeom'))
if prstGeom is not None:
avLst = prstGeom.find(qn('a:avLst'))
if avLst is None:
avLst = etree.SubElement(prstGeom, qn('a:avLst'))
gd = etree.SubElement(avLst, qn('a:gd'))
gd.set('name', 'adj')
gd.set('fmla', 'val 30000')
return sp
def add_emoji_text(slide, emoji, x, y, w, h, size=36):
"""Add an emoji / symbol as large text."""
tb = slide.shapes.add_textbox(x, y, w, h)
tf = tb.text_frame
tf.word_wrap = False
tf.margin_left = 0; tf.margin_right = 0
tf.margin_top = 0; tf.margin_bottom = 0
p = tf.paragraphs[0]
p.alignment = PP_ALIGN.CENTER
run = p.add_run()
run.text = emoji
run.font.size = Pt(size)
return tb
def add_gradient_header(slide, title, subtitle=None):
"""Add a coloured header bar with title."""
add_rect(slide, 0, 0, W, Inches(1.3), C_CARD1)
add_textbox(slide, title,
Inches(0.4), Inches(0.12), Inches(12.5), Inches(0.75),
font_name="Calibri", size=34, bold=True,
color=C_ACCENT3, align=PP_ALIGN.LEFT)
if subtitle:
add_textbox(slide, subtitle,
Inches(0.4), Inches(0.82), Inches(12.5), Inches(0.45),
font_name="Calibri", size=16, bold=False,
color=C_LIGHT, align=PP_ALIGN.LEFT)
def add_pill(slide, text, x, y, w, h, bg_color, text_color=None, size=15):
if text_color is None: text_color = C_WHITE
rr = rounded_rect(slide, x, y, w, h, bg_color)
add_textbox(slide, text,
x + Inches(0.08), y + Inches(0.05), w - Inches(0.16), h - Inches(0.1),
font_name="Calibri", size=size, bold=True,
color=text_color, align=PP_ALIGN.CENTER,
v_anchor=MSO_ANCHOR.MIDDLE)
def add_card(slide, lines, x, y, w, h, card_color=None, title_color=None, body_color=None,
font_name="Calibri", title_size=18, body_size=15):
"""Generic content card."""
if card_color is None: card_color = C_CARD1
if title_color is None: title_color = C_ACCENT3
if body_color is None: body_color = C_LIGHT
rounded_rect(slide, x, y, w, h, card_color)
formatted = []
for i, line in enumerate(lines):
if i == 0:
formatted.append((line, True, title_size, title_color))
else:
formatted.append((line, False, body_size, body_color))
add_multiline_textbox(slide, formatted,
x + Inches(0.15), y + Inches(0.12),
w - Inches(0.3), h - Inches(0.24),
font_name=font_name, align=PP_ALIGN.LEFT,
v_anchor=MSO_ANCHOR.TOP)
# ══════════════════════════════════════════════════════════════
# SLIDE 1 — TITLE SLIDE
# ══════════════════════════════════════════════════════════════
s1 = add_slide()
fill_bg(s1, C_BG_DARK)
# Decorative background circles (simulate with rectangles)
for (cx, cy, sz, col) in [
(Inches(12.5), Inches(0.5), Inches(3), RGBColor(0x20, 0x10, 0x50)),
(Inches(0.2), Inches(6.5), Inches(2), RGBColor(0x10, 0x20, 0x45)),
(Inches(6.5), Inches(7.0), Inches(1.5), RGBColor(0x1A, 0x1A, 0x50)),
]:
sh = s1.shapes.add_shape(9, cx, cy, sz, sz) # 9 = OVAL
sh.fill.solid(); sh.fill.fore_color.rgb = col
sh.line.fill.background()
# Main Title
add_textbox(s1, "😴 vs 😒",
Inches(1), Inches(0.6), Inches(11), Inches(1.4),
font_name="Calibri", size=72, bold=True,
color=C_WHITE, align=PP_ALIGN.CENTER)
add_textbox(s1, "FATIGUE vs LAZINESS",
Inches(1), Inches(1.9), Inches(11), Inches(0.9),
font_name="Calibri", size=42, bold=True,
color=C_ACCENT3, align=PP_ALIGN.CENTER)
add_textbox(s1, "What's the difference? Why does it happen? How do you beat it?",
Inches(1.5), Inches(2.75), Inches(10), Inches(0.55),
font_name="Calibri", size=20, bold=False,
color=C_LIGHT, align=PP_ALIGN.CENTER)
# Divider line
r = s1.shapes.add_shape(1, Inches(3.5), Inches(3.45), Inches(6.333), Inches(0.04))
r.fill.solid(); r.fill.fore_color.rgb = C_ACCENT3
r.line.fill.background()
# Topic pills
topics = [
("🔍 Key Differences", C_ACCENT1),
("⚡ Root Causes", C_ACCENT2),
("💊 Health Effects", C_ACCENT4),
("🏃 Exercise Fix", C_ACCENT5),
("🛠 How to Overcome", C_ACCENT3),
]
pill_w = Inches(2.1)
pill_h = Inches(0.52)
start_x = Inches(0.5)
gap = Inches(0.25)
for i, (label, col) in enumerate(topics):
px = start_x + i * (pill_w + gap)
add_pill(s1, label, px, Inches(3.7), pill_w, pill_h, col, size=13)
add_textbox(s1, "An interactive guide to understanding your body & mind",
Inches(1.5), Inches(4.55), Inches(10), Inches(0.45),
font_name="Calibri", size=16, bold=False, italic=True,
color=RGBColor(0xAA, 0xAA, 0xCC), align=PP_ALIGN.CENTER)
# Speaker note
s1.notes_slide.notes_text_frame.text = (
"Welcome slide. Ask the audience: 'How many of you have hit the snooze button today?' "
"Use the poll as an icebreaker."
)
# ══════════════════════════════════════════════════════════════
# SLIDE 2 — WHAT IS FATIGUE vs LAZINESS? (Side-by-side)
# ══════════════════════════════════════════════════════════════
s2 = add_slide()
fill_bg(s2, C_BG_DARK)
add_gradient_header(s2, "🔍 What Are We Talking About?",
"Understanding the two — they are NOT the same thing!")
# Left card — Fatigue
rounded_rect(s2, Inches(0.3), Inches(1.5), Inches(6.0), Inches(5.5),
RGBColor(0x2A, 0x10, 0x20))
add_textbox(s2, "😴 FATIGUE",
Inches(0.5), Inches(1.65), Inches(5.6), Inches(0.7),
size=28, bold=True, color=C_ACCENT1, align=PP_ALIGN.CENTER)
fatigue_def = [
"A physical or mental state of extreme",
"tiredness caused by exertion, illness,",
"stress, or inadequate rest.",
"",
"🧠 Involves the brain & body",
"⚡ Reduces capacity to function",
"🩺 Can be a medical symptom",
"😔 Not a matter of willpower",
"🔄 Needs rest + recovery to resolve",
]
add_multiline_textbox(s2, fatigue_def,
Inches(0.5), Inches(2.4), Inches(5.6), Inches(4.2),
size=17, color=C_LIGHT, align=PP_ALIGN.LEFT)
# Right card — Laziness
rounded_rect(s2, Inches(7.0), Inches(1.5), Inches(6.0), Inches(5.5),
RGBColor(0x10, 0x25, 0x20))
add_textbox(s2, "😒 LAZINESS",
Inches(7.2), Inches(1.65), Inches(5.6), Inches(0.7),
size=28, bold=True, color=C_ACCENT2, align=PP_ALIGN.CENTER)
lazy_def = [
"An unwillingness to exert effort or",
"take action, despite having the energy",
"and capacity to do so.",
"",
"🎯 Involves motivation & mindset",
"💭 Often a behavioural habit",
"🧩 Linked to boredom / fear / avoidance",
"✅ Can be changed with intention",
"🔧 Requires habit-building to resolve",
]
add_multiline_textbox(s2, lazy_def,
Inches(7.2), Inches(2.4), Inches(5.6), Inches(4.2),
size=17, color=C_LIGHT, align=PP_ALIGN.LEFT)
# VS badge in the middle
sh = s2.shapes.add_shape(9, Inches(6.2), Inches(3.5), Inches(0.9), Inches(0.9))
sh.fill.solid(); sh.fill.fore_color.rgb = C_ACCENT3
sh.line.fill.background()
add_textbox(s2, "VS", Inches(6.2), Inches(3.55), Inches(0.9), Inches(0.8),
size=20, bold=True, color=C_BG_DARK, align=PP_ALIGN.CENTER)
# ══════════════════════════════════════════════════════════════
# SLIDE 3 — KEY DIFFERENCES TABLE
# ══════════════════════════════════════════════════════════════
s3 = add_slide()
fill_bg(s3, C_BG_DARK)
add_gradient_header(s3, "📊 Key Differences at a Glance",
"Side-by-side comparison across 6 dimensions")
headers = ["Dimension", "FATIGUE 😴", "LAZINESS 😒"]
rows = [
["Origin", "Physical / mental depletion", "Lack of motivation / avoidance"],
["Energy Level", "Genuinely low energy", "Normal energy, just unused"],
["Willpower", "Effort doesn't help much", "Effort CAN overcome it"],
["Solution", "Rest, sleep, nutrition, treatment","Habit change, goal-setting"],
["Duration", "Resolves with adequate recovery", "Can persist without intervention"],
["Medical risk", "Can signal illness or burnout", "Rarely a medical condition"],
]
col_widths = [Inches(2.8), Inches(4.6), Inches(4.6)]
row_h = Inches(0.67)
start_y = Inches(1.45)
start_x = Inches(0.6)
header_colors = [C_CARD1, C_ACCENT1, C_ACCENT2]
text_colors = [C_ACCENT3, C_LIGHT, C_LIGHT]
# Header row
x = start_x
for i, (hdr, bg, tc) in enumerate(zip(headers, header_colors, text_colors)):
rounded_rect(s3, x, start_y, col_widths[i], row_h, bg)
add_textbox(s3, hdr, x + Inches(0.1), start_y + Inches(0.1),
col_widths[i] - Inches(0.2), row_h - Inches(0.2),
size=17, bold=True, color=tc, align=PP_ALIGN.CENTER,
v_anchor=MSO_ANCHOR.MIDDLE)
x += col_widths[i] + Inches(0.05)
# Data rows
for ri, row in enumerate(rows):
y = start_y + (ri + 1) * (row_h + Inches(0.06))
x = start_x
bg_row = [RGBColor(0x1E, 0x1E, 0x44), RGBColor(0x28, 0x12, 0x1A), RGBColor(0x12, 0x22, 0x1A)]
tc_row = [C_ACCENT3, C_LIGHT, C_LIGHT]
for ci, (cell, bg, tc) in enumerate(zip(row, bg_row, tc_row)):
rounded_rect(s3, x, y, col_widths[ci], row_h, bg)
add_textbox(s3, cell,
x + Inches(0.1), y + Inches(0.08),
col_widths[ci] - Inches(0.2), row_h - Inches(0.16),
size=15, bold=(ci == 0), color=tc,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
x += col_widths[ci] + Inches(0.05)
# ══════════════════════════════════════════════════════════════
# SLIDE 4 — CAUSES OF FATIGUE
# ══════════════════════════════════════════════════════════════
s4 = add_slide()
fill_bg(s4, C_BG_DARK)
add_gradient_header(s4, "⚡ Causes of Fatigue",
"Why does your body/mind run out of fuel?")
causes_fatigue = [
("😴 Sleep Deprivation", "Not getting 7-9 hours of quality sleep — the #1 cause"),
("🩸 Anaemia / Low Iron", "Reduced oxygen delivery to muscles and brain"),
("🧠 Mental Overload", "Prolonged stress, anxiety, depression drain cognitive reserves"),
("🍔 Poor Nutrition", "Vitamin deficiencies (B12, D, Iron), sugar crashes"),
("🦠 Illness / Infection", "Immune response, viral load (e.g. post-COVID fatigue)"),
("💊 Medications", "Antihistamines, beta-blockers, antidepressants can cause fatigue"),
("🪑 Sedentary Lifestyle", "Lack of movement reduces cardiovascular efficiency"),
("🔥 Overtraining", "Too much exercise without adequate recovery"),
]
cw = Inches(5.9)
ch = Inches(0.66)
sx = Inches(0.35)
sy = Inches(1.5)
gap_x = Inches(0.45)
gap_y = Inches(0.08)
for i, (title, desc) in enumerate(causes_fatigue):
col = i % 2
row = i // 2
x = sx + col * (cw + gap_x)
y = sy + row * (ch + gap_y)
bg = RGBColor(0x2A, 0x14, 0x20) if col == 0 else RGBColor(0x14, 0x20, 0x30)
rounded_rect(s4, x, y, cw, ch, bg)
add_textbox(s4, title,
x + Inches(0.12), y + Inches(0.05),
cw - Inches(0.24), Inches(0.3),
size=15, bold=True, color=C_ACCENT1, align=PP_ALIGN.LEFT)
add_textbox(s4, desc,
x + Inches(0.12), y + Inches(0.33),
cw - Inches(0.24), Inches(0.28),
size=12.5, bold=False, color=C_LIGHT, align=PP_ALIGN.LEFT)
# ══════════════════════════════════════════════════════════════
# SLIDE 5 — CAUSES OF LAZINESS
# ══════════════════════════════════════════════════════════════
s5 = add_slide()
fill_bg(s5, C_BG_DARK)
add_gradient_header(s5, "🧠 Causes of Laziness",
"What actually stops you from getting things done?")
causes_lazy = [
("😰 Fear of Failure", "Avoiding tasks to escape the possibility of doing them wrong"),
("🎯 Lack of Clear Goals", "No defined purpose = no motivation to start"),
("📱 Instant Gratification", "Dopamine hijacking — scrolling is easier than working"),
("😞 Low Self-Efficacy", "Belief that effort won't lead to success"),
("🔁 Bad Habits & Routines", "Grooved neural pathways that default to inaction"),
("😐 Boredom / Disengagement","Task feels meaningless or unstimulating"),
("🧩 Perfectionism", "Paralysis by analysis — waiting for the 'right moment'"),
("💬 Negative Self-Talk", "'I'll do it later' — chronic procrastination loop"),
]
for i, (title, desc) in enumerate(causes_lazy):
col = i % 2
row = i // 2
x = sx + col * (cw + gap_x)
y = sy + row * (ch + gap_y)
bg = RGBColor(0x12, 0x25, 0x20) if col == 0 else RGBColor(0x18, 0x1A, 0x30)
rounded_rect(s5, x, y, cw, ch, bg)
add_textbox(s5, title,
x + Inches(0.12), y + Inches(0.05),
cw - Inches(0.24), Inches(0.3),
size=15, bold=True, color=C_ACCENT2, align=PP_ALIGN.LEFT)
add_textbox(s5, desc,
x + Inches(0.12), y + Inches(0.33),
cw - Inches(0.24), Inches(0.28),
size=12.5, bold=False, color=C_LIGHT, align=PP_ALIGN.LEFT)
# ══════════════════════════════════════════════════════════════
# SLIDE 6 — HEALTH EFFECTS
# ══════════════════════════════════════════════════════════════
s6 = add_slide()
fill_bg(s6, C_BG_DARK)
add_gradient_header(s6, "💊 Effects on Health",
"Both can seriously hurt you if left unchecked")
health_items = [
("❤️ Cardiovascular Risk", C_ACCENT1,
"Chronic fatigue linked to hypertension, heart disease & stroke"),
("🧠 Mental Health Decline", C_ACCENT4,
"Both fatigue & laziness worsen depression, anxiety & cognitive fog"),
("⚖️ Weight Gain", C_ACCENT3,
"Sedentary behaviour disrupts metabolism & increases obesity risk"),
("🦴 Muscle Weakness", C_ACCENT2,
"Fatigue causes muscle atrophy; laziness leads to deconditioning"),
("🩸 Hormonal Imbalance", C_ACCENT5,
"Sleep deprivation raises cortisol; disrupts insulin & thyroid hormones"),
("🛡️ Weakened Immunity", RGBColor(0xFF, 0x99, 0x66),
"Chronic fatigue suppresses immune function, raising infection risk"),
("😴 Sleep Disorders", RGBColor(0xAA, 0x88, 0xFF),
"Poor habits feed insomnia & sleep apnea in a vicious cycle"),
("📉 Productivity & Quality of Life", RGBColor(0x66, 0xCC, 0xFF),
"Both reduce work performance, relationships & life satisfaction"),
]
card_w = Inches(5.9)
card_h = Inches(0.66)
gx = Inches(0.45)
gy = Inches(0.08)
for i, (label, accent, desc) in enumerate(health_items):
col = i % 2
row = i // 2
x = Inches(0.35) + col * (card_w + gx)
y = Inches(1.5) + row * (card_h + gy)
rounded_rect(s6, x, y, card_w, card_h, RGBColor(0x18, 0x18, 0x40))
# left accent bar
rr = s6.shapes.add_shape(1, x, y, Inches(0.07), card_h)
rr.fill.solid(); rr.fill.fore_color.rgb = accent
rr.line.fill.background()
add_textbox(s6, label,
x + Inches(0.18), y + Inches(0.05),
card_w - Inches(0.3), Inches(0.3),
size=15, bold=True, color=accent, align=PP_ALIGN.LEFT)
add_textbox(s6, desc,
x + Inches(0.18), y + Inches(0.33),
card_w - Inches(0.3), Inches(0.28),
size=12.5, color=C_LIGHT, align=PP_ALIGN.LEFT)
# ══════════════════════════════════════════════════════════════
# SLIDE 7 — HOW EXERCISE HELPS
# ══════════════════════════════════════════════════════════════
s7 = add_slide()
fill_bg(s7, C_BG_DARK)
add_gradient_header(s7, "🏃 How Exercise Fights Both Fatigue & Laziness",
"Science-backed mechanisms — move more, feel better!")
exercise_cards = [
("💨 Boosts Oxygen Delivery",
"Cardio improves VO2max, meaning your heart & muscles work more efficiently — less effort for the same task."),
("🧠 Releases Feel-Good Hormones",
"Exercise triggers endorphins, serotonin & dopamine — natural mood lifters that crush procrastination."),
("😴 Improves Sleep Quality",
"Regular moderate exercise deepens slow-wave sleep, the most restorative stage — wake up truly refreshed."),
("⚡ Builds Mitochondria",
"Aerobic training creates more mitochondria in cells — literally more energy production capacity."),
("🔋 Reduces Mental Fatigue",
"Even a 20-minute walk increases cerebral blood flow and reduces brain fog within minutes."),
("🏋️ Fights Deconditioning",
"Strength training reverses muscle atrophy, making daily tasks require less effort and feel less tiring."),
]
ew = Inches(3.9)
eh = Inches(1.45)
egx = Inches(0.27)
egy = Inches(0.18)
for i, (title, desc) in enumerate(exercise_cards):
col = i % 3
row = i // 3
x = Inches(0.35) + col * (ew + egx)
y = Inches(1.5) + row * (eh + egy)
bg = [RGBColor(0x14, 0x24, 0x38),
RGBColor(0x18, 0x22, 0x34),
RGBColor(0x1A, 0x20, 0x30)][col]
rounded_rect(s7, x, y, ew, eh, bg)
# accent top bar
bar = s7.shapes.add_shape(1, x, y, ew, Inches(0.07))
bar.fill.solid(); bar.fill.fore_color.rgb = C_ACCENT5
bar.line.fill.background()
add_textbox(s7, title,
x + Inches(0.12), y + Inches(0.12),
ew - Inches(0.24), Inches(0.4),
size=15, bold=True, color=C_ACCENT5, align=PP_ALIGN.LEFT)
add_textbox(s7, desc,
x + Inches(0.12), y + Inches(0.55),
ew - Inches(0.24), Inches(0.82),
size=13, color=C_LIGHT, align=PP_ALIGN.LEFT, wrap=True)
# Bottom callout
rounded_rect(s7, Inches(0.35), Inches(6.55), Inches(12.6), Inches(0.72),
RGBColor(0x20, 0x30, 0x50))
add_textbox(s7,
"🎯 Recommended: 150 min moderate cardio/week + 2x strength training "
"— even 10-minute walks make a measurable difference!",
Inches(0.5), Inches(6.6), Inches(12.3), Inches(0.62),
size=15, bold=True, color=C_ACCENT3, align=PP_ALIGN.CENTER)
# ══════════════════════════════════════════════════════════════
# SLIDE 8 — BEST EXERCISES
# ══════════════════════════════════════════════════════════════
s8 = add_slide()
fill_bg(s8, C_BG_DARK)
add_gradient_header(s8, "🏋️ Best Exercises to Combat Fatigue & Laziness",
"Pick what you enjoy — consistency beats intensity!")
exercises = [
("🚶 Walking", "20-30 min daily", "Lowest barrier, immediate mood lift, reduces fatigue by 65% in studies"),
("🧘 Yoga / Stretching","15-45 min", "Reduces cortisol, improves flexibility & mental calm"),
("🚴 Cycling", "30-45 min", "Low-impact cardio that builds endurance & mitochondrial density"),
("🏊 Swimming", "20-40 min", "Full-body workout, especially good for fatigue from chronic conditions"),
("🏃 Running/Jogging", "20-30 min", "High endorphin release, strongest anti-depression effect"),
("🏋️ Strength Training","30-45 min, 2-3x", "Reverses deconditioning, boosts testosterone & confidence"),
("🤸 HIIT", "15-20 min", "Max efficiency — especially useful for 'I have no time' laziness"),
("🕺 Dancing", "Any duration", "Fun factor = highest adherence; dopamine + social reward"),
]
ew2 = Inches(5.85)
eh2 = Inches(0.68)
gx2 = Inches(0.45)
gy2 = Inches(0.1)
for i, (name, duration, benefit) in enumerate(exercises):
col = i % 2
row = i // 2
x = Inches(0.35) + col * (ew2 + gx2)
y = Inches(1.5) + row * (eh2 + gy2)
rounded_rect(s8, x, y, ew2, eh2, RGBColor(0x18, 0x20, 0x40))
# Duration pill
add_pill(s8, duration,
x + Inches(0.12), y + Inches(0.13),
Inches(1.4), Inches(0.26),
RGBColor(0x20, 0x50, 0x40), text_color=C_ACCENT2, size=11)
add_textbox(s8, name,
x + Inches(1.62), y + Inches(0.07),
Inches(1.8), Inches(0.28),
size=15, bold=True, color=C_ACCENT3, align=PP_ALIGN.LEFT)
add_textbox(s8, benefit,
x + Inches(0.12), y + Inches(0.42),
ew2 - Inches(0.24), Inches(0.24),
size=12, color=C_LIGHT, align=PP_ALIGN.LEFT)
# ══════════════════════════════════════════════════════════════
# SLIDE 9 — HOW TO OVERCOME FATIGUE
# ══════════════════════════════════════════════════════════════
s9 = add_slide()
fill_bg(s9, C_BG_DARK)
add_gradient_header(s9, "🛠 Overcoming FATIGUE — A Recovery Toolkit",
"Science-backed strategies to restore your energy")
fatigue_tips = [
("1️⃣", "Prioritise Sleep",
"7–9 hrs, consistent schedule, dark/cool room, no screens 1 hr before bed"),
("2️⃣", "Optimise Nutrition",
"Iron, B12, Vitamin D, complex carbs, hydration (even mild dehydration causes fatigue)"),
("3️⃣", "Manage Stress",
"Mindfulness, journaling, therapy — chronic stress depletes your energy reserves"),
("4️⃣", "Light Exercise",
"Counter-intuitive but true: gentle movement actually restores energy levels"),
("5️⃣", "Check Medical Causes",
"Rule out anaemia, thyroid disease, diabetes, sleep apnea, depression"),
("6️⃣", "Strategic Rest",
"Short 20-min naps (no longer!) boost alertness without causing grogginess"),
]
tw = Inches(5.9)
th = Inches(0.82)
tgx = Inches(0.45)
tgy = Inches(0.12)
for i, (num, title, tip) in enumerate(fatigue_tips):
col = i % 2
row = i // 2
x = Inches(0.35) + col * (tw + tgx)
y = Inches(1.5) + row * (th + tgy)
rounded_rect(s9, x, y, tw, th, RGBColor(0x25, 0x10, 0x18))
add_textbox(s9, num,
x + Inches(0.1), y + Inches(0.12),
Inches(0.45), Inches(0.58),
size=22, bold=True, color=C_ACCENT1, align=PP_ALIGN.CENTER)
add_textbox(s9, title,
x + Inches(0.6), y + Inches(0.05),
tw - Inches(0.72), Inches(0.3),
size=15, bold=True, color=C_ACCENT1, align=PP_ALIGN.LEFT)
add_textbox(s9, tip,
x + Inches(0.6), y + Inches(0.35),
tw - Inches(0.72), Inches(0.44),
size=12.5, color=C_LIGHT, align=PP_ALIGN.LEFT)
# ══════════════════════════════════════════════════════════════
# SLIDE 10 — HOW TO OVERCOME LAZINESS
# ══════════════════════════════════════════════════════════════
s10 = add_slide()
fill_bg(s10, C_BG_DARK)
add_gradient_header(s10, "🚀 Overcoming LAZINESS — A Motivation Playbook",
"Behavioural science tricks to get yourself moving!")
lazy_tips = [
("1️⃣", "2-Minute Rule",
"If it takes < 2 minutes, do it NOW. This breaks the avoidance loop immediately"),
("2️⃣", "Implementation Intentions",
"'I will do X at Y time in Z place' — specificity triples follow-through rate"),
("3️⃣", "Shrink the Task",
"Start with just 5 minutes. Starting IS the hardest part — momentum does the rest"),
("4️⃣", "Remove Friction",
"Set out workout clothes the night before. Make the right choice the easy choice"),
("5️⃣", "Reward Loops",
"Pair boring tasks with something enjoyable — your favourite podcast + a task"),
("6️⃣", "Social Accountability",
"Tell someone your goal. Public commitment raises completion rates by 65%"),
]
for i, (num, title, tip) in enumerate(lazy_tips):
col = i % 2
row = i // 2
x = Inches(0.35) + col * (tw + tgx)
y = Inches(1.5) + row * (th + tgy)
rounded_rect(s10, x, y, tw, th, RGBColor(0x10, 0x22, 0x18))
add_textbox(s10, num,
x + Inches(0.1), y + Inches(0.12),
Inches(0.45), Inches(0.58),
size=22, bold=True, color=C_ACCENT2, align=PP_ALIGN.CENTER)
add_textbox(s10, title,
x + Inches(0.6), y + Inches(0.05),
tw - Inches(0.72), Inches(0.3),
size=15, bold=True, color=C_ACCENT2, align=PP_ALIGN.LEFT)
add_textbox(s10, tip,
x + Inches(0.6), y + Inches(0.35),
tw - Inches(0.72), Inches(0.44),
size=12.5, color=C_LIGHT, align=PP_ALIGN.LEFT)
# ══════════════════════════════════════════════════════════════
# SLIDE 11 — QUICK SELF-CHECK QUIZ
# ══════════════════════════════════════════════════════════════
s11 = add_slide()
fill_bg(s11, C_BG_DARK)
add_gradient_header(s11, "🎯 Quick Self-Check — Which Are YOU Experiencing?",
"Answer honestly — no judgement here! 😄")
q_title = "Ask yourself these 4 questions:"
add_textbox(s11, q_title,
Inches(0.5), Inches(1.45), Inches(12.3), Inches(0.4),
size=18, bold=True, color=C_ACCENT3, align=PP_ALIGN.LEFT)
questions = [
("Q1", "Do you feel tired even after a full night's sleep?",
"YES → Likely Fatigue", "NO → Might be Laziness"),
("Q2", "Do you feel too tired to do things you actually ENJOY?",
"YES → Likely Fatigue", "NO → Might be Laziness"),
("Q3", "Has this been going on for more than 2 weeks?",
"YES → See a doctor!", "NO → Try motivation strategies"),
("Q4", "Does rest make you feel better?",
"YES → Classic Fatigue pattern", "NO → Explore motivation & habit"),
]
qw = Inches(5.85)
qh = Inches(1.05)
qgx = Inches(0.45)
qgy = Inches(0.15)
for i, (qnum, question, yes_ans, no_ans) in enumerate(questions):
col = i % 2
row = i // 2
x = Inches(0.35) + col * (qw + qgx)
y = Inches(1.98) + row * (qh + qgy)
rounded_rect(s11, x, y, qw, qh, RGBColor(0x1A, 0x1A, 0x42))
# question number badge
sh = s11.shapes.add_shape(9, x + Inches(0.1), y + Inches(0.12), Inches(0.52), Inches(0.52))
sh.fill.solid(); sh.fill.fore_color.rgb = C_ACCENT4
sh.line.fill.background()
add_textbox(s11, qnum, x + Inches(0.1), y + Inches(0.12),
Inches(0.52), Inches(0.52),
size=13, bold=True, color=C_WHITE, align=PP_ALIGN.CENTER,
v_anchor=MSO_ANCHOR.MIDDLE)
add_textbox(s11, question,
x + Inches(0.75), y + Inches(0.1),
qw - Inches(0.87), Inches(0.45),
size=14, bold=True, color=C_LIGHT, align=PP_ALIGN.LEFT)
# YES / NO answers
add_pill(s11, "✅ " + yes_ans, x + Inches(0.12), y + Inches(0.6),
Inches(2.5), Inches(0.3), RGBColor(0x10, 0x40, 0x20),
text_color=C_ACCENT2, size=11)
add_pill(s11, "❌ " + no_ans, x + Inches(2.75), y + Inches(0.6),
Inches(2.9), Inches(0.3), RGBColor(0x35, 0x10, 0x10),
text_color=C_ACCENT1, size=11)
# Bottom note
rounded_rect(s11, Inches(0.35), Inches(6.52), Inches(12.6), Inches(0.72),
RGBColor(0x18, 0x18, 0x40))
add_textbox(s11,
"⚠️ If you scored mostly YES — please consult a healthcare professional. "
"Chronic fatigue can indicate an underlying medical condition.",
Inches(0.5), Inches(6.57), Inches(12.3), Inches(0.62),
size=14, bold=False, italic=True, color=RGBColor(0xFF, 0xCC, 0x66),
align=PP_ALIGN.CENTER)
# ══════════════════════════════════════════════════════════════
# SLIDE 12 — DAILY ROUTINE PLAN
# ══════════════════════════════════════════════════════════════
s12 = add_slide()
fill_bg(s12, C_BG_DARK)
add_gradient_header(s12, "📅 Your 7-Day Energy Reset Plan",
"A practical daily routine to beat both fatigue AND laziness")
plan = [
("🌅 Morning", "7:00 AM", "Wake same time daily. 5 min stretch. Drink water before coffee.", C_ACCENT3),
("🧘 Movement", "7:30 AM", "10-20 min walk or yoga. Even 5 min counts — just START.", C_ACCENT2),
("🥗 Breakfast", "8:00 AM", "Protein + complex carbs + fruit. Avoid sugary cereals.", RGBColor(0xFF, 0x99, 0x44)),
("🎯 Work Block","9:00 AM", "Tackle hardest task first (peak energy). 25 min work + 5 min break (Pomodoro).", C_ACCENT5),
("🚶 Midday", "12:30 PM", "Short walk after lunch. Avoid heavy carb-only meals.", C_ACCENT2),
("💪 Exercise", "5:00 PM", "30 min workout (your choice). This is non-negotiable!", C_ACCENT1),
("📵 Evening", "9:00 PM", "Screen-free wind-down. Read, meditate, gentle stretching.", C_ACCENT4),
("😴 Sleep", "10:30 PM", "Consistent bedtime. Cool dark room. No phone in bed.", C_ACCENT5),
]
pw = Inches(5.85)
ph = Inches(0.64)
pgx = Inches(0.45)
pgy = Inches(0.1)
for i, (phase, time_str, desc, col) in enumerate(plan):
c = i % 2
r = i // 2
x = Inches(0.35) + c * (pw + pgx)
y = Inches(1.5) + r * (ph + pgy)
rounded_rect(s12, x, y, pw, ph, RGBColor(0x16, 0x18, 0x38))
# Time badge
add_pill(s12, time_str,
x + Inches(0.08), y + Inches(0.14),
Inches(1.0), Inches(0.28),
col, size=11)
add_textbox(s12, phase,
x + Inches(1.18), y + Inches(0.06),
Inches(1.5), Inches(0.28),
size=14, bold=True, color=col, align=PP_ALIGN.LEFT)
add_textbox(s12, desc,
x + Inches(0.1), y + Inches(0.36),
pw - Inches(0.2), Inches(0.24),
size=12, color=C_LIGHT, align=PP_ALIGN.LEFT)
# ══════════════════════════════════════════════════════════════
# SLIDE 13 — KEY TAKEAWAYS
# ══════════════════════════════════════════════════════════════
s13 = add_slide()
fill_bg(s13, C_BG_DARK)
add_gradient_header(s13, "🌟 Key Takeaways",
"What you should walk away knowing today")
takeaways = [
(C_ACCENT1, "Fatigue ≠ Laziness",
"One is a physiological/psychological state. The other is a behavioural pattern. "
"Confusing them leads to guilt, shame, and zero progress."),
(C_ACCENT2, "Both are fixable",
"Fatigue responds to rest, nutrition, sleep & medical treatment. "
"Laziness responds to habit design, accountability & motivation science."),
(C_ACCENT3, "Exercise is the universal tool",
"Regular physical activity is one of the only interventions proven to help "
"both conditions — it boosts energy, mood, sleep, and willpower simultaneously."),
(C_ACCENT5, "Start small, start now",
"You don't need a perfect plan. A 10-minute walk TODAY does more than a perfect "
"workout you plan for Monday and never do."),
]
ty = Inches(1.5)
for i, (col, title, desc) in enumerate(takeaways):
rounded_rect(s13, Inches(0.35), ty, Inches(12.6), Inches(1.12),
RGBColor(0x16, 0x18, 0x3A))
# Left accent bar
bar = s13.shapes.add_shape(1, Inches(0.35), ty, Inches(0.1), Inches(1.12))
bar.fill.solid(); bar.fill.fore_color.rgb = col
bar.line.fill.background()
add_textbox(s13, title,
Inches(0.6), ty + Inches(0.08),
Inches(12.0), Inches(0.35),
size=18, bold=True, color=col, align=PP_ALIGN.LEFT)
add_textbox(s13, desc,
Inches(0.6), ty + Inches(0.45),
Inches(12.0), Inches(0.58),
size=14, color=C_LIGHT, align=PP_ALIGN.LEFT)
ty += Inches(1.22)
# ══════════════════════════════════════════════════════════════
# SLIDE 14 — CLOSING / CALL TO ACTION
# ══════════════════════════════════════════════════════════════
s14 = add_slide()
fill_bg(s14, C_BG_DARK)
# decorative ovals
for (cx, cy, sz, col) in [
(Inches(11.5), Inches(0.3), Inches(4), RGBColor(0x1E, 0x10, 0x48)),
(Inches(0.0), Inches(5.0), Inches(3), RGBColor(0x10, 0x22, 0x44)),
(Inches(5.0), Inches(6.5), Inches(2), RGBColor(0x12, 0x18, 0x3A)),
]:
sh = s14.shapes.add_shape(9, cx, cy, sz, sz)
sh.fill.solid(); sh.fill.fore_color.rgb = col
sh.line.fill.background()
add_textbox(s14, "🚀",
Inches(5.6), Inches(0.5), Inches(2), Inches(1.2),
size=60, align=PP_ALIGN.CENTER)
add_textbox(s14, "Your Energy Journey Starts NOW",
Inches(1), Inches(1.6), Inches(11.2), Inches(0.85),
size=36, bold=True, color=C_ACCENT3, align=PP_ALIGN.CENTER)
add_textbox(s14, "One small action, taken consistently, changes everything.",
Inches(2), Inches(2.5), Inches(9.2), Inches(0.5),
size=20, italic=True, color=C_LIGHT, align=PP_ALIGN.CENTER)
# 3 action pills
actions = [
("😴 Fix your sleep tonight", C_ACCENT1),
("🏃 Move for 10 mins tomorrow", C_ACCENT5),
("🎯 Write ONE goal down right now", C_ACCENT2),
]
aw = Inches(3.6)
ah = Inches(0.65)
ax_start = Inches(0.9)
for i, (act, col) in enumerate(actions):
ax = ax_start + i * Inches(4.0)
add_pill(s14, act, ax, Inches(3.25), aw, ah, col, size=14)
# Quote
rounded_rect(s14, Inches(1.2), Inches(4.2), Inches(10.9), Inches(1.1),
RGBColor(0x1C, 0x1C, 0x40))
add_textbox(s14,
'"The secret of getting ahead is getting started."',
Inches(1.4), Inches(4.3), Inches(10.5), Inches(0.55),
size=18, bold=True, italic=True,
color=C_ACCENT3, align=PP_ALIGN.CENTER)
add_textbox(s14, "— Mark Twain",
Inches(1.4), Inches(4.82), Inches(10.5), Inches(0.35),
size=14, italic=True, color=C_LIGHT, align=PP_ALIGN.CENTER)
add_textbox(s14,
"Thank you • Questions? • Let's discuss!",
Inches(1), Inches(5.55), Inches(11.2), Inches(0.5),
size=20, bold=True, color=C_ACCENT4, align=PP_ALIGN.CENTER)
add_textbox(s14,
"😴 vs 😒 | Fatigue vs Laziness | Know the difference, own your energy",
Inches(0.5), Inches(6.85), Inches(12.3), Inches(0.4),
size=13, italic=True, color=RGBColor(0x88, 0x88, 0xAA),
align=PP_ALIGN.CENTER)
# ── Save ────────────────────────────────────────────────────────
out_path = "/tmp/workspace/fatigue-vs-laziness/Fatigue_vs_Laziness.pptx"
from io import BytesIO
buf = BytesIO()
prs.save(buf)
with open(out_path, "wb") as f:
f.write(buf.getvalue())
print(f"✅ Saved: {out_path}")
print(f" Slides: {len(prs.slides)}")
cd /tmp/workspace/fatigue-vs-laziness && python build_pptx.py 2>&1
Fatigue vs Laziness
Presentation · PPTX
| # | Slide | Highlights |
|---|---|---|
| 1 | Title Slide | Fun emoji header, topic pills, icebreaker note |
| 2 | What Are We Talking About? | Side-by-side definition cards with VS badge |
| 3 | Key Differences Table | 6-dimension colour-coded comparison grid |
| 4 | Causes of Fatigue | 8 science-backed root causes with icons |
| 5 | Causes of Laziness | 8 psychological/behavioural causes with icons |
| 6 | Health Effects | 8 health impacts with accent-colour bars |
| 7 | How Exercise Helps | 6 mechanism cards + WHO recommendation callout |
| 8 | Best Exercises | 8 exercises with duration badges and benefits |
| 9 | Overcoming Fatigue | 6-step recovery toolkit |
| 10 | Overcoming Laziness | 6 behavioural science strategies |
| 11 | Self-Check Quiz | 4 interactive YES/NO diagnostic questions |
| 12 | 7-Day Energy Reset Plan | Hour-by-hour daily routine with time badges |
| 13 | Key Takeaways | 4 core messages with accent bars |
| 14 | Closing / Call to Action | Quote, 3 action pills, thank-you |
can you add few more slides with deeper research to explain to fitness clients?
exercise fatigue neuromuscular recovery overtraining
physical inactivity motivation exercise behavior psychology
~/fatigue-vs-laziness/add_fitness_slides.py
"""
Appends 8 deep-research fitness-client slides to the existing presentation.
New Slides (15-22):
15 — The Neuroscience of Fatigue (Central vs Peripheral)
16 — Muscle-Level Fatigue: What Really Happens Inside
17 — Overtraining Syndrome: When Hard Work Backfires
18 — The Neuroscience of Laziness (Dopamine & Motivation)
19 — Self-Determination Theory for Fitness Coaches
20 — HRV & Recovery Biomarkers (Fitness Client Monitoring)
21 — Nutrition Blueprint for Energy & Performance
22 — Periodization: Programming to Prevent Fatigue
"""
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.oxml.ns import qn
from io import BytesIO
from lxml import etree
# ── Colour Palette (same as original) ───────────────────────────
C_BG_DARK = RGBColor(0x12, 0x12, 0x2E)
C_BG_MID = RGBColor(0x1A, 0x1A, 0x40)
C_ACCENT1 = RGBColor(0xFF, 0x6B, 0x6B) # coral-red
C_ACCENT2 = RGBColor(0x4E, 0xC9, 0xB0) # teal-green
C_ACCENT3 = RGBColor(0xFF, 0xD1, 0x66) # golden yellow
C_ACCENT4 = RGBColor(0x9B, 0x59, 0xB6) # purple
C_ACCENT5 = RGBColor(0x3A, 0xC9, 0xFF) # sky blue
C_WHITE = RGBColor(0xFF, 0xFF, 0xFF)
C_LIGHT = RGBColor(0xE0, 0xE0, 0xF0)
C_CARD1 = RGBColor(0x20, 0x20, 0x50)
W = Inches(13.333)
H = Inches(7.5)
path = "/tmp/workspace/fatigue-vs-laziness/Fatigue_vs_Laziness.pptx"
prs = Presentation(path)
blank_layout = prs.slide_layouts[6]
# ── Helpers (duplicated from build script) ───────────────────────
def add_slide():
return prs.slides.add_slide(blank_layout)
def fill_bg(slide, color):
bg = slide.background
fill = bg.fill
fill.solid()
fill.fore_color.rgb = color
def add_rect(slide, x, y, w, h, color):
shape = slide.shapes.add_shape(1, x, y, w, h)
shape.fill.solid()
shape.fill.fore_color.rgb = color
shape.line.fill.background()
return shape
def add_textbox(slide, text, x, y, w, h,
font_name="Calibri", size=18, bold=False, italic=False,
color=None, align=PP_ALIGN.LEFT, v_anchor=MSO_ANCHOR.TOP,
wrap=True):
if color is None: color = C_WHITE
tb = slide.shapes.add_textbox(x, y, w, h)
tf = tb.text_frame
tf.word_wrap = wrap
tf.vertical_anchor = v_anchor
tf.margin_left = 0; tf.margin_right = 0
tf.margin_top = 0; tf.margin_bottom = 0
p = tf.paragraphs[0]
p.alignment = align
run = p.add_run()
run.text = text
run.font.name = font_name
run.font.size = Pt(size)
run.font.bold = bold
run.font.italic = italic
run.font.color.rgb = color
return tb
def rounded_rect(slide, x, y, w, h, color):
sp = slide.shapes.add_shape(5, x, y, w, h)
sp.fill.solid()
sp.fill.fore_color.rgb = color
sp.line.fill.background()
sp_elem = sp._element
spPr = sp_elem.find(qn('p:spPr'))
prstGeom = spPr.find(qn('a:prstGeom'))
if prstGeom is not None:
avLst = prstGeom.find(qn('a:avLst'))
if avLst is None:
avLst = etree.SubElement(prstGeom, qn('a:avLst'))
gd = etree.SubElement(avLst, qn('a:gd'))
gd.set('name', 'adj')
gd.set('fmla', 'val 30000')
return sp
def add_multiline(slide, lines, x, y, w, h,
font_name="Calibri", default_size=16, default_bold=False,
default_color=None, align=PP_ALIGN.LEFT,
v_anchor=MSO_ANCHOR.TOP):
if default_color is None: default_color = C_LIGHT
tb = slide.shapes.add_textbox(x, y, w, h)
tf = tb.text_frame
tf.word_wrap = True
tf.vertical_anchor = v_anchor
tf.margin_left = 0; tf.margin_right = 0
tf.margin_top = 0; tf.margin_bottom = 0
first = True
for item in lines:
if isinstance(item, str):
text, b, s, c = item, default_bold, default_size, default_color
else:
text = item[0]
b = item[1] if len(item) > 1 else default_bold
s = item[2] if len(item) > 2 else default_size
c = item[3] if len(item) > 3 else default_color
p = tf.paragraphs[0] if first else tf.add_paragraph()
first = False
p.alignment = align
run = p.add_run()
run.text = text
run.font.name = font_name
run.font.size = Pt(s)
run.font.bold = b
run.font.color.rgb = c
return tb
def header(slide, title, subtitle=None):
add_rect(slide, 0, 0, W, Inches(1.3), C_CARD1)
add_textbox(slide, title,
Inches(0.4), Inches(0.12), Inches(12.5), Inches(0.75),
size=32, bold=True, color=C_ACCENT3, align=PP_ALIGN.LEFT)
if subtitle:
add_textbox(slide, subtitle,
Inches(0.4), Inches(0.82), Inches(12.5), Inches(0.42),
size=15, color=C_LIGHT, align=PP_ALIGN.LEFT)
def add_pill(slide, text, x, y, w, h, bg, tc=None, size=12):
if tc is None: tc = C_WHITE
rounded_rect(slide, x, y, w, h, bg)
add_textbox(slide, text,
x + Inches(0.06), y + Inches(0.04),
w - Inches(0.12), h - Inches(0.08),
size=size, bold=True, color=tc,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
def accent_bar(slide, x, y, h, color):
bar = slide.shapes.add_shape(1, x, y, Inches(0.09), h)
bar.fill.solid(); bar.fill.fore_color.rgb = color
bar.line.fill.background()
def divider(slide, y, color=None):
if color is None: color = RGBColor(0x30, 0x30, 0x60)
r = slide.shapes.add_shape(1, Inches(0.35), y, Inches(12.6), Inches(0.03))
r.fill.solid(); r.fill.fore_color.rgb = color
r.line.fill.background()
# ══════════════════════════════════════════════════════════════
# SECTION BREAK — FITNESS CLIENT DEEP DIVE
# ══════════════════════════════════════════════════════════════
sb = add_slide()
fill_bg(sb, C_BG_DARK)
# Decorative ovals
for cx, cy, sz, col in [
(Inches(11.0), Inches(0.0), Inches(5), RGBColor(0x18, 0x0A, 0x40)),
(Inches(0.0), Inches(4.5), Inches(4), RGBColor(0x0A, 0x1A, 0x38)),
(Inches(5.5), Inches(6.8), Inches(2), RGBColor(0x14, 0x14, 0x3A)),
]:
sh = sb.shapes.add_shape(9, cx, cy, sz, sz)
sh.fill.solid(); sh.fill.fore_color.rgb = col
sh.line.fill.background()
add_textbox(sb, "🔬",
Inches(5.7), Inches(0.8), Inches(2), Inches(1.3), size=64, align=PP_ALIGN.CENTER)
add_textbox(sb, "FITNESS CLIENT DEEP DIVE",
Inches(1), Inches(2.1), Inches(11.2), Inches(0.8),
size=38, bold=True, color=C_ACCENT3, align=PP_ALIGN.CENTER)
add_textbox(sb, "The Science Behind What You Feel in the Gym — and Away From It",
Inches(1.5), Inches(3.0), Inches(10.2), Inches(0.5),
size=19, italic=True, color=C_LIGHT, align=PP_ALIGN.CENTER)
# Divider
r = sb.shapes.add_shape(1, Inches(3.5), Inches(3.65), Inches(6.333), Inches(0.04))
r.fill.solid(); r.fill.fore_color.rgb = C_ACCENT4
r.line.fill.background()
topics_break = [
("🧠 Neuroscience", C_ACCENT4),
("💪 Muscle Biology", C_ACCENT1),
("📊 Biomarkers", C_ACCENT5),
("🥗 Nutrition", C_ACCENT2),
("📅 Periodization", C_ACCENT3),
]
pw = Inches(2.2); ph = Inches(0.52)
px = Inches(0.6)
for label, col in topics_break:
add_pill(sb, label, px, Inches(4.05), pw, ph, col, size=13)
px += pw + Inches(0.22)
# ══════════════════════════════════════════════════════════════
# SLIDE 15 — NEUROSCIENCE OF FATIGUE
# ══════════════════════════════════════════════════════════════
s15 = add_slide()
fill_bg(s15, C_BG_DARK)
header(s15, "🧠 The Neuroscience of Fatigue",
"Two distinct systems fail when you're truly exhausted")
# Central Fatigue column
rounded_rect(s15, Inches(0.3), Inches(1.45), Inches(6.0), Inches(5.75),
RGBColor(0x1E, 0x0E, 0x32))
add_textbox(s15, "⬆️ CENTRAL FATIGUE",
Inches(0.5), Inches(1.6), Inches(5.6), Inches(0.55),
size=20, bold=True, color=C_ACCENT4, align=PP_ALIGN.CENTER)
add_textbox(s15, "Brain & CNS level",
Inches(0.5), Inches(2.15), Inches(5.6), Inches(0.3),
size=13, italic=True, color=RGBColor(0xBB, 0xAA, 0xFF), align=PP_ALIGN.CENTER)
central = [
("📍 What happens", True, 14, C_ACCENT4),
("Reduced motor cortex drive to working muscles. The brain \n"
"voluntarily 'throttles' effort as a protective mechanism.", False, 13, C_LIGHT),
("", False, 8, C_LIGHT),
("📍 Neurotransmitters involved", True, 14, C_ACCENT4),
("↑ Serotonin (fatigue signal) | ↓ Dopamine (drive signal)\n"
"Tryptophan crosses BBB → more serotonin during prolonged exercise", False, 13, C_LIGHT),
("", False, 8, C_LIGHT),
("📍 Fitness implications", True, 14, C_ACCENT4),
("Mental training, pacing strategy & arousal control can delay\n"
"central fatigue. Caffeine works here — blocks adenosine receptors.", False, 13, C_LIGHT),
("", False, 8, C_LIGHT),
("📍 Signs in your client", True, 14, C_ACCENT4),
("Reduced motivation mid-set, slower reaction time, difficulty\n"
"concentrating, perceived effort > actual effort.", False, 13, C_LIGHT),
]
add_multiline(s15, central, Inches(0.5), Inches(2.5), Inches(5.6), Inches(4.5),
default_size=13, align=PP_ALIGN.LEFT)
# Peripheral Fatigue column
rounded_rect(s15, Inches(7.0), Inches(1.45), Inches(6.0), Inches(5.75),
RGBColor(0x10, 0x20, 0x30))
add_textbox(s15, "⬇️ PERIPHERAL FATIGUE",
Inches(7.2), Inches(1.6), Inches(5.6), Inches(0.55),
size=20, bold=True, color=C_ACCENT5, align=PP_ALIGN.CENTER)
add_textbox(s15, "Muscle & NMJ level",
Inches(7.2), Inches(2.15), Inches(5.6), Inches(0.3),
size=13, italic=True, color=RGBColor(0x88, 0xCC, 0xFF), align=PP_ALIGN.CENTER)
peripheral = [
("📍 What happens", True, 14, C_ACCENT5),
("Failure at the neuromuscular junction or within the muscle\n"
"fibre itself — the signal arrives but the muscle can't respond.", False, 13, C_LIGHT),
("", False, 8, C_LIGHT),
("📍 Key biochemical events", True, 14, C_ACCENT5),
("↓ Glycogen stores | ↑ H⁺ ions (pH drop)\n"
"Pi accumulation inhibits cross-bridge cycling\n"
"Ca²⁺ release impaired from sarcoplasmic reticulum", False, 13, C_LIGHT),
("", False, 8, C_LIGHT),
("📍 Fitness implications", True, 14, C_ACCENT5),
("Nutrition (carbs), hydration, warm-up protocols and\n"
"rest intervals directly target peripheral fatigue.", False, 13, C_LIGHT),
("", False, 8, C_LIGHT),
("📍 Signs in your client", True, 14, C_ACCENT5),
("Burning sensation in muscle, form breakdown, inability to\n"
"complete reps even with high motivation.", False, 13, C_LIGHT),
]
add_multiline(s15, peripheral, Inches(7.2), Inches(2.5), Inches(5.6), Inches(4.5),
default_size=13, align=PP_ALIGN.LEFT)
# VS badge
sh = s15.shapes.add_shape(9, Inches(6.2), Inches(3.85), Inches(0.88), Inches(0.88))
sh.fill.solid(); sh.fill.fore_color.rgb = C_ACCENT3; sh.line.fill.background()
add_textbox(s15, "VS", Inches(6.2), Inches(3.9), Inches(0.88), Inches(0.8),
size=18, bold=True, color=C_BG_DARK, align=PP_ALIGN.CENTER)
s15.notes_slide.notes_text_frame.text = (
"Source: Firestein & Kelley's Textbook of Rheumatology; "
"Brownstein et al. 2021 (PMID 32627930). "
"Key coaching point: always distinguish which fatigue type your client is showing — "
"central fatigue needs rest/pacing; peripheral needs substrate replenishment."
)
# ══════════════════════════════════════════════════════════════
# SLIDE 16 — MUSCLE-LEVEL FATIGUE BIOLOGY
# ══════════════════════════════════════════════════════════════
s16 = add_slide()
fill_bg(s16, C_BG_DARK)
header(s16, "💪 Inside the Muscle: What Fatigue Actually Does",
"The cellular cascade that limits performance — and how training reverses it")
# Top row — 3 mechanism cards
mech_cards = [
(C_ACCENT1,
"🔋 Energy Depletion",
"ATP & PCr are depleted within 10 sec at max effort. Anaerobic glycolysis kicks in but "
"generates H⁺ ions → intracellular pH drops → enzyme function impaired → force drops.",
"Implication: Rest periods in strength training exist to allow PCr resynthesis (~3 min for full recovery)."),
(C_ACCENT3,
"⚗️ Metabolite Accumulation",
"Inorganic phosphate (Pi) from ATP hydrolysis and H⁺ from lactate production directly "
"inhibit myosin ATPase and impair Ca²⁺ handling in the sarcoplasmic reticulum.",
"Implication: HIIT with short rest intervals keeps Pi high — useful for metabolic stress but not max strength."),
(C_ACCENT5,
"🧬 Glycogen Depletion",
"Muscle glycogen is depleted in < 2 minutes at max intensity. Moderate exercise can exhaust "
"glycogen in 60–90 min. Once depleted, fatigue is dramatic and performance collapses.",
"Implication: Pre-workout carbs + intra-workout nutrition directly protect against this mechanism."),
]
cw3 = Inches(4.1); ch3 = Inches(2.6)
gx3 = Inches(0.26)
for i, (col, title, body, impl) in enumerate(mech_cards):
x = Inches(0.35) + i * (cw3 + gx3)
y = Inches(1.45)
rounded_rect(s16, x, y, cw3, ch3, RGBColor(0x18, 0x18, 0x40))
# top accent bar
bar = s16.shapes.add_shape(1, x, y, cw3, Inches(0.08))
bar.fill.solid(); bar.fill.fore_color.rgb = col; bar.line.fill.background()
add_textbox(s16, title,
x + Inches(0.12), y + Inches(0.14), cw3 - Inches(0.24), Inches(0.38),
size=15, bold=True, color=col, align=PP_ALIGN.LEFT)
add_textbox(s16, body,
x + Inches(0.12), y + Inches(0.56), cw3 - Inches(0.24), Inches(1.15),
size=12, color=C_LIGHT, align=PP_ALIGN.LEFT, wrap=True)
add_textbox(s16, impl,
x + Inches(0.12), y + Inches(1.75), cw3 - Inches(0.24), Inches(0.72),
size=11.5, bold=True, italic=True,
color=RGBColor(0xFF, 0xEE, 0x99), align=PP_ALIGN.LEFT, wrap=True)
# Bottom row — fibre types & training adaptation
rounded_rect(s16, Inches(0.35), Inches(4.22), Inches(12.6), Inches(2.95),
RGBColor(0x14, 0x20, 0x30))
add_textbox(s16, "🏋️ Muscle Fibre Types & Training Adaptations",
Inches(0.55), Inches(4.32), Inches(12.0), Inches(0.38),
size=16, bold=True, color=C_ACCENT2, align=PP_ALIGN.LEFT)
fibre_data = [
("Type I (Slow-Twitch)", C_ACCENT2,
"High mitochondria | Aerobic | Fatigue-resistant\nEndurance training hypertrophies these + ↑ capillary density\n→ More efficient oxygen use, delays fatigue onset"),
("Type IIa (Fast-Twitch)", C_ACCENT3,
"Intermediate — can shift toward Type I with training\nResponds to mixed resistance + endurance work\n→ Power + moderate endurance"),
("Type IIx (Fast-Twitch)", C_ACCENT1,
"Low mitochondria | Anaerobic | Rapid fatigue\nStrength / power training hypertrophies these\n→ Max force but tires quickly; needs longer rest"),
("Training Effect", C_ACCENT5,
"Detraining begins in just 2 weeks! Aerobic capacity\ndrops first. Strength decays more slowly.\nConsistency is more important than intensity."),
]
fw = Inches(3.0); fh = Inches(2.25)
fgx = Inches(0.24)
for i, (name, col, desc) in enumerate(fibre_data):
fx = Inches(0.5) + i * (fw + fgx)
fy = Inches(4.72)
rounded_rect(s16, fx, fy, fw, fh, RGBColor(0x1C, 0x28, 0x3C))
accent_bar(s16, fx, fy, fh, col)
add_textbox(s16, name,
fx + Inches(0.18), fy + Inches(0.1), fw - Inches(0.3), Inches(0.32),
size=13, bold=True, color=col, align=PP_ALIGN.LEFT)
add_textbox(s16, desc,
fx + Inches(0.18), fy + Inches(0.45), fw - Inches(0.3), Inches(1.7),
size=11.5, color=C_LIGHT, align=PP_ALIGN.LEFT, wrap=True)
s16.notes_slide.notes_text_frame.text = (
"Sources: Miller's Review of Orthopaedics 9e (p.71); "
"Basic Medical Biochemistry 6e; Cheng et al. 2020 (PMID 32179050). "
"Coach tip: use this slide to explain rest period programming to clients."
)
# ══════════════════════════════════════════════════════════════
# SLIDE 17 — OVERTRAINING SYNDROME
# ══════════════════════════════════════════════════════════════
s17 = add_slide()
fill_bg(s17, C_BG_DARK)
header(s17, "🚨 Overtraining Syndrome (OTS): When Hard Work Backfires",
"The #1 fatigue trap for motivated fitness clients — and how to avoid it")
# OTS stages
stages = [
(C_ACCENT3, "Stage 1: Overreaching (Functional)",
"Short-term performance decline from too much load.\nResolves with 1-2 weeks rest.\nAcceptable & even desirable in periodized training.",
"✅ Normal training stress"),
(C_ACCENT1, "Stage 2: Non-Functional Overreaching",
"Performance decline for weeks–months.\nMood disturbance, fatigue, sleep disruption.\nRequires 4-12 weeks recovery.",
"⚠️ Early warning — act now"),
(RGBColor(0xFF, 0x44, 0x44), "Stage 3: Overtraining Syndrome",
"Full OTS: performance decline for months–years.\nHormonal dysregulation (↓ testosterone, ↑ cortisol).\nRequires medical evaluation.",
"🚨 Medical emergency"),
]
sw = Inches(4.0); sh = Inches(2.7)
sgx = Inches(0.24)
for i, (col, title, body, badge) in enumerate(stages):
sx = Inches(0.35) + i * (sw + sgx)
sy = Inches(1.45)
rounded_rect(s17, sx, sy, sw, sh, RGBColor(0x1C, 0x10, 0x28))
bar = s17.shapes.add_shape(1, sx, sy, sw, Inches(0.08))
bar.fill.solid(); bar.fill.fore_color.rgb = col; bar.line.fill.background()
add_textbox(s17, f"STAGE {i+1}", sx + Inches(0.12), sy + Inches(0.14),
sw - Inches(0.24), Inches(0.28),
size=11, bold=True, color=col, align=PP_ALIGN.LEFT)
add_textbox(s17, title,
sx + Inches(0.12), sy + Inches(0.42), sw - Inches(0.24), Inches(0.38),
size=14, bold=True, color=C_WHITE, align=PP_ALIGN.LEFT, wrap=True)
add_textbox(s17, body,
sx + Inches(0.12), sy + Inches(0.85), sw - Inches(0.24), Inches(1.25),
size=12.5, color=C_LIGHT, align=PP_ALIGN.LEFT, wrap=True)
add_pill(s17, badge,
sx + Inches(0.12), sy + Inches(2.3), sw - Inches(0.24), Inches(0.28),
RGBColor(0x28, 0x20, 0x38), tc=col, size=12)
# Warning signs grid
rounded_rect(s17, Inches(0.35), Inches(4.32), Inches(12.6), Inches(2.85),
RGBColor(0x18, 0x10, 0x28))
add_textbox(s17, "🔴 Key Warning Signs of OTS — Tell Your Clients to Report These",
Inches(0.55), Inches(4.42), Inches(12.0), Inches(0.38),
size=16, bold=True, color=C_ACCENT1, align=PP_ALIGN.LEFT)
warning_signs = [
"😴 Persistent fatigue despite rest",
"📉 Performance declining despite training",
"😤 Mood swings, irritability, depression",
"🤧 Frequent illness (↓ immune function)",
"💔 Elevated resting heart rate (>5-7 bpm above normal)",
"🍽️ Loss of appetite or motivation to train",
"😰 Sleep disturbances despite exhaustion",
"🦴 Persistent muscle soreness (>72 hrs)",
]
ws_w = Inches(2.95); ws_h = Inches(0.52)
wgx = Inches(0.22); wgy = Inches(0.1)
for i, sign in enumerate(warning_signs):
col = i % 4
row = i // 4
wx = Inches(0.5) + col * (ws_w + wgx)
wy = Inches(4.9) + row * (ws_h + wgy)
rounded_rect(s17, wx, wy, ws_w, ws_h, RGBColor(0x28, 0x14, 0x24))
add_textbox(s17, sign,
wx + Inches(0.1), wy + Inches(0.06), ws_w - Inches(0.2), ws_h - Inches(0.12),
size=12, color=C_LIGHT, align=PP_ALIGN.LEFT, v_anchor=MSO_ANCHOR.MIDDLE)
s17.notes_slide.notes_text_frame.text = (
"Source: Grandou et al. 2020 (PMID 31820373) — Overtraining in Resistance Exercise, Sports Med. "
"Coach key: teach clients the difference between productive soreness and OTS. "
"Implement deload weeks every 4-8 weeks."
)
# ══════════════════════════════════════════════════════════════
# SLIDE 18 — NEUROSCIENCE OF LAZINESS / MOTIVATION
# ══════════════════════════════════════════════════════════════
s18 = add_slide()
fill_bg(s18, C_BG_DARK)
header(s18, "🧬 The Brain Science of Laziness & Motivation",
"Why your clients KNOW they should exercise but still don't — the dopamine story")
# Left: Dopamine system
rounded_rect(s18, Inches(0.3), Inches(1.45), Inches(6.1), Inches(5.72),
RGBColor(0x18, 0x10, 0x32))
add_textbox(s18, "🔴 The Dopamine Problem",
Inches(0.5), Inches(1.6), Inches(5.7), Inches(0.5),
size=20, bold=True, color=C_ACCENT4, align=PP_ALIGN.CENTER)
dopamine_lines = [
("How dopamine drives inertia:", True, 14, C_ACCENT4),
("", False, 6, C_LIGHT),
("📱 Instant rewards (social media, junk food) flood the nucleus\n"
"accumbens with dopamine — creating a high comparison point.", False, 13, C_LIGHT),
("", False, 6, C_LIGHT),
("🏃 Exercise rewards are DELAYED — the brain's reward prediction\n"
"system undervalues future rewards vs. immediate ones.", False, 13, C_LIGHT),
("", False, 6, C_LIGHT),
("😐 Sedentary behaviour downregulates D2 dopamine receptors —\n"
"making motivation progressively HARDER over time.", False, 13, C_LIGHT),
("", False, 6, C_LIGHT),
("✅ Exercise actually upregulates dopamine receptors — so the\n"
"more you exercise, the easier motivation becomes.", False, 13, C_LIGHT),
("", False, 8, C_LIGHT),
("💡 Coaching Hack:", True, 14, C_ACCENT3),
("Front-load the reward. Play a favourite playlist ONLY during\n"
"workouts. Use social connection. Celebrate small wins loudly.", False, 13, C_LIGHT),
]
add_multiline(s18, dopamine_lines,
Inches(0.5), Inches(2.15), Inches(5.7), Inches(4.9),
default_size=13, align=PP_ALIGN.LEFT)
# Right: Self-Determination Theory overview
rounded_rect(s18, Inches(7.0), Inches(1.45), Inches(6.0), Inches(5.72),
RGBColor(0x10, 0x20, 0x28))
add_textbox(s18, "✅ Intrinsic vs. Extrinsic Motivation",
Inches(7.2), Inches(1.6), Inches(5.6), Inches(0.5),
size=20, bold=True, color=C_ACCENT5, align=PP_ALIGN.CENTER)
sdt_lines = [
("Self-Determination Theory (Deci & Ryan):", True, 14, C_ACCENT5),
("", False, 6, C_LIGHT),
("Three psychological needs that drive sustainable exercise:", False, 13, C_LIGHT),
("", False, 6, C_LIGHT),
("🎯 Autonomy", True, 14, C_ACCENT3),
("Feeling in control of the choice to exercise.\nForced exercise kills intrinsic motivation.", False, 13, C_LIGHT),
("", False, 6, C_LIGHT),
("💪 Competence", True, 14, C_ACCENT2),
("Feeling capable and improving.\nWin-rate programming builds this — start easy.", False, 13, C_LIGHT),
("", False, 6, C_LIGHT),
("👥 Relatedness", True, 14, C_ACCENT1),
("Social connection in training (classes, partners,\ncommunity) dramatically improves adherence.", False, 13, C_LIGHT),
("", False, 8, C_LIGHT),
("📚 Research (Macali et al., 2025 — PMID 39972665):", True, 13, C_ACCENT3),
("Intrinsic motivation is the strongest predictor\nof long-term physical activity behavior.", False, 13, C_LIGHT),
]
add_multiline(s18, sdt_lines,
Inches(7.2), Inches(2.15), Inches(5.6), Inches(4.9),
default_size=13, align=PP_ALIGN.LEFT)
s18.notes_slide.notes_text_frame.text = (
"Key research: Macali et al. 2025 (PMID 39972665) systematic review on motivation & exercise. "
"Gerber et al. 2025 (PMID 39854639) on psychophysiological foundations of physical activity. "
"Coach point: understand which motivation type each client has before designing their program."
)
# ══════════════════════════════════════════════════════════════
# SLIDE 19 — COACHING FRAMEWORK FOR LAZY CLIENTS
# ══════════════════════════════════════════════════════════════
s19 = add_slide()
fill_bg(s19, C_BG_DARK)
header(s19, "🎯 Coaching Framework: Moving Clients From Lazy to Driven",
"Evidence-based strategies — SDT, behavioural activation, and habit science")
framework = [
(C_ACCENT3, "🔍 Step 1: Diagnose the Root Cause",
[
"Ask: Is it fear of failure? Perfectionism? Low self-efficacy? Boredom?",
"Use motivational interviewing: 'What would exercise give you that you don't have now?'",
"Never assume — each client has a different blockage.",
]),
(C_ACCENT2, "📐 Step 2: Design for WIN-RATE",
[
"Start clients at 60-70% of their perceived capability (not max effort).",
"Progressive overload is useless if clients drop out. Adherence first, intensity second.",
"Build competence fast — early wins create momentum.",
]),
(C_ACCENT5, "⚡ Step 3: Reduce Activation Energy",
[
"Help clients design their environment: kit bag ready, gym near commute route.",
"2-minute rule: commit to just showing up for 2 minutes. The session follows.",
"Habit stacking: 'After I [existing habit], I will [exercise action].'",
]),
(C_ACCENT1, "🏆 Step 4: Build Reward Loops",
[
"Immediate reward > delayed result. Celebrate effort, not just outcomes.",
"Use WhatsApp check-ins, milestone badges, social accountability.",
"Research: public commitment increases goal completion by up to 65%.",
]),
(C_ACCENT4, "📊 Step 5: Track Progress Visually",
[
"Show clients their own data — reps improved, weight moved, HRV recovering.",
"Visible progress is the strongest intrinsic motivator for continued effort.",
"Weekly reviews: What worked? What felt good? What do you want to do more of?",
]),
(C_ACCENT3, "🔄 Step 6: Reframe Setbacks",
[
"A missed session is data, not failure. Ask: what obstacle appeared?",
"Teach self-compassion — guilt about laziness increases inactivity (paradox!).",
"Identity shift: 'I am someone who moves every day' > 'I am trying to exercise.'",
]),
]
fw2 = Inches(5.85); fh2 = Inches(1.42)
fgx2 = Inches(0.45); fgy2 = Inches(0.08)
for i, (col, title, points) in enumerate(framework):
c = i % 2; r = i // 2
fx = Inches(0.35) + c * (fw2 + fgx2)
fy = Inches(1.5) + r * (fh2 + fgy2)
rounded_rect(s19, fx, fy, fw2, fh2, RGBColor(0x16, 0x18, 0x38))
accent_bar(s19, fx, fy, fh2, col)
add_textbox(s19, title,
fx + Inches(0.2), fy + Inches(0.08), fw2 - Inches(0.32), Inches(0.32),
size=14, bold=True, color=col, align=PP_ALIGN.LEFT)
body = " • " + "\n • ".join(points)
add_textbox(s19, body,
fx + Inches(0.2), fy + Inches(0.44), fw2 - Inches(0.32), Inches(0.9),
size=11.5, color=C_LIGHT, align=PP_ALIGN.LEFT, wrap=True)
s19.notes_slide.notes_text_frame.text = (
"Based on Self-Determination Theory (Deci & Ryan), Behavioural Activation research, "
"and habit science (BJ Fogg's Tiny Habits, James Clear's Atomic Habits). "
"Most relevant for clients who repeatedly miss sessions or start and stop."
)
# ══════════════════════════════════════════════════════════════
# SLIDE 20 — HRV & RECOVERY BIOMARKERS
# ══════════════════════════════════════════════════════════════
s20 = add_slide()
fill_bg(s20, C_BG_DARK)
header(s20, "📊 Recovery Biomarkers: Know When to Push, Know When to Rest",
"Objective tools to distinguish fatigue from laziness in real-time")
# Top section: HRV explained
rounded_rect(s20, Inches(0.35), Inches(1.45), Inches(12.6), Inches(2.0),
RGBColor(0x14, 0x1C, 0x38))
add_textbox(s20, "💓 Heart Rate Variability (HRV) — Your #1 Recovery Tool",
Inches(0.55), Inches(1.55), Inches(12.0), Inches(0.38),
size=16, bold=True, color=C_ACCENT5, align=PP_ALIGN.LEFT)
hrv_cols = [
("📐 What is HRV?",
C_ACCENT5,
"The variation in time between consecutive heartbeats. "
"Higher HRV = better parasympathetic tone = better recovered. "
"Measured via chest strap or modern smartwatch (Garmin, Whoop, Oura)."),
("📉 Low HRV Means...",
C_ACCENT1,
"Sympathetic nervous system dominance. Body is stressed/fatigued. "
"Train intensity should be REDUCED. Not laziness — it's a recovery signal. "
"< 20% of normal = consider complete rest day."),
("📈 High HRV Means...",
C_ACCENT2,
"Well-recovered. Body is ready for high-intensity work. "
"Green-light for hard training. "
"Best measured on waking, lying still, same time daily."),
]
hw = Inches(4.0); hh = Inches(1.42)
hgx = Inches(0.27)
for i, (title, col, body) in enumerate(hrv_cols):
hx = Inches(0.5) + i * (hw + hgx)
hy = Inches(1.88)
add_textbox(s20, title, hx, hy, hw, Inches(0.3),
size=13, bold=True, color=col, align=PP_ALIGN.LEFT)
add_textbox(s20, body, hx, hy + Inches(0.32), hw, Inches(0.98),
size=12, color=C_LIGHT, align=PP_ALIGN.LEFT, wrap=True)
divider(s20, Inches(3.58))
# Bottom: Biomarker grid
add_textbox(s20, "🔬 Other Key Biomarkers for Fitness Coaches",
Inches(0.55), Inches(3.68), Inches(12.0), Inches(0.38),
size=16, bold=True, color=C_ACCENT3, align=PP_ALIGN.LEFT)
biomarkers = [
("Resting Heart Rate (RHR)", C_ACCENT1,
"↑ RHR >5-7 bpm above baseline = incomplete recovery\nTrack daily on waking. Simple & free."),
("Sleep Quality Score", C_ACCENT4,
"Deep sleep % drops with overtraining. < 20% deep sleep = flag.\nOura Ring / Garmin / Apple Watch track this."),
("Subjective Wellness (1-10)", C_ACCENT3,
"Ask daily: Energy / Mood / Sleep quality / Muscle soreness.\nSurprisingly accurate — correlates well with HRV."),
("Grip Strength", C_ACCENT5,
"Morning grip strength < 10% below normal = CNS fatigue.\nSimple dynamometer test. Takes 10 seconds."),
("Creatine Kinase (CK)", C_ACCENT1,
"Blood test: ↑ CK indicates muscle damage. Normal < 200 U/L.\nUseful after very intense blocks. Requires lab test."),
("RPE & Training Load", C_ACCENT2,
"RPE (Rate of Perceived Exertion): client effort rating.\nAcute:chronic workload ratio > 1.5 = injury risk zone."),
]
bw = Inches(3.95); bh = Inches(1.0)
bgx = Inches(0.27); bgy = Inches(0.1)
for i, (label, col, desc) in enumerate(biomarkers):
bc = i % 3; br = i // 3
bx = Inches(0.35) + bc * (bw + bgx)
by = Inches(4.15) + br * (bh + bgy)
rounded_rect(s20, bx, by, bw, bh, RGBColor(0x18, 0x1C, 0x3C))
accent_bar(s20, bx, by, bh, col)
add_textbox(s20, label,
bx + Inches(0.2), by + Inches(0.06), bw - Inches(0.3), Inches(0.28),
size=13, bold=True, color=col, align=PP_ALIGN.LEFT)
add_textbox(s20, desc,
bx + Inches(0.2), by + Inches(0.38), bw - Inches(0.3), Inches(0.55),
size=11.5, color=C_LIGHT, align=PP_ALIGN.LEFT, wrap=True)
s20.notes_slide.notes_text_frame.text = (
"Sources: Bestwick-Stevenson et al. 2022 (PMID 35468639) — Assessment of Fatigue & Recovery in Sport. "
"Alba-Jiménez et al. 2022 (PMID 35324642) — Neuromuscular Fatigue in Team Sports. "
"Coach tip: Whoop and Oura Ring are consumer-grade HRV tools that work well for motivated clients."
)
# ══════════════════════════════════════════════════════════════
# SLIDE 21 — NUTRITION FOR ENERGY & PERFORMANCE
# ══════════════════════════════════════════════════════════════
s21 = add_slide()
fill_bg(s21, C_BG_DARK)
header(s21, "🥗 Nutrition Blueprint: Fuelling Against Fatigue",
"What to eat — and when — to protect performance and maximise recovery")
# Timing section
add_textbox(s21, "⏱️ Nutrient Timing for Fitness Clients",
Inches(0.5), Inches(1.48), Inches(12.2), Inches(0.35),
size=16, bold=True, color=C_ACCENT3, align=PP_ALIGN.LEFT)
timing = [
("🌅 Pre-Workout\n(1-2 hrs before)", C_ACCENT3,
"Complex carbs (oats, banana, rice)\n+ Moderate protein (20g)\n+ Low fat / low fibre\n→ Sustained glycogen availability"),
("⚡ Intra-Workout\n(> 60 min sessions)", C_ACCENT5,
"30-60g carbs per hour (gel, banana, diluted juice)\n+ Electrolytes (Na, K, Mg)\n→ Prevents peripheral fatigue from glycogen depletion"),
("🔄 Post-Workout\n(within 30-45 min)", C_ACCENT2,
"20-40g protein (whey or whole food)\n+ Fast carbs (glycogen replenishment)\n+ Antioxidants (berries, turmeric)\n→ Accelerates repair, reduces DOMS"),
("😴 Pre-Sleep\n(1 hr before bed)", C_ACCENT4,
"Slow protein: casein or Greek yoghurt (40g)\n+ Tryptophan-rich foods (turkey, milk, almonds)\n→ Overnight muscle protein synthesis + better sleep"),
]
tw_n = Inches(3.0); th_n = Inches(2.1)
tgx_n = Inches(0.27)
for i, (timeblock, col, detail) in enumerate(timing):
tx = Inches(0.35) + i * (tw_n + tgx_n)
ty = Inches(1.95)
rounded_rect(s21, tx, ty, tw_n, th_n, RGBColor(0x16, 0x1C, 0x38))
bar = s21.shapes.add_shape(1, tx, ty, tw_n, Inches(0.07))
bar.fill.solid(); bar.fill.fore_color.rgb = col; bar.line.fill.background()
add_textbox(s21, timeblock,
tx + Inches(0.12), ty + Inches(0.12), tw_n - Inches(0.24), Inches(0.5),
size=13, bold=True, color=col, align=PP_ALIGN.LEFT, wrap=True)
add_textbox(s21, detail,
tx + Inches(0.12), ty + Inches(0.65), tw_n - Inches(0.24), Inches(1.35),
size=12, color=C_LIGHT, align=PP_ALIGN.LEFT, wrap=True)
divider(s21, Inches(4.18))
# Key nutrients for energy
add_textbox(s21, "💊 Key Micronutrients That Directly Impact Fatigue",
Inches(0.5), Inches(4.28), Inches(12.2), Inches(0.35),
size=16, bold=True, color=C_ACCENT2, align=PP_ALIGN.LEFT)
nutrients = [
("🩸 Iron", C_ACCENT1, "Oxygen transport. Deficiency = anaemia = severe fatigue.\nSources: red meat, spinach, lentils + Vitamin C"),
("☀️ Vitamin D", C_ACCENT3, "Muscle function & mood. 70%+ of people are deficient.\nTest yearly. Supplement 1000-4000 IU/day in winter"),
("🧠 B12", C_ACCENT5, "Nerve function & energy. Deficiency causes profound fatigue.\nSources: meat, eggs, dairy. Vegans MUST supplement"),
("⚡ Magnesium", C_ACCENT2, "ATP synthesis, sleep, muscle relaxation. Very common deficiency.\nSources: nuts, seeds, dark chocolate, leafy greens"),
("💧 Hydration", C_ACCENT4, "Even 2% dehydration reduces performance by 10-20%.\n500ml water 2 hrs before training; 150-250ml every 15-20 min"),
("⚗️ Creatine", C_ACCENT3, "Most evidence-based ergogenic. Replenishes PCr stores.\n5g/day maintenance. Safe for long-term use."),
]
nw = Inches(3.9); nh = Inches(0.92)
ngx = Inches(0.27); ngy = Inches(0.1)
for i, (name, col, info) in enumerate(nutrients):
nc = i % 3; nr = i // 3
nx2 = Inches(0.35) + nc * (nw + ngx)
ny2 = Inches(4.72) + nr * (nh + ngy)
rounded_rect(s21, nx2, ny2, nw, nh, RGBColor(0x16, 0x22, 0x32))
accent_bar(s21, nx2, ny2, nh, col)
add_textbox(s21, name,
nx2 + Inches(0.2), ny2 + Inches(0.06), nw - Inches(0.32), Inches(0.28),
size=13, bold=True, color=col, align=PP_ALIGN.LEFT)
add_textbox(s21, info,
nx2 + Inches(0.2), ny2 + Inches(0.38), nw - Inches(0.32), Inches(0.48),
size=11.5, color=C_LIGHT, align=PP_ALIGN.LEFT, wrap=True)
s21.notes_slide.notes_text_frame.text = (
"Sources: Basic Medical Biochemistry 6e (glycogen depletion & metabolic fatigue). "
"Medical Physiology (ATP/anaerobic glycolysis). "
"Coach point: nutrition timing is often the most underrated performance variable for recreational clients."
)
# ══════════════════════════════════════════════════════════════
# SLIDE 22 — PERIODIZATION
# ══════════════════════════════════════════════════════════════
s22 = add_slide()
fill_bg(s22, C_BG_DARK)
header(s22, "📅 Periodization: Programming to Prevent Fatigue & Burn-Out",
"Structure your training cycles so clients get stronger — not just more tired")
# 3 periodization models
models = [
(C_ACCENT3, "📈 Linear Periodization",
"Classic model: gradually increase intensity, decrease volume over weeks.\n\n"
"Week 1-4: High volume, low-moderate intensity (hypertrophy)\n"
"Week 5-8: Moderate volume, moderate intensity (strength)\n"
"Week 9-12: Low volume, high intensity (power/peak)\n"
"Week 13: DELOAD — 50% volume, maintain intensity\n\n"
"Best for: beginners and intermediate clients with a single goal.",
"✅ Simple. Easy to track. Client-friendly."),
(C_ACCENT5, "🔄 Undulating Periodization",
"Vary intensity AND volume within the same week or even session.\n\n"
"Monday: Heavy (4x5 @ 85% 1RM)\n"
"Wednesday: Moderate (3x10 @ 70% 1RM)\n"
"Friday: Light/metabolic (3x15 @ 60% 1RM)\n\n"
"Prevents accommodation. Higher neuromuscular stimulus variety.\n"
"Best for: intermediate-advanced clients, multiple training goals.",
"⚡ More complex but superior long-term gains."),
(C_ACCENT2, "🗓️ Block Periodization",
"Train one primary quality at a time in 3-6 week 'blocks'.\n\n"
"Block 1 — Accumulation: volume + endurance base\n"
"Block 2 — Transmutation: convert base to sport-specific strength\n"
"Block 3 — Realisation: peak performance, competition prep\n\n"
"Allows full recovery between qualities. Prevents OTS.\n"
"Best for: advanced athletes with competitive goals.",
"🎯 Best OTS prevention model for serious clients."),
]
mw = Inches(4.0); mh = Inches(5.6)
mgx = Inches(0.27)
for i, (col, title, body, badge) in enumerate(models):
mx = Inches(0.35) + i * (mw + mgx)
my = Inches(1.45)
rounded_rect(s22, mx, my, mw, mh, RGBColor(0x14, 0x1A, 0x32))
bar = s22.shapes.add_shape(1, mx, my, mw, Inches(0.08))
bar.fill.solid(); bar.fill.fore_color.rgb = col; bar.line.fill.background()
add_textbox(s22, title,
mx + Inches(0.12), my + Inches(0.14), mw - Inches(0.24), Inches(0.38),
size=15, bold=True, color=col, align=PP_ALIGN.LEFT, wrap=True)
add_textbox(s22, body,
mx + Inches(0.12), my + Inches(0.58), mw - Inches(0.24), Inches(4.35),
size=12, color=C_LIGHT, align=PP_ALIGN.LEFT, wrap=True)
add_pill(s22, badge,
mx + Inches(0.12), my + Inches(5.2), mw - Inches(0.24), Inches(0.3),
RGBColor(0x20, 0x20, 0x44), tc=col, size=12)
s22.notes_slide.notes_text_frame.text = (
"Sources: Miller's Review of Orthopaedics 9e — training adaptation; "
"Grandou et al. 2020 (PMID 31820373) — systematic review on overtraining resistance exercise. "
"Coaching point: ALL serious clients need a deload every 4-8 weeks to prevent OTS. "
"Laziness after deload is normal — it's the body recovering, not failing."
)
# ── Save ─────────────────────────────────────────────────────────
out_path = "/tmp/workspace/fatigue-vs-laziness/Fatigue_vs_Laziness.pptx"
buf = BytesIO()
prs.save(buf)
with open(out_path, "wb") as f:
f.write(buf.getvalue())
print(f"✅ Saved: {out_path}")
print(f" Total slides: {len(prs.slides)}")
cd /tmp/workspace/fatigue-vs-laziness && python add_fitness_slides.py 2>&1
Fatigue vs Laziness
Presentation · PPTX
| # | Slide | What It Covers |
|---|---|---|
| 15 | Section Break | "Fitness Client Deep Dive" intro with topic pills |
| 16 | Neuroscience of Fatigue | Central vs. Peripheral fatigue side-by-side — neurotransmitters (serotonin/dopamine), NMJ failure, Ca²⁺ impairment, H⁺ accumulation. Coaching cues for each. |
| 17 | Inside the Muscle | Three mechanism cards (ATP/PCr depletion, metabolite accumulation, glycogen depletion) + muscle fibre type table (Type I, IIa, IIx) with training implications backed by orthopaedic textbook |
| 18 | Overtraining Syndrome | 3-stage OTS model (functional overreaching → non-functional → full OTS) with 8 warning signs to watch for in clients |
| 19 | Brain Science of Laziness | Dopamine reward system, D2 receptor downregulation from inactivity, Self-Determination Theory (Autonomy / Competence / Relatedness) with 2025 PubMed citation |
| 20 | Coaching Framework | 6-step evidence-based system to move clients from lazy to driven — diagnose root cause, design for win-rate, habit stacking, reward loops, visual tracking |
| 21 | HRV & Recovery Biomarkers | HRV explained for coaches, RHR tracking, subjective wellness scoring, grip strength, CK blood markers, acute:chronic workload ratio |
| 22 | Nutrition Blueprint | Pre/intra/post/pre-sleep nutrient timing + 6 key micronutrients (Iron, Vit D, B12, Magnesium, Hydration, Creatine) with dosing guidance |
| 23 | Periodization | Linear vs. Undulating vs. Block periodization models with full weekly programming examples and OTS prevention rationale |