Working state (mostly)

This commit is contained in:
2026-08-08 14:38:26 +02:00
parent 137a9a7868
commit f345f8bb4f
7 changed files with 32 additions and 22 deletions
+10 -10
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: <08-08-26 12:28> # Time-stamp: <08-08-26 13:18>
#+OPTIONS: #+OPTIONS:
* Méta * Méta
@@ -80,14 +80,14 @@ Copier `default_config.py` en `config.py`. Éventuellement le modifier.
noms/prénoms des élèves, un par ligne noms/prénoms des élèves, un par ligne
2. Créer un dossier correspondant à l'évaluation (=Interro= dans la 2. Créer un dossier correspondant à l'évaluation (=Interro= dans la
suite) suite)
3. Mettre l'énoncé, au format pdf, et l'énoncé et le corrigé au 3. Suivre les instructions suivantes
format .tex dans le dossier.
* Étapes et Script * Étapes et Script
** Prétraitement de l'énoncé ** Prétraitement de l'énoncé
Dans le dossier de l'évaluation, mettre : `enonce.pdf`, `enonce.tex`, Dans le dossier de l'évaluation, mettre les fichiers suivants de l'évaluation :
`correction.tex`.
`enonce.pdf`, `enonce.tex`, `correction.tex`.
- `python gemini_for_enonce.py Interro` or - `python gemini_for_enonce.py Interro` or
`python gemini_for_enonce.py Interro --restart` `python gemini_for_enonce.py Interro --restart`
@@ -123,7 +123,6 @@ Dans le dossier de l'évaluation, mettre : `enonce.pdf`, `enonce.tex`,
- Alternative personnelle : `python enonce_info.py Interro` - Alternative personnelle : `python enonce_info.py Interro`
** Prétraitement des copies ** Prétraitement des copies
Mettre les copies scannées au format pdf dans =Interro=. Mettre les copies scannées au format pdf dans =Interro=.
@@ -137,11 +136,12 @@ Mettre les copies scannées au format pdf dans =Interro=.
3. =python page_splitter.py Interro= 3. =python page_splitter.py Interro=
Découpe des copies A3 en pages A4, en retirant les pages vides. Découpe des copies A3 en pages A4, en retirant les pages vides.
+ s pour garder les deux pages
+ t/n pour garder celle de gauche/de droite
+ r pour jeter les deux pages
Les key bindings ne sont pas adaptés à un clavier azerty… À changer… Pour chaque page double il est possible
+ de garder les deux pages
+ de ne garder qu'une des deux pages.
+ de jeter les deux pages
+ de déplacer la délimitation à droite/gauche
Fix issues with =python page_splitter.py Interro14/Copies/Copie01.pdf= Fix issues with =python page_splitter.py Interro14/Copies/Copie01.pdf=
4. =python cutleft.py Interro= 4. =python cutleft.py Interro=
+2 -1
View File
@@ -281,6 +281,7 @@ import PIL.ImageOps
from config import LATEX_ANOT_AFTER, LATEX_ANOT_BEFORE from config import LATEX_ANOT_AFTER, LATEX_ANOT_BEFORE
from string import Template
def render_real_latex_text(text, width_px, bg_color=(255, 255, 255, 255), max_lines=None, fontsize=19): def render_real_latex_text(text, width_px, bg_color=(255, 255, 255, 255), max_lines=None, fontsize=19):
@@ -289,7 +290,7 @@ def render_real_latex_text(text, width_px, bg_color=(255, 255, 255, 255), max_li
line_spacing = int(fontsize * 1.2) line_spacing = int(fontsize * 1.2)
# Use the 'standalone' class with 'varwidth' to auto-crop height while restricting width # Use the 'standalone' class with 'varwidth' to auto-crop height while restricting width
header = LATEX_ANOT_BEFORE.format( header = LATEX_ANOT_BEFORE.substitute(
width_in=width_in, fontsize=fontsize, line_spacing=line_spacing width_in=width_in, fontsize=fontsize, line_spacing=line_spacing
) )
latex_template = f"{header}{text}{LATEX_ANOT_AFTER}" latex_template = f"{header}{text}{LATEX_ANOT_AFTER}"
+10 -3
View File
@@ -5,6 +5,9 @@ API_KEY = os.environ.get("GEMINI_API_KEY")
# Modèle pour des choses très légères # Modèle pour des choses très légères
MODEL_LITE_ID = "gemini-3.5-flash-lite" MODEL_LITE_ID = "gemini-3.5-flash-lite"
# Modèle pour identifier visuellement les labels
MODEL_FOR_LABEL_ID = "gemini-3.5-flash-lite"
# Modèle pour des choses normales # Modèle pour des choses normales
MODEL_FLASH_ID = "gemini-3.6-flash" MODEL_FLASH_ID = "gemini-3.6-flash"
@@ -42,7 +45,7 @@ PLOTTING_KB = {
### Latex templates ### Latex templates
### Pour la génération d'énoncés ### Pour la génération d'énoncés
LATEX_BEFORE = r"""\documentclass[varwidth=24.8cm,margin=0.4cm]{standalone} LATEX_BEFORE = r"""\documentclass[varwidth=24.8cm,margin=0.4cm]{standalone}
\usepackage[utf8]{inputenc} \usepackage[utf8]{inputenc}
@@ -66,7 +69,10 @@ LATEX_AFTER = r"""
### Pour les annotations sur copies ### Pour les annotations sur copies
LATEX_ANOT_BEFORE = r"""\documentclass[varwidth={width_in}in,margin=0.2cm]{standalone} from string import Template
LATEX_ANOT_BEFORE = Template(
r"""\documentclass[varwidth=${width_in}in,margin=0.2cm]{standalone}
\usepackage[utf8]{inputenc} \usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc} \usepackage[T1]{fontenc}
\usepackage{lmodern} % Enables arbitrary font scaling \usepackage{lmodern} % Enables arbitrary font scaling
@@ -75,8 +81,9 @@ LATEX_ANOT_BEFORE = r"""\documentclass[varwidth={width_in}in,margin=0.2cm]{stand
\usepackage{commands} \usepackage{commands}
%\usepackage{anyfontsize} % replaced by lmodern %\usepackage{anyfontsize} % replaced by lmodern
\begin{document} \begin{document}
\fontsize{{{fontsize}}}{{{line_spacing}}}\selectfont \fontsize{${fontsize}}{${line_spacing}}\selectfont
""" """
)
LATEX_ANOT_AFTER = r""" LATEX_ANOT_AFTER = r"""
\end{document} \end{document}
+1 -1
View File
@@ -14,7 +14,7 @@ from collections import defaultdict
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
import config import config
MODEL_ID = config.MODEL_FLASH_ID MODEL_ID = config.MODEL_FOR_LABEL_ID
api_key = config.API_KEY api_key = config.API_KEY
my_prompt = """I'm giving you an image of the left columns of a written exam. my_prompt = """I'm giving you an image of the left columns of a written exam.
+1 -2
View File
@@ -137,7 +137,6 @@ def worker_thread(base_dir, files_to_process, all_labels):
prepare_image(str(img_path), bb_list, all_labels, nb_pages, last_label_index) prepare_image(str(img_path), bb_list, all_labels, nb_pages, last_label_index)
error_msg = None error_msg = None
image_queue.put((pil_image, json_path, metadata))
except Exception as e: except Exception as e:
print(f"Error processing {img_path.name}: {e}") print(f"Error processing {img_path.name}: {e}")
pil_image = Image.open(str(img_path)) pil_image = Image.open(str(img_path))
@@ -200,7 +199,7 @@ class ImageViewer:
self.root.bind(PLOTTING_KB["previous"], self.on_previous) self.root.bind(PLOTTING_KB["previous"], self.on_previous)
self.root.bind(PLOTTING_KB["edit"], self.on_edit) self.root.bind(PLOTTING_KB["edit"], self.on_edit)
self.root.bind(PLOTTING_KB["open pdf"], self.on_open_pdf) self.root.bind(PLOTTING_KB["open pdf"], self.on_open_pdf)
self.root.bind(PLOTTING_KB["open originial pdf"], self.on_open_ori_pdf) self.root.bind(PLOTTING_KB["open original pdf"], self.on_open_ori_pdf)
self.root.bind(PLOTTING_KB["open eval"], self.on_open_interro) self.root.bind(PLOTTING_KB["open eval"], self.on_open_interro)
self.root.bind('<Escape>', lambda e: self.root.quit()) self.root.bind('<Escape>', lambda e: self.root.quit())
self.label.bind('<Button-1>', self.on_click) self.label.bind('<Button-1>', self.on_click)
+5 -4
View File
@@ -89,11 +89,12 @@ do not score or give feedback to any other question."""
from utils import get_label_text_content, get_label_sol_content, get_label_persp_content from utils import get_label_text_content, get_label_sol_content, get_label_persp_content
def make_prompt(input_dir,full_label): def make_prompt(input_dir,full_label):
text = get_label_text_content(input_dir, full_label) text = get_label_text_content(input_dir, full_label) or ""
corr = get_label_sol_content(input_dir, full_label) corr = get_label_sol_content(input_dir, full_label) or ""
persp = get_label_persp_content(input_dir, full_label) persp = get_label_persp_content(input_dir, full_label) or ""
# print("Debug : l/t/c/p", full_label, text, corr, persp)
if persp and persp != "": if persp:
persp = "\n\nHere are additional scoring instructions : \n\n```\n" + persp +"\n```\n" persp = "\n\nHere are additional scoring instructions : \n\n```\n" + persp +"\n```\n"
return main_prompt.replace("<<text>>", text).replace("<<corr>>", corr).replace("<<persp>>", persp).replace("<<label>>", full_label) return main_prompt.replace("<<text>>", text).replace("<<corr>>", corr).replace("<<persp>>", persp).replace("<<label>>", full_label)
+3 -1
View File
@@ -90,7 +90,9 @@ def get_exam_file_content(folder_path, mode, label):
return direct_file.read_text(encoding="utf-8") return direct_file.read_text(encoding="utf-8")
# 2. Search for grouped files: prefix[suffix1,suffix2,...] # 2. Search for grouped files: prefix[suffix1,suffix2,...]
for file_path in target_dir.glob("*[*]"): for file_path in target_dir.iterdir():
if not file_path.is_file():
continue
name = file_path.name name = file_path.name
if "[" in name and name.endswith("]"): if "[" in name and name.endswith("]"):
# Split 'prefix[suffixes]' -> 'prefix', 'suffixes' # Split 'prefix[suffixes]' -> 'prefix', 'suffixes'