import gradio as gr import html import time import re # ── Словники для аналізу ────────────────────────────────────────── PARTS_KEYWORDS = { "організаційний момент": ["організаційний", "привітання", "перевірка присутніх", "готовність"], "актуалізація знань": ["актуалізація", "пригадаємо", "повторення попередньої", "що ви знаєте"], "мотивація": ["мотивація", "навіщо", "проблемне питання", "загадка", "цікавий факт", "мотив"], "вивчення нового матеріалу": ["новий матеріал", "тема уроку", "ознайомимося", "вивчення", "нова тема"], "закріплення": ["закріплення", "виконайте вправу", "завдання", "практик", "вправ"], "підсумок": ["підсумок", "що нового дізналися", "рефлексія", "висновок", "підведемо"], "домашнє завдання": ["домашнє завдання", "д/з", "вдома виконайте", "додому"], } METHODS_KEYWORDS = { "пояснення вчителя": ["пояснення", "розповідає", "розповідь", "лекція", "вчитель пояснює"], "бесіда": ["бесіда", "запитання", "запитує", "відповідають", "обговорення", "діалог"], "демонстрація": ["демонстра", "показує", "презентація", "таблиця", "схема", "малюнок", "ілюстрац"], "практична робота": ["практична", "виконують вправу", "розв'язують", "пишуть", "розв'яжіть"], "самостійна робота": ["самостійна", "індивідуально", "кожен учень", "самостійно"], "гра": ["гра", "ігровий", "вікторина", "змагання", "грають"], "групова робота": ["група", "групова", "команда", "разом", "парна робота", "в парах"], "проєктна робота": ["проєкт", "дослідження", "міні-проєкт"], "дискусія": ["дискусія", "думки", "різні точки зору", "полемік", "дебат"], } LESSON_TYPE_RULES = [ ("урок вивчення нового матеріалу", ["новий матеріал", "нова тема", "вперше", "ознайомимося"]), ("урок закріплення знань", ["закріплення", "вправи", "тренування", "відпрацювання"]), ("урок повторення та узагальнення", ["повторення", "узагальнення", "систематизація", "пригадаємо"]), ("урок контролю знань", ["контроль", "тестування", "самостійна робота", "перевірка"]), ("комбінований урок", []), ] SUBJECT_KEYWORDS = { "математика": ["число", "задач", "приклад", "рівнян", "геометр", "дріб", "додаван", "множен"], "українська мова": ["слово", "речення", "текст", "орфограф", "частини мови", "дієслово", "іменник"], "природознавство": ["природа", "рослин", "тварин", "екосистем", "географ", "клімат", "ґрунт"], "читання": ["читання", "твір", "автор", "казка", "оповідання", "вірш", "герой"], "історія": ["історія", "подія", "епоха", "держава", "культура", "суспільство"], "біологія": ["клітина", "організм", "біологія", "еволюція", "фотосинтез"], } # ── Аналіз ──────────────────────────────────────────────────────── def detect_parts(text: str) -> list[str]: t = text.lower() return [p for p, kws in PARTS_KEYWORDS.items() if any(k in t for k in kws)] or ["структуру не визначено"] def detect_methods(text: str) -> list[str]: t = text.lower() return [m for m, kws in METHODS_KEYWORDS.items() if any(k in t for k in kws)] or ["загальні методи"] def detect_lesson_type(text: str) -> str: t = text.lower() for lesson_type, kws in LESSON_TYPE_RULES[:-1]: if any(k in t for k in kws): return lesson_type has_new = any(k in t for k in ["новий матеріал", "нова тема", "вивчення"]) has_fix = any(k in t for k in ["закріплення", "вправи", "практич"]) if has_new and has_fix: return "комбінований урок" if has_new: return "урок вивчення нового матеріалу" return "комбінований урок" def detect_subject(text: str) -> str: t = text.lower() scores = {subj: sum(1 for k in kws if k in t) for subj, kws in SUBJECT_KEYWORDS.items()} best = max(scores, key=scores.get) return best if scores[best] > 0 else "не визначено" def extract_topic(text: str) -> str: """Витягує тему уроку з конспекту""" patterns = [ r"тема[:\s]+(.+?)[\n\r]", r"тема уроку[:\s]+(.+?)[\n\r]", r"урок[:\s]+(.+?)[\n\r]", ] for pattern in patterns: m = re.search(pattern, text, re.IGNORECASE) if m: return m.group(1).strip() first_line = text.strip().split("\n")[0] return first_line[:80] if first_line else "не визначено" def extract_goal(text: str) -> str: """Витягує мету уроку""" patterns = [ r"мета[:\s]+(.+?)[\n\r]", r"мета уроку[:\s]+(.+?)[\n\r]", r"завдання уроку[:\s]+(.+?)[\n\r]", ] for pattern in patterns: m = re.search(pattern, text, re.IGNORECASE) if m: return m.group(1).strip() return "не визначено" def count_activity_words(text: str) -> dict: """Підраховує показники активності учнів""" t = text.lower() return { "активність учнів": sum(t.count(k) for k in ["учні", "діти", "школярі", "вони виконують"]), "робота вчителя": sum(t.count(k) for k in ["вчитель", "педагог", "викладач"]), "взаємодія": sum(t.count(k) for k in ["разом", "обговорення", "відповідають", "запитує"]), } FORMS_KEYWORDS = { "фронтальна робота": ["фронтальна", "весь клас", "усі учні", "клас відповідає"], "індивідуальна робота": ["індивідуально", "кожен учень", "самостійно", "індивідуальна"], "парна робота": ["в парах", "парна", "сусід по парті", "разом із сусідом"], "групова робота": ["група", "групова", "команда", "по групах", "в групах"], "колективна робота": ["колективна", "спільно", "разом", "увесь клас"], } TOOLS_KEYWORDS = { "підручник": ["підручник", "с.", "сторінка", "впр.", "вправа"], "зошит": ["зошит", "записують", "пишуть у зошиті"], "дошка": ["дошка", "на дошці", "записує на дошці"], "презентація": ["презентація", "слайд", "проєктор", "екран"], "картки": ["картка", "роздатковий матеріал", "картки"], "таблиця / схема": ["таблиця", "схема", "малюнок", "ілюстрація", "діаграма"], "натуральні об'єкти":["гербарій", "модель", "макет", "реальний об'єкт", "муляж"], "відео / аудіо": ["відео", "аудіо", "запис", "прослуховування", "перегляд"], } TASKS_KEYWORDS = { "читання тексту": ["читають", "прочитайте", "читання"], "письмові вправи": ["пишуть", "запишіть", "написати", "вправа у зошиті"], "усні відповіді": ["відповідають", "розкажіть", "усна відповідь", "говорять"], "розв'язання задач": ["розв'язують", "задача", "розв'яжіть", "приклад"], "робота з підручником": ["підручник", "відкрийте", "знайдіть у підручнику"], "заповнення таблиці": ["заповніть таблицю", "заповнюють", "таблицю"], "малювання / схеми": ["намалюйте", "схема", "зарисуйте", "позначте"], "тестові завдання": ["тест", "тестові", "обери правильну відповідь"], "творчі завдання": ["придумайте", "складіть", "творче завдання", "власний приклад"], "спостереження": ["спостерігають", "розгляньте", "опишіть що бачите"], } def detect_forms(text: str) -> list[str]: t = text.lower() return [f for f, kws in FORMS_KEYWORDS.items() if any(k in t for k in kws)] or ["не визначено"] def detect_tools(text: str) -> list[str]: t = text.lower() return [tool for tool, kws in TOOLS_KEYWORDS.items() if any(k in t for k in kws)] or ["не визначено"] def detect_tasks(text: str) -> list[str]: t = text.lower() return [task for task, kws in TASKS_KEYWORDS.items() if any(k in t for k in kws)] or ["не визначено"] def build_lesson_narrative( topic: str, goal: str, lesson_type: str, subject: str, parts: list[str], methods: list[str], forms: list[str], tools: list[str], tasks: list[str], teacher: str, text: str, ) -> str: """Генерує детальний текст спостереження уроку у стилі педагогічного протоколу""" teacher_str = html.escape(teacher) if teacher.strip() else "Вчитель" topic_str = html.escape(topic) if topic != "не визначено" else "—" goal_str = html.escape(goal) if goal != "не визначено" else "—" subj_str = html.escape(subject) if subject != "не визначено" else "" t = text.lower() paragraphs = [] # ── 1. Вступна характеристика ───────────────────────────────── subj_part = f" з {subj_str}" if subj_str else "" paragraphs.append( f"{teacher_str} провів(ла) {html.escape(lesson_type)}{subj_part}. " f"Тема уроку — «{topic_str}». " f"Мета: {goal_str}." ) # ── 2. Структура уроку ──────────────────────────────────────── valid_parts = [p for p in parts if p != "структуру не визначено"] if valid_parts: parts_list = "; ".join(f"{html.escape(p)}" for p in valid_parts) paragraphs.append( f"Урок включав такі структурні етапи: {parts_list}. " + ("Усі етапи логічно пов'язані між собою та відповідають обраному типу уроку." if len(valid_parts) >= 5 else "Окремі структурні етапи у конспекті чітко не виділені — рекомендується деталізувати план.") ) else: paragraphs.append( "Структурні етапи уроку у конспекті окремо не позначені." ) # ── 3. Організаційний момент / мотивація ───────────────────── org_phrases = [] if any(k in t for k in ["організаційний", "привітання", "готовність"]): org_phrases.append( f"На початку уроку {teacher_str} організував(ла) клас: " "привітав(ла) учнів, перевірив(ла) готовність робочих місць." ) if any(k in t for k in ["мотивація", "загадка", "цікавий факт", "проблемне питання", "мотив"]): org_phrases.append( "Для мотивації навчальної діяльності було використано проблемно-ігровий прийом або " "цікаве запитання, що зацікавило учнів та налаштувало їх на роботу." ) if any(k in t for k in ["актуалізація", "пригадаємо", "повторення"]): org_phrases.append( "Актуалізація опорних знань відбувалась через усне опитування або повторення " "раніше вивченого матеріалу." ) if org_phrases: paragraphs.append(" ".join(org_phrases)) # ── 4. Методи навчання ──────────────────────────────────────── valid_methods = [m for m in methods if m != "загальні методи"] if valid_methods: m_str = ", ".join(f"{html.escape(m)}" for m in valid_methods) paragraphs.append( f"У ході уроку {teacher_str} застосовував(ла) такі методи навчання: {m_str}. " ) method_details = [] if any(k in t for k in ["пояснення", "розповідає", "розповідь"]): method_details.append( "Словесний метод — пояснення — використовувався для ознайомлення учнів " "з новим матеріалом. Вчитель чітко й доступно викладав навчальний зміст, " "ілюструючи пояснення прикладами." ) if any(k in t for k in ["бесіда", "запитання", "відповідають", "обговорення"]): method_details.append( "Бесіда застосовувалась як метод діалогічної взаємодії: " "вчитель ставив запитання, учні формулювали відповіді, " "що сприяло розвитку мовлення та критичного мислення." ) if any(k in t for k in ["демонстра", "таблиця", "схема", "презентація", "малюнок"]): method_details.append( "Наочно-демонстраційний метод реалізовувався через показ таблиць, " "схем або ілюстрацій, що забезпечувало наочність сприймання нового матеріалу." ) if any(k in t for k in ["практична", "вправу", "розв'язують", "пишуть"]): method_details.append( "Практичний метод — виконання вправ і завдань — забезпечував " "відпрацювання навичок та закріплення вивченого." ) if any(k in t for k in ["самостійна", "індивідуально", "кожен учень"]): method_details.append( "Самостійна робота сприяла формуванню вміння учнів працювати " "без безпосередньої допомоги вчителя та розвитку навчальної самостійності." ) if any(k in t for k in ["гра", "ігровий", "вікторина"]): method_details.append( "Ігровий метод підвищував мотивацію та активність учнів, " "забезпечував емоційне залучення до навчального процесу." ) if method_details: paragraphs.extend(method_details) # ── 5. Форми організації ────────────────────────────────────── valid_forms = [f for f in forms if f != "не визначено"] if valid_forms: f_str = ", ".join(f"{html.escape(f)}" for f in valid_forms) form_comment = "" if "індивідуальна робота" in valid_forms and "фронтальна робота" in valid_forms: form_comment = ( " Поєднання фронтальної та індивідуальної форм роботи " "забезпечувало як колективне засвоєння, так і особистісну перевірку знань кожного учня." ) elif "групова робота" in valid_forms: form_comment = ( " Групова форма роботи розвивала комунікативні навички " "та вміння співпрацювати в команді." ) paragraphs.append( f"Форми організації навчальної діяльності: {f_str}.{form_comment}" ) # ── 6. Засоби навчання ──────────────────────────────────────── valid_tools = [t_ for t_ in tools if t_ != "не визначено"] if valid_tools: tools_str = ", ".join(f"{html.escape(t_)}" for t_ in valid_tools) paragraphs.append( f"Засоби навчання, використані на уроці: {tools_str}. " "Добір засобів відповідав змісту уроку та віковим особливостям учнів." ) # ── 7. Завдання учнів (деталізовано) ───────────────────────── task_details = [] if any(k in t for k in ["читають", "прочитайте", "читання"]): task_details.append( "Учні читали текст (або умову задачі), що розвивало навички " "свідомого читання та розуміння навчального матеріалу." ) if any(k in t for k in ["пишуть", "запишіть", "написати", "у зошиті", "зошит"]): task_details.append( "Виконувались письмові вправи у зошитах: учні записували " "відповіді, вирази або слова відповідно до завдань вчителя." ) if any(k in t for k in ["відповідають", "розкажіть", "усна відповідь"]): task_details.append( "Учні давали усні відповіді на запитання вчителя, " "формулювали власні думки та висновки." ) if any(k in t for k in ["задача", "розв'яжіть", "розв'язують", "приклад"]): task_details.append( "Виконувалось розв'язання задач і прикладів: " "учні аналізували умову, обирали дію, записували розв'язок і відповідь." ) if any(k in t for k in ["підручник", "відкрийте", "с.", "сторінка", "впр."]): task_details.append( "Проводилась робота з підручником: виконання вправ " "за вказаними сторінками та завданнями." ) if any(k in t for k in ["тест", "тестові", "обери правильну"]): task_details.append( "Учні виконували тестові завдання для перевірки рівня " "засвоєння вивченого матеріалу." ) if any(k in t for k in ["придумайте", "складіть", "творче"]): task_details.append( "Пропонувались творчі завдання — скласти власний приклад, " "придумати продовження або варіант завдання." ) if any(k in t for k in ["таблицю", "заповніть", "схема", "намалюйте"]): task_details.append( "Учні заповнювали таблиці або схеми, що сприяло " "систематизації та структуруванню знань." ) if task_details: paragraphs.append( f"Завдання, які виконували учні на уроці:" ) paragraphs.extend(task_details) # ── 8. Рефлексія ───────────────────────────────────────────── if any(k in t for k in ["рефлексія", "підсумок", "що дізналися", "висновок"]): paragraphs.append( f"Завершальний етап уроку містив підсумок та рефлексію. " f"{teacher_str} організував(ла) обговорення результатів роботи: " "учні відповіли на запитання про те, що нового дізналися, " "що сподобалося, що було складним. " "Це сприяло усвідомленню власних навчальних досягнень." ) if any(k in t for k in ["домашнє завдання", "д/з", "вдома"]): paragraphs.append( f"{teacher_str} повідомив(ла) домашнє завдання, " "надавши необхідні інструкції щодо його виконання." ) # ── 9. Загальний висновок ───────────────────────────────────── score = len(valid_parts) + len(valid_methods) + len(valid_forms) + len(valid_tools) if score >= 10: conclusion = ( "Урок відзначається чіткою структурою, різноманітністю методів та форм роботи. " "Конспект свідчить про ретельну підготовку вчителя та методичну грамотність." ) elif score >= 5: conclusion = ( "Урок має достатньо опрацьований конспект з визначеними методами та формами роботи. " "Окремі аспекти можна деталізувати додатково." ) else: conclusion = ( "Конспект потребує детальнішого опрацювання: варто чіткіше прописати " "методи, форми роботи, засоби навчання та завдання для учнів." ) paragraphs.append(conclusion) return "".join( f'
{p}
' for p in paragraphs ) # ── HTML-компоненти ─────────────────────────────────────────────── def pill(text: str, bg: str, color: str) -> str: return (f'' f'{html.escape(text)}') def pills(items: list[str], bg: str, color: str) -> str: return "".join(pill(i, bg, color) for i in items) def card(icon: str, title: str, body: str, border: str = "#2196F3", bg: str = "#e8f4f8") -> str: return (f'Немає збережених аналізів.
" return "".join( f'