You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
4.5 KiB
129 lines
4.5 KiB
from openai import OpenAI |
|
from PyPDF2 import PdfReader |
|
from django.conf import settings |
|
|
|
liste_eleves = {} |
|
client = OpenAI(api_key=settings.OPENAI_API_KEY) |
|
|
|
def split_by_eleve(text): |
|
""" |
|
Découpe le texte en une liste de chaînes, chaque élément commençant par 'ELEVE'. |
|
""" |
|
import re |
|
# On split sur chaque occurrence de 'ELEVE' suivie d'un ou plusieurs chiffres |
|
parts = re.split(r'(ELEVE\d+)', text) |
|
result = [] |
|
for i in range(1, len(parts), 2): |
|
# parts[i] est 'ELEVEid', parts[i+1] est le texte associé |
|
bloc = parts[i] + parts[i+1] if i+1 < len(parts) else parts[i] |
|
result.append(bloc.strip()) |
|
return result |
|
|
|
def anonymiserPdf(file, eleves): |
|
eleve_id = 1 |
|
pages_content = "" |
|
|
|
for page in file.pages: |
|
lines = page.extract_text().split('\n') |
|
curent_page = [] |
|
write = False |
|
eleve_found = False |
|
|
|
for i, line in enumerate(lines): |
|
# Attendre la ligne qui se termine par " Trimestre" |
|
if not write: |
|
if line.strip().endswith("Trimestre"): |
|
write = True |
|
continue |
|
|
|
# Enregistrer la ligne suivante (nom de l'élève) |
|
if write and not eleve_found: |
|
eleve_nom = line.strip() |
|
if eleve_nom not in eleves: |
|
eleves[eleve_nom] = f"ELEVE{eleve_id}" |
|
eleve_id += 1 |
|
curent_page.append(eleves[eleve_nom] + "\n") |
|
eleve_found = True |
|
continue |
|
|
|
# Attendre la ligne qui commence par "Appréciations" |
|
if eleve_found: |
|
if line.strip().startswith("Appréciations"): |
|
# Commencer à écrire les lignes suivantes |
|
for l in lines[i+1:]: |
|
if l.startswith("M.") or l.startswith("Mme"): |
|
continue |
|
curent_page.append(l + "\n") |
|
break # Fin du traitement de cette page |
|
|
|
pages_content += "".join(curent_page) |
|
return pages_content |
|
|
|
def get_eleve_name(text, eleves): |
|
""" |
|
Extrait le nom de l'élève à partir du texte. |
|
""" |
|
for line in text.split('\n'): |
|
line = line.strip() |
|
if line in eleves: |
|
return eleves[line] |
|
return None |
|
|
|
def replace_eleve_ids_with_names(text, eleves): |
|
# Inverse the eleves dict to map ELEVEid -> nom prénom |
|
id_to_name = {v: k for k, v in eleves.items()} |
|
# Trier les IDs par longueur décroissante pour éviter les remplacements partiels |
|
for eleve_id in sorted(id_to_name.keys(), key=len, reverse=True): |
|
nom = id_to_name[eleve_id] |
|
if eleve_id in text: |
|
text = text.replace(eleve_id, nom) |
|
return text |
|
|
|
def generatationAppreciations(appreciations_path, modele_path=None): |
|
|
|
if (modele_path): |
|
modele = PdfReader(modele_path) |
|
modele_anonyme = anonymiserPdf(modele, liste_eleves) |
|
|
|
appreciations = PdfReader(appreciations_path) |
|
appreciation_anonyme = anonymiserPdf(appreciations, liste_eleves) |
|
tableau_appreciations = split_by_eleve(appreciation_anonyme) |
|
|
|
responses = [] |
|
#debug |
|
tableau_appreciations = tableau_appreciations[:3] |
|
for eleve in tableau_appreciations: |
|
if modele_path: |
|
# Si un modèle est fourni, on utilise le modèle pour chaque élève |
|
data = [ |
|
{ |
|
"role": "developer", |
|
"content": "Tu dois générer des appréciations générales de bulletins avec le style de l'exemple suivant (500 caractères max)" |
|
},{ |
|
"role": "assistant", |
|
"content": modele_anonyme |
|
}, |
|
{ |
|
"role": "user", |
|
"content": eleve |
|
}] |
|
else: |
|
data = [ |
|
{ |
|
"role": "developer", |
|
"content": "Tu dois générer des appréciations générales de bulletins (500 caractères max)" |
|
}, |
|
{ |
|
"role": "user", |
|
"content": eleve |
|
}] |
|
completion = client.chat.completions.create( |
|
model="gpt-4.1-mini", |
|
messages=data, |
|
temperature=1, |
|
top_p=1) |
|
resultat = "<b><u><i>" + get_eleve_name(completion.choices[0].message.content, liste_eleves) + "</i></u></b>\n" |
|
resultat += replace_eleve_ids_with_names(completion.choices[0].message.content, liste_eleves) |
|
responses.append(resultat) |
|
|
|
return responses
|
|
|