Spaces:
Sleeping
Sleeping
| import csv | |
| from pathlib import Path | |
| from models import Question | |
| def load_questions(csv_path: str) -> list[Question]: | |
| path = Path(csv_path) | |
| if not path.exists(): | |
| raise FileNotFoundError(f"質問ファイルが見つかりません: {csv_path}") | |
| questions: list[Question] = [] | |
| with open(path, encoding="utf-8-sig") as f: | |
| reader = csv.DictReader(f) | |
| required_columns = { | |
| "id", "category", "question_text", "expected_keywords", | |
| "keyword_weight", "ai_weight", "improv_weight", | |
| "max_score", "scoring_criteria", | |
| } | |
| if reader.fieldnames is None: | |
| raise ValueError("CSVファイルにヘッダーがありません。") | |
| actual_columns = set(reader.fieldnames) | |
| missing = required_columns - actual_columns | |
| if missing: | |
| raise ValueError(f"CSVに必須カラムがありません: {missing}") | |
| for row_num, row in enumerate(reader, start=2): | |
| try: | |
| keyword_weight = float(row["keyword_weight"]) | |
| ai_weight = float(row["ai_weight"]) | |
| improv_weight = float(row["improv_weight"]) | |
| max_score = int(row["max_score"]) | |
| weight_sum = keyword_weight + ai_weight + improv_weight | |
| if abs(weight_sum - 1.0) > 0.01: | |
| raise ValueError( | |
| f"重みの合計が1.0ではありません: {weight_sum:.2f}" | |
| ) | |
| if max_score <= 0: | |
| raise ValueError(f"max_scoreは1以上必要です: {max_score}") | |
| keywords = [ | |
| kw.strip() | |
| for kw in row["expected_keywords"].split(",") | |
| if kw.strip() | |
| ] | |
| if not keywords: | |
| raise ValueError("expected_keywordsが空です。") | |
| question = Question( | |
| id=int(row["id"]), | |
| category=row["category"].strip(), | |
| question_text=row["question_text"].strip(), | |
| expected_keywords=keywords, | |
| keyword_weight=keyword_weight, | |
| ai_weight=ai_weight, | |
| improv_weight=improv_weight, | |
| max_score=max_score, | |
| scoring_criteria=row["scoring_criteria"].strip(), | |
| follow_up=row.get("follow_up", "").strip(), | |
| ) | |
| questions.append(question) | |
| except (ValueError, KeyError) as e: | |
| raise ValueError(f"CSV {row_num}行目にエラー: {e}") from e | |
| if not questions: | |
| raise ValueError("CSVに質問が1つもありません。") | |
| return questions | |