Spaces:
Runtime error
Runtime error
File size: 4,734 Bytes
d3ee77e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | #!/usr/bin/env python3
"""
Convertit le corpus enseignant JSON vers le CSV du workflow qualité BacPilot.
Usage:
python3 scripts/convert_corpus_json_to_csv.py <corpus_dir> <output_csv>
Exemple:
python3 scripts/convert_corpus_json_to_csv.py \
/home/debpc/corpus_teacher_100 \
quality/corpus/teacher_evaluation_cases_100.csv
Seules les copies avec status TEACHER_VALIDATED ou READY_FOR_EVAL sont exportées.
Les copies DRAFT sont ignorées.
"""
import csv
import json
import sys
from pathlib import Path
FIELDNAMES = [
"submission_case_id", "exercise_id", "chapter", "skill",
"student_answer_anonymized", "teacher_score", "teacher_max_score",
"teacher_errors", "teacher_comment",
"bacpilot_score", "bacpilot_max_score", "bacpilot_verdict",
"bacpilot_confidence", "bacpilot_main_error",
"absolute_score_error", "false_error_count", "missed_error_count",
"needs_human_review_expected", "needs_human_review_bacpilot", "decision",
]
VERDICTS_REVIEW = {
"PARTIELLEMENT_CORRECT",
"METHODE_CORRECTE_RESULTAT_FAUX",
"RESULTAT_CORRECT_JUSTIFICATION_INSUFFISANTE",
"NON_EVALUABLE",
}
def extract_student_answer(path: Path) -> str:
text = path.read_text(encoding="utf-8")
if "Réponse :" in text:
after = text.split("Réponse :")[-1].strip()
if after.startswith("---"):
after = after[3:].strip()
return after
return text.strip()
def convert(corpus_dir: Path, output_csv: Path) -> None:
copies_dir = corpus_dir / "copies"
if not copies_dir.exists():
print(f"ERREUR: dossier copies introuvable dans {corpus_dir}")
sys.exit(1)
rows = []
converted = 0
skipped_draft = 0
errors = []
for copy_dir in sorted(copies_dir.iterdir()):
if not copy_dir.is_dir():
continue
meta_path = copy_dir / "metadata.json"
answer_path = copy_dir / "student_answer.md"
correction_path = copy_dir / "teacher_correction.json"
if not all(p.exists() for p in [meta_path, answer_path, correction_path]):
errors.append(f"{copy_dir.name}: fichiers manquants")
continue
try:
meta = json.loads(meta_path.read_text(encoding="utf-8"))
correction = json.loads(correction_path.read_text(encoding="utf-8"))
except json.JSONDecodeError as e:
errors.append(f"{copy_dir.name}: JSON invalide — {e}")
continue
status = correction.get("status", "DRAFT")
if status not in ("TEACHER_VALIDATED", "READY_FOR_EVAL"):
skipped_draft += 1
continue
student_answer = extract_student_answer(answer_path)
main_errors = correction.get("main_errors", [])
verdict = correction.get("verdict", "")
needs_review = "true" if verdict in VERDICTS_REVIEW else "false"
rows.append({
"submission_case_id": correction.get("copy_id", copy_dir.name),
"exercise_id": correction.get("exercise_id", ""),
"chapter": meta.get("chapter", ""),
"skill": meta.get("skill", ""),
"student_answer_anonymized": student_answer,
"teacher_score": correction.get("teacher_score", ""),
"teacher_max_score": correction.get("max_score", ""),
"teacher_errors": ";".join(main_errors),
"teacher_comment": correction.get("teacher_comment", ""),
"bacpilot_score": "",
"bacpilot_max_score": "",
"bacpilot_verdict": "",
"bacpilot_confidence": "",
"bacpilot_main_error": "",
"absolute_score_error": "",
"false_error_count": "",
"missed_error_count": "",
"needs_human_review_expected": needs_review,
"needs_human_review_bacpilot": "",
"decision": "",
})
converted += 1
output_csv.parent.mkdir(parents=True, exist_ok=True)
with output_csv.open("w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
writer.writeheader()
writer.writerows(rows)
print(f"CONVERTED={converted}")
print(f"SKIPPED_DRAFT={skipped_draft}")
print(f"ERRORS={len(errors)}")
print(f"OUTPUT={output_csv}")
if errors:
for e in errors:
print(f" ERREUR: {e}")
if converted == 0:
print("STATUS=NO_READY_COPIES — remplir les copies et passer status à TEACHER_VALIDATED")
else:
print("STATUS=OK")
if __name__ == "__main__":
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <corpus_dir> <output_csv>")
sys.exit(1)
convert(Path(sys.argv[1]), Path(sys.argv[2]))
|