support for `--update-score' after manual update of score.json

master
Sébastien Miquel 2026-06-06 10:10:53 +02:00
parent 80d06e4693
commit a80187ba80
3 changed files with 58 additions and 13 deletions

View File

@ -1,7 +1,7 @@
#+title: Script #+title: Script
#+author: Sébastien Miquel #+author: Sébastien Miquel
#+date: 14-03-2026 #+date: 14-03-2026
# Time-stamp: <02-06-26 09:26> # Time-stamp: <06-06-26 10:10>
#+OPTIONS: #+OPTIONS:
* Méta * Méta
@ -245,7 +245,10 @@ OU
Si un nom est =Unknown= : renommer à la main le dossier et le fichier dedans. Si un nom est =Unknown= : renommer à la main le dossier et le fichier dedans.
On peut faire des changements manuels aux =score.json= ici. 4. On peut faire des changements manuels aux =score.json= ici, puis
- `python reading_annotations.py --update-score Interro`
- `python reading_grouped_annotations.py --update-score Interro`
pour mettre à jour les scores dans les images.
4. (gestion perso) 4. (gestion perso)
+ =gestion_classe ne= pour créer l'interro puis + =gestion_classe ne= pour créer l'interro puis
+ =gestion_classe we= (set barème here) + =gestion_classe we= (set barème here)

View File

@ -161,7 +161,8 @@ def has_significant_notes(note_img, threshold=20):
# print(f"Debug : visible pixels is {visible_pixels}") # print(f"Debug : visible pixels is {visible_pixels}")
return visible_pixels > threshold return visible_pixels > threshold
def apply_actions_and_regenerate(root_dir, data, student_id, actions, notes_layer, all_labels): def apply_actions_and_regenerate(root_dir, data, student_id, actions, notes_layer,
all_labels, update_score=False):
""" """
Modifies data based on actions, reads bnote.json, cuts notes, Modifies data based on actions, reads bnote.json, cuts notes,
regenerates all label images for consistency, saves dirty ones, regenerates all label images for consistency, saves dirty ones,
@ -230,6 +231,23 @@ def apply_actions_and_regenerate(root_dir, data, student_id, actions, notes_laye
print(f" > Deleted rect in {label}") print(f" > Deleted rect in {label}")
dirty_labels.add(label) dirty_labels.add(label)
# --- 1.5 Override with existing score.json if requested ---
if update_score and os.path.exists(score_path):
try:
with open(score_path, "r") as f:
existing_scores = json.load(f)
for label, existing_score in existing_scores.items():
if label in labels_data:
current_score = str(labels_data[label]['result'].get('score', 0))
# If manually modified, override the result and mark dirty
if current_score != str(existing_score):
labels_data[label]['result']['score'] = existing_score
dirty_labels.add(label)
print(f" > Overrode score for {label} to {existing_score} from existing score.json")
except json.JSONDecodeError:
print(f" > Warning: Could not read existing {score_path}")
# --- 2. Process Images (Cut notes, Regenerate, Concatenate) --- # --- 2. Process Images (Cut notes, Regenerate, Concatenate) ---
concat_list = [] concat_list = []
concat_list_F = [] concat_list_F = []
@ -332,11 +350,13 @@ def apply_actions_and_regenerate(root_dir, data, student_id, actions, notes_laye
from utils import read_all_labels from utils import read_all_labels
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) < 2: import argparse
print("Usage: python reading_annotations.py <Dir>") parser = argparse.ArgumentParser(description="Read annotations and compile PDFs")
sys.exit(1) parser.add_argument("input_path", help="Directory path")
parser.add_argument("--update-score", action="store_true", help="Override scores with values from existing score.json")
args = parser.parse_args()
root_dir = sys.argv[1] root_dir = args.input_path
try: try:
all_labels = read_all_labels(Path(root_dir)) all_labels = read_all_labels(Path(root_dir))
@ -352,7 +372,9 @@ if __name__ == "__main__":
if os.path.exists(bnot_dir): if os.path.exists(bnot_dir):
print(f"Processing annotations for: {student_id}") print(f"Processing annotations for: {student_id}")
actions, notes = detect_checks_and_notes(bnot_dir) actions, notes = detect_checks_and_notes(bnot_dir)
if actions or notes: if actions or notes or args.update_score:
apply_actions_and_regenerate(root_dir, original_data, student_id, actions, notes, all_labels) apply_actions_and_regenerate(root_dir, original_data, student_id,
actions, notes, all_labels,
update_score=args.update_score)
else: else:
print(" No changes detected or missing files.") print(" No changes detected or missing files.")

View File

@ -91,7 +91,8 @@ def save_paginated_pdf(image_groups, output_path):
pages[0].save(output_path, "PDF", resolution=100.0, save_all=True, append_images=pages[1:]) pages[0].save(output_path, "PDF", resolution=100.0, save_all=True, append_images=pages[1:])
def apply_actions_and_regenerate_grouped(root_dir, data, student_id, def apply_actions_and_regenerate_grouped(root_dir, data, student_id,
actions, label_notes, all_labels): actions, label_notes, all_labels,
update_score=False):
""" """
Modifies data based on actions, pastes label-specific note crops, Modifies data based on actions, pastes label-specific note crops,
regenerates label images for consistency, saves dirty ones, regenerates label images for consistency, saves dirty ones,
@ -155,6 +156,23 @@ def apply_actions_and_regenerate_grouped(root_dir, data, student_id,
logs.append(f" > Deleted rect in {label}") logs.append(f" > Deleted rect in {label}")
dirty_labels.add(label) dirty_labels.add(label)
# --- 1.5 Override with existing score.json if requested ---
if update_score and os.path.exists(score_path):
try:
with open(score_path, "r") as f:
existing_scores = json.load(f)
for label, existing_score in existing_scores.items():
if label in labels_data:
current_score = str(labels_data[label]['result'].get('score', 0))
# If manually modified, override the result and mark dirty
if current_score != str(existing_score):
labels_data[label]['result']['score'] = existing_score
dirty_labels.add(label)
logs.append(f" > Overrode score for {label} to {existing_score} from existing score.json")
except json.JSONDecodeError:
logs.append(f" > Warning: Could not read existing {score_path}")
# --- 2. Process Images (Regenerate & Concatenate) --- # --- 2. Process Images (Regenerate & Concatenate) ---
concat_list = [] concat_list = []
concat_list_F = [] concat_list_F = []
@ -258,6 +276,7 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Read grouped annotations and compile PDFs") parser = argparse.ArgumentParser(description="Read grouped annotations and compile PDFs")
parser.add_argument("input_path", help="Directory path") parser.add_argument("input_path", help="Directory path")
parser.add_argument("--refaire", action="store_true", help="Merge refaire annotations from Bnot") parser.add_argument("--refaire", action="store_true", help="Merge refaire annotations from Bnot")
parser.add_argument("--update-score", action="store_true", help="Override scores with values from existing score.json")
args = parser.parse_args() args = parser.parse_args()
root_dir = sys.argv[1] root_dir = sys.argv[1]
@ -396,7 +415,8 @@ if __name__ == "__main__":
sid, sid,
actions_by_student[sid], actions_by_student[sid],
notes_by_student[sid], notes_by_student[sid],
all_labels all_labels,
update_score=args.update_score
) )
# --- 2. Process each student concurrently using 4 threads --- # --- 2. Process each student concurrently using 4 threads ---