Working state (mostly)
This commit is contained in:
+10
-10
@@ -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
@@ -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
@@ -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}
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
Reference in New Issue
Block a user