Spaces:
Running
Running
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")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|