Spaces:
Sleeping
Sleeping
| # ============================================== | |
| # models.py (v2025-final) | |
| # ============================================== | |
| from sqlalchemy import Column, Integer, String, Text, Boolean, ForeignKey | |
| from sqlalchemy.orm import relationship | |
| import json | |
| # db.py์์ ์์ฑํ Base ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ต๋๋ค. | |
| from db import Base | |
| # ---------------------------------------------- | |
| # Question ๋ชจ๋ธ | |
| # ---------------------------------------------- | |
| class Question(Base): | |
| __tablename__ = "questions" | |
| id = Column(Integer, primary_key=True, autoincrement=True) | |
| # ๋ฌธ์ ์ง๋ฌธ (๊ธฐ์กด ์ด๋ฆ ์ ์ง) | |
| stem = Column(Text, nullable=False) | |
| # ์ ๋ต (๋จ์ ๋ฆฌ์คํธ๋ก ๋ณ๊ฒฝ๋์ด๋ "A", "B" ๋๋ "1", "2" ๊ฐ์ ์ธ๋ฑ์ค ํค ์ ์ฅ) | |
| answer = Column(String(255)) | |
| # ํด์ค | |
| explanation = Column(Text) | |
| # ๋ฌธ์ ์ ํ (MCQ: ๊ฐ๊ด์) | |
| question_type = Column(String(50), default="MCQ") | |
| # ๋ฉํ ๋ฐ์ดํฐ | |
| page = Column(Integer) | |
| category = Column(String(100)) | |
| subcategory = Column(String(100)) | |
| code = Column(Text) | |
| source = Column(String(255)) | |
| # ------------------------------------------------------- | |
| # [๋ฐ์ดํฐ ๊ตฌ์กฐ ๋ณ๊ฒฝ ํต์ฌ] | |
| # ๊ธฐ์กด: [{"key": "A", "text": "๋ด์ฉ"}] | |
| # ๋ณ๊ฒฝ: ["๋ด์ฉ1", "๋ด์ฉ2", "๋ด์ฉ3"] (๋จ์ ๋ฌธ์์ด ๋ฆฌ์คํธ) | |
| # ------------------------------------------------------- | |
| options_json = Column(Text, default="[]") | |
| pairs = Column(Text, default="{}") | |
| sequence = Column(Text, default="[]") | |
| # ------------------------------------------------------- | |
| # Helper Methods (JSON ์ง๋ ฌํ/์ญ์ง๋ ฌํ) | |
| # ------------------------------------------------------- | |
| def set_options(self, options): | |
| """ | |
| ๋ฆฌ์คํธ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ JSON ๋ฌธ์์ด๋ก ๋ณํํ์ฌ ์ ์ฅํฉ๋๋ค. | |
| Input ์์: ["EC2", "S3", "Lambda"] | |
| """ | |
| try: | |
| if options is None: | |
| self.options_json = "[]" | |
| elif isinstance(options, (list, dict)): | |
| # ensure_ascii=False: ํ๊ธ ๊นจ์ง ๋ฐฉ์ง | |
| self.options_json = json.dumps(options, ensure_ascii=False) | |
| else: | |
| # ๋ฌธ์์ด๋ก ๋ค์ด์ค๋ฉด ๊ทธ๋๋ก ์ ์ฅ ์๋ ํน์ ๋ฆฌ์คํธ๋ก ๊ฐ์ธ๊ธฐ | |
| self.options_json = json.dumps([str(options)], ensure_ascii=False) | |
| except Exception as e: | |
| print(f"Error setting options: {e}") | |
| self.options_json = "[]" | |
| def get_options(self): | |
| """ | |
| ์ ์ฅ๋ JSON ๋ฌธ์์ด์ ํ์ด์ฌ ๋ฆฌ์คํธ๋ก ๋ฐํํฉ๋๋ค. | |
| Return ์์: ["EC2", "S3", "Lambda"] | |
| """ | |
| try: | |
| if not self.options_json: | |
| return [] | |
| return json.loads(self.options_json) | |
| except Exception: | |
| return [] | |
| # (์ถ๊ฐ) pairs, sequence ์ฒ๋ฆฌ๋ ๋์ผํ ๋ฐฉ์์ผ๋ก ์์ ์ฑ ํ๋ณด | |
| def get_pairs(self): | |
| try: | |
| return json.loads(self.pairs) if self.pairs else {} | |
| except: | |
| return {} | |
| def get_sequence(self): | |
| try: | |
| return json.loads(self.sequence) if self.sequence else [] | |
| except: | |
| return [] | |
| def __repr__(self): | |
| return f"<Question id={self.id} type={self.question_type} stem={self.stem[:20]}...>" | |
| # ---------------------------------------------- | |
| # Attempt ๋ชจ๋ธ (์ฌ์ฉ์ ํ์ด ๊ธฐ๋ก) | |
| # ---------------------------------------------- | |
| class Attempt(Base): | |
| __tablename__ = "attempts" | |
| id = Column(Integer, primary_key=True, autoincrement=True) | |
| # ์ฌ์ฉ์ ID (๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ด ์๋ค๋ฉด guest ํน์ ๋ธ๋ผ์ฐ์ ์ง๋ฌธ ๋ฑ ์ฌ์ฉ) | |
| user_id = Column(String(100), nullable=False, default="guest") | |
| # ๋ฌธ์ ID (FK) | |
| question_id = Column(Integer, ForeignKey("questions.id")) | |
| # ์ฌ์ฉ์๊ฐ ์ ํํ ๋ต (ํ๋ก ํธ์๋์์ ์์ฑํ Key: "A", "B", "1" ๋ฑ) | |
| chosen = Column(String(10)) | |
| # ์ ๋ต ์ฌ๋ถ | |
| correct = Column(Boolean, default=False) | |
| # ์ค๋ต ๋ ธํธ ์ ํ (wrong: ํ๋ฆผ, bookmark: ์ค์ ํ์ ๋ฑ) | |
| note_type = Column(String(20), default="wrong") | |
| # ๊ด๊ณ ์ค์ (Attempt.question ์ผ๋ก ๋ฌธ์ ์ ๋ณด ์ ๊ทผ ๊ฐ๋ฅ) | |
| question = relationship("Question", backref="attempts") | |
| def __repr__(self): | |
| return f"<Attempt q={self.question_id}, user={self.user_id}, correct={self.correct}>" |