'use strict'; /* * Уроки блока «Тригонометрия» курса «ЦЭ/ЦТ — Математика» (по PILOT_TRIGONOMETRY.md). * Создаёт 3 урока (круг → тождества → уравнения) в секции «Тригонометрия» курса. * Форматы блоков — РОВНО под рендер frontend/lesson.html (text/heading/callout * экранируются → только текст; математика через $...$ / $$...$$; callout.style * = info|warning|success|error). data хранится JSON-строкой (API её парсит). * ИДЕМПОТЕНТЕН: урок с тем же title в курсе не создаётся повторно. * Запуск: node backend/scripts/seed_ctmath_lessons_trig.js [--dry] */ const db = require('../src/db/db'); const DRY = process.argv.includes('--dry'); const COURSE_TITLE = 'ЦЭ/ЦТ — Математика'; const SECTION_TITLE = 'Тригонометрия'; const course = db.prepare("SELECT id FROM courses WHERE subject_slug='math' AND title=?").get(COURSE_TITLE); if (!course) { console.error('Нет курса «' + COURSE_TITLE + '». Сначала: node backend/scripts/seed_ctmath_course.js'); process.exit(1); } const section = db.prepare('SELECT id FROM course_sections WHERE course_id=? AND title=?').get(course.id, SECTION_TITLE); if (!section) { console.error('Нет секции «' + SECTION_TITLE + '» в курсе ' + course.id); process.exit(1); } // helpers для краткости описания блоков const H = (text, level = 2) => ['heading', { text, level }]; const P = (text) => ['text', { text }]; const F = (tex, label) => ['formula', label ? { label, tex } : { tex }]; const CI = (text) => ['callout', { style: 'info', text }]; const CW = (text) => ['callout', { style: 'warning', text }]; const CS = (text) => ['callout', { style: 'success', text }]; const SIM= (caption) => ['sim', { simId: 'trigcircle', caption }]; const FC = (front, back) => ['flashcard', { front, back }]; const QZ = (question, options, correctIndex) => ['quiz', { question, options, correctIndex }]; const ORD= (question, items) => ['ordering', { question, items }]; const MAT= (question, pairs) => ['matching', { question, pairs }]; const ACC= (title, content) => ['accordion', { title, content }]; const TBL= (header, rows) => ['table', { header, rows }]; // ── Урок 1: Тригонометрический круг и значения (А3, базовый) ── const L1 = [ H('Тригонометрический круг: смысл синуса и косинуса'), P('Возьмём окружность радиуса 1 с центром в начале координат. При повороте на угол $\\alpha$ точка на этой окружности получает координаты $(\\cos\\alpha;\\ \\sin\\alpha)$. Это определение, из которого выводится вся тригонометрия: заучивать таблицы наизусть не нужно — нужно уметь «читать» круг.'), F('\\cos\\alpha = x,\\quad \\sin\\alpha = y,\\quad \\operatorname{tg}\\alpha=\\dfrac{y}{x},\\quad \\operatorname{ctg}\\alpha=\\dfrac{x}{y}', 'Определения через единичную окружность'), SIM('Покрутите угол и следите за координатами точки — это и есть $\\cos\\alpha$ и $\\sin\\alpha$'), CI('Знаки по четвертям: I (+,+), II (−,+), III (−,−), IV (+,−). Косинус — это абсцисса, синус — ордината.'), H('Значения для основных углов', 3), TBL( ['$\\alpha$', '$0$', '$\\tfrac{\\pi}{6}$', '$\\tfrac{\\pi}{4}$', '$\\tfrac{\\pi}{3}$', '$\\tfrac{\\pi}{2}$'], [ ['$\\sin\\alpha$', '$0$', '$\\tfrac{1}{2}$', '$\\tfrac{\\sqrt2}{2}$', '$\\tfrac{\\sqrt3}{2}$', '$1$'], ['$\\cos\\alpha$', '$1$', '$\\tfrac{\\sqrt3}{2}$', '$\\tfrac{\\sqrt2}{2}$', '$\\tfrac{1}{2}$', '$0$'], ['$\\operatorname{tg}\\alpha$', '$0$', '$\\tfrac{\\sqrt3}{3}$', '$1$', '$\\sqrt3$', '—'], ] ), F('\\sin x = 0 \\iff x=\\pi k;\\qquad \\cos x = 0 \\iff x=\\tfrac{\\pi}{2}+\\pi k', 'Когда функция равна нулю'), CW('Типичная ошибка — путать, где ноль у синуса (при $0,\\ \\pi,\\ 2\\pi,\\dots$) и у косинуса (при $\\tfrac{\\pi}{2},\\ \\tfrac{3\\pi}{2},\\dots$). На круге это видно сразу: синус — высота, косинус — горизонталь.'), FC('$\\sin x = 0$ при каких $x$?', '$x = \\pi k,\\ k\\in\\mathbb{Z}$'), FC('$\\cos x = 0$ при каких $x$?', '$x = \\tfrac{\\pi}{2}+\\pi k$'), H('Разбор задания А3', 3), P('Типичное А3: среди нескольких значений аргумента указать то, при котором функция равна нулю.'), P('Пример. Среди $-\\tfrac{\\pi}{6};\\ \\tfrac{\\pi}{4};\\ \\tfrac{\\pi}{3};\\ -\\tfrac{3\\pi}{2};\\ -6\\pi$ укажите то, при котором $\\sin x = 0$.'), P('Решение. $\\sin x=0$ только когда $x$ кратно $\\pi$. Из списка кратно $\\pi$ лишь $-6\\pi$.'), CS('Ответ: $-6\\pi$.'), QZ('При каком значении аргумента cos x = 1?', ['π/2', 'π', '0', '3π/2'], 2), CI('Тренажёр по теме «Тригонометрия» (реальные задания А3 прошлых лет) — в практике курса. Цель освоения: не менее 90% на заданиях А3.'), ]; // ── Урок 2: Тождества и формулы (А8, В4, средний) ── const L2 = [ H('Тождества: как не учить 30 формул'), F('\\sin^2\\alpha+\\cos^2\\alpha=1', 'Основное тригонометрическое тождество'), P('Это теорема Пифагора для точки $(\\cos\\alpha;\\ \\sin\\alpha)$ на единичной окружности. Разделив его на $\\cos^2\\alpha$ и на $\\sin^2\\alpha$, получаем связи с тангенсом и котангенсом — их выводят на месте, а не заучивают.'), F('1+\\operatorname{tg}^2\\alpha=\\dfrac{1}{\\cos^2\\alpha},\\qquad 1+\\operatorname{ctg}^2\\alpha=\\dfrac{1}{\\sin^2\\alpha}'), ACC('Формулы сложения и двойного угла (раскрыть)', 'Сложение: $\\sin(\\alpha\\pm\\beta)=\\sin\\alpha\\cos\\beta\\pm\\cos\\alpha\\sin\\beta$; $\\cos(\\alpha\\pm\\beta)=\\cos\\alpha\\cos\\beta\\mp\\sin\\alpha\\sin\\beta$. Двойной угол: $\\sin 2\\alpha=2\\sin\\alpha\\cos\\alpha$; $\\cos 2\\alpha=\\cos^2\\alpha-\\sin^2\\alpha$. Все они следуют из формул сложения.'), CI('Обратные функции и их области значений (на них ловят в А8): $\\arcsin x\\in[-\\tfrac{\\pi}{2};\\tfrac{\\pi}{2}]$, $\\arccos x\\in[0;\\pi]$, $\\operatorname{arctg} x\\in(-\\tfrac{\\pi}{2};\\tfrac{\\pi}{2})$.'), MAT('Сопоставьте выражение и тождественно равное ему', [ { left: '$\\sin 2\\alpha$', right: '$2\\sin\\alpha\\cos\\alpha$' }, { left: '$\\cos 2\\alpha$', right: '$\\cos^2\\alpha-\\sin^2\\alpha$' }, { left: '$1-\\cos 2\\alpha$', right: '$2\\sin^2\\alpha$' }, ]), H('Разбор А8 (обратные функции и модуль)', 3), P('Пример. Найдите значение $\\dfrac{38}{\\pi}\\cdot\\arcsin(-1)-|-7|$.'), P('Решение. $\\arcsin(-1)=-\\tfrac{\\pi}{2}$, поэтому $\\dfrac{38}{\\pi}\\cdot\\left(-\\tfrac{\\pi}{2}\\right)=-19$; далее $-19-7=-26$.'), CS('Ответ: $-26$.'), H('Разбор В4 (тождество)', 3), P('Пример. Найдите $\\operatorname{ctg}^2\\alpha$, если $\\sin\\alpha=\\tfrac{1}{5}$.'), P('Решение. $\\cos^2\\alpha=1-\\tfrac{1}{25}=\\tfrac{24}{25}$, поэтому $\\operatorname{ctg}^2\\alpha=\\dfrac{\\cos^2\\alpha}{\\sin^2\\alpha}=\\dfrac{24/25}{1/25}=24$.'), CS('Ответ: $24$.'), FC('$1+\\operatorname{tg}^2\\alpha$', '$\\dfrac{1}{\\cos^2\\alpha}$'), FC('$\\cos 2\\alpha$', '$\\cos^2\\alpha-\\sin^2\\alpha=1-2\\sin^2\\alpha=2\\cos^2\\alpha-1$'), FC('Область значений $\\arccos x$', '$[0;\\ \\pi]$'), CI('Тренажёр: реальные задания А8 и В4 в практике курса. Цель освоения: не менее 85%.'), ]; // ── Урок 3: Уравнения и отбор корней (В15, продвинутый) ── const L3 = [ H('Тригонометрические уравнения и отбор корней'), F('\\sin x=a\\Rightarrow x=(-1)^n\\arcsin a+\\pi n;\\quad \\cos x=a\\Rightarrow x=\\pm\\arccos a+2\\pi n;\\quad \\operatorname{tg} x=a\\Rightarrow x=\\operatorname{arctg} a+\\pi n', 'Формулы корней простейших уравнений'), P('Стратегия В15: сначала свести уравнение к произведению или простейшему виду формулами преобразования; затем выписать общие формулы корней; затем отобрать корни, попадающие в заданный промежуток; и наконец выполнить требуемое (например, найти сумму корней).'), ORD('Расставьте шаги решения В15 по порядку', [ 'Преобразовать уравнение к произведению или простейшему виду', 'Выписать общие формулы корней', 'Подставить целые n и отобрать корни на заданном промежутке', 'Сложить (или иначе обработать) отобранные корни', ]), SIM('Отбор корней: отметьте промежуток и проверьте, какие корни в него попадают'), CW('Самая частая потеря баллов в В15 — неполный отбор корней и потеря ОДЗ (для $\\operatorname{tg}$ и $\\operatorname{ctg}$). Проверяйте оба семейства корней.'), H('Разбор простого примера', 3), P('Найдите (в градусах) сумму корней уравнения $\\cos 2x=0$ на промежутке $(0^\\circ;\\ 180^\\circ)$.'), P('Решение. $\\cos 2x=0\\Rightarrow 2x=90^\\circ+180^\\circ k\\Rightarrow x=45^\\circ+90^\\circ k$. На промежутке лежат $45^\\circ$ и $135^\\circ$. Их сумма равна $180$.'), CS('Ответ: $180$.'), ACC('Более сложный пример (В15 из ЦЭ-2024) — раскрыть', 'Найдите сумму различных корней уравнения $2\\sin 3x\\cos 3x-\\sin 6x\\sin 10x=0$ на промежутке $(-150^\\circ;-55^\\circ)$. Идея: $2\\sin 3x\\cos 3x=\\sin 6x$, выносим общий множитель: $\\sin 6x\\,(1-\\sin 10x)=0$. Дальше решаем $\\sin 6x=0$ или $\\sin 10x=1$ и отбираем корни на промежутке.'), FC('$\\sin x=a$ (корни)', '$x=(-1)^n\\arcsin a+\\pi n$'), FC('$\\cos x=a$ (корни)', '$x=\\pm\\arccos a+2\\pi n$'), FC('$\\operatorname{tg} x=a$ (корни)', '$x=\\operatorname{arctg} a+\\pi n$'), CI('Тренажёр: тема «Тригонометрические уравнения» (В15) в практике курса. Цель освоения: не менее 70%, отбор корней без потерь.'), ]; const LESSONS = [ { title: 'Тригонометрический круг и значения', read: 9, blocks: L1 }, { title: 'Тождества и формулы', read: 10, blocks: L2 }, { title: 'Уравнения и отбор корней', read: 11, blocks: L3 }, ]; console.log(DRY ? '[DRY-RUN]' : '[APPLY]', `курс id=${course.id}, секция «${SECTION_TITLE}» id=${section.id}`); const insLesson = db.prepare('INSERT INTO lessons (course_id, title, order_index, is_published, section_id, read_time) VALUES (?,?,?,1,?,?)'); const insBlock = db.prepare('INSERT INTO lesson_blocks (lesson_id, type, order_index, data) VALUES (?,?,?,?)'); LESSONS.forEach((L, i) => { const ex = db.prepare('SELECT id FROM lessons WHERE course_id=? AND title=?').get(course.id, L.title); if (ex) { console.log(` есть урок: «${L.title}» (id ${ex.id}) — пропуск`); return; } if (DRY) { console.log(` + урок «${L.title}» (${L.blocks.length} блоков)`); return; } const lid = insLesson.run(course.id, L.title, i + 1, section.id, L.read).lastInsertRowid; L.blocks.forEach(([type, data], bi) => insBlock.run(lid, type, bi, JSON.stringify(data))); console.log(` + урок «${L.title}» (id ${lid}, ${L.blocks.length} блоков)`); }); console.log(DRY ? 'DRY-RUN: ничего не записано.' : 'Готово. Уроки тригонометрии добавлены в курс (черновик; ученикам видны после публикации курса).');