- Implement robustSentenceSplit across reader.js and backend (miner.py, cefr.py) to prevent false cutoffs on honorifics (Mr., Mrs., Dr.), single-letter initials (John F. Kennedy), decimals, acronyms (U.S., U.K.), and abbreviations (No. 4, etc.) - Upgrade translation prompt to professional literary Russian, eliminating literal word-for-word translation and preserving titles/honorifics - Inject surrounding paragraph context into translation API to avoid out-of-context translations - Inject offline dictionary hints into LLM prompt for accurate contextual word meaning - Prefer qwen2.5:3b for higher translation fluency and fidelity - Purge truncated cache entries from sentence_translations and restore Card 30 (briefcase) with authentic full sentence - Bump Service Worker cache to notes-v6.0 - Add unit tests for robust sentence splitting, prompt formatting, and translation API
2454 lines
138 KiB
Python
2454 lines
138 KiB
Python
"""
|
||
CEFR Level Vocabulary Tests & Assessment Engine (A1, A2, B1, B2).
|
||
Oxford 3000 / 5000 based curated benchmark Cloze Tap questions.
|
||
100% offline, zero-dependency, pure Python stdlib + SQLite.
|
||
Features:
|
||
- Fast 1-tap Cloze Tap quiz format.
|
||
- Automated Gap Ingestion: mistakes automatically create/update vocabulary cards
|
||
with status 'learning' in the user's SRS active deck with level tags.
|
||
- Per-level progress tracking (mastered, learning, percentage).
|
||
"""
|
||
|
||
import re
|
||
import json
|
||
import sqlite3
|
||
import random
|
||
from typing import Dict, Any, List, Optional
|
||
from datetime import datetime
|
||
|
||
CEFR_LEVELS = ["A1", "A2", "B1", "B2"]
|
||
|
||
# Curated High-Yield CEFR Question Bank (Oxford 3000/5000)
|
||
# 65 items per level = 260 questions total
|
||
CURATED_CEFR_QUESTIONS: List[Dict[str, Any]] = [
|
||
# =========================================================================
|
||
# LEVEL A1 (Beginner: Daily life, basic items, common verbs & adjectives)
|
||
# =========================================================================
|
||
{
|
||
"level": "A1", "term": "expensive", "pos": "adjective", "phonetic": "/ɪkˈspen.sɪv/",
|
||
"translation": "дорогой (по цене)",
|
||
"sentence": "This watch is too ___ for me to buy right now.",
|
||
"options": ["expensive", "cheap", "simple", "clean"],
|
||
"explanation": "Expensive (дорогой) — имеет высокую стоимость. В контексте: слишком дорого, чтобы купить сейчас.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "weather", "pos": "noun", "phonetic": "/ˈweð.ər/",
|
||
"translation": "погода",
|
||
"sentence": "The ___ today is sunny and wonderfully warm.",
|
||
"options": ["weather", "season", "journey", "holiday"],
|
||
"explanation": "Weather (погода) — состояние атмосферы на данный момент (солнечно, тепло).",
|
||
},
|
||
{
|
||
"level": "A1", "term": "remember", "pos": "verb", "phonetic": "/rɪˈmem.bər/",
|
||
"translation": "помнить, вспоминать",
|
||
"sentence": "I cannot ___ his phone number without looking at my phone.",
|
||
"options": ["remember", "forget", "decide", "repeat"],
|
||
"explanation": "Remember (помнить) — удерживать информацию в памяти.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "careful", "pos": "adjective", "phonetic": "/ˈkeə.fəl/",
|
||
"translation": "осторожный, внимательный",
|
||
"sentence": "Be ___ when you cross the busy street!",
|
||
"options": ["careful", "boring", "dangerous", "wrong"],
|
||
"explanation": "Careful (осторожный) — обращающий внимание на безопасность.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "breakfast", "pos": "noun", "phonetic": "/ˈbrek.fəst/",
|
||
"translation": "завтрак",
|
||
"sentence": "She always eats eggs and toast for ___.",
|
||
"options": ["breakfast", "dinner", "kitchen", "uniform"],
|
||
"explanation": "Breakfast (завтрак) — первый утренний прием пищи.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "decide", "pos": "verb", "phonetic": "/dɪˈsaɪd/",
|
||
"translation": "решать, принимать решение",
|
||
"sentence": "We need to ___ where to go for our summer vacation.",
|
||
"options": ["decide", "invite", "listen", "travel"],
|
||
"explanation": "Decide (решать) — делать выбор между вариантами.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "village", "pos": "noun", "phonetic": "/ˈvɪl.ɪdʒ/",
|
||
"translation": "деревня, село",
|
||
"sentence": "My grandparents live in a quiet ___ in the mountains.",
|
||
"options": ["village", "airport", "hospital", "library"],
|
||
"explanation": "Village (деревня) — небольшой населенный пункт за городом.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "dangerous", "pos": "adjective", "phonetic": "/ˈdeɪn.dʒər.əs/",
|
||
"translation": "опасный",
|
||
"sentence": "Swimming in this stormy river is very ___.",
|
||
"options": ["dangerous", "exciting", "healthy", "wonderful"],
|
||
"explanation": "Dangerous (опасный) — способный причинить вред или травму.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "invite", "pos": "verb", "phonetic": "/ɪnˈvaɪt/",
|
||
"translation": "приглашать",
|
||
"sentence": "They want to ___ all their classmates to the birthday party.",
|
||
"options": ["invite", "address", "listen", "welcome"],
|
||
"explanation": "Invite (приглашать) — звать кого-то на мероприятие.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "borrow", "pos": "verb", "phonetic": "/ˈbɒr.əʊ/",
|
||
"translation": "одалживать, брать взаймы",
|
||
"sentence": "Can I ___ your pencil for a minute, please?",
|
||
"options": ["borrow", "lend", "spend", "repeat"],
|
||
"explanation": "Borrow (брать взаймы) — брать вещь во временное пользование.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "healthy", "pos": "adjective", "phonetic": "/ˈhel.θi/",
|
||
"translation": "здоровый, полезный для здоровья",
|
||
"sentence": "Eating fresh fruit and vegetables keeps your body ___.",
|
||
"options": ["healthy", "boring", "wrong", "famous"],
|
||
"explanation": "Healthy (здоровый) — способствующий хорошему самочувствию.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "journey", "pos": "noun", "phonetic": "/ˈdʒɜː.ni/",
|
||
"translation": "путешествие, поездка",
|
||
"sentence": "It was a long ___ by train across the entire country.",
|
||
"options": ["journey", "ticket", "minute", "station"],
|
||
"explanation": "Journey (путешествие, поездка) — передвижение из одного места в другое.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "simple", "pos": "adjective", "phonetic": "/ˈsɪm.pəl/",
|
||
"translation": "простой, несложный",
|
||
"sentence": "The recipe is very ___ and only takes ten minutes.",
|
||
"options": ["simple", "expensive", "dangerous", "careful"],
|
||
"explanation": "Simple (простой) — легкий для понимания или выполнения.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "foreign", "pos": "adjective", "phonetic": "/ˈfɒr.ən/",
|
||
"translation": "иностранный, зарубежный",
|
||
"sentence": "She enjoys learning ___ languages and studying their grammar.",
|
||
"options": ["foreign", "famous", "careful", "boring"],
|
||
"explanation": "Foreign (иностранный) — принадлежащий другой стране.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "neighbor", "pos": "noun", "phonetic": "/ˈneɪ.bər/",
|
||
"translation": "сосед",
|
||
"sentence": "Our next-door ___ has three friendly dogs.",
|
||
"options": ["neighbor", "student", "parent", "person"],
|
||
"explanation": "Neighbor (сосед) — человек, живущий рядом.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "exciting", "pos": "adjective", "phonetic": "/ɪkˈsaɪ.tɪŋ/",
|
||
"translation": "захватывающий, увлекательный",
|
||
"sentence": "Watching the championship final was really ___!",
|
||
"options": ["exciting", "boring", "wrong", "cheap"],
|
||
"explanation": "Exciting (захватывающий) — вызывающий сильные положительные эмоции.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "listen", "pos": "verb", "phonetic": "/ˈlɪs.ən/",
|
||
"translation": "слушать",
|
||
"sentence": "You should ___ carefully to the teacher's instructions.",
|
||
"options": ["listen", "invite", "decide", "repeat"],
|
||
"explanation": "Listen (слушать) — обращать слуховое внимание на речь или звук.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "hospital", "pos": "noun", "phonetic": "/ˈhɒs.pɪ.təl/",
|
||
"translation": "больница, госпиталь",
|
||
"sentence": "The doctor works in the largest city ___.",
|
||
"options": ["hospital", "airport", "station", "library"],
|
||
"explanation": "Hospital (больница) — медицинское учреждение для лечения больных.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "ticket", "pos": "noun", "phonetic": "/ˈtɪk.ɪt/",
|
||
"translation": "билет",
|
||
"sentence": "Don't forget to buy a metro ___ before entering.",
|
||
"options": ["ticket", "package", "message", "question"],
|
||
"explanation": "Ticket (билет) — документ на право проезда или посещения.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "boring", "pos": "adjective", "phonetic": "/ˈbɔː.rɪŋ/",
|
||
"translation": "скучный",
|
||
"sentence": "The lecture was so ___ that half the audience fell asleep.",
|
||
"options": ["boring", "exciting", "wonderful", "healthy"],
|
||
"explanation": "Boring (скучный) — не вызывающий интереса.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "airport", "pos": "noun", "phonetic": "/ˈeə.pɔːt/",
|
||
"translation": "аэропорт",
|
||
"sentence": "We arrived at the ___ two hours before our departure.",
|
||
"options": ["airport", "hospital", "station", "village"],
|
||
"explanation": "Airport (аэропорт) — комплекс для взлета, посадки и обслуживания самолетов.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "clothes", "pos": "noun", "phonetic": "/kləʊðz/",
|
||
"translation": "одежда",
|
||
"sentence": "He bought warm winter ___ because it was snowing outside.",
|
||
"options": ["clothes", "luggage", "tickets", "packages"],
|
||
"explanation": "Clothes (одежда) — предметы гардероба, надеваемые на тело.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "repeat", "pos": "verb", "phonetic": "/rɪˈpiːt/",
|
||
"translation": "повторять",
|
||
"sentence": "Could you please ___ that question? I didn't hear you.",
|
||
"options": ["repeat", "decide", "invite", "borrow"],
|
||
"explanation": "Repeat (повторять) — сказать или сделать что-то еще раз.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "famous", "pos": "adjective", "phonetic": "/ˈfeɪ.məs/",
|
||
"translation": "знаменитый, известный",
|
||
"sentence": "She is a very ___ actress known around the globe.",
|
||
"options": ["famous", "careful", "wrong", "simple"],
|
||
"explanation": "Famous (знаменитый) — широко известный многим людям.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "message", "pos": "noun", "phonetic": "/ˈmes.ɪdʒ/",
|
||
"translation": "сообщение",
|
||
"sentence": "He sent me a text ___ to confirm the meeting time.",
|
||
"options": ["message", "question", "address", "ticket"],
|
||
"explanation": "Message (сообщение) — переданная информация в письменном или голосовом виде.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "wonderful", "pos": "adjective", "phonetic": "/ˈwʌn.də.fəl/",
|
||
"translation": "замечательный, чудесный",
|
||
"sentence": "We had a ___ weekend walking by the lake.",
|
||
"options": ["wonderful", "dangerous", "boring", "wrong"],
|
||
"explanation": "Wonderful (чудесный) — приносящий огромное удовольствие или восхищение.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "station", "pos": "noun", "phonetic": "/ˈsteɪ.ʃən/",
|
||
"translation": "станция, вокзал",
|
||
"sentence": "The train arrived at the central railway ___ on schedule.",
|
||
"options": ["station", "airport", "hospital", "village"],
|
||
"explanation": "Station (станция, вокзал) — остановочный пункт поездов или автобусов.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "library", "pos": "noun", "phonetic": "/ˈlaɪ.brər.i/",
|
||
"translation": "библиотека",
|
||
"sentence": "Students go to the quiet ___ to read textbooks.",
|
||
"options": ["library", "hospital", "station", "airport"],
|
||
"explanation": "Library (библиотека) — учреждение для хранения и выдачи книг.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "package", "pos": "noun", "phonetic": "/ˈpæk.ɪdʒ/",
|
||
"translation": "посылка, пакет",
|
||
"sentence": "The courier delivered a heavy cardboard ___ to my door.",
|
||
"options": ["package", "ticket", "message", "minute"],
|
||
"explanation": "Package (посылка, сверток) — упакованный груз для доставки.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "travel", "pos": "verb", "phonetic": "/ˈtræv.əl/",
|
||
"translation": "путешествовать",
|
||
"sentence": "They plan to ___ across Europe during their holidays.",
|
||
"options": ["travel", "decide", "listen", "repeat"],
|
||
"explanation": "Travel (путешествовать) — совершать поездки в другие города или страны.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "address", "pos": "noun", "phonetic": "/əˈdres/",
|
||
"translation": "адрес",
|
||
"sentence": "Please write down your postal ___ on the delivery form.",
|
||
"options": ["address", "message", "question", "ticket"],
|
||
"explanation": "Address (адрес) — указание места жительства или нахождения здания.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "wrong", "pos": "adjective", "phonetic": "/rɒŋ/",
|
||
"translation": "неправильный, неверный",
|
||
"sentence": "I took the ___ bus and ended up in another neighborhood.",
|
||
"options": ["wrong", "simple", "healthy", "famous"],
|
||
"explanation": "Wrong (неправильный) — несоответствующий правде или правильному направлению.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "yesterday", "pos": "adverb", "phonetic": "/ˈjes.tə.deɪ/",
|
||
"translation": "вчера",
|
||
"sentence": "I bought some new shoes ___ afternoon.",
|
||
"options": ["yesterday", "tomorrow", "always", "together"],
|
||
"explanation": "Yesterday (вчера) — в день, предшествующий сегодняшнему.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "tomorrow", "pos": "adverb", "phonetic": "/təˈmɒr.əʊ/",
|
||
"translation": "завтра",
|
||
"sentence": "The bank will open again ___ morning at nine.",
|
||
"options": ["tomorrow", "yesterday", "always", "together"],
|
||
"explanation": "Tomorrow (завтра) — в день, следующий за сегодняшним.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "holiday", "pos": "noun", "phonetic": "/ˈhɒl.ə.deɪ/",
|
||
"translation": "праздник, отпуск",
|
||
"sentence": "We booked a sunny two-week ___ by the Mediterranean sea.",
|
||
"options": ["holiday", "journey", "station", "airport"],
|
||
"explanation": "Holiday (отпуск, праздник) — период отдыха от работы или учебы.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "uniform", "pos": "noun", "phonetic": "/ˈjuː.nɪ.fɔːm/",
|
||
"translation": "форма, униформа",
|
||
"sentence": "Police officers must wear a neat ___ on duty.",
|
||
"options": ["uniform", "clothes", "package", "ticket"],
|
||
"explanation": "Uniform (униформа) — установленная служебная форма одежды.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "between", "pos": "preposition", "phonetic": "/bɪˈtwiːn/",
|
||
"translation": "между",
|
||
"sentence": "The pharmacy is situated ___ the bakery and the bank.",
|
||
"options": ["between", "together", "always", "because"],
|
||
"explanation": "Between (между) — в пространстве, разделяющем два объекта.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "together", "pos": "adverb", "phonetic": "/təˈɡeð.ər/",
|
||
"translation": "вместе",
|
||
"sentence": "Let's work ___ to complete the project faster.",
|
||
"options": ["together", "between", "yesterday", "tomorrow"],
|
||
"explanation": "Together (вместе) — совместно с кем-либо.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "welcome", "pos": "noun", "phonetic": "/ˈwel.kəm/",
|
||
"translation": "теплый прием, приветствие",
|
||
"sentence": "The host gave a cheerful ___ to all the guests.",
|
||
"options": ["welcome", "address", "message", "journey"],
|
||
"explanation": "Welcome (приветствие, радушный прием) — доброе отношение к прибывшим.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "question", "pos": "noun", "phonetic": "/ˈkwes.tʃən/",
|
||
"translation": "вопрос",
|
||
"sentence": "If you are confused, raise your hand and ask a ___.",
|
||
"options": ["question", "message", "address", "ticket"],
|
||
"explanation": "Question (вопрос) — обращение с целью получить ответ.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "bottle", "pos": "noun", "phonetic": "/ˈbɒt.əl/",
|
||
"translation": "бутылка",
|
||
"sentence": "Could you bring a ___ of cold water from the fridge?",
|
||
"options": ["bottle", "ticket", "weather", "message"],
|
||
"explanation": "Bottle (бутылка) — емкость для хранения напитков и жидкостей.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "island", "pos": "noun", "phonetic": "/ˈaɪ.lənd/",
|
||
"translation": "остров",
|
||
"sentence": "They spent their holiday on a small Greek ___.",
|
||
"options": ["island", "village", "airport", "station"],
|
||
"explanation": "Island (остров) — участок суши, окруженный водой.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "pocket", "pos": "noun", "phonetic": "/ˈpɒk.ɪt/",
|
||
"translation": "карман",
|
||
"sentence": "He put his keys and wallet into his jacket ___.",
|
||
"options": ["pocket", "package", "bottle", "uniform"],
|
||
"explanation": "Pocket (карман) — часть одежды в виде мешочка для мелких вещей.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "mirror", "pos": "noun", "phonetic": "/ˈmɪr.ər/",
|
||
"translation": "зеркало",
|
||
"sentence": "She looked at herself in the bathroom ___.",
|
||
"options": ["mirror", "window", "picture", "corner"],
|
||
"explanation": "Mirror (зеркало) — стеклянная поверхность, отражающая изображение.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "market", "pos": "noun", "phonetic": "/ˈmɑː.kɪt/",
|
||
"translation": "рынок, базар",
|
||
"sentence": "We buy fresh fruit every Saturday at the local ___.",
|
||
"options": ["market", "hospital", "station", "library"],
|
||
"explanation": "Market (рынок) — место торговли свежими продуктами и вещами.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "bridge", "pos": "noun", "phonetic": "/brɪdʒ/",
|
||
"translation": "мост",
|
||
"sentence": "The old stone ___ crosses the wide river.",
|
||
"options": ["bridge", "village", "island", "corner"],
|
||
"explanation": "Bridge (мост) — сооружение для перехода через реку или дорогу.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "corner", "pos": "noun", "phonetic": "/ˈkɔː.nər/",
|
||
"translation": "угол",
|
||
"sentence": "There is a small bakery on the ___ of our street.",
|
||
"options": ["corner", "mirror", "bottle", "pocket"],
|
||
"explanation": "Corner (угол) — место пересечения двух стен или улиц.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "cloud", "pos": "noun", "phonetic": "/klaʊd/",
|
||
"translation": "облако, туча",
|
||
"sentence": "Look at that dark ___ in the sky; it will rain soon.",
|
||
"options": ["cloud", "weather", "season", "island"],
|
||
"explanation": "Cloud (облако, туча) — скопление водяных паров на небе.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "floor", "pos": "noun", "phonetic": "/flɔːr/",
|
||
"translation": "пол, этаж",
|
||
"sentence": "Our new apartment is on the third ___.",
|
||
"options": ["floor", "corner", "market", "bridge"],
|
||
"explanation": "Floor (пол, этаж) — ярус в здании или нижняя поверхность комнаты.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "laugh", "pos": "verb", "phonetic": "/lɑːf/",
|
||
"translation": "смеяться",
|
||
"sentence": "The funny comedy movie made everybody ___.",
|
||
"options": ["laugh", "listen", "borrow", "decide"],
|
||
"explanation": "Laugh (смеяться) — выражать радость или веселье характерными звуками.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "shout", "pos": "verb", "phonetic": "/ʃaʊt/",
|
||
"translation": "кричать",
|
||
"sentence": "Please do not ___ inside the quiet library.",
|
||
"options": ["shout", "whisper", "invite", "repeat"],
|
||
"explanation": "Shout (кричать) — издавать громкий звук голосом.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "wash", "pos": "verb", "phonetic": "/wɒʃ/",
|
||
"translation": "мыть, стирать",
|
||
"sentence": "Remember to ___ your hands before having dinner.",
|
||
"options": ["wash", "borrow", "travel", "listen"],
|
||
"explanation": "Wash (мыть) — очищать водой с мылом.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "catch", "pos": "verb", "phonetic": "/kætʃ/",
|
||
"translation": "ловить, успеть (на транспорт)",
|
||
"sentence": "We must run quickly to ___ the morning bus.",
|
||
"options": ["catch", "throw", "decide", "invite"],
|
||
"explanation": "Catch (ловить, успевать) — поймать предмет или успеть сесть на транспорт.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "throw", "pos": "verb", "phonetic": "/θrəʊ/",
|
||
"translation": "бросать, кидать",
|
||
"sentence": "He tried to ___ the ball over the tall wall.",
|
||
"options": ["throw", "catch", "wash", "borrow"],
|
||
"explanation": "Throw (бросать) — метать предмет движением руки.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "build", "pos": "verb", "phonetic": "/bɪld/",
|
||
"translation": "строить",
|
||
"sentence": "They plan to ___ a new school in our neighborhood.",
|
||
"options": ["build", "borrow", "destroy", "invite"],
|
||
"explanation": "Build (строить) — возводить здание или конструкцию.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "climb", "pos": "verb", "phonetic": "/klaɪm/",
|
||
"translation": "взбираться, карабкаться",
|
||
"sentence": "Children love to ___ the big trees in the park.",
|
||
"options": ["climb", "throw", "catch", "repeat"],
|
||
"explanation": "Climb (взбираться) — подниматься вверх, цепляясь руками и ногами.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "heavy", "pos": "adjective", "phonetic": "/ˈhev.i/",
|
||
"translation": "тяжелый",
|
||
"sentence": "This suitcase is too ___ for me to carry alone.",
|
||
"options": ["heavy", "light", "clean", "simple"],
|
||
"explanation": "Heavy (тяжелый) — имеющий большой вес.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "narrow", "pos": "adjective", "phonetic": "/ˈnær.əʊ/",
|
||
"translation": "узкий",
|
||
"sentence": "The car could not drive down the ___ street.",
|
||
"options": ["narrow", "wide", "expensive", "famous"],
|
||
"explanation": "Narrow (узкий) — имеющий небольшую ширину.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "empty", "pos": "adjective", "phonetic": "/ˈemp.ti/",
|
||
"translation": "пустой",
|
||
"sentence": "The fuel tank is completely ___, so we must stop.",
|
||
"options": ["empty", "heavy", "healthy", "boring"],
|
||
"explanation": "Empty (пустой) — не содержащий ничего внутри.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "hungry", "pos": "adjective", "phonetic": "/ˈhʌŋ.ɡri/",
|
||
"translation": "голодный",
|
||
"sentence": "After the long walk in the forest, we were very ___.",
|
||
"options": ["hungry", "thirsty", "careful", "dangerous"],
|
||
"explanation": "Hungry (голодный) — испытывающий потребность в еде.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "thirsty", "pos": "adjective", "phonetic": "/ˈθɜː.sti/",
|
||
"translation": "испытывающий жажду",
|
||
"sentence": "Drink some water if you feel ___ after running.",
|
||
"options": ["thirsty", "hungry", "empty", "heavy"],
|
||
"explanation": "Thirsty (испытывающий жажду) — желающий пить воду.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "quiet", "pos": "adjective", "phonetic": "/ˈkwaɪ.ət/",
|
||
"translation": "тихий, спокойный",
|
||
"sentence": "This is a very ___ library where people study peacefully.",
|
||
"options": ["quiet", "loud", "dangerous", "careful"],
|
||
"explanation": "Quiet (тихий) — не производящий шума, спокойный.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "loud", "pos": "adjective", "phonetic": "/laʊd/",
|
||
"translation": "громкий, шумный",
|
||
"sentence": "The music was so ___ that I could not hear your voice.",
|
||
"options": ["loud", "quiet", "simple", "clean"],
|
||
"explanation": "Loud (громкий) — обладающий большой силой звука.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "clever", "pos": "adjective", "phonetic": "/ˈklev.ər/",
|
||
"translation": "умный, сообразительный",
|
||
"sentence": "She found a very ___ solution to that difficult riddle.",
|
||
"options": ["clever", "wrong", "boring", "dangerous"],
|
||
"explanation": "Clever (сообразительный, умный) — быстро понимающий и находчивый.",
|
||
},
|
||
{
|
||
"level": "A1", "term": "blanket", "pos": "noun", "phonetic": "/ˈblæŋ.kɪt/",
|
||
"translation": "одеяло, плед",
|
||
"sentence": "It was cold, so she put a warm ___ over the bed.",
|
||
"options": ["blanket", "package", "mirror", "pocket"],
|
||
"explanation": "Blanket (одеяло, плед) — теплое шерстяное или хлопковое покрывало.",
|
||
},
|
||
|
||
# =========================================================================
|
||
# LEVEL A2 (Elementary: Practical everyday conversation, work, actions)
|
||
# =========================================================================
|
||
{
|
||
"level": "A2", "term": "necessary", "pos": "adjective", "phonetic": "/ˈnes.ə.ser.i/",
|
||
"translation": "необходимый, нужный",
|
||
"sentence": "Good sleep is ___ for maintaining proper physical health.",
|
||
"options": ["necessary", "temporary", "available", "convenient"],
|
||
"explanation": "Necessary (необходимый) — требуется или обязательно для чего-либо.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "improve", "pos": "verb", "phonetic": "/ɪmˈpruːv/",
|
||
"translation": "улучшать, совершенствовать",
|
||
"sentence": "Reading articles in English helps to ___ your vocabulary.",
|
||
"options": ["improve", "damage", "refuse", "doubt"],
|
||
"explanation": "Improve (улучшать) — делать что-то лучше или качественнее.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "environment", "pos": "noun", "phonetic": "/ɪnˈvaɪ.rən.mənt/",
|
||
"translation": "окружающая среда",
|
||
"sentence": "Solar energy is clean and protects the ___.",
|
||
"options": ["environment", "culture", "condition", "experience"],
|
||
"explanation": "Environment (окружающая среда) — природный мир вокруг нас.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "believe", "pos": "verb", "phonetic": "/bɪˈliːv/",
|
||
"translation": "верить, полагать",
|
||
"sentence": "I truly ___ that consistent effort brings great results.",
|
||
"options": ["believe", "remind", "avoid", "refuse"],
|
||
"explanation": "Believe (верить) — быть уверенным в правдивости чего-либо.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "experience", "pos": "noun", "phonetic": "/ɪkˈspɪə.ri.əns/",
|
||
"translation": "опыт",
|
||
"sentence": "The applicant has four years of direct practical ___.",
|
||
"options": ["experience", "opinion", "solution", "culture"],
|
||
"explanation": "Experience (опыт) — знания и навыки, полученные в процессе деятельности.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "describe", "pos": "verb", "phonetic": "/dɪˈskraɪb/",
|
||
"translation": "описывать",
|
||
"sentence": "Can you ___ what the missing backpack looks like?",
|
||
"options": ["describe", "connect", "afford", "damage"],
|
||
"explanation": "Describe (описывать) — рассказывать о признаках или свойствах предмета.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "choice", "pos": "noun", "phonetic": "/tʃɔɪs/",
|
||
"translation": "выбор",
|
||
"sentence": "Customers have a wide ___ of fresh dishes on the menu.",
|
||
"options": ["choice", "condition", "reason", "degree"],
|
||
"explanation": "Choice (выбор) — возможность предпочесть один вариант другому.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "condition", "pos": "noun", "phonetic": "/kənˈdɪʃ.ən/",
|
||
"translation": "состояние, условие",
|
||
"sentence": "The used bicycle is still in nearly perfect ___.",
|
||
"options": ["condition", "solution", "opinion", "culture"],
|
||
"explanation": "Condition (состояние) — физическая форма или сохранность объекта.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "explain", "pos": "verb", "phonetic": "/ɪkˈspleɪn/",
|
||
"translation": "объяснять",
|
||
"sentence": "The engineer will ___ how to configure the router.",
|
||
"options": ["explain", "refuse", "avoid", "doubt"],
|
||
"explanation": "Explain (объяснять) — делать понятным логику или механизм.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "reason", "pos": "noun", "phonetic": "/ˈriː.zən/",
|
||
"translation": "причина, повод",
|
||
"sentence": "The main ___ for his absence was a sudden fever.",
|
||
"options": ["reason", "effect", "degree", "habit"],
|
||
"explanation": "Reason (причина) — основание или повод для какого-либо события.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "succeed", "pos": "verb", "phonetic": "/səkˈsiːd/",
|
||
"translation": "преуспевать, добиваться успеха",
|
||
"sentence": "If you prepare thoroughly, you will ___ in your exam.",
|
||
"options": ["succeed", "fail", "refuse", "avoid"],
|
||
"explanation": "Succeed (преуспевать) — достигать желаемой цели.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "afford", "pos": "verb", "phonetic": "/əˈfɔːd/",
|
||
"translation": "позволить себе (финансово)",
|
||
"sentence": "We cannot ___ to rent such an expensive apartment right now.",
|
||
"options": ["afford", "connect", "damage", "manage"],
|
||
"explanation": "Afford (позволить себе) — иметь достаточно денег или ресурсов.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "arrange", "pos": "verb", "phonetic": "/əˈreɪndʒ/",
|
||
"translation": "организовывать, договариваться",
|
||
"sentence": "Let's ___ a video call for Friday morning.",
|
||
"options": ["arrange", "refuse", "damage", "doubt"],
|
||
"explanation": "Arrange (организовывать) — согласовать план или встречу.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "avoid", "pos": "verb", "phonetic": "/əˈvɔɪd/",
|
||
"translation": "избегать, уклоняться",
|
||
"sentence": "Drivers should always ___ speeding in residential areas.",
|
||
"options": ["avoid", "afford", "protect", "support"],
|
||
"explanation": "Avoid (избегать) — стараться не допустить нежелательного действия.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "compare", "pos": "verb", "phonetic": "/kəmˈpeər/",
|
||
"translation": "сравнивать",
|
||
"sentence": "It is useful to ___ prices before buying airline tickets.",
|
||
"options": ["compare", "connect", "damage", "refuse"],
|
||
"explanation": "Compare (сравнивать) — сопоставлять объекты для выявления различий.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "complete", "pos": "verb", "phonetic": "/kəmˈpliːt/",
|
||
"translation": "завершать, заполнять",
|
||
"sentence": "Please ___ the online registration form to continue.",
|
||
"options": ["complete", "remind", "manage", "avoid"],
|
||
"explanation": "Complete (завершать, заполнять) — доводить дело или форму до конца.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "connect", "pos": "verb", "phonetic": "/kəˈnekt/",
|
||
"translation": "соединять, подключать",
|
||
"sentence": "Plug in the cable to ___ your phone to the computer.",
|
||
"options": ["connect", "damage", "refuse", "doubt"],
|
||
"explanation": "Connect (подключать) — устанавливать физическую или логическую связь.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "contain", "pos": "verb", "phonetic": "/kənˈteɪn/",
|
||
"translation": "содержать в себе",
|
||
"sentence": "These citrus fruits ___ large quantities of vitamin C.",
|
||
"options": ["contain", "expect", "manage", "refuse"],
|
||
"explanation": "Contain (содержать) — включать в свой состав.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "crowd", "pos": "noun", "phonetic": "/kraʊd/",
|
||
"translation": "толпа людей",
|
||
"sentence": "A cheering ___ filled the stadium during the game.",
|
||
"options": ["crowd", "flight", "future", "habit"],
|
||
"explanation": "Crowd (толпа) — большое скопление людей в одном месте.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "culture", "pos": "noun", "phonetic": "/ˈkʌl.tʃər/",
|
||
"translation": "культура",
|
||
"sentence": "Living abroad exposes you to a totally different ___.",
|
||
"options": ["culture", "condition", "degree", "solution"],
|
||
"explanation": "Culture (культура) — традиции, обычаи и образ жизни народа.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "damage", "pos": "noun", "phonetic": "/ˈdæm.ɪdʒ/",
|
||
"translation": "ущерб, повреждение",
|
||
"sentence": "The hailstorm caused severe ___ to the parked cars.",
|
||
"options": ["damage", "effect", "reason", "choice"],
|
||
"explanation": "Damage (ущерб) — физический вред или разрушение предметов.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "degree", "pos": "noun", "phonetic": "/dɪˈɡriː/",
|
||
"translation": "градус, степень",
|
||
"sentence": "The temperature dropped by five ___ during the night.",
|
||
"options": ["degree", "condition", "reason", "choice"],
|
||
"explanation": "Degree (градус) — единица измерения температуры или угла.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "depend", "pos": "verb", "phonetic": "/dɪˈpend/",
|
||
"translation": "зависеть",
|
||
"sentence": "Whether we go hiking will ___ on the weather tomorrow.",
|
||
"options": ["depend", "expect", "manage", "refuse"],
|
||
"explanation": "Depend (зависеть) — определяться внешними факторами.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "discover", "pos": "verb", "phonetic": "/dɪˈskʌv.ər/",
|
||
"translation": "открывать, обнаруживать",
|
||
"sentence": "Researchers hope to ___ cleaner methods of energy production.",
|
||
"options": ["discover", "damage", "avoid", "refuse"],
|
||
"explanation": "Discover (обнаруживать) — находить ранее неизвестное.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "discuss", "pos": "verb", "phonetic": "/dɪˈskʌs/",
|
||
"translation": "обсуждать",
|
||
"sentence": "Let's gather in the conference room to ___ the roadmap.",
|
||
"options": ["discuss", "refuse", "damage", "avoid"],
|
||
"explanation": "Discuss (обсуждать) — обмениваться мнениями по вопросу.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "doubt", "pos": "noun", "phonetic": "/daʊt/",
|
||
"translation": "сомнение",
|
||
"sentence": "There is no ___ that he is telling the absolute truth.",
|
||
"options": ["doubt", "habit", "crowd", "flight"],
|
||
"explanation": "Doubt (сомнение) — отсутствие твердой уверенности.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "effect", "pos": "noun", "phonetic": "/ɪˈfekt/",
|
||
"translation": "эффект, следствие",
|
||
"sentence": "The new law had a noticeable positive ___ on the economy.",
|
||
"options": ["effect", "reason", "degree", "choice"],
|
||
"explanation": "Effect (эффект) — результат или последствие определенного действия.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "energy", "pos": "noun", "phonetic": "/ˈen.ə.dʒi/",
|
||
"translation": "энергия, силы",
|
||
"sentence": "Running every morning gives me a lot of positive ___.",
|
||
"options": ["energy", "culture", "condition", "solution"],
|
||
"explanation": "Energy (энергия) — физическая или моральная сила для действий.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "expect", "pos": "verb", "phonetic": "/ɪkˈspekt/",
|
||
"translation": "ожидать, рассчитывать",
|
||
"sentence": "We ___ the parcel to arrive before five in the afternoon.",
|
||
"options": ["expect", "refuse", "damage", "avoid"],
|
||
"explanation": "Expect (ожидать) — рассчитывать на наступление события.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "fail", "pos": "verb", "phonetic": "/feɪl/",
|
||
"translation": "потерпеть неудачу, провалить",
|
||
"sentence": "If students do not study, they may ___ the final test.",
|
||
"options": ["fail", "succeed", "manage", "support"],
|
||
"explanation": "Fail (провалить) — не справиться с поставленной задачей.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "flight", "pos": "noun", "phonetic": "/flaɪt/",
|
||
"translation": "рейс, полет",
|
||
"sentence": "Their transatlantic ___ was smooth and arrived on time.",
|
||
"options": ["flight", "crowd", "habit", "future"],
|
||
"explanation": "Flight (рейс, полет) — путешествие на воздушном судне.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "future", "pos": "noun", "phonetic": "/ˈfjuː.tʃər/",
|
||
"translation": "будущее",
|
||
"sentence": "Artificial intelligence will transform the ___ of work.",
|
||
"options": ["future", "culture", "flight", "condition"],
|
||
"explanation": "Future (будущее) — время, которое еще предстоит пережить.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "guess", "pos": "noun", "phonetic": "/ɡes/",
|
||
"translation": "догадка, предположение",
|
||
"sentence": "If you don't know the exact answer, make an educated ___.",
|
||
"options": ["guess", "choice", "reason", "degree"],
|
||
"explanation": "Guess (догадка) — предположение без точных данных.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "habit", "pos": "noun", "phonetic": "/ˈhæb.ɪt/",
|
||
"translation": "привычка",
|
||
"sentence": "Brushing your teeth before bed is a healthy personal ___.",
|
||
"options": ["habit", "crowd", "flight", "future"],
|
||
"explanation": "Habit (привычка) — регулярное автоматическое действие.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "happen", "pos": "verb", "phonetic": "/ˈhæp.ən/",
|
||
"translation": "случаться, происходить",
|
||
"sentence": "Nobody predicted that such an accident could ___.",
|
||
"options": ["happen", "refuse", "avoid", "damage"],
|
||
"explanation": "Happen (происходить) — иметь место, совершаться.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "imagine", "pos": "verb", "phonetic": "/ɪˈmædʒ.ɪn/",
|
||
"translation": "представлять, воображать",
|
||
"sentence": "It is hard to ___ modern life without high-speed internet.",
|
||
"options": ["imagine", "refuse", "damage", "avoid"],
|
||
"explanation": "Imagine (воображать) — создавать мысленный образ в голове.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "manage", "pos": "verb", "phonetic": "/ˈmæn.ɪdʒ/",
|
||
"translation": "справляться, суметь сделать",
|
||
"sentence": "Despite heavy traffic, she did ___ to reach the office on time.",
|
||
"options": ["manage", "refuse", "avoid", "damage"],
|
||
"explanation": "Manage (справляться) — успешно преодолеть трудность и выполнить дело.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "nature", "pos": "noun", "phonetic": "/ˈneɪ.tʃər/",
|
||
"translation": "природа",
|
||
"sentence": "A weekend hike in the woods lets you enjoy pure ___.",
|
||
"options": ["nature", "culture", "crowd", "flight"],
|
||
"explanation": "Nature (природа) — естественный мир растений, животных и ландшафтов.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "notice", "pos": "verb", "phonetic": "/ˈnəʊ.tɪs/",
|
||
"translation": "замечать, обращать внимание",
|
||
"sentence": "Did you ___ that the bookstore moved to another street?",
|
||
"options": ["notice", "refuse", "damage", "avoid"],
|
||
"explanation": "Notice (замечать) — зафиксировать что-то зрением или вниманием.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "opinion", "pos": "noun", "phonetic": "/əˈpɪn.jən/",
|
||
"translation": "мнение, точка зрения",
|
||
"sentence": "In my humble ___, this is the tastiest coffee in town.",
|
||
"options": ["opinion", "condition", "solution", "reason"],
|
||
"explanation": "Opinion (мнение) — личная оценка или суждение о предмете.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "accident", "pos": "noun", "phonetic": "/ˈæk.sɪ.dənt/",
|
||
"translation": "авария, несчастный случай",
|
||
"sentence": "He had a minor car ___ because of the slippery road.",
|
||
"options": ["accident", "condition", "flight", "habit"],
|
||
"explanation": "Accident (авария, несчастный случай) — непредвиденное происшествие с ущербом.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "advice", "pos": "noun", "phonetic": "/ədˈvaɪs/",
|
||
"translation": "совет",
|
||
"sentence": "My teacher gave me great ___ on how to prepare for exams.",
|
||
"options": ["advice", "opinion", "reason", "culture"],
|
||
"explanation": "Advice (совет) — полезная рекомендация или наставление.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "compete", "pos": "verb", "phonetic": "/kəmˈpiːt/",
|
||
"translation": "соревноваться, состязаться",
|
||
"sentence": "Athletes from thirty countries will ___ in the tournament.",
|
||
"options": ["compete", "compare", "contain", "succeed"],
|
||
"explanation": "Compete (соревноваться) — стремиться к победе в состязании с другими.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "customer", "pos": "noun", "phonetic": "/ˈkʌs.tə.mər/",
|
||
"translation": "клиент, покупатель",
|
||
"sentence": "The shop assistant was polite and helped every ___.",
|
||
"options": ["customer", "passenger", "crowd", "flight"],
|
||
"explanation": "Customer (клиент, покупатель) — лицо, приобретающее товары или услуги.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "earn", "pos": "verb", "phonetic": "/ɜːn/",
|
||
"translation": "зарабатывать",
|
||
"sentence": "He works overtime to ___ enough money for a new laptop.",
|
||
"options": ["earn", "afford", "borrow", "spend"],
|
||
"explanation": "Earn (зарабатывать) — получать деньги за выполняемую работу.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "equipment", "pos": "noun", "phonetic": "/ɪˈkwɪp.mənt/",
|
||
"translation": "оборудование, снаряжение",
|
||
"sentence": "Make sure you bring the right sports ___ for camping.",
|
||
"options": ["equipment", "environment", "culture", "condition"],
|
||
"explanation": "Equipment (оборудование, снаряжение) — необходимые инструменты или вещи для занятия.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "patient", "pos": "adjective", "phonetic": "/ˈpeɪ.ʃənt/",
|
||
"translation": "терпеливый",
|
||
"sentence": "Teachers need to be very ___ with young beginner students.",
|
||
"options": ["patient", "careful", "dangerous", "healthy"],
|
||
"explanation": "Patient (терпеливый) — способный спокойно переносить трудности или ожидание.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "pollute", "pos": "verb", "phonetic": "/pəˈluːt/",
|
||
"translation": "загрязнять",
|
||
"sentence": "Factories should not ___ the air with toxic smoke.",
|
||
"options": ["pollute", "improve", "protect", "contain"],
|
||
"explanation": "Pollute (загрязнять) — делать окружающую среду грязной или вредной.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "proud", "pos": "adjective", "phonetic": "/praʊd/",
|
||
"translation": "гордый (испытывающий гордость)",
|
||
"sentence": "Her parents were very ___ when she won first prize.",
|
||
"options": ["proud", "disappointed", "jealous", "afraid"],
|
||
"explanation": "Proud (гордый) — испытывающий чувство глубокого удовлетворения за успех.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "refuse", "pos": "verb", "phonetic": "/rɪˈfjuːz/",
|
||
"translation": "отказываться",
|
||
"sentence": "I had to ___ his invitation because of urgent work.",
|
||
"options": ["refuse", "accept", "decide", "suggest"],
|
||
"explanation": "Refuse (отказываться) — отклонить предложение или просьбу.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "repair", "pos": "verb", "phonetic": "/rɪˈpeər/",
|
||
"translation": "чинить, ремонтировать",
|
||
"sentence": "Can you help me ___ this broken bicycle wheel?",
|
||
"options": ["repair", "damage", "destroy", "improve"],
|
||
"explanation": "Repair (ремонтировать) — восстанавливать поврежденный предмет.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "salary", "pos": "noun", "phonetic": "/ˈsæl.ər.i/",
|
||
"translation": "заработная плата",
|
||
"sentence": "They offered him a higher monthly ___ in the new position.",
|
||
"options": ["salary", "ticket", "package", "damage"],
|
||
"explanation": "Salary (зарплата) — регулярная оплата труда работника.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "separate", "pos": "adjective", "phonetic": "/ˈsep.ər.ət/",
|
||
"translation": "отдельный, раздельный",
|
||
"sentence": "The children sleep in ___ rooms on the second floor.",
|
||
"options": ["separate", "connected", "complete", "necessary"],
|
||
"explanation": "Separate (отдельный) — находящийся отдельно от других, не соединенный.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "strange", "pos": "adjective", "phonetic": "/streɪndʒ/",
|
||
"translation": "странный, необычный",
|
||
"sentence": "I heard a ___ noise coming from the basement at midnight.",
|
||
"options": ["strange", "simple", "famous", "boring"],
|
||
"explanation": "Strange (странный) — непривычный, вызывающий удивление или недоумение.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "traffic", "pos": "noun", "phonetic": "/ˈtræf.ɪk/",
|
||
"translation": "дорожное движение",
|
||
"sentence": "There was heavy ___ on the highway, so we arrived late.",
|
||
"options": ["traffic", "flight", "crowd", "weather"],
|
||
"explanation": "Traffic (дорожное движение) — поток транспортных средств на дороге.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "urgent", "pos": "adjective", "phonetic": "/ˈɜː.dʒənt/",
|
||
"translation": "срочный, неотложный",
|
||
"sentence": "The doctor received an ___ phone call from the clinic.",
|
||
"options": ["urgent", "patient", "boring", "slow"],
|
||
"explanation": "Urgent (срочный) — требующий немедленного внимания или действия.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "warn", "pos": "verb", "phonetic": "/wɔːn/",
|
||
"translation": "предупреждать",
|
||
"sentence": "The guard tried to ___ the tourists about the thin ice.",
|
||
"options": ["warn", "invite", "explain", "interrupt"],
|
||
"explanation": "Warn (предупреждать) — заранее извещать об опасности или неприятности.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "attend", "pos": "verb", "phonetic": "/əˈtend/",
|
||
"translation": "посещать, присутствовать",
|
||
"sentence": "All staff members are required to ___ the weekly meeting.",
|
||
"options": ["attend", "avoid", "expect", "improve"],
|
||
"explanation": "Attend (посещать) — присутствовать на собрании, уроке или мероприятии.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "benefit", "pos": "noun", "phonetic": "/ˈben.ɪ.fɪt/",
|
||
"translation": "польза, выгода, преимущество",
|
||
"sentence": "Regular exercise offers an enormous health ___ for everyone.",
|
||
"options": ["benefit", "damage", "condition", "accident"],
|
||
"explanation": "Benefit (польза, выгода) — положительный эффект или преимущество.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "celebrate", "pos": "verb", "phonetic": "/ˈsel.ə.breɪt/",
|
||
"translation": "праздновать, отмечать",
|
||
"sentence": "We gathered together to ___ her graduation with a cake.",
|
||
"options": ["celebrate", "compete", "describe", "separate"],
|
||
"explanation": "Celebrate (праздновать) — отмечать радостное событие или праздник.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "protect", "pos": "verb", "phonetic": "/prəˈtekt/",
|
||
"translation": "защищать, оберегать",
|
||
"sentence": "Sunglasses ___ your eyes from strong ultraviolet rays.",
|
||
"options": ["protect", "pollute", "damage", "interrupt"],
|
||
"explanation": "Protect (защищать) — предохранять от вреда, опасности или повреждений.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "remain", "pos": "verb", "phonetic": "/rɪˈmeɪn/",
|
||
"translation": "оставаться",
|
||
"sentence": "Please ___ seated until the aircraft comes to a stop.",
|
||
"options": ["remain", "depart", "change", "connect"],
|
||
"explanation": "Remain (оставаться) — продолжать находиться в прежнем месте или состоянии.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "suggest", "pos": "verb", "phonetic": "/səˈdʒest/",
|
||
"translation": "предлагать, советовать",
|
||
"sentence": "Can you ___ a good Italian restaurant downtown?",
|
||
"options": ["suggest", "refuse", "warn", "guess"],
|
||
"explanation": "Suggest (предлагать) — высказать идею, рекомендацию или вариант выбора.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "transport", "pos": "noun", "phonetic": "/ˈtræn.spɔːt/",
|
||
"translation": "транспорт",
|
||
"sentence": "Public ___ in the capital is fast, clean, and reliable.",
|
||
"options": ["transport", "traffic", "flight", "journey"],
|
||
"explanation": "Transport (транспорт) — средства перевозки людей и грузов.",
|
||
},
|
||
{
|
||
"level": "A2", "term": "wealthy", "pos": "adjective", "phonetic": "/ˈwel.θi/",
|
||
"translation": "богатый, состоятельный",
|
||
"sentence": "He comes from a ___ family that owns several businesses.",
|
||
"options": ["wealthy", "expensive", "proud", "patient"],
|
||
"explanation": "Wealthy (состоятельный) — обладающий большим богатством или имуществом.",
|
||
},
|
||
|
||
# =========================================================================
|
||
# LEVEL B1 (Intermediate: Abstract concepts, professional life, reasoning)
|
||
# =========================================================================
|
||
{
|
||
"level": "B1", "term": "decision", "pos": "noun", "phonetic": "/dɪˈsɪʒ.ən/",
|
||
"translation": "решение",
|
||
"sentence": "Choosing a career path is a major life ___.",
|
||
"options": ["decision", "opportunity", "relationship", "behavior"],
|
||
"explanation": "Decision (решение) — сделанный выбор или заключение после размышлений.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "achieve", "pos": "verb", "phonetic": "/əˈtʃiːv/",
|
||
"translation": "достигать (цели)",
|
||
"sentence": "With persistent practice, you can ___ fluency in English.",
|
||
"options": ["achieve", "interrupt", "hesitate", "negotiate"],
|
||
"explanation": "Achieve (достигать) — успешно завершить запланированное упорным трудом.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "community", "pos": "noun", "phonetic": "/kəˈmjuː.nə.ti/",
|
||
"translation": "сообщество, общественность",
|
||
"sentence": "The local ___ gathered to build a new playground.",
|
||
"options": ["community", "relationship", "behavior", "mystery"],
|
||
"explanation": "Community (сообщество) — группа людей, объединенных общим местом или интересами.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "convenient", "pos": "adjective", "phonetic": "/kənˈviː.ni.ənt/",
|
||
"translation": "удобный, подходящий",
|
||
"sentence": "Living near a subway station is extremely ___ for commuting.",
|
||
"options": ["convenient", "generous", "jealous", "temporary"],
|
||
"explanation": "Convenient (удобный) — подходящий по расположению или времени, экономящий силы.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "develop", "pos": "verb", "phonetic": "/dɪˈvel.əp/",
|
||
"translation": "развивать, разрабатывать",
|
||
"sentence": "Our engineering squad will ___ a modern backend service.",
|
||
"options": ["develop", "hesitate", "interrupt", "negotiate"],
|
||
"explanation": "Develop (разрабатывать) — создавать, улучшать и развивать продукт.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "opportunity", "pos": "noun", "phonetic": "/ˌɒp.əˈtʃuː.nə.ti/",
|
||
"translation": "возможность, шанс",
|
||
"sentence": "An internship abroad provides a rare ___ to gain global experience.",
|
||
"options": ["opportunity", "consequence", "requirement", "behavior"],
|
||
"explanation": "Opportunity (возможность) — благоприятное стечение обстоятельств.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "relationship", "pos": "noun", "phonetic": "/rɪˈleɪ.ʃən.ʃɪp/",
|
||
"translation": "отношения, взаимосвязь",
|
||
"sentence": "Mutual trust is essential for building a lasting professional ___.",
|
||
"options": ["relationship", "community", "behavior", "mystery"],
|
||
"explanation": "Relationship (отношения) — связь и взаимодействие между людьми.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "behavior", "pos": "noun", "phonetic": "/bɪˈheɪ.vjər/",
|
||
"translation": "поведение",
|
||
"sentence": "The teacher commended the student for respectful classroom ___.",
|
||
"options": ["behavior", "community", "decision", "mystery"],
|
||
"explanation": "Behavior (поведение) — манера вести себя и действовать.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "challenge", "pos": "noun", "phonetic": "/ˈtʃæl.ɪndʒ/",
|
||
"translation": "сложная задача, вызов",
|
||
"sentence": "Migrating a legacy database is always a serious technical ___.",
|
||
"options": ["challenge", "opportunity", "consequence", "requirement"],
|
||
"explanation": "Challenge (вызов) — сложная задача, требующая усилий.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "consequence", "pos": "noun", "phonetic": "/ˈkɒn.sɪ.kwəns/",
|
||
"translation": "последствие",
|
||
"sentence": "Losing your data is a direct ___ of not keeping backups.",
|
||
"options": ["consequence", "community", "behavior", "opportunity"],
|
||
"explanation": "Consequence (последствие) — результат, вытекающий из действия.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "consider", "pos": "verb", "phonetic": "/kənˈsɪd.ər/",
|
||
"translation": "обдумывать, учитывать",
|
||
"sentence": "You should carefully ___ all pros and cons before signing.",
|
||
"options": ["consider", "hesitate", "interrupt", "negotiate"],
|
||
"explanation": "Consider (обдумывать) — взвешивать факторы перед решением.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "definitely", "pos": "adverb", "phonetic": "/ˈdef.ɪ.nət.li/",
|
||
"translation": "определенно, точно",
|
||
"sentence": "I will ___ finish this pull request before leaving today.",
|
||
"options": ["definitely", "fluently", "generously", "logically"],
|
||
"explanation": "Definitely (определенно) — без малейших сомнений.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "disappointed", "pos": "adjective", "phonetic": "/ˌdɪs.əˈpɔɪn.tɪd/",
|
||
"translation": "разочарованный",
|
||
"sentence": "We felt ___ when our favorite restaurant was closed.",
|
||
"options": ["disappointed", "confident", "generous", "sensible"],
|
||
"explanation": "Disappointed (разочарованный) — огорченный несбывшимися ожиданиями.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "encourage", "pos": "verb", "phonetic": "/ɪnˈkʌr.ɪdʒ/",
|
||
"translation": "поощрять, подбадривать",
|
||
"sentence": "Mentors should always ___ beginners when learning new skills.",
|
||
"options": ["encourage", "interrupt", "hesitate", "negotiate"],
|
||
"explanation": "Encourage (поощрять) — вселять уверенность и поддерживать.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "essential", "pos": "adjective", "phonetic": "/ɪˈsen.ʃəl/",
|
||
"translation": "существенный, неотъемлемый",
|
||
"sentence": "Writing tests is an ___ part of production software engineering.",
|
||
"options": ["essential", "temporary", "jealous", "modest"],
|
||
"explanation": "Essential (существенный) — фундаментально важный.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "fluent", "pos": "adjective", "phonetic": "/ˈfluː.ənt/",
|
||
"translation": "беглый, свободно говорящий",
|
||
"sentence": "After years in London, she became completely ___ in English.",
|
||
"options": ["fluent", "generous", "modest", "logical"],
|
||
"explanation": "Fluent (беглый) — способный свободно и без запинок говорить на языке.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "generous", "pos": "adjective", "phonetic": "/ˈdʒen.ər.əs/",
|
||
"translation": "щедрый, великодушный",
|
||
"sentence": "The sponsor made a very ___ contribution to the charity.",
|
||
"options": ["generous", "jealous", "temporary", "sensible"],
|
||
"explanation": "Generous (щедрый) — готовый охотно делиться ресурсами.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "hesitate", "pos": "verb", "phonetic": "/ˈhez.ɪ.teɪt/",
|
||
"translation": "колебаться, сомневаться",
|
||
"sentence": "Please do not ___ to ask if any requirement is unclear.",
|
||
"options": ["hesitate", "negotiate", "achieve", "interrupt"],
|
||
"explanation": "Hesitate (колебаться) — медлить из-за сомнений или нерешительности.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "influence", "pos": "noun", "phonetic": "/ˈɪn.flu.əns/",
|
||
"translation": "влияние, воздействие",
|
||
"sentence": "Good books have a deep positive ___ on personal growth.",
|
||
"options": ["influence", "behavior", "mystery", "challenge"],
|
||
"explanation": "Influence (влияние) — сила воздействия на мысли или действия других.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "interrupt", "pos": "verb", "phonetic": "/ˌɪn.təˈrʌpt/",
|
||
"translation": "перебивать, прерывать",
|
||
"sentence": "It is impolite to ___ colleagues while they present their ideas.",
|
||
"options": ["interrupt", "hesitate", "encourage", "negotiate"],
|
||
"explanation": "Interrupt (перебивать) — нарушать ход чьей-то речи или действия.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "jealous", "pos": "adjective", "phonetic": "/ˈdʒel.əs/",
|
||
"translation": "ревнивый, завистливый",
|
||
"sentence": "He was slightly ___ of his friend's new sports car.",
|
||
"options": ["jealous", "generous", "sensible", "modest"],
|
||
"explanation": "Jealous (завистливый) — испытывающий досаду от чужого успеха или имущества.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "maintain", "pos": "verb", "phonetic": "/meɪnˈteɪn/",
|
||
"translation": "поддерживать, сохранять",
|
||
"sentence": "It takes daily habit to ___ high code quality in a repo.",
|
||
"options": ["maintain", "interrupt", "hesitate", "negotiate"],
|
||
"explanation": "Maintain (поддерживать) — сохранять объект в надлежащем состоянии.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "mystery", "pos": "noun", "phonetic": "/ˈmɪs.tər.i/",
|
||
"translation": "тайна, загадка",
|
||
"sentence": "The origin of that ancient ruined temple remains an unsolved ___.",
|
||
"options": ["mystery", "behavior", "relationship", "decision"],
|
||
"explanation": "Mystery (загадка) — то, что трудно объяснить или понять.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "negotiate", "pos": "verb", "phonetic": "/nəˈɡəʊ.ʃi.eɪt/",
|
||
"translation": "вести переговоры, договариваться",
|
||
"sentence": "The founders met to ___ the terms of their partnership.",
|
||
"options": ["negotiate", "interrupt", "hesitate", "encourage"],
|
||
"explanation": "Negotiate (вести переговоры) — обсуждать условия для достижения соглашения.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "obvious", "pos": "adjective", "phonetic": "/ˈɒb.vi.əs/",
|
||
"translation": "очевидный, явный",
|
||
"sentence": "It is ___ that system security must be prioritized from day one.",
|
||
"options": ["obvious", "modest", "temporary", "jealous"],
|
||
"explanation": "Obvious (очевидный) — легко заметный и понятный без объяснений.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "particular", "pos": "adjective", "phonetic": "/pəˈtɪk.jə.lər/",
|
||
"translation": "конкретный, определенный",
|
||
"sentence": "Was there any ___ reason why the service crashed?",
|
||
"options": ["particular", "fluent", "generous", "jealous"],
|
||
"explanation": "Particular (конкретный) — относящийся именно к данному случаю или лицу.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "persuade", "pos": "verb", "phonetic": "/pəˈsweɪd/",
|
||
"translation": "убеждать",
|
||
"sentence": "She was able to ___ the manager with well-prepared statistics.",
|
||
"options": ["persuade", "interrupt", "hesitate", "maintain"],
|
||
"explanation": "Persuade (убеждать) — склонять к своей точке зрения доводами.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "reliable", "pos": "adjective", "phonetic": "/rɪˈlaɪ.ə.bəl/",
|
||
"translation": "надежный",
|
||
"sentence": "We need a ___ database that does not lose data on restart.",
|
||
"options": ["reliable", "jealous", "temporary", "disappointed"],
|
||
"explanation": "Reliable (надежный) — верный, заслуживающий доверия.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "requirement", "pos": "noun", "phonetic": "/rɪˈkwaɪə.mənt/",
|
||
"translation": "требование, условие",
|
||
"sentence": "Having Python installed is a mandatory ___ for this script.",
|
||
"options": ["requirement", "consequence", "community", "behavior"],
|
||
"explanation": "Requirement (требование) — обязательное условие.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "sensible", "pos": "adjective", "phonetic": "/ˈsen.sə.bəl/",
|
||
"translation": "благоразумный, разумный",
|
||
"sentence": "Wearing a warm jacket in sub-zero weather is a very ___ choice.",
|
||
"options": ["sensible", "jealous", "temporary", "disappointed"],
|
||
"explanation": "Sensible (благоразумный) — продиктованный здравым смыслом.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "suitable", "pos": "adjective", "phonetic": "/ˈsuː.tə.bəl/",
|
||
"translation": "подходящий, годный",
|
||
"sentence": "This quiet study room is very ___ for reading long texts.",
|
||
"options": ["suitable", "jealous", "disappointed", "fluent"],
|
||
"explanation": "Suitable (подходящий) — соответствующий целям и потребностям.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "temporary", "pos": "adjective", "phonetic": "/ˈtem.pər.ər.i/",
|
||
"translation": "временный",
|
||
"sentence": "The detour is only ___ while the bridge is repaired.",
|
||
"options": ["temporary", "essential", "reliable", "fluent"],
|
||
"explanation": "Temporary (временный) — действующий лишь ограниченный период времени.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "universal", "pos": "adjective", "phonetic": "/ˌjuː.nɪˈvɜː.səl/",
|
||
"translation": "всеобщий, универсальный",
|
||
"sentence": "Curiosity is a ___ characteristic of human nature.",
|
||
"options": ["universal", "temporary", "jealous", "modest"],
|
||
"explanation": "Universal (универсальный) — применимый повсеместно.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "valuable", "pos": "adjective", "phonetic": "/ˈvæl.jə.bəl/",
|
||
"translation": "ценный, полезный",
|
||
"sentence": "Her feedback on our design provided ___ insights.",
|
||
"options": ["valuable", "jealous", "temporary", "disappointed"],
|
||
"explanation": "Valuable (ценный) — обладающий большой пользой или ценностью.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "vulnerable", "pos": "adjective", "phonetic": "/ˈvʌl.nər.ə.bəl/",
|
||
"translation": "уязвимый",
|
||
"sentence": "Unpatched systems are highly ___ to automated cyber attacks.",
|
||
"options": ["vulnerable", "generous", "fluent", "sensible"],
|
||
"explanation": "Vulnerable (уязвимый) — слабо защищенный от вредоносных факторов.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "ambitious", "pos": "adjective", "phonetic": "/æmˈbɪʃ.əs/",
|
||
"translation": "амбициозный, целеустремленный",
|
||
"sentence": "The startup announced an ___ plan to launch ten satellites.",
|
||
"options": ["ambitious", "jealous", "disappointed", "temporary"],
|
||
"explanation": "Ambitious (амбициозный) — ставящий смелые, масштабные цели.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "confident", "pos": "adjective", "phonetic": "/ˈkɒn.fɪ.dənt/",
|
||
"translation": "уверенный в себе",
|
||
"sentence": "He gave a clear presentation because he felt ___ in his results.",
|
||
"options": ["confident", "disappointed", "jealous", "temporary"],
|
||
"explanation": "Confident (уверенный) — не сомневающийся в своих силах.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "curious", "pos": "adjective", "phonetic": "/ˈkjʊə.ri.əs/",
|
||
"translation": "любознательный, любопытный",
|
||
"sentence": "Young children are endlessly ___ about the world around them.",
|
||
"options": ["curious", "disappointed", "jealous", "fluent"],
|
||
"explanation": "Curious (любознательный) — стремящийся узнать что-то новое.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "efficient", "pos": "adjective", "phonetic": "/ɪˈfɪʃ.ənt/",
|
||
"translation": "эффективный, продуктивный",
|
||
"sentence": "Using keyboard shortcuts makes editing text much more ___.",
|
||
"options": ["efficient", "jealous", "temporary", "modest"],
|
||
"explanation": "Efficient (эффективный) — дающий максимальный результат при минимуме затрат.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "reasonable", "pos": "adjective", "phonetic": "/ˈriː.zən.ə.bəl/",
|
||
"translation": "разумный, приемлемый",
|
||
"sentence": "The hotel offered comfortable clean rooms at a very ___ price.",
|
||
"options": ["reasonable", "jealous", "disappointed", "temporary"],
|
||
"explanation": "Reasonable (разумный, приемлемый) — адекватный, справедливый по цене или требованиям.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "accomplish", "pos": "verb", "phonetic": "/əˈkʌm.plɪʃ/",
|
||
"translation": "выполнить, достичь",
|
||
"sentence": "With proper focus, you can ___ your goals ahead of schedule.",
|
||
"options": ["accomplish", "hesitate", "interrupt", "negotiate"],
|
||
"explanation": "Accomplish (достичь, выполнить) — успешно завершить начатое дело или цель.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "accurate", "pos": "adjective", "phonetic": "/ˈæk.jə.rət/",
|
||
"translation": "точный, правильный",
|
||
"sentence": "The financial report must provide completely ___ figures.",
|
||
"options": ["accurate", "vulnerable", "sensible", "fluent"],
|
||
"explanation": "Accurate (точный) — соответствующий истине, без ошибок.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "adequate", "pos": "adjective", "phonetic": "/ˈæd.ə.kwət/",
|
||
"translation": "достаточный, соответствующий",
|
||
"sentence": "Make sure you get ___ sleep before running the marathon.",
|
||
"options": ["adequate", "temporary", "curious", "jealous"],
|
||
"explanation": "Adequate (достаточный) — удовлетворяющий определенным требованиям или норме.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "anxiety", "pos": "noun", "phonetic": "/æŋˈzaɪ.ə.ti/",
|
||
"translation": "тревожность, беспокойство",
|
||
"sentence": "Meditation helps reduce stress and chronic ___ significantly.",
|
||
"options": ["anxiety", "consequence", "decision", "mystery"],
|
||
"explanation": "Anxiety (тревожность) — эмоциональное состояние сильного внутреннего беспокойства.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "apparent", "pos": "adjective", "phonetic": "/əˈpær.ənt/",
|
||
"translation": "очевидный, явный",
|
||
"sentence": "It soon became ___ that they had made a serious error.",
|
||
"options": ["apparent", "valuable", "ambitious", "fluent"],
|
||
"explanation": "Apparent (очевидный) — легко различимый, понятный без объяснений.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "circumstance", "pos": "noun", "phonetic": "/ˈsɜː.kəm.stɑːns/",
|
||
"translation": "обстоятельство",
|
||
"sentence": "Under no ___ should you share your banking passwords.",
|
||
"options": ["circumstance", "community", "requirement", "behavior"],
|
||
"explanation": "Circumstance (обстоятельство) — условие или событие, сопровождающее ситуацию.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "convince", "pos": "verb", "phonetic": "/kənˈvɪns/",
|
||
"translation": "убеждать",
|
||
"sentence": "He tried hard to ___ the committee of the plan's feasibility.",
|
||
"options": ["convince", "interrupt", "hesitate", "maintain"],
|
||
"explanation": "Convince (убеждать) — склонять к согласию аргументами и доводами.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "critical", "pos": "adjective", "phonetic": "/ˈkrɪt.ɪ.kəl/",
|
||
"translation": "критический, решающий",
|
||
"sentence": "The first few hours after an injury are of ___ importance.",
|
||
"options": ["critical", "fluent", "generous", "suitable"],
|
||
"explanation": "Critical (критический, решающий) — имеющий решающее значение для исхода дела.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "deny", "pos": "verb", "phonetic": "/dɪˈnaɪ/",
|
||
"translation": "отрицать",
|
||
"sentence": "The suspect continued to ___ any involvement in the theft.",
|
||
"options": ["deny", "persuade", "interrupt", "encourage"],
|
||
"explanation": "Deny (отрицать) — отвергать утверждение или обвинение.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "emphasize", "pos": "verb", "phonetic": "/ˈem.fə.saɪz/",
|
||
"translation": "подчеркивать, акцентировать",
|
||
"sentence": "The teacher wished to ___ the importance of consistent practice.",
|
||
"options": ["emphasize", "hesitate", "negotiate", "consider"],
|
||
"explanation": "Emphasize (подчеркивать) — обращать особое внимание на что-то.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "frequent", "pos": "adjective", "phonetic": "/ˈfriː.kwənt/",
|
||
"translation": "частый",
|
||
"sentence": "Bus delays are a ___ problem during snowy winter months.",
|
||
"options": ["frequent", "temporary", "valuable", "vulnerable"],
|
||
"explanation": "Frequent (частый) — повторяющийся через короткие промежутки времени.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "genuine", "pos": "adjective", "phonetic": "/ˈdʒen.ju.ɪn/",
|
||
"translation": "подлинный, искренний",
|
||
"sentence": "She showed ___ interest in learning about foreign cultures.",
|
||
"options": ["genuine", "jealous", "disappointed", "sensible"],
|
||
"explanation": "Genuine (подлинный, искренний) — неподдельный, настоящий.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "intend", "pos": "verb", "phonetic": "/ɪnˈtend/",
|
||
"translation": "намереваться, планировать",
|
||
"sentence": "Do you ___ to stay here permanently or return home soon?",
|
||
"options": ["intend", "hesitate", "interrupt", "negotiate"],
|
||
"explanation": "Intend (намереваться) — иметь твердый план или намерение что-то совершить.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "obtain", "pos": "verb", "phonetic": "/əbˈteɪn/",
|
||
"translation": "получать, приобретать",
|
||
"sentence": "You must ___ an entry visa before traveling abroad.",
|
||
"options": ["obtain", "deny", "hesitate", "disappoint"],
|
||
"explanation": "Obtain (получать) — приобретать или добиваться обладания чем-либо.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "persistent", "pos": "adjective", "phonetic": "/pəˈsɪs.tənt/",
|
||
"translation": "настойчивый, упорный",
|
||
"sentence": "Through ___ hard work, she eventually mastered fluent English.",
|
||
"options": ["persistent", "temporary", "vulnerable", "jealous"],
|
||
"explanation": "Persistent (упорный, настойчивый) — продолжающий действовать, невзирая на препятствия.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "predict", "pos": "verb", "phonetic": "/prɪˈdɪkt/",
|
||
"translation": "предсказывать, прогнозировать",
|
||
"sentence": "Economists struggle to ___ market swings with high accuracy.",
|
||
"options": ["predict", "persuade", "interrupt", "maintain"],
|
||
"explanation": "Predict (предсказывать) — делать прогноз о будущем на основе фактов.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "sufficient", "pos": "adjective", "phonetic": "/səˈfɪʃ.ənt/",
|
||
"translation": "достаточный",
|
||
"sentence": "We have ___ evidence to prove that the hypothesis is sound.",
|
||
"options": ["sufficient", "curious", "jealous", "ambitious"],
|
||
"explanation": "Sufficient (достаточный) — в том количестве, которое требуется для цели.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "threaten", "pos": "verb", "phonetic": "/ˈθret.ən/",
|
||
"translation": "угрожать",
|
||
"sentence": "Rising sea levels ___ low-lying coastal towns worldwide.",
|
||
"options": ["threaten", "encourage", "convince", "accomplish"],
|
||
"explanation": "Threaten (угрожать) — представлять потенциальную опасность или риск.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "approve", "pos": "verb", "phonetic": "/əˈpruːv/",
|
||
"translation": "одобрять, утверждать",
|
||
"sentence": "The board of directors is expected to ___ the budget tomorrow.",
|
||
"options": ["approve", "deny", "hesitate", "interrupt"],
|
||
"explanation": "Approve (одобрять) — официально соглашаться или санкционировать.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "broadcast", "pos": "verb", "phonetic": "/ˈbrɔːd.kɑːst/",
|
||
"translation": "вещать, транслировать",
|
||
"sentence": "The radio station will ___ the live championship match.",
|
||
"options": ["broadcast", "negotiate", "maintain", "interrupt"],
|
||
"explanation": "Broadcast (вещать) — передавать информацию по радио, телевидению или сети.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "cooperate", "pos": "verb", "phonetic": "/kəʊˈɒp.ər.eɪt/",
|
||
"translation": "сотрудничать, взаимодействовать",
|
||
"sentence": "The two research teams decided to ___ on the clinical study.",
|
||
"options": ["cooperate", "compete", "hesitate", "deny"],
|
||
"explanation": "Cooperate (сотрудничать) — совместно трудиться ради общей цели.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "distinguish", "pos": "verb", "phonetic": "/dɪˈstɪŋ.ɡwɪʃ/",
|
||
"translation": "различать, отличать",
|
||
"sentence": "It is difficult to ___ the two identical twin sisters.",
|
||
"options": ["distinguish", "convince", "interrupt", "persuade"],
|
||
"explanation": "Distinguish (различать) — замечать разницу между объектами.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "eliminate", "pos": "verb", "phonetic": "/iˈlɪm.ɪ.neɪt/",
|
||
"translation": "устранять, ликвидировать",
|
||
"sentence": "Automation aims to ___ repetitive manual clerical tasks.",
|
||
"options": ["eliminate", "maintain", "hesitate", "develop"],
|
||
"explanation": "Eliminate (устранять) — полностью удалять или избавляться от чего-либо.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "guarantee", "pos": "verb", "phonetic": "/ˌɡær.ənˈtiː/",
|
||
"translation": "гарантировать",
|
||
"sentence": "We cannot ___ that the shipment will arrive by tomorrow.",
|
||
"options": ["guarantee", "deny", "hesitate", "threaten"],
|
||
"explanation": "Guarantee (гарантировать) — давать твердое обещание или заверение.",
|
||
},
|
||
{
|
||
"level": "B1", "term": "identify", "pos": "verb", "phonetic": "/aɪˈden.tɪ.faɪ/",
|
||
"translation": "опознавать, определять",
|
||
"sentence": "The system uses biometric scans to ___ authorized employees.",
|
||
"options": ["identify", "deny", "hesitate", "threaten"],
|
||
"explanation": "Identify (опознавать) — устанавливать точную личность или природу объекта.",
|
||
},
|
||
|
||
# =========================================================================
|
||
# LEVEL B2 (Upper-Intermediate: Academic, nuanced, debate, precision)
|
||
# =========================================================================
|
||
{
|
||
"level": "B2", "term": "compromise", "pos": "noun", "phonetic": "/ˈkɒm.prə.maɪz/",
|
||
"translation": "компромисс, взаимная уступка",
|
||
"sentence": "After intense negotiations, both sides reached a workable ___.",
|
||
"options": ["compromise", "consensus", "ambiguity", "contradiction"],
|
||
"explanation": "Compromise (компромисс) — соглашение на основе взаимных уступок.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "inevitable", "pos": "adjective", "phonetic": "/ɪnˈev.ɪ.tə.bəl/",
|
||
"translation": "неизбежный, неотвратимый",
|
||
"sentence": "Some degree of change is ___ in any growing organization.",
|
||
"options": ["inevitable", "plausible", "arbitrary", "versatile"],
|
||
"explanation": "Inevitable (неизбежный) — то, что невозможно предотвратить.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "elaborate", "pos": "verb", "phonetic": "/ɪˈlæb.ə.reɪt/",
|
||
"translation": "вдаваться в детали, подробно разъяснять",
|
||
"sentence": "Could you please ___ on how this algorithm handles edge cases?",
|
||
"options": ["elaborate", "diminish", "facilitate", "terminate"],
|
||
"explanation": "Elaborate (подробно разъяснять) — раскрывать тему с дополнительными деталями.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "coherent", "pos": "adjective", "phonetic": "/kəʊˈhɪə.rənt/",
|
||
"translation": "связный, логичный, последовательный",
|
||
"sentence": "She outlined a remarkably clear and ___ architectural design.",
|
||
"options": ["coherent", "arbitrary", "reluctant", "ambiguous"],
|
||
"explanation": "Coherent (связный, последовательный) — логически выстроенный без внутренних противоречий.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "sophisticated", "pos": "adjective", "phonetic": "/səˈfɪs.tɪ.keɪ.tɪd/",
|
||
"translation": "сложный, утонченный, высокотехнологичный",
|
||
"sentence": "Modern network firewalls utilize ___ pattern detection.",
|
||
"options": ["sophisticated", "arbitrary", "preliminary", "reluctant"],
|
||
"explanation": "Sophisticated (высокотехнологичный) — обладающий высоким уровнем сложности и развития.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "resilient", "pos": "adjective", "phonetic": "/rɪˈzɪl.jənt/",
|
||
"translation": "устойчивый к сбоям, жизнестойкий",
|
||
"sentence": "The distributed cluster proved ___ even when two nodes went down.",
|
||
"options": ["resilient", "reluctant", "arbitrary", "plausible"],
|
||
"explanation": "Resilient (жизнестойкий, отказоустойчивый) — способный быстро восстанавливаться после потрясений.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "ambiguity", "pos": "noun", "phonetic": "/ˌæm.bɪˈɡjuː.ə.ti/",
|
||
"translation": "двусмысленность, неопределенность",
|
||
"sentence": "Good API specifications avoid any semantic ___.",
|
||
"options": ["ambiguity", "consensus", "compromise", "versatility"],
|
||
"explanation": "Ambiguity (двусмысленность) — наличие нескольких противоречивых трактовок.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "comprehensive", "pos": "adjective", "phonetic": "/ˌkɒm.prɪˈhen.sɪv/",
|
||
"translation": "всесторонний, исчерпывающий",
|
||
"sentence": "The documentation provides a ___ guide to all SDK methods.",
|
||
"options": ["comprehensive", "reluctant", "arbitrary", "preliminary"],
|
||
"explanation": "Comprehensive (исчерпывающий) — охватывающий предмет целиком и во всех деталях.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "profound", "pos": "adjective", "phonetic": "/prəˈfaʊnd/",
|
||
"translation": "глубокий, фундаментальный",
|
||
"sentence": "The discovery of antibiotics had a ___ impact on human longevity.",
|
||
"options": ["profound", "reluctant", "arbitrary", "plausible"],
|
||
"explanation": "Profound (глубокий) — оказывающий огромное и фундаментальное влияние.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "contradictory", "pos": "adjective", "phonetic": "/ˌkɒn.trəˈdɪk.tər.i/",
|
||
"translation": "противоречивый",
|
||
"sentence": "The witness gave two completely ___ accounts of what occurred.",
|
||
"options": ["contradictory", "versatile", "preliminary", "resilient"],
|
||
"explanation": "Contradictory (противоречивый) — взаимоисключающий.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "enhance", "pos": "verb", "phonetic": "/ɪnˈhɑːns/",
|
||
"translation": "усиливать, повышать качество",
|
||
"sentence": "Adding indexes to foreign keys will significantly ___ query speed.",
|
||
"options": ["enhance", "diminish", "terminate", "undermine"],
|
||
"explanation": "Enhance (усиливать) — увеличивать качество, силу или ценность.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "facilitate", "pos": "verb", "phonetic": "/fəˈsɪl.ɪ.teɪt/",
|
||
"translation": "облегчать, способствовать",
|
||
"sentence": "Clean APIs ___ integration with third-party mobile applications.",
|
||
"options": ["facilitate", "undermine", "fluctuate", "terminate"],
|
||
"explanation": "Facilitate (способствовать) — делать процесс проще и быстрее.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "advocate", "pos": "verb", "phonetic": "/ˈæd.və.keɪt/",
|
||
"translation": "выступать в защиту, отстаивать",
|
||
"sentence": "Senior developers strongly ___ for automated testing pipelines.",
|
||
"options": ["advocate", "terminate", "undermine", "fluctuate"],
|
||
"explanation": "Advocate (отстаивать) — публично поддерживать идею или принцип.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "diminish", "pos": "verb", "phonetic": "/dɪˈmɪn.ɪʃ/",
|
||
"translation": "уменьшаться, ослабевать",
|
||
"sentence": "Regular backups help to ___ the risks of sudden data loss.",
|
||
"options": ["diminish", "enhance", "facilitate", "advocate"],
|
||
"explanation": "Diminish (уменьшать) — сокращать величину, масштаб или силу.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "feasible", "pos": "adjective", "phonetic": "/ˈfiː.zə.bəl/",
|
||
"translation": "осуществимый, реальный",
|
||
"sentence": "Completing this migration in one sprint is technically ___.",
|
||
"options": ["feasible", "reluctant", "arbitrary", "ambiguous"],
|
||
"explanation": "Feasible (осуществимый) — вполне выполнимый при имеющихся ресурсах.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "substantial", "pos": "adjective", "phonetic": "/səbˈstæn.ʃəl/",
|
||
"translation": "существенный, значительный",
|
||
"sentence": "We noticed a ___ reduction in server memory usage after tuning.",
|
||
"options": ["substantial", "preliminary", "reluctant", "arbitrary"],
|
||
"explanation": "Substantial (значительный) — весомый по объему или значению.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "subsequent", "pos": "adjective", "phonetic": "/ˈsʌb.sɪ.kwənt/",
|
||
"translation": "последующий",
|
||
"sentence": "The initial build broke, but all ___ builds passed cleanly.",
|
||
"options": ["subsequent", "reluctant", "arbitrary", "versatile"],
|
||
"explanation": "Subsequent (последующий) — происходящий после чего-либо.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "perceive", "pos": "verb", "phonetic": "/pəˈsiːv/",
|
||
"translation": "воспринимать, осознавать",
|
||
"sentence": "Different users ___ software latency in very distinct ways.",
|
||
"options": ["perceive", "allocate", "terminate", "undermine"],
|
||
"explanation": "Perceive (воспринимать) — осознавать через органы чувств или разум.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "convey", "pos": "verb", "phonetic": "/kənˈveɪ/",
|
||
"translation": "передавать, выражать (мысль)",
|
||
"sentence": "Clear charts can ___ complex statistical insights at a glance.",
|
||
"options": ["convey", "allocate", "terminate", "fluctuate"],
|
||
"explanation": "Convey (передавать) — делать мысль или значение понятными другим.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "crucial", "pos": "adjective", "phonetic": "/ˈkruː.ʃəl/",
|
||
"translation": "решающий, критически важный",
|
||
"sentence": "Code reviews are ___ for maintaining high quality in shared repos.",
|
||
"options": ["crucial", "arbitrary", "reluctant", "plausible"],
|
||
"explanation": "Crucial (критически важный) — определяющий успех или провал.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "deduce", "pos": "verb", "phonetic": "/dɪˈdʒuːs/",
|
||
"translation": "делать логический вывод, выводить",
|
||
"sentence": "From the error stack trace, we can easily ___ the exact root cause.",
|
||
"options": ["deduce", "allocate", "undermine", "fluctuate"],
|
||
"explanation": "Deduce (делать вывод) — приходить к умозаключению на основе фактов.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "discrete", "pos": "adjective", "phonetic": "/dɪˈskriːt/",
|
||
"translation": "дискретный, раздельный, обособленный",
|
||
"sentence": "The protocol breaks streaming data into small ___ chunks.",
|
||
"options": ["discrete", "reluctant", "arbitrary", "plausible"],
|
||
"explanation": "Discrete (дискретный) — состоящий из отдельных четких единиц.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "explicit", "pos": "adjective", "phonetic": "/ɪkˈsplɪs.ɪt/",
|
||
"translation": "явный, четко выраженный",
|
||
"sentence": "The configuration provides ___ timeout limits for network calls.",
|
||
"options": ["explicit", "ambiguous", "reluctant", "arbitrary"],
|
||
"explanation": "Explicit (явный, точный) — сформулированный прямо и без двусмысленности.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "fundamental", "pos": "adjective", "phonetic": "/ˌfʌn.dəˈmen.təl/",
|
||
"translation": "фундаментальный, основополагающий",
|
||
"sentence": "Understanding pointers is a ___ concept in systems programming.",
|
||
"options": ["fundamental", "arbitrary", "reluctant", "preliminary"],
|
||
"explanation": "Fundamental (основополагающий) — служащий базисом для всего остального.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "hierarchical", "pos": "adjective", "phonetic": "/ˌhaɪəˈrɑː.kɪ.kəl/",
|
||
"translation": "иерархический",
|
||
"sentence": "Filesystems organize documents in a strict ___ folder tree.",
|
||
"options": ["hierarchical", "arbitrary", "reluctant", "plausible"],
|
||
"explanation": "Hierarchical (иерархический) — построенный по принципу соподчинения уровней.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "implicit", "pos": "adjective", "phonetic": "/ɪmˈplɪs.ɪt/",
|
||
"translation": "неявный, подразумеваемый",
|
||
"sentence": "There is an ___ trust assumption between these internal services.",
|
||
"options": ["implicit", "explicit", "arbitrary", "versatile"],
|
||
"explanation": "Implicit (неявный, подразумеваемый) — не выраженный прямо, но очевидный по смыслу.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "inherent", "pos": "adjective", "phonetic": "/ɪnˈher.ənt/",
|
||
"translation": "присущий, неотъемлемый",
|
||
"sentence": "Network latency is an ___ property of distributed cloud systems.",
|
||
"options": ["inherent", "preliminary", "reluctant", "arbitrary"],
|
||
"explanation": "Inherent (присущий) — составляющий неотъемлемую природную черту объекта.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "integrate", "pos": "verb", "phonetic": "/ˈɪn.tɪ.ɡreɪt/",
|
||
"translation": "интегрировать, объединять",
|
||
"sentence": "We want to ___ the payment gateway seamlessly into the checkout.",
|
||
"options": ["integrate", "undermine", "terminate", "fluctuate"],
|
||
"explanation": "Integrate (интегрировать) — соединять части в единое целое.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "justify", "pos": "verb", "phonetic": "/ˈdʒʌs.tɪ.faɪ/",
|
||
"translation": "оправдывать, обосновывать",
|
||
"sentence": "You should bring performance metrics to ___ the rewrite.",
|
||
"options": ["justify", "undermine", "terminate", "fluctuate"],
|
||
"explanation": "Justify (обосновывать) — приводить разумные доводы в защиту решения.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "preliminary", "pos": "adjective", "phonetic": "/prɪˈlɪm.ɪ.nər.i/",
|
||
"translation": "предварительный",
|
||
"sentence": "These are only the ___ benchmark results; full tests run tonight.",
|
||
"options": ["preliminary", "reluctant", "arbitrary", "versatile"],
|
||
"explanation": "Preliminary (предварительный) — предшествующий окончательному этапу.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "random", "pos": "adjective", "phonetic": "/ˈræn.dəm/",
|
||
"translation": "случайный, произвольный",
|
||
"sentence": "The program selects test samples using a uniform ___ distribution.",
|
||
"options": ["random", "reluctant", "plausible", "resilient"],
|
||
"explanation": "Random (случайный) — выбранный без закономерности или предвзятости.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "reluctant", "pos": "adjective", "phonetic": "/rɪˈlʌk.tənt/",
|
||
"translation": "неохотный, сомневающийся",
|
||
"sentence": "He was ___ to rewrite working code without clear justification.",
|
||
"options": ["reluctant", "resilient", "versatile", "plausible"],
|
||
"explanation": "Reluctant (неохотный) — делающий что-либо с неохотой или сомнением.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "simultaneous", "pos": "adjective", "phonetic": "/ˌsɪm.əlˈteɪ.ni.əs/",
|
||
"translation": "одновременный",
|
||
"sentence": "The database engine easily handles hundreds of ___ read queries.",
|
||
"options": ["simultaneous", "reluctant", "arbitrary", "preliminary"],
|
||
"explanation": "Simultaneous (одновременный) — происходящий в одно и то же мгновение.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "undermine", "pos": "verb", "phonetic": "/ˌʌn.dəˈmaɪn/",
|
||
"translation": "подрывать, ослаблять",
|
||
"sentence": "Skipping validation steps will inevitably ___ system reliability.",
|
||
"options": ["undermine", "facilitate", "enhance", "advocate"],
|
||
"explanation": "Undermine (подрывать) — постепенно разрушать или ослаблять основы.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "accommodate", "pos": "verb", "phonetic": "/əˈkɒm.ə.deɪt/",
|
||
"translation": "вмещать, приспосабливать",
|
||
"sentence": "The new server cluster can easily ___ millions of daily visitors.",
|
||
"options": ["accommodate", "undermine", "terminate", "fluctuate"],
|
||
"explanation": "Accommodate (вмещать) — иметь достаточно места или ресурсов для кого-либо.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "allocate", "pos": "verb", "phonetic": "/ˈæl.ə.keɪt/",
|
||
"translation": "выделять (ресурсы, память)",
|
||
"sentence": "We need to ___ sufficient RAM for the in-memory cache.",
|
||
"options": ["allocate", "undermine", "terminate", "fluctuate"],
|
||
"explanation": "Allocate (выделять) — распределять или закреплять ресурсы под задачу.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "arbitrary", "pos": "adjective", "phonetic": "/ˈɑː.bɪ.trər.i/",
|
||
"translation": "произвольный, случайный (без четкого правила)",
|
||
"sentence": "Do not pick an ___ timeout value; measure actual latencies.",
|
||
"options": ["arbitrary", "resilient", "coherent", "versatile"],
|
||
"explanation": "Arbitrary (произвольный) — основанный на случайном выборе, а не на правиле.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "consensus", "pos": "noun", "phonetic": "/kənˈsen.səs/",
|
||
"translation": "консенсус, общее согласие",
|
||
"sentence": "The architecture committee finally reached a general ___.",
|
||
"options": ["consensus", "ambiguity", "contradiction", "compromise"],
|
||
"explanation": "Consensus (консенсус) — общее единогласие мнений всех сторон.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "fluctuate", "pos": "verb", "phonetic": "/ˈflʌk.tʃu.eɪt/",
|
||
"translation": "колебаться, меняться",
|
||
"sentence": "Internet speeds can ___ depending on peak network hours.",
|
||
"options": ["fluctuate", "undermine", "terminate", "advocate"],
|
||
"explanation": "Fluctuate (колебаться) — непрерывно изменяться вверх и вниз.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "plausible", "pos": "adjective", "phonetic": "/ˈplɔː.zə.bəl/",
|
||
"translation": "правдоподобный, вероятный",
|
||
"sentence": "His explanation for the memory leak sounded completely ___.",
|
||
"options": ["plausible", "reluctant", "arbitrary", "preliminary"],
|
||
"explanation": "Plausible (правдоподобный) — заслуживающий доверия, вероятный.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "deteriorate", "pos": "verb", "phonetic": "/dɪˈtɪə.ri.ə.reɪt/",
|
||
"translation": "ухудшаться",
|
||
"sentence": "Without prompt maintenance, old bridges rapidly ___.",
|
||
"options": ["deteriorate", "enhance", "facilitate", "integrate"],
|
||
"explanation": "Deteriorate (ухудшаться) — становиться хуже по качеству или состоянию.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "discrepancy", "pos": "noun", "phonetic": "/dɪˈskrep.ən.si/",
|
||
"translation": "расхождение, несоответствие",
|
||
"sentence": "The audit revealed an unexplained ___ in the quarterly ledgers.",
|
||
"options": ["discrepancy", "consensus", "compromise", "ambiguity"],
|
||
"explanation": "Discrepancy (несоответствие) — различие между данными, которые должны совпадать.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "eligible", "pos": "adjective", "phonetic": "/ˈel.ɪ.dʒə.bəl/",
|
||
"translation": "имеющий право, подходящий",
|
||
"sentence": "Only full-time students are ___ to apply for the grant.",
|
||
"options": ["eligible", "reluctant", "arbitrary", "plausible"],
|
||
"explanation": "Eligible (имеющий право) — отвечающий установленным критериям для участия.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "lucrative", "pos": "adjective", "phonetic": "/ˈluː.krə.tɪv/",
|
||
"translation": "прибыльный, доходный",
|
||
"sentence": "The entrepreneur signed a remarkably ___ contract overseas.",
|
||
"options": ["lucrative", "profound", "vulnerable", "preliminary"],
|
||
"explanation": "Lucrative (прибыльный) — приносящий большую финансовую выгоду.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "meticulous", "pos": "adjective", "phonetic": "/məˈtɪk.jə.ləs/",
|
||
"translation": "дотошный, скрупулезный",
|
||
"sentence": "The researcher kept ___ notes during every phase of the trial.",
|
||
"options": ["meticulous", "random", "arbitrary", "contradictory"],
|
||
"explanation": "Meticulous (скрупулезный) — проявляющий исключительное внимание к каждой детали.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "novel", "pos": "adjective", "phonetic": "/ˈnɒv.əl/",
|
||
"translation": "новаторский, оригинальный",
|
||
"sentence": "The scientists proposed a ___ approach to carbon sequestration.",
|
||
"options": ["novel", "coherent", "inevitable", "resilient"],
|
||
"explanation": "Novel (новаторский) — принципиально новый, ранее не применявшийся.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "relentless", "pos": "adjective", "phonetic": "/rɪˈlent.ləs/",
|
||
"translation": "неумолимый, непрекращающийся",
|
||
"sentence": "Success required years of ___ discipline and daily focus.",
|
||
"options": ["relentless", "reluctant", "arbitrary", "preliminary"],
|
||
"explanation": "Relentless (непрекращающийся) — продолжающийся с неослабевающей силой.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "scrutinize", "pos": "verb", "phonetic": "/ˈskruː.tɪ.naɪz/",
|
||
"translation": "тщательно исследовать, изучать",
|
||
"sentence": "Regulators will closely ___ the proposed merger of both banks.",
|
||
"options": ["scrutinize", "diminish", "undermine", "fluctuate"],
|
||
"explanation": "Scrutinize (тщательно исследовать) — подвергать глубокому пристальному анализу.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "subtle", "pos": "adjective", "phonetic": "/ˈsʌt.əl/",
|
||
"translation": "тонкий, едва уловимый",
|
||
"sentence": "There is a ___ nuance between these two grammatical forms.",
|
||
"options": ["subtle", "substantial", "fundamental", "explicit"],
|
||
"explanation": "Subtle (тонкий, неуловимый) — едва заметный, требующий чуткости для восприятия.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "tangible", "pos": "adjective", "phonetic": "/ˈtæn.dʒə.bəl/",
|
||
"translation": "осязаемый, реальный",
|
||
"sentence": "The new training program yielded ___ improvements in morale.",
|
||
"options": ["tangible", "ambiguous", "arbitrary", "hierarchical"],
|
||
"explanation": "Tangible (осязаемый) — конкретный, явный, доступный для непосредственной оценки.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "ubiquitous", "pos": "adjective", "phonetic": "/juːˈbɪk.wɪ.təs/",
|
||
"translation": "вездесущий, повсеместный",
|
||
"sentence": "Smartphones have become ___ in modern urban society.",
|
||
"options": ["ubiquitous", "discrete", "reluctant", "preliminary"],
|
||
"explanation": "Ubiquitous (вездесущий) — встречающийся повсюду одновременно.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "unprecedented", "pos": "adjective", "phonetic": "/ʌnˈpres.ɪ.den.tɪd/",
|
||
"translation": "беспрецедентный",
|
||
"sentence": "The pandemic caused an ___ shock to global supply chains.",
|
||
"options": ["unprecedented", "coherent", "contradictory", "plausible"],
|
||
"explanation": "Unprecedented (беспрецедентный) — не имевший аналогов в прошлом.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "viable", "pos": "adjective", "phonetic": "/ˈvaɪ.ə.bəl/",
|
||
"translation": "жизнеспособный",
|
||
"sentence": "Solar power has become a commercially ___ source of energy.",
|
||
"options": ["viable", "arbitrary", "reluctant", "inevitable"],
|
||
"explanation": "Viable (жизнеспособный) — способный успешно функционировать и развиваться.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "withstand", "pos": "verb", "phonetic": "/wɪðˈstænd/",
|
||
"translation": "выдерживать, противостоять",
|
||
"sentence": "The newly engineered structure can ___ severe earthquakes.",
|
||
"options": ["withstand", "diminish", "undermine", "deteriorate"],
|
||
"explanation": "Withstand (выдерживать) — стойко сопротивляться разрушительному воздействию.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "yield", "pos": "verb", "phonetic": "/jiːld/",
|
||
"translation": "приносить (результат, доход)",
|
||
"sentence": "Long-term compounding investments ___ significant dividends.",
|
||
"options": ["yield", "undermine", "deduce", "scrutinize"],
|
||
"explanation": "Yield (приносить плоды) — давать прибыль, урожай или практический результат.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "zealous", "pos": "adjective", "phonetic": "/ˈzel.əs/",
|
||
"translation": "ревностный, ярый",
|
||
"sentence": "The attorney was a ___ defender of fundamental civil liberties.",
|
||
"options": ["zealous", "complacent", "reluctant", "arbitrary"],
|
||
"explanation": "Zealous (ревностный) — проявляющий горячую увлеченность и преданность делу.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "ambiguous", "pos": "adjective", "phonetic": "/æmˈbɪɡ.ju.əs/",
|
||
"translation": "двусмысленный, неясный",
|
||
"sentence": "The legal wording of the agreement was intentionally ___.",
|
||
"options": ["ambiguous", "explicit", "coherent", "tangible"],
|
||
"explanation": "Ambiguous (двусмысленный) — допускающий двоякое или нечеткое толкование.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "benevolent", "pos": "adjective", "phonetic": "/bəˈnev.əl.ənt/",
|
||
"translation": "благожелательный, великодушный",
|
||
"sentence": "The charity relies on gifts from ___ private donors.",
|
||
"options": ["benevolent", "relentless", "arbitrary", "hierarchical"],
|
||
"explanation": "Benevolent (благожелательный) — настроенный доброжелательно, стремящийся делать добро.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "complacent", "pos": "adjective", "phonetic": "/kəmˈpleɪ.sənt/",
|
||
"translation": "самодовольный, беспечный",
|
||
"sentence": "After consecutive victories, the team grew dangerously ___.",
|
||
"options": ["complacent", "meticulous", "diligent", "resilient"],
|
||
"explanation": "Complacent (самодовольный) — чрезмерно удовлетворенный собой и потерявший бдительность.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "diligent", "pos": "adjective", "phonetic": "/ˈdɪl.ɪ.dʒənt/",
|
||
"translation": "прилежный, старательный",
|
||
"sentence": "Her ___ pursuit of scientific inquiry earned international acclaim.",
|
||
"options": ["diligent", "arbitrary", "reluctant", "subsequent"],
|
||
"explanation": "Diligent (прилежный) — усердно и добросовестно выполняющий работу.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "ephemeral", "pos": "adjective", "phonetic": "/ɪˈfem.ər.əl/",
|
||
"translation": "мимолетный, недолговечный",
|
||
"sentence": "Social media fame is often ___ and vanishes overnight.",
|
||
"options": ["ephemeral", "substantial", "fundamental", "comprehensive"],
|
||
"explanation": "Ephemeral (мимолетный) — длящийся лишь краткий миг.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "formidable", "pos": "adjective", "phonetic": "/ˈfɔː.mɪ.də.bəl/",
|
||
"translation": "грозный, внушительный",
|
||
"sentence": "The defending chess champion represents a ___ adversary.",
|
||
"options": ["formidable", "arbitrary", "discrete", "vulnerable"],
|
||
"explanation": "Formidable (грозный, внушительный) — внушающий уважение или страх своей мощью.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "gregarious", "pos": "adjective", "phonetic": "/ɡrɪˈɡeə.ri.əs/",
|
||
"translation": "общительный, стадный",
|
||
"sentence": "Dolphins are highly social and ___ marine mammals.",
|
||
"options": ["gregarious", "reluctant", "arbitrary", "preliminary"],
|
||
"explanation": "Gregarious (общительный) — любящий находиться среди сородичей или людей.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "homogeneous", "pos": "adjective", "phonetic": "/ˌhɒm.əˈdʒiː.ni.əs/",
|
||
"translation": "однородный, гомогенный",
|
||
"sentence": "The modern metropolis is far from a culturally ___ enclave.",
|
||
"options": ["homogeneous", "contradictory", "arbitrary", "ubiquitous"],
|
||
"explanation": "Homogeneous (однородный) — состоящий из одинаковых по составу частей.",
|
||
},
|
||
{
|
||
"level": "B2", "term": "innovative", "pos": "adjective", "phonetic": "/ˈɪn.ə.və.tɪv/",
|
||
"translation": "новаторский, передовой",
|
||
"sentence": "The startup patented an ___ algorithm for real-time translation.",
|
||
"options": ["innovative", "arbitrary", "complacent", "plausible"],
|
||
"explanation": "Innovative (новаторский) — использующий передовые оригинальные методы.",
|
||
},
|
||
]
|
||
|
||
|
||
def seed_cefr_questions(conn: sqlite3.Connection) -> int:
|
||
"""
|
||
Populates cefr_questions table with curated Oxford 3000/5000 benchmark questions.
|
||
Safe and idempotent (using INSERT OR IGNORE).
|
||
"""
|
||
inserted = 0
|
||
for q in CURATED_CEFR_QUESTIONS:
|
||
options_str = json.dumps(q["options"], ensure_ascii=False)
|
||
cursor = conn.execute(
|
||
"""
|
||
INSERT OR IGNORE INTO cefr_questions (
|
||
level, term, translation, pos, phonetic, sentence, options_json, explanation
|
||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||
""",
|
||
(
|
||
q["level"],
|
||
q["term"],
|
||
q["translation"],
|
||
q.get("pos", ""),
|
||
q.get("phonetic", ""),
|
||
q["sentence"],
|
||
options_str,
|
||
q.get("explanation", ""),
|
||
),
|
||
)
|
||
if cursor.rowcount > 0:
|
||
inserted += 1
|
||
return inserted
|
||
|
||
|
||
def get_cefr_level_summaries(conn: sqlite3.Connection, user_id: int) -> List[Dict[str, Any]]:
|
||
"""
|
||
Computes real-time progress metrics for each CEFR level (A1, A2, B1, B2) for user.
|
||
"""
|
||
summaries = []
|
||
level_titles = {
|
||
"A1": "Beginner (Начальный)",
|
||
"A2": "Elementary (Базовый)",
|
||
"B1": "Intermediate (Средний)",
|
||
"B2": "Upper-Intermediate (Продвинутый)",
|
||
}
|
||
|
||
for lvl in CEFR_LEVELS:
|
||
total_q = conn.execute(
|
||
"SELECT COUNT(*) FROM cefr_questions WHERE level = ?", (lvl,)
|
||
).fetchone()[0]
|
||
|
||
row = conn.execute(
|
||
"""
|
||
SELECT
|
||
SUM(CASE WHEN is_mastered = 1 THEN 1 ELSE 0 END) as mastered_cnt,
|
||
SUM(CASE WHEN mistakes > 0 AND is_mastered = 0 THEN 1 ELSE 0 END) as in_learning_cnt,
|
||
COUNT(*) as attempted_cnt
|
||
FROM cefr_progress
|
||
WHERE user_id = ? AND level = ?
|
||
""",
|
||
(user_id, lvl),
|
||
).fetchone()
|
||
|
||
mastered = row["mastered_cnt"] or 0
|
||
in_learning = row["in_learning_cnt"] or 0
|
||
attempted = row["attempted_cnt"] or 0
|
||
|
||
# Also count active SRS cards with this level tag
|
||
srs_tag = f"level-{lvl.lower()}"
|
||
active_vocab_cards = conn.execute(
|
||
"""
|
||
SELECT COUNT(*) FROM vocabulary_cards
|
||
WHERE user_id = ? AND tags LIKE ?
|
||
""",
|
||
(user_id, f"%{srs_tag}%"),
|
||
).fetchone()[0]
|
||
|
||
pct = int(round((mastered / total_q) * 100)) if total_q > 0 else 0
|
||
|
||
summaries.append({
|
||
"level": lvl,
|
||
"title": level_titles.get(lvl, lvl),
|
||
"total_questions": total_q,
|
||
"mastered_count": mastered,
|
||
"in_learning_count": in_learning,
|
||
"attempted_count": attempted,
|
||
"srs_cards_count": active_vocab_cards,
|
||
"progress_percent": pct,
|
||
})
|
||
|
||
return summaries
|
||
|
||
|
||
def get_cefr_quiz_batch(
|
||
conn: sqlite3.Connection,
|
||
user_id: int,
|
||
level: str,
|
||
count: int = 10,
|
||
mode: str = "all",
|
||
) -> List[Dict[str, Any]]:
|
||
"""
|
||
Fetches next batch of Cloze Tap questions for the selected level.
|
||
If mode == 'mistakes', returns questions where user made mistakes and hasn't mastered yet.
|
||
Otherwise prioritizes unattempted questions, then review of mistakes.
|
||
Options are randomized per question. Correct answer is kept hidden from client.
|
||
"""
|
||
clean_level = level.upper().strip()
|
||
if clean_level not in CEFR_LEVELS:
|
||
clean_level = "A1"
|
||
count = max(1, min(count, 30))
|
||
|
||
if mode == "mistakes":
|
||
rows = conn.execute(
|
||
"""
|
||
SELECT q.id, q.level, q.sentence, q.translation, q.pos, q.options_json,
|
||
q.source_book_id, q.source_book_title, q.source_chapter_title
|
||
FROM cefr_questions q
|
||
JOIN cefr_progress p ON q.id = p.question_id
|
||
WHERE p.user_id = ? AND q.level = ? AND p.is_mastered = 0 AND p.mistakes > 0
|
||
ORDER BY p.last_tested_at ASC
|
||
LIMIT ?
|
||
""",
|
||
(user_id, clean_level, count),
|
||
).fetchall()
|
||
else:
|
||
# 1. Unattempted questions
|
||
rows = conn.execute(
|
||
"""
|
||
SELECT q.id, q.level, q.sentence, q.translation, q.pos, q.options_json,
|
||
q.source_book_id, q.source_book_title, q.source_chapter_title
|
||
FROM cefr_questions q
|
||
LEFT JOIN cefr_progress p ON q.id = p.question_id AND p.user_id = ?
|
||
WHERE q.level = ? AND (p.question_id IS NULL OR p.is_mastered = 0)
|
||
ORDER BY CASE WHEN p.question_id IS NULL THEN 0 ELSE 1 END,
|
||
p.last_tested_at ASC,
|
||
q.id DESC
|
||
LIMIT ?
|
||
""",
|
||
(user_id, clean_level, count),
|
||
).fetchall()
|
||
|
||
# If not enough, fill with any from this level
|
||
if len(rows) < count:
|
||
needed = count - len(rows)
|
||
existing_ids = [r["id"] for r in rows]
|
||
placeholders = ",".join(["?"] * len(existing_ids)) if existing_ids else "-1"
|
||
extra = conn.execute(
|
||
f"""
|
||
SELECT q.id, q.level, q.sentence, q.translation, q.pos, q.options_json,
|
||
q.source_book_id, q.source_book_title, q.source_chapter_title
|
||
FROM cefr_questions q
|
||
WHERE q.level = ? AND q.id NOT IN ({placeholders})
|
||
ORDER BY q.id DESC
|
||
LIMIT ?
|
||
""",
|
||
[clean_level] + existing_ids + [needed],
|
||
).fetchall()
|
||
rows = list(rows) + list(extra)
|
||
|
||
quiz_items = []
|
||
for r in rows:
|
||
try:
|
||
options = json.loads(r["options_json"])
|
||
except Exception:
|
||
options = []
|
||
# Randomize options order
|
||
shuffled_options = list(options)
|
||
random.shuffle(shuffled_options)
|
||
|
||
item = {
|
||
"id": r["id"],
|
||
"level": r["level"],
|
||
"sentence": r["sentence"],
|
||
"clue": r["translation"],
|
||
"pos": r["pos"] or "",
|
||
"options": shuffled_options,
|
||
}
|
||
if "source_book_title" in r.keys() and r["source_book_title"]:
|
||
item["source_book_title"] = r["source_book_title"]
|
||
item["source_chapter_title"] = r["source_chapter_title"] or ""
|
||
quiz_items.append(item)
|
||
|
||
return quiz_items
|
||
|
||
|
||
def resolve_context_sentence_for_term(
|
||
conn: sqlite3.Connection,
|
||
term: str,
|
||
candidate_sentence: str = "",
|
||
) -> str:
|
||
"""
|
||
Resolves the best authentic context sentence for a given term:
|
||
1. If candidate_sentence contains the term, use it (with ___ replaced).
|
||
2. Look up in cefr_questions specifically for this term.
|
||
3. Look up in books table for an authentic sentence containing this term.
|
||
4. Fallback to clean natural sentence.
|
||
"""
|
||
clean_term = term.strip()
|
||
if not clean_term:
|
||
return ""
|
||
|
||
# 1. If candidate_sentence already contains this term (and is a complete sentence)
|
||
if candidate_sentence:
|
||
cand_clean = candidate_sentence.strip()
|
||
is_complete = bool(re.search(r"[.!?]['\"”’»)]*$", cand_clean)) and not bool(
|
||
re.search(r"\b(?:Mr|Mrs|Ms|Miss|Dr|Prof|St|Jr|Sr|[A-Za-z])\.['\"”’»)]*$", cand_clean, re.IGNORECASE)
|
||
)
|
||
if is_complete and re.search(rf"\b{re.escape(clean_term)}\b", cand_clean, re.IGNORECASE):
|
||
return re.sub(r"\s+", " ", cand_clean.replace("___", clean_term)).strip()
|
||
|
||
# 2. Look up in cefr_questions specifically for this term
|
||
try:
|
||
q_row = conn.execute(
|
||
"SELECT sentence FROM cefr_questions WHERE lower(trim(term)) = lower(trim(?)) ORDER BY id ASC LIMIT 1",
|
||
(clean_term,),
|
||
).fetchone()
|
||
if q_row and q_row["sentence"]:
|
||
return re.sub(r"\s+", " ", q_row["sentence"].replace("___", clean_term)).strip()
|
||
except Exception:
|
||
pass
|
||
|
||
# 3. Look up in books table
|
||
try:
|
||
books = conn.execute("SELECT chapters_json FROM books ORDER BY id DESC LIMIT 50").fetchall()
|
||
for b in books:
|
||
try:
|
||
chapters = json.loads(b["chapters_json"])
|
||
except Exception:
|
||
continue
|
||
for ch in chapters:
|
||
content = ch.get("content", "")
|
||
if clean_term.lower() in content.lower():
|
||
from app.miner import robust_sentence_split
|
||
for s_clean in robust_sentence_split(content):
|
||
if 20 <= len(s_clean) <= 240 and re.search(rf"\b{re.escape(clean_term)}\b", s_clean, re.IGNORECASE):
|
||
return s_clean.strip()
|
||
except Exception:
|
||
pass
|
||
|
||
# 4. If candidate_sentence had '___' and came from this term
|
||
if candidate_sentence and "___" in candidate_sentence:
|
||
return re.sub(r"\s+", " ", candidate_sentence.replace("___", clean_term)).strip()
|
||
|
||
return f"Using '{clean_term}' in meaningful sentences reinforces active recall and long-term fluency."
|
||
|
||
|
||
def process_cefr_answer(
|
||
conn: sqlite3.Connection,
|
||
user_id: int,
|
||
question_id: int,
|
||
selected_option: str,
|
||
) -> Dict[str, Any]:
|
||
"""
|
||
Validates user's Cloze Tap choice.
|
||
- If correct: marks question mastered.
|
||
- If mistake:
|
||
- marks mistake in cefr_progress
|
||
- AUTOMATIC GAP INGESTION: creates or updates vocabulary_card in user's dictionary
|
||
with srs_state='learning', interval=0, next_review=now, level tags so it appears
|
||
in daily morning SRS training!
|
||
"""
|
||
q_row = conn.execute(
|
||
"SELECT * FROM cefr_questions WHERE id = ?", (question_id,)
|
||
).fetchone()
|
||
|
||
if not q_row:
|
||
return {"error": "Question not found"}
|
||
|
||
target_term = q_row["term"].strip()
|
||
selected_clean = (selected_option or "").strip()
|
||
is_correct = selected_clean.lower() == target_term.lower()
|
||
explanation = q_row["explanation"] or ""
|
||
level = q_row["level"]
|
||
phonetic = q_row["phonetic"] or ""
|
||
pos = q_row["pos"] or ""
|
||
translation = q_row["translation"] or ""
|
||
sentence_with_term = q_row["sentence"].replace("___", target_term)
|
||
|
||
# 1. Update or Insert into cefr_progress
|
||
prog_row = conn.execute(
|
||
"SELECT * FROM cefr_progress WHERE user_id = ? AND question_id = ?",
|
||
(user_id, question_id),
|
||
).fetchone()
|
||
|
||
if prog_row:
|
||
new_attempts = prog_row["attempts"] + 1
|
||
new_mistakes = prog_row["mistakes"] + (0 if is_correct else 1)
|
||
new_mastered = 1 if is_correct else 0
|
||
conn.execute(
|
||
"""
|
||
UPDATE cefr_progress
|
||
SET is_mastered = ?, attempts = ?, mistakes = ?, last_tested_at = CURRENT_TIMESTAMP
|
||
WHERE id = ?
|
||
""",
|
||
(new_mastered, new_attempts, new_mistakes, prog_row["id"]),
|
||
)
|
||
else:
|
||
conn.execute(
|
||
"""
|
||
INSERT INTO cefr_progress (user_id, question_id, level, is_mastered, attempts, mistakes, last_tested_at)
|
||
VALUES (?, ?, ?, ?, 1, ?, CURRENT_TIMESTAMP)
|
||
""",
|
||
(user_id, question_id, level, 1 if is_correct else 0, 0 if is_correct else 1),
|
||
)
|
||
|
||
# 2. Activity log entry for heatmap streak calculation
|
||
target_card_info = None
|
||
selected_card_info = None
|
||
|
||
if not is_correct:
|
||
# =====================================================================
|
||
# DUAL AUTOMATED GAP INGESTION (Crucial Pedagogical Requirement)
|
||
# 1. Correct target word -> goes 100% to vocabulary with its sentence
|
||
# 2. Chosen wrong word -> also goes to vocabulary with its OWN context!
|
||
# =====================================================================
|
||
target_ctx = resolve_context_sentence_for_term(conn, target_term, sentence_with_term)
|
||
target_card_info = _ingest_card_for_user(
|
||
conn,
|
||
user_id=user_id,
|
||
term=target_term,
|
||
translation=translation,
|
||
phonetic=phonetic,
|
||
pos=pos,
|
||
context_sentence=target_ctx,
|
||
explanation=explanation,
|
||
level=level,
|
||
tag_suffix="test-mistake",
|
||
custom_note=f"Верный ответ из теста уровня {level}",
|
||
)
|
||
|
||
# Ingest the erroneously selected option (the user's mistaken choice)
|
||
sel_row = conn.execute(
|
||
"SELECT term, translation, phonetic, pos FROM offline_dictionary WHERE term = ? COLLATE NOCASE",
|
||
(selected_clean,),
|
||
).fetchone()
|
||
sel_trans = sel_row["translation"] if sel_row else selected_clean
|
||
sel_phon = sel_row["phonetic"] if sel_row else ""
|
||
sel_pos = sel_row["pos"] if sel_row else ""
|
||
sel_ctx = resolve_context_sentence_for_term(conn, selected_clean)
|
||
|
||
selected_card_info = _ingest_card_for_user(
|
||
conn,
|
||
user_id=user_id,
|
||
term=selected_clean,
|
||
translation=sel_trans,
|
||
phonetic=sel_phon,
|
||
pos=sel_pos,
|
||
context_sentence=sel_ctx,
|
||
explanation=f"Выбрано по ошибке в вопросе про '{target_term}'",
|
||
level=level,
|
||
tag_suffix="test-mistake-chosen",
|
||
custom_note=f"Ошибочно выбрано вместо '{target_term}' (тест {level})",
|
||
)
|
||
else:
|
||
# On correct answer, if user has this card in library, record a positive review log
|
||
existing_card = conn.execute(
|
||
"SELECT id FROM vocabulary_cards WHERE user_id = ? AND lower(trim(term)) = ?",
|
||
(user_id, target_term.lower()),
|
||
).fetchone()
|
||
if existing_card:
|
||
conn.execute(
|
||
"""
|
||
INSERT INTO srs_logs (user_id, card_id, rating, interval, ease, reviewed_at)
|
||
VALUES (?, ?, 4, 1, 2.5, CURRENT_TIMESTAMP)
|
||
""",
|
||
(user_id, existing_card["id"]),
|
||
)
|
||
|
||
# 3. Build rich options breakdown for ALL 4 options
|
||
try:
|
||
raw_options = json.loads(q_row["options_json"])
|
||
except Exception:
|
||
raw_options = [target_term]
|
||
|
||
options_breakdown = []
|
||
for opt in raw_options:
|
||
opt_clean = opt.strip()
|
||
is_target = (opt_clean.lower() == target_term.lower())
|
||
was_selected = (opt_clean.lower() == selected_clean.lower())
|
||
|
||
if is_target:
|
||
opt_trans = translation
|
||
opt_phon = phonetic
|
||
opt_pos = pos
|
||
else:
|
||
opt_row = conn.execute(
|
||
"SELECT term, translation, phonetic, pos FROM offline_dictionary WHERE term = ? COLLATE NOCASE",
|
||
(opt_clean,),
|
||
).fetchone()
|
||
opt_trans = opt_row["translation"] if opt_row else opt_clean
|
||
opt_phon = opt_row["phonetic"] if opt_row else ""
|
||
opt_pos = opt_row["pos"] if opt_row else ""
|
||
|
||
user_card = conn.execute(
|
||
"SELECT id, srs_state FROM vocabulary_cards WHERE user_id = ? AND lower(trim(term)) = ?",
|
||
(user_id, opt_clean.lower()),
|
||
).fetchone()
|
||
|
||
is_auto_added = False
|
||
if not is_correct and (is_target or was_selected):
|
||
is_auto_added = True
|
||
|
||
opt_ctx = resolve_context_sentence_for_term(conn, opt_clean, sentence_with_term if is_target else "")
|
||
|
||
options_breakdown.append({
|
||
"term": opt_clean,
|
||
"translation": opt_trans,
|
||
"phonetic": opt_phon,
|
||
"pos": opt_pos,
|
||
"context_sentence": opt_ctx,
|
||
"is_correct": is_target,
|
||
"was_selected": was_selected,
|
||
"in_library": bool(user_card) or is_auto_added,
|
||
"card_id": user_card["id"] if user_card else None,
|
||
"auto_added": is_auto_added,
|
||
})
|
||
|
||
return {
|
||
"correct": is_correct,
|
||
"correct_option": target_term,
|
||
"selected_option": selected_clean,
|
||
"phonetic": phonetic,
|
||
"translation": translation,
|
||
"explanation": explanation,
|
||
"card_created": target_card_info["card_created"] if target_card_info else False,
|
||
"card_updated": target_card_info["card_updated"] if target_card_info else False,
|
||
"card_id": target_card_info["card_id"] if target_card_info else None,
|
||
"card_term": target_term,
|
||
"selected_card_id": selected_card_info["card_id"] if selected_card_info else None,
|
||
"selected_card_term": selected_clean if not is_correct else None,
|
||
"selected_translation": selected_card_info["translation"] if selected_card_info else None,
|
||
"source_book_title": q_row["source_book_title"] if "source_book_title" in q_row.keys() else None,
|
||
"source_chapter_title": q_row["source_chapter_title"] if "source_chapter_title" in q_row.keys() else None,
|
||
"options_breakdown": options_breakdown,
|
||
}
|
||
|
||
|
||
def _ingest_card_for_user(
|
||
conn: sqlite3.Connection,
|
||
user_id: int,
|
||
term: str,
|
||
translation: str,
|
||
phonetic: str,
|
||
pos: str,
|
||
context_sentence: str,
|
||
explanation: str,
|
||
level: str,
|
||
tag_suffix: str = "test-mistake",
|
||
custom_note: str = "",
|
||
) -> Dict[str, Any]:
|
||
"""
|
||
Internal helper to insert or update a vocabulary card in 'learning' SRS state.
|
||
"""
|
||
level_tag = f"level-{level.lower()}"
|
||
col_name = f"Уровни CEFR ({level.upper()})"
|
||
term_clean = term.strip()
|
||
|
||
existing_card = conn.execute(
|
||
"SELECT * FROM vocabulary_cards WHERE user_id = ? AND lower(trim(term)) = ?",
|
||
(user_id, term_clean.lower()),
|
||
).fetchone()
|
||
|
||
card_created = False
|
||
card_updated = False
|
||
card_id = None
|
||
|
||
if not existing_card:
|
||
cur = conn.execute(
|
||
"""
|
||
INSERT INTO vocabulary_cards (
|
||
user_id, term, translation, context_sentence, phonetic, audio_url,
|
||
part_of_speech, definition_en, tags, notes, collection,
|
||
srs_reps, srs_interval, srs_ease, srs_state, error_count,
|
||
srs_next_review
|
||
) VALUES (?, ?, ?, ?, ?, '', ?, ?, ?, ?, ?, 0, 0, 2.5, 'learning', 1, CURRENT_TIMESTAMP)
|
||
""",
|
||
(
|
||
user_id,
|
||
term_clean,
|
||
translation or term_clean,
|
||
context_sentence or "",
|
||
phonetic or "",
|
||
pos or "",
|
||
explanation or "",
|
||
f"{level_tag}, cefr-test, {tag_suffix}",
|
||
custom_note or f"Добавлено из теста уровня {level}",
|
||
col_name,
|
||
),
|
||
)
|
||
card_id = cur.lastrowid
|
||
card_created = True
|
||
else:
|
||
card_id = existing_card["id"]
|
||
existing_tags = set([t.strip() for t in (existing_card["tags"] or "").split(",") if t.strip()])
|
||
existing_tags.add(level_tag)
|
||
existing_tags.add("cefr-test")
|
||
existing_tags.add(tag_suffix)
|
||
updated_tags = ", ".join(sorted(existing_tags))
|
||
|
||
updated_context = (existing_card["context_sentence"] or "").strip()
|
||
# If existing context has "___" or lacks the term, overwrite with new authentic context!
|
||
if ("___" in updated_context or not re.search(rf"\b{re.escape(term_clean)}\b", updated_context, re.IGNORECASE)) and context_sentence:
|
||
updated_context = context_sentence
|
||
elif context_sentence and context_sentence not in updated_context:
|
||
updated_context = f"{updated_context}\n\n{context_sentence}".strip()
|
||
|
||
conn.execute(
|
||
"""
|
||
UPDATE vocabulary_cards
|
||
SET srs_state = 'learning',
|
||
srs_next_review = CURRENT_TIMESTAMP,
|
||
error_count = error_count + 1,
|
||
tags = ?,
|
||
context_sentence = ?
|
||
WHERE id = ?
|
||
""",
|
||
(updated_tags, updated_context, card_id),
|
||
)
|
||
card_updated = True
|
||
|
||
# Log in srs_logs
|
||
if card_id:
|
||
conn.execute(
|
||
"""
|
||
INSERT INTO srs_logs (user_id, card_id, rating, interval, ease, reviewed_at)
|
||
VALUES (?, ?, 1, 0, 2.5, CURRENT_TIMESTAMP)
|
||
""",
|
||
(user_id, card_id),
|
||
)
|
||
|
||
return {
|
||
"card_id": card_id,
|
||
"term": term_clean,
|
||
"translation": translation,
|
||
"card_created": card_created,
|
||
"card_updated": card_updated,
|
||
}
|
||
|
||
|
||
def ingest_cefr_word(
|
||
conn: sqlite3.Connection,
|
||
user_id: int,
|
||
level: str,
|
||
term: str,
|
||
context_sentence: str = "",
|
||
) -> Dict[str, Any]:
|
||
"""
|
||
Manually ingests an unselected option word from a CEFR test into user's SRS deck.
|
||
"""
|
||
clean_term = term.strip()
|
||
clean_level = level.upper().strip()
|
||
|
||
resolved_ctx = resolve_context_sentence_for_term(conn, clean_term, context_sentence)
|
||
|
||
row = conn.execute(
|
||
"SELECT term, translation, phonetic, pos FROM offline_dictionary WHERE term = ? COLLATE NOCASE",
|
||
(clean_term,),
|
||
).fetchone()
|
||
trans = row["translation"] if row else clean_term
|
||
phon = row["phonetic"] if row else ""
|
||
pos = row["pos"] if row else ""
|
||
|
||
info = _ingest_card_for_user(
|
||
conn,
|
||
user_id=user_id,
|
||
term=clean_term,
|
||
translation=trans,
|
||
phonetic=phon,
|
||
pos=pos,
|
||
context_sentence=resolved_ctx,
|
||
explanation=f"Добавлено вручную из вариантов вопроса теста CEFR ({clean_level})",
|
||
level=clean_level,
|
||
tag_suffix="manual-test-add",
|
||
custom_note=f"Добавлено из вариантов вопроса теста {clean_level}",
|
||
)
|
||
return {
|
||
"status": "ok",
|
||
"card_id": info["card_id"],
|
||
"term": clean_term,
|
||
"translation": trans,
|
||
"phonetic": phon,
|
||
"context_sentence": resolved_ctx,
|
||
}
|
||
|
||
|
||
|
||
def reset_user_cefr_level(conn: sqlite3.Connection, user_id: int, level: str) -> int:
|
||
"""
|
||
Resets progress for a specific CEFR level for user.
|
||
"""
|
||
clean_level = level.upper().strip()
|
||
cursor = conn.execute(
|
||
"DELETE FROM cefr_progress WHERE user_id = ? AND level = ?",
|
||
(user_id, clean_level),
|
||
)
|
||
return cursor.rowcount
|