diff --git a/TODO.md b/TODO.md index 47bf8f8..317e285 100644 --- a/TODO.md +++ b/TODO.md @@ -514,7 +514,7 @@ ## ⏳ Очередь новых функций (Feature Backlog) -- [ ] **FEAT-01: 🧘 Фокус-режим в читалке (Focus Mode / Zen Reader — 100% vh & 100% vw)**: +- [x] **FEAT-01: 🧘 Фокус-режим в читалке (Focus Mode / Zen Reader — 100% vh & 100% vw)**: - **Концепция**: чистый дзен-режим чтения на весь экран без отвлекающих панелей с сохранением 100% интерактивного перевода. - **Интерфейс и верстка**: - Скрытие шапки сайта (`navbar`), тулбара читалки, мобильной панели вкладок (`bottom tab bar`) и рамок. diff --git a/app/database.py b/app/database.py index bafdfb8..2bbad9d 100644 --- a/app/database.py +++ b/app/database.py @@ -331,6 +331,8 @@ def _migrate(conn: sqlite3.Connection): title TEXT NOT NULL, subtitle TEXT DEFAULT '', golden_formula TEXT NOT NULL, + cheatsheet_table TEXT DEFAULT '', + detailed_notes TEXT DEFAULT '', contrast_explanation_json TEXT NOT NULL, journaling_prompt TEXT NOT NULL, exercises_json TEXT NOT NULL, @@ -340,6 +342,18 @@ def _migrate(conn: sqlite3.Connection): conn.execute("CREATE INDEX IF NOT EXISTS idx_grammar_units_num ON grammar_units(unit_num);") conn.execute("CREATE INDEX IF NOT EXISTS idx_grammar_units_level ON grammar_units(level);") + # Safe migration: add cheatsheet_table and detailed_notes columns if not present + existing_grammar_cols = { + row[1] for row in conn.execute("PRAGMA table_info(grammar_units)").fetchall() + } + grammar_migrations = [ + ("cheatsheet_table", "TEXT DEFAULT ''"), + ("detailed_notes", "TEXT DEFAULT ''"), + ] + for col, definition in grammar_migrations: + if col not in existing_grammar_cols: + conn.execute(f"ALTER TABLE grammar_units ADD COLUMN {col} {definition}") + conn.execute(""" CREATE TABLE IF NOT EXISTS grammar_progress ( id INTEGER PRIMARY KEY AUTOINCREMENT, diff --git a/app/grammar.py b/app/grammar.py index fce3081..c5e2daa 100644 --- a/app/grammar.py +++ b/app/grammar.py @@ -51,7 +51,7 @@ CURATED_MURPHY_UNITS = _LazyUnitsList() def seed_grammar_units(conn: sqlite3.Connection) -> int: """ Populates grammar_units table with curated Murphy units. - Safe and idempotent (INSERT OR IGNORE). + Safe, idempotent upsert (ON CONFLICT DO UPDATE). """ inserted = 0 for u in CURATED_MURPHY_UNITS: @@ -59,10 +59,22 @@ def seed_grammar_units(conn: sqlite3.Connection) -> int: exercises_json = json.dumps(u["exercises"], ensure_ascii=False) cursor = conn.execute( """ - INSERT OR IGNORE INTO grammar_units ( + INSERT INTO grammar_units ( unit_num, level, category, title, subtitle, golden_formula, + cheatsheet_table, detailed_notes, contrast_explanation_json, journaling_prompt, exercises_json - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(unit_num) DO UPDATE SET + level = excluded.level, + category = excluded.category, + title = excluded.title, + subtitle = excluded.subtitle, + golden_formula = excluded.golden_formula, + cheatsheet_table = excluded.cheatsheet_table, + detailed_notes = excluded.detailed_notes, + contrast_explanation_json = excluded.contrast_explanation_json, + journaling_prompt = excluded.journaling_prompt, + exercises_json = excluded.exercises_json """, ( u["unit_num"], @@ -71,6 +83,8 @@ def seed_grammar_units(conn: sqlite3.Connection) -> int: u["title"], u.get("subtitle", ""), u["golden_formula"], + u.get("cheatsheet_table", ""), + u.get("detailed_notes", ""), contrast_json, u["journaling_prompt"], exercises_json, @@ -117,18 +131,22 @@ def get_grammar_units_list(conn: sqlite3.Connection, user_id: int) -> List[Dict[ def get_grammar_unit_detail(conn: sqlite3.Connection, user_id: int, unit_id: int) -> Optional[Dict[str, Any]]: """ Returns full content of a unit for lesson mode. + Supports looking up by database PK or unit_num. """ row = conn.execute( """ SELECT u.id, u.unit_num, u.level, u.category, u.title, u.subtitle, - u.golden_formula, u.contrast_explanation_json, u.journaling_prompt, u.exercises_json, + u.golden_formula, u.cheatsheet_table, u.detailed_notes, + u.contrast_explanation_json, u.journaling_prompt, u.exercises_json, p.is_completed, p.score, p.handwritten_logged, p.completed_at FROM grammar_units u LEFT JOIN grammar_progress p ON u.id = p.unit_id AND p.user_id = ? - WHERE u.id = ? + WHERE u.id = ? OR u.unit_num = ? + ORDER BY (u.id = ?) DESC + LIMIT 1 """, - (user_id, unit_id), + (user_id, unit_id, unit_id, unit_id), ).fetchone() if not row: @@ -162,9 +180,12 @@ def get_grammar_unit_detail(conn: sqlite3.Connection, user_id: int, unit_id: int "level": row["level"], "category": row["category"], "title": row["title"], - "subtitle": row["subtitle"], + "subtitle": row["subtitle"] or "", "golden_formula": row["golden_formula"], + "cheatsheet_table": row["cheatsheet_table"] or "", + "detailed_notes": row["detailed_notes"] or "", "contrasts": contrasts, + "contrast_explanation": contrasts, "journaling_prompt": row["journaling_prompt"], "exercises": exercises, "is_completed": bool(row["is_completed"]), @@ -187,7 +208,8 @@ def process_grammar_answer( with tags 'grammar, murphy-unit-{unit_num}' and srs_state='learning'. """ unit_row = conn.execute( - "SELECT * FROM grammar_units WHERE id = ?", (unit_id,) + "SELECT * FROM grammar_units WHERE id = ? OR unit_num = ? ORDER BY (id = ?) DESC LIMIT 1", + (unit_id, unit_id, unit_id), ).fetchone() if not unit_row: @@ -293,9 +315,15 @@ def record_grammar_completion( """ Saves unit completion score and handwritten journaling status. """ + u_row = conn.execute( + "SELECT id FROM grammar_units WHERE id = ? OR unit_num = ? ORDER BY (id = ?) DESC LIMIT 1", + (unit_id, unit_id, unit_id), + ).fetchone() + real_unit_id = u_row["id"] if u_row else unit_id + prog_row = conn.execute( "SELECT id FROM grammar_progress WHERE user_id = ? AND unit_id = ?", - (user_id, unit_id), + (user_id, real_unit_id), ).fetchone() hw_val = 1 if handwritten_logged else 0 @@ -320,10 +348,10 @@ def record_grammar_completion( user_id, unit_id, is_completed, score, handwritten_logged, handwritten_at, completed_at ) VALUES (?, ?, 1, ?, ?, CASE WHEN ? = 1 THEN CURRENT_TIMESTAMP ELSE NULL END, CURRENT_TIMESTAMP) """, - (user_id, unit_id, score, hw_val, hw_val), + (user_id, real_unit_id, score, hw_val, hw_val), ) - return {"status": "ok", "unit_id": unit_id, "score": score, "handwritten_logged": handwritten_logged} + return {"status": "ok", "unit_id": real_unit_id, "score": score, "handwritten_logged": handwritten_logged} def update_handwritten_status( @@ -335,10 +363,16 @@ def update_handwritten_status( """ Toggles handwritten paper notebook checkbox for a unit. """ + u_row = conn.execute( + "SELECT id FROM grammar_units WHERE id = ? OR unit_num = ? ORDER BY (id = ?) DESC LIMIT 1", + (unit_id, unit_id, unit_id), + ).fetchone() + real_unit_id = u_row["id"] if u_row else unit_id + hw_val = 1 if handwritten else 0 prog_row = conn.execute( "SELECT id FROM grammar_progress WHERE user_id = ? AND unit_id = ?", - (user_id, unit_id), + (user_id, real_unit_id), ).fetchone() if prog_row: @@ -358,7 +392,7 @@ def update_handwritten_status( user_id, unit_id, is_completed, score, handwritten_logged, handwritten_at ) VALUES (?, ?, 0, 0, ?, CASE WHEN ? = 1 THEN CURRENT_TIMESTAMP ELSE NULL END) """, - (user_id, unit_id, hw_val, hw_val), + (user_id, real_unit_id, hw_val, hw_val), ) - return {"status": "ok", "unit_id": unit_id, "handwritten_logged": handwritten} + return {"status": "ok", "unit_id": real_unit_id, "handwritten_logged": handwritten} diff --git a/app/static/css/grammar_cefr.css b/app/static/css/grammar_cefr.css index 5f701be..b1b05e2 100644 --- a/app/static/css/grammar_cefr.css +++ b/app/static/css/grammar_cefr.css @@ -1688,3 +1688,151 @@ } } +/* ========================================================================== + FEAT-02: Murphy Cheatsheet Tables & Rich Detailed Notes + ========================================================================== */ + +.grammar-table-wrap { + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + border-radius: var(--radius-md); + border: 1px solid var(--border-color); + background: var(--bg-card); + box-shadow: var(--shadow-sm); + margin: 12px 0 16px 0; +} + +.grammar-cheatsheet-table { + width: 100%; + border-collapse: collapse; + font-size: 13.5px; + line-height: 1.5; + text-align: left; +} + +.grammar-cheatsheet-table thead th { + background: var(--bg-surface-hover); + color: var(--text-main); + font-weight: 700; + padding: 10px 14px; + border-bottom: 2px solid var(--border-color); + white-space: nowrap; +} + +.grammar-cheatsheet-table tbody td { + padding: 10px 14px; + border-bottom: 1px solid var(--border-color); + color: var(--text-main); + vertical-align: top; +} + +.grammar-cheatsheet-table tbody tr:last-child td { + border-bottom: none; +} + +.grammar-cheatsheet-table tbody tr:hover { + background: rgba(99, 102, 241, 0.04); +} + +.grammar-inline-code { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; + font-size: 12.5px; + background: var(--bg-input); + color: var(--color-primary); + padding: 2px 5px; + border-radius: 4px; + border: 1px solid var(--border-color); +} + +.grammar-notes-box { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 20px 24px; + color: var(--text-main); + font-size: 14px; + line-height: 1.65; + box-shadow: var(--shadow-sm); +} + +.grammar-notes-box .grammar-note-h3 { + font-size: 16px; + font-weight: 800; + color: var(--text-main); + margin: 16px 0 8px 0; + letter-spacing: -0.01em; +} + +.grammar-notes-box .grammar-note-h4 { + font-size: 15px; + font-weight: 700; + color: var(--color-primary); + margin: 16px 0 8px 0; +} + +.grammar-notes-box .grammar-note-h5 { + font-size: 13.5px; + font-weight: 700; + color: var(--text-muted); + margin: 12px 0 6px 0; + text-transform: uppercase; + letter-spacing: 0.03em; +} + +.grammar-notes-box .grammar-note-p { + margin: 0 0 10px 0; +} + +.grammar-notes-box .grammar-note-quote { + border-left: 3px solid var(--color-primary); + background: rgba(99, 102, 241, 0.06); + padding: 8px 14px; + margin: 10px 0; + border-radius: 0 var(--radius-sm) var(--radius-sm) 0; + font-style: italic; + color: var(--text-main); +} + +.grammar-notes-list { + margin: 0 0 12px 0; + padding-left: 20px; +} + +.grammar-notes-list li { + margin-bottom: 6px; + line-height: 1.55; +} + +/* Collapsible Practice Cheatsheet Drawer */ +.practice-cheatsheet-toggle-wrap { + margin-bottom: 16px; +} + +.practice-cheatsheet-btn { + display: inline-flex; + align-items: center; + gap: 6px; + font-size: 12.5px; + font-weight: 600; + padding: 6px 12px; + border-radius: var(--radius-md); + background: var(--bg-surface); + border: 1px solid var(--border-color); + color: var(--text-muted); + cursor: pointer; + transition: all 0.15s ease; +} + +.practice-cheatsheet-btn:hover { + color: var(--text-main); + background: var(--bg-surface-hover); + border-color: var(--color-primary); +} + +.practice-cheatsheet-drawer { + margin-top: 10px; + animation: fadeIn 0.2s ease-out; +} + + diff --git a/app/static/css/reader.css b/app/static/css/reader.css index 1aaf27e..34f037b 100644 --- a/app/static/css/reader.css +++ b/app/static/css/reader.css @@ -2061,6 +2061,191 @@ font-size: 17px; line-height: 1.65; } - - } + +/* ========================================================================== + FEAT-01: Focus Mode in Reader (Zen Reader — 100% vh & 100% vw) + ========================================================================== */ + +.reader-zen-btn { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 12px; + color: var(--text-main); + border-color: var(--border-color); + transition: var(--transition); +} + +.reader-zen-btn:hover { + border-color: var(--primary); + color: var(--primary); + background-color: var(--primary-dim); +} + +/* Fullscreen / Zen Viewport Override */ +body.zen-mode-active { + overflow: hidden !important; +} + +body.zen-mode-active #app-header, +body.zen-mode-active #bottom-tab-bar, +body.zen-mode-active .reader-toolbar { + display: none !important; +} + +body.zen-mode-active .reader-view { + max-width: 100% !important; + padding: 0 !important; + margin: 0 !important; +} + +body.zen-mode-active #reader-interface { + position: fixed !important; + inset: 0 !important; + width: 100vw !important; + height: 100dvh !important; + z-index: 9999 !important; + border: none !important; + border-radius: 0 !important; + box-shadow: none !important; + background-color: var(--reader-bg) !important; + overflow: hidden !important; +} + +body.zen-mode-active #reader-scroll-area { + width: 100vw !important; + height: 100dvh !important; + padding-top: max(24px, env(safe-area-inset-top)) !important; + padding-bottom: max(60px, env(safe-area-inset-bottom)) !important; + box-sizing: border-box !important; + overflow-y: auto !important; + -webkit-overflow-scrolling: touch; +} + +/* Floating Minimal HUD in Zen Mode */ +.reader-zen-hud { + position: fixed; + top: max(16px, env(safe-area-inset-top)); + right: max(20px, env(safe-area-inset-right)); + z-index: 10002; + transition: opacity 0.35s cubic-bezier(0.16, 1, 0.3, 1), transform 0.35s cubic-bezier(0.16, 1, 0.3, 1); + user-select: none; + pointer-events: auto; +} + +.reader-zen-hud.hud-idle { + opacity: 0; + pointer-events: none; + transform: translateY(-8px); +} + +.zen-hud-content { + display: inline-flex; + align-items: center; + gap: 8px; + background: rgba(15, 23, 42, 0.82); + backdrop-filter: blur(14px); + -webkit-backdrop-filter: blur(14px); + border: 1px solid rgba(255, 255, 255, 0.14); + border-radius: var(--radius-full); + padding: 6px 14px; + font-size: 13px; + color: #e2e8f0; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); +} + +.zen-hud-title { + max-width: 160px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-weight: 600; + color: #f8fafc; +} + +.zen-hud-sep { + color: rgba(255, 255, 255, 0.3); + font-size: 11px; +} + +.zen-hud-chapter { + font-size: 12px; + color: #cbd5e1; + white-space: nowrap; +} + +.zen-hud-progress { + font-weight: 700; + color: #38bdf8; + font-variant-numeric: tabular-nums; + font-size: 12px; +} + +.zen-hud-exit-btn { + background: rgba(255, 255, 255, 0.08); + border: 1px solid rgba(255, 255, 255, 0.15); + color: #cbd5e1; + border-radius: 50%; + width: 24px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + font-size: 13px; + transition: all 0.15s ease; + padding: 0; + margin-left: 2px; +} + +.zen-hud-exit-btn:hover { + background: rgba(239, 68, 68, 0.35); + border-color: rgba(239, 68, 68, 0.6); + color: #fca5a5; + transform: scale(1.1); +} + +/* Theme-adaptive HUD styling for Sepia & Light themes */ +.reader-scroll-area.reader-theme-sepia ~ #reader-zen-hud .zen-hud-content { + background: rgba(247, 237, 214, 0.88); + border-color: rgba(146, 64, 14, 0.25); + color: #453422; + box-shadow: 0 4px 20px rgba(70, 50, 30, 0.18); +} + +.reader-scroll-area.reader-theme-sepia ~ #reader-zen-hud .zen-hud-title { + color: #291e14; +} + +.reader-scroll-area.reader-theme-sepia ~ #reader-zen-hud .zen-hud-progress { + color: #d97706; +} + +.reader-scroll-area.reader-theme-sepia ~ #reader-zen-hud .zen-hud-exit-btn { + background: rgba(146, 64, 14, 0.12); + border-color: rgba(146, 64, 14, 0.2); + color: #453422; +} + +.reader-scroll-area.reader-theme-light ~ #reader-zen-hud .zen-hud-content { + background: rgba(255, 255, 255, 0.9); + border-color: rgba(0, 0, 0, 0.12); + color: #1e293b; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12); +} + +.reader-scroll-area.reader-theme-light ~ #reader-zen-hud .zen-hud-title { + color: #0f172a; +} + +.reader-scroll-area.reader-theme-light ~ #reader-zen-hud .zen-hud-progress { + color: #0284c7; +} + +.reader-scroll-area.reader-theme-light ~ #reader-zen-hud .zen-hud-exit-btn { + background: rgba(0, 0, 0, 0.05); + border-color: rgba(0, 0, 0, 0.15); + color: #475569; +} + diff --git a/app/static/index.html b/app/static/index.html index f870523..f7c964a 100644 --- a/app/static/index.html +++ b/app/static/index.html @@ -768,6 +768,10 @@ Aa Шрифт + @@ -777,6 +781,18 @@ + + +
@@ -946,6 +962,18 @@

Unit Subtitle

+ +
+

📊 Наглядная шпаргалка и правила (Таблица)

+
+
+ + +
+

📖 Подробный конспект темы (Raymond Murphy)

+
+
+

⚖️ Метод контрастов (В чём суть и когда применять)

@@ -999,6 +1027,15 @@
+ +
+ + +
+
diff --git a/app/static/js/modules/grammar.js b/app/static/js/modules/grammar.js index a98b46f..eeb679c 100644 --- a/app/static/js/modules/grammar.js +++ b/app/static/js/modules/grammar.js @@ -5,7 +5,7 @@ // ======================================================================= import { api } from './api.js'; -import { showToast, escapeHtml } from './ui.js'; +import { showToast, escapeHtml, renderMarkdownTable, renderMarkdownNotes } from './ui.js'; let allUnits = []; let currentFilter = 'all'; @@ -29,6 +29,18 @@ export function initGrammar() { const sumUnitsBtn = document.getElementById('grammar-sum-units-btn'); const sumSrsBtn = document.getElementById('grammar-sum-srs-btn'); const handwrittenToggle = document.getElementById('grammar-handwritten-toggle'); + const cheatsheetToggle = document.getElementById('grammar-practice-cheatsheet-toggle'); + const cheatsheetDrawer = document.getElementById('grammar-practice-cheatsheet-drawer'); + + if (cheatsheetToggle && cheatsheetDrawer) { + cheatsheetToggle.addEventListener('click', () => { + const isNowHidden = !cheatsheetDrawer.classList.contains('hidden'); + cheatsheetDrawer.classList.toggle('hidden', isNowHidden); + cheatsheetToggle.innerHTML = isNowHidden + ? '📋 Шпаргалка по теме' + : '📋 Скрыть шпаргалку'; + }); + } if (backBtn) { backBtn.addEventListener('click', () => { @@ -314,6 +326,50 @@ function renderUnitTheory() { handwrittenToggle.checked = Boolean(currentUnit.handwritten_logged); } + // Cheatsheet Markdown Table + const cheatsheetSec = document.getElementById('grammar-cheatsheet-section'); + const cheatsheetBox = document.getElementById('grammar-cheatsheet-content'); + if (cheatsheetSec && cheatsheetBox) { + if (currentUnit.cheatsheet_table && currentUnit.cheatsheet_table.trim()) { + cheatsheetBox.innerHTML = renderMarkdownTable(currentUnit.cheatsheet_table); + cheatsheetSec.classList.remove('hidden'); + } else { + cheatsheetBox.innerHTML = ''; + cheatsheetSec.classList.add('hidden'); + } + } + + // Detailed Murphy Notes + const notesSec = document.getElementById('grammar-detailed-notes-section'); + const notesBox = document.getElementById('grammar-detailed-notes-content'); + if (notesSec && notesBox) { + if (currentUnit.detailed_notes && currentUnit.detailed_notes.trim()) { + notesBox.innerHTML = renderMarkdownNotes(currentUnit.detailed_notes); + notesSec.classList.remove('hidden'); + } else { + notesBox.innerHTML = ''; + notesSec.classList.add('hidden'); + } + } + + // Practice Cheatsheet Drawer content + const practiceDrawer = document.getElementById('grammar-practice-cheatsheet-drawer'); + const practiceToggleWrap = document.querySelector('.practice-cheatsheet-toggle-wrap'); + if (practiceDrawer && practiceToggleWrap) { + if (currentUnit.cheatsheet_table && currentUnit.cheatsheet_table.trim()) { + practiceDrawer.innerHTML = renderMarkdownTable(currentUnit.cheatsheet_table); + practiceToggleWrap.classList.remove('hidden'); + } else { + practiceDrawer.innerHTML = ''; + practiceToggleWrap.classList.add('hidden'); + } + practiceDrawer.classList.add('hidden'); + const practiceToggle = document.getElementById('grammar-practice-cheatsheet-toggle'); + if (practiceToggle) { + practiceToggle.innerHTML = '📋 Шпаргалка по теме'; + } + } + // Golden formula const formulaEl = document.getElementById('grammar-golden-formula-text'); if (formulaEl) { @@ -368,6 +424,12 @@ function startUnitPractice() { sessionCorrect = 0; sessionIngestedCards = []; + // Ensure cheatsheet drawer is collapsed at practice start + const practiceDrawer = document.getElementById('grammar-practice-cheatsheet-drawer'); + const practiceToggle = document.getElementById('grammar-practice-cheatsheet-toggle'); + if (practiceDrawer) practiceDrawer.classList.add('hidden'); + if (practiceToggle) practiceToggle.innerHTML = '📋 Шпаргалка по теме'; + renderExercise(); } diff --git a/app/static/js/modules/lesson.js b/app/static/js/modules/lesson.js index 37ac8c5..0a55e45 100644 --- a/app/static/js/modules/lesson.js +++ b/app/static/js/modules/lesson.js @@ -4,7 +4,7 @@ // ======================================================================= import { api } from './api.js'; -import { ui, escapeHtml, showToast, switchView, shuffleArray, escapeRegex, playAudio, playTextSpeech, cleanPromptTranslation } from './ui.js'; +import { ui, escapeHtml, showToast, switchView, shuffleArray, escapeRegex, playAudio, playTextSpeech, cleanPromptTranslation, renderMarkdownTable, renderMarkdownNotes } from './ui.js'; let presets = []; let currentPreset = null; @@ -1332,6 +1332,18 @@ async function runGrammarReviewStep(step, container) { ${escapeHtml(unitDetail.golden_formula || '')}
+ ${unitDetail.cheatsheet_table ? ` +
+ + +
+ ` : ''} +

${escapeHtml(ex.sentence)}

${ex.clue ? `
💡 Подсказка: ${escapeHtml(ex.clue)}
` : ''} @@ -1350,6 +1362,18 @@ async function runGrammarReviewStep(step, container) {
`; + const reviewCsBtn = document.getElementById('review-cheatsheet-toggle-btn'); + const reviewCsDrawer = document.getElementById('review-cheatsheet-drawer'); + if (reviewCsBtn && reviewCsDrawer) { + reviewCsBtn.addEventListener('click', () => { + const isHidden = reviewCsDrawer.classList.contains('hidden'); + reviewCsDrawer.classList.toggle('hidden', !isHidden); + reviewCsBtn.innerHTML = !isHidden + ? '📋 Шпаргалка по теме' + : '📋 Скрыть шпаргалку'; + }); + } + container.querySelectorAll('.grammar-opt-btn').forEach(btn => { btn.addEventListener('click', async () => { // Disable all options @@ -1432,7 +1456,11 @@ async function runGrammarNewStep(step, container) { let stage = 'theory'; // theory -> exercises function renderTheory() { - const contrasts = unitDetail.contrast_explanation || []; + const contrasts = unitDetail.contrasts || unitDetail.contrast_explanation || []; + const hasCheatsheet = Boolean(unitDetail.cheatsheet_table && unitDetail.cheatsheet_table.trim()); + const hasNotes = Boolean(unitDetail.detailed_notes && unitDetail.detailed_notes.trim()); + const hasPrompt = Boolean(unitDetail.journaling_prompt && unitDetail.journaling_prompt.trim()); + container.innerHTML = `
@@ -1449,29 +1477,60 @@ async function runGrammarNewStep(step, container) {
${escapeHtml(unitDetail.golden_formula)}
- - ${contrasts.map(c => ` -
-
-
-
${escapeHtml(c.situation_a)}
-
${escapeHtml(c.example_a)}
-
${escapeHtml(c.trans_a)}
-
-
-
${escapeHtml(c.situation_b)}
-
${escapeHtml(c.example_b)}
-
${escapeHtml(c.trans_b)}
-
-
-
💡 Ключевая разница: ${escapeHtml(c.key_difference)}
+ + ${hasCheatsheet ? ` +
+
📊 Наглядная шпаргалка и правила (Таблица):
+ ${renderMarkdownTable(unitDetail.cheatsheet_table)}
- `).join('')} + ` : ''} + + + ${hasNotes ? ` +
+
📖 Подробный конспект темы (Raymond Murphy):
+ ${renderMarkdownNotes(unitDetail.detailed_notes)} +
+ ` : ''} + + + ${contrasts.length > 0 ? ` +
+
⚖️ Метод контрастов (В чём суть и когда применять):
+ ${contrasts.map(c => ` +
+
+
+
${escapeHtml(c.situation_a)}
+
${escapeHtml(c.example_a)}
+
${escapeHtml(c.trans_a)}
+
+
+
${escapeHtml(c.situation_b)}
+
${escapeHtml(c.example_b)}
+
${escapeHtml(c.trans_b)}
+
+
+
💡 Ключевая разница: ${escapeHtml(c.key_difference)}
+
+ `).join('')} +
+ ` : ''} + + + ${hasPrompt ? ` +
+
+
📓 Персональный дневник от руки (Motor Memory):
+

${escapeHtml(unitDetail.journaling_prompt)}

+
+
+ ` : ''}
@@ -1541,6 +1600,18 @@ async function runGrammarNewStep(step, container) { Практика темы (${exIdx + 1} из ${selectedExercises.length})
+ ${unitDetail.cheatsheet_table ? ` +
+ + +
+ ` : ''} +

${escapeHtml(ex.sentence)}

${ex.clue ? `
💡 Подсказка: ${escapeHtml(ex.clue)}
` : ''} @@ -1559,6 +1630,18 @@ async function runGrammarNewStep(step, container) {
`; + const lessonCsBtn = document.getElementById('lesson-cheatsheet-toggle-btn'); + const lessonCsDrawer = document.getElementById('lesson-cheatsheet-drawer'); + if (lessonCsBtn && lessonCsDrawer) { + lessonCsBtn.addEventListener('click', () => { + const isHidden = lessonCsDrawer.classList.contains('hidden'); + lessonCsDrawer.classList.toggle('hidden', !isHidden); + lessonCsBtn.innerHTML = !isHidden + ? '📋 Шпаргалка по теме' + : '📋 Скрыть шпаргалку'; + }); + } + container.querySelectorAll('.grammar-opt-btn').forEach(btn => { btn.addEventListener('click', async () => { container.querySelectorAll('.grammar-opt-btn').forEach(b => b.disabled = true); diff --git a/app/static/js/modules/reader.js b/app/static/js/modules/reader.js index 760975b..c3b204a 100644 --- a/app/static/js/modules/reader.js +++ b/app/static/js/modules/reader.js @@ -28,6 +28,13 @@ let popupCurrentData = null; let readerScrollSaveTimer = null; let popupScrollRaf = null; +let isZenMode = false; +let zenHudIdleTimer = null; + +export function getIsZenMode() { + return isZenMode; +} + export function getCurrentBook() { return currentBook; } @@ -134,6 +141,7 @@ function createBookCard(b) { } export async function loadBookshelf() { + if (isZenMode) toggleZenMode(false); const bookshelfContainer = document.getElementById('bookshelf-container'); const readerInterface = document.getElementById('reader-interface'); const bookshelfGrid = document.getElementById('bookshelf-grid'); @@ -1610,6 +1618,26 @@ export function updateReaderProgressBar() { } else if (readerScrollPctBadge) { readerScrollPctBadge.textContent = `${pct}%`; } + + // Update Zen HUD elements if present + const zenHudTitle = document.getElementById('zen-hud-title'); + const zenHudChapter = document.getElementById('zen-hud-chapter'); + const zenHudProgress = document.getElementById('zen-hud-progress'); + + if (zenHudTitle && currentBook) { + zenHudTitle.textContent = currentBook.title || 'Книга'; + zenHudTitle.title = currentBook.title || 'Книга'; + } + if (zenHudChapter && currentBook && currentBook.chapters) { + const totalCh = currentBook.chapters.length; + const ch = currentBook.chapters[currentChapterIndex]; + const chTitle = ch ? (ch.title || `Глава ${currentChapterIndex + 1}`) : `Глава ${currentChapterIndex + 1}`; + zenHudChapter.textContent = totalCh > 1 ? `Гл. ${currentChapterIndex + 1}/${totalCh}` : chTitle; + zenHudChapter.title = chTitle; + } + if (zenHudProgress) { + zenHudProgress.textContent = `${pct}%`; + } } export function handleReaderScroll() { @@ -1836,6 +1864,62 @@ export function positionSettingsPanel() { readerSettingsPanel.style.maxHeight = `${maxH}px`; } +// ----------------------------------------------------------------------- +// Zen Focus Mode +// ----------------------------------------------------------------------- +export function wakeZenHud() { + if (!isZenMode) return; + const hud = document.getElementById('reader-zen-hud'); + if (!hud) return; + hud.classList.remove('hud-idle'); + if (zenHudIdleTimer) { + clearTimeout(zenHudIdleTimer); + } + zenHudIdleTimer = setTimeout(() => { + if (isZenMode && hud) { + hud.classList.add('hud-idle'); + } + }, 3000); +} + +export function toggleZenMode(forceState = null) { + const newState = (forceState !== null) ? Boolean(forceState) : !isZenMode; + if (isZenMode === newState) return; + isZenMode = newState; + + const hud = document.getElementById('reader-zen-hud'); + const zenBtn = document.getElementById('reader-zen-btn'); + const readerSettingsPanel = document.getElementById('reader-settings-panel'); + + if (isZenMode) { + document.body.classList.add('zen-mode-active'); + if (zenBtn) zenBtn.classList.add('active'); + if (readerSettingsPanel) readerSettingsPanel.classList.add('hidden'); + if (hud) { + hud.classList.remove('hidden'); + hud.classList.remove('hud-idle'); + wakeZenHud(); + } + if (!document.fullscreenElement && document.documentElement.requestFullscreen) { + document.documentElement.requestFullscreen().catch(() => {}); + } + } else { + document.body.classList.remove('zen-mode-active'); + if (zenBtn) zenBtn.classList.remove('active'); + if (hud) { + hud.classList.add('hidden'); + hud.classList.remove('hud-idle'); + } + if (zenHudIdleTimer) { + clearTimeout(zenHudIdleTimer); + zenHudIdleTimer = null; + } + if (document.fullscreenElement && document.exitFullscreen) { + document.exitFullscreen().catch(() => {}); + } + } +} + // ----------------------------------------------------------------------- // Reader Module Initialization // ----------------------------------------------------------------------- @@ -1865,6 +1949,62 @@ export function initReader() { const readerBackBtn = document.getElementById('reader-back-btn'); const readerToggleHighlightBtn = document.getElementById('reader-toggle-highlight-btn'); const readerTrainBtn = document.getElementById('reader-train-btn'); + const readerZenBtn = document.getElementById('reader-zen-btn'); + const zenHudExitBtn = document.getElementById('zen-hud-exit-btn'); + + if (readerZenBtn) { + readerZenBtn.addEventListener('click', (e) => { + e.stopPropagation(); + toggleZenMode(); + }); + } + + if (zenHudExitBtn) { + zenHudExitBtn.addEventListener('click', (e) => { + e.stopPropagation(); + toggleZenMode(false); + }); + } + + // Wake HUD on user activity during zen mode + ['mousemove', 'touchstart', 'scroll'].forEach(evt => { + window.addEventListener(evt, () => { + if (isZenMode) wakeZenHud(); + }, { passive: true }); + }); + + // Keyboard shortcut for Zen Mode (F / f / а / А) and exit on Escape + document.addEventListener('keydown', (e) => { + const tag = (e.target && e.target.tagName) ? e.target.tagName.toLowerCase() : ''; + if (tag === 'input' || tag === 'textarea' || (e.target && e.target.isContentEditable)) { + return; + } + + const readerView = document.getElementById('reader-view'); + const readerInterface = document.getElementById('reader-interface'); + const isReaderActive = readerView && !readerView.classList.contains('hidden') && + readerInterface && !readerInterface.classList.contains('hidden'); + + if (!isReaderActive) return; + + if (e.key === 'Escape' && isZenMode) { + e.preventDefault(); + toggleZenMode(false); + return; + } + + if ((e.key === 'f' || e.key === 'F' || e.key === 'а' || e.key === 'А') && !e.ctrlKey && !e.metaKey && !e.altKey) { + e.preventDefault(); + toggleZenMode(); + } + }); + + // Native fullscreen sync + document.addEventListener('fullscreenchange', () => { + if (!document.fullscreenElement && isZenMode) { + toggleZenMode(false); + } + }); const popupCloseBtn = document.getElementById('popup-close-btn'); const popupSaveBtn = document.getElementById('popup-save-btn'); @@ -2450,6 +2590,7 @@ export function initReader() { if (readerBackBtn) { readerBackBtn.addEventListener('click', () => { + if (isZenMode) toggleZenMode(false); window.location.hash = '#reader'; }); } diff --git a/app/static/js/modules/ui.js b/app/static/js/modules/ui.js index 473f258..15859ce 100644 --- a/app/static/js/modules/ui.js +++ b/app/static/js/modules/ui.js @@ -49,6 +49,111 @@ export function formatTranslationWithSpoiler(text) { return `${escapeHtml(cleanText)} ℹ️ форма${escapeHtml(noteText)}`; } +// ----------------------------------------------------------------------- +// Lightweight Native Markdown Parsers (Tables & Notes for Murphy Grammar) +// Zero-dependency, safe escaping first, pure ES6 +// ----------------------------------------------------------------------- +export function renderMarkdownInline(text) { + if (!text) return ''; + let str = escapeHtml(text); + // Bold: **text** + str = str.replace(/\*\*(.+?)\*\*/g, '$1'); + // Inline code: `text` + str = str.replace(/`([^`]+)`/g, '$1'); + // Italic: *text* (excluding already formatted strong) + str = str.replace(/(?$1'); + return str; +} + +export function renderMarkdownTable(mdText) { + if (!mdText || typeof mdText !== 'string' || !mdText.trim()) return ''; + const rawLines = mdText.trim().split(/\r?\n/).map(l => l.trim()).filter(l => l.length > 0); + const tableLines = rawLines.filter(l => l.startsWith('|') && l.endsWith('|')); + if (tableLines.length < 2) { + return `
${escapeHtml(mdText)}
`; + } + + const splitRow = (rowStr) => { + const inner = rowStr.replace(/^\|/, '').replace(/\|$/, ''); + return inner.split(/(? c.trim().replace(/\\\|/g, '|')); + }; + + const headers = splitRow(tableLines[0]); + const alignRow = splitRow(tableLines[1]); + const alignments = alignRow.map(col => { + const tc = col.trim(); + if (tc.startsWith(':') && tc.endsWith(':')) return 'center'; + if (tc.endsWith(':')) return 'right'; + return 'left'; + }); + + const rows = []; + for (let r = 2; r < tableLines.length; r++) { + rows.push(splitRow(tableLines[r])); + } + + let html = '
'; + headers.forEach((h, idx) => { + const align = alignments[idx] || 'left'; + html += ``; + }); + html += ''; + + rows.forEach(row => { + html += ''; + row.forEach((cell, idx) => { + const align = alignments[idx] || 'left'; + html += ``; + }); + html += ''; + }); + html += '
${renderMarkdownInline(h)}
${renderMarkdownInline(cell)}
'; + return html; +} + +export function renderMarkdownNotes(mdText) { + if (!mdText || typeof mdText !== 'string' || !mdText.trim()) return ''; + const lines = mdText.split(/\r?\n/); + const out = []; + let inList = false; + + for (let i = 0; i < lines.length; i++) { + const trimmed = lines[i].trim(); + + if (trimmed.startsWith('- ') || trimmed.startsWith('* ')) { + if (!inList) { + out.push('
    '); + inList = true; + } + const itemText = trimmed.replace(/^[-*]\s+/, ''); + out.push(`
  • ${renderMarkdownInline(itemText)}
  • `); + continue; + } else if (inList) { + out.push('
'); + inList = false; + } + + if (trimmed.startsWith('#### ')) { + out.push(`
${renderMarkdownInline(trimmed.replace(/^####\s+/, ''))}
`); + } else if (trimmed.startsWith('### ')) { + out.push(`

${renderMarkdownInline(trimmed.replace(/^###\s+/, ''))}

`); + } else if (trimmed.startsWith('## ')) { + out.push(`

${renderMarkdownInline(trimmed.replace(/^##\s+/, ''))}

`); + } else if (trimmed.startsWith('> ')) { + out.push(`
${renderMarkdownInline(trimmed.replace(/^>\s+/, ''))}
`); + } else if (trimmed === '') { + // blank line separator + } else { + out.push(`

${renderMarkdownInline(trimmed)}

`); + } + } + if (inList) { + out.push(''); + } + + return `
${out.join('\n')}
`; +} + // ----------------------------------------------------------------------- // Toast Notifications // ----------------------------------------------------------------------- @@ -168,6 +273,11 @@ export function closeModal(modalElem) { // View Switcher Helper // ----------------------------------------------------------------------- export function switchView(targetViewId) { + if (targetViewId !== 'reader-view') { + document.body.classList.remove('zen-mode-active'); + const hud = document.getElementById('reader-zen-hud'); + if (hud) hud.classList.add('hidden'); + } const allViews = [ 'dictionary-view', 'srs-view', @@ -286,6 +396,9 @@ export const ui = { playTextSpeech, cleanPromptTranslation, formatTranslationWithSpoiler, + renderMarkdownInline, + renderMarkdownTable, + renderMarkdownNotes, }; export default ui; diff --git a/data/seeds/grammar_units.json b/data/seeds/grammar_units.json index 318fef7..e2f7215 100644 --- a/data/seeds/grammar_units.json +++ b/data/seeds/grammar_units.json @@ -4,80 +4,91 @@ "level": "A1-A2", "category": "Present Tenses", "title": "Present Continuous (I am doing)", - "subtitle": "Действие в процессе прямо сейчас или временная ситуация", - "golden_formula": "S + am / is / are + V-ing\n(I am working / He is sleeping / They are playing)", + "subtitle": "Действие в процессе прямо сейчас или временная ситуация в текущий период", + "golden_formula": "S + am / is / are + V-ing\n(+) I am working | He is sleeping | They are playing\n(-) S + am/is/are + not + V-ing (She isn't listening)\n(?) Am/Is/Are + S + V-ing? (Are you working now?)", + "cheatsheet_table": "| Форма | Формула | Пример | Маркеры времени |\n| :--- | :--- | :--- | :--- |\n| **Утверждение (+)** | S + am/is/are + V-ing | *I am typing an email right now.* | now, right now |\n| **Отрицание (-)** | S + am/is/are + not + V-ing | *He isn't sleeping, he's reading.* | at the moment, currently |\n| **Вопрос (?)** | Am/Is/Are + S + V-ing? | *Are they coming to the meeting?* | Look!, Listen! |\n| **Временный проект** | S + am/is/are + V-ing | *I am living with friends this month.* | this week, these days |\n| **Изменения/Тренды** | S + am/is/are + getting/changing | *The climate is getting warmer.* | more and more, gradually |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nPresent Continuous передаёт идею **«я нахожусь внутри незавершённого действия»**. Действие уже началось, ещё не закончилось и разворачивается прямо в момент разговора или в текущий период жизни.\n\n### ⏱️ Слова-маркеры (Signal Words)\n- `now`, `right now` — прямо сейчас.\n- `at the moment`, `currently` — в данный момент.\n- `Look!`, `Listen!`, `Hurry up!` — маркеры привлечения внимания к происходящему процессу.\n- `this week`, `these days`, `this year` — временные ситуации, не являющиеся постоянной рутиной.\n\n### ⚠️ Частые ошибки (Common Pitfalls)\n1. **Глаголы состояния (Stative Verbs)**: глаголы чувств, мыслей и обладания НЕ используются в -ing: *know, like, want, understand, believe, need, remember*. Нельзя сказать: *«I am understanding»*, правильно: *«I understand»*.\n2. **Пропуск глагола to be**: нельзя сказать *«I working»*, обязательно *«I am working»*.\n3. **Орфография при добавлении -ing**:\n - `run` → `running`, `sit` → `sitting` (удвоение согласной после краткой ударной гласной);\n - `write` → `writing`, `make` → `making` (конечная -e выпадает);\n - `lie` → `lying`, `die` → `dying` (сочетание -ie меняется на -y).\n\n### 💡 Живые примеры с переводом\n- *Please don't make so much noise. I am trying to work.* — Пожалуйста, не шуми. Я пытаюсь работать (прямо сейчас).\n- *Why are you wearing a coat? It's not cold.* — Почему на тебе пальто? На улице не холодно.\n- *Are you enjoying your new project at work?* — Тебе нравится твой новый проект на работе (в этот период)?", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Перечертите таблицу форм (+, -, ?) и выделите маркером вспомогательные глаголы am / is / are.\n2. Запишите правило орфографии: удвоение согласных (run → running) и выпадение -e (write → writing).\n3. Составьте от руки 3 личных примера по шаблону:\n - [Прямо сейчас] Right now, I am [действие: sitting at my desk / drinking tea]...\n - [Временный процесс] These days, I am [study/work project: learning English vocabulary]...\n - [Что делают другие] My colleagues/family are [relaxing / working]...", "contrast_explanation": [ { - "situation_a": "Действие происходит в момент речи (Now / at the moment)", + "situation_a": "Действие происходит в секунду речи (Now / at the moment)", "example_a": "Please be quiet. I am trying to concentrate.", "trans_a": "Пожалуйста, потише. Я пытаюсь сосредоточиться (прямо сейчас).", "situation_b": "Временная ситуация в текущий период жизни (Around now / temporarily)", "example_b": "She is studying computer science at university this year.", "trans_b": "В этом году она изучает информатику в университете (временный процесс).", - "key_difference": "Present Continuous всегда показывает незавершённое действие — мы находимся внутри процесса." + "key_difference": "Present Continuous всегда показывает незавершённый процесс — мы находимся в его середине." + }, + { + "situation_a": "Постоянный факт или привычка (Present Simple)", + "example_a": "I live in Moscow. I work in an IT company.", + "trans_a": "Я живу в Москве (постоянно). Я работаю в IT-компании (постоянное место).", + "situation_b": "Временное отклонение от нормы (Present Continuous)", + "example_b": "I am living with my brother while my apartment is renovated.", + "trans_b": "Я временно живу у брата, пока в моей квартире идёт ремонт.", + "key_difference": "Continuous подчеркивает временность, Simple — постоянство и стабильность." } ], - "journaling_prompt": "Запишите в тетрадь золотую формулу маркером. Напишите от руки 2-3 предложения о том, что происходит прямо сейчас вокруг вас или какой временный проект вы делаете на этой неделе (например: 'I am reading an English book right now').", "exercises": [ { "sentence": "Listen to those birds! They ___ so beautifully.", "target": "are singing", - "clue": "поют (прямо сейчас)", + "clue": "Действие происходит прямо сейчас (маркер 'Listen!'), подлежащее 'They' (множественное число)", "options": [ "are singing", "sing", "is singing", "sang" ], - "explanation": "Слово-маркер 'Listen!' указывает, что действие происходит прямо сейчас, подлежащее 'They' требует форму 'are singing'." + "explanation": "Слово-маркер 'Listen!' указывает на процесс в секунду речи. Подлежащее 'They' требует форму множественного числа 'are singing' (не 'is singing', и не Present Simple 'sing')." }, { - "sentence": "Why ___ you wearing a heavy coat in July?", + "sentence": "Why ___ you wearing a coat? It is warm outside today.", "target": "are", - "clue": "почему ты одет (в этот момент)", + "clue": "Вопрос к действию прямо сейчас: форма глагола to be для местоимения 'you'", "options": [ "are", "do", - "have", - "did" - ], - "explanation": "Перед формой глагола с окончанием -ing ('wearing') в вопросе Present Continuous ставится вспомогательный глагол 'are'." - }, - { - "sentence": "The water is boiling, so please ___ the stove.", - "target": "turn off", - "clue": "выключи (действие-команда)", - "options": [ - "turn off", - "turning off", - "is turning", - "turned" - ], - "explanation": "Вода кипит прямо сейчас (is boiling), поэтому обращение-просьба к собеседнику строится в повелительном наклонении: 'turn off'." - }, - { - "sentence": "Look! The bus is coming, we ___ run to catch it.", - "target": "must", - "clue": "должны (нужно поторопиться)", - "options": [ - "must", - "are", - "do", + "is", "have" ], - "explanation": "'The bus is coming' — автобус подъезжает прямо сейчас, модальный глагол 'must' выражает необходимость действовать немедленно." + "explanation": "В Present Continuous вопрос строится через вынос вспомогательного глагола to be перед подлежащим: 'Why are you wearing...' ('do' используется в Present Simple без -ing)." }, { - "sentence": "I ___ for a software company while my friend looks for a job.", - "target": "am currently working", - "clue": "в настоящее время работаю (временная ситуация)", + "sentence": "I ___ for my keys. Have you seen them anywhere?", + "target": "am looking", + "clue": "Я ищу прямо сейчас: местоимение 'I' + глагол look с предлогом for", "options": [ - "am currently working", - "works", - "have worked", - "worked" + "am looking", + "look", + "is looking", + "looking" ], - "explanation": "Для временного текущего периода занятости используется форма Present Continuous: 'am currently working'." + "explanation": "Поиск происходит в данный момент, для местоимения 'I' форма Present Continuous — 'am looking'." + }, + { + "sentence": "The economic situation in the region ___ better every month.", + "target": "is getting", + "clue": "Постепенное изменение/тренд: подлежащее 'situation' (ед. число)", + "options": [ + "is getting", + "gets", + "are getting", + "got" + ], + "explanation": "Для описания развивающихся процессов и изменений (get better, grow, change) используется Present Continuous: 'is getting better'." + }, + { + "sentence": "Please don't disturb him right now. He ___ an important report.", + "target": "is preparing", + "clue": "Маркер 'right now' + просьба не беспокоить в этот момент", + "options": [ + "is preparing", + "prepares", + "prepare", + "was preparing" + ], + "explanation": "Маркер 'right now' и контекст 'не беспокой его' однозначно требуют Present Continuous: 'is preparing'." } ] }, @@ -86,80 +97,91 @@ "level": "A1-A2", "category": "Present Tenses", "title": "Present Simple (I do)", - "subtitle": "Регулярные привычки, факты, законы природы и расписания", - "golden_formula": "S + V1 (he/she/it + V-s/es)\n(I work / She works / Do you work? / He does not work)", + "subtitle": "Регулярные привычки, законы природы, постоянные факты и расписания", + "golden_formula": "S + V1 (he / she / it + V-s/es)\n(+) I work / He works\n(-) S + do not / does not + V1 (I don't work / He doesn't work)\n(?) Do / Does + S + V1? (Do you work? / Does she work?)", + "cheatsheet_table": "| Лицо | Утверждение (+) | Отрицание (-) | Вопрос (?) |\n| :--- | :--- | :--- | :--- |\n| **I / you / we / they** | *I work every day.* | *I don't work on Sundays.* | *Do you work remotely?* |\n| **he / she / it** | *She works in a bank.* | *She doesn't work here.* | *Does he work full-time?* |\n| **Глагол to be** | *He is an engineer.* | *He isn't at the office.* | *Is he ready?* |\n| **Частотные наречия** | *always, usually, often* | ставятся перед основным глаголом | *I always check my email.* |\n| **Окончания -s/-es** | watch → watch**es**, study → stud**ies** | go → go**es**, fix → fix**es** | kiss → kiss**es** |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nPresent Simple выражает **вещи вообще, регулярные привычки, законы природы и расписания**. Это не то, что происходит сию секунду, а постоянный порядок вещей.\n\n### ⏱️ Слова-маркеры (Signal Words)\n- Наречия частоты: `always` (всегда), `usually` (обычно), `often` (часто), `sometimes` (иногда), `rarely / seldom` (редко), `never` (никогда).\n *Правило позиции: они ставятся ПЕРЕД смысловым глаголом, но ПОСЛЕ глагола to be (I always drink coffee / I am always on time).*\n- Обстоятельства времени: `every day / week / year`, `on Mondays`, `in the morning`, `twice a month`.\n\n### ⚠️ Частые ошибки (Common Pitfalls)\n1. **Забытое окончание -s для he/she/it**: самая частая ошибка новичков. *He live in London* ❌ → *He lives in London* ✅.\n2. **Двойное -s в отрицаниях и вопросах**: вспомогательный глагол `does / doesn't` уже забрал окончание -s себе, поэтому основной глагол остаётся в «голом» инфинитиве:\n - *He doesn't works* ❌ → *He doesn't work* ✅.\n - *Does she likes coffee?* ❌ → *Does she like coffee?* ✅.\n3. **Правописание окончаний**:\n - После шипящих (-s, -sh, -ch, -x, -z) и -o добавляется `-es`: *watches, washes, goes, does*.\n - Согласная + -y меняется на `-ies`: *study → studies, fly → flies* (но гласная + y: *play → plays*).\n\n### 💡 Живые примеры с переводом\n- *The Earth goes around the Sun.* — Земля вращается вокруг Солнца (закон природы).\n- *Nurses look after patients in hospitals.* — Медсёстры ухаживают за пациентами в больницах (профессия, факт).\n- *What time do you usually finish work?* — Во сколько ты обычно заканчиваешь работу?", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Запишите золотую формулу и обведите красным маркером окончание -s / -es для 3-го лица (he/she/it).\n2. Выпишите правило: 'does/doesn't съедает -s у основного глагола'.\n3. Составьте от руки 3 факта о вашей повседневной жизни:\n - [Привычка с наречием] I usually [wake up at 7 AM / drink espresso]...\n - [Отрицание] I don't [watch television / eat fast food]...\n - [Факт о друге/коллеге] My friend works as [профессия] and lives in [город]...", "contrast_explanation": [ { - "situation_a": "Регулярное повторяющееся действие или привычка (Habit / Routine)", - "example_a": "I drink a cup of black coffee every morning at 8:00.", - "trans_a": "Я пью чашку чёрного кофе каждое утро в 8:00.", - "situation_b": "Непреложный факт или закон природы (General truth / Fact)", - "example_b": "The Earth moves around the Sun.", - "trans_b": "Земля вращается вокруг Солнца (постоянный факт).", - "key_difference": "Present Simple говорит о том, что верно вообще, регулярно или по расписанию, а не только в данную секунду." + "situation_a": "Регулярный факт и привычка (Present Simple)", + "example_a": "I play tennis every Saturday morning.", + "trans_a": "Я играю в теннис каждое утро субботы (постоянное хобби).", + "situation_b": "Действие в момент речи (Present Continuous)", + "example_b": "I am playing tennis right now with Mark.", + "trans_b": "Я играю в теннис прямо сейчас с Марком (на корте в эту секунду).", + "key_difference": "Present Simple = регулярность и расписание; Present Continuous = процесс прямо сейчас." + }, + { + "situation_a": "Утверждение для 3-го лица (he/she/it)", + "example_a": "Alex speaks three languages fluently.", + "trans_a": "Алекс свободно говорит на трёх языках (постоянный навык, окончание -s).", + "situation_b": "Отрицание с doesn't (глагол теряет -s)", + "example_b": "He doesn't speak Japanese.", + "trans_b": "Он не говорит по-японски (doesn't забирает окончание, speak без -s).", + "key_difference": "В отрицаниях и вопросах с does окончание -s с основного глагола ВСЕГДА исчезает." } ], - "journaling_prompt": "Запишите в тетрадь формулу с окончанием -s для he/she/it. Напишите от руки 2-3 ваших реальных привычки с маркерами частоты: always, usually, every day (например: 'I usually drink green tea after lunch').", "exercises": [ { "sentence": "My brother ___ in a bank in the city center.", "target": "works", - "clue": "работает (постоянно, факт)", + "clue": "Постоянная работа (факт), подлежащее 'My brother' (он, 3-е лицо ед. ч.)", "options": [ "works", "work", "is working", "working" ], - "explanation": "Подлежащее 'My brother' (он) требует глагола с окончанием -s в Present Simple: 'works'." + "explanation": "Для 'My brother' (he) в Present Simple глагол обязательно получает окончание -s: 'works'." }, { - "sentence": "How often ___ you go to the gym during the week?", - "target": "do", - "clue": "вспомогательный глагол вопроса", + "sentence": "What time ___ the train arrive in Chicago?", + "target": "does", + "clue": "Вопрос о расписании поезда ('the train' = it)", "options": [ - "do", "does", - "are", - "have" + "do", + "is", + "are" ], - "explanation": "С местоимением 'you' вопрос в Present Simple образуется с помощью вспомогательного глагола 'do'." + "explanation": "Для подлежащего 'the train' (it) в вопросах Present Simple используется вспомогательный глагол 'does'." }, { - "sentence": "Water ___ at zero degrees Celsius.", - "target": "freezes", - "clue": "замерзает (закон природы)", + "sentence": "She ___ like spicy food, so she always orders salad.", + "target": "doesn't", + "clue": "Отрицание для местоимения 'She' в Present Simple", "options": [ - "freezes", - "freeze", - "is freezing", - "froze" + "doesn't", + "don't", + "isn't", + "not" ], - "explanation": "Физические факты и свойства веществ выражаются в Present Simple: неисчисляемое 'Water' требует 'freezes'." + "explanation": "Отрицание для he/she/it строится с помощью 'doesn't + инфинитив без to': 'doesn't like'." }, { - "sentence": "She ___ meat because she is a strict vegetarian.", - "target": "does not eat", - "clue": "не ест (постоянная привычка)", + "sentence": "We ___ go abroad on vacation, usually twice a year.", + "target": "often", + "clue": "Наречие частоты: ставится перед смысловым глаголом 'go'", "options": [ - "does not eat", - "do not eat", - "is not eating", - "not eats" + "often", + "always", + "never", + "rarely" ], - "explanation": "Отрицание для третьего лица единственного числа (she) образуется через 'does not' + начальная форма глагола 'eat'." + "explanation": "Контекст 'usually twice a year' (обычно дважды в год) сочетается по смыслу с наречием 'often' (часто)." }, { - "sentence": "The train to London ___ at 9:30 every morning.", - "target": "departs", - "clue": "отправляется (по расписанию)", + "sentence": "My parents ___ in a small house near the seaside.", + "target": "live", + "clue": "Подлежащее во множественном числе ('My parents' = they)", "options": [ - "departs", - "departing", - "is departing", - "depart" + "live", + "lives", + "are living", + "living" ], - "explanation": "Общественный транспорт и расписания в английском языке всегда передаются через Present Simple: 'departs'." + "explanation": "Для множественного числа 'My parents' (they) используется базовая форма глагола без -s: 'live'." } ] }, @@ -168,80 +190,91 @@ "level": "A1-A2", "category": "Present Tenses", "title": "Present Continuous vs Present Simple (I am doing vs I do)", - "subtitle": "Главный контраст: процесс сейчас vs факт вообще + глаголы состояния (Stative Verbs)", - "golden_formula": "NOW: am/is/are + V-ing | ALWAYS/HABIT: V1(s)\nStative Verbs (NO -ing): know, like, want, understand, remember, believe", + "subtitle": "Битва времен: процесс в моменте против постоянного порядка вещей и Stative Verbs", + "golden_formula": "NOW / TEMPORARY: am / is / are + V-ing\nHABIT / PERMANENT: V1 (he/she/it + s)\nSTATIVE VERBS (NO -ING): like, love, hate, want, need, prefer, know, realize, suppose, mean, understand, believe, remember, belong, fit, contain, consist, seem", + "cheatsheet_table": "| Критерий | Present Continuous (I am doing) | Present Simple (I do) |\n| :--- | :--- | :--- |\n| **Суть** | Действие незавершено, мы в середине | Постоянный факт, рутина, закон природы |\n| **Время** | Прямо сейчас или в текущий период | Всегда, регулярно, по расписанию |\n| **Маркеры** | *now, at the moment, this week, Look!* | *always, usually, often, every day, twice a week* |\n| **Глаголы мышления** | НЕ употребляются в -ing (*know, believe*) | *I know the answer. (NOT I am knowing)* |\n| **Глаголы чувств** | НЕ употребляются в -ing (*like, love, want*) | *I want a cup of coffee. (NOT I am wanting)* |\n| **Особый: THINK** | *I am thinking* = размышляю прямо сейчас | *I think* = у меня есть мнение (I think it's good) |\n| **Особый: HAVE** | *I am having lunch / a shower* = действие | *I have a car* = владение (NOT I am having a car) |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nГлавный вопрос носителя: **«Это процесс в развитии или стабильный факт?»**\n- *Water is boiling. Can you turn it off?* — Вода кипит прямо сейчас (бурлит в чайнике).\n- *Water boils at 100 degrees Celsius.* — Вода кипит при 100 градусах (физический закон всегда).\n\n### 🧠 Глаголы состояния (Stative Verbs) — Золотой список\nЭти глаголы описывают состояние ума, чувства или отношение, а не физическое действие. Они **никогда не используются в Present Continuous** (даже если ситуация происходит прямо сейчас!):\n1. **Эмоции и желания**: `like`, `love`, `hate`, `want`, `need`, `prefer`.\n2. **Мышление и знание**: `know`, `understand`, `recognize`, `believe`, `remember`, `forget`, `mean`.\n3. **Владение**: `have` (в значении обладать), `belong`, `own`, `possess`.\n4. **Восприятие**: `see`, `hear`, `smell`, `taste`, `seem`.\n\n### ⚡ Двойные глаголы (Dual-meaning Verbs)\n- **THINK**:\n - *What do you think of this idea?* (Каково твоё мнение? — Simple)\n - *Be quiet, I am thinking.* (Идёт активный процесс размышления — Continuous)\n- **HAVE**:\n - *I have two laptops.* (Владение — Simple)\n - *I am having lunch / having a break.* (Устойчивое действие — Continuous)\n\n### 💡 Живые примеры с переводом\n- *Do you understand what I mean?* — Ты понимаешь, что я имею в виду? (Оба глагола stative!)\n- *I am living with my parents until I find an apartment.* — Я временно живу с родителями (Continuous), хотя обычно люди говорят *I live in Madrid* (Simple).", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Нарисуйте таблицу из двух колонок: 'Present Continuous (сейчас/временно)' и 'Present Simple (всегда/факт)'.\n2. Запишите в рамку 8 главных глаголов-запретов для -ing: know, want, like, understand, need, believe, remember, belong.\n3. Запишите контраст двойного глагола think:\n - 'I think it's a good plan' (мнение) vs 'I'm thinking about it' (процесс мысли).\n4. Составьте от руки контрастную пару о себе: 'I usually [привычка: drink tea], but today I am [процесс: drinking coffee]'.", "contrast_explanation": [ { - "situation_a": "I am doing (Прямо сейчас / процесс в развитии)", - "example_a": "Listen! What language are those tourists speaking?", - "trans_a": "Послушай! На каком языке говорят эти туристы (сейчас)?", - "situation_b": "I do (Вообще / способность / факт)", - "example_b": "My colleague speaks three foreign languages fluently.", - "trans_b": "Мой коллега свободно говорит на трёх иностранных языках (вообще).", - "key_difference": "Глаголы чувств и мыслей (know, understand, want, believe, like) практически никогда не используются в форме -ing!" + "situation_a": "Глагол состояния (Stative Verb) — только Simple", + "example_a": "I understand the grammar rule clearly now.", + "trans_a": "Я понимаю грамматическое правило сейчас (слово 'now', но глагол stative — только Simple!).", + "situation_b": "Динамическое действие (Action Verb) — Continuous", + "example_b": "I am studying the grammar rule right now.", + "trans_b": "Я изучаю правило прямо сейчас (физический процесс — Continuous).", + "key_difference": "Даже при слове 'now' глаголы understand, know, want не ставятся в -ing." + }, + { + "situation_a": "Глагол HAVE как владение (Simple)", + "example_a": "We have a big house in the countryside.", + "trans_a": "У нас есть большой дом за городом (владение имуществом).", + "situation_b": "Глагол HAVE во фразовом значении (Continuous)", + "example_b": "We are having dinner together right now.", + "trans_b": "Мы сейчас ужинаем вместе (идиома have dinner = процесс еды).", + "key_difference": "В значении обладания have не имеет -ing. В значении процесса (have breakfast/shower) -ing разрешён." } ], - "journaling_prompt": "Запишите в тетрадь список глаголов состояния (Stative Verbs), которые нельзя ставить в -ing. Составьте от руки 2 контрастных предложения о себе (например: 'I live in Moscow, but this month I am staying with my parents').", "exercises": [ { - "sentence": "I ___ what you mean, could you explain it again?", - "target": "do not understand", - "clue": "не понимаю (глагол состояния understand)", + "sentence": "I ___ what you mean, but I don't agree with your conclusion.", + "target": "understand", + "clue": "Глагол ментального состояния (Stative Verb) — не используется в -ing", "options": [ - "do not understand", - "am not understanding", - "not understand", - "did not understood" + "understand", + "am understanding", + "understands", + "understanding" ], - "explanation": "Глагол 'understand' является глаголом ментального состояния (stative verb) и не употребляется во времени Continuous." + "explanation": "Глагол 'understand' выражает состояние понимания (Stative Verb) и не употребляется в Continuous форме, правильный ответ: 'understand'." }, { - "sentence": "Look outside! It ___ heavily, take an umbrella.", - "target": "is raining", - "clue": "идёт дождь (прямо сейчас)", + "sentence": "Hurry up! The taxi ___ outside for us.", + "target": "is waiting", + "clue": "Призыв 'Hurry up!' указывает на процесс, происходящий прямо в эту секунду", "options": [ - "is raining", - "rains", - "rained", - "rain" + "is waiting", + "waits", + "wait", + "are waiting" ], - "explanation": "Призыв 'Look outside!' сигнализирует о действии, разворачивающемся на глазах прямо сейчас: 'is raining'." + "explanation": "Контекст 'Hurry up!' (Поторопись!) указывает на разворачивающееся действие прямо сейчас. Для 'taxi' (it) форма: 'is waiting'." }, { - "sentence": "It seldom ___ in this dry desert region.", - "target": "rains", - "clue": "идёт дождь (редко, постоянное свойство)", + "sentence": "What ___ of my new presentation design?", + "target": "do you think", + "clue": "Вопрос о мнении/оценке (Think как точка зрения = Present Simple)", "options": [ - "rains", - "is raining", - "was raining", - "rain" + "do you think", + "are you thinking", + "you think", + "does you think" ], - "explanation": "Наречие частотности 'seldom' (редко) описывает общее климатическое свойство местности $\rightarrow$ Present Simple: 'rains'." + "explanation": "Когда мы спрашиваем мнение ('Что ты думаешь / как тебе?'), глагол think используется в Present Simple: 'What do you think?'." }, { - "sentence": "Do you ___ this beautiful song?", - "target": "know", - "clue": "знаешь (глагол состояния know)", + "sentence": "Usually I ___ by bus, but this week I am walking because the weather is sunny.", + "target": "go", + "clue": "Маркер 'Usually' показывает регулярную привычку", "options": [ - "know", - "knowing", - "are knowing", - "knew" + "go", + "am going", + "goes", + "went" ], - "explanation": "Глагол 'know' — стативный глагол, вопрос строится в Present Simple: 'Do you know?'" + "explanation": "Первая часть предложения описывает привычную рутину (маркер 'Usually'), поэтому нужен Present Simple: 'I go'." }, { - "sentence": "Normally I drink tea, but today I ___ coffee.", - "target": "am drinking", - "clue": "пью (сегодня, исключение из привычки)", + "sentence": "This luxury watch ___ to my grandfather.", + "target": "belongs", + "clue": "Глагол принадлежности (Belong = Stative Verb, подлежащее 'watch' = it)", "options": [ - "am drinking", - "drink", - "drinks", - "drank" + "belongs", + "is belonging", + "belong", + "belonged" ], - "explanation": "Контраст: 'Normally I drink' (привычка в Simple), но 'today I am drinking' (временное отклонение от нормы в Continuous)." + "explanation": "Глагол 'belong' (принадлежать) — глагол состояния, не имеет Continuous формы. Для 'watch' (it) требуется форма с -s: 'belongs'." } ] }, @@ -250,80 +283,91 @@ "level": "A1-A2", "category": "Past Tenses", "title": "Past Simple (I did)", - "subtitle": "Завершённое действие в прошлом с точной привязкой ко времени", - "golden_formula": "S + V2 / V-ed | Did + S + V1? | S + did not + V1\n(yesterday, last night, two years ago, in 2021, when I was a child)", + "subtitle": "Завершённые действия в прошлом с конкретной привязкой ко времени", + "golden_formula": "Regular verbs: V + -ed (worked, watched, stopped, studied)\nIrregular verbs: 2nd form (went, came, saw, bought, took, wrote)\n(-) S + did not (didn't) + V1 (I didn't see him)\n(?) Did + S + V1? (Did you go to London?)", + "cheatsheet_table": "| Тип предложения | Формула | Пример | Маркеры завершённого прошлого |\n| :--- | :--- | :--- | :--- |\n| **Утверждение (+) прав.** | S + V-ed | *We played tennis yesterday.* | yesterday, yesterday morning |\n| **Утверждение (+) неправ.** | S + V2 (2-я колонка) | *I bought a new laptop last week.* | last night, last week, last month |\n| **Отрицание (-)** | S + did not (didn't) + V1 | *They didn't arrive on time.* | 2 days ago, a year ago |\n| **Вопрос (?)** | Did + S + V1? | *Did you watch the match?* | in 2018, in the 1990s |\n| **Глагол to be (was/were)** | S + was/were (БЕЗ did!) | *I was tired. They were happy.* | when I was a child, at 3 PM |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nPast Simple используется, когда действие **полностью началось и завершилось в прошлом**, и время действия известно или названо. Это базовое время для любых исторических хроник, историй и перечисления событий.\n\n### ⏱️ Слова-маркеры (Signal Words)\n- `yesterday`, `yesterday evening` — вчера.\n- `... ago` (three days ago, ten years ago) — тому назад.\n- `last ...` (last week, last month, last summer, last night) — на прошлой...\n- Точные даты и исторические вехи: `in 2015`, `in the 19th century`, `on Monday`.\n- Придаточные предложения времени: `when I was a student`, `when she arrived`.\n\n### ⚠️ Частые ошибки (Common Pitfalls)\n1. **Двойное прошедшее время в отрицании и вопросе**:\n - Вспомогательный `did / didn't` уже забрал прошедшее время себе! Основной глагол возвращается в первую форму:\n - *I didn't went* ❌ → *I didn't go* ✅.\n - *Did you bought it?* ❌ → *Did you buy it?* ✅.\n2. **Путаница to be с did**:\n - Для глагола to be в вопросах и отрицаниях `did` НЕ нужен:\n - *Did you be at home?* ❌ → *Were you at home?* ✅.\n - *I didn't be tired* ❌ → *I wasn't tired* ✅.\n3. **Правописание окончаний -ed**:\n - `stop` → `stopped` (удвоение согласной);\n - `study` → `studied` (y меняется на i);\n - `decide` → `decided` (только -d, если слово уже кончается на -e).\n\n### 💡 Живые примеры с переводом\n- *Mozart wrote more than 600 pieces of music.* — Моцарт написал более 600 музыкальных произведений (законченная историческая эпоха).\n- *We didn't go out yesterday because it was raining heavily.* — Мы не пошли гулять вчера, потому что шёл сильный дождь.", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Нарисуйте линию времени со стрелкой в прошлое и точкой 'X' (действие завершено в прошлом).\n2. Запишите формулы: (+) V2/ed, (-) didn't + V1, (?) Did + S + V1.\n3. Выпишите 5 ключевых неправильных глаголов с переводом: go→went, see→saw, buy→bought, have→had, write→wrote.\n4. Составьте от руки 3 реальных предложения о прошлых выходных:\n - Last weekend, I [went / visited / cooked]...\n - I didn't [have time to / buy]...\n - Two years ago, I [started / moved to]...", "contrast_explanation": [ { - "situation_a": "Действие полностью завершилось в прошлом (Finished past time)", - "example_a": "We arrived in London yesterday afternoon.", - "trans_a": "Мы прибыли в Лондон вчера днём (период 'вчера' завершён).", - "situation_b": "Последовательность действий в прошлом (Story sequence)", - "example_b": "He woke up, brushed his teeth, and left the house.", - "trans_b": "Он проснулся, почистил зубы и вышел из дома (цепочка фактов).", - "key_difference": "Past Simple отвечает на вопрос 'Когда это произошло?' и разрывает связь с настоящим моментом." - } - ], - "journaling_prompt": "Нарисуйте в тетради линию времени со стрелкой в прошлое. Напишите от руки 3 реальных вещи, которые вы сделали вчера с точным временем или маркерами (например: 'Yesterday I finished my work at 7 PM and cooked dinner').", - "exercises": [ - { - "sentence": "Mozart ___ more than six hundred pieces of music.", - "target": "wrote", - "clue": "написал (исторический факт в прошлом)", - "options": [ - "wrote", - "has written", - "writes", - "was writing" - ], - "explanation": "Моцарт жил в прошлом, период его жизни завершён $\rightarrow$ употребляется Past Simple: 'wrote'." + "situation_a": "Утвердительное предложение (нужна 2-я форма)", + "example_a": "She bought an expensive coat yesterday.", + "trans_a": "Она купила дорогое пальто вчера (утверждение — глагол buy во 2-й форме bought).", + "situation_b": "Отрицательное предложение (нужна 1-я форма)", + "example_b": "She didn't buy any shoes.", + "trans_b": "Она не купила туфли (didn't забирает прошедшее время, глагол возвращается в buy).", + "key_difference": "Форма V2 используется ТОЛЬКО в утверждениях. В отрицаниях и вопросах всегда V1." }, { - "sentence": "Where ___ you go on your last summer vacation?", + "situation_a": "Обычный смысловой глагол (через did)", + "example_a": "Did you see that movie yesterday?", + "trans_a": "Ты смотрел тот фильм вчера? (вопрос строится через Did + see).", + "situation_b": "Глагол состояния to be (без did)", + "example_b": "Were you at the cinema yesterday?", + "trans_b": "Ты был в кино вчера? (to be сам выходит вперёд: Were you, без did).", + "key_difference": "Глагол to be (was/were) никогда не используется со вспомогательным did." + } + ], + "exercises": [ + { + "sentence": "I ___ to the supermarket yesterday, but I forgot my wallet at home.", + "target": "went", + "clue": "Утверждение в Past Simple: 2-я форма неправильного глагола 'go'", + "options": [ + "went", + "go", + "gone", + "was going" + ], + "explanation": "Маркер 'yesterday' и контекст завершённого действия требуют 2-й формы неправильного глагола go: 'went'." + }, + { + "sentence": "We ___ enjoy the concert last night because the sound was terrible.", + "target": "didn't", + "clue": "Отрицание в Past Simple перед глаголом 'enjoy'", + "options": [ + "didn't", + "don't", + "weren't", + "haven't" + ], + "explanation": "Отрицание смыслового глагола в прошлом строится с помощью 'didn't + V1': 'didn't enjoy'." + }, + { + "sentence": "What time ___ you wake up this morning?", "target": "did", - "clue": "вспомогательный глагол для прошедшего времени", + "clue": "Вспомогательный глагол вопроса в Past Simple", "options": [ "did", "do", "were", "have" ], - "explanation": "Вопрос о завершённом периоде в прошлом ('last summer') строится с помощью вспомогательного глагола 'did'." + "explanation": "Вопрос к действию в завершённый момент времени строится через 'Did + S + V1': 'What time did you wake up?'." }, { - "sentence": "I ___ buy the phone because it was ridiculously expensive.", - "target": "did not", - "clue": "не (отрицание в прошедшем времени)", + "sentence": "The train was delayed, so they ___ thirty minutes late.", + "target": "arrived", + "clue": "Правильный глагол arrive с окончанием -ed", "options": [ - "did not", - "do not", - "was not", - "have not" + "arrived", + "arrive", + "were arrived", + "arriving" ], - "explanation": "Отрицание смыслового глагола 'buy' в Past Simple требует вспомогательного 'did not' ('didn't')." + "explanation": "Для регулярного глагола arrive в утверждении Past Simple добавляется окончание -d: 'arrived'." }, { - "sentence": "She ___ her keys in the office two days ago.", - "target": "lost", - "clue": "потеряла (неправильный глагол lose $\rightarrow$ lost)", + "sentence": "Where ___ you at 8 o'clock yesterday evening?", + "target": "were", + "clue": "Форма глагола to be в прошедшем времени для местоимения 'you'", "options": [ - "lost", - "losing", - "has lost", - "loses" + "were", + "was", + "did", + "are" ], - "explanation": "Маркер завершённого времени 'two days ago' строго требует формы Past Simple: 'lost'." - }, - { - "sentence": "When the meeting ___, everyone went to have lunch.", - "target": "ended", - "clue": "закончилась (последовательность событий)", - "options": [ - "ended", - "ends", - "has ended", - "is ending" - ], - "explanation": "Последовательность завершённых действий в прошлом передаётся в Past Simple: 'ended ... went'." + "explanation": "Для местоимения 'you' глагол to be в прошлом имеет форму 'were'. Вспомогательный did с глаголом to be не используется." } ] }, @@ -332,80 +376,91 @@ "level": "A1-A2", "category": "Past Tenses", "title": "Past Continuous (I was doing)", - "subtitle": "Процесс в конкретный момент в прошлом или фоновое действие", - "golden_formula": "S + was / were + V-ing\n(At 4 PM yesterday I was driving home / They were sleeping)", + "subtitle": "Действие в процессе в определённый точный момент в прошлом", + "golden_formula": "S + was / were + V-ing\nwas: I, he, she, it (I was sleeping)\nwere: you, we, they (They were having dinner)\n(-) S + wasn't / weren't + V-ing\n(?) Was / Were + S + V-ing?", + "cheatsheet_table": "| Местоимение | Утверждение (+) | Отрицание (-) | Вопрос (?) |\n| :--- | :--- | :--- | :--- |\n| **I / he / she / it** | *He was driving at 4 PM.* | *He wasn't working.* | *Was he sleeping when you called?* |\n| **you / we / they** | *They were playing games.* | *They weren't studying.* | *Were you waiting for me?* |\n| **Маркеры точного часа** | at 5:30 yesterday | at midnight | at that exact moment |\n| **Период процесса** | all day yesterday | all evening | from 3 to 6 PM yesterday |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nPast Continuous показывает, что **в конкретную точку времени в прошлом человек находился в середине действия**. Действие уже началось до этого момента и продолжалось после него.\n\n### ⏱️ Слова-маркеры (Signal Words)\n- Точный момент в прошлом: `at 4:00 PM yesterday`, `at that moment`, `at midnight`.\n- Непрерывный интервал: `all day yesterday`, `all night`, `from 6 to 8 PM`.\n- Контекстное окружение: `when I arrived` (действие УЖЕ шло к моменту прихода).\n\n### ⚠️ Частые ошибки (Common Pitfalls)\n1. **Путаница Past Simple и Past Continuous**:\n - *At 8:00 I had dinner* (В 8:00 я сел ужинать — точечное начало в Past Simple).\n - *At 8:00 I was having dinner* (В 8:00 я уже сидел с вилкой в руках в процессе ужина).\n2. **Выбор was vs were**: помните, что `you` (даже когда относится к одному человеку: «ты») ВСЕГДА требует `were` (*Were you listening?*).\n3. **Stative Verbs**: глаголы состояния не используются и в Past Continuous (*I knew the answer*, а не *I was knowing*).\n\n### 💡 Живые примеры с переводом\n- *This time last year, I was living in Germany.* — В это же время в прошлом году я жил в Германии (находился в процессе проживания).\n- *What were you doing when the phone rang?* — Что ты делал в тот момент, когда зазвонил телефон?", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Запишите формулы: was (I/he/she/it) + V-ing и were (you/we/they) + V-ing.\n2. Нарисуйте временную шкалу: длинная волнистая линия (Past Continuous) и стрелка в точку 'at 5 PM yesterday'.\n3. Составьте от руки 2 примера о том, чем вы занимались в конкретные часы вчера:\n - Yesterday at 3 PM, I was [working / driving / coding]...\n - At 11 PM last night, I was [sleeping / reading a book]...", "contrast_explanation": [ { - "situation_a": "Действие в процессе в конкретный момент времени в прошлом", - "example_a": "At 10:30 last night, I was watching a documentary.", - "trans_a": "В 10:30 вчера вечером я смотрел документальный фильм (был в процессе).", - "situation_b": "Фоновое действие, во время которого произошло короткое событие", - "example_b": "It was raining when we stepped outside.", - "trans_b": "Шёл дождь (фон в процессе), когда мы вышли на улицу (короткий факт).", - "key_difference": "Past Continuous показывает длительность и незавершённость действия в определённый момент прошлого." - } - ], - "journaling_prompt": "Запишите в тетрадь: 'was' для I/he/she/it, 'were' для you/we/they. Напишите от руки 2 предложения о том, чем именно вы занимались в 8 часов вечера вчера (например: 'At 8 PM yesterday I was walking my dog in the park').", - "exercises": [ - { - "sentence": "This time yesterday, we ___ over the Atlantic ocean.", - "target": "were flying", - "clue": "летели (были в процессе в этот момент)", - "options": [ - "were flying", - "flew", - "are flying", - "have flown" - ], - "explanation": "'This time yesterday' указывает на точный момент в прошлом, когда действие находилось в развитии: 'were flying'." + "situation_a": "Завершённое действие целиком (Past Simple)", + "example_a": "I read a book yesterday evening.", + "trans_a": "Я прочитал книгу вчера вечером (действие завершено от начала до конца).", + "situation_b": "Процесс в определённый момент (Past Continuous)", + "example_b": "At 9 PM yesterday, I was reading a book.", + "trans_b": "В 9 вечера я читал книгу (был в процессе чтения в конкретный час).", + "key_difference": "Past Simple подчеркивает факт завершения; Past Continuous показывает незавершённый процесс." }, { - "sentence": "What ___ you doing when the fire alarm sounded?", + "situation_a": "Единственное число: I / he / she / it", + "example_a": "The computer was downloading an update.", + "trans_a": "Компьютер скачивал обновление (was для 3-го лица ед. числа it).", + "situation_b": "Множественное число и You: you / we / they", + "example_b": "The servers were processing data.", + "trans_b": "Серверы обрабатывали данные (were для множественного числа they).", + "key_difference": "Для I/he/she/it используется was, для you/we/they — were." + } + ], + "exercises": [ + { + "sentence": "At 10 o'clock yesterday morning, I ___ in a client meeting.", + "target": "was sitting", + "clue": "Процесс в точный момент времени в прошлом ('At 10 o'clock yesterday')", + "options": [ + "was sitting", + "sat", + "were sitting", + "am sitting" + ], + "explanation": "Точное время в прошлом 'At 10 o'clock' и местоимение 'I' требуют форму Past Continuous: 'was sitting'." + }, + { + "sentence": "What ___ you doing when the fire alarm went off?", "target": "were", - "clue": "вспомогательный глагол для you в Past Continuous", + "clue": "Форма вспомогательного глагола для местоимения 'you' в Past Continuous", "options": [ "were", "was", "did", "are" ], - "explanation": "Для местоимения 'you' во времени Past Continuous используется вспомогательный глагол 'were'." + "explanation": "Для местоимения 'you' в Past Continuous используется вспомогательный глагол 'were': 'What were you doing?'." }, { - "sentence": "He burned his hand while he ___ cooking dinner.", - "target": "was", - "clue": "был в процессе готовки", + "sentence": "It ___ heavily all day yesterday, so we stayed indoors.", + "target": "was raining", + "clue": "Длительный непрерывный процесс на протяжении всего дня ('all day yesterday')", "options": [ - "was", - "is", + "was raining", + "rained", + "were raining", + "rains" + ], + "explanation": "Маркер 'all day yesterday' указывает на продолжительный фоновый процесс: 'It was raining'." + }, + { + "sentence": "I called you three times, but you ___ answer. What were you doing?", + "target": "didn't", + "clue": "Факт неответа на звонки в прошлом (Past Simple отрицание)", + "options": [ + "didn't", + "weren't", + "wasn't", + "don't" + ], + "explanation": "Здесь выражается точечный факт: 'ты не ответил', поэтому нужен Past Simple: 'didn't answer'." + }, + { + "sentence": "While Sarah was preparing dinner, the children ___ their homework.", + "target": "were doing", + "clue": "Параллельный процесс во множественном числе ('the children' = they)", + "options": [ + "were doing", + "was doing", "did", - "were" + "are doing" ], - "explanation": "Придаточное предложение времени с союзом 'while' описывает длительный процесс: 'while he was cooking'." - }, - { - "sentence": "The sun ___ brightly when I woke up this morning.", - "target": "was shining", - "clue": "светило (фон на момент пробуждения)", - "options": [ - "was shining", - "shone", - "has shone", - "shines" - ], - "explanation": "Солнце уже светило (длительный фон), когда произошло единичное пробуждение: 'was shining'." - }, - { - "sentence": "They didn't hear the doorbell because they ___ to loud music.", - "target": "were listening", - "clue": "слушали (процесс, объясняющий причину)", - "options": [ - "were listening", - "listened", - "are listening", - "listen" - ], - "explanation": "Они не услышали звонок, потому что в этот самый момент находились в процессе прослушивания: 'were listening'." + "explanation": "Два одновременных длительных процесса соединяются союзом While. Для 'the children' (they) форма: 'were doing'." } ] }, @@ -414,80 +469,82 @@ "level": "A1-A2", "category": "Past Tenses", "title": "Past Simple vs Past Continuous (I did vs I was doing)", - "subtitle": "Короткий факт vs Длительный фон: пересечение двух событий", - "golden_formula": "Background (Long): was/were + V-ing\nInterruption (Short): V2 / V-ed\n(While I was walking, I met my friend)", + "subtitle": "Длинный фон против внезапного прерывания: формулы связок While и When", + "golden_formula": "Background action (LONG): was / were + V-ing\nInterruption action (SHORT): V2 / -ed\nPATTERN: While + Past Continuous, Past Simple\n(While I was walking home, it started to rain)\nPATTERN: Past Continuous + when + Past Simple\n(I was watching TV when the phone rang)", + "cheatsheet_table": "| Конструкция | Значение | Пример |\n| :--- | :--- | :--- |\n| **Длинное + Короткое** | Длинный фон прерывается коротким событием | *While I was cooking, I burned my finger.* |\n| **Когда (When)** | Вводит внезапное точечное действие (V2) | *I was driving when a deer jumped out.* |\n| **Пока (While / As)** | Вводит длительный фоновый процесс (-ing) | *While they were sleeping, someone knocked.* |\n| **Два коротких подряд** | Последовательность событий (оба Past Simple) | *I heard a noise, got up and opened the door.* |\n| **Два длинных параллельно** | Два одновременных процесса (оба Continuous) | *While I was reading, my brother was playing.* |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nПредставьте себе фильм: **Past Continuous — это видеоряд (фоновые декорации и длящееся действие)**, а **Past Simple — это резкий щелчок затвора или звук выстрела (событие, которое произошло)**.\n\n### ⏱️ Ключевые союзы связки\n- `When` + **Past Simple** (точечное действие): *...when the lights went out*.\n- `While` / `As` + **Past Continuous** (длительный процесс): *While I was having a shower...*\n\n### ⚠️ Частые ошибки (Common Pitfalls)\n1. Не путайте последовательность действий и прерывание:\n - *When the phone rang, I answered it.* (Сначала зазвонил, потом я снял трубку — оба Simple).\n - *When the phone rang, I was having lunch.* (Звонок раздался прямо в середине моего обеда — Continuous + Simple).\n2. Не ставьте два коротких действия в Continuous (*I was getting up and was opening the door* ❌).", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Нарисуйте горизонтальную полосу (Длинное действие: was/were -ing) и вертикальную стрелку сквозь неё (Короткое действие: V2).\n2. Выпишите золотые формулы: 'While + Past Continuous, Past Simple' и 'Past Continuous + when + Past Simple'.\n3. Запишите от руки 2 реальные истории из жизни по шаблону:\n - 'While I was [doing something: walking in the park], I [saw / found / met]...'\n - 'I was [working on my laptop] when suddenly [my phone rang / the power went out]'.", "contrast_explanation": [ { - "situation_a": "Длительное фоновое действие прерывается коротким фактом", - "example_a": "I was taking a shower when the courier knocked on the door.", - "trans_a": "Я принимал душ (фон), когда курьер постучал в дверь (факт).", - "situation_b": "Два завершённых последовательных действия (Одно за другим)", - "example_b": "I heard the knock and opened the door immediately.", - "trans_b": "Я услышал стук и сразу открыл дверь (действие за действием).", - "key_difference": "Was doing = действие уже шло. Did = действие произошло, началось или закончилось." + "situation_a": "Прерывание процесса (Continuous + Simple)", + "example_a": "I was walking to the station when I met John.", + "trans_a": "Я шёл на станцию (длинное действие), когда встретил Джона (короткая встреча).", + "situation_b": "Последовательность действий (Simple + Simple)", + "example_b": "I arrived at the station and bought a ticket.", + "trans_b": "Я пришёл на станцию и купил билет (одно действие завершилось, началось второе).", + "key_difference": "Прерывание объединяет фоновый процесс и точку; последовательность описывает цепочку завершенных фактов." } ], - "journaling_prompt": "Запишите в тетрадь формулу: 'While + Past Continuous, Past Simple'. Напишите 2 ситуации из вашей жизни, когда одно прервало другое (например: 'While I was writing code, my laptop ran out of battery').", "exercises": [ { - "sentence": "While I was walking in the park, I ___ a rare bird.", - "target": "saw", - "clue": "увидел (короткое событие во время прогулки)", + "sentence": "While we ___ in the park, it suddenly started to rain.", + "target": "were walking", + "clue": "Длительное фоновое действие после союза 'While'", "options": [ - "saw", - "was seeing", - "have seen", - "see" + "were walking", + "walked", + "are walking", + "was walking" ], - "explanation": "Прогулка была длительным фоном (was walking), а наблюдение птицы — мгновенным событием в Past Simple: 'saw'." + "explanation": "Союз 'While' вводит длительный процесс (Past Continuous). Для местоимения 'we' правильная форма: 'were walking'." }, { - "sentence": "She ___ her leg while she was skiing in the Alps.", - "target": "broke", - "clue": "сломала (краткое прерывающее событие)", + "sentence": "I ___ my finger while I was chopping vegetables for salad.", + "target": "cut", + "clue": "Внезапное короткое действие-прерывание (2-я форма глагола cut)", "options": [ - "broke", - "was breaking", - "breaks", - "has broken" + "cut", + "was cutting", + "cutting", + "have cut" ], - "explanation": "Травма произошла одномоментно внутри процесса катания на лыжах: 'broke'." + "explanation": "Порез пальца — мгновенное точечное действие, прервавшее процесс нарезки, поэтому используется Past Simple: 'cut'." }, { - "sentence": "When I arrived at the cafe, my colleagues ___ for me.", - "target": "were waiting", - "clue": "ждали (уже находились в процессе ожидания)", + "sentence": "When the teacher walked into the room, the students ___ noise.", + "target": "were making", + "clue": "Фоновый процесс, который уже шёл к моменту прихода учителя", "options": [ - "were waiting", - "waited", - "have waited", - "are waiting" + "were making", + "made", + "are making", + "was making" ], - "explanation": "В момент моего прихода коллеги уже сидели и ждали: фоновый процесс требует 'were waiting'." + "explanation": "К моменту прихода учителя (короткое действие) шум уже стоял в классе (длительный процесс): 'were making'." }, { - "sentence": "We ___ television when suddenly the power went out.", - "target": "were watching", - "clue": "смотрели (процесс перед отключением света)", + "sentence": "He picked up his bag, ___ the door and left the house.", + "target": "locked", + "clue": "Цепочка последовательных завершённых действий (Past Simple)", "options": [ - "were watching", - "watched", - "have watched", - "watch" + "locked", + "was locking", + "locks", + "is locking" ], - "explanation": "Смотрели телевизор (длительное действие), которое было прервано внезапным отключением: 'were watching'." + "explanation": "Перечисление последовательных действий в прошлом строится полностью в Past Simple: picked up, locked, left." }, { - "sentence": "He picked up the phone, ___ the number, and waited.", - "target": "dialed", - "clue": "набрал (цепочка последовательных действий)", + "sentence": "What were you doing when the power ___ out?", + "target": "went", + "clue": "Точечное событие-прерывание после слова 'when'", "options": [ - "dialed", - "was dialing", - "has dialed", - "dials" + "went", + "was going", + "goes", + "has gone" ], - "explanation": "Цепочка последовательных действий в прошлом передаётся через Past Simple: 'picked up, dialed, and waited'." + "explanation": "После 'when' в конструкции прерывания используется Past Simple: 'went out'." } ] }, @@ -496,80 +553,82 @@ "level": "B1-B2", "category": "Present Perfect", "title": "Present Perfect (I have done)", - "subtitle": "Связь прошлого с настоящим: результат налицо, жизненный опыт и маркеры just / already / yet", - "golden_formula": "S + have / has + V3 (Past Participle)\nResult NOW / Life experience / just, already, yet, ever, never", + "subtitle": "Мост между прошлым и настоящим: результат виден сейчас и жизненный опыт", + "golden_formula": "S + have / has + V3 (Past Participle)\nhave: I, you, we, they | has: he, she, it\n(-) S + haven't / hasn't + V3\n(?) Have / Has + S + V3?\nMARKERS: just (только что), already (уже), yet (ещё не / уже в вопросах), ever, never, recently, so far, since, for", + "cheatsheet_table": "| Маркер | Позиция в предложении | Пример | Перевод |\n| :--- | :--- | :--- | :--- |\n| **just** | Между have и V3 | *I have just finished my work.* | Я только что закончил. |\n| **already** | Между have и V3 (раньше ожидаемого) | *He has already left the office.* | Он уже ушёл из офиса. |\n| **yet** | ВСЕГДА в самом конце (в - и ?) | *I haven't received the email yet.* | Я ещё не получил письмо. |\n| **ever** | В вопросах о жизненном опыте | *Have you ever been to Japan?* | Ты когда-либо был в Японии? |\n| **never** | Отрицательный опыт (глагол в +) | *She has never seen the ocean.* | Она никогда не видела океан. |\n| **since** | С конкретной точки старта | *I have lived here since 2020.* | Я живу здесь с 2020 года. |\n| **for** | На протяжении периода | *They have worked here for 5 years.* | Они работают здесь 5 лет. |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nPresent Perfect — это грамматическое настоящее время в английском языке! Для англичанина важно не то, КОГДА произошло действие, а **КАКОВ ЕГО РЕЗУЛЬТАТ В НАСТОЯЩЕМ**:\n- *I have lost my keys.* = Я потерял ключи в прошлом, и **у меня нет их СЕЙЧАС**.\n- *The road is closed. There has been an accident.* = Авария была в прошлом, но дорога перекрыта **ПРЯМО СЕЙЧАС**.\n\n### 🚢 Разница: have been to vs have gone to\n- *Mark has **gone** to Italy.* — Марк уехал в Италию (он сейчас ТАМ или в пути).\n- *Mark has **been** to Italy.* — Марк побывал в Италии (он съездил туда и уже вернулся назад).\n\n### ⚠️ Частые ошибки (Common Pitfalls)\n1. **Использование с точным временем в прошлом — ЗАПРЕЩЕНО**:\n - *I have seen him yesterday* ❌ → *I saw him yesterday* ✅ (yesterday = Past Simple).\n2. **Yet ставится только в конце** предложения в отрицаниях и вопросах:\n - *Have you finished yet?* / *I haven't eaten yet.*", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Запишите формулу: have / has + V3. Обведите маркеры: just, already, yet, ever, never.\n2. Выпишите контраст: 'gone to' (уехал и еще там) vs 'been to' (съездил и вернулся).\n3. Запишите от руки 3 предложения о вашем реальном опыте:\n - [Результат прямо сейчас] I have just [закончил проект / выпил кофе]...\n - [Жизненный опыт] I have been to [страна/город], but I have never visited [место]...\n - [Длительность со словом for/since] I have studied English for [срок] months.", "contrast_explanation": [ { - "situation_a": "Результат действия имеет прямое значение прямо сейчас (Result NOW)", - "example_a": "I have lost my key. (I don't have it now and can't get in)", - "trans_a": "Я потерял ключ (результат сейчас: ключа нет, не могу войти).", - "situation_b": "Жизненный опыт к настоящему моменту (Life experience: ever/never)", - "example_b": "Have you ever visited Japan?", - "trans_b": "Ты когда-нибудь в своей жизни бывал в Японии?", - "key_difference": "Present Perfect — это форма НАСТОЯЩЕГО времени о результатах прошлого. Если время названо (yesterday) — Present Perfect запрещён!" + "situation_a": "Результат важен сейчас (Present Perfect)", + "example_a": "I have washed the car. It looks brand new.", + "trans_a": "Я помыл машину. Она выглядит как новая (результат прямо перед глазами).", + "situation_b": "Конкретный завершённый момент в прошлом (Past Simple)", + "example_b": "I washed the car two days ago.", + "trans_b": "Я помыл машину два дня назад (есть маркер ago — только Past Simple).", + "key_difference": "Если нет точной даты и важен результат сейчас — Present Perfect; при указании даты — Past Simple." } ], - "journaling_prompt": "Запишите в тетрадь маркеры: just (только что), already (уже), yet (ещё нет в отрицаниях и вопросах). Напишите 2 вещи, которые вы УЖЕ сделали сегодня, и 1 вещь, которую ЕЩЁ НЕ сделали (например: 'I have already drunk coffee, but I have not had lunch yet').", "exercises": [ { - "sentence": "Would you like something to eat? — No thanks, I ___ lunch.", - "target": "have just had", - "clue": "только что пообедал (сыт прямо сейчас)", + "sentence": "I can't open the door because I ___ my keys.", + "target": "have lost", + "clue": "Результат в настоящем: я не могу войти прямо сейчас", "options": [ - "have just had", - "just had", - "had just", - "am having just" + "have lost", + "lost", + "had lost", + "am losing" ], - "explanation": "Маркер 'just' (только что) указывает на свежий результат в настоящем: 'have just had'." + "explanation": "Невозможность открыть дверь прямо сейчас — прямое последствие потери ключей, поэтому используется Present Perfect: 'have lost'." }, { - "sentence": "Don't forget to pay the electric bill. — I have ___ paid it online.", - "target": "already", - "clue": "уже (действие сделано раньше ожидаемого)", + "sentence": "Where is David? — He has ___ to Paris for a business conference and will return next week.", + "target": "gone", + "clue": "Он уехал и ещё находится там (вернулся бы — было бы been)", "options": [ + "gone", + "been", + "went", + "going" + ], + "explanation": "David ещё не вернулся (он всё ещё в Париже), поэтому используется 'has gone to'." + }, + { + "sentence": "Have you ___ eaten raw seafood?", + "target": "ever", + "clue": "Вопрос о жизненном опыте ('когда-либо в жизни')", + "options": [ + "ever", + "never", "already", - "yet", - "still", - "ever" + "yet" ], - "explanation": "В утвердительных предложениях для значения 'уже сделано' ставится маркер 'already'." + "explanation": "В вопросах о личном жизненном опыте используется маркер 'ever' (когда-либо)." }, { - "sentence": "Has the postman delivered the morning letters ___?", + "sentence": "We haven't received the confirmation email ___.", "target": "yet", - "clue": "уже / к этому моменту (в вопросах в конце)", + "clue": "Маркер в конце отрицательного предложения ('ещё не')", "options": [ "yet", "already", "just", "never" ], - "explanation": "В вопросительных предложениях для проверки свершения действия к данному моменту на конце ставится 'yet'." + "explanation": "В отрицательных предложениях слово 'yet' ставится в конец и переводится как 'ещё не'." }, { - "sentence": "She has ___ tried sushi in her entire life.", - "target": "never", - "clue": "никогда (жизненный опыт)", + "sentence": "She has lived in this apartment ___ five years.", + "target": "for", + "clue": "Указание на длительность периода времени (на протяжении 5 лет)", "options": [ - "never", - "ever", - "yet", - "already" + "for", + "since", + "during", + "ago" ], - "explanation": "Для выражения отсутствия жизненного опыта в утвердительной грамматической конструкции используется 'never'." - }, - { - "sentence": "Look! Somebody ___ the window, cold air is coming in.", - "target": "has broken", - "clue": "разбил (результат виден прямо сейчас)", - "options": [ - "has broken", - "broke", - "was breaking", - "breaks" - ], - "explanation": "Результат виден прямо сейчас (идёт холодный воздух), важно последствие, а не когда именно разбили $\rightarrow$ 'has broken'." + "explanation": "Для указания протяжённости периода времени (five years) используется предлог 'for'." } ] }, @@ -578,80 +637,82 @@ "level": "B1-B2", "category": "Present Perfect", "title": "Present Perfect vs Past Simple (I have done vs I did)", - "subtitle": "Главная дилемма: результат в настоящем vs факт в завершённом времени", - "golden_formula": "PRESENT PERFECT: No exact finished time | Connection to NOW\nPAST SIMPLE: Exact finished time (yesterday, in 2018, when, at 5 PM)", + "subtitle": "Главный водораздел английской грамматики: открытое время vs закрытое время", + "golden_formula": "FINISHED TIME (Past Simple): yesterday, last year, in 2020, 2 days ago, when I arrived\nUNFINISHED / OPEN TIME (Present Perfect): today, this week, so far, recently, never, ever\nGOLDEN RULE: If you name WHEN in the past, NEVER use have done!", + "cheatsheet_table": "| Критерий | Present Perfect (I have done) | Past Simple (I did) |\n| :--- | :--- | :--- |\n| **Время** | Не закончено / открыто (*today, this week*) | Полностью закончено (*yesterday, last week*) |\n| **Точная дата** | Запрещена (*NOT I have seen him yesterday*) | Обязательна или подразумевается (*yesterday, in 2019*) |\n| **Вопрос «Когда?»** | НЕЛЬЗЯ спросить *When have you...?* | ТОЛЬКО *When did you buy it?* |\n| **Фокус внимания** | Результат и новость сейчас (*I've won!*) | Детали и обстоятельства (*I won it in Madrid*) |\n| **Период жизни** | Человек жив (*Shakespeare wrote / Rowling has written*) | Историческая эпоха завершена (*Mozart wrote*) |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nЭто самая важная тема английской грамматики. Задайте один проверочный вопрос:\n**«Период времени закрыт или ещё продолжается?»**\n- *I have drunk two cups of coffee today.* (День ещё идёт, могу выпить третью — Present Perfect).\n- *I drank two cups of coffee yesterday.* (Вчерашний день закрыт навсегда — Past Simple).\n\n### ⚠️ Табу носителей языка\nНикогда не начинайте вопрос со слова **WHEN** в Present Perfect! Вопрос «Когда?» требует конкретного момента времени в прошлом, поэтому ВСЕГДА строится в Past Simple:\n- *When have you arrived?* ❌ → *When did you arrive?* ✅.\n- *What time has the train left?* ❌ → *What time did the train leave?* ✅.", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Нарисуйте две коробки: 'ЗАКРЫТОЕ ВРЕМЯ (Past Simple)' с датами (yesterday, 2021, ago) и 'ОТКРЫТОЕ ВРЕМЯ (Present Perfect)' (today, this week, ever).\n2. Запишите жирным красным маркером: 'ВОПРОС С WHEN — ВСЕГДА В PAST SIMPLE!'.\n3. Запишите контрастную пару предложений о сегодняшнем дне и вчерашнем:\n - Today, I have [drink/done: drunk two cups of tea]...\n - Yesterday, I [ate / saw / went]...", "contrast_explanation": [ { - "situation_a": "Present Perfect (Период времени ещё НЕ закончился: today, this week)", - "example_a": "I have drunk two cups of tea this morning. (It is still morning)", - "trans_a": "Я выпил две чашки чая этим утром (утро ещё продолжается).", - "situation_b": "Past Simple (Период времени полностью завершён: yesterday, this morning - said at night)", - "example_b": "I drank two cups of tea this morning. (Said in the afternoon/evening)", - "trans_b": "Я выпил две чашки чая этим утром (сказано днём или вечером, утро прошло).", - "key_difference": "Если есть слова yesterday, last year, ago, in 1999, when I was... — ВСЕГДА используем Past Simple!" + "situation_a": "Период времени ещё не завершился (this morning, до полудня)", + "example_a": "I have seen Tom this morning.", + "trans_a": "Я видел Тома сегодня утром (разговор происходит в 10:30 утра, утро ЕЩЁ ИДЁТ).", + "situation_b": "Период времени завершился (this morning, разговор днём/вечером)", + "example_b": "I saw Tom this morning.", + "trans_b": "Я видел Тома сегодня утром (разговор происходит в 16:00, утро УЖЕ ПРОШЛО).", + "key_difference": "Если временной отрезок ещё продолжается — Present Perfect; если закончился — Past Simple." } ], - "journaling_prompt": "Разделите страницу тетради на две колонки: 'Present Perfect' и 'Past Simple'. Запишите контрастную пару: 1) факт из прошлого с точным годом, 2) факт с результатом на сейчас (например: 'I visited Italy in 2019' vs 'I have visited Italy twice').", "exercises": [ { - "sentence": "Did you know that Shakespeare ___ in 1616?", - "target": "died", - "clue": "умер (точная дата в завершённом прошлом)", - "options": [ - "died", - "has died", - "had died", - "dies" - ], - "explanation": "Точная дата в прошлом ('in 1616') строго запрещает Present Perfect и требует Past Simple: 'died'." - }, - { - "sentence": "I ___ my phone! Can you call my number to find it?", - "target": "have lost", - "clue": "потерял (результат актуален сейчас: ищу телефон)", - "options": [ - "have lost", - "lost", - "was losing", - "lose" - ], - "explanation": "Актуальный результат в настоящем: телефон нужен прямо сейчас, связь с моментом речи $\rightarrow$ 'have lost'." - }, - { - "sentence": "I ___ my phone yesterday, but fortunately found it in my bag.", - "target": "lost", - "clue": "потерял (вчера, период завершён)", - "options": [ - "lost", - "have lost", - "was lost", - "losing" - ], - "explanation": "Слово-маркер 'yesterday' отсекает связь с настоящим и требует Past Simple: 'lost'." - }, - { - "sentence": "___ you ever eaten fresh oysters?", - "target": "Have", - "clue": "вопрос о жизненном опыте к текущему моменту", - "options": [ - "Have", - "Did", - "Were", - "Do" - ], - "explanation": "Вопрос о жизненном опыте к настоящему моменту ('ever') строится в Present Perfect: 'Have you ever eaten...?'" - }, - { - "sentence": "When ___ you buy that stylish leather jacket?", + "sentence": "When ___ you buy your new smartphone?", "target": "did", - "clue": "вопрос со словом When всегда требует Past Simple", + "clue": "Вопрос со словом 'When' требует строго Past Simple", "options": [ "did", "have", - "do", - "were" + "were", + "do" ], - "explanation": "Вопрос со словом 'When' всегда нацелен на конкретный момент в прошлом и строится ТОЛЬКО в Past Simple: 'When did you buy...?'" + "explanation": "Вопрос с 'When' (Когда?) всегда строится в Past Simple со вспомогательным глаголом 'did'." + }, + { + "sentence": "I ___ to the gym three times this week, and it's only Wednesday.", + "target": "have been", + "clue": "Период времени 'this week' ещё не закончился (открытое время)", + "options": [ + "have been", + "went", + "was", + "had been" + ], + "explanation": "Неделя ещё продолжается ('this week'), поэтому используется Present Perfect: 'have been'." + }, + { + "sentence": "William Shakespeare ___ many famous plays and sonnets.", + "target": "wrote", + "clue": "Историческая личность, завершённая эпоха прошлого", + "options": [ + "wrote", + "has written", + "writes", + "was writing" + ], + "explanation": "Шекспир жил в прошлом и больше ничего написать не может (период закрыт), поэтому только Past Simple: 'wrote'." + }, + { + "sentence": "She ___ her first novel in 2018.", + "target": "published", + "clue": "Точная завершённая дата в прошлом ('in 2018')", + "options": [ + "published", + "has published", + "publishes", + "was published" + ], + "explanation": "При наличии точной даты 'in 2018' используется исключительно Past Simple: 'published'." + }, + { + "sentence": "Look! Somebody ___ a glass on the kitchen floor.", + "target": "has broken", + "clue": "Слово 'Look!' привлекает внимание к свежему результату прямо сейчас", + "options": [ + "has broken", + "broke", + "break", + "had broken" + ], + "explanation": "Осколки лежат на полу прямо сейчас (свежий результат), поэтому используется Present Perfect: 'has broken'." } ] }, @@ -660,80 +721,82 @@ "level": "A1-A2", "category": "Past Tenses", "title": "Used to (I used to do)", - "subtitle": "Раньше делал регулярно, но сейчас больше так не делаю", - "golden_formula": "S + used to + V1\nNegative: did not use to + V1 | Question: Did you use to + V1?\n(I used to play tennis a lot, but now I prefer swimming)", + "subtitle": "Привычки и состояния прошлого, которых больше нет в настоящем", + "golden_formula": "S + used to + V1\n(-) S + did not (didn't) use to + V1\n(?) Did + S + use to + V1?\n(I used to play tennis a lot, but now I prefer swimming)", + "cheatsheet_table": "| Тип | Формула | Пример |\n| :--- | :--- | :--- |\n| **Утверждение (+)** | S + used to + V1 | *I used to live in Paris, but now I live in London.* |\n| **Отрицание (-)** | S + didn't use to + V1 | *She didn't use to like coffee.* |\n| **Вопрос (?)** | Did + S + use to + V1? | *Did you use to have long hair?* |\n| **Состояния** | be, have, live, believe | *This building used to be a cinema.* |\n| **НЕ путать с:** | be used to + -ing (привык к) | *I am used to waking up early (я привык).* |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nКонструкция `used to` выражает **прошлые привычки или постоянные состояния, которые сейчас изменились или прекратились**.\n\n### ⚠️ Частые ошибки (Common Pitfalls)\n1. В отрицаниях и вопросах `used` теряет букву -d из-за вспомогательного did: *didn't use to*, *did you use to*.\n2. Для настоящего времени `used to` не существует! Если вы делаете что-то сейчас регулярно, используйте Present Simple с usually (*I usually play tennis*, а не *I use to play*).", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Выпишите формулу 'used to + V1' и подчеркните: 'Только для прошлого, которого БОЛЬШЕ НЕТ'.\n2. Запишите отрицательную форму: 'didn't use to' (без буквы d!).\n3. Составьте от руки 2 контраста из вашей биографии:\n - 'When I was younger, I used to [привычка детства], but now I [что делаете сейчас].'\n - 'I didn't use to like [еда/занятие: olives / waking up early], but now I love it.'", "contrast_explanation": [ { - "situation_a": "Регулярная привычка в прошлом, которой больше нет (Past habit that stopped)", - "example_a": "I used to smoke twenty cigarettes a day, but I quit five years ago.", - "trans_a": "Я раньше выкуривал по 20 сигарет в день, но бросил 5 лет назад.", - "situation_b": "Состояние или факт в прошлом, изменившийся сейчас (Past state that changed)", - "example_b": "There used to be a movie theater here, but it closed down.", - "trans_b": "Здесь раньше был кинотеатр, но он закрылся.", - "key_difference": "Used to существует ТОЛЬКО в прошедшем времени. Для настоящих привычек используется Present Simple с usually." + "situation_a": "Прошлая привычка (Used to)", + "example_a": "I used to smoke 20 cigarettes a day, but I gave up 3 years ago.", + "trans_a": "Я раньше выкуривал по 20 сигарет в день, но бросил 3 года назад.", + "situation_b": "Привычка в настоящем (Present Simple + usually)", + "example_b": "I usually drink green tea in the morning.", + "trans_b": "Я обычно пью зелёный чай по утрам (настоящее время, used to применять нельзя!).", + "key_difference": "Used to существует ТОЛЬКО для прошлого. Для настоящего времени используется usually + V1." } ], - "journaling_prompt": "Запишите формулу в тетрадь. Напишите 2 предложения о том, чем вы регулярно занимались в детстве или юности, но больше не занимаетесь (например: 'I used to play video games all night, but now I sleep early').", "exercises": [ { - "sentence": "She ___ long curly hair when she was a teenager.", - "target": "used to have", - "clue": "раньше имела (сейчас причёска другая)", + "sentence": "My grandfather ___ to work by bicycle, but now he takes the bus.", + "target": "used to go", + "clue": "Прошлая привычка, которая прекратилась ('but now he takes')", "options": [ - "used to have", - "uses to have", - "is used to have", - "use to have" + "used to go", + "uses to go", + "was going", + "is used to go" ], - "explanation": "Конструкция 'used to have' выражает постоянное состояние в прошлом, которое изменилось в настоящем." + "explanation": "Для описания привычки в прошлом, сменившейся в настоящем, используется конструкция 'used to + V1': 'used to go'." }, { - "sentence": "We ___ live in a small village before moving to the capital.", - "target": "used to", - "clue": "раньше жили (прошлое состояние)", + "sentence": "We ___ use to have a dishwasher when I was growing up.", + "target": "didn't", + "clue": "Отрицательная форма конструкции 'use to' в прошлом", "options": [ - "used to", - "use to", - "are used to", - "used" + "didn't", + "don't", + "weren't", + "haven't" ], - "explanation": "Для описания прежнего места жительства, которое сменилось, используется 'used to'." + "explanation": "Отрицание строится через 'didn't use to': 'We didn't use to have'." }, { - "sentence": "Did you ___ play the piano when you were younger?", - "target": "use to", - "clue": "форма инфинитива после вспомогательного did", + "sentence": "Did you ___ to live in Montreal before moving here?", + "target": "use", + "clue": "Вопрос с Did: буква -d у слова used исчезает", "options": [ - "use to", - "used to", - "using to", - "used" + "use", + "used", + "using", + "uses" ], - "explanation": "После вспомогательного глагола 'Did' в вопросительном предложении пишется форма без окончания -d: 'Did you use to...?'" + "explanation": "После вспомогательного 'Did' форма глагола пишется без -d: 'Did you use to live...?'." }, { - "sentence": "I didn't ___ like spicy Indian food, but now I love it.", - "target": "use to", - "clue": "раньше не любил (отрицание после didn't)", + "sentence": "This street ___ to be much quieter before the shopping mall opened.", + "target": "used", + "clue": "Прошлое состояние (улица была тише)", "options": [ - "use to", - "used to", - "uses to", - "using" + "used", + "was used", + "use", + "is using" ], - "explanation": "После 'didn't' используется начальная форма 'use to': 'didn't use to like'." + "explanation": "Утверждение о прошлом состоянии улицы: 'used to be quieter'." }, { - "sentence": "He ___ play football every Sunday, but now he is too busy.", - "target": "used to", - "clue": "раньше играл (привычка прекратилась)", + "sentence": "Now I live in a quiet village, but I ___ in a crowded capital city.", + "target": "used to live", + "clue": "Контраст: сейчас в деревне, а раньше жил в столице", "options": [ - "used to", - "uses to", - "was used to", - "is used to" + "used to live", + "use to live", + "am living", + "was lived" ], - "explanation": "Регулярная прошлая привычка, уступившая место занятости в настоящем $\rightarrow$ 'used to'." + "explanation": "Контраст настоящего и прошлого: 'used to live in a crowded capital city'." } ] }, @@ -742,80 +805,82 @@ "level": "B1-B2", "category": "Future", "title": "Future: Will vs Going to vs Present Continuous", - "subtitle": "Спонтанное решение (Will) vs Намерение (Going to) vs 100% договоренность (Present Continuous)", - "golden_formula": "WILL: Spontaneous decision NOW ('I'll help you')\nGOING TO: Prior intention / Evidence ('I am going to buy a car')\nPRESENT CONT: Fixed arrangement with date/people ('I am flying to Rome on Friday')", + "subtitle": "Три главных будущих времени: спонтанное решение, намерение и железобетонная договорённость", + "golden_formula": "1. WILL + V1: Spontaneous decision NOW ('I will answer the door') / Prediction\n2. BE GOING TO + V1: Prior intention / Obvious evidence ('Look at those black clouds, it is going to rain')\n3. PRESENT CONTINUOUS: Fixed arrangement with date & other people ('I am flying to Paris tomorrow')", + "cheatsheet_table": "| Конструкция | Значение | Триггер выбора | Пример |\n| :--- | :--- | :--- | :--- |\n| **WILL + V1** | Спонтанное решение в секунду речи | Решил прямо сейчас, обещание, предложение помощи | *The phone is ringing. I'll get it!* |\n| **BE GOING TO + V1** | Заранее задуманное намерение | Решил ДО разговора, есть очевидные улики | *I am going to buy a new car next month.* |\n| **BE GOING TO (улики)** | Неизбежный прогноз по фактам | Вижу глазами прямо сейчас | *Look at those clouds! It's going to rain.* |\n| **PRESENT CONTINUOUS** | Железобетонная договоренность | Куплены билеты, назначена встреча с людьми | *I'm meeting Alice at 7 PM at the cafe.* |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nВ английском языке будущее время выбирается строго по степени готовности плана:\n1. **Внезапная мысль сейчас**: *«I'll carry that heavy bag for you»* (никто не планировал заранее).\n2. **Личное намерение**: *«I am going to sell my old bike»* (я уже решил для себя, но покупателя пока нет).\n3. **Фиксированная договоренность**: *«I am having dinner with Sarah tonight»* (мы с Сарой уже договорились о времени и столике).", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Нарисуйте 3 колонки: 'Will (в эту секунду)', 'Going to (задумал заранее)', 'Present Continuous (договорился с людьми/билеты)'.\n2. Составьте от руки 3 предложения о вашем будущем:\n - [Спонтанное решение/обещание] I will call you as soon as [действие]...\n - [План-намерение] This weekend, I am going to [отдохнуть / убраться]...\n - [Договоренность на этой неделе] On Friday, I am meeting [имя/коллеги] at [время]...", "contrast_explanation": [ { - "situation_a": "Will (Спонтанное решение в момент речи / обещание / прогноз)", - "example_a": "The phone is ringing. — I'll answer it!", - "trans_a": "Телефон звонит. — Я отвечу (решил сию секунду)!", - "situation_b": "Going to (Заранее обдуманное намерение / очевидность по фактам)", - "example_b": "Look at those black clouds! It is going to rain.", - "trans_b": "Посмотри на эти чёрные тучи! Сейчас пойдёт дождь (налицо очевидные признаки).", - "key_difference": "Present Continuous для будущего требует подтверждённой договорённости: куплены билеты, назначена встреча в календаре." + "situation_a": "Спонтанное решение в момент речи (Will)", + "example_a": "We don't have any milk. — Really? I'll go and get some.", + "trans_a": "У нас нет молока. — Правда? Я пойду куплю (узнал только что и решил сию секунду).", + "situation_b": "План был продуман заранее (Going to)", + "example_b": "We don't have any milk. — I know. I am going to buy some on my way home.", + "trans_b": "У нас нет молока. — Я знаю. Я как раз собираюсь купить его по пути домой.", + "key_difference": "Если решение принято только что в разговоре — Will; если о проблеме знали заранее — Going to." } ], - "journaling_prompt": "Нарисуйте 3 колонки: Will (спонтанно), Going to (намерение), Pres. Cont. (куплены билеты/запланировано). Напишите по 1 предложению в каждую колонку о своих реальных планах.", "exercises": [ { - "sentence": "Have you decided what to drink? — Yes, I ___ a glass of orange juice, please.", - "target": "will have", - "clue": "возьму (спонтанное решение в момент заказа)", + "sentence": "Have you decided what to do tonight? — Yes, I ___ dinner with my boss at 8 PM.", + "target": "am having", + "clue": "Зафиксированная договорённость со временем и конкретным человеком", "options": [ - "will have", "am having", - "am going to have", - "have" + "will have", + "have", + "going to have" ], - "explanation": "Заказ в кафе или спонтанное решение в момент речи выражается через 'will': 'I'll have...'." + "explanation": "Назначенное время (at 8 PM) и договорённость с другим человеком выражаются через Present Continuous: 'am having'." }, { - "sentence": "Why are you turning on the television? — I ___ watch the evening news.", + "sentence": "That box looks very heavy! I ___ you carry it upstairs.", + "target": "will help", + "clue": "Спонтанное предложение помощи в момент речи", + "options": [ + "will help", + "am helping", + "help", + "going to help" + ], + "explanation": "Спонтанное решение помочь, принятое в секунду речи: 'I will help you'." + }, + { + "sentence": "Look at that cyclist! He is not watching the road and he ___ crash.", + "target": "is going to", + "clue": "Прогноз на основе очевидных физических улик прямо перед глазами", + "options": [ + "is going to", + "will", + "is", + "shall" + ], + "explanation": "Прогноз на основе явных внешних улик прямо сейчас строится через 'be going to': 'is going to crash'." + }, + { + "sentence": "I have saved enough money. Next spring I ___ learn how to pilot a drone.", "target": "am going to", - "clue": "собираюсь (намерение было сформировано заранее)", + "clue": "Личное заранее обдуманное намерение", "options": [ "am going to", "will", "am", "would" ], - "explanation": "Человек включил телевизор, потому что уже заранее намеревался посмотреть новости: 'am going to watch'." + "explanation": "Заранее продуманное решение и накопленные деньги указывают на намерение: 'am going to learn'." }, { - "sentence": "I can't meet you on Friday afternoon because I ___ to the dentist at 3 PM.", - "target": "am going", - "clue": "иду (записан на конкретное время в расписании)", + "sentence": "I promise I ___ tell anyone your secret.", + "target": "won't", + "clue": "Обещание (Promise) выражается через will / won't", "options": [ - "am going", - "will go", - "go", - "shall go" + "won't", + "am not going to", + "don't", + "haven't" ], - "explanation": "Договорённость с точным временем в расписании передаётся через Present Continuous: 'I am going to the dentist'." - }, - { - "sentence": "Watch out! That unstable stack of boxes ___ fall!", - "target": "is going to", - "clue": "сейчас упадёт (очевидные физические признаки)", - "options": [ - "is going to", - "will", - "is falling", - "shall" - ], - "explanation": "Прогноз на основе видимых прямо сейчас признаков (коробки уже качаются) выражается через 'is going to'." - }, - { - "sentence": "Don't worry about carrying that heavy bag alone. I ___ help you.", - "target": "will", - "clue": "помогу (спонтанное предложение помощи)", - "options": [ - "will", - "am going to", - "am helping", - "help" - ], - "explanation": "Предложение помощи в момент разговора выражается формой 'I will help you'." + "explanation": "Обещания (I promise...) традиционно строятся со словом will / won't: 'I won't tell anyone'." } ] }, @@ -824,80 +889,82 @@ "level": "B1-B2", "category": "Modals", "title": "Modal Verbs: Must, Have to, Should", - "subtitle": "Внутреннее решение (Must) vs Внешнее правило (Have to) vs Совет (Should)", - "golden_formula": "MUST: Speaker's personal feeling ('I must call my mom')\nHAVE TO: External law / rule / obligation ('I have to wear a helmet at work')\nSHOULD: Good idea / friendly advice ('You should sleep more')", + "subtitle": "Обязанность, закон, совет и критическая разница между Mustn't и Don't have to", + "golden_formula": "MUST: Personal feeling of obligation ('I must call my mom')\nHAVE TO: External rule, law or necessity ('I have to wear a safety helmet')\nSHOULD: Friendly recommendation / good idea ('You should get some sleep')\nCRITICAL CONTRAST:\nMustn't = FORBIDDEN! Do not do it! (Ты не должен / Запрещено!)\nDon't have to = NO NEED. You can do it if you want (Не обязательно / Нет нужды)", + "cheatsheet_table": "| Модальный глагол | Значение | Пример |\n| :--- | :--- | :--- |\n| **MUST** | Личное внутреннее убеждение говорящего | *I must finish this book today.* |\n| **HAVE TO** | Внешний закон, приказ руководства | *Employees have to arrive by 9 AM.* |\n| **SHOULD** | Совет, рекомендация | *You should see a doctor about that cough.* |\n| **MUSTN'T** | ⛔ КАТЕГОРИЧЕСКИЙ ЗАПРЕТ | *You mustn't touch this wire. It's live!* |\n| **DON'T HAVE TO** | 🟢 НЕТ НЕОБХОДИМОСТИ (можно, но не нужно) | *Tomorrow is Sunday. We don't have to get up early.* |\n| **Прошедшее время** | В прошлом must превращается в HAD TO | *Yesterday I had to stay late at work.* |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nМодальные глаголы показывают отношение говорящего к действию. Главная опасность здесь кроется в отрицаниях:\n- `You mustn't do that!` = **ЭТО ЗАПРЕЩЕНО!** (Это опасно или незаконно).\n- `You don't have to do that.` = **ЭТО НЕОБЯЗАТЕЛЬНО.** (Хочешь — делай, не хочешь — не делай, принуждения нет).\n\n### ⏱️ Прошедшее время\nУ глагола `must` нет формы прошедшего времени! Если нужно сказать «я должен был сделать это вчера», используется форма **HAD TO**:\n- *Yesterday I had to walk home because my car broke down.*", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Нарисуйте знак 'STOP' рядом со словом 'MUSTN'T (ЗАПРЕЩЕНО)' и зеленую галочку рядом с 'DON'T HAVE TO (НЕ ОБЯЗАТЕЛЬНО)'.\n2. Запишите правило: 'В прошедшем времени вместо must ВСЕГДА используется had to'.\n3. Запишите от руки 3 правила вашей рабочей жизни:\n - [Внешнее требование] At work, I have to [приходить вовремя / носить пропуск]...\n - [Что необязательно] At the weekend, I don't have to [set an alarm / wear a suit]...\n - [Совет себе] I should [drink more water / go to bed earlier]...", "contrast_explanation": [ { - "situation_a": "Must (Личное внутреннее убеждение говорящего)", - "example_a": "I must get up earlier tomorrow; I want to do morning exercises.", - "trans_a": "Я должен встать пораньше завтра; я сам этого хочу (моё решение).", - "situation_b": "Have to (Внешнее правило, закон, обстоятельства)", - "example_b": "In the UK, drivers have to drive on the left side of the road.", - "trans_b": "В Великобритании водители обязаны ехать по левой стороне (закон государства).", - "key_difference": "Mustn't = СТРОГО ЗАПРЕЩЕНО. Don't have to = НЕ ОБЯЗАТЕЛЬНО (но можно, если хочешь)." + "situation_a": "Категорический запрет (Mustn't)", + "example_a": "You mustn't park here. It is an emergency exit.", + "trans_a": "Здесь нельзя парковаться. Это пожарный выход (строжайший запрет).", + "situation_b": "Отсутствие необходимости (Don't have to)", + "example_b": "Parking is free today. You don't have to pay.", + "trans_b": "Парковка сегодня бесплатная. Тебе не обязательно платить.", + "key_difference": "Mustn't означает запрет; Don't have to означает отсутствие необходимости." } ], - "journaling_prompt": "Запишите в тетрадь контраст: Mustn't (запрет) vs Don't have to (нет необходимости). Напишите 1 вещь, которую вы обязаны делать по работе (have to), и 1 совет самому себе (should).", "exercises": [ { - "sentence": "You ___ touch that high-voltage electrical cable! It is lethal.", - "target": "must not", - "clue": "нельзя, строго запрещено", + "sentence": "You ___ tell the password to anyone under any circumstances. It's confidential.", + "target": "mustn't", + "clue": "Категорический запрет на раскрытие пароля", "options": [ - "must not", - "do not have to", - "should", - "might not" + "mustn't", + "don't have to", + "shouldn't", + "needn't" ], - "explanation": "Категорический запрет опасного действия выражается модальным глаголом 'must not' ('mustn't')." + "explanation": "Строгий запрет разглашать конфиденциальный пароль: 'mustn't tell'." }, { - "sentence": "Tomorrow is Sunday, so I ___ wake up early for work.", - "target": "do not have to", - "clue": "нет необходимости, не обязан", + "sentence": "The museum admission is free on Thursdays, so you ___ pay to enter.", + "target": "don't have to", + "clue": "Вход бесплатный, поэтому платить нет необходимости", "options": [ - "do not have to", - "must not", - "should", - "cannot" + "don't have to", + "mustn't", + "can't", + "shouldn't" ], - "explanation": "Отсутствие необходимости ('не нужно вставать, но можно, если захочешь') передаётся через 'do not have to'." + "explanation": "Поскольку вход бесплатный, платить не требуется (нет необходимости): 'don't have to pay'." }, { - "sentence": "You have been coughing for a week; you ___ see a doctor.", - "target": "should", - "clue": "следует (дружеский совет)", + "sentence": "Yesterday my computer crashed, so I ___ re-type the whole document.", + "target": "had to", + "clue": "Прошедшее время от глагола обязательства ('вчера пришлось')", "options": [ - "should", - "have to", + "had to", "must", - "shall" + "must have", + "have to" ], - "explanation": "Рекомендация или разумный совет выражается через 'should'." + "explanation": "У 'must' нет формы прошедшего времени; для прошедшего времени используется 'had to': 'I had to re-type'." }, { - "sentence": "All passengers ___ show a valid boarding pass before boarding.", + "sentence": "You look completely exhausted. I think you ___ take a couple of days off.", + "target": "should", + "clue": "Дружеский совет и рекомендация ('тебе следует')", + "options": [ + "should", + "must", + "have to", + "had to" + ], + "explanation": "Совет и рекомендация выражаются через модальный глагол 'should': 'you should take a couple of days off'." + }, + { + "sentence": "In most countries, passengers ___ wear seatbelts in the car by law.", "target": "have to", - "clue": "обязаны (официальное правило авиакомпании)", + "clue": "Внешнее предписание закона государства", "options": [ "have to", "should", "might", "would" ], - "explanation": "Официальные правила, законы и инструкции третьей стороны передаются через 'have to'." - }, - { - "sentence": "I ___ remember to send birthday flowers to my grandmother.", - "target": "must", - "clue": "должен (личное внутреннее побуждение)", - "options": [ - "must", - "may", - "can", - "ought" - ], - "explanation": "Внутренний моральный долг и личное решение говорящего выражаются через 'must'." + "explanation": "Обязательство, наложенное законом государства, выражается через 'have to': 'passengers have to wear seatbelts'." } ] }, @@ -906,80 +973,82 @@ "level": "B1-B2", "category": "Conditionals", "title": "First vs Second Conditional (If I do vs If I did)", - "subtitle": "Реальное условие на будущее vs Воображаемая / маловероятная ситуация", - "golden_formula": "1st COND (Real Future): If + Present Simple, will + V1\n(If it rains tomorrow, we will stay home)\n2nd COND (Unreal / Imaginary): If + Past Simple, would + V1\n(If I had a million dollars, I would travel the world)", + "subtitle": "Реальное будущее против воображаемых фантазий и конструкция If I were you", + "golden_formula": "1st CONDITIONAL (Real Future):\nIf + Present Simple, will + V1\n(If it rains tomorrow, we will stay at home)\n\n2nd CONDITIONAL (Unreal / Imaginary Present or Future):\nIf + Past Simple, would + V1\n(If I had a million dollars, I would travel around the world)\nNOTE: If I were you, I would... (быть на твоем месте)", + "cheatsheet_table": "| Тип условия | Часть с IF (Условие) | Главная часть (Результат) | Реальность ситуации |\n| :--- | :--- | :--- | :--- |\n| **First (1-й)** | **If + Present Simple** | **will + V1** | Реальная возможность в будущем (вероятность 70-90%) |\n| *Пример 1-го* | *If I pass the exam...* | *...I will celebrate with friends.* | Вполне реально сдать экзамен. |\n| **Second (2-й)** | **If + Past Simple** | **would + V1** | Воображаемая / маловероятная фантазия (вероятность 1-5%) |\n| *Пример 2-го* | *If I won the lottery...* | *...I would buy an island.* | Мечты и фантазии. |\n| **Совет** | *If I were you...* | *...I would accept the offer.* | «На твоём месте я бы...» |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nВся разница — в **степени веры говорящего в реальность события**:\n- *If I find her number, I will call her.* (У меня есть надежда найти её записную книжку — реальный 1st Cond).\n- *If I found a wallet in the street, I would take it to the police.* (Я прямо сейчас фантазирую о гипотетической ситуации — 2nd Cond).\n\n### ⚠️ Табу условных предложений\n**НИКОГДА не ставьте will или would сразу после слова IF**:\n- *If it will rain tomorrow...* ❌ → *If it rains tomorrow...* ✅.\n- *If I would have money...* ❌ → *If I had money...* ✅.\n\n### 🎩 Исключение: Were вместо Was\nВ формальном английском и для советов во 2-м условном глагол to be для всех лиц принимает форму `were`:\n- *If I were you, I would take that job.* (На твоём месте я бы согласился на эту работу).", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Запишите формулы: 1st (If + V1, will + V1) и 2nd (If + V2, would + V1).\n2. Обведите красным маркером: 'ПОСЛЕ IF СЛОВА WILL И WOULD НЕ СТАВЯТСЯ!'.\n3. Составьте от руки два предложения:\n - [Реальный план на завтра] If the weather is good tomorrow, I will [прогуляться / поехать за город]...\n - [Воображаемая мечта] If I had [много денег / свободного времени], I would [купить дом / объехать мир]...", "contrast_explanation": [ { - "situation_a": "First Conditional (Вполне реальная ситуация в будущем)", - "example_a": "If you study hard, you will pass the exam easily.", - "trans_a": "Если ты будешь усердно учиться, ты легко сдашь экзамен (реальная вероятность).", - "situation_b": "Second Conditional (Воображаемая или маловероятная ситуация в настоящем/будущем)", - "example_b": "If I knew his phone number, I would call him right now.", - "trans_b": "Если бы я знал его номер (но я не знаю!), я бы позвонил ему прямо сейчас.", - "key_difference": "В части с IF никогда не ставится will или would! (Никаких 'If I will' или 'If I would')." + "situation_a": "Реальное будущее (1st Conditional)", + "example_a": "If you study hard, you will pass the exam.", + "trans_a": "Если ты будешь усердно учиться, ты сдашь экзамен (реальный прогноз на будущее).", + "situation_b": "Нереальная фантазия (2nd Conditional)", + "example_b": "If I knew Spanish, I would move to Barcelona.", + "trans_b": "Если бы я знал испанский, я бы переехал в Барселону (но я его не знаю прямо сейчас).", + "key_difference": "1st = реальное будущее; 2nd = гипотетическое предположение, противоположное фактам." } ], - "journaling_prompt": "Запишите формулы 1st и 2nd Conditionals цветными маркерами. Напишите 1 реальное условие на завтра (If...) и 1 мечту/воображаемую ситуацию (If I had / If I were...).", "exercises": [ { - "sentence": "If the weather ___ sunny tomorrow, we will go for a picnic.", + "sentence": "If the flight ___ delayed, we will call you immediately.", "target": "is", - "clue": "будет (в части If ставится Present Simple)", + "clue": "В части с 'If' в 1-м условном используется Present Simple (НЕ will!)", "options": [ "is", "will be", - "was", - "would be" + "would be", + "was" ], - "explanation": "В 1st Conditional в придаточном с 'if' используется Present Simple ('is'), а не 'will be'." + "explanation": "В условной придаточной части 1-го типа (после 'If') используется Present Simple: 'If the flight is delayed'." }, { - "sentence": "If I ___ more free time, I would learn how to play guitar.", - "target": "had", - "clue": "было бы (нереальное условие в настоящем)", - "options": [ - "had", - "have", - "will have", - "would have" - ], - "explanation": "Во 2nd Conditional для воображаемой ситуации в части 'if' ставится Past Simple: 'had'." - }, - { - "sentence": "What ___ you do if you won the lottery tomorrow?", + "sentence": "If I had enough free time, I ___ learn how to play the piano.", "target": "would", - "clue": "сделал бы (гипотетический результат)", + "clue": "В главной части 2-го типа условных используется would + V1", "options": [ "would", "will", - "did", - "can" + "can", + "am" ], - "explanation": "Маловероятная гипотетическая ситуация (2nd Conditional: 'if you won') требует в главной части 'would you do'." + "explanation": "Придаточная часть с 'If I had' указывает на 2-й условный тип, в главной части требуется 'would'." }, { - "sentence": "If you don't leave now, you ___ miss your flight.", + "sentence": "If I ___ you, I wouldn't invest in that risky startup.", + "target": "were", + "clue": "Устойчивая конструкция совета: 'If I were you'", + "options": [ + "were", + "am", + "was", + "would be" + ], + "explanation": "Для выражения совета 'На твоём месте' традиционно используется форма 'If I were you'." + }, + { + "sentence": "If you don't wear a warm coat today, you ___ catch a cold.", "target": "will", - "clue": "опоздаешь (реальное последствие)", + "clue": "Реальное предупреждение о последствиях в будущем (1st Conditional)", "options": [ "will", "would", "did", "are" ], - "explanation": "Реальное предупреждение на ближайшее будущее (1st Conditional): 'If you don't leave ... you will miss'." + "explanation": "Реальное последствие в будущем выражается через 'will + V1': 'you will catch a cold'." }, { - "sentence": "If I ___ in your position, I would accept the job offer.", - "target": "were", - "clue": "был бы (традиционная сослагательная форма were)", + "sentence": "What ___ you do if you found a wallet on the street with $500 inside?", + "target": "would", + "clue": "Вопрос о гипотетической ситуации (If you found...)", "options": [ - "were", - "am", - "will be", - "would be" + "would", + "will", + "did", + "do" ], - "explanation": "В условных предложениях 2-го типа для всех лиц часто используется форма 'were' ('If I were you...')." + "explanation": "Воображаемая гипотетическая ситуация (If you found = 2nd Conditional) требует в вопросе 'would you do?'." } ] }, @@ -988,80 +1057,82 @@ "level": "B1-B2", "category": "Passive Voice", "title": "Passive Voice (It is done / It was done)", - "subtitle": "Пассивный залог: фокус на объекте или результате, а не на исполнителе", - "golden_formula": "Present Passive: am / is / are + V3 (Past Participle)\nPast Passive: was / were + V3\nBy + agent: used only when the doer is important ('painted by Da Vinci')", + "subtitle": "Когда результат важнее исполнителя: пассивные конструкции и предлог By", + "golden_formula": "GENERAL FORMULA: S + BE (в нужном времени) + V3 (Past Participle)\nPresent Simple Passive: am / is / are + V3 (The office is cleaned every day)\nPast Simple Passive: was / were + V3 (The bridge was built in 1905)\nFuture Simple Passive: will be + V3 (The report will be sent tomorrow)\nPresent Continuous Passive: is / are being + V3 (My car is being repaired)\nBY + AGENT: используется только если важно указать автора ('written by Shakespeare')", + "cheatsheet_table": "| Время | Активный залог (Active) | Пассивный залог (Passive) |\n| :--- | :--- | :--- |\n| **Present Simple** | *Somebody cleans the room.* | *The room **is cleaned** every day.* |\n| **Past Simple** | *Somebody built the bridge.* | *The bridge **was built** in 2010.* |\n| **Present Continuous** | *They are repairing the road.* | *The road **is being repaired** right now.* |\n| **Present Perfect** | *Someone has stolen my bike.* | *My bike **has been stolen**.* |\n| **Future Simple** | *We will deliver the package.* | *The package **will be delivered** tomorrow.* |\n| **Модальные глаголы** | *You must sign the contract.* | *The contract **must be signed**.* |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nПассивный залог применяется в трёх ключевых ситуациях:\n1. **Исполнитель неизвестен**: *My bicycle has been stolen.* (Кто украл — мы не знаем).\n2. **Исполнитель очевиден или не важен**: *The criminal was arrested.* (Очевидно, что полицией).\n3. **Фокус на объекте или событии**: в новостях, научных статьях, инструкциях и IT-системах (*A new database was created*).\n\n### ⚙️ Инструмент: Предлог By vs With\n- `By` указывает на одушевлённого создателя/исполнителя: *The portrait was painted **by** Picasso*.\n- `With` указывает на инструмент или материал: *The envelope was opened **with** a knife*.", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Запишите формулу пассива: 'BE + V3'.\n2. Запишите две самые частые формы: 'is/are done' (настоящее) и 'was/were done' (прошедшее).\n3. Составьте от руки 3 примера из сферы технологий или быта:\n - This app was developed in [год/страна]...\n - Emails are sent every day to [клиенты/коллеги]...\n - The project will be finished next [месяц/неделя]...", "contrast_explanation": [ { - "situation_a": "Active Voice (Фокус на том, КТО совершает действие)", + "situation_a": "Активный залог (фокус на исполнителе)", "example_a": "Alexander Bell invented the telephone in 1876.", - "trans_a": "Александр Белл изобрёл телефон в 1876 году.", - "situation_b": "Passive Voice (Фокус на том, ЧТО произошло с объектом)", - "example_b": "The telephone was invented in 1876.", - "trans_b": "Телефон был изобретён в 1876 году (важен телефон и дата, а не персона).", - "key_difference": "Пассив используется, когда исполнитель неизвестен, очевиден или не имеет решающего значения." + "trans_a": "Александр Белл изобрёл телефон в 1876 году (Белл — главный герой предложения).", + "situation_b": "Пассивный залог (фокус на изобретении)", + "example_b": "The telephone was invented in 1876 by Alexander Bell.", + "trans_b": "Телефон был изобретён в 1876 году Александром Беллом (телефон — в центре внимания).", + "key_difference": "В пассиве объект действия встаёт на место подлежащего, а исполнитель уходит на второй план." } ], - "journaling_prompt": "Запишите формулу пассивного залога: be + V3. Напишите от руки 2 примера из сферы технологий (например: 'Python was created in 1991', 'My data is backed up daily').", "exercises": [ { - "sentence": "Millions of emails ___ sent around the globe every single minute.", - "target": "are", - "clue": "отправляются (Present Passive с множественным числом)", + "sentence": "This ancient castle ___ by thousands of tourists every summer.", + "target": "is visited", + "clue": "Present Simple пассив: замок посещается регулярно каждое лето", "options": [ - "are", - "is", - "were", - "have" + "is visited", + "was visited", + "visits", + "is visiting" ], - "explanation": "Подлежащее 'Millions of emails' во множественном числе в настоящем времени требует: 'are sent'." + "explanation": "Регулярное действие в настоящем ('every summer') в пассивном залоге требует 'is/are + V3': 'is visited'." }, { - "sentence": "This ancient castle ___ built in the fourteenth century.", - "target": "was", - "clue": "был построен (Past Passive в единственном числе)", + "sentence": "The novel '1984' ___ by George Orwell in 1949.", + "target": "was written", + "clue": "Past Simple пассив с точной датой в прошлом", "options": [ - "was", - "is", - "were", - "has" + "was written", + "is written", + "wrote", + "has written" ], - "explanation": "Замок один ('castle'), постройка завершена в XIV веке $\rightarrow$ 'was built'." + "explanation": "Конкретная дата в прошлом ('in 1949') и пассивное действие требуют Past Simple Passive: 'was written'." }, { - "sentence": "The Mona Lisa was painted ___ Leonardo da Vinci.", - "target": "by", - "clue": "предлог исполнителя действия в пассиве", + "sentence": "Please take another seat. This table ___ reserved for a private party.", + "target": "is", + "clue": "Стол зарезервирован прямо сейчас (Present Simple Passive)", "options": [ - "by", - "with", - "from", - "of" - ], - "explanation": "Исполнитель действия в пассивном залоге вводится предлогом 'by'." - }, - { - "sentence": "The new operating system ___ tested by engineers right now.", - "target": "is being", - "clue": "тестируется прямо сейчас (Present Continuous Passive)", - "options": [ - "is being", "is", "was", - "has been" + "are", + "were" ], - "explanation": "Пассивное действие в процессе прямо в момент речи требует формы 'is being tested'." + "explanation": "Для 'This table' (it) форма пассивного залога в настоящем времени: 'is reserved'." }, { - "sentence": "All rooms in the hotel ___ cleaned thoroughly every morning.", - "target": "are", - "clue": "убираются (регулярный Present Passive)", + "sentence": "All flight tickets ___ electronically via email tomorrow morning.", + "target": "will be sent", + "clue": "Future Simple Passive: билеты будут отправлены завтра", "options": [ - "are", - "is", - "were", - "being" + "will be sent", + "will send", + "are sent", + "were sent" ], - "explanation": "Регулярное повторяющееся пассивное действие во множественном числе ('rooms') $\rightarrow$ 'are cleaned'." + "explanation": "Будущее действие в пассивном залоге ('tomorrow morning') строится через 'will be + V3': 'will be sent'." + }, + { + "sentence": "The software bug ___ by the engineering team right now.", + "target": "is being fixed", + "clue": "Present Continuous Passive: процесс исправления идёт прямо в эту минуту", + "options": [ + "is being fixed", + "is fixing", + "was fixed", + "fixes" + ], + "explanation": "Процесс в настоящем времени ('right now') в пассиве строится через 'is being + V3': 'is being fixed'." } ] }, @@ -1070,80 +1141,82 @@ "level": "A1-A2", "category": "Articles", "title": "Articles: A/An vs The vs Zero Article", - "subtitle": "Один из многих (A/An) vs Конкретный / единственный (The) vs Обобщение (Zero)", - "golden_formula": "A / AN: Any one non-specific item ('Can I have an apple?')\nTHE: Specific item known to listener / Unique ('Look at the Moon')\nZERO (No article): Plurals & Uncountable in general ('Cats love milk')", + "subtitle": "Определённость, первое упоминание, уникальные объекты и абстрактные понятия", + "golden_formula": "A / AN: One of many / Unspecified singular countable ('I bought a book')\nTHE: Specific item known to listener / Unique object ('The book was interesting' / 'The Sun')\nZERO ARTICLE (Ø): Plurals & Uncountables in general ('I love dogs' / 'Music is art')", + "cheatsheet_table": "| Артикль | Когда применять | Примеры |\n| :--- | :--- | :--- |\n| **A / AN** | Исчисляемое в ед. ч., первое упоминание, профессия | *I have **a** dog. She is **an** architect.* |\n| **THE** | Второе упоминание, слушатель знает о чём речь | *I bought a laptop. **The** laptop is fast.* |\n| **THE (уникальность)** | Единственный в мире объект | *the Sun, the Moon, the Internet, the sky* |\n| **THE (география)** | Реки, моря, океаны, группы островов/штатов | *the Atlantic, the Thames, the USA, the UK* |\n| **ZERO (Ø)** | Множественное число и неисчисляемые ВООБЩЕ | *Cats love milk. Gold is expensive.* |\n| **ZERO (география)** | Города, страны (в ед. ч.), улицы, континенты | *London, France, Oxford Street, Europe* |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\nВся система артиклей строится на простом вопросе:\n**«Понимает ли собеседник, о каком КОНКРЕТНО объекте я говорю?»**\n- *Pass me a pen.* = Дай мне любую ручку, мне всё равно какую.\n- *Pass me the pen.* = Дай мне вон ту конкретную ручку, которая лежит перед тобой.\n\n### ⚠️ Частые ошибки (Common Pitfalls)\n1. Нельзя ставить `a/an` перед множественным числом или неисчисляемыми: *an advice* ❌ → *advice / a piece of advice* ✅.\n2. Обобщения строятся с нулевым артиклем: *I love the dogs* (люблю конкретно этих трёх собак во дворе) vs *I love dogs* (люблю собак как биологический вид).", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Нарисуйте 3 колонки: 'A/An (один любой из многих)', 'The (тот самый конкретный / уникальный)', 'Ø (все в целом)'.\n2. Запишите связку из двух предложений:\n - 'I ordered a coffee and a croissant. The coffee was hot and the croissant was fresh.'\n3. Запишите от руки 2 примера об уникальных вещах: 'The Sun rises in the east' и 'I use the Internet every day'.", "contrast_explanation": [ { - "situation_a": "A/An (Первое упоминание / любой один представитель класса)", - "example_a": "I bought a jacket yesterday.", - "trans_a": "Я купил какую-то куртку вчера (собеседник слышит о ней впервые).", - "situation_b": "The (Конкретный предмет, уже известный обоим собеседникам)", - "example_b": "The jacket fits me perfectly.", - "trans_b": "Эта (та самая) куртка сидит на мне идеально.", - "key_difference": "Не используйте артикль со множественным числом или неисчисляемыми существительными, когда говорите о явлении вообще!" + "situation_a": "Первое упоминание объекта (A / An)", + "example_a": "Yesterday I watched a movie.", + "trans_a": "Вчера я посмотрел фильм (какой-то один фильм, собеседник пока не знает какой).", + "situation_b": "Повторное упоминание того же объекта (The)", + "example_b": "The movie was directed by Christopher Nolan.", + "trans_b": "Этот фильм снял Кристофер Нолан (собеседник уже понимает, о каком именно фильме речь).", + "key_difference": "При первом вводе предмета в диалог используется a/an; при повторном — the." } ], - "journaling_prompt": "Нарисуйте в тетради 3 колонки: A/An, The, Ø (без артикля). Напишите цепочку из 2 предложений: первое с 'a', второе с 'the' (например: 'I adopted a cat. The cat is black').", "exercises": [ { - "sentence": "She wants to buy ___ electric car next month.", - "target": "an", - "clue": "электромобиль (слово начинается с гласного звука)", - "options": [ - "an", - "a", - "the", - "—" - ], - "explanation": "Перед исчисляемым существительным в единственном числе, начинающимся с гласного звука [e], ставится артикль 'an'." - }, - { - "sentence": "Could you please close ___ window? It is getting chilly.", + "sentence": "Can you please close ___ window? It is getting cold in here.", "target": "the", - "clue": "окно (конкретное окно в этой комнате)", + "clue": "Собеседник видит конкретное окно в комнате", "options": [ "the", "a", "an", - "—" + "no article" ], - "explanation": "Собеседникам понятно, о каком именно окне в комнате идёт речь $\rightarrow$ определённый артикль 'the'." + "explanation": "Речь идёт о конкретном окне в данной комнате, понятном обоим собеседникам: 'close the window'." }, { - "sentence": "___ apples are good for your health.", - "target": "—", - "clue": "яблоки вообще (без артикля)", + "sentence": "Paris is ___ capital city of France.", + "target": "the", + "clue": "У Франции только одна столица (уникальный статус)", "options": [ - "—", + "the", + "a", + "an", + "no article" + ], + "explanation": "Столица у страны одна-единственная (уникальный объект), поэтому используется 'the capital city'." + }, + { + "sentence": "My sister wants to become ___ architect in a design studio.", + "target": "an", + "clue": "Слово 'architect' начинается с гласного звука [ɑː]", + "options": [ + "an", + "a", + "the", + "no article" + ], + "explanation": "Перед названием профессии в единственном числе, начинающимся с гласного звука ('architect'), ставится артикль 'an'." + }, + { + "sentence": "___ apples are rich in fiber and vitamins.", + "target": "no article", + "clue": "Яблоки как класс фруктов в целом во множественном числе", + "options": [ + "no article", "The", "An", "A" ], - "explanation": "Когда мы говорим о яблоках в целом как о классе продуктов во множественном числе, артикль отсутствует ('Zero Article')." + "explanation": "Когда мы говорим о вещах во множественном числе в общем смысле, артикль не ставится: 'Apples are rich...'." }, { - "sentence": "___ Moon orbits around our planet.", - "target": "The", - "clue": "Луна (уникальный единственный в природе объект)", - "options": [ - "The", - "A", - "An", - "—" - ], - "explanation": "Уникальные астрономические объекты, единственные в своём роде, всегда требуют артикля 'The': 'The Moon'." - }, - { - "sentence": "He ordered a soup and a salad; ___ soup was delicious.", + "sentence": "We spent our vacation relaxing on the coast of ___ Black Sea.", "target": "the", - "clue": "суп (второе упоминание того же самого супа)", + "clue": "Перед названиями морей всегда ставится определённый артикль The", "options": [ "the", "a", "an", - "—" + "no article" ], - "explanation": "При повторном упоминании объекта ('a soup' $\rightarrow$ 'the soup') используется определённый артикль 'the'." + "explanation": "С названиями морей, океанов и рек всегда употребляется определённый артикль: 'the Black Sea'." } ] }, @@ -1152,80 +1225,82 @@ "level": "B1-B2", "category": "Gerund & Infinitive", "title": "Gerund vs Infinitive (doing vs to do)", - "subtitle": "Герундий (-ing) vs Инфинитив (to do) после глаголов и предлогов", - "golden_formula": "VERB + ING: enjoy, avoid, mind, finish, suggest, look forward to\nVERB + TO DO: decide, hope, promise, refuse, manage, want, afford\nAFTER PREPOSITIONS: ALWAYS -ING (good at coding, interested in learning)", + "subtitle": "Две формы глагола: списки управления, правило предлогов и изменение смысла", + "golden_formula": "VERB + GERUND (-ing): enjoy, avoid, mind, finish, suggest, consider, risk, postpone\nVERB + INFINITIVE (to + V1): decide, plan, hope, promise, refuse, manage, agree, afford\nRULE: AFTER ANY PREPOSITION → ALWAYS GERUND! (interested in learning, good at coding)\nDUAL MEANING:\nstop doing (бросить навсегда) vs stop to do (остановиться, чтобы сделать)\nremember doing (помнить событие из прошлого) vs remember to do (не забыть сделать)", + "cheatsheet_table": "| Категория | Глаголы управления | Пример |\n| :--- | :--- | :--- |\n| **Только Герундий (-ing)** | *enjoy, avoid, mind, suggest, finish, keep* | *I enjoy reading science fiction.* |\n| **Только Инфинитив (to do)** | *decide, hope, plan, promise, offer, refuse* | *We decided to move to a new apartment.* |\n| **После предлогов (100%)** | *interested in, good at, afraid of, instead of* | *He is very good at solving problems.* |\n| **STOP (разница смысла)** | *stop smoking* (бросить вредную привычку) | *stop to smoke* (остановиться, чтобы закурить) |\n| **REMEMBER (разница)** | *remember locking* (помню, как закрывал) | *remember to lock* (не забудь закрыть дверь) |", + "detailed_notes": "### 🎯 Суть правила и логика носителя языка\n1. **Герундий (-ing)** часто несёт оттенок реального жизненного опыта, процесса или удовольствия: *I enjoy cooking*.\n2. **Инфинитив (to do)** ориентирован в будущее: на цель, намерение или решение: *I decided to cook dinner*.\n\n### ⚓ Железное правило предлогов\nЕсли после предлога (`in`, `on`, `at`, `for`, `about`, `before`, `after`, `instead of`) идёт глагол, он **ОБЯЗАН быть в форме герундия (-ing)**:\n- *Thank you for helping me.* (НЕ *for help*).\n- *She left without saying goodbye.*", + "journaling_prompt": "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n1. Нарисуйте две колонки: 'Глагол + -ing' (enjoy, avoid, mind, finish) и 'Глагол + to do' (decide, hope, plan, promise).\n2. Запишите в рамку закон: 'ПОСЛЕ ЛЮБОГО ПРЕДЛОГА — ВСЕГДА ТОЛЬКО -ING!'.\n3. Составьте от руки 3 предложения:\n - [Что нравится] I really enjoy [reading / coding / traveling]...\n - [Что решили сделать] Recently, I decided to [learn English / exercise regularly]...\n - [Конструкция с предлогом] I am interested in [improving my grammar / learning AI]...", "contrast_explanation": [ { - "situation_a": "Глаголы, требующие только герундия (-ing)", - "example_a": "I really enjoy reading books in the evening.", - "trans_a": "Мне очень нравится читать книги по вечерам (enjoy + V-ing).", - "situation_b": "Глаголы, требующие только инфинитива (to do)", - "example_b": "We decided to stay at home because of the storm.", - "trans_b": "Мы решили остаться дома из-за шторма (decide + to do).", - "key_difference": "После любых предлогов (in, at, about, without, before, after) ВСЕГДА используется форма -ing!" + "situation_a": "Прекращение действия навсегда (Stop + -ing)", + "example_a": "He stopped smoking five years ago.", + "trans_a": "Он бросил курить пять лет назад (действие прекращено навсегда).", + "situation_b": "Пауза ради другой цели (Stop + to do)", + "example_b": "He was driving for three hours, then stopped to smoke a cigarette.", + "trans_b": "Он был за рулём три часа, затем остановил машину, чтобы выкурить сигарету.", + "key_difference": "Stop + -ing = бросить привычку; Stop + to do = сделать паузу ради другой цели." } ], - "journaling_prompt": "Запишите в тетрадь 2 списка: 1) Глаголы + -ing (enjoy, avoid), 2) Глаголы + to (decide, hope). Напишите 2 предложения: одно с тем, чем вы наслаждаетесь (enjoy doing), другое с тем, что решили сделать (decided to do).", "exercises": [ { - "sentence": "I am looking forward to ___ you at the conference.", - "target": "meeting", - "clue": "встретить (после предлога to в устойчивой связке look forward to)", + "sentence": "I really enjoy ___ audiobooks during my daily commute.", + "target": "listening to", + "clue": "Глагол enjoy требует после себя герундий (-ing)", "options": [ - "meeting", - "meet", - "to meet", - "met" + "listening to", + "to listen to", + "listen to", + "listened to" ], - "explanation": "В выражении 'look forward to' частица 'to' является предлогом, поэтому после неё обязательно используется герундий: 'meeting'." + "explanation": "После глагола 'enjoy' всегда используется герундий: 'enjoy listening to'." }, { - "sentence": "She decided ___ for the scholarship.", - "target": "to apply", - "clue": "подать заявку (после глагола decide)", + "sentence": "We have decided ___ our summer vacation in Spain.", + "target": "to spend", + "clue": "Глагол decide требует после себя инфинитив с частицей to", "options": [ - "to apply", - "applying", - "apply", - "applied" + "to spend", + "spending", + "spend", + "spent" ], - "explanation": "Глагол 'decide' требует после себя инфинитива с частицей to: 'decided to apply'." + "explanation": "После глагола 'decide' используется инфинитив с частицей to: 'decided to spend'." }, { - "sentence": "You should avoid ___ heavily right before bedtime.", + "sentence": "She is interested in ___ a new programming language.", + "target": "learning", + "clue": "После предлога 'in' глагол обязан стоять в форме герундия (-ing)", + "options": [ + "learning", + "to learn", + "learn", + "learned" + ], + "explanation": "Железное правило: после любого предлога (здесь 'in') всегда используется герундий: 'interested in learning'." + }, + { + "sentence": "Please remember ___ the front door before you go to bed.", + "target": "to lock", + "clue": "Не забыть сделать действие в будущем (remember to do)", + "options": [ + "to lock", + "locking", + "lock", + "locked" + ], + "explanation": "Напоминание о необходимости совершить действие в будущем: 'remember to lock'." + }, + { + "sentence": "You should avoid ___ heavily before going to sleep.", "target": "eating", - "clue": "есть (после глагола avoid)", + "clue": "Глагол avoid требует после себя форму на -ing", "options": [ "eating", "to eat", "eat", "eaten" ], - "explanation": "Глагол 'avoid' (избегать) управляет исключительно формой герундия: 'avoid eating'." - }, - { - "sentence": "He is very good at ___ complex algorithmic problems.", - "target": "solving", - "clue": "решать (после предлога at)", - "options": [ - "solving", - "to solve", - "solve", - "solved" - ], - "explanation": "После любых английских предлогов (здесь: предлог 'at') глагол принимает форму герундия: 'good at solving'." - }, - { - "sentence": "We can't afford ___ on a luxury cruise this summer.", - "target": "to go", - "clue": "поехать (после глагола afford)", - "options": [ - "to go", - "going", - "go", - "gone" - ], - "explanation": "Глагол 'afford' (позволить себе финансово) требует инфинитива с частицей to: 'afford to go'." + "explanation": "После глагола 'avoid' (избегать) используется форма герундия: 'avoid eating'." } ] } diff --git a/scripts/build_rich_grammar_units.py b/scripts/build_rich_grammar_units.py new file mode 100644 index 0000000..3df939d --- /dev/null +++ b/scripts/build_rich_grammar_units.py @@ -0,0 +1,1463 @@ +#!/usr/bin/env python3 +""" +Generates rich, detailed Murphy Grammar Units (FEAT-02). +Includes: +- Markdown Cheatsheet Tables (forms, markers, conjugations, common mistakes) +- Detailed Notes by Raymond Murphy (logic, signal words, pitfalls, authentic examples) +- Enhanced Contrasts & Journaling Framework +- Enhanced Exercise Clues & Explanations +""" + +import json +from pathlib import Path + +UNITS = [ + # ------------------------------------------------------------------------- + # Unit 1: Present Continuous + # ------------------------------------------------------------------------- + { + "unit_num": 1, + "level": "A1-A2", + "category": "Present Tenses", + "title": "Present Continuous (I am doing)", + "subtitle": "Действие в процессе прямо сейчас или временная ситуация в текущий период", + "golden_formula": "S + am / is / are + V-ing\n(+) I am working | He is sleeping | They are playing\n(-) S + am/is/are + not + V-ing (She isn't listening)\n(?) Am/Is/Are + S + V-ing? (Are you working now?)", + "cheatsheet_table": ( + "| Форма | Формула | Пример | Маркеры времени |\n" + "| :--- | :--- | :--- | :--- |\n" + "| **Утверждение (+)** | S + am/is/are + V-ing | *I am typing an email right now.* | now, right now |\n" + "| **Отрицание (-)** | S + am/is/are + not + V-ing | *He isn't sleeping, he's reading.* | at the moment, currently |\n" + "| **Вопрос (?)** | Am/Is/Are + S + V-ing? | *Are they coming to the meeting?* | Look!, Listen! |\n" + "| **Временный проект** | S + am/is/are + V-ing | *I am living with friends this month.* | this week, these days |\n" + "| **Изменения/Тренды** | S + am/is/are + getting/changing | *The climate is getting warmer.* | more and more, gradually |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Present Continuous передаёт идею **«я нахожусь внутри незавершённого действия»**. Действие уже началось, ещё не закончилось и разворачивается прямо в момент разговора или в текущий период жизни.\n\n" + "### ⏱️ Слова-маркеры (Signal Words)\n" + "- `now`, `right now` — прямо сейчас.\n" + "- `at the moment`, `currently` — в данный момент.\n" + "- `Look!`, `Listen!`, `Hurry up!` — маркеры привлечения внимания к происходящему процессу.\n" + "- `this week`, `these days`, `this year` — временные ситуации, не являющиеся постоянной рутиной.\n\n" + "### ⚠️ Частые ошибки (Common Pitfalls)\n" + "1. **Глаголы состояния (Stative Verbs)**: глаголы чувств, мыслей и обладания НЕ используются в -ing: *know, like, want, understand, believe, need, remember*. Нельзя сказать: *«I am understanding»*, правильно: *«I understand»*.\n" + "2. **Пропуск глагола to be**: нельзя сказать *«I working»*, обязательно *«I am working»*.\n" + "3. **Орфография при добавлении -ing**:\n" + " - `run` → `running`, `sit` → `sitting` (удвоение согласной после краткой ударной гласной);\n" + " - `write` → `writing`, `make` → `making` (конечная -e выпадает);\n" + " - `lie` → `lying`, `die` → `dying` (сочетание -ie меняется на -y).\n\n" + "### 💡 Живые примеры с переводом\n" + "- *Please don't make so much noise. I am trying to work.* — Пожалуйста, не шуми. Я пытаюсь работать (прямо сейчас).\n" + "- *Why are you wearing a coat? It's not cold.* — Почему на тебе пальто? На улице не холодно.\n" + "- *Are you enjoying your new project at work?* — Тебе нравится твой новый проект на работе (в этот период)?" + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Перечертите таблицу форм (+, -, ?) и выделите маркером вспомогательные глаголы am / is / are.\n" + "2. Запишите правило орфографии: удвоение согласных (run → running) и выпадение -e (write → writing).\n" + "3. Составьте от руки 3 личных примера по шаблону:\n" + " - [Прямо сейчас] Right now, I am [действие: sitting at my desk / drinking tea]...\n" + " - [Временный процесс] These days, I am [study/work project: learning English vocabulary]...\n" + " - [Что делают другие] My colleagues/family are [relaxing / working]..." + ), + "contrast_explanation": [ + { + "situation_a": "Действие происходит в секунду речи (Now / at the moment)", + "example_a": "Please be quiet. I am trying to concentrate.", + "trans_a": "Пожалуйста, потише. Я пытаюсь сосредоточиться (прямо сейчас).", + "situation_b": "Временная ситуация в текущий период жизни (Around now / temporarily)", + "example_b": "She is studying computer science at university this year.", + "trans_b": "В этом году она изучает информатику в университете (временный процесс).", + "key_difference": "Present Continuous всегда показывает незавершённый процесс — мы находимся в его середине." + }, + { + "situation_a": "Постоянный факт или привычка (Present Simple)", + "example_a": "I live in Moscow. I work in an IT company.", + "trans_a": "Я живу в Москве (постоянно). Я работаю в IT-компании (постоянное место).", + "situation_b": "Временное отклонение от нормы (Present Continuous)", + "example_b": "I am living with my brother while my apartment is renovated.", + "trans_b": "Я временно живу у брата, пока в моей квартире идёт ремонт.", + "key_difference": "Continuous подчеркивает временность, Simple — постоянство и стабильность." + } + ], + "exercises": [ + { + "sentence": "Listen to those birds! They ___ so beautifully.", + "target": "are singing", + "clue": "Действие происходит прямо сейчас (маркер 'Listen!'), подлежащее 'They' (множественное число)", + "options": ["are singing", "sing", "is singing", "sang"], + "explanation": "Слово-маркер 'Listen!' указывает на процесс в секунду речи. Подлежащее 'They' требует форму множественного числа 'are singing' (не 'is singing', и не Present Simple 'sing')." + }, + { + "sentence": "Why ___ you wearing a coat? It is warm outside today.", + "target": "are", + "clue": "Вопрос к действию прямо сейчас: форма глагола to be для местоимения 'you'", + "options": ["are", "do", "is", "have"], + "explanation": "В Present Continuous вопрос строится через вынос вспомогательного глагола to be перед подлежащим: 'Why are you wearing...' ('do' используется в Present Simple без -ing)." + }, + { + "sentence": "I ___ for my keys. Have you seen them anywhere?", + "target": "am looking", + "clue": "Я ищу прямо сейчас: местоимение 'I' + глагол look с предлогом for", + "options": ["am looking", "look", "is looking", "looking"], + "explanation": "Поиск происходит в данный момент, для местоимения 'I' форма Present Continuous — 'am looking'." + }, + { + "sentence": "The economic situation in the region ___ better every month.", + "target": "is getting", + "clue": "Постепенное изменение/тренд: подлежащее 'situation' (ед. число)", + "options": ["is getting", "gets", "are getting", "got"], + "explanation": "Для описания развивающихся процессов и изменений (get better, grow, change) используется Present Continuous: 'is getting better'." + }, + { + "sentence": "Please don't disturb him right now. He ___ an important report.", + "target": "is preparing", + "clue": "Маркер 'right now' + просьба не беспокоить в этот момент", + "options": ["is preparing", "prepares", "prepare", "was preparing"], + "explanation": "Маркер 'right now' и контекст 'не беспокой его' однозначно требуют Present Continuous: 'is preparing'." + } + ] + }, + + # ------------------------------------------------------------------------- + # Unit 2: Present Simple + # ------------------------------------------------------------------------- + { + "unit_num": 2, + "level": "A1-A2", + "category": "Present Tenses", + "title": "Present Simple (I do)", + "subtitle": "Регулярные привычки, законы природы, постоянные факты и расписания", + "golden_formula": "S + V1 (he / she / it + V-s/es)\n(+) I work / He works\n(-) S + do not / does not + V1 (I don't work / He doesn't work)\n(?) Do / Does + S + V1? (Do you work? / Does she work?)", + "cheatsheet_table": ( + "| Лицо | Утверждение (+) | Отрицание (-) | Вопрос (?) |\n" + "| :--- | :--- | :--- | :--- |\n" + "| **I / you / we / they** | *I work every day.* | *I don't work on Sundays.* | *Do you work remotely?* |\n" + "| **he / she / it** | *She works in a bank.* | *She doesn't work here.* | *Does he work full-time?* |\n" + "| **Глагол to be** | *He is an engineer.* | *He isn't at the office.* | *Is he ready?* |\n" + "| **Частотные наречия** | *always, usually, often* | ставятся перед основным глаголом | *I always check my email.* |\n" + "| **Окончания -s/-es** | watch → watch**es**, study → stud**ies** | go → go**es**, fix → fix**es** | kiss → kiss**es** |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Present Simple выражает **вещи вообще, регулярные привычки, законы природы и расписания**. Это не то, что происходит сию секунду, а постоянный порядок вещей.\n\n" + "### ⏱️ Слова-маркеры (Signal Words)\n" + "- Наречия частоты: `always` (всегда), `usually` (обычно), `often` (часто), `sometimes` (иногда), `rarely / seldom` (редко), `never` (никогда).\n" + " *Правило позиции: они ставятся ПЕРЕД смысловым глаголом, но ПОСЛЕ глагола to be (I always drink coffee / I am always on time).*\n" + "- Обстоятельства времени: `every day / week / year`, `on Mondays`, `in the morning`, `twice a month`.\n\n" + "### ⚠️ Частые ошибки (Common Pitfalls)\n" + "1. **Забытое окончание -s для he/she/it**: самая частая ошибка новичков. *He live in London* ❌ → *He lives in London* ✅.\n" + "2. **Двойное -s в отрицаниях и вопросах**: вспомогательный глагол `does / doesn't` уже забрал окончание -s себе, поэтому основной глагол остаётся в «голом» инфинитиве:\n" + " - *He doesn't works* ❌ → *He doesn't work* ✅.\n" + " - *Does she likes coffee?* ❌ → *Does she like coffee?* ✅.\n" + "3. **Правописание окончаний**:\n" + " - После шипящих (-s, -sh, -ch, -x, -z) и -o добавляется `-es`: *watches, washes, goes, does*.\n" + " - Согласная + -y меняется на `-ies`: *study → studies, fly → flies* (но гласная + y: *play → plays*).\n\n" + "### 💡 Живые примеры с переводом\n" + "- *The Earth goes around the Sun.* — Земля вращается вокруг Солнца (закон природы).\n" + "- *Nurses look after patients in hospitals.* — Медсёстры ухаживают за пациентами в больницах (профессия, факт).\n" + "- *What time do you usually finish work?* — Во сколько ты обычно заканчиваешь работу?" + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Запишите золотую формулу и обведите красным маркером окончание -s / -es для 3-го лица (he/she/it).\n" + "2. Выпишите правило: 'does/doesn't съедает -s у основного глагола'.\n" + "3. Составьте от руки 3 факта о вашей повседневной жизни:\n" + " - [Привычка с наречием] I usually [wake up at 7 AM / drink espresso]...\n" + " - [Отрицание] I don't [watch television / eat fast food]...\n" + " - [Факт о друге/коллеге] My friend works as [профессия] and lives in [город]..." + ), + "contrast_explanation": [ + { + "situation_a": "Регулярный факт и привычка (Present Simple)", + "example_a": "I play tennis every Saturday morning.", + "trans_a": "Я играю в теннис каждое утро субботы (постоянное хобби).", + "situation_b": "Действие в момент речи (Present Continuous)", + "example_b": "I am playing tennis right now with Mark.", + "trans_b": "Я играю в теннис прямо сейчас с Марком (на корте в эту секунду).", + "key_difference": "Present Simple = регулярность и расписание; Present Continuous = процесс прямо сейчас." + }, + { + "situation_a": "Утверждение для 3-го лица (he/she/it)", + "example_a": "Alex speaks three languages fluently.", + "trans_a": "Алекс свободно говорит на трёх языках (постоянный навык, окончание -s).", + "situation_b": "Отрицание с doesn't (глагол теряет -s)", + "example_b": "He doesn't speak Japanese.", + "trans_b": "Он не говорит по-японски (doesn't забирает окончание, speak без -s).", + "key_difference": "В отрицаниях и вопросах с does окончание -s с основного глагола ВСЕГДА исчезает." + } + ], + "exercises": [ + { + "sentence": "My brother ___ in a bank in the city center.", + "target": "works", + "clue": "Постоянная работа (факт), подлежащее 'My brother' (он, 3-е лицо ед. ч.)", + "options": ["works", "work", "is working", "working"], + "explanation": "Для 'My brother' (he) в Present Simple глагол обязательно получает окончание -s: 'works'." + }, + { + "sentence": "What time ___ the train arrive in Chicago?", + "target": "does", + "clue": "Вопрос о расписании поезда ('the train' = it)", + "options": ["does", "do", "is", "are"], + "explanation": "Для подлежащего 'the train' (it) в вопросах Present Simple используется вспомогательный глагол 'does'." + }, + { + "sentence": "She ___ like spicy food, so she always orders salad.", + "target": "doesn't", + "clue": "Отрицание для местоимения 'She' в Present Simple", + "options": ["doesn't", "don't", "isn't", "not"], + "explanation": "Отрицание для he/she/it строится с помощью 'doesn't + инфинитив без to': 'doesn't like'." + }, + { + "sentence": "We ___ go abroad on vacation, usually twice a year.", + "target": "often", + "clue": "Наречие частоты: ставится перед смысловым глаголом 'go'", + "options": ["often", "always", "never", "rarely"], + "explanation": "Контекст 'usually twice a year' (обычно дважды в год) сочетается по смыслу с наречием 'often' (часто)." + }, + { + "sentence": "My parents ___ in a small house near the seaside.", + "target": "live", + "clue": "Подлежащее во множественном числе ('My parents' = they)", + "options": ["live", "lives", "are living", "living"], + "explanation": "Для множественного числа 'My parents' (they) используется базовая форма глагола без -s: 'live'." + } + ] + }, + + # ------------------------------------------------------------------------- + # Unit 3: Present Continuous vs Present Simple + # ------------------------------------------------------------------------- + { + "unit_num": 3, + "level": "A1-A2", + "category": "Present Tenses", + "title": "Present Continuous vs Present Simple (I am doing vs I do)", + "subtitle": "Битва времен: процесс в моменте против постоянного порядка вещей и Stative Verbs", + "golden_formula": "NOW / TEMPORARY: am / is / are + V-ing\nHABIT / PERMANENT: V1 (he/she/it + s)\nSTATIVE VERBS (NO -ING): like, love, hate, want, need, prefer, know, realize, suppose, mean, understand, believe, remember, belong, fit, contain, consist, seem", + "cheatsheet_table": ( + "| Критерий | Present Continuous (I am doing) | Present Simple (I do) |\n" + "| :--- | :--- | :--- |\n" + "| **Суть** | Действие незавершено, мы в середине | Постоянный факт, рутина, закон природы |\n" + "| **Время** | Прямо сейчас или в текущий период | Всегда, регулярно, по расписанию |\n" + "| **Маркеры** | *now, at the moment, this week, Look!* | *always, usually, often, every day, twice a week* |\n" + "| **Глаголы мышления** | НЕ употребляются в -ing (*know, believe*) | *I know the answer. (NOT I am knowing)* |\n" + "| **Глаголы чувств** | НЕ употребляются в -ing (*like, love, want*) | *I want a cup of coffee. (NOT I am wanting)* |\n" + "| **Особый: THINK** | *I am thinking* = размышляю прямо сейчас | *I think* = у меня есть мнение (I think it's good) |\n" + "| **Особый: HAVE** | *I am having lunch / a shower* = действие | *I have a car* = владение (NOT I am having a car) |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Главный вопрос носителя: **«Это процесс в развитии или стабильный факт?»**\n" + "- *Water is boiling. Can you turn it off?* — Вода кипит прямо сейчас (бурлит в чайнике).\n" + "- *Water boils at 100 degrees Celsius.* — Вода кипит при 100 градусах (физический закон всегда).\n\n" + "### 🧠 Глаголы состояния (Stative Verbs) — Золотой список\n" + "Эти глаголы описывают состояние ума, чувства или отношение, а не физическое действие. Они **никогда не используются в Present Continuous** (даже если ситуация происходит прямо сейчас!):\n" + "1. **Эмоции и желания**: `like`, `love`, `hate`, `want`, `need`, `prefer`.\n" + "2. **Мышление и знание**: `know`, `understand`, `recognize`, `believe`, `remember`, `forget`, `mean`.\n" + "3. **Владение**: `have` (в значении обладать), `belong`, `own`, `possess`.\n" + "4. **Восприятие**: `see`, `hear`, `smell`, `taste`, `seem`.\n\n" + "### ⚡ Двойные глаголы (Dual-meaning Verbs)\n" + "- **THINK**:\n" + " - *What do you think of this idea?* (Каково твоё мнение? — Simple)\n" + " - *Be quiet, I am thinking.* (Идёт активный процесс размышления — Continuous)\n" + "- **HAVE**:\n" + " - *I have two laptops.* (Владение — Simple)\n" + " - *I am having lunch / having a break.* (Устойчивое действие — Continuous)\n\n" + "### 💡 Живые примеры с переводом\n" + "- *Do you understand what I mean?* — Ты понимаешь, что я имею в виду? (Оба глагола stative!)\n" + "- *I am living with my parents until I find an apartment.* — Я временно живу с родителями (Continuous), хотя обычно люди говорят *I live in Madrid* (Simple)." + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Нарисуйте таблицу из двух колонок: 'Present Continuous (сейчас/временно)' и 'Present Simple (всегда/факт)'.\n" + "2. Запишите в рамку 8 главных глаголов-запретов для -ing: know, want, like, understand, need, believe, remember, belong.\n" + "3. Запишите контраст двойного глагола think:\n" + " - 'I think it's a good plan' (мнение) vs 'I'm thinking about it' (процесс мысли).\n" + "4. Составьте от руки контрастную пару о себе: 'I usually [привычка: drink tea], but today I am [процесс: drinking coffee]'." + ), + "contrast_explanation": [ + { + "situation_a": "Глагол состояния (Stative Verb) — только Simple", + "example_a": "I understand the grammar rule clearly now.", + "trans_a": "Я понимаю грамматическое правило сейчас (слово 'now', но глагол stative — только Simple!).", + "situation_b": "Динамическое действие (Action Verb) — Continuous", + "example_b": "I am studying the grammar rule right now.", + "trans_b": "Я изучаю правило прямо сейчас (физический процесс — Continuous).", + "key_difference": "Даже при слове 'now' глаголы understand, know, want не ставятся в -ing." + }, + { + "situation_a": "Глагол HAVE как владение (Simple)", + "example_a": "We have a big house in the countryside.", + "trans_a": "У нас есть большой дом за городом (владение имуществом).", + "situation_b": "Глагол HAVE во фразовом значении (Continuous)", + "example_b": "We are having dinner together right now.", + "trans_b": "Мы сейчас ужинаем вместе (идиома have dinner = процесс еды).", + "key_difference": "В значении обладания have не имеет -ing. В значении процесса (have breakfast/shower) -ing разрешён." + } + ], + "exercises": [ + { + "sentence": "I ___ what you mean, but I don't agree with your conclusion.", + "target": "understand", + "clue": "Глагол ментального состояния (Stative Verb) — не используется в -ing", + "options": ["understand", "am understanding", "understands", "understanding"], + "explanation": "Глагол 'understand' выражает состояние понимания (Stative Verb) и не употребляется в Continuous форме, правильный ответ: 'understand'." + }, + { + "sentence": "Hurry up! The taxi ___ outside for us.", + "target": "is waiting", + "clue": "Призыв 'Hurry up!' указывает на процесс, происходящий прямо в эту секунду", + "options": ["is waiting", "waits", "wait", "are waiting"], + "explanation": "Контекст 'Hurry up!' (Поторопись!) указывает на разворачивающееся действие прямо сейчас. Для 'taxi' (it) форма: 'is waiting'." + }, + { + "sentence": "What ___ of my new presentation design?", + "target": "do you think", + "clue": "Вопрос о мнении/оценке (Think как точка зрения = Present Simple)", + "options": ["do you think", "are you thinking", "you think", "does you think"], + "explanation": "Когда мы спрашиваем мнение ('Что ты думаешь / как тебе?'), глагол think используется в Present Simple: 'What do you think?'." + }, + { + "sentence": "Usually I ___ by bus, but this week I am walking because the weather is sunny.", + "target": "go", + "clue": "Маркер 'Usually' показывает регулярную привычку", + "options": ["go", "am going", "goes", "went"], + "explanation": "Первая часть предложения описывает привычную рутину (маркер 'Usually'), поэтому нужен Present Simple: 'I go'." + }, + { + "sentence": "This luxury watch ___ to my grandfather.", + "target": "belongs", + "clue": "Глагол принадлежности (Belong = Stative Verb, подлежащее 'watch' = it)", + "options": ["belongs", "is belonging", "belong", "belonged"], + "explanation": "Глагол 'belong' (принадлежать) — глагол состояния, не имеет Continuous формы. Для 'watch' (it) требуется форма с -s: 'belongs'." + } + ] + }, + + # ------------------------------------------------------------------------- + # Unit 4: Past Simple + # ------------------------------------------------------------------------- + { + "unit_num": 4, + "level": "A1-A2", + "category": "Past Tenses", + "title": "Past Simple (I did)", + "subtitle": "Завершённые действия в прошлом с конкретной привязкой ко времени", + "golden_formula": "Regular verbs: V + -ed (worked, watched, stopped, studied)\nIrregular verbs: 2nd form (went, came, saw, bought, took, wrote)\n(-) S + did not (didn't) + V1 (I didn't see him)\n(?) Did + S + V1? (Did you go to London?)", + "cheatsheet_table": ( + "| Тип предложения | Формула | Пример | Маркеры завершённого прошлого |\n" + "| :--- | :--- | :--- | :--- |\n" + "| **Утверждение (+) прав.** | S + V-ed | *We played tennis yesterday.* | yesterday, yesterday morning |\n" + "| **Утверждение (+) неправ.** | S + V2 (2-я колонка) | *I bought a new laptop last week.* | last night, last week, last month |\n" + "| **Отрицание (-)** | S + did not (didn't) + V1 | *They didn't arrive on time.* | 2 days ago, a year ago |\n" + "| **Вопрос (?)** | Did + S + V1? | *Did you watch the match?* | in 2018, in the 1990s |\n" + "| **Глагол to be (was/were)** | S + was/were (БЕЗ did!) | *I was tired. They were happy.* | when I was a child, at 3 PM |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Past Simple используется, когда действие **полностью началось и завершилось в прошлом**, и время действия известно или названо. Это базовое время для любых исторических хроник, историй и перечисления событий.\n\n" + "### ⏱️ Слова-маркеры (Signal Words)\n" + "- `yesterday`, `yesterday evening` — вчера.\n" + "- `... ago` (three days ago, ten years ago) — тому назад.\n" + "- `last ...` (last week, last month, last summer, last night) — на прошлой...\n" + "- Точные даты и исторические вехи: `in 2015`, `in the 19th century`, `on Monday`.\n" + "- Придаточные предложения времени: `when I was a student`, `when she arrived`.\n\n" + "### ⚠️ Частые ошибки (Common Pitfalls)\n" + "1. **Двойное прошедшее время в отрицании и вопросе**:\n" + " - Вспомогательный `did / didn't` уже забрал прошедшее время себе! Основной глагол возвращается в первую форму:\n" + " - *I didn't went* ❌ → *I didn't go* ✅.\n" + " - *Did you bought it?* ❌ → *Did you buy it?* ✅.\n" + "2. **Путаница to be с did**:\n" + " - Для глагола to be в вопросах и отрицаниях `did` НЕ нужен:\n" + " - *Did you be at home?* ❌ → *Were you at home?* ✅.\n" + " - *I didn't be tired* ❌ → *I wasn't tired* ✅.\n" + "3. **Правописание окончаний -ed**:\n" + " - `stop` → `stopped` (удвоение согласной);\n" + " - `study` → `studied` (y меняется на i);\n" + " - `decide` → `decided` (только -d, если слово уже кончается на -e).\n\n" + "### 💡 Живые примеры с переводом\n" + "- *Mozart wrote more than 600 pieces of music.* — Моцарт написал более 600 музыкальных произведений (законченная историческая эпоха).\n" + "- *We didn't go out yesterday because it was raining heavily.* — Мы не пошли гулять вчера, потому что шёл сильный дождь." + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Нарисуйте линию времени со стрелкой в прошлое и точкой 'X' (действие завершено в прошлом).\n" + "2. Запишите формулы: (+) V2/ed, (-) didn't + V1, (?) Did + S + V1.\n" + "3. Выпишите 5 ключевых неправильных глаголов с переводом: go→went, see→saw, buy→bought, have→had, write→wrote.\n" + "4. Составьте от руки 3 реальных предложения о прошлых выходных:\n" + " - Last weekend, I [went / visited / cooked]...\n" + " - I didn't [have time to / buy]...\n" + " - Two years ago, I [started / moved to]..." + ), + "contrast_explanation": [ + { + "situation_a": "Утвердительное предложение (нужна 2-я форма)", + "example_a": "She bought an expensive coat yesterday.", + "trans_a": "Она купила дорогое пальто вчера (утверждение — глагол buy во 2-й форме bought).", + "situation_b": "Отрицательное предложение (нужна 1-я форма)", + "example_b": "She didn't buy any shoes.", + "trans_b": "Она не купила туфли (didn't забирает прошедшее время, глагол возвращается в buy).", + "key_difference": "Форма V2 используется ТОЛЬКО в утверждениях. В отрицаниях и вопросах всегда V1." + }, + { + "situation_a": "Обычный смысловой глагол (через did)", + "example_a": "Did you see that movie yesterday?", + "trans_a": "Ты смотрел тот фильм вчера? (вопрос строится через Did + see).", + "situation_b": "Глагол состояния to be (без did)", + "example_b": "Were you at the cinema yesterday?", + "trans_b": "Ты был в кино вчера? (to be сам выходит вперёд: Were you, без did).", + "key_difference": "Глагол to be (was/were) никогда не используется со вспомогательным did." + } + ], + "exercises": [ + { + "sentence": "I ___ to the supermarket yesterday, but I forgot my wallet at home.", + "target": "went", + "clue": "Утверждение в Past Simple: 2-я форма неправильного глагола 'go'", + "options": ["went", "go", "gone", "was going"], + "explanation": "Маркер 'yesterday' и контекст завершённого действия требуют 2-й формы неправильного глагола go: 'went'." + }, + { + "sentence": "We ___ enjoy the concert last night because the sound was terrible.", + "target": "didn't", + "clue": "Отрицание в Past Simple перед глаголом 'enjoy'", + "options": ["didn't", "don't", "weren't", "haven't"], + "explanation": "Отрицание смыслового глагола в прошлом строится с помощью 'didn't + V1': 'didn't enjoy'." + }, + { + "sentence": "What time ___ you wake up this morning?", + "target": "did", + "clue": "Вспомогательный глагол вопроса в Past Simple", + "options": ["did", "do", "were", "have"], + "explanation": "Вопрос к действию в завершённый момент времени строится через 'Did + S + V1': 'What time did you wake up?'." + }, + { + "sentence": "The train was delayed, so they ___ thirty minutes late.", + "target": "arrived", + "clue": "Правильный глагол arrive с окончанием -ed", + "options": ["arrived", "arrive", "were arrived", "arriving"], + "explanation": "Для регулярного глагола arrive в утверждении Past Simple добавляется окончание -d: 'arrived'." + }, + { + "sentence": "Where ___ you at 8 o'clock yesterday evening?", + "target": "were", + "clue": "Форма глагола to be в прошедшем времени для местоимения 'you'", + "options": ["were", "was", "did", "are"], + "explanation": "Для местоимения 'you' глагол to be в прошлом имеет форму 'were'. Вспомогательный did с глаголом to be не используется." + } + ] + }, + + # ------------------------------------------------------------------------- + # Unit 5: Past Continuous + # ------------------------------------------------------------------------- + { + "unit_num": 5, + "level": "A1-A2", + "category": "Past Tenses", + "title": "Past Continuous (I was doing)", + "subtitle": "Действие в процессе в определённый точный момент в прошлом", + "golden_formula": "S + was / were + V-ing\nwas: I, he, she, it (I was sleeping)\nwere: you, we, they (They were having dinner)\n(-) S + wasn't / weren't + V-ing\n(?) Was / Were + S + V-ing?", + "cheatsheet_table": ( + "| Местоимение | Утверждение (+) | Отрицание (-) | Вопрос (?) |\n" + "| :--- | :--- | :--- | :--- |\n" + "| **I / he / she / it** | *He was driving at 4 PM.* | *He wasn't working.* | *Was he sleeping when you called?* |\n" + "| **you / we / they** | *They were playing games.* | *They weren't studying.* | *Were you waiting for me?* |\n" + "| **Маркеры точного часа** | at 5:30 yesterday | at midnight | at that exact moment |\n" + "| **Период процесса** | all day yesterday | all evening | from 3 to 6 PM yesterday |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Past Continuous показывает, что **в конкретную точку времени в прошлом человек находился в середине действия**. Действие уже началось до этого момента и продолжалось после него.\n\n" + "### ⏱️ Слова-маркеры (Signal Words)\n" + "- Точный момент в прошлом: `at 4:00 PM yesterday`, `at that moment`, `at midnight`.\n" + "- Непрерывный интервал: `all day yesterday`, `all night`, `from 6 to 8 PM`.\n" + "- Контекстное окружение: `when I arrived` (действие УЖЕ шло к моменту прихода).\n\n" + "### ⚠️ Частые ошибки (Common Pitfalls)\n" + "1. **Путаница Past Simple и Past Continuous**:\n" + " - *At 8:00 I had dinner* (В 8:00 я сел ужинать — точечное начало в Past Simple).\n" + " - *At 8:00 I was having dinner* (В 8:00 я уже сидел с вилкой в руках в процессе ужина).\n" + "2. **Выбор was vs were**: помните, что `you` (даже когда относится к одному человеку: «ты») ВСЕГДА требует `were` (*Were you listening?*).\n" + "3. **Stative Verbs**: глаголы состояния не используются и в Past Continuous (*I knew the answer*, а не *I was knowing*).\n\n" + "### 💡 Живые примеры с переводом\n" + "- *This time last year, I was living in Germany.* — В это же время в прошлом году я жил в Германии (находился в процессе проживания).\n" + "- *What were you doing when the phone rang?* — Что ты делал в тот момент, когда зазвонил телефон?" + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Запишите формулы: was (I/he/she/it) + V-ing и were (you/we/they) + V-ing.\n" + "2. Нарисуйте временную шкалу: длинная волнистая линия (Past Continuous) и стрелка в точку 'at 5 PM yesterday'.\n" + "3. Составьте от руки 2 примера о том, чем вы занимались в конкретные часы вчера:\n" + " - Yesterday at 3 PM, I was [working / driving / coding]...\n" + " - At 11 PM last night, I was [sleeping / reading a book]..." + ), + "contrast_explanation": [ + { + "situation_a": "Завершённое действие целиком (Past Simple)", + "example_a": "I read a book yesterday evening.", + "trans_a": "Я прочитал книгу вчера вечером (действие завершено от начала до конца).", + "situation_b": "Процесс в определённый момент (Past Continuous)", + "example_b": "At 9 PM yesterday, I was reading a book.", + "trans_b": "В 9 вечера я читал книгу (был в процессе чтения в конкретный час).", + "key_difference": "Past Simple подчеркивает факт завершения; Past Continuous показывает незавершённый процесс." + }, + { + "situation_a": "Единственное число: I / he / she / it", + "example_a": "The computer was downloading an update.", + "trans_a": "Компьютер скачивал обновление (was для 3-го лица ед. числа it).", + "situation_b": "Множественное число и You: you / we / they", + "example_b": "The servers were processing data.", + "trans_b": "Серверы обрабатывали данные (were для множественного числа they).", + "key_difference": "Для I/he/she/it используется was, для you/we/they — were." + } + ], + "exercises": [ + { + "sentence": "At 10 o'clock yesterday morning, I ___ in a client meeting.", + "target": "was sitting", + "clue": "Процесс в точный момент времени в прошлом ('At 10 o'clock yesterday')", + "options": ["was sitting", "sat", "were sitting", "am sitting"], + "explanation": "Точное время в прошлом 'At 10 o'clock' и местоимение 'I' требуют форму Past Continuous: 'was sitting'." + }, + { + "sentence": "What ___ you doing when the fire alarm went off?", + "target": "were", + "clue": "Форма вспомогательного глагола для местоимения 'you' в Past Continuous", + "options": ["were", "was", "did", "are"], + "explanation": "Для местоимения 'you' в Past Continuous используется вспомогательный глагол 'were': 'What were you doing?'." + }, + { + "sentence": "It ___ heavily all day yesterday, so we stayed indoors.", + "target": "was raining", + "clue": "Длительный непрерывный процесс на протяжении всего дня ('all day yesterday')", + "options": ["was raining", "rained", "were raining", "rains"], + "explanation": "Маркер 'all day yesterday' указывает на продолжительный фоновый процесс: 'It was raining'." + }, + { + "sentence": "I called you three times, but you ___ answer. What were you doing?", + "target": "didn't", + "clue": "Факт неответа на звонки в прошлом (Past Simple отрицание)", + "options": ["didn't", "weren't", "wasn't", "don't"], + "explanation": "Здесь выражается точечный факт: 'ты не ответил', поэтому нужен Past Simple: 'didn't answer'." + }, + { + "sentence": "While Sarah was preparing dinner, the children ___ their homework.", + "target": "were doing", + "clue": "Параллельный процесс во множественном числе ('the children' = they)", + "options": ["were doing", "was doing", "did", "are doing"], + "explanation": "Два одновременных длительных процесса соединяются союзом While. Для 'the children' (they) форма: 'were doing'." + } + ] + } +] + +# We will complete units 6 through 15 below programmatically and merge with existing units +MORE_UNITS = [ + # ------------------------------------------------------------------------- + # Unit 6: Past Simple vs Past Continuous + # ------------------------------------------------------------------------- + { + "unit_num": 6, + "level": "A1-A2", + "category": "Past Tenses", + "title": "Past Simple vs Past Continuous (I did vs I was doing)", + "subtitle": "Длинный фон против внезапного прерывания: формулы связок While и When", + "golden_formula": "Background action (LONG): was / were + V-ing\nInterruption action (SHORT): V2 / -ed\nPATTERN: While + Past Continuous, Past Simple\n(While I was walking home, it started to rain)\nPATTERN: Past Continuous + when + Past Simple\n(I was watching TV when the phone rang)", + "cheatsheet_table": ( + "| Конструкция | Значение | Пример |\n" + "| :--- | :--- | :--- |\n" + "| **Длинное + Короткое** | Длинный фон прерывается коротким событием | *While I was cooking, I burned my finger.* |\n" + "| **Когда (When)** | Вводит внезапное точечное действие (V2) | *I was driving when a deer jumped out.* |\n" + "| **Пока (While / As)** | Вводит длительный фоновый процесс (-ing) | *While they were sleeping, someone knocked.* |\n" + "| **Два коротких подряд** | Последовательность событий (оба Past Simple) | *I heard a noise, got up and opened the door.* |\n" + "| **Два длинных параллельно** | Два одновременных процесса (оба Continuous) | *While I was reading, my brother was playing.* |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Представьте себе фильм: **Past Continuous — это видеоряд (фоновые декорации и длящееся действие)**, а **Past Simple — это резкий щелчок затвора или звук выстрела (событие, которое произошло)**.\n\n" + "### ⏱️ Ключевые союзы связки\n" + "- `When` + **Past Simple** (точечное действие): *...when the lights went out*.\n" + "- `While` / `As` + **Past Continuous** (длительный процесс): *While I was having a shower...*\n\n" + "### ⚠️ Частые ошибки (Common Pitfalls)\n" + "1. Не путайте последовательность действий и прерывание:\n" + " - *When the phone rang, I answered it.* (Сначала зазвонил, потом я снял трубку — оба Simple).\n" + " - *When the phone rang, I was having lunch.* (Звонок раздался прямо в середине моего обеда — Continuous + Simple).\n" + "2. Не ставьте два коротких действия в Continuous (*I was getting up and was opening the door* ❌)." + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Нарисуйте горизонтальную полосу (Длинное действие: was/were -ing) и вертикальную стрелку сквозь неё (Короткое действие: V2).\n" + "2. Выпишите золотые формулы: 'While + Past Continuous, Past Simple' и 'Past Continuous + when + Past Simple'.\n" + "3. Запишите от руки 2 реальные истории из жизни по шаблону:\n" + " - 'While I was [doing something: walking in the park], I [saw / found / met]...'\n" + " - 'I was [working on my laptop] when suddenly [my phone rang / the power went out]'." + ), + "contrast_explanation": [ + { + "situation_a": "Прерывание процесса (Continuous + Simple)", + "example_a": "I was walking to the station when I met John.", + "trans_a": "Я шёл на станцию (длинное действие), когда встретил Джона (короткая встреча).", + "situation_b": "Последовательность действий (Simple + Simple)", + "example_b": "I arrived at the station and bought a ticket.", + "trans_b": "Я пришёл на станцию и купил билет (одно действие завершилось, началось второе).", + "key_difference": "Прерывание объединяет фоновый процесс и точку; последовательность описывает цепочку завершенных фактов." + } + ], + "exercises": [ + { + "sentence": "While we ___ in the park, it suddenly started to rain.", + "target": "were walking", + "clue": "Длительное фоновое действие после союза 'While'", + "options": ["were walking", "walked", "are walking", "was walking"], + "explanation": "Союз 'While' вводит длительный процесс (Past Continuous). Для местоимения 'we' правильная форма: 'were walking'." + }, + { + "sentence": "I ___ my finger while I was chopping vegetables for salad.", + "target": "cut", + "clue": "Внезапное короткое действие-прерывание (2-я форма глагола cut)", + "options": ["cut", "was cutting", "cutting", "have cut"], + "explanation": "Порез пальца — мгновенное точечное действие, прервавшее процесс нарезки, поэтому используется Past Simple: 'cut'." + }, + { + "sentence": "When the teacher walked into the room, the students ___ noise.", + "target": "were making", + "clue": "Фоновый процесс, который уже шёл к моменту прихода учителя", + "options": ["were making", "made", "are making", "was making"], + "explanation": "К моменту прихода учителя (короткое действие) шум уже стоял в классе (длительный процесс): 'were making'." + }, + { + "sentence": "He picked up his bag, ___ the door and left the house.", + "target": "locked", + "clue": "Цепочка последовательных завершённых действий (Past Simple)", + "options": ["locked", "was locking", "locks", "is locking"], + "explanation": "Перечисление последовательных действий в прошлом строится полностью в Past Simple: picked up, locked, left." + }, + { + "sentence": "What were you doing when the power ___ out?", + "target": "went", + "clue": "Точечное событие-прерывание после слова 'when'", + "options": ["went", "was going", "goes", "has gone"], + "explanation": "После 'when' в конструкции прерывания используется Past Simple: 'went out'." + } + ] + }, + + # ------------------------------------------------------------------------- + # Unit 7: Present Perfect + # ------------------------------------------------------------------------- + { + "unit_num": 7, + "level": "B1-B2", + "category": "Present Perfect", + "title": "Present Perfect (I have done)", + "subtitle": "Мост между прошлым и настоящим: результат виден сейчас и жизненный опыт", + "golden_formula": "S + have / has + V3 (Past Participle)\nhave: I, you, we, they | has: he, she, it\n(-) S + haven't / hasn't + V3\n(?) Have / Has + S + V3?\nMARKERS: just (только что), already (уже), yet (ещё не / уже в вопросах), ever, never, recently, so far, since, for", + "cheatsheet_table": ( + "| Маркер | Позиция в предложении | Пример | Перевод |\n" + "| :--- | :--- | :--- | :--- |\n" + "| **just** | Между have и V3 | *I have just finished my work.* | Я только что закончил. |\n" + "| **already** | Между have и V3 (раньше ожидаемого) | *He has already left the office.* | Он уже ушёл из офиса. |\n" + "| **yet** | ВСЕГДА в самом конце (в - и ?) | *I haven't received the email yet.* | Я ещё не получил письмо. |\n" + "| **ever** | В вопросах о жизненном опыте | *Have you ever been to Japan?* | Ты когда-либо был в Японии? |\n" + "| **never** | Отрицательный опыт (глагол в +) | *She has never seen the ocean.* | Она никогда не видела океан. |\n" + "| **since** | С конкретной точки старта | *I have lived here since 2020.* | Я живу здесь с 2020 года. |\n" + "| **for** | На протяжении периода | *They have worked here for 5 years.* | Они работают здесь 5 лет. |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Present Perfect — это грамматическое настоящее время в английском языке! Для англичанина важно не то, КОГДА произошло действие, а **КАКОВ ЕГО РЕЗУЛЬТАТ В НАСТОЯЩЕМ**:\n" + "- *I have lost my keys.* = Я потерял ключи в прошлом, и **у меня нет их СЕЙЧАС**.\n" + "- *The road is closed. There has been an accident.* = Авария была в прошлом, но дорога перекрыта **ПРЯМО СЕЙЧАС**.\n\n" + "### 🚢 Разница: have been to vs have gone to\n" + "- *Mark has **gone** to Italy.* — Марк уехал в Италию (он сейчас ТАМ или в пути).\n" + "- *Mark has **been** to Italy.* — Марк побывал в Италии (он съездил туда и уже вернулся назад).\n\n" + "### ⚠️ Частые ошибки (Common Pitfalls)\n" + "1. **Использование с точным временем в прошлом — ЗАПРЕЩЕНО**:\n" + " - *I have seen him yesterday* ❌ → *I saw him yesterday* ✅ (yesterday = Past Simple).\n" + "2. **Yet ставится только в конце** предложения в отрицаниях и вопросах:\n" + " - *Have you finished yet?* / *I haven't eaten yet.*" + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Запишите формулу: have / has + V3. Обведите маркеры: just, already, yet, ever, never.\n" + "2. Выпишите контраст: 'gone to' (уехал и еще там) vs 'been to' (съездил и вернулся).\n" + "3. Запишите от руки 3 предложения о вашем реальном опыте:\n" + " - [Результат прямо сейчас] I have just [закончил проект / выпил кофе]...\n" + " - [Жизненный опыт] I have been to [страна/город], but I have never visited [место]...\n" + " - [Длительность со словом for/since] I have studied English for [срок] months." + ), + "contrast_explanation": [ + { + "situation_a": "Результат важен сейчас (Present Perfect)", + "example_a": "I have washed the car. It looks brand new.", + "trans_a": "Я помыл машину. Она выглядит как новая (результат прямо перед глазами).", + "situation_b": "Конкретный завершённый момент в прошлом (Past Simple)", + "example_b": "I washed the car two days ago.", + "trans_b": "Я помыл машину два дня назад (есть маркер ago — только Past Simple).", + "key_difference": "Если нет точной даты и важен результат сейчас — Present Perfect; при указании даты — Past Simple." + } + ], + "exercises": [ + { + "sentence": "I can't open the door because I ___ my keys.", + "target": "have lost", + "clue": "Результат в настоящем: я не могу войти прямо сейчас", + "options": ["have lost", "lost", "had lost", "am losing"], + "explanation": "Невозможность открыть дверь прямо сейчас — прямое последствие потери ключей, поэтому используется Present Perfect: 'have lost'." + }, + { + "sentence": "Where is David? — He has ___ to Paris for a business conference and will return next week.", + "target": "gone", + "clue": "Он уехал и ещё находится там (вернулся бы — было бы been)", + "options": ["gone", "been", "went", "going"], + "explanation": "David ещё не вернулся (он всё ещё в Париже), поэтому используется 'has gone to'." + }, + { + "sentence": "Have you ___ eaten raw seafood?", + "target": "ever", + "clue": "Вопрос о жизненном опыте ('когда-либо в жизни')", + "options": ["ever", "never", "already", "yet"], + "explanation": "В вопросах о личном жизненном опыте используется маркер 'ever' (когда-либо)." + }, + { + "sentence": "We haven't received the confirmation email ___.", + "target": "yet", + "clue": "Маркер в конце отрицательного предложения ('ещё не')", + "options": ["yet", "already", "just", "never"], + "explanation": "В отрицательных предложениях слово 'yet' ставится в конец и переводится как 'ещё не'." + }, + { + "sentence": "She has lived in this apartment ___ five years.", + "target": "for", + "clue": "Указание на длительность периода времени (на протяжении 5 лет)", + "options": ["for", "since", "during", "ago"], + "explanation": "Для указания протяжённости периода времени (five years) используется предлог 'for'." + } + ] + }, + + # ------------------------------------------------------------------------- + # Unit 8: Present Perfect vs Past Simple + # ------------------------------------------------------------------------- + { + "unit_num": 8, + "level": "B1-B2", + "category": "Present Perfect", + "title": "Present Perfect vs Past Simple (I have done vs I did)", + "subtitle": "Главный водораздел английской грамматики: открытое время vs закрытое время", + "golden_formula": "FINISHED TIME (Past Simple): yesterday, last year, in 2020, 2 days ago, when I arrived\nUNFINISHED / OPEN TIME (Present Perfect): today, this week, so far, recently, never, ever\nGOLDEN RULE: If you name WHEN in the past, NEVER use have done!", + "cheatsheet_table": ( + "| Критерий | Present Perfect (I have done) | Past Simple (I did) |\n" + "| :--- | :--- | :--- |\n" + "| **Время** | Не закончено / открыто (*today, this week*) | Полностью закончено (*yesterday, last week*) |\n" + "| **Точная дата** | Запрещена (*NOT I have seen him yesterday*) | Обязательна или подразумевается (*yesterday, in 2019*) |\n" + "| **Вопрос «Когда?»** | НЕЛЬЗЯ спросить *When have you...?* | ТОЛЬКО *When did you buy it?* |\n" + "| **Фокус внимания** | Результат и новость сейчас (*I've won!*) | Детали и обстоятельства (*I won it in Madrid*) |\n" + "| **Период жизни** | Человек жив (*Shakespeare wrote / Rowling has written*) | Историческая эпоха завершена (*Mozart wrote*) |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Это самая важная тема английской грамматики. Задайте один проверочный вопрос:\n" + "**«Период времени закрыт или ещё продолжается?»**\n" + "- *I have drunk two cups of coffee today.* (День ещё идёт, могу выпить третью — Present Perfect).\n" + "- *I drank two cups of coffee yesterday.* (Вчерашний день закрыт навсегда — Past Simple).\n\n" + "### ⚠️ Табу носителей языка\n" + "Никогда не начинайте вопрос со слова **WHEN** в Present Perfect! Вопрос «Когда?» требует конкретного момента времени в прошлом, поэтому ВСЕГДА строится в Past Simple:\n" + "- *When have you arrived?* ❌ → *When did you arrive?* ✅.\n" + "- *What time has the train left?* ❌ → *What time did the train leave?* ✅." + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Нарисуйте две коробки: 'ЗАКРЫТОЕ ВРЕМЯ (Past Simple)' с датами (yesterday, 2021, ago) и 'ОТКРЫТОЕ ВРЕМЯ (Present Perfect)' (today, this week, ever).\n" + "2. Запишите жирным красным маркером: 'ВОПРОС С WHEN — ВСЕГДА В PAST SIMPLE!'.\n" + "3. Запишите контрастную пару предложений о сегодняшнем дне и вчерашнем:\n" + " - Today, I have [drink/done: drunk two cups of tea]...\n" + " - Yesterday, I [ate / saw / went]..." + ), + "contrast_explanation": [ + { + "situation_a": "Период времени ещё не завершился (this morning, до полудня)", + "example_a": "I have seen Tom this morning.", + "trans_a": "Я видел Тома сегодня утром (разговор происходит в 10:30 утра, утро ЕЩЁ ИДЁТ).", + "situation_b": "Период времени завершился (this morning, разговор днём/вечером)", + "example_b": "I saw Tom this morning.", + "trans_b": "Я видел Тома сегодня утром (разговор происходит в 16:00, утро УЖЕ ПРОШЛО).", + "key_difference": "Если временной отрезок ещё продолжается — Present Perfect; если закончился — Past Simple." + } + ], + "exercises": [ + { + "sentence": "When ___ you buy your new smartphone?", + "target": "did", + "clue": "Вопрос со словом 'When' требует строго Past Simple", + "options": ["did", "have", "were", "do"], + "explanation": "Вопрос с 'When' (Когда?) всегда строится в Past Simple со вспомогательным глаголом 'did'." + }, + { + "sentence": "I ___ to the gym three times this week, and it's only Wednesday.", + "target": "have been", + "clue": "Период времени 'this week' ещё не закончился (открытое время)", + "options": ["have been", "went", "was", "had been"], + "explanation": "Неделя ещё продолжается ('this week'), поэтому используется Present Perfect: 'have been'." + }, + { + "sentence": "William Shakespeare ___ many famous plays and sonnets.", + "target": "wrote", + "clue": "Историческая личность, завершённая эпоха прошлого", + "options": ["wrote", "has written", "writes", "was writing"], + "explanation": "Шекспир жил в прошлом и больше ничего написать не может (период закрыт), поэтому только Past Simple: 'wrote'." + }, + { + "sentence": "She ___ her first novel in 2018.", + "target": "published", + "clue": "Точная завершённая дата в прошлом ('in 2018')", + "options": ["published", "has published", "publishes", "was published"], + "explanation": "При наличии точной даты 'in 2018' используется исключительно Past Simple: 'published'." + }, + { + "sentence": "Look! Somebody ___ a glass on the kitchen floor.", + "target": "has broken", + "clue": "Слово 'Look!' привлекает внимание к свежему результату прямо сейчас", + "options": ["has broken", "broke", "break", "had broken"], + "explanation": "Осколки лежат на полу прямо сейчас (свежий результат), поэтому используется Present Perfect: 'has broken'." + } + ] + } +] + +# Units 9 through 15 +REST_OF_UNITS = [ + # ------------------------------------------------------------------------- + # Unit 9: Used to + # ------------------------------------------------------------------------- + { + "unit_num": 9, + "level": "A1-A2", + "category": "Past Tenses", + "title": "Used to (I used to do)", + "subtitle": "Привычки и состояния прошлого, которых больше нет в настоящем", + "golden_formula": "S + used to + V1\n(-) S + did not (didn't) use to + V1\n(?) Did + S + use to + V1?\n(I used to play tennis a lot, but now I prefer swimming)", + "cheatsheet_table": ( + "| Тип | Формула | Пример |\n" + "| :--- | :--- | :--- |\n" + "| **Утверждение (+)** | S + used to + V1 | *I used to live in Paris, but now I live in London.* |\n" + "| **Отрицание (-)** | S + didn't use to + V1 | *She didn't use to like coffee.* |\n" + "| **Вопрос (?)** | Did + S + use to + V1? | *Did you use to have long hair?* |\n" + "| **Состояния** | be, have, live, believe | *This building used to be a cinema.* |\n" + "| **НЕ путать с:** | be used to + -ing (привык к) | *I am used to waking up early (я привык).* |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Конструкция `used to` выражает **прошлые привычки или постоянные состояния, которые сейчас изменились или прекратились**.\n\n" + "### ⚠️ Частые ошибки (Common Pitfalls)\n" + "1. В отрицаниях и вопросах `used` теряет букву -d из-за вспомогательного did: *didn't use to*, *did you use to*.\n" + "2. Для настоящего времени `used to` не существует! Если вы делаете что-то сейчас регулярно, используйте Present Simple с usually (*I usually play tennis*, а не *I use to play*)." + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Выпишите формулу 'used to + V1' и подчеркните: 'Только для прошлого, которого БОЛЬШЕ НЕТ'.\n" + "2. Запишите отрицательную форму: 'didn't use to' (без буквы d!).\n" + "3. Составьте от руки 2 контраста из вашей биографии:\n" + " - 'When I was younger, I used to [привычка детства], but now I [что делаете сейчас].'\n" + " - 'I didn't use to like [еда/занятие: olives / waking up early], but now I love it.'" + ), + "contrast_explanation": [ + { + "situation_a": "Прошлая привычка (Used to)", + "example_a": "I used to smoke 20 cigarettes a day, but I gave up 3 years ago.", + "trans_a": "Я раньше выкуривал по 20 сигарет в день, но бросил 3 года назад.", + "situation_b": "Привычка в настоящем (Present Simple + usually)", + "example_b": "I usually drink green tea in the morning.", + "trans_b": "Я обычно пью зелёный чай по утрам (настоящее время, used to применять нельзя!).", + "key_difference": "Used to существует ТОЛЬКО для прошлого. Для настоящего времени используется usually + V1." + } + ], + "exercises": [ + { + "sentence": "My grandfather ___ to work by bicycle, but now he takes the bus.", + "target": "used to go", + "clue": "Прошлая привычка, которая прекратилась ('but now he takes')", + "options": ["used to go", "uses to go", "was going", "is used to go"], + "explanation": "Для описания привычки в прошлом, сменившейся в настоящем, используется конструкция 'used to + V1': 'used to go'." + }, + { + "sentence": "We ___ use to have a dishwasher when I was growing up.", + "target": "didn't", + "clue": "Отрицательная форма конструкции 'use to' в прошлом", + "options": ["didn't", "don't", "weren't", "haven't"], + "explanation": "Отрицание строится через 'didn't use to': 'We didn't use to have'." + }, + { + "sentence": "Did you ___ to live in Montreal before moving here?", + "target": "use", + "clue": "Вопрос с Did: буква -d у слова used исчезает", + "options": ["use", "used", "using", "uses"], + "explanation": "После вспомогательного 'Did' форма глагола пишется без -d: 'Did you use to live...?'." + }, + { + "sentence": "This street ___ to be much quieter before the shopping mall opened.", + "target": "used", + "clue": "Прошлое состояние (улица была тише)", + "options": ["used", "was used", "use", "is using"], + "explanation": "Утверждение о прошлом состоянии улицы: 'used to be quieter'." + }, + { + "sentence": "Now I live in a quiet village, but I ___ in a crowded capital city.", + "target": "used to live", + "clue": "Контраст: сейчас в деревне, а раньше жил в столице", + "options": ["used to live", "use to live", "am living", "was lived"], + "explanation": "Контраст настоящего и прошлого: 'used to live in a crowded capital city'." + } + ] + }, + + # ------------------------------------------------------------------------- + # Unit 10: Future + # ------------------------------------------------------------------------- + { + "unit_num": 10, + "level": "B1-B2", + "category": "Future", + "title": "Future: Will vs Going to vs Present Continuous", + "subtitle": "Три главных будущих времени: спонтанное решение, намерение и железобетонная договорённость", + "golden_formula": "1. WILL + V1: Spontaneous decision NOW ('I will answer the door') / Prediction\n2. BE GOING TO + V1: Prior intention / Obvious evidence ('Look at those black clouds, it is going to rain')\n3. PRESENT CONTINUOUS: Fixed arrangement with date & other people ('I am flying to Paris tomorrow')", + "cheatsheet_table": ( + "| Конструкция | Значение | Триггер выбора | Пример |\n" + "| :--- | :--- | :--- | :--- |\n" + "| **WILL + V1** | Спонтанное решение в секунду речи | Решил прямо сейчас, обещание, предложение помощи | *The phone is ringing. I'll get it!* |\n" + "| **BE GOING TO + V1** | Заранее задуманное намерение | Решил ДО разговора, есть очевидные улики | *I am going to buy a new car next month.* |\n" + "| **BE GOING TO (улики)** | Неизбежный прогноз по фактам | Вижу глазами прямо сейчас | *Look at those clouds! It's going to rain.* |\n" + "| **PRESENT CONTINUOUS** | Железобетонная договоренность | Куплены билеты, назначена встреча с людьми | *I'm meeting Alice at 7 PM at the cafe.* |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "В английском языке будущее время выбирается строго по степени готовности плана:\n" + "1. **Внезапная мысль сейчас**: *«I'll carry that heavy bag for you»* (никто не планировал заранее).\n" + "2. **Личное намерение**: *«I am going to sell my old bike»* (я уже решил для себя, но покупателя пока нет).\n" + "3. **Фиксированная договоренность**: *«I am having dinner with Sarah tonight»* (мы с Сарой уже договорились о времени и столике)." + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Нарисуйте 3 колонки: 'Will (в эту секунду)', 'Going to (задумал заранее)', 'Present Continuous (договорился с людьми/билеты)'.\n" + "2. Составьте от руки 3 предложения о вашем будущем:\n" + " - [Спонтанное решение/обещание] I will call you as soon as [действие]...\n" + " - [План-намерение] This weekend, I am going to [отдохнуть / убраться]...\n" + " - [Договоренность на этой неделе] On Friday, I am meeting [имя/коллеги] at [время]..." + ), + "contrast_explanation": [ + { + "situation_a": "Спонтанное решение в момент речи (Will)", + "example_a": "We don't have any milk. — Really? I'll go and get some.", + "trans_a": "У нас нет молока. — Правда? Я пойду куплю (узнал только что и решил сию секунду).", + "situation_b": "План был продуман заранее (Going to)", + "example_b": "We don't have any milk. — I know. I am going to buy some on my way home.", + "trans_b": "У нас нет молока. — Я знаю. Я как раз собираюсь купить его по пути домой.", + "key_difference": "Если решение принято только что в разговоре — Will; если о проблеме знали заранее — Going to." + } + ], + "exercises": [ + { + "sentence": "Have you decided what to do tonight? — Yes, I ___ dinner with my boss at 8 PM.", + "target": "am having", + "clue": "Зафиксированная договорённость со временем и конкретным человеком", + "options": ["am having", "will have", "have", "going to have"], + "explanation": "Назначенное время (at 8 PM) и договорённость с другим человеком выражаются через Present Continuous: 'am having'." + }, + { + "sentence": "That box looks very heavy! I ___ you carry it upstairs.", + "target": "will help", + "clue": "Спонтанное предложение помощи в момент речи", + "options": ["will help", "am helping", "help", "going to help"], + "explanation": "Спонтанное решение помочь, принятое в секунду речи: 'I will help you'." + }, + { + "sentence": "Look at that cyclist! He is not watching the road and he ___ crash.", + "target": "is going to", + "clue": "Прогноз на основе очевидных физических улик прямо перед глазами", + "options": ["is going to", "will", "is", "shall"], + "explanation": "Прогноз на основе явных внешних улик прямо сейчас строится через 'be going to': 'is going to crash'." + }, + { + "sentence": "I have saved enough money. Next spring I ___ learn how to pilot a drone.", + "target": "am going to", + "clue": "Личное заранее обдуманное намерение", + "options": ["am going to", "will", "am", "would"], + "explanation": "Заранее продуманное решение и накопленные деньги указывают на намерение: 'am going to learn'." + }, + { + "sentence": "I promise I ___ tell anyone your secret.", + "target": "won't", + "clue": "Обещание (Promise) выражается через will / won't", + "options": ["won't", "am not going to", "don't", "haven't"], + "explanation": "Обещания (I promise...) традиционно строятся со словом will / won't: 'I won't tell anyone'." + } + ] + }, + + # ------------------------------------------------------------------------- + # Unit 11: Modals + # ------------------------------------------------------------------------- + { + "unit_num": 11, + "level": "B1-B2", + "category": "Modals", + "title": "Modal Verbs: Must, Have to, Should", + "subtitle": "Обязанность, закон, совет и критическая разница между Mustn't и Don't have to", + "golden_formula": "MUST: Personal feeling of obligation ('I must call my mom')\nHAVE TO: External rule, law or necessity ('I have to wear a safety helmet')\nSHOULD: Friendly recommendation / good idea ('You should get some sleep')\nCRITICAL CONTRAST:\nMustn't = FORBIDDEN! Do not do it! (Ты не должен / Запрещено!)\nDon't have to = NO NEED. You can do it if you want (Не обязательно / Нет нужды)", + "cheatsheet_table": ( + "| Модальный глагол | Значение | Пример |\n" + "| :--- | :--- | :--- |\n" + "| **MUST** | Личное внутреннее убеждение говорящего | *I must finish this book today.* |\n" + "| **HAVE TO** | Внешний закон, приказ руководства | *Employees have to arrive by 9 AM.* |\n" + "| **SHOULD** | Совет, рекомендация | *You should see a doctor about that cough.* |\n" + "| **MUSTN'T** | ⛔ КАТЕГОРИЧЕСКИЙ ЗАПРЕТ | *You mustn't touch this wire. It's live!* |\n" + "| **DON'T HAVE TO** | 🟢 НЕТ НЕОБХОДИМОСТИ (можно, но не нужно) | *Tomorrow is Sunday. We don't have to get up early.* |\n" + "| **Прошедшее время** | В прошлом must превращается в HAD TO | *Yesterday I had to stay late at work.* |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Модальные глаголы показывают отношение говорящего к действию. Главная опасность здесь кроется в отрицаниях:\n" + "- `You mustn't do that!` = **ЭТО ЗАПРЕЩЕНО!** (Это опасно или незаконно).\n" + "- `You don't have to do that.` = **ЭТО НЕОБЯЗАТЕЛЬНО.** (Хочешь — делай, не хочешь — не делай, принуждения нет).\n\n" + "### ⏱️ Прошедшее время\n" + "У глагола `must` нет формы прошедшего времени! Если нужно сказать «я должен был сделать это вчера», используется форма **HAD TO**:\n" + "- *Yesterday I had to walk home because my car broke down.*" + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Нарисуйте знак 'STOP' рядом со словом 'MUSTN'T (ЗАПРЕЩЕНО)' и зеленую галочку рядом с 'DON'T HAVE TO (НЕ ОБЯЗАТЕЛЬНО)'.\n" + "2. Запишите правило: 'В прошедшем времени вместо must ВСЕГДА используется had to'.\n" + "3. Запишите от руки 3 правила вашей рабочей жизни:\n" + " - [Внешнее требование] At work, I have to [приходить вовремя / носить пропуск]...\n" + " - [Что необязательно] At the weekend, I don't have to [set an alarm / wear a suit]...\n" + " - [Совет себе] I should [drink more water / go to bed earlier]..." + ), + "contrast_explanation": [ + { + "situation_a": "Категорический запрет (Mustn't)", + "example_a": "You mustn't park here. It is an emergency exit.", + "trans_a": "Здесь нельзя парковаться. Это пожарный выход (строжайший запрет).", + "situation_b": "Отсутствие необходимости (Don't have to)", + "example_b": "Parking is free today. You don't have to pay.", + "trans_b": "Парковка сегодня бесплатная. Тебе не обязательно платить.", + "key_difference": "Mustn't означает запрет; Don't have to означает отсутствие необходимости." + } + ], + "exercises": [ + { + "sentence": "You ___ tell the password to anyone under any circumstances. It's confidential.", + "target": "mustn't", + "clue": "Категорический запрет на раскрытие пароля", + "options": ["mustn't", "don't have to", "shouldn't", "needn't"], + "explanation": "Строгий запрет разглашать конфиденциальный пароль: 'mustn't tell'." + }, + { + "sentence": "The museum admission is free on Thursdays, so you ___ pay to enter.", + "target": "don't have to", + "clue": "Вход бесплатный, поэтому платить нет необходимости", + "options": ["don't have to", "mustn't", "can't", "shouldn't"], + "explanation": "Поскольку вход бесплатный, платить не требуется (нет необходимости): 'don't have to pay'." + }, + { + "sentence": "Yesterday my computer crashed, so I ___ re-type the whole document.", + "target": "had to", + "clue": "Прошедшее время от глагола обязательства ('вчера пришлось')", + "options": ["had to", "must", "must have", "have to"], + "explanation": "У 'must' нет формы прошедшего времени; для прошедшего времени используется 'had to': 'I had to re-type'." + }, + { + "sentence": "You look completely exhausted. I think you ___ take a couple of days off.", + "target": "should", + "clue": "Дружеский совет и рекомендация ('тебе следует')", + "options": ["should", "must", "have to", "had to"], + "explanation": "Совет и рекомендация выражаются через модальный глагол 'should': 'you should take a couple of days off'." + }, + { + "sentence": "In most countries, passengers ___ wear seatbelts in the car by law.", + "target": "have to", + "clue": "Внешнее предписание закона государства", + "options": ["have to", "should", "might", "would"], + "explanation": "Обязательство, наложенное законом государства, выражается через 'have to': 'passengers have to wear seatbelts'." + } + ] + }, + + # ------------------------------------------------------------------------- + # Unit 12: Conditionals + # ------------------------------------------------------------------------- + { + "unit_num": 12, + "level": "B1-B2", + "category": "Conditionals", + "title": "First vs Second Conditional (If I do vs If I did)", + "subtitle": "Реальное будущее против воображаемых фантазий и конструкция If I were you", + "golden_formula": "1st CONDITIONAL (Real Future):\nIf + Present Simple, will + V1\n(If it rains tomorrow, we will stay at home)\n\n2nd CONDITIONAL (Unreal / Imaginary Present or Future):\nIf + Past Simple, would + V1\n(If I had a million dollars, I would travel around the world)\nNOTE: If I were you, I would... (быть на твоем месте)", + "cheatsheet_table": ( + "| Тип условия | Часть с IF (Условие) | Главная часть (Результат) | Реальность ситуации |\n" + "| :--- | :--- | :--- | :--- |\n" + "| **First (1-й)** | **If + Present Simple** | **will + V1** | Реальная возможность в будущем (вероятность 70-90%) |\n" + "| *Пример 1-го* | *If I pass the exam...* | *...I will celebrate with friends.* | Вполне реально сдать экзамен. |\n" + "| **Second (2-й)** | **If + Past Simple** | **would + V1** | Воображаемая / маловероятная фантазия (вероятность 1-5%) |\n" + "| *Пример 2-го* | *If I won the lottery...* | *...I would buy an island.* | Мечты и фантазии. |\n" + "| **Совет** | *If I were you...* | *...I would accept the offer.* | «На твоём месте я бы...» |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Вся разница — в **степени веры говорящего в реальность события**:\n" + "- *If I find her number, I will call her.* (У меня есть надежда найти её записную книжку — реальный 1st Cond).\n" + "- *If I found a wallet in the street, I would take it to the police.* (Я прямо сейчас фантазирую о гипотетической ситуации — 2nd Cond).\n\n" + "### ⚠️ Табу условных предложений\n" + "**НИКОГДА не ставьте will или would сразу после слова IF**:\n" + "- *If it will rain tomorrow...* ❌ → *If it rains tomorrow...* ✅.\n" + "- *If I would have money...* ❌ → *If I had money...* ✅.\n\n" + "### 🎩 Исключение: Were вместо Was\n" + "В формальном английском и для советов во 2-м условном глагол to be для всех лиц принимает форму `were`:\n" + "- *If I were you, I would take that job.* (На твоём месте я бы согласился на эту работу)." + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Запишите формулы: 1st (If + V1, will + V1) и 2nd (If + V2, would + V1).\n" + "2. Обведите красным маркером: 'ПОСЛЕ IF СЛОВА WILL И WOULD НЕ СТАВЯТСЯ!'.\n" + "3. Составьте от руки два предложения:\n" + " - [Реальный план на завтра] If the weather is good tomorrow, I will [прогуляться / поехать за город]...\n" + " - [Воображаемая мечта] If I had [много денег / свободного времени], I would [купить дом / объехать мир]..." + ), + "contrast_explanation": [ + { + "situation_a": "Реальное будущее (1st Conditional)", + "example_a": "If you study hard, you will pass the exam.", + "trans_a": "Если ты будешь усердно учиться, ты сдашь экзамен (реальный прогноз на будущее).", + "situation_b": "Нереальная фантазия (2nd Conditional)", + "example_b": "If I knew Spanish, I would move to Barcelona.", + "trans_b": "Если бы я знал испанский, я бы переехал в Барселону (но я его не знаю прямо сейчас).", + "key_difference": "1st = реальное будущее; 2nd = гипотетическое предположение, противоположное фактам." + } + ], + "exercises": [ + { + "sentence": "If the flight ___ delayed, we will call you immediately.", + "target": "is", + "clue": "В части с 'If' в 1-м условном используется Present Simple (НЕ will!)", + "options": ["is", "will be", "would be", "was"], + "explanation": "В условной придаточной части 1-го типа (после 'If') используется Present Simple: 'If the flight is delayed'." + }, + { + "sentence": "If I had enough free time, I ___ learn how to play the piano.", + "target": "would", + "clue": "В главной части 2-го типа условных используется would + V1", + "options": ["would", "will", "can", "am"], + "explanation": "Придаточная часть с 'If I had' указывает на 2-й условный тип, в главной части требуется 'would'." + }, + { + "sentence": "If I ___ you, I wouldn't invest in that risky startup.", + "target": "were", + "clue": "Устойчивая конструкция совета: 'If I were you'", + "options": ["were", "am", "was", "would be"], + "explanation": "Для выражения совета 'На твоём месте' традиционно используется форма 'If I were you'." + }, + { + "sentence": "If you don't wear a warm coat today, you ___ catch a cold.", + "target": "will", + "clue": "Реальное предупреждение о последствиях в будущем (1st Conditional)", + "options": ["will", "would", "did", "are"], + "explanation": "Реальное последствие в будущем выражается через 'will + V1': 'you will catch a cold'." + }, + { + "sentence": "What ___ you do if you found a wallet on the street with $500 inside?", + "target": "would", + "clue": "Вопрос о гипотетической ситуации (If you found...)", + "options": ["would", "will", "did", "do"], + "explanation": "Воображаемая гипотетическая ситуация (If you found = 2nd Conditional) требует в вопросе 'would you do?'." + } + ] + }, + + # ------------------------------------------------------------------------- + # Unit 13: Passive Voice + # ------------------------------------------------------------------------- + { + "unit_num": 13, + "level": "B1-B2", + "category": "Passive Voice", + "title": "Passive Voice (It is done / It was done)", + "subtitle": "Когда результат важнее исполнителя: пассивные конструкции и предлог By", + "golden_formula": "GENERAL FORMULA: S + BE (в нужном времени) + V3 (Past Participle)\nPresent Simple Passive: am / is / are + V3 (The office is cleaned every day)\nPast Simple Passive: was / were + V3 (The bridge was built in 1905)\nFuture Simple Passive: will be + V3 (The report will be sent tomorrow)\nPresent Continuous Passive: is / are being + V3 (My car is being repaired)\nBY + AGENT: используется только если важно указать автора ('written by Shakespeare')", + "cheatsheet_table": ( + "| Время | Активный залог (Active) | Пассивный залог (Passive) |\n" + "| :--- | :--- | :--- |\n" + "| **Present Simple** | *Somebody cleans the room.* | *The room **is cleaned** every day.* |\n" + "| **Past Simple** | *Somebody built the bridge.* | *The bridge **was built** in 2010.* |\n" + "| **Present Continuous** | *They are repairing the road.* | *The road **is being repaired** right now.* |\n" + "| **Present Perfect** | *Someone has stolen my bike.* | *My bike **has been stolen**.* |\n" + "| **Future Simple** | *We will deliver the package.* | *The package **will be delivered** tomorrow.* |\n" + "| **Модальные глаголы** | *You must sign the contract.* | *The contract **must be signed**.* |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Пассивный залог применяется в трёх ключевых ситуациях:\n" + "1. **Исполнитель неизвестен**: *My bicycle has been stolen.* (Кто украл — мы не знаем).\n" + "2. **Исполнитель очевиден или не важен**: *The criminal was arrested.* (Очевидно, что полицией).\n" + "3. **Фокус на объекте или событии**: в новостях, научных статьях, инструкциях и IT-системах (*A new database was created*).\n\n" + "### ⚙️ Инструмент: Предлог By vs With\n" + "- `By` указывает на одушевлённого создателя/исполнителя: *The portrait was painted **by** Picasso*.\n" + "- `With` указывает на инструмент или материал: *The envelope was opened **with** a knife*." + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Запишите формулу пассива: 'BE + V3'.\n" + "2. Запишите две самые частые формы: 'is/are done' (настоящее) и 'was/were done' (прошедшее).\n" + "3. Составьте от руки 3 примера из сферы технологий или быта:\n" + " - This app was developed in [год/страна]...\n" + " - Emails are sent every day to [клиенты/коллеги]...\n" + " - The project will be finished next [месяц/неделя]..." + ), + "contrast_explanation": [ + { + "situation_a": "Активный залог (фокус на исполнителе)", + "example_a": "Alexander Bell invented the telephone in 1876.", + "trans_a": "Александр Белл изобрёл телефон в 1876 году (Белл — главный герой предложения).", + "situation_b": "Пассивный залог (фокус на изобретении)", + "example_b": "The telephone was invented in 1876 by Alexander Bell.", + "trans_b": "Телефон был изобретён в 1876 году Александром Беллом (телефон — в центре внимания).", + "key_difference": "В пассиве объект действия встаёт на место подлежащего, а исполнитель уходит на второй план." + } + ], + "exercises": [ + { + "sentence": "This ancient castle ___ by thousands of tourists every summer.", + "target": "is visited", + "clue": "Present Simple пассив: замок посещается регулярно каждое лето", + "options": ["is visited", "was visited", "visits", "is visiting"], + "explanation": "Регулярное действие в настоящем ('every summer') в пассивном залоге требует 'is/are + V3': 'is visited'." + }, + { + "sentence": "The novel '1984' ___ by George Orwell in 1949.", + "target": "was written", + "clue": "Past Simple пассив с точной датой в прошлом", + "options": ["was written", "is written", "wrote", "has written"], + "explanation": "Конкретная дата в прошлом ('in 1949') и пассивное действие требуют Past Simple Passive: 'was written'." + }, + { + "sentence": "Please take another seat. This table ___ reserved for a private party.", + "target": "is", + "clue": "Стол зарезервирован прямо сейчас (Present Simple Passive)", + "options": ["is", "was", "are", "were"], + "explanation": "Для 'This table' (it) форма пассивного залога в настоящем времени: 'is reserved'." + }, + { + "sentence": "All flight tickets ___ electronically via email tomorrow morning.", + "target": "will be sent", + "clue": "Future Simple Passive: билеты будут отправлены завтра", + "options": ["will be sent", "will send", "are sent", "were sent"], + "explanation": "Будущее действие в пассивном залоге ('tomorrow morning') строится через 'will be + V3': 'will be sent'." + }, + { + "sentence": "The software bug ___ by the engineering team right now.", + "target": "is being fixed", + "clue": "Present Continuous Passive: процесс исправления идёт прямо в эту минуту", + "options": ["is being fixed", "is fixing", "was fixed", "fixes"], + "explanation": "Процесс в настоящем времени ('right now') в пассиве строится через 'is being + V3': 'is being fixed'." + } + ] + }, + + # ------------------------------------------------------------------------- + # Unit 14: Articles + # ------------------------------------------------------------------------- + { + "unit_num": 14, + "level": "A1-A2", + "category": "Articles", + "title": "Articles: A/An vs The vs Zero Article", + "subtitle": "Определённость, первое упоминание, уникальные объекты и абстрактные понятия", + "golden_formula": "A / AN: One of many / Unspecified singular countable ('I bought a book')\nTHE: Specific item known to listener / Unique object ('The book was interesting' / 'The Sun')\nZERO ARTICLE (Ø): Plurals & Uncountables in general ('I love dogs' / 'Music is art')", + "cheatsheet_table": ( + "| Артикль | Когда применять | Примеры |\n" + "| :--- | :--- | :--- |\n" + "| **A / AN** | Исчисляемое в ед. ч., первое упоминание, профессия | *I have **a** dog. She is **an** architect.* |\n" + "| **THE** | Второе упоминание, слушатель знает о чём речь | *I bought a laptop. **The** laptop is fast.* |\n" + "| **THE (уникальность)** | Единственный в мире объект | *the Sun, the Moon, the Internet, the sky* |\n" + "| **THE (география)** | Реки, моря, океаны, группы островов/штатов | *the Atlantic, the Thames, the USA, the UK* |\n" + "| **ZERO (Ø)** | Множественное число и неисчисляемые ВООБЩЕ | *Cats love milk. Gold is expensive.* |\n" + "| **ZERO (география)** | Города, страны (в ед. ч.), улицы, континенты | *London, France, Oxford Street, Europe* |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "Вся система артиклей строится на простом вопросе:\n" + "**«Понимает ли собеседник, о каком КОНКРЕТНО объекте я говорю?»**\n" + "- *Pass me a pen.* = Дай мне любую ручку, мне всё равно какую.\n" + "- *Pass me the pen.* = Дай мне вон ту конкретную ручку, которая лежит перед тобой.\n\n" + "### ⚠️ Частые ошибки (Common Pitfalls)\n" + "1. Нельзя ставить `a/an` перед множественным числом или неисчисляемыми: *an advice* ❌ → *advice / a piece of advice* ✅.\n" + "2. Обобщения строятся с нулевым артиклем: *I love the dogs* (люблю конкретно этих трёх собак во дворе) vs *I love dogs* (люблю собак как биологический вид)." + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Нарисуйте 3 колонки: 'A/An (один любой из многих)', 'The (тот самый конкретный / уникальный)', 'Ø (все в целом)'.\n" + "2. Запишите связку из двух предложений:\n" + " - 'I ordered a coffee and a croissant. The coffee was hot and the croissant was fresh.'\n" + "3. Запишите от руки 2 примера об уникальных вещах: 'The Sun rises in the east' и 'I use the Internet every day'." + ), + "contrast_explanation": [ + { + "situation_a": "Первое упоминание объекта (A / An)", + "example_a": "Yesterday I watched a movie.", + "trans_a": "Вчера я посмотрел фильм (какой-то один фильм, собеседник пока не знает какой).", + "situation_b": "Повторное упоминание того же объекта (The)", + "example_b": "The movie was directed by Christopher Nolan.", + "trans_b": "Этот фильм снял Кристофер Нолан (собеседник уже понимает, о каком именно фильме речь).", + "key_difference": "При первом вводе предмета в диалог используется a/an; при повторном — the." + } + ], + "exercises": [ + { + "sentence": "Can you please close ___ window? It is getting cold in here.", + "target": "the", + "clue": "Собеседник видит конкретное окно в комнате", + "options": ["the", "a", "an", "no article"], + "explanation": "Речь идёт о конкретном окне в данной комнате, понятном обоим собеседникам: 'close the window'." + }, + { + "sentence": "Paris is ___ capital city of France.", + "target": "the", + "clue": "У Франции только одна столица (уникальный статус)", + "options": ["the", "a", "an", "no article"], + "explanation": "Столица у страны одна-единственная (уникальный объект), поэтому используется 'the capital city'." + }, + { + "sentence": "My sister wants to become ___ software engineer.", + "target": "an", + "clue": "Профессия начинается с гласного звука [e]", + "options": ["an", "a", "the", "no article"], + "explanation": "Перед названиями профессий в единственном числе ставится a/an. Слово 'software' начинается с согласной? Но здесь 'software engineer' -> перед 'software' ставится 'a'! Подождите, 'software engineer' начинается на [s], поэтому 'a software engineer'!" + }, + { + "sentence": "___ apples are rich in fiber and vitamins.", + "target": "no article", + "clue": "Яблоки как класс фруктов в целом во множественном числе", + "options": ["no article", "The", "An", "A"], + "explanation": "Когда мы говорим о вещах во множественном числе в общем смысле, артикль не ставится: 'Apples are rich...'." + }, + { + "sentence": "We spent our vacation relaxing on the coast of ___ Black Sea.", + "target": "the", + "clue": "Перед названиями морей всегда ставится определённый артикль The", + "options": ["the", "a", "an", "no article"], + "explanation": "С названиями морей, океанов и рек всегда употребляется определённый артикль: 'the Black Sea'." + } + ] + }, + + # ------------------------------------------------------------------------- + # Unit 15: Gerund vs Infinitive + # ------------------------------------------------------------------------- + { + "unit_num": 15, + "level": "B1-B2", + "category": "Gerund & Infinitive", + "title": "Gerund vs Infinitive (doing vs to do)", + "subtitle": "Две формы глагола: списки управления, правило предлогов и изменение смысла", + "golden_formula": "VERB + GERUND (-ing): enjoy, avoid, mind, finish, suggest, consider, risk, postpone\nVERB + INFINITIVE (to + V1): decide, plan, hope, promise, refuse, manage, agree, afford\nRULE: AFTER ANY PREPOSITION → ALWAYS GERUND! (interested in learning, good at coding)\nDUAL MEANING:\nstop doing (бросить навсегда) vs stop to do (остановиться, чтобы сделать)\nremember doing (помнить событие из прошлого) vs remember to do (не забыть сделать)", + "cheatsheet_table": ( + "| Категория | Глаголы управления | Пример |\n" + "| :--- | :--- | :--- |\n" + "| **Только Герундий (-ing)** | *enjoy, avoid, mind, suggest, finish, keep* | *I enjoy reading science fiction.* |\n" + "| **Только Инфинитив (to do)** | *decide, hope, plan, promise, offer, refuse* | *We decided to move to a new apartment.* |\n" + "| **После предлогов (100%)** | *interested in, good at, afraid of, instead of* | *He is very good at solving problems.* |\n" + "| **STOP (разница смысла)** | *stop smoking* (бросить вредную привычку) | *stop to smoke* (остановиться, чтобы закурить) |\n" + "| **REMEMBER (разница)** | *remember locking* (помню, как закрывал) | *remember to lock* (не забудь закрыть дверь) |" + ), + "detailed_notes": ( + "### 🎯 Суть правила и логика носителя языка\n" + "1. **Герундий (-ing)** часто несёт оттенок реального жизненного опыта, процесса или удовольствия: *I enjoy cooking*.\n" + "2. **Инфинитив (to do)** ориентирован в будущее: на цель, намерение или решение: *I decided to cook dinner*.\n\n" + "### ⚓ Железное правило предлогов\n" + "Если после предлога (`in`, `on`, `at`, `for`, `about`, `before`, `after`, `instead of`) идёт глагол, он **ОБЯЗАН быть в форме герундия (-ing)**:\n" + "- *Thank you for helping me.* (НЕ *for help*).\n" + "- *She left without saying goodbye.*" + ), + "journaling_prompt": ( + "📓 ПЛАН ЗАПИСИ В БУМАЖНУЮ ТЕТРАДЬ:\n" + "1. Нарисуйте две колонки: 'Глагол + -ing' (enjoy, avoid, mind, finish) и 'Глагол + to do' (decide, hope, plan, promise).\n" + "2. Запишите в рамку закон: 'ПОСЛЕ ЛЮБОГО ПРЕДЛОГА — ВСЕГДА ТОЛЬКО -ING!'.\n" + "3. Составьте от руки 3 предложения:\n" + " - [Что нравится] I really enjoy [reading / coding / traveling]...\n" + " - [Что решили сделать] Recently, I decided to [learn English / exercise regularly]...\n" + " - [Конструкция с предлогом] I am interested in [improving my grammar / learning AI]..." + ), + "contrast_explanation": [ + { + "situation_a": "Прекращение действия навсегда (Stop + -ing)", + "example_a": "He stopped smoking five years ago.", + "trans_a": "Он бросил курить пять лет назад (действие прекращено навсегда).", + "situation_b": "Пауза ради другой цели (Stop + to do)", + "example_b": "He was driving for three hours, then stopped to smoke a cigarette.", + "trans_b": "Он был за рулём три часа, затем остановил машину, чтобы выкурить сигарету.", + "key_difference": "Stop + -ing = бросить привычку; Stop + to do = сделать паузу ради другой цели." + } + ], + "exercises": [ + { + "sentence": "I really enjoy ___ audiobooks during my daily commute.", + "target": "listening to", + "clue": "Глагол enjoy требует после себя герундий (-ing)", + "options": ["listening to", "to listen to", "listen to", "listened to"], + "explanation": "После глагола 'enjoy' всегда используется герундий: 'enjoy listening to'." + }, + { + "sentence": "We have decided ___ our summer vacation in Spain.", + "target": "to spend", + "clue": "Глагол decide требует после себя инфинитив с частицей to", + "options": ["to spend", "spending", "spend", "spent"], + "explanation": "После глагола 'decide' используется инфинитив с частицей to: 'decided to spend'." + }, + { + "sentence": "She is interested in ___ a new programming language.", + "target": "learning", + "clue": "После предлога 'in' глагол обязан стоять в форме герундия (-ing)", + "options": ["learning", "to learn", "learn", "learned"], + "explanation": "Железное правило: после любого предлога (здесь 'in') всегда используется герундий: 'interested in learning'." + }, + { + "sentence": "Please remember ___ the front door before you go to bed.", + "target": "to lock", + "clue": "Не забыть сделать действие в будущем (remember to do)", + "options": ["to lock", "locking", "lock", "locked"], + "explanation": "Напоминание о необходимости совершить действие в будущем: 'remember to lock'." + }, + { + "sentence": "You should avoid ___ heavily before going to sleep.", + "target": "eating", + "clue": "Глагол avoid требует после себя форму на -ing", + "options": ["eating", "to eat", "eat", "eaten"], + "explanation": "После глагола 'avoid' (избегать) используется форма герундия: 'avoid eating'." + } + ] + } +] + +def main(): + # Fix Unit 14 Exercise 3 clue/options for consistency + all_final_units = UNITS + MORE_UNITS + REST_OF_UNITS + # Unit 14 Ex 3 fix + for u in all_final_units: + if u["unit_num"] == 14: + u["exercises"][2] = { + "sentence": "My sister wants to become ___ architect in a design studio.", + "target": "an", + "clue": "Слово 'architect' начинается с гласного звука [ɑː]", + "options": ["an", "a", "the", "no article"], + "explanation": "Перед названием профессии в единственном числе, начинающимся с гласного звука ('architect'), ставится артикль 'an'." + } + + print(f"Total curated units compiled: {len(all_final_units)}") + seeds_path = Path("data/seeds/grammar_units.json") + seeds_path.parent.mkdir(parents=True, exist_ok=True) + with open(seeds_path, "w", encoding="utf-8") as f: + json.dump(all_final_units, f, indent=2, ensure_ascii=False) + print(f"Saved rich seeds to {seeds_path} ({seeds_path.stat().st_size} bytes)") + +if __name__ == "__main__": + main() diff --git a/tests/test_api.py b/tests/test_api.py index c698750..eeb4958 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1511,8 +1511,18 @@ def test_grammar_engine_and_handwritten_journaling(): assert len(u_data["contrasts"]) >= 1 assert "journaling_prompt" in u_data assert "тетрадь" in u_data["journaling_prompt"].lower() + assert "cheatsheet_table" in u_data + assert "|" in u_data["cheatsheet_table"] + assert "detailed_notes" in u_data + assert len(u_data["detailed_notes"]) > 100 + assert "###" in u_data["detailed_notes"] assert len(u_data["exercises"]) == 5 + # Check lookup by unit_num directly + num_res = client.get("/api/grammar/units/1") + assert num_res.status_code == 200 + assert num_res.json()["id"] == unit_1_id + ex0 = u_data["exercises"][0] assert len(ex0["options"]) == 4