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()