Update modules/studentact/current_situation_interface.py
Browse files
modules/studentact/current_situation_interface.py
CHANGED
@@ -28,7 +28,7 @@ logger = logging.getLogger(__name__)
|
|
28 |
|
29 |
def display_current_situation_interface(lang_code, nlp_models, t):
|
30 |
"""
|
31 |
-
Interfaz simplificada
|
32 |
"""
|
33 |
try:
|
34 |
# Inicializar estados si no existen
|
@@ -53,7 +53,7 @@ def display_current_situation_interface(lang_code, nlp_models, t):
|
|
53 |
# Función para manejar cambios en el texto
|
54 |
def on_text_change():
|
55 |
st.session_state.text_input = st.session_state.text_area
|
56 |
-
st.session_state.show_results = False
|
57 |
|
58 |
# Text area con manejo de estado
|
59 |
text_input = st.text_area(
|
@@ -73,7 +73,6 @@ def display_current_situation_interface(lang_code, nlp_models, t):
|
|
73 |
):
|
74 |
try:
|
75 |
with st.spinner(t.get('processing', "Analizando...")):
|
76 |
-
# Procesar texto y obtener métricas
|
77 |
doc = nlp_models[lang_code](text_input)
|
78 |
metrics = analyze_text_dimensions(doc)
|
79 |
|
@@ -82,13 +81,12 @@ def display_current_situation_interface(lang_code, nlp_models, t):
|
|
82 |
username=st.session_state.username,
|
83 |
text=text_input,
|
84 |
metrics=metrics,
|
85 |
-
feedback=None
|
86 |
)
|
87 |
|
88 |
if not storage_success:
|
89 |
logger.warning("No se pudo guardar el análisis en la base de datos")
|
90 |
|
91 |
-
# Actualizar estado
|
92 |
st.session_state.current_doc = doc
|
93 |
st.session_state.current_metrics = metrics
|
94 |
st.session_state.show_results = True
|
@@ -97,195 +95,77 @@ def display_current_situation_interface(lang_code, nlp_models, t):
|
|
97 |
except Exception as e:
|
98 |
logger.error(f"Error en análisis: {str(e)}")
|
99 |
st.error(t.get('analysis_error', "Error al analizar el texto"))
|
100 |
-
|
101 |
# Mostrar resultados en la columna derecha
|
102 |
with results_col:
|
103 |
if st.session_state.show_results and st.session_state.current_metrics is not None:
|
104 |
-
|
105 |
-
|
106 |
-
# Opción para ver detalles
|
107 |
-
with st.expander("🔍 Ver análisis detallado", expanded=False):
|
108 |
-
display_current_situation_visual(
|
109 |
-
st.session_state.current_doc,
|
110 |
-
st.session_state.current_metrics
|
111 |
-
)
|
112 |
-
|
113 |
except Exception as e:
|
114 |
logger.error(f"Error en interfaz: {str(e)}")
|
115 |
st.error("Ocurrió un error. Por favor, intente de nuevo.")
|
116 |
|
117 |
-
|
118 |
-
|
119 |
-
def display_current_situation_visual(doc, metrics):
|
120 |
"""
|
121 |
-
Muestra
|
122 |
"""
|
123 |
try:
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
# 2. Visualización de estructura
|
134 |
-
with st.expander("Análisis de Estructura", expanded=True):
|
135 |
-
syntax_graph = create_syntax_complexity_graph(doc)
|
136 |
-
if syntax_graph:
|
137 |
-
st.pyplot(syntax_graph)
|
138 |
-
plt.close(syntax_graph)
|
139 |
-
|
140 |
-
# 3. Visualización de cohesión
|
141 |
-
with st.expander("Análisis de Cohesión", expanded=True):
|
142 |
-
cohesion_graph = create_cohesion_heatmap(doc)
|
143 |
-
if cohesion_graph:
|
144 |
-
st.pyplot(cohesion_graph)
|
145 |
-
plt.close(cohesion_graph)
|
146 |
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
|
|
|
|
|
151 |
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
Muestra recomendaciones basadas en las métricas del texto.
|
156 |
-
"""
|
157 |
-
# 1. Resumen Visual con Explicación
|
158 |
-
st.markdown("### 📊 Resumen de tu Análisis")
|
159 |
-
|
160 |
-
# Explicación del sistema de medición
|
161 |
-
st.markdown("""
|
162 |
-
**¿Cómo interpretar los resultados?**
|
163 |
-
|
164 |
-
Cada métrica se mide en una escala de 0.0 a 1.0, donde:
|
165 |
-
- 0.0 - 0.4: Necesita atención prioritaria
|
166 |
-
- 0.4 - 0.6: En desarrollo
|
167 |
-
- 0.6 - 0.8: Buen nivel
|
168 |
-
- 0.8 - 1.0: Nivel avanzado
|
169 |
-
""")
|
170 |
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
with col1:
|
175 |
-
st.metric(
|
176 |
-
"Vocabulario",
|
177 |
-
f"{metrics['vocabulary']['normalized_score']:.2f}",
|
178 |
-
help="Mide la variedad y riqueza de tu vocabulario. Un valor alto indica un uso diverso de palabras sin repeticiones excesivas."
|
179 |
-
)
|
180 |
-
with st.expander("ℹ️ Detalles"):
|
181 |
-
st.write("""
|
182 |
-
**Vocabulario**
|
183 |
-
- Evalúa la diversidad léxica
|
184 |
-
- Considera palabras únicas vs. totales
|
185 |
-
- Detecta repeticiones innecesarias
|
186 |
-
- Valor óptimo: > 0.7
|
187 |
-
""")
|
188 |
-
|
189 |
-
with col2:
|
190 |
-
st.metric(
|
191 |
-
"Estructura",
|
192 |
-
f"{metrics['structure']['normalized_score']:.2f}",
|
193 |
-
help="Evalúa la complejidad y variedad de las estructuras sintácticas en tus oraciones."
|
194 |
-
)
|
195 |
-
with st.expander("ℹ️ Detalles"):
|
196 |
-
st.write("""
|
197 |
-
**Estructura**
|
198 |
-
- Analiza la complejidad sintáctica
|
199 |
-
- Mide variación en construcciones
|
200 |
-
- Evalúa longitud de oraciones
|
201 |
-
- Valor óptimo: > 0.6
|
202 |
-
""")
|
203 |
-
|
204 |
-
with col3:
|
205 |
-
st.metric(
|
206 |
-
"Cohesión",
|
207 |
-
f"{metrics['cohesion']['normalized_score']:.2f}",
|
208 |
-
help="Indica qué tan bien conectadas están tus ideas y párrafos entre sí."
|
209 |
-
)
|
210 |
-
with st.expander("ℹ️ Detalles"):
|
211 |
-
st.write("""
|
212 |
-
**Cohesión**
|
213 |
-
- Mide conexiones entre ideas
|
214 |
-
- Evalúa uso de conectores
|
215 |
-
- Analiza progresión temática
|
216 |
-
- Valor óptimo: > 0.65
|
217 |
-
""")
|
218 |
-
|
219 |
-
with col4:
|
220 |
-
st.metric(
|
221 |
-
"Claridad",
|
222 |
-
f"{metrics['clarity']['normalized_score']:.2f}",
|
223 |
-
help="Evalúa la facilidad de comprensión general de tu texto."
|
224 |
-
)
|
225 |
-
with st.expander("ℹ️ Detalles"):
|
226 |
-
st.write("""
|
227 |
-
**Claridad**
|
228 |
-
- Evalúa comprensibilidad
|
229 |
-
- Considera estructura lógica
|
230 |
-
- Mide precisión expresiva
|
231 |
-
- Valor óptimo: > 0.7
|
232 |
-
""")
|
233 |
|
234 |
-
|
|
|
|
|
235 |
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
st.
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
""
|
267 |
-
|
268 |
-
# Recomendaciones de cohesión
|
269 |
-
if metrics['cohesion']['normalized_score'] < 0.65:
|
270 |
-
st.warning("""
|
271 |
-
#### 🔄 Análisis del Discurso Recomendado
|
272 |
-
|
273 |
-
**Para mejorar la conexión entre ideas:**
|
274 |
-
1. Realizar el análisis del discurso de un texto modelo
|
275 |
-
2. Practicar el uso de diferentes conectores textuales
|
276 |
-
3. Identificar cadenas de referencia en textos académicos
|
277 |
-
4. Ejercitar la progresión temática en tus escritos
|
278 |
-
|
279 |
-
*Hacer clic en "Comenzar ejercicios" para acceder al módulo de análisis del discurso*
|
280 |
-
""")
|
281 |
-
|
282 |
-
# Botón de acción
|
283 |
-
st.markdown("---")
|
284 |
-
col1, col2, col3 = st.columns([1,2,1])
|
285 |
-
with col2:
|
286 |
-
st.button(
|
287 |
-
"🎯 Comenzar ejercicios recomendados",
|
288 |
-
type="primary",
|
289 |
-
use_container_width=True,
|
290 |
-
key="start_exercises"
|
291 |
-
)
|
|
|
28 |
|
29 |
def display_current_situation_interface(lang_code, nlp_models, t):
|
30 |
"""
|
31 |
+
Interfaz simplificada con gráfico de radar para visualizar métricas.
|
32 |
"""
|
33 |
try:
|
34 |
# Inicializar estados si no existen
|
|
|
53 |
# Función para manejar cambios en el texto
|
54 |
def on_text_change():
|
55 |
st.session_state.text_input = st.session_state.text_area
|
56 |
+
st.session_state.show_results = False
|
57 |
|
58 |
# Text area con manejo de estado
|
59 |
text_input = st.text_area(
|
|
|
73 |
):
|
74 |
try:
|
75 |
with st.spinner(t.get('processing', "Analizando...")):
|
|
|
76 |
doc = nlp_models[lang_code](text_input)
|
77 |
metrics = analyze_text_dimensions(doc)
|
78 |
|
|
|
81 |
username=st.session_state.username,
|
82 |
text=text_input,
|
83 |
metrics=metrics,
|
84 |
+
feedback=None
|
85 |
)
|
86 |
|
87 |
if not storage_success:
|
88 |
logger.warning("No se pudo guardar el análisis en la base de datos")
|
89 |
|
|
|
90 |
st.session_state.current_doc = doc
|
91 |
st.session_state.current_metrics = metrics
|
92 |
st.session_state.show_results = True
|
|
|
95 |
except Exception as e:
|
96 |
logger.error(f"Error en análisis: {str(e)}")
|
97 |
st.error(t.get('analysis_error', "Error al analizar el texto"))
|
98 |
+
|
99 |
# Mostrar resultados en la columna derecha
|
100 |
with results_col:
|
101 |
if st.session_state.show_results and st.session_state.current_metrics is not None:
|
102 |
+
display_radar_chart(st.session_state.current_metrics)
|
103 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
except Exception as e:
|
105 |
logger.error(f"Error en interfaz: {str(e)}")
|
106 |
st.error("Ocurrió un error. Por favor, intente de nuevo.")
|
107 |
|
108 |
+
def display_radar_chart(metrics):
|
|
|
|
|
109 |
"""
|
110 |
+
Muestra un gráfico de radar con las cuatro métricas.
|
111 |
"""
|
112 |
try:
|
113 |
+
# Preparar datos para el gráfico de radar
|
114 |
+
categories = ['Vocabulario', 'Estructura', 'Cohesión', 'Claridad']
|
115 |
+
values = [
|
116 |
+
metrics['vocabulary']['normalized_score'],
|
117 |
+
metrics['structure']['normalized_score'],
|
118 |
+
metrics['cohesion']['normalized_score'],
|
119 |
+
metrics['clarity']['normalized_score']
|
120 |
+
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
|
122 |
+
# Crear figura
|
123 |
+
fig = plt.figure(figsize=(8, 8))
|
124 |
+
ax = fig.add_subplot(111, projection='polar')
|
125 |
|
126 |
+
# Número de variables
|
127 |
+
num_vars = len(categories)
|
128 |
|
129 |
+
# Calcular ángulos para cada eje
|
130 |
+
angles = [n / float(num_vars) * 2 * np.pi for n in range(num_vars)]
|
131 |
+
angles += angles[:1] # Completar el círculo
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
|
133 |
+
# Extender valores para cerrar el polígono
|
134 |
+
values += values[:1]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
|
136 |
+
# Dibujar las líneas de la cuadrícula principal
|
137 |
+
ax.set_xticks(angles[:-1])
|
138 |
+
ax.set_xticklabels(categories)
|
139 |
|
140 |
+
# Configurar círculos concéntricos y etiquetas
|
141 |
+
circle_ticks = np.arange(0, 1.1, 0.1)
|
142 |
+
ax.set_yticks(circle_ticks)
|
143 |
+
ax.set_yticklabels([f'{tick:.1f}' for tick in circle_ticks])
|
144 |
+
ax.set_ylim(0, 1)
|
145 |
+
|
146 |
+
# Dibujar líneas de la cuadrícula
|
147 |
+
ax.grid(True)
|
148 |
+
|
149 |
+
# Dibujar el gráfico
|
150 |
+
ax.plot(angles, values, 'o-', linewidth=2, label='Métricas')
|
151 |
+
ax.fill(angles, values, alpha=0.25)
|
152 |
+
|
153 |
+
# Ajustar el layout y mostrar
|
154 |
+
plt.tight_layout()
|
155 |
+
st.pyplot(fig)
|
156 |
+
plt.close()
|
157 |
+
|
158 |
+
# Mostrar valores numéricos debajo del gráfico
|
159 |
+
col1, col2, col3, col4 = st.columns(4)
|
160 |
+
with col1:
|
161 |
+
st.metric("Vocabulario", f"{values[0]:.2f}")
|
162 |
+
with col2:
|
163 |
+
st.metric("Estructura", f"{values[1]:.2f}")
|
164 |
+
with col3:
|
165 |
+
st.metric("Cohesión", f"{values[2]:.2f}")
|
166 |
+
with col4:
|
167 |
+
st.metric("Claridad", f"{values[3]:.2f}")
|
168 |
+
|
169 |
+
except Exception as e:
|
170 |
+
logger.error(f"Error generando gráfico de radar: {str(e)}")
|
171 |
+
st.error("Error al generar la visualización")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|