Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -58,7 +58,7 @@ def extraer_texto(pdf_path: str) -> str:
|
|
58 |
def split_secciones(texto: str) -> (str, str):
|
59 |
"""
|
60 |
Separa el texto en dos partes: la secci贸n 'Preguntas' y la secci贸n 'RESPUESTAS'.
|
61 |
-
Busca las palabras 'Preguntas' y 'RESPUESTAS' ignorando espacios al inicio
|
62 |
"""
|
63 |
match_preg = re.search(r'(?im)^\s*preguntas', texto)
|
64 |
match_resp = re.search(r'(?im)^\s*respuestas', texto)
|
@@ -66,8 +66,8 @@ def split_secciones(texto: str) -> (str, str):
|
|
66 |
if not match_preg or not match_resp:
|
67 |
return (texto, "")
|
68 |
|
69 |
-
start_preg = match_preg.end() #
|
70 |
-
start_resp = match_resp.start() #
|
71 |
|
72 |
texto_preguntas = texto[start_preg:start_resp].strip()
|
73 |
texto_respuestas = texto[match_resp.end():].strip()
|
@@ -79,26 +79,29 @@ def parsear_enumeraciones(texto: str) -> dict:
|
|
79 |
separa cada n煤mero y su contenido.
|
80 |
Retorna un dict: {"Pregunta 1": "contenido", "Pregunta 2": "contenido", ...}.
|
81 |
Este patr贸n es flexible y tolera espacios al inicio y formatos creativos.
|
|
|
82 |
"""
|
83 |
-
#
|
84 |
-
# un punto o gui贸n y opcionalmente otro n煤mero
|
85 |
bloques = re.split(r'(?=^\s*\d+[\.\-]\s*(?:\d+[\.\-])?\s*)', texto, flags=re.MULTILINE)
|
86 |
resultado = {}
|
87 |
for bloque in bloques:
|
88 |
bloque = bloque.strip()
|
89 |
if not bloque:
|
90 |
continue
|
91 |
-
#
|
92 |
match = re.match(r'^\s*(\d+)[\.\-]\s*(?:\d+[\.\-])?\s*(.*)', bloque)
|
93 |
if match:
|
94 |
numero = match.group(1)
|
95 |
contenido = match.group(2)
|
96 |
-
# Si
|
97 |
lineas = bloque.split("\n")
|
98 |
if len(lineas) > 1:
|
99 |
contenido_completo = " ".join([linea.strip() for linea in lineas[1:]])
|
100 |
if contenido_completo:
|
101 |
-
contenido
|
|
|
|
|
102 |
resultado[f"Pregunta {numero}"] = contenido.strip()
|
103 |
return resultado
|
104 |
|
@@ -165,7 +168,7 @@ def revisar_examen(json_cred, pdf_docente, pdf_alumno):
|
|
165 |
1. Configura credenciales.
|
166 |
2. Extrae y parsea el contenido de los PDFs.
|
167 |
3. Separa las secciones 'Preguntas' y 'RESPUESTAS'.
|
168 |
-
4. Parsea las enumeraciones de cada secci贸n (
|
169 |
5. Compara las respuestas del alumno con las correctas.
|
170 |
6. Llama a un LLM para generar un resumen final con retroalimentaci贸n.
|
171 |
"""
|
@@ -191,7 +194,7 @@ def revisar_examen(json_cred, pdf_docente, pdf_alumno):
|
|
191 |
yield "Parseando enumeraciones (docente)..."
|
192 |
dict_preg_doc = parsear_enumeraciones(preguntas_doc)
|
193 |
dict_resp_doc = parsear_enumeraciones(respuestas_doc)
|
194 |
-
# Unir las respuestas del docente
|
195 |
dict_docente = {}
|
196 |
for key in dict_preg_doc:
|
197 |
dict_docente[key] = dict_resp_doc.get(key, "")
|
|
|
58 |
def split_secciones(texto: str) -> (str, str):
|
59 |
"""
|
60 |
Separa el texto en dos partes: la secci贸n 'Preguntas' y la secci贸n 'RESPUESTAS'.
|
61 |
+
Busca las palabras 'Preguntas' y 'RESPUESTAS' ignorando may煤sculas y espacios al inicio.
|
62 |
"""
|
63 |
match_preg = re.search(r'(?im)^\s*preguntas', texto)
|
64 |
match_resp = re.search(r'(?im)^\s*respuestas', texto)
|
|
|
66 |
if not match_preg or not match_resp:
|
67 |
return (texto, "")
|
68 |
|
69 |
+
start_preg = match_preg.end() # Fin de "Preguntas"
|
70 |
+
start_resp = match_resp.start() # Inicio de "RESPUESTAS"
|
71 |
|
72 |
texto_preguntas = texto[start_preg:start_resp].strip()
|
73 |
texto_respuestas = texto[match_resp.end():].strip()
|
|
|
79 |
separa cada n煤mero y su contenido.
|
80 |
Retorna un dict: {"Pregunta 1": "contenido", "Pregunta 2": "contenido", ...}.
|
81 |
Este patr贸n es flexible y tolera espacios al inicio y formatos creativos.
|
82 |
+
Adem谩s, elimina duplicados al inicio de la respuesta (por ejemplo, "Durante Durante ...").
|
83 |
"""
|
84 |
+
# Se utiliza un lookahead para dividir cada bloque cuando se encuentre una l铆nea que empiece con un n煤mero,
|
85 |
+
# un punto o gui贸n y, opcionalmente, otro n煤mero con punto o gui贸n.
|
86 |
bloques = re.split(r'(?=^\s*\d+[\.\-]\s*(?:\d+[\.\-])?\s*)', texto, flags=re.MULTILINE)
|
87 |
resultado = {}
|
88 |
for bloque in bloques:
|
89 |
bloque = bloque.strip()
|
90 |
if not bloque:
|
91 |
continue
|
92 |
+
# Extraemos el n煤mero de la pregunta y el contenido.
|
93 |
match = re.match(r'^\s*(\d+)[\.\-]\s*(?:\d+[\.\-])?\s*(.*)', bloque)
|
94 |
if match:
|
95 |
numero = match.group(1)
|
96 |
contenido = match.group(2)
|
97 |
+
# Si hay m煤ltiples l铆neas, unimos las l铆neas adicionales.
|
98 |
lineas = bloque.split("\n")
|
99 |
if len(lineas) > 1:
|
100 |
contenido_completo = " ".join([linea.strip() for linea in lineas[1:]])
|
101 |
if contenido_completo:
|
102 |
+
contenido = contenido + " " + contenido_completo
|
103 |
+
# Eliminar duplicados al inicio (por ejemplo, "Durante Durante ..." se convierte en "Durante ...")
|
104 |
+
contenido = re.sub(r'^(\S+)(\s+\1)+\s+', r'\1 ', contenido)
|
105 |
resultado[f"Pregunta {numero}"] = contenido.strip()
|
106 |
return resultado
|
107 |
|
|
|
168 |
1. Configura credenciales.
|
169 |
2. Extrae y parsea el contenido de los PDFs.
|
170 |
3. Separa las secciones 'Preguntas' y 'RESPUESTAS'.
|
171 |
+
4. Parsea las enumeraciones de cada secci贸n (soportando formatos creativos).
|
172 |
5. Compara las respuestas del alumno con las correctas.
|
173 |
6. Llama a un LLM para generar un resumen final con retroalimentaci贸n.
|
174 |
"""
|
|
|
194 |
yield "Parseando enumeraciones (docente)..."
|
195 |
dict_preg_doc = parsear_enumeraciones(preguntas_doc)
|
196 |
dict_resp_doc = parsear_enumeraciones(respuestas_doc)
|
197 |
+
# Unir las respuestas correctas del docente
|
198 |
dict_docente = {}
|
199 |
for key in dict_preg_doc:
|
200 |
dict_docente[key] = dict_resp_doc.get(key, "")
|