'use strict'; /* * Колоды карточек формул для подготовки к ЦЭ/ЦТ (интервальное повторение). * flashcard_decks(user_id,title,description,color) + flashcard_cards(deck_id,front,back,order_idx). * Математика — KaTeX inline $…$ (страница флешкарт рендерит \( \), \[ \], $ $; НЕ $$). * Идемпотентно: колода с таким title у владельца не создаётся повторно. * node backend/scripts/seed_ctmath_flashcards.js [--dry] */ const db = require('../src/db/db'); const DRY = process.argv.includes('--dry'); const owner = (db.prepare("SELECT id FROM users WHERE role='admin' ORDER BY id LIMIT 1").get() || db.prepare('SELECT id FROM users ORDER BY id LIMIT 1').get()).id; const DECKS = [ { title: 'ЦТ · Тригонометрия — формулы', color: '#9B5DE5', cards: [ ['Определения через единичную окружность', '$\\cos\\alpha=x,\\ \\sin\\alpha=y$ (координаты точки)'], ['Основное тригонометрическое тождество', '$\\sin^2\\alpha+\\cos^2\\alpha=1$'], ['$1+\\operatorname{tg}^2\\alpha$', '$\\dfrac{1}{\\cos^2\\alpha}$'], ['$1+\\operatorname{ctg}^2\\alpha$', '$\\dfrac{1}{\\sin^2\\alpha}$'], ['$\\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=1-2\\sin^2\\alpha=2\\cos^2\\alpha-1$'], ['Понижение степени: $\\sin^2\\alpha$', '$\\dfrac{1-\\cos 2\\alpha}{2}$'], ['Область значений $\\arcsin x$', '$\\left[-\\tfrac{\\pi}{2};\\tfrac{\\pi}{2}\\right]$'], ['Область значений $\\arccos x$', '$[0;\\ \\pi]$'], ['$\\sin x=a$ — корни', '$x=(-1)^n\\arcsin a+\\pi n$'], ['$\\cos x=a$ — корни', '$x=\\pm\\arccos a+2\\pi n$'], ['$\\operatorname{tg} x=a$ — корни', '$x=\\operatorname{arctg} a+\\pi n$'], ['$\\sin x=0$', '$x=\\pi n$'], ['$\\cos x=0$', '$x=\\tfrac{\\pi}{2}+\\pi n$'], ]}, { title: 'ЦТ · Стереометрия — формулы', color: '#00BBF9', cards: [ ['$V$ призмы', '$S_{\\text{осн}}\\cdot h$'], ['$V$ пирамиды', '$\\tfrac{1}{3}S_{\\text{осн}}\\cdot h$'], ['$V$ цилиндра', '$\\pi R^2 h$'], ['$V$ конуса', '$\\tfrac{1}{3}\\pi R^2 h$'], ['$V$ шара', '$\\tfrac{4}{3}\\pi R^3$'], ['$S$ сферы', '$4\\pi R^2$'], ['$S_{\\text{бок}}$ цилиндра', '$2\\pi R h$'], ['$S_{\\text{бок}}$ конуса', '$\\pi R l$'], ['Сечение $\\parallel$ основанию: отношение площадей', '$k^2$, где $k$ — отношение высот от вершины'], ['Угол между прямыми (векторы)', '$\\cos\\varphi=\\dfrac{|\\vec a\\cdot\\vec b|}{|\\vec a|\\,|\\vec b|}$'], ['Скалярное произведение', '$a_xb_x+a_yb_y+a_zb_z$'], ['Длина вектора', '$\\sqrt{a_x^2+a_y^2+a_z^2}$'], ['Сфера касается плоскости', 'Радиус в точку касания $\\perp$ плоскости (далее Пифагор)'], ['Расстояние между скрещивающимися прямыми', 'Длина их общего перпендикуляра'], ]}, { title: 'ЦТ · Логарифмы и степени — формулы', color: '#F15BB5', cards: [ ['$\\log_a(xy)$', '$\\log_a x+\\log_a y$'], ['$\\log_a\\dfrac{x}{y}$', '$\\log_a x-\\log_a y$'], ['$\\log_a x^p$', '$p\\log_a x$'], ['Переход к новому основанию', '$\\log_a x=\\dfrac{\\log_b x}{\\log_b a}$'], ['$a^{\\log_a x}$', '$x$'], ['$\\log_a a$ и $\\log_a 1$', '$1$ и $0$'], ['$a^m\\cdot a^n$', '$a^{m+n}$'], ['$(a^m)^n$', '$a^{mn}$'], ['$a^{-n}$', '$\\dfrac{1}{a^n}$'], ['$a^{m/n}$', '$\\sqrt[n]{a^m}$'], ]}, { title: 'ЦТ · Производная — формулы', color: '#00F5D4', cards: [ ['$(x^n)\'$', '$n x^{n-1}$'], ['$(\\sin x)\'$', '$\\cos x$'], ['$(\\cos x)\'$', '$-\\sin x$'], ['$(e^x)\'$', '$e^x$'], ['$(\\ln x)\'$', '$\\dfrac{1}{x}$'], ['$(uv)\'$', '$u\'v+uv\'$'], ['$\\left(\\dfrac{u}{v}\\right)\'$', '$\\dfrac{u\'v-uv\'}{v^2}$'], ['Монотонность по производной', '$f\'>0$ — возрастает; $f\'<0$ — убывает'], ['Точка экстремума', '$f\'=0$ и меняет знак'], ]}, ]; const findDeck = db.prepare('SELECT id FROM flashcard_decks WHERE user_id=? AND title=?'); const insDeck = db.prepare('INSERT INTO flashcard_decks (user_id,title,description,color) VALUES (?,?,?,?)'); const insCard = db.prepare('INSERT INTO flashcard_cards (deck_id,front,back,order_idx) VALUES (?,?,?,?)'); console.log(DRY ? '[DRY-RUN]' : '[APPLY]', 'владелец user_id=', owner); for (const d of DECKS) { const ex = findDeck.get(owner, d.title); if (ex) { console.log(` есть колода: «${d.title}» (id ${ex.id}) — пропуск`); continue; } if (DRY) { console.log(` + колода «${d.title}» (${d.cards.length} карт)`); continue; } const did = insDeck.run(owner, d.title, 'Формулы для подготовки к ЦЭ/ЦТ. Интервальное повторение.', d.color).lastInsertRowid; d.cards.forEach(([f, b], i) => insCard.run(did, f, b, i)); console.log(` + колода «${d.title}» (id ${did}, ${d.cards.length} карт)`); } console.log(DRY ? 'DRY-RUN: ничего не записано.' : 'Готово. Колоды формул добавлены (владелец — admin; раздать классу можно через доступ к колоде).');