Skip to content

Instantly share code, notes, and snippets.

@sigmadream
Created July 11, 2025 03:00
Show Gist options
  • Save sigmadream/ef67d427c0ee0ea452b35f6fae20a0ad to your computer and use it in GitHub Desktop.
Save sigmadream/ef67d427c0ee0ea452b35f6fae20a0ad to your computer and use it in GitHub Desktop.
from typing import Annotated, List, Dict, Any
from fastapi import APIRouter, Depends, status, HTTPException
from sqlmodel import Session, select
from .solve import path_getter, dir_maker
from ..database import get_db
from ..models import (
GichulQna,
GichulSet,
GichulSetGrade,
GichulSetInning,
GichulSetType,
GichulSubject,
)
from pathlib import Path
from collections import defaultdict
import os, re, random
from dotenv import load_dotenv
load_dotenv()
router = APIRouter(prefix="/cbt", tags=["Randomly Mixed Questions"])
base_path_str = os.getenv("BASE_PATH")
if base_path_str is None:
raise ValueError("BASE_PATH not set")
base_path = Path(base_path_str)
# 상수 정의
QUESTIONS_PER_SUBJECT = 25
def cbt_imgpath_getter(exam_set: GichulSet) -> str:
directory = dir_maker(
year=str(exam_set.year),
license=exam_set.type,
level=exam_set.grade,
round=exam_set.inning
)
return directory
# 중복 문제 제거 및 과목 분류
def remove_duplicate_questions(sets: List[GichulSet]) -> Dict[GichulSubject, List[GichulQna]]:
subject_questions = defaultdict(list)
for exam_set in sets:
for qna in exam_set.qnas:
if qna.questionstr and qna.ex1str:
joined_text = " ".join([qna.questionstr, qna.ex1str])
if joined_text not in [existing_qna.questionstr + " " + existing_qna.ex1str
for existing_qna in subject_questions[qna.subject]]:
subject_questions[qna.subject].append(qna)
return subject_questions
# 각 기출문제 세트별 이미지 경로
def create_image_path_dict(sets: List[GichulSet]) -> Dict[int, Dict[str, str]]:
path_dict = {}
for exam_set in sets:
directory = cbt_imgpath_getter(exam_set)
path_dict[exam_set.id] = path_getter(directory)
return path_dict
# 문제 선택
def select_random_questions_by_subject(
subject_questions: Dict[GichulSubject, List[GichulQna]]
) -> Dict[GichulSubject, List[GichulQna]]:
random_questions = {}
for subject, questions in subject_questions.items():
if len(questions) >= QUESTIONS_PER_SUBJECT:
random_questions[subject] = random.sample(questions, QUESTIONS_PER_SUBJECT)
else:
random_questions[subject] = questions
return random_questions
# 문제에 이미지 경로 정보를 추가합니다.
def add_image_paths_to_questions(
questions_dict: Dict[GichulSubject, List[GichulQna]],
path_dict: Dict[int, Dict[str, str]]
) -> Dict[str, List[Dict[str, Any]]]:
result = {}
pic_marker_reg = re.compile(r"@(\w+)")
for subject, questions in questions_dict.items():
qnas_as_dicts = [qna.model_dump() for qna in questions]
for qna_dict in qnas_as_dicts:
full_text = " ".join(
qna_dict.get(key, " ")
for key in ["questionstr", "ex1str", "ex2str", "ex3str", "ex4str"]
)
found_pics = pic_marker_reg.findall(full_text)
if found_pics:
gichulset_id = qna_dict["gichulset_id"]
if gichulset_id in path_dict:
img_paths = [
path_dict[gichulset_id][pic_name]
for pic_name in found_pics
if pic_name in path_dict[gichulset_id]
]
qna_dict["imgPaths"] = img_paths
result[subject] = qnas_as_dicts
return result
@router.get("/")
def get_one_random_qna_set(
license: GichulSetType,
level: GichulSetGrade,
db: Annotated[Session, Depends(get_db)],
) -> Dict[str, List[Dict[str, Any]]]:
try:
# 1. 데이터베이스에서 기출문제 세트 조회
sets = db.exec(
select(GichulSet).where(
GichulSet.type == license,
GichulSet.grade == level
)
).all()
if not sets:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"해당 조건의 기출문제 세트를 찾을 수 없습니다: {license.value}, {level.value}급"
)
# 2. 중복 제거 및 과목별 분류
subject_questions = remove_duplicate_questions(sets)
# 3. 이미지 경로 딕셔너리 생성
path_dict = create_image_path_dict(sets)
# 4. 과목별 랜덤 문제 선택
random_questions = select_random_questions_by_subject(subject_questions)
# 5. 이미지 경로 정보 추가
result = add_image_paths_to_questions(random_questions, path_dict)
return result
except HTTPException:
raise
except Exception as e:
print(f"Error in get_one_random_qna_set: {e}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="문제 세트 생성 중 오류가 발생했습니다."
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment