#!/usr/bin/env python3
"""
Week 30: Multiplication Facts 6-10
Phase 5: Multiplication Introduction

Standards: 2.OA.A.1 — operations; times tables 6-10, commutative property,
strategies for harder facts (9s finger trick, 6s = 3s doubled)

New Standard:
- Reduced drill (4-6 problems per section)
- Estimation before calculating
- Multiple strategies (commutative flip, doubling, 9s trick)
- Better word problems (reasoning, real-world contexts)
- Open-ended challenges (Create Your Own)
- Number talks (explain WITHOUT calculating)
- Friday self-check with emoji reflection
"""

import os
import glob
from weasyprint import HTML

from math_helpers import (
    CSS, TEACHER_CSS,
    page, page_multi, hdr, sec, b, bw, bl,
    tg_page_multi, tg_sec, tg_note, tg_section_title,
    array_svg, eq_group_svg, grid_svg,
    star_svg, medal_svg, trophy_svg, check_svg,
    times_table_html, skip_count_html, mini_chart_html,
)
from activity_builders import (
    build_equal_groups,
    build_skip_counting,
    build_times_table,
    build_challenge_box,
    build_two_step_problems,
)

BASE = os.path.expanduser("~/Home_School/2nd_Grade/Math")
WEEK = os.path.join(BASE, "Week_30")


# ═══════════════════════════════════════════════════
# MONDAY — The Turn-Around Trick (Commutative Property)
# ═══════════════════════════════════════════════════
def monday():
    # 1: Fluency warmup — facts you already know (0-5)
    s1 = '<div class="abox" style="background:#e8f5e9;">'\
         '<p><b>2-min Fluency Warm-up</b> — Facts you already know!</p>'\
         '<div class="mgrid c3">'
    for f in ["5 × 4", "3 × 6", "2 × 8", "4 × 5", "5 × 7", "3 × 9"]:
        s1 += f'<div class="abox"><p>{f} = {b("3em")}</p></div>'
    s1 += '</div></div>'

    # 2: Commutative property — see it with arrays (guided)
    s2 = '<p class="note"><b>The Turn-Around Trick!</b> When you flip the numbers, '\
         'the answer stays the same. 6 × 3 = 3 × 6. Look — it\'s the same array, just turned!</p>'\
         '<div class="mgrid c2">'
    s2 += f'<div class="abox"><p>3 rows of 6</p>{array_svg(3, 6, width="110")}'\
          f'<p>3 × 6 = {b("3em")}</p></div>'
    s2 += f'<div class="abox"><p>6 rows of 3</p>{array_svg(6, 3, width="60")}'\
          f'<p>6 × 3 = {b("3em")}</p></div>'
    s2 += '</div>'\
          '<p class="note">So if you know your 0-5 facts, you ALREADY know most 6-10 facts!</p>'

    # 3: Use the turn-around trick (reduced from 8 to 4)
    s3 = '<p class="note">Flip each hard fact into an easy fact you already know, then solve.</p>'\
         '<div class="mgrid c2">'
    for a, c in [(7, 2), (8, 5), (9, 3), (6, 4)]:
        s3 += f'<div class="abox"><p><b>{a} × {c}</b> → flip it: {b("3em")} × {b("3em")}</p>'\
              f'<p>Answer: {b("3em")}</p></div>'
    s3 += '</div>'

    # 4: Number Talk — why flipping works
    s4 = '<div class="abox" style="background:#e3f2fd;">'\
         '<p><b>Number Talk</b> — Explain WITHOUT calculating.</p>'\
         '<div class="mgrid c2">'
    s4 += '<div class="abox"><p>Kim knows 5 × 8 = 40 but is stuck on 8 × 5.</p>'\
          '<p>What would you tell Kim?</p>'\
          '<p style="font-size:11px;">My thinking: ' + bw() + '</p></div>'
    s4 += '<div class="abox"><p>Does the turn-around trick work for SUBTRACTION? Is 8 − 5 the same as 5 − 8?</p>'\
          '<p style="font-size:11px;">My thinking: ' + bw() + '</p></div>'
    s4 += '</div></div>'

    # 5: Challenge
    s5 = build_challenge_box({
        "problems": [
            {"text": "Draw two arrays that prove 4 × 7 = 7 × 4 in the space below.<br><span style='display:block; min-height:80px; border:1px dashed #999; border-radius:4px;'></span>"},
            {"text": "Write two more turn-around pairs of your own: " + bw("10em") + " and " + bw("10em")},
        ]
    })

    return page(30, "Monday", "The Turn-Around Trick",
        f'''{sec(1, "Warm-up: Facts You Know", s1)}
{sec(2, "The Turn-Around Trick (Commutative Property)", s2)}
{sec(3, "Flip It to Solve It", s3)}
{sec(4, "Number Talk: Why Flipping Works", s4)}
{sec(5, "Challenge: Prove It", s5)}''')


# ═══════════════════════════════════════════════════
# TUESDAY — The 6s and 7s
# ═══════════════════════════════════════════════════
def tuesday():
    # 1: Fluency warmup — skip count by 6s and 7s
    s1 = '<div class="abox" style="background:#e8f5e9;">'\
         '<p><b>2-min Fluency Warm-up</b> — Skip count. Fill in the missing numbers.</p>'
    s1 += build_skip_counting({
        "sequences": [
            {"start": 6, "step": 6, "count": 8, "blank_indices": [3, 5, 7]},
            {"start": 7, "step": 7, "count": 8, "blank_indices": [2, 4, 6]},
        ],
        "note": "Count by 6s, then by 7s."
    })
    s1 += '</div>'

    # 2: 6s strategy — double the 3s!
    s2 = '<p class="note"><b>Strategy: 6s are 3s doubled!</b> To find 6 × 4: '\
         'first find 3 × 4 = 12, then double it: 24. Try it:</p>'\
         '<div class="mgrid c2">'
    for n in [5, 3, 7, 6]:
        s2 += f'<div class="abox"><p><b>6 × {n}</b></p>'\
              f'<p>3 × {n} = {b("5em")}</p>'\
              f'<p>Double it: {b("5em")}</p>'\
              f'<p>6 × {n} = {b("3em")}</p></div>'
    s2 += '</div>'

    # 3: Estimate First! — 6s and 7s
    s3 = '<div class="abox" style="background:#fff3e0;">'\
         '<p><b>Estimate First!</b> Circle MORE or LESS than 30, then solve.</p>'\
         '<div class="mgrid c2">'
    for g, n in [(6, 4), (7, 5), (6, 6), (7, 3)]:
        s3 += f'<div class="abox"><p><b>{g} × {n}</b></p>'\
              '<p>more than 30 / less than 30</p>'\
              f'<p>Actual: {b("3em")}</p></div>'
    s3 += '</div></div>'

    # 4: 7s times table with blanks (reduced drill)
    s4 = build_times_table({
        "factor": 7,
        "blanks": [3, 5, 7, 9],
        "note": "Fill in the missing 7s facts. Hint: use the turn-around trick for ones you know!"
    })

    # 5: Two strategies for one fact
    s5 = '<div class="abox" style="background:#f3e5f5;">'\
         '<p><b>Show Two Different Ways</b> — Solve <b>6 × 5</b> two ways.</p>'\
         '<p>Way 1 (turn-around trick): flip to 5 × 6 and skip count by 5: ' + bw("12em") + '</p>'\
         '<p>Way 2 (double the 3s): 3 × 5 = ___, doubled = ___</p>'\
         '<p>6 × 5 = ' + b("3em") + '</p>'\
         '<p style="font-size:11px; color:#666;">Which strategy do you like best? Why? ' + bw() + '</p>'\
         '</div>'

    return page(30, "Tuesday", "The 6s and 7s",
        f'''{sec(1, "Warm-up: Skip Count by 6s and 7s", s1)}
{sec(2, "Strategy: 6s are 3s Doubled", s2)}
{sec(3, "Estimate First!", s3)}
{sec(4, "The 7s Times Table", s4)}
{sec(5, "Show Two Different Ways", s5)}''')


# ═══════════════════════════════════════════════════
# WEDNESDAY — The 8s and 9s (with the 9s Trick!)
# ═══════════════════════════════════════════════════
def wednesday():
    # 1: Fluency warmup — skip count by 8s and 9s
    s1 = '<div class="abox" style="background:#e8f5e9;">'\
         '<p><b>2-min Fluency Warm-up</b> — Skip count. Fill in the missing numbers.</p>'
    s1 += build_skip_counting({
        "sequences": [
            {"start": 8, "step": 8, "count": 8, "blank_indices": [3, 5, 7]},
            {"start": 9, "step": 9, "count": 8, "blank_indices": [2, 4, 6]},
        ],
        "note": "Count by 8s, then by 9s."
    })
    s1 += '</div>'

    # 2: The amazing 9s pattern
    s2 = '<p class="note"><b>The 9s Secret!</b> Look at the 9s: 9, 18, 27, 36, 45... '\
         'The two digits of every answer <b>add up to 9</b>! (1+8=9, 2+7=9, 3+6=9). '\
         'And the tens digit is always ONE LESS than the number you multiplied. Try it:</p>'\
         '<div class="mgrid c2">'
    for n in [4, 6, 8, 7]:
        s2 += f'<div class="abox"><p><b>9 × {n}</b></p>'\
              f'<p>Tens digit (one less than {n}): {b("3em")}</p>'\
              f'<p>Ones digit (digits add to 9): {b("3em")}</p>'\
              f'<p>9 × {n} = {b("3em")}</p></div>'
    s2 += '</div>'

    # 3: 8s strategy — double, double, double!
    s3 = '<p class="note"><b>Strategy: 8s are triple-doubles!</b> To find 8 × 3: '\
         'double 3 (=6), double again (=12), double once more (=24). Try it:</p>'\
         '<div class="mgrid c2">'
    for n in [4, 2, 5, 3]:
        s3 += f'<div class="abox"><p><b>8 × {n}</b></p>'\
              f'<p>Double {n}: {b("5em")} → Double: {b("5em")} → Double: {b("5em")}</p>'\
              f'<p>8 × {n} = {b("3em")}</p></div>'
    s3 += '</div>'

    # 4: Word problems with 8s and 9s (reduced to 2)
    s4 = '<div class="wp">'\
         '<p class="note">Write the multiplication sentence and solve. Use any strategy!</p>'\
         '<div class="mgrid c2">'
    problems = [
        ("An octopus has 8 arms. How many arms do 3 octopuses have?", "arms"),
        ("A baseball team has 9 players. How many players are on 4 teams?", "players"),
    ]
    for text, unit in problems:
        s4 += f'<div class="abox"><p style="font-size:0.95em;">{text}</p>'\
              '<p>Multiplication sentence: ' + bw("9em") + '</p>'\
              '<p>' + b("4em") + f' {unit}</p></div>'
    s4 += '</div></div>'

    # 5: Number Talk — check with the 9s secret
    s5 = '<div class="abox" style="background:#e3f2fd;">'\
         '<p><b>Number Talk</b> — Explain WITHOUT multiplying.</p>'\
         '<div class="mgrid c2">'
    s5 += '<div class="abox"><p>Tom says 9 × 6 = 56.</p>'\
          '<p>Use the 9s secret to check — could 56 be right?</p>'\
          '<p style="font-size:11px;">My thinking: ' + bw() + '</p></div>'
    s5 += '<div class="abox"><p>Which is easier for YOU: 8 × 2 or 2 × 8? Why?</p>'\
          '<p style="font-size:11px;">My thinking: ' + bw() + '</p></div>'
    s5 += '</div></div>'

    return page(30, "Wednesday", "The 8s and 9s",
        f'''{sec(1, "Warm-up: Skip Count by 8s and 9s", s1)}
{sec(2, "The 9s Secret", s2)}
{sec(3, "Strategy: 8s are Triple-Doubles", s3)}
{sec(4, "Word Problems", s4)}
{sec(5, "Number Talk: Check It!", s5)}''')


# ═══════════════════════════════════════════════════
# THURSDAY — The 10s & Mixed Word Problems
# ═══════════════════════════════════════════════════
def thursday():
    # 1: Fluency warmup — 10s (the easiest!)
    s1 = '<div class="abox" style="background:#e8f5e9;">'\
         '<p><b>2-min Fluency Warm-up</b> — 10s are easy: just add a zero!</p>'\
         '<div class="mgrid c3">'
    for f in ["10 × 3", "10 × 7", "10 × 5", "10 × 9", "10 × 6", "10 × 10"]:
        s1 += f'<div class="abox"><p>{f} = {b("3em")}</p></div>'
    s1 += '</div></div>'

    # 2: Better word problems (reduced to 3)
    s2 = '<div class="wp">'\
         '<p class="note">Underline the important numbers. Pick a strategy, write the sentence, and solve.</p>'\
         '<div class="mgrid c2">'
    problems = [
        ("A box of crayons has 8 crayons. The art teacher buys 4 boxes. How many crayons did she buy?", "crayons"),
        ("There are 7 days in a week. How many days are in 3 weeks?", "days"),
        ("A dime is worth 10 cents. Maria has 6 dimes. How many cents does she have?", "cents"),
    ]
    for text, unit in problems:
        s2 += f'<div class="abox"><p style="font-size:0.95em;">{text}</p>'\
              '<p>Multiplication sentence: ' + bw("9em") + '</p>'\
              '<p>' + b("4em") + f' {unit}</p></div>'
    s2 += '</div></div>'

    # 3: Two-step problem
    s3 = '<div class="abox">'\
         '<p class="note">Solve step by step.</p>'\
         + build_two_step_problems({
             "problems": [
                 {
                     "text": "A garden has 6 rows of 6 carrots. Rabbits eat 10 carrots. How many carrots are left in the garden?",
                     "blanks": 2
                 }
             ],
             "note": "Step 1: multiply to find the total. Step 2: subtract."
         }) + '</div>'

    # 4: Number Talk — pick the smart strategy
    s4 = '<div class="abox" style="background:#e3f2fd;">'\
         '<p><b>Number Talk</b> — Don\'t solve! Just tell WHICH strategy you would pick and why.</p>'\
         '<div class="mgrid c2">'
    s4 += '<div class="abox"><p><b>9 × 7</b></p>'\
          '<p>9s secret? Turn-around? Skip count?</p>'\
          '<p style="font-size:11px;">I would use: ' + bw() + '</p></div>'
    s4 += '<div class="abox"><p><b>6 × 8</b></p>'\
          '<p>Double the 3s? Triple-double the 8s?</p>'\
          '<p style="font-size:11px;">I would use: ' + bw() + '</p></div>'
    s4 += '</div></div>'

    # 5: Create your own
    s5 = '<div class="abox" style="background:#f3e5f5;">'\
         '<p><b>Create Your Own Word Problem</b></p>'\
         '<p>Write a word problem using a 6, 7, 8, 9, or 10 fact. '\
         'Ideas: spider legs (8), days in a week (7), fingers (10)... Then solve it.</p>'\
         '<p style="min-height:60px; border-bottom:1px solid #333;"></p>'\
         '<p style="min-height:30px; border-bottom:1px solid #333;"></p>'\
         '<p>Multiplication sentence: ' + bw("9em") + '</p>'\
         '<p>Answer: ' + bl() + '</p>'\
         '</div>'

    return page(30, "Thursday", "The 10s & Mixed Word Problems",
        f'''{sec(1, "Warm-up: The Easy 10s", s1)}
{sec(2, "Word Problems", s2)}
{sec(3, "Two-Step Problem", s3)}
{sec(4, "Number Talk: Pick Your Strategy", s4)}
{sec(5, "Challenge: Create Your Own", s5)}''')


# ═══════════════════════════════════════════════════
# FRIDAY — Review & Self-Check
# ═══════════════════════════════════════════════════
def friday():
    # 1: Fluency warmup — mixed 6-10 facts
    s1 = '<div class="abox" style="background:#e8f5e9;">'\
         '<p><b>2-min Fluency Warm-up</b> — Show what you know! Use any strategy.</p>'\
         '<div class="mgrid c3">'
    for f in ["6 × 4", "7 × 3", "8 × 5", "9 × 2", "10 × 8", "6 × 6"]:
        s1 += f'<div class="abox"><p>{f} = {b("3em")}</p></div>'
    s1 += '</div></div>'

    # 2: Estimate First!
    s2 = '<div class="abox" style="background:#fff3e0;">'\
         '<p><b>Estimate First!</b> Circle MORE or LESS than 40, then solve.</p>'\
         '<div class="mgrid c2">'
    for g, n in [(6, 5), (9, 5), (7, 7), (8, 4)]:
        s2 += f'<div class="abox"><p><b>{g} × {n}</b></p>'\
              '<p>more than 40 / less than 40</p>'\
              f'<p>Actual: {b("3em")}</p></div>'
    s2 += '</div></div>'

    # 3: Strategy match-up review
    s3 = '<div class="abox">'\
         '<p class="note">Solve each fact AND name the strategy you used '\
         '(turn-around, 9s secret, doubling, skip count, add a zero).</p>'\
         '<div class="mgrid c2">'
    for f in ["9 × 8", "6 × 3", "10 × 7", "8 × 3"]:
        s3 += f'<div class="abox"><p><b>{f}</b> = {b("3em")}</p>'\
              '<p style="font-size:11px;">Strategy I used: ' + bw() + '</p></div>'
    s3 += '</div></div>'

    # 4: Word problem review (reduced to 2)
    s4 = '<div class="wp">'\
         '<p class="note">Write the multiplication sentence and solve.</p>'\
         '<div class="mgrid c2">'
    problems = [
        ("A carton holds 6 eggs. How many eggs are in 5 cartons?", "eggs"),
        ("Each pack of trading cards has 9 cards. Kai buys 3 packs. How many cards does he get?", "cards"),
    ]
    for text, unit in problems:
        s4 += f'<div class="abox"><p style="font-size:0.95em;">{text}</p>'\
              '<p>Multiplication sentence: ' + bw("9em") + '</p>'\
              '<p>' + b("4em") + f' {unit}</p></div>'
    s4 += '</div></div>'

    # 5: Self-check with emoji reflection + celebration
    s5 = '<div class="selfcheck">'\
         f'<p>{trophy_svg()} <b>You finished ALL the times tables 0-10! Self-Check time:</b></p>'\
         '<div style="display:flex; gap:20px; flex-wrap:wrap;">'\
         '<div style="background:#fff3e0; padding:10px; border-radius:5px; flex:1; min-width:150px;">'\
         '<p><b>Turn-Around Trick</b></p>'\
         '<p>😊 I got it!  |  😐 Getting there  |  😟 Need help</p>'\
         '</div>'\
         '<div style="background:#e3f2fd; padding:10px; border-radius:5px; flex:1; min-width:150px;">'\
         '<p><b>6s, 7s, 8s Facts</b></p>'\
         '<p>😊 I got it!  |  😐 Getting there  |  😟 Need help</p>'\
         '</div>'\
         '<div style="background:#f3e5f5; padding:10px; border-radius:5px; flex:1; min-width:150px;">'\
         '<p><b>9s Secret &amp; 10s</b></p>'\
         '<p>😊 I got it!  |  😐 Getting there  |  😟 Need help</p>'\
         '</div>'\
         '</div>'\
         '<p style="margin-top:10px;"><b>One thing I learned this week:</b> ' + bl() + '</p>'\
         '<p><b>My favorite multiplication strategy:</b> ' + bl() + '</p>'\
         '<p><b>The fact I want to practice more:</b> ' + b("6em") + '</p>'\
         '</div>'

    return page(30, "Friday", "Week 30 Review & Self-Check",
        f'''{sec(1, "Warm-up: Mixed Facts", s1)}
{sec(2, "Estimate First!", s2)}
{sec(3, "Strategy Match-Up", s3)}
{sec(4, "Word Problems", s4)}
{sec(5, "Self-Check & Celebration", s5)}''')


# ═══════════════════════════════════════════════════
# TEACHER GUIDE — Combined for all days
# ═══════════════════════════════════════════════════
def teacher_guide():
    return tg_page_multi(
        "Week 30", "Multiplication Facts 6-10 — Teacher Guide",

        # Monday
        tg_section_title("Monday: The Turn-Around Trick") +
        tg_sec(1, "Warm-up", ["20, 18, 16, 20, 35, 27"]) +
        tg_sec(2, "Commutative", ["Both arrays = 18 — same dots, turned sideways"]) +
        tg_sec(3, "Flip It", ["7×2→2×7=14; 8×5→5×8=40; 9×3→3×9=27; 6×4→4×6=24"]) +
        tg_sec(4, "Number Talk", ["8×5 = 5×8 = 40 (turn-around)", "No! Subtraction is NOT commutative"]) +
        tg_sec(5, "Challenge", ["4×7 and 7×4 arrays both show 28; accept any valid pairs"]) +
        tg_note("Page break"),

        # Tuesday
        tg_section_title("Tuesday: 6s and 7s") +
        tg_sec(1, "Warm-up", ["6s blanks: 24, 36, 48 | 7s blanks: 21, 35, 49"]) +
        tg_sec(2, "6s = 3s doubled", ["6×5: 15→30; 6×3: 9→18; 6×7: 21→42; 6×6: 18→36"]) +
        tg_sec(3, "Estimate First", ["6×4=24 less; 7×5=35 more; 6×6=36 more; 7×3=21 less"]) +
        tg_sec(4, "7s Table blanks", ["7×3=21, 7×5=35, 7×7=49, 7×9=63"]) +
        tg_sec(5, "Two Ways", ["Skip count: 5,10,15,20,25,30; 3×5=15 doubled=30; answer 30"]) +
        tg_note("Page break"),

        # Wednesday
        tg_section_title("Wednesday: 8s and 9s") +
        tg_sec(1, "Warm-up", ["8s blanks: 32, 48, 64 | 9s blanks: 27, 45, 63"]) +
        tg_sec(2, "9s Secret", ["9×4=36 (3,6); 9×6=54 (5,4); 9×8=72 (7,2); 9×7=63 (6,3)"]) +
        tg_sec(3, "8s Triple-Double", ["8×4: 8→16→32; 8×2: 4→8→16; 8×5: 10→20→40; 8×3: 6→12→24"]) +
        tg_sec(4, "Word Problems", ["3×8=24 arms; 4×9=36 players"]) +
        tg_sec(5, "Number Talk", ["56: 5+6=11≠9, so wrong (9×6=54)", "Accept either — same answer by turn-around"]) +
        tg_note("Page break"),

        # Thursday
        tg_section_title("Thursday: 10s & Mixed Word Problems") +
        tg_sec(1, "Warm-up 10s", ["30, 70, 50, 90, 60, 100"]) +
        tg_sec(2, "Word Problems", ["4×8=32 crayons; 3×7=21 days; 6×10=60 cents"]) +
        tg_sec(3, "Two-Step", ["Step 1: 6×6=36. Step 2: 36−10=26 carrots"]) +
        tg_sec(4, "Number Talk", ["9×7: any valid strategy (9s secret gives 63)", "6×8: any valid strategy (48)"]) +
        tg_sec(5, "Create Own", ["Accept student problems with a 6-10 fact"]) +
        tg_note("Page break"),

        # Friday
        tg_section_title("Friday: Review & Self-Check") +
        tg_sec(1, "Warm-up", ["24, 21, 40, 18, 80, 36"]) +
        tg_sec(2, "Estimate First", ["6×5=30 less; 9×5=45 more; 7×7=49 more; 8×4=32 less"]) +
        tg_sec(3, "Strategy Match", ["9×8=72; 6×3=18; 10×7=70; 8×3=24 — any valid strategy name"]) +
        tg_sec(4, "Word Problems", ["5×6=30 eggs; 3×9=27 cards"]) +
        tg_sec(5, "Self-Check", ["Accept student self-assessment; celebrate finishing 0-10!"])
    )


# ═══════════════════════════════════════════════════
# GENERATE
# ═══════════════════════════════════════════════════
if __name__ == "__main__":
    os.makedirs(WEEK, exist_ok=True)
    for f in glob.glob(os.path.join(WEEK, "*.pdf")):
        os.remove(f)
    for f in glob.glob(os.path.join(WEEK, "*.html")):
        os.remove(f)

    days = [
        (monday, "Monday", "The Turn-Around Trick"),
        (tuesday, "Tuesday", "The 6s and 7s"),
        (wednesday, "Wednesday", "The 8s and 9s"),
        (thursday, "Thursday", "The 10s & Mixed Word Problems"),
        (friday, "Friday", "Week 30 Review & Self-Check"),
    ]

    for lesson_func, day, title in days:
        html = lesson_func()
        fname = f"Week_30_{day}"
        path = os.path.join(WEEK, f"{fname}.html")
        with open(path, "w") as f:
            f.write(html)
        pdf_path = os.path.join(WEEK, f"{fname}.pdf")
        HTML(filename=path).write_pdf(pdf_path)
        print(f"Generated: {pdf_path}")

    html = teacher_guide()
    path = os.path.join(WEEK, "Week_30_Teacher_Guide.html")
    with open(path, "w") as f:
        f.write(html)
    pdf_path = os.path.join(WEEK, "Week_30_Teacher_Guide.pdf")
    HTML(filename=path).write_pdf(pdf_path)
    print(f"Generated: {pdf_path}")

    print("\nWeek 30 (Multiplication Facts 6-10) complete!")