Download exam_functions.py from Denysyk/Lab6: direct link, hf CLI and curl.
- Browser
- Download file 6.83 kB
-
https://huggingface.co/spaces/Denysyk/Lab6/resolve/main/exam_functions.py
- Command line
-
hf download hf://spaces/Denysyk/Lab6/exam_functions.py
-
curl -L -o exam_functions.py https://huggingface.co/spaces/Denysyk/Lab6/resolve/main/exam_functions.py
6.83 kB
| """ | |
| Exam backend functions for AI Examiner Agent. | |
| """ | |
| import json | |
| import random | |
| import os | |
| from datetime import datetime | |
| from typing import TypedDict, Literal | |
| TOPICS = [ | |
| "Tokenization and text preprocessing", | |
| "Word embeddings (Word2Vec, GloVe, FastText)", | |
| "Recurrent neural networks (RNN, LSTM, GRU)", | |
| "Attention mechanism and Transformers", | |
| "BERT and pre-trained language models", | |
| "Named Entity Recognition (NER)", | |
| "Sentiment analysis", | |
| "Machine translation", | |
| "Text classification", | |
| "Language model evaluation metrics (BLEU, ROUGE, Perplexity)", | |
| ] | |
| STUDENTS = [ | |
| {"name": "Stanislav Androshchuk", "email": "Stanislav.Androshchuk.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Oleksandr Babilia", "email": "Oleksandr.Babilia.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Vitalii Bahrynets", "email": "Vitalii.Bahrynets.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Dmytro Betsa", "email": "Dmytro.Betsa.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Kateryna Bilyk", "email": "Kateryna.Bilyk.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Iryna Boiko", "email": "Iryna.Boiko.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Ihor Boklach", "email": "Ihor.Boklach.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Bohdan Boretskyi", "email": "Bohdan.Boretskyi.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Yaroslav Borys", "email": "Yaroslav.Borys.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Denys Brativnyk", "email": "Denys.Brativnyk.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Oleksandr Vlasiuk", "email": "Oleksandr.Vlasiuk.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Oleksandr Voznyi", "email": "Oleksandr.Voznyi.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Khrystyna Dolynska", "email": "Khrystyna.Dolynska.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Viktor Zharkivskyi", "email": "Viktor.Zharkivskyi.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Olena Kalenchuk", "email": "Olena.Kalenchuk.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Dmytro Kostinskyi", "email": "Dmytro.Kostinskyi.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Anastasiia Kudybovska", "email": "Anastasiia.Kudybovska.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Vladyslav Kuchynskyi", "email": "Vladyslav.Kuchynskyi.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Olena Litovska", "email": "Olena.Litovska.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Oleh Lozovyi", "email": "Oleh.Lozovyi.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Roman Maior", "email": "Roman.Maior.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Yevhen Makarenko", "email": "Yevhen.Makarenko.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Serhii Matsyshyn", "email": "Serhii.Matsyshyn.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Maksym Myna", "email": "Maksym.Myna.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Artem Mikanov", "email": "Artem.Mikanov.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Vitalii Mil", "email": "Vitalii.Mil.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Vladyslav Miniailo", "email": "Vladyslav.Miniailo.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Vladyslav Moiseienko", "email": "Vladyslav.Moiseienko.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Tymofii Nasobko", "email": "Tymofii.Nasobko.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Arsenii Ohar", "email": "Arsenii.Ohar.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Marta Oliinyk", "email": "Marta.Oliinyk.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Oleksii Oliinyk", "email": "Oleksii.Oliinyk.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Roman Omelchuk", "email": "Roman.Omelchuk.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Maksym Orlianskyi", "email": "Maksym.Orlianskyi.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Alina Pavliv", "email": "Alina.Pavliv.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Andrii Pytel", "email": "Andrii.Pytel.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Oleksii Postovyi", "email": "Oleksii.Postovyi.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Myroslav Pronyshyn", "email": "Myroslav.Pronyshyn.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Yurii Pukhta", "email": "Yurii.Pukhta.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Denys Ratushniak", "email": "Denys.Ratushniak.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Nazar Savitskyi", "email": "Nazar.Savitskyi.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Oleksandr Siryk", "email": "Oleksandr.Siryk.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Petro Slobodian", "email": "Petro.Slobodian.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Artem Somar", "email": "Artem.Somar.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Vladyslav Spivakov", "email": "Vladyslav.Spivakov.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Pavlo Stetsiuk", "email": "Pavlo.Stetsiuk.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Vladyslav Taraban", "email": "Vladyslav.Taraban.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Andrii Tarasov", "email": "Andrii.Tarasov.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Illia Feloniuk", "email": "Illia.Feloniuk.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Sviatoslav Shainoha", "email": "Sviatoslav.Shainoha.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Sviatoslav Shylkov", "email": "Sviatoslav.Shylkov.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Vitalii Yuzvyn", "email": "Vitalii.Yuzvyn.mKNSSh.2025@lpnu.ua"}, | |
| {"name": "Vladyslav Yakymchuk", "email": "Vladyslav.Yakymchuk.mKNSSh.2025@lpnu.ua"}, | |
| # demo | |
| {"name": "Test", "email": "test@test.com"}, | |
| ] | |
| DB_FILE = "exam_db.json" | |
| def _load_db() -> dict: | |
| if os.path.exists(DB_FILE): | |
| with open(DB_FILE, "r", encoding="utf-8") as f: | |
| return json.load(f) | |
| return {"exams": []} | |
| def _save_db(db: dict) -> None: | |
| with open(DB_FILE, "w", encoding="utf-8") as f: | |
| json.dump(db, f, ensure_ascii=False, indent=2) | |
| def start_exam(email: str, name: str) -> list[str]: | |
| student = next( | |
| (s for s in STUDENTS if s["email"].lower() == email.strip().lower()), | |
| None, | |
| ) | |
| if student is None: | |
| raise ValueError( | |
| f"Student with email '{email}' not found. Please check your email address." | |
| ) | |
| topics = random.sample(TOPICS, k=random.randint(2, 3)) | |
| db = _load_db() | |
| db["exams"].append({ | |
| "email": email, | |
| "name": name, | |
| "started_at": datetime.now().isoformat(), | |
| "topics": topics, | |
| "score": None, | |
| "finished_at": None, | |
| }) | |
| _save_db(db) | |
| print(f"[DB] Exam started for {name} <{email}>. Topics: {topics}") | |
| return topics | |
| _topic_queue: list[str] = [] | |
| def set_topic_queue(topics: list[str]) -> None: | |
| global _topic_queue | |
| _topic_queue = list(topics) | |
| def get_next_topic() -> str: | |
| if _topic_queue: | |
| return _topic_queue.pop(0) | |
| return "" | |
| class Message(TypedDict): | |
| role: Literal["system", "user", "tool_call"] | |
| content: str | |
| datetime: str | |
| def end_exam(email: str, score: float, history: list[Message]) -> None: | |
| db = _load_db() | |
| for exam in reversed(db["exams"]): | |
| if exam["email"].lower() == email.lower() and exam["score"] is None: | |
| exam["score"] = score | |
| exam["finished_at"] = datetime.now().isoformat() | |
| exam["history"] = history | |
| break | |
| _save_db(db) | |
| print(f"[DB] Exam finished for {email}. Score: {score}/10") |