From aa780134edc175471bfecb355c8a75649ee2bf8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Miquel?= Date: Tue, 10 Mar 2026 16:34:40 +0100 Subject: [PATCH] Score more right on annotating, and ID at the left. --- annotating.py | 24 +++++++++++++++++++----- annotating_by_label.py | 4 +++- correction.py | 13 ++++++++++++- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/annotating.py b/annotating.py index a41d4e1..e6cfc2a 100644 --- a/annotating.py +++ b/annotating.py @@ -301,7 +301,7 @@ def color(score): def render_score_text(label, score, error, width_px, fontsize=18, bg_color=(255, 255, 255, 255), - with_error=True): + with_error=True, id=None): # 1. Calculate Color Gradient # 2. Build highlight-text String & Properties @@ -313,6 +313,9 @@ def render_score_text(label, score, error, width_px, fontsize=18, score_str += f" <{error}>" hl_props.append({"color": "orange", "fontweight": "bold"}) + if id: + score_str = f"{id} " + score_str + # 3. Wrap Text dpi = 100 fig_width = width_px / dpi @@ -353,7 +356,9 @@ def compose_label_image(base_img, label, result, hmin, render_fn=render_latex_text, draw_callback=None, with_error=True, - with_empty=False): + with_empty=False, + more_right=False, + with_id=None): """ Composes the final image with annotations. @@ -384,8 +389,13 @@ def compose_label_image(base_img, label, result, hmin, # 1. Prepare Headers header_elements = [] - img_score = render_score_text(label, score, error, base_img.width // 2, - fontsize=18, with_error=with_error) + if more_right: + width = base_img.width // 2 + else: + width = base_img.width // 2 - 150 + img_score = render_score_text(label, score, error, width, + fontsize=18, with_error=with_error, + id=with_error) header_elements.append({"type": "score", "img": img_score, "data": result}) # Global Feedbacks @@ -405,7 +415,11 @@ def compose_label_image(base_img, label, result, hmin, draw = ImageDraw.Draw(final_img, "RGBA") for el in header_elements: - final_img.paste(el["img"], (0, current_y)) + if el["type"] == "score" and more_right: + final_img.paste(el["img"], (150, current_y)) + else: + final_img.paste(el["img"], (0, current_y)) + if draw_callback: # Hook for checkboxes diff --git a/annotating_by_label.py b/annotating_by_label.py index f49f301..0fa4c27 100644 --- a/annotating_by_label.py +++ b/annotating_by_label.py @@ -27,7 +27,9 @@ def render_item(item): final_img, header_h = annotating.compose_label_image( base_img, label, content['result'], content['coordinates'][0], render_fn=annotating_with_checks.safe_render_latex, - draw_callback=cb_renderer.callback + draw_callback=cb_renderer.callback, + more_right=True, + with_id=student_id ) if final_img is None: return None diff --git a/correction.py b/correction.py index 02b3f15..e19b363 100644 --- a/correction.py +++ b/correction.py @@ -145,6 +145,7 @@ def make_prompt(full_label): from google import genai from google.genai import types import base64 +import shlex import json from pathlib import Path import os @@ -218,6 +219,7 @@ start_time = time.time() overwrite = args.overwrite limit = args.limit completed_tasks = [] +errors_summary = [] # --- Lock for thread-safe file writing --- io_lock = threading.Lock() @@ -343,7 +345,10 @@ def process_single_task(task_tuple): except json.JSONDecodeError: print(f"Error decoding JSON for {file_path}", file=sys.stderr) except Exception as e: - print(f"Exception processing {file_path}: {e}", file=sys.stderr) + error_msg = f"Exception processing {file_path}: {e}" + print(error_msg, file=sys.stderr) + with io_lock: + errors_summary.append((error_msg, file_path)) print(f"Starting processing on {len(tasks_to_process)} tasks with {NB_THREADS} threads...") @@ -353,3 +358,9 @@ with concurrent.futures.ThreadPoolExecutor(max_workers=NB_THREADS) as executor: end_time = time.time() print("Time elapsed : ", end_time - start_time) print("Requests to pro / flash : ", pro_count, flash_count) +if errors_summary: + print("\n--- Summary of Exceptions ---", file=sys.stderr) + for (err, file) in errors_summary: + print(err, file=sys.stderr) + escaped_path = shlex.quote(str(file_path)) + print(f"Run : python correction.py {escaped_path}")