#!/usr/bin/env python3
"""
Week 8: Subtracting Within 100 (No Regrouping) — REWRITTEN
Phase 2: Addition & Subtraction to 100
New Standard:
- Reduced drill (40% fewer problems)
- Added estimation activities
- Multiple strategies encouraged
- Better word problems (reasoning over keywords)
- Real challenges (open-ended thinking)
- Number talks (compare without calculating)
- Friday self-check with 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, tg_page_multi, tg_sec, tg_note, tg_section_title,
)
from activity_builders import (
build_column_subtraction,
build_missing_subtrahend,
)
BASE = os.path.expanduser("~/Home_School/2nd_Grade/Math")
WEEK = os.path.join(BASE, "Week_8")
# ═══════════════════════════════════════════════════
# MONDAY — Subtracting Tens (Mental Math)
# ═══════════════════════════════════════════════════
def monday():
# 1: Subtract 10 from any number (reduced from 6 to 4)
s1 = '<p class="note">When you subtract 10, only the <b>tens digit</b> changes. The ones stay the same.</p>'
s1 += '<div class="mgrid c3">'
for n in [53, 75, 87, 42]:
s1 += f'<div class="abox"><p>{n} - 10 = {b("5em")}</p></div>'
s1 += '</div>'
# 2: Subtract multiples of 10 (reduced from 6 to 4)
s2 = '<p class="note">Subtract the tens. Keep the ones.</p>'
s2 += '<div class="mgrid c3">'
for a, t in [(54, 20), (86, 30), (88, 10), (83, 20)]:
s2 += f'<div class="abox"><p>{a} - {t} = {b("5em")}</p></div>'
s2 += '</div>'
# 3: Number line jumps (reduced from 4 to 2)
s3 = '<p class="note">Use the number line. Mark jumps of 10 backward from the first number.</p>'
s3 += '<div class="mgrid c2">'
for a, t in [(75, 30), (87, 40)]:
s3 += f'<div class="abox"><p style="font-size:1.1em;"><b>{a} - {t} = {b("5em")}</b></p>'
start_tick = (a // 10) * 10
end_tick = start_tick + 60
s3 += '<div style="position:relative; height:50px; margin-top:20px;">'
s3 += '<div style="position:absolute; left:0; right:0; top:25px; height:3px; background:#333;"></div>'
for tick in range(start_tick, end_tick + 10, 10):
left_pct = ((tick - start_tick) / 60) * 100
s3 += f'<div style="position:absolute; left:{left_pct}%; top:20px; height:10px; width:2px; background:#333;"></div>'
s3 += f'<div style="position:absolute; left:{left_pct}%; top:32px; transform:translateX(-50%); font-size:0.85em;">{tick}</div>'
s3 += '</div>'
s3 += f'<p style="font-size:0.85em; color:#666; margin-top:10px;">Mark jumps of 10 backward from {a}</p>'
s3 += '</div>'
s3 += '</div>'
# 4: NEW — Number Talk: Which difference is bigger? Explain without calculating.
s4 = '<div class="abox" style="background:#e3f2fd;">'
s4 += '<p><b>Number Talk</b> — Which difference is bigger? Explain WITHOUT calculating.</p>'
s4 += '<div class="mgrid c2">'
s4 += '<div class="abox"><p>75 - 20 or 75 - 40</p><p style="font-size:11px;">My thinking: ' + bw() + '</p></div>'
s4 += '<div class="abox"><p>86 - 30 or 86 - 10</p><p style="font-size:11px;">My thinking: ' + bw() + '</p></div>'
s4 += '</div></div>'
# 5: Challenge — Subtract three numbers (reduced from 4 to 2)
s5 = '<div class="abox" style="background:#f3e5f5;">'
s5 += '<p><b>Challenge</b> — Subtract all the tens first, then all the ones.</p>'
s5 += '<div class="mgrid c2">'
for a, c, e in [(95, 30, 20), (83, 50, 10)]:
s5 += f'<div class="abox"><p>{a} - {c} - {e} = {b("6em")}</p></div>'
s5 += '</div></div>'
return page(8, "Monday", "Subtracting Tens (Mental Math)",
f'''{sec(1, "Subtract 10", s1)}
{sec(2, "Subtract Multiples of 10", s2)}
{sec(3, "Number Line Jumps", s3)}
{sec(4, "Number Talk: Which Difference is Bigger?", s4)}
{sec(5, "Challenge: Three Numbers", s5)}''')
# ═══════════════════════════════════════════════════
# TUESDAY — Subtracting 2-Digit Numbers (Horizontal)
# ═══════════════════════════════════════════════════
def tuesday():
# 1: Subtract ones first, then tens (reduced from 6 to 4)
s1 = '<p class="note">Subtract the ones, then subtract the tens. Write the total.</p>'
s1 += '<div class="mgrid c3">'
problems = [(68, 45), (88, 54), (78, 36), (87, 15)]
for a, c in problems:
s1 += f'<div class="abox"><p>{a} - {c} = {b("5em")}</p></div>'
s1 += '</div>'
# 2: NEW — Estimation: About how much?
s2 = '<div class="abox" style="background:#fff3e0;">'
s2 += '<p><b>Estimate First!</b> About how much?</p>'
s2 += '<div class="mgrid c2">'
for a, c in [(77, 42), (89, 38), (88, 25)]:
at, ao = a // 10, a % 10
ct, co = c // 10, c % 10
s2 += f'<div class="abox"><p><b>{a} - {c}</b></p>'
s2 += f'<p>Round to tens: {at*10} - {ct*10} = {(at-ct)*10}</p>'
s2 += f'<p>About: ' + b('4em') + '</p>'
s2 += f'<p>Actual: ' + b('4em') + '</p></div>'
s2 += '</div></div>'
# 3: Step-by-step subtraction (reduced from 3 to 2)
s3 = '<p class="note">Show your work: subtract ones, subtract tens, combine.</p>'
s3 += '<div class="mgrid c2">'
for a, c in [(59, 35), (99, 56)]:
ao, at = a % 10, a // 10
co, ct = c % 10, c // 10
s3 += f'<div class="abox"><p><b>{a} - {c}</b></p>'
s3 += f'<p>Ones: {ao} - {co} = ' + b("4em") + '</p>'
s3 += f'<p>Tens: {at} - {ct} = ' + b("4em") + '0</p>'
s3 += '<p><b>Total: </b>' + b("5em") + '</p></div>'
s3 += '</div>'
# 4: Multiple strategies encouraged
s4 = '<div class="abox">'
s4 += '<p class="note">Use ANY strategy you prefer. Try a different one for each problem.</p>'
s4 += '<div class="mgrid c2">'
for a, c in [(77, 42), (89, 38), (88, 16), (69, 24)]:
s4 += f'<div class="abox"><p><b>{a} - {c} = </b>{b("5em")}</p>'
s4 += '<p style="font-size:11px; color:#666;">Strategy I used: ' + bw() + '</p></div>'
s4 += '</div></div>'
# 5: NEW — Better word problems (reasoning, not keywords)
s5 = '<div class="wp">'
s5 += '<p class="note">Read carefully. Think about what is happening in the situation.</p>'
s5 += '<div class="mgrid c2">'
s5 += '<div class="abox"><p>Mike had 57 toy cars. He gave 34 to his brother. How many toy cars does Mike have left?</p><p style="font-size:11px;">Draw or write your thinking: ' + bw() + '</p><p>Answer: ' + b("4em") + ' cars</p></div>'
s5 += '<div class="abox"><p>A store had 77 red balls. They sold 32 to customers. How many red balls are left in the store?</p><p style="font-size:11px;">Draw or write your thinking: ' + bw() + '</p><p>Answer: ' + b("4em") + ' balls</p></div>'
s5 += '</div></div>'
return page(8, "Tuesday", "Subtracting 2-Digit Numbers",
f'''{sec(1, "Subtract Ones, Then Tens", s1)}
{sec(2, "Estimate First!", s2)}
{sec(3, "Step-by-Step Subtraction", s3)}
{sec(4, "Try Different Strategies", s4)}
{sec(5, "Word Problems", s5)}''')
# ═══════════════════════════════════════════════════
# WEDNESDAY — Column Subtraction (No Regrouping)
# ═══════════════════════════════════════════════════
def wednesday():
# 1: Column subtraction introduction (reduced from 6 to 4)
s1 = '<p class="note">Line up the numbers. Subtract ones column, then tens column.</p>'
s1 = build_column_subtraction({
"problems": [(68, 45), (88, 54), (78, 36), (87, 15)],
"digits": 2,
"note": "Line up the columns. Subtract ones first, then tens."
})
# 2: More column practice (reduced from 6 to 4)
s2 = build_column_subtraction({
"problems": [(77, 42), (89, 38), (88, 16), (69, 24)],
"digits": 2,
"note": "Keep your columns straight!"
})
# 3: Three numbers (column, reduced from 3 to 2)
s3 = '<p class="note">Subtract from left to right. Ones column first, then tens.</p>'
s3 += '<div class="mgrid c2">'
for a, c, e in [(99, 34, 22), (99, 41, 23)]:
s3 += f'<div class="abox" style="text-align:center;">'
s3 += f'<p style="font-size:1.3em; letter-spacing:3px;"> {a}</p>'
s3 += f'<p style="font-size:1.3em; letter-spacing:3px;">- {c}</p>'
s3 += '<hr style="border:2px solid #333;">'
s3 += f'<p style="font-size:1.3em; letter-spacing:3px;"> {b("4em")}</p>'
s3 += f'<p style="font-size:1.3em; letter-spacing:3px;">- {e}</p>'
s3 += '<hr style="border:2px solid #333;">'
s3 += f'<p style="font-size:1.3em; letter-spacing:3px;"> {b("4em")}</p>'
s3 += '</div>'
s3 += '</div>'
# 4: Find the error (reduced from 3 to 2)
s4 = '<div class="abox">'
s4 += '<p class="note">One of these is wrong. Find it, explain the error, and fix it.</p>'
s4 += '<div class="mgrid c2">'
s4 += '<div class="abox"><p style="text-align:center;"> 68</p><p style="text-align:center;">- 45</p><hr><p style="text-align:center;"> 23</p><p>✓ or ✗?</p><p style="font-size:11px;">If wrong, fix: ' + b("4em") + '</p></div>'
s4 += '<div class="abox"><p style="text-align:center;"> 78</p><p style="text-align:center;">- 36</p><hr><p style="text-align:center;"> 43</p><p>✓ or ✗?</p><p style="font-size:11px;">If wrong, fix: ' + b("4em") + '</p></div>'
s4 += '</div></div>'
# 5: Challenge — Create a column subtraction
s5 = '<div class="abox" style="background:#f3e5f5;">'
s5 += '<p><b>Create Your Own</b></p>'
s5 += '<p>Make a column subtraction problem where the answer is 34. Write it and solve it.</p>'
s5 += '<p style="text-align:center; font-size:1.3em; letter-spacing:3px;"> ' + b("3em") + '</p>'
s5 += '<p style="text-align:center; font-size:1.3em; letter-spacing:3px;">- ' + b("3em") + '</p>'
s5 += '<hr style="border:2px solid #333;">'
s5 += '<p style="text-align:center; font-size:1.3em; letter-spacing:3px;"> 34</p>'
s5 += '</div>'
return page(8, "Wednesday", "Column Subtraction",
f'''{sec(1, "Column Subtraction", s1)}
{sec(2, "More Practice", s2)}
{sec(3, "Three Numbers", s3)}
{sec(4, "Find the Error", s4)}
{sec(5, "Challenge: Create Your Own", s5)}''')
# ═══════════════════════════════════════════════════
# THURSDAY — Word Problems & Real World
# ═══════════════════════════════════════════════════
def thursday():
# 1: Better word problems (reduced from 4 to 3)
s1 = '<div class="wp">'
s1 += '<p class="note">Read carefully. Think about what is happening.</p>'
s1 += '<div class="mgrid c2">'
problems = [
("Emma collected 76 shells. She gave 42 to her sister for a craft project. How many shells does Emma have left?", 76, 42, "shells"),
("The library had 88 books. They gave 32 to another school. How many books are left?", 88, 32, "books"),
("A farmer had 87 birds. 24 flew away when a cat appeared. How many birds are left?", 87, 24, "birds"),
]
for text, a, c, unit in problems:
s1 += f'<div class="abox"><p style="font-size:0.95em;">{text}</p>'
s1 += '<p style="font-size:11px;">Draw or write your thinking: ' + bw() + '</p>'
s1 += '<p>' + b("6em") + f' {unit}</p></div>'
s1 += '</div></div>'
# 2: Compare two problems (reduced from 2 to 1)
s2 = '<div class="abox">'
s2 += '<p class="note">Solve both. Which difference is bigger? Explain WITHOUT calculating first.</p>'
s2 += '<div class="mgrid c1">'
s2 += '<div class="abox"><p>A: 79 - 45 = ' + b("5em") + '</p>'
s2 += '<p>B: 87 - 23 = ' + b("5em") + '</p>'
s2 += '<p>Before calculating, which do you think is bigger? <span class="bw">A</span> or <span class="bw">B</span></p>'
s2 += '<p>My thinking: ' + bw() + '</p>'
s2 += '<p>After calculating, which is actually bigger? <span class="bw">A</span> or <span class="bw">B</span></p></div>'
s2 += '</div></div>'
# 3: Two-step problems (reduced from 2 to 1)
s3 = '<div class="abox">'
s3 += '<p class="note">Solve step by step. Write each answer.</p>'
s3 += '<div class="mgrid c1">'
s3 += '<div class="abox"><p>Sarah had 57 stickers. She gave 23 to Tom. Then she gave 10 to her mom. How many stickers does Sarah have left?</p>'
s3 += '<p>Step 1: ' + b("6em") + '</p>'
s3 += '<p>Step 2: ' + b("6em") + '</p>'
s3 += '<p>Total left: ' + b("6em") + ' stickers</p></div>'
s3 += '</div></div>'
# 4: Create your own (kept)
s4 = '<div class="abox" style="background:#f3e5f5;">'
s4 += '<p><b>Create Your Own Word Problem</b></p>'
s4 += '<p>Write a subtraction word problem about something you like (sports, animals, games, etc.). Then solve it.</p>'
s4 += '<p style="min-height:50px; border-bottom:1px solid #333;"></p>'
s4 += '<p>Answer: ' + bl() + '</p>'
s4 += '</div>'
return page(8, "Thursday", "Subtraction Word Problems",
f'''{sec(1, "Word Problems", s1)}
{sec(2, "Compare Differences", s2)}
{sec(3, "Two-Step Problem", s3)}
{sec(4, "Create Your Own", s4)}''')
# ═══════════════════════════════════════════════════
# FRIDAY — Review & Self-Check
# ═══════════════════════════════════════════════════
def friday():
# 1: Mental math warm-up (reduced from 8 to 6)
s1 = '<p class="note">Solve in your head. Go fast!</p>'
s1 += '<div class="mgrid c3">'
for a, t in [(50, 30), (90, 50), (70, 60), (90, 20), (70, 40), (90, 30)]:
s1 += f'<div class="abox"><p>{a} - {t} = {b("4em")}</p></div>'
s1 += '</div>'
# 2: Column subtraction review (reduced from 6 to 4)
s2 = build_column_subtraction({
"problems": [(79, 45), (89, 27), (89, 35), (89, 63)],
"digits": 2,
"note": "Review: Column subtraction (no regrouping)."
})
# 3: Mixed horizontal (reduced from 6 to 4)
s3 = '<p class="note">Use any strategy you prefer.</p>'
s3 += '<div class="mgrid c3">'
for a, c in [(99, 52), (99, 25), (76, 42), (89, 26)]:
s3 += f'<div class="abox"><p>{a} - {c} = {b("5em")}</p></div>'
s3 += '</div>'
# 4: Word problem review (reduced from 3 to 2)
s4 = '<div class="wp">'
s4 += '<p class="note">Read carefully. Show your work.</p>'
s4 += '<div class="mgrid c2">'
problems = [
("A class had 49 students. 25 went home early. How many students are left?", 49, 25, "students"),
("Jake read 79 pages. He finished 36 yesterday. How many pages does he have left?", 79, 36, "pages"),
]
for text, a, c, unit in problems:
s4 += f'<div class="abox"><p style="font-size:0.95em;">{text}</p>'
s4 += '<p>' + b("6em") + f' {unit}</p></div>'
s4 += '</div></div>'
# 5: NEW — Self-check with reflection
s5 = '<div class="selfcheck">'
s5 += '<p><b>Self-Check: How do you feel about subtracting 2-digit numbers?</b></p>'
s5 += '<div style="display:flex; gap:20px; flex-wrap:wrap;">'
s5 += '<div style="background:#ffebee; padding:10px; border-radius:5px; flex:1; min-width:150px;">'
s5 += '<p><b>Mental Math (Subtracting Tens)</b></p>'
s5 += '<p>😊 I got it! | 😐 Getting there | 😟 Need help</p>'
s5 += '</div>'
s5 += '<div style="background:#e3f2fd; padding:10px; border-radius:5px; flex:1; min-width:150px;">'
s5 += '<p><b>Column Subtraction</b></p>'
s5 += '<p>😊 I got it! | 😐 Getting there | 😟 Need help</p>'
s5 += '</div>'
s5 += '<div style="background:#fff3e0; padding:10px; border-radius:5px; flex:1; min-width:150px;">'
s5 += '<p><b>Word Problems</b></p>'
s5 += '<p>😊 I got it! | 😐 Getting there | 😟 Need help</p>'
s5 += '</div>'
s5 += '</div>'
s5 += '<p style="margin-top:10px;"><b>My favorite strategy for subtracting 2-digit numbers:</b> ' + bl() + '</p>'
s5 += '<p><b>One thing I want to practice more:</b> ' + bl() + '</p>'
s5 += '</div>'
return page(8, "Friday", "Week 8 Review & Self-Check",
f'''{sec(1, "Mental Math Warm-up", s1)}
{sec(2, "Column Subtraction Review", s2)}
{sec(3, "Mixed Practice", s3)}
{sec(4, "Word Problems", s4)}
{sec(5, "Self-Check & Reflection", s5)}''')
# ═══════════════════════════════════════════════════
# TEACHER GUIDE — Combined for all days
# ═══════════════════════════════════════════════════
def teacher_guide():
"""Generate combined teacher guide for all 5 days."""
return tg_page_multi(
"Week 8", "Subtracting Within 100 (No Regrouping) — Teacher Guide",
# Monday
tg_section_title("Monday: Subtracting Tens (Mental Math)") +
tg_sec(1, "Subtract 10", ["43, 65, 77, 32"]) +
tg_sec(2, "Multiples of 10", ["34, 56, 78, 63"]) +
tg_sec(3, "Number Line", ["45, 47"]) +
tg_sec(4, "Number Talk", ["75-20 is bigger (subtract less)", "86-10 is bigger (subtract less)"]) +
tg_sec(5, "Challenge", ["45, 23"]) +
tg_note("Page break"),
# Tuesday
tg_section_title("Tuesday: Subtracting 2-Digit Numbers") +
tg_sec(1, "Subtract Ones Then Tens", ["23, 34, 42, 72"]) +
tg_sec(2, "Estimation", ["About 30, actual 35 / About 50, actual 51 / About 60, actual 63"]) +
tg_sec(3, "Step-by-Step", ["24, 43"]) +
tg_sec(4, "Strategies", ["35, 51, 72, 45"]) +
tg_sec(5, "Word Problems", ["23 cars, 45 balls"]) +
tg_note("Page break"),
# Wednesday
tg_section_title("Wednesday: Column Subtraction") +
tg_sec(1, "Column Subtraction", ["23, 34, 42, 72"]) +
tg_sec(2, "More Practice", ["35, 51, 72, 45"]) +
tg_sec(3, "Three Numbers", ["43, 35"]) +
tg_sec(4, "Find Error", ["23 is correct ✓, 43 is wrong ✗ (should be 42)"]) +
tg_sec(5, "Create Own", ["Various: 50-16, 60-26, 70-36, etc."]) +
tg_note("Page break"),
# Thursday
tg_section_title("Thursday: Word Problems") +
tg_sec(1, "Word Problems", ["34 shells, 56 books, 63 birds"]) +
tg_sec(2, "Compare", ["A=34, B=64, B is bigger"]) +
tg_sec(3, "Two-Step", ["34, 24, 24 stickers"]) +
tg_sec(4, "Create Own", ["Accept student-created problems"]) +
tg_note("Page break"),
# Friday
tg_section_title("Friday: Review & Self-Check") +
tg_sec(1, "Mental Math", ["20, 40, 10, 70, 30, 60"]) +
tg_sec(2, "Column Review", ["34, 62, 54, 26"]) +
tg_sec(3, "Mixed", ["47, 74, 34, 63"]) +
tg_sec(4, "Word Problems", ["24 students, 43 pages"]) +
tg_sec(5, "Self-Check", ["Accept student self-assessment and reflection"])
)
# ═══════════════════════════════════════════════════
# GENERATE
# ═══════════════════════════════════════════════════
if __name__ == "__main__":
# Clean old files
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", "Subtracting Tens (Mental Math)"),
(tuesday, "Tuesday", "Subtracting 2-Digit Numbers"),
(wednesday, "Wednesday", "Column Subtraction"),
(thursday, "Thursday", "Subtraction Word Problems"),
(friday, "Friday", "Week 8 Review & Self-Check"),
]
# Generate student worksheets
for lesson_func, day, title in days:
html = lesson_func()
fname = f"Week_8_{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}")
# Generate combined teacher guide
html = teacher_guide()
path = os.path.join(WEEK, "Week_8_Teacher_Guide.html")
with open(path, "w") as f:
f.write(html)
pdf_path = os.path.join(WEEK, "Week_8_Teacher_Guide.pdf")
HTML(filename=path).write_pdf(pdf_path)
print(f"Generated: {pdf_path}")
print("\nWeek 8 (rewritten to new standard) complete!")