import time class EnglishLesson: def __init__(self, lesson_number, episode_title, script_url, previous_vocab=None): self.lesson_number = lesson_number self.episode_title = episode_title self.script_url = script_url self.previous_vocab = previous_vocab if previous_vocab is not None else [] self.current_vocab = {} self.current_phrases = {} self.grammar_points = [] self.pre_activation_exercises = [] self.comprehension_questions = [] def display_message(self, message, delay=1): """Displays a message with a slight delay to simulate a conversational pace.""" print(message) time.sleep(delay) def check_answer(self, user_answer, correct_answer, explanation, is_case_sensitive=False): """Checks user's answer and provides immediate feedback.""" if not is_case_sensitive: user_answer = user_answer.lower().strip() correct_answer = correct_answer.lower().strip() if user_answer == correct_answer: self.display_message("🌟 Отлично! Вы абсолютно правы! " + explanation, 0.5) return True else: self.display_message(f"🤔 Не совсем так. Правильный ответ был: '{correct_answer}'. {explanation}", 0.5) return False def start_lesson(self): self.display_message(f"\n--- Добро пожаловать на Урок {self.lesson_number}: Эпизод '{self.episode_title}' ---", 1.5) self.display_message("Я ваш персональный учитель английского, и сегодня мы погрузимся в мир 'Друзей'!", 1.5) self.display_message(f"Наш путь к C1 начинается с этого увлекательного эпизода. Готовы? Поехали!\n", 2) self._spaced_repetition() self._lexical_filtering() self._pre_activation() self._comprehensible_input() self._forced_production() self.display_message("\n--- Урок завершен! Отличная работа! ---", 1.5) self.display_message("Вы сделали большой шаг к свободному владению английским. Продолжайте в том же духе!", 1.5) self.display_message("В следующий раз мы закрепим эти слова и двинемся дальше!\n", 2) def _spaced_repetition(self): """Stage 1: Spaced Repetition - Recalling previous vocabulary.""" self.display_message("### Этап 1: Spaced Repetition (Интервальное повторение)", 1) if self.previous_vocab: self.display_message("Давайте вспомним несколько слов из нашего прошлого урока. Это поможет 'достать' их из долговременной памяти!", 1.5) for i, (word, meaning) in enumerate(self.previous_vocab): user_input = input(f"Как переводится слово или фраза '{word}'? (Подсказка: {meaning[:5]}...) ").strip() if self.check_answer(user_input, meaning, f"В прошлый раз мы изучали '{word}' как '{meaning}'."): pass # Correct, no further action needed for this simulation time.sleep(0.5) self.display_message("Отлично! Мозг 'разогрет' и готов к новой информации!\n", 1.5) else: self.display_message("Поскольку это наш первый урок, мы начнем сразу с новой лексики. Но в следующий раз обязательно будут повторения!", 2) self.display_message("Подумайте, может быть, у вас есть какие-то слова или фразы, которые вы недавно выучили и хотели бы повторить? Попробуйте вспомнить 2-3 слова.", 2) input("Нажмите Enter, когда будете готовы двигаться дальше...") self.display_message("Замечательно! Теперь переходим к новым открытиям.\n", 1.5) def _lexical_filtering(self): """Stage 2: Lexical Filtering - Introducing new vocabulary, phrases, idioms, and slang.""" self.display_message("### Этап 2: Lexical Filtering (Отбор лексики)", 1) self.display_message("Из сегодняшнего фрагмента серии я выбрал самые сочные и полезные слова и выражения, которые помогут вам звучать как носитель!", 2) self.current_vocab = { "hump": "горб (в контексте шутки Чендлера)", "bemused": "озадаченный, смущенный", "mortified": "очень смущенный, униженный, опозоренный", "gravy boat": "соусник", "deadpan": "невозмутимый, с невозмутимым лицом (о шутках Чендлера)", "regional work": "работа на местном уровне (о выступлении Джоуи)" } self.current_phrases = { "go out with someone": "встречаться с кем-то (романтически)", "there's gotta be something wrong with him": "с ним должно быть что-то не так (сленг: gotta = got to)", "go through something": "пройти через что-то (испытание, опыт)", "sounds like a date to me": "по-моему, это свидание", "get screwed": "быть обманутым, попасть в неприятности (сленг)", "steer clear of someone/something": "держаться подальше от кого-то/чего-то", "cut someone off": "перебить кого-то (по телефону), отключить (связь)", "drift apart": "отдалиться друг от друга (об отношениях)", "turned on by something": "быть возбужденным/заведенным чем-то (в широком смысле, не только сексуально)", "freaked out": "испугаться, запаниковать, быть в шоке (сленг)", "have a major crush on someone": "быть сильно влюбленным в кого-то (втайне)", "crash on the couch": "переночевать на диване" } self.grammar_points = [ { "topic": "Phrasal Verbs", "explanation": "Phrasal verbs — это глаголы, состоящие из глагола и предлога/наречия, значение которых часто отличается от значения отдельных слов. Они очень распространены в разговорном английском и придают речи естественность. Например, *'go out with'* (встречаться с кем-то), *'go through'* (проходить через что-то), *'drift apart'* (отдалиться).", "example": "Monica is *going out with* Paul. (Моника *встречается* с Полом.)", "context_from_script": "Joey: C'mon, you're *going out with* the guy! There's gotta be something wrong with him!" }, { "topic": "Conditional Sentences (Type 1)", "explanation": "Первый тип условных предложений используется для описания реальных или очень вероятных ситуаций в будущем. Структура: If + Present Simple, will + Verb (base form). В 'Друзьях' часто используются похожие конструкции для выражения последствий действий.", "example": "If I don't input those numbers, it doesn't make much of a difference. (Если я не введу эти числа, это не сильно повлияет.)", "context_from_script": "Chandler: All right, kids, I gotta get to work. *If I don't input those numbers,... it doesn't make much of a difference...*" } ] self.display_message("\n--- Новый Словарь ---", 1) for word, meaning in self.current_vocab.items(): self.display_message(f"- **{word}**: {meaning}") time.sleep(0.3) self.display_message("\n--- Разговорные Фразы, Идиомы, Сленг ---", 1) for phrase, meaning in self.current_phrases.items(): self.display_message(f"- **{phrase}**: {meaning}") time.sleep(0.3) self.display_message("\n--- Грамматика в Контексте ---", 1) for gp in self.grammar_points: self.display_message(f"**Тема**: {gp['topic']}") self.display_message(f"**Объяснение**: {gp['explanation']}") self.display_message(f"**Пример из эпизода**: \"{gp['context_from_script']}\"") self.display_message(f"**Как это работает**: {gp['example']}\n") time.sleep(1) self.display_message("Отлично! Теперь, когда наш мозг знает, что искать, давайте его немного потренируем.\n", 2) def _pre_activation(self): """Stage 3: Pre-activation - Exercises to practice new vocabulary and grammar.""" self.display_message("### Этап 3: Pre-activation (Подготовка к просмотру)", 1) self.display_message("Эти упражнения помогут вашему мозгу 'активировать' новую лексику, чтобы вы легче узнавали ее в эпизоде.", 2) self.pre_activation_exercises = [ { "type": "matching", "question": "Сопоставьте слово с его значением:", "options": { "1. Mortified": "a) Быть сильно влюбленным в кого-то", "2. Steer clear of": "b) Очень смущенный, опозоренный", "3. Have a major crush on": "c) Держаться подальше от кого-то/чего-то", "4. Gravy boat": "d) Соусник" }, "correct_answers": {"1": "b", "2": "c", "3": "a", "4": "d"}, "explanation": { "1": "Mortified означает 'очень смущенный или опозоренный'.", "2": "Steer clear of означает 'держаться подальше от'.", "3": "Have a major crush on означает 'быть сильно влюбленным в кого-то'.", "4": "Gravy boat - это 'соусник'." } }, { "type": "fill_in_the_blank", "question": "Вставьте подходящее слово/фразу из списка в предложение: *drift apart, freaked out, deadpan, go out with*", "sentence": "When she realized she was more ______ by a {______} than her fiancé, Rachel really ______.", "blanks": ["turned on", "gravy boat", "freaked out"], "keys": ["turned on", "gravy boat", "freaked out"], # for easier checking "explanation": "Рейчел была 'turned on' (заведена) соусником ('gravy boat') и 'freaked out' (запаниковала) от этого." }, { "type": "grammar_fill", "question": "Выберите правильную форму глагола или фразу, чтобы завершить предложение, используя конструкции, похожие на Conditional Type 1 или phrasal verbs:", "sentence": "If you _______ (not / input) those numbers, it _______ (not / make) much of a difference.", "correct_answers": ["don't input", "won't make"], "explanation": "Здесь используется Conditional Type 1: If + Present Simple, will + Verb (base form). 'Don't input' (Present Simple) и 'won't make' (will + not + make)." } ] for i, exercise in enumerate(self.pre_activation_exercises): self.display_message(f"\n--- Упражнение {i+1} ---", 1) self.display_message(exercise["question"], 1) if exercise["type"] == "matching": for num, opt in exercise["options"].items(): self.display_message(f"{num} {opt.split(')')[0]}) {opt.split(')')[1].strip()}") user_answers = {} for num in exercise["options"].keys(): ans = input(f"Сопоставьте {num.split('.')[1].strip()} с буквой (a, b, c, d): ").lower().strip() user_answers[num.split('.')[0]] = ans all_correct = True for num, correct_ans in exercise["correct_answers"].items(): if user_answers.get(num) != correct_ans: self.display_message(f"Неверно для '{exercise['options'][num].split(')')[1].strip()}'. Правильно: {correct_ans}) {exercise['explanation'][num]}", 0.5) all_correct = False else: self.display_message(f"Верно для '{exercise['options'][num].split(')')[1].strip()}'! {exercise['explanation'][num]}", 0.5) if all_correct: self.display_message("🎉 Все верно! Отличная работа с сопоставлением!", 1) elif exercise["type"] == "fill_in_the_blank": print(exercise["sentence"].replace("{______}", "______")) # Display sentence with blanks user_input_parts = [] for j, blank in enumerate(exercise["blanks"]): user_input = input(f"Заполните пропуск {j+1} ({blank.split(' ')[0]}...): ").lower().strip() user_input_parts.append(user_input) full_user_sentence = exercise["sentence"] for k, user_ans in enumerate(user_input_parts): full_user_sentence = full_user_sentence.replace("{______}", user_ans, 1) is_correct = True for k, correct_key in enumerate(exercise["keys"]): if user_input_parts[k] != correct_key.lower().strip(): is_correct = False break if is_correct: self.display_message("🌟 Отлично! Вы заполнили все пропуски верно!", 1) else: self.display_message("🤔 Не все ответы верны. Давайте разберем: " + exercise["explanation"], 1) self.display_message(f"Правильное предложение: {exercise['sentence'].format(turned_on=exercise['keys'][0], gravy_boat=exercise['keys'][1], freaked_out=exercise['keys'][2])}", 1) elif exercise["type"] == "grammar_fill": self.display_message(exercise["sentence"], 1) user_ans1 = input("Первый пропуск (глагол в скобках): ").lower().strip() user_ans2 = input("Второй пропуск (глагол в скобках): ").lower().strip() if self.check_answer(user_ans1, exercise["correct_answers"][0], "") and self.check_answer(user_ans2, exercise["correct_answers"][1], ""): self.display_message("🎉 Оба ответа верны! Вы отлично справились с грамматикой!", 1) else: self.display_message("🤔 Давайте еще раз посмотрим на грамматику. " + exercise["explanation"], 1) self.display_message(f"Правильный вариант: \"If you **{exercise['correct_answers'][0]}** those numbers, it **{exercise['correct_answers'][1]}** much of a difference.\"", 1) time.sleep(1) self.display_message("Молодцы! Теперь ваш мозг полностью готов к восприятию живой английской речи. Время для просмотра!\n", 2) def _comprehensible_input(self): """Stage 4: Comprehensible Input - Guided viewing of the episode segment.""" self.display_message("### Этап 4: Comprehensible Input (Естественное погружение)", 1) self.display_message("Пришло время посмотреть отрывок из первой серии 'Друзей'. Ваша задача — сфокусироваться на том, чтобы услышать новые слова и фразы, а также обратить внимание на грамматические конструкции, которые мы только что обсудили.", 3) self.display_message("Не пытайтесь понять каждое слово. Главное — уловить общий смысл и знакомые элементы. Это как строить мост: вы ищете знакомые опоры, а не проверяете каждую доску.", 3) self.display_message(f"Вот ссылка на скрипт, чтобы вы могли следить за диалогами: {self.script_url}", 2) self.display_message("Рекомендую посмотреть первые 5-7 минут эпизода. Постарайтесь уловить, как герои используют слова 'go out with', 'freaked out', 'mortified' и другие.", 3) input("Когда будете готовы, посмотрите фрагмент и нажмите Enter, чтобы продолжить...") self.display_message("Отлично! Надеюсь, вы получили удовольствие от просмотра и узнали много нового! Как ощущения?\n", 2) def _forced_production(self): """Stage 5: Forced Production - Questions to activate vocabulary and grammar.""" self.display_message("### Этап 5: Forced Production (Активное использование)", 1) self.display_message("Теперь давайте проверим, насколько хорошо вы усвоили материал, и заставим эти слова работать на вас!", 2) self.comprehension_questions = [ { "question": "В начале эпизода Джоуи и Чендлер шутят по поводу парня, с которым встречается Моника. Какие 'недостатки' они ему приписывают, используя сленг или необычные выражения?", "correct_keywords": ["hump", "hairpiece", "eat chalk"], "explanation": "Чендлер спрашивает: 'Does he have a hump? A hump and a hairpiece?' (У него горб? Горб и парик?). А Фиби добавляет: 'Wait, does he eat chalk?' (Подождите, он ест мел?). Это были их забавные предположения о 'недостатках' Пола." }, { "question": "Росс делится своими переживаниями после развода. Как он описывает свое состояние, используя яркое, преувеличенное выражение?", "correct_keywords": ["reached down my throat", "small intestine", "tied around my neck"], "explanation": "Росс говорит: 'I just feel like someone reached down my throat, grabbed my small intestine, pulled it out of my mouth and tied it around my neck...' (Я чувствую, будто кто-то залез мне в горло, схватил тонкую кишку, вытащил ее изо рта и завязал вокруг шеи...). Это очень наглядное описание его страданий!" }, { "question": "Когда Моника рассказывает Полу, что она сделала со старым полотенцем своего парня, Пол отвечает: 'Ooh, steer clear of you.' Что означает эта фраза в данном контексте?", "correct_keywords": ["avoid", "stay away from"], "explanation": "Фраза 'steer clear of you' означает 'держаться от тебя подальше', 'избегать тебя'. Пол в шутку говорит, что Моника кажется опасной после такого поступка с полотенцем!" }, { "question": "Рейчел сбегает со свадьбы. Какое необычное, даже смешное сравнение она использует для своего жениха Барри, когда понимает, что не хочет за него замуж?", "correct_keywords": ["Mr. Potato Head"], "explanation": "Рейчел говорит: 'how much Barry looks like Mr. Potato Head' (как сильно Барри похож на Мистера Картофельную Голову). Это сравнение помогает ей осознать, что она не любит его." }, { "question": "Вспомните фразу Моники, которой она 'приветствует' Рейчел в 'реальном мире' после того, как та разрезает свои кредитные карты. Как она звучит и что означает?", "correct_keywords": ["Welcome to the real world", "It sucks", "You're gonna love it"], "explanation": "Моника говорит: 'Welcome to the real world! It sucks. You're gonna love it!' (Добро пожаловать в реальный мир! Он отстойный. Тебе понравится!). Это ироничное и правдивое приветствие в мире взрослых обязанностей." } ] for i, q in enumerate(self.comprehension_questions): self.display_message(f"\n--- Вопрос на понимание {i+1} ---", 1) self.display_message(q["question"], 1.5) user_answer = input("Ваш ответ: ").lower().strip() is_correct = False for keyword in q["correct_keywords"]: if keyword.lower() in user_answer: is_correct = True break if is_correct: self.display_message("🌟 Отличный ответ! Вы уловили ключевые моменты. " + q["explanation"], 1.5) else: self.display_message("🤔 Интересный взгляд, но давайте уточним. " + q["explanation"], 1.5) time.sleep(1) self.display_message("\n### Задание на активное использование (выводим лексику в речь!)", 1.5) self.display_message("Представьте, что вы рассказываете другу о первой серии 'Друзей'. Используйте как минимум 3 новых слова/фразы из нашего урока (например, 'freaked out', 'drift apart', 'major crush on').", 3) self.display_message("Напишите небольшой абзац (3-5 предложений) о том, что вам запомнилось или что удивило в поведении героев.", 2) user_story = input("Ваш рассказ: ") self.display_message("Превосходно! Это отличный способ закрепить новую лексику, используя ее в реальном контексте. Я вижу, что вы стараетесь, и это самое главное!\n", 2) # For the next lesson, we would save current_vocab and current_phrases to previous_vocab self.previous_vocab.extend(list(self.current_vocab.items())) self.previous_vocab.extend(list(self.current_phrases.items())) # --- Запуск Урока --- if __name__ == "__main__": # Для первого урока previous_vocab пуст lesson1 = EnglishLesson( lesson_number=1, episode_title="The One Where Monica Gets a New Roommate (The Pilot)", script_url="https://edersoncorbari.github.io/friends-scripts/season/0101.html", previous_vocab=[] # Пустой список для первого урока ) lesson1.start_lesson() # Пример, как можно передать лексику для следующего урока (для демонстрации Spaced Repetition) # В реальной системе это сохранялось бы в базу данных или файл next_lesson_previous_vocab = lesson1.previous_vocab print("\n--- Подготовка к следующему уроку ---") print("Сохраненная лексика для повторения:", [word for word, _ in next_lesson_previous_vocab]) # Пример второго урока (закомментировано, чтобы не запускать сразу весь цикл) # lesson2 = EnglishLesson( # lesson_number=2, # episode_title="The One with the Sonogram at the End", # script_url="https://edersoncorbari.github.io/friends-scripts/season/0102.html", # previous_vocab=next_lesson_previous_vocab # ) # lesson2.start_lesson()