Update modules/studentact/student_activities_v2.py
Browse files
modules/studentact/student_activities_v2.py
CHANGED
@@ -77,6 +77,7 @@ def display_student_activities(username: str, lang_code: str, t: dict):
|
|
77 |
|
78 |
|
79 |
###############################################################################################
|
|
|
80 |
def display_current_situation_activities(username: str, t: dict):
|
81 |
"""
|
82 |
Muestra análisis de situación actual junto con las recomendaciones de Claude
|
@@ -97,20 +98,23 @@ def display_current_situation_activities(username: str, t: dict):
|
|
97 |
return
|
98 |
|
99 |
# Crear un diccionario para indexar análisis por timestamp
|
|
|
100 |
logger.info("Creando índice temporal de análisis")
|
101 |
analyses_by_timestamp = {}
|
102 |
|
103 |
# Indexar análisis de situación actual
|
104 |
for analysis in situation_analyses:
|
105 |
if 'timestamp' in analysis:
|
106 |
-
|
|
|
107 |
if timestamp_key not in analyses_by_timestamp:
|
108 |
analyses_by_timestamp[timestamp_key] = {'situation': analysis}
|
109 |
|
110 |
# Indexar recomendaciones de Claude
|
111 |
for recommendation in claude_recommendations:
|
112 |
if 'timestamp' in recommendation:
|
113 |
-
|
|
|
114 |
if timestamp_key in analyses_by_timestamp:
|
115 |
analyses_by_timestamp[timestamp_key]['recommendation'] = recommendation
|
116 |
else:
|
@@ -141,12 +145,13 @@ def display_current_situation_activities(username: str, t: dict):
|
|
141 |
if not situation_data and not recommendation_data:
|
142 |
continue
|
143 |
|
144 |
-
# Determinar qué texto mostrar
|
145 |
text_to_show = situation_data.get('text', recommendation_data.get('text', ''))
|
146 |
text_type = situation_data.get('text_type', recommendation_data.get('text_type', ''))
|
147 |
|
148 |
# Formatear fecha para mostrar
|
149 |
try:
|
|
|
150 |
timestamp_str = situation_data.get('timestamp', recommendation_data.get('timestamp', timestamp_key))
|
151 |
timestamp = datetime.fromisoformat(timestamp_str.replace('Z', '+00:00'))
|
152 |
formatted_date = timestamp.strftime("%d/%m/%Y %H:%M:%S")
|
@@ -164,24 +169,30 @@ def display_current_situation_activities(username: str, t: dict):
|
|
164 |
}.get(text_type, text_type)
|
165 |
title += f" - {text_type_display}"
|
166 |
|
|
|
|
|
|
|
167 |
# Mostrar el análisis en un expander
|
168 |
-
with st.expander(title, expanded=False, key=
|
169 |
# Mostrar texto analizado
|
170 |
st.subheader(t.get('analyzed_text', 'Texto analizado'))
|
|
|
|
|
171 |
st.text_area(
|
172 |
label="Texto analizado",
|
173 |
value=text_to_show,
|
174 |
height=100,
|
175 |
disabled=True,
|
176 |
-
key=
|
177 |
label_visibility="hidden"
|
178 |
)
|
179 |
|
180 |
# Crear tabs para separar diagnóstico y recomendaciones
|
|
|
181 |
diagnosis_tab, recommendations_tab = st.tabs([
|
182 |
t.get('diagnosis_tab', 'Diagnóstico'),
|
183 |
t.get('recommendations_tab', 'Recomendaciones')
|
184 |
-
])
|
185 |
|
186 |
# Tab de diagnóstico
|
187 |
with diagnosis_tab:
|
@@ -196,7 +207,7 @@ def display_current_situation_activities(username: str, t: dict):
|
|
196 |
st.subheader(t.get('key_metrics', 'Métricas clave'))
|
197 |
|
198 |
# Mostrar cada métrica principal
|
199 |
-
for
|
200 |
if isinstance(metric_data, dict) and 'normalized_score' in metric_data:
|
201 |
score = metric_data['normalized_score']
|
202 |
|
@@ -212,40 +223,45 @@ def display_current_situation_activities(username: str, t: dict):
|
|
212 |
color = "#ccffcc" # light green
|
213 |
|
214 |
# Mostrar la métrica con estilo
|
|
|
215 |
st.markdown(f"""
|
216 |
<div style="background-color:{color}; padding:10px; border-radius:5px; margin-bottom:10px;">
|
217 |
<b>{emoji} {metric_name.capitalize()}:</b> {score:.2f}
|
218 |
</div>
|
219 |
-
""", unsafe_allow_html=True)
|
220 |
|
221 |
# Mostrar detalles adicionales si están disponibles
|
222 |
with col2:
|
223 |
st.subheader(t.get('details', 'Detalles'))
|
224 |
|
225 |
-
#
|
226 |
-
for
|
227 |
if isinstance(metric_data, dict) and 'details' in metric_data and metric_data['details']:
|
228 |
-
|
229 |
-
st.
|
|
|
|
|
230 |
else:
|
231 |
st.info(t.get('no_diagnosis', 'No hay datos de diagnóstico disponibles'))
|
232 |
|
233 |
# Tab de recomendaciones
|
234 |
with recommendations_tab:
|
235 |
if recommendation_data and 'recommendations' in recommendation_data:
|
|
|
236 |
st.markdown(f"""
|
237 |
<div style="padding: 20px; border-radius: 10px;
|
238 |
background-color: #f8f9fa; margin-bottom: 20px;">
|
239 |
{recommendation_data['recommendations']}
|
240 |
</div>
|
241 |
-
""", unsafe_allow_html=True)
|
242 |
elif recommendation_data and 'feedback' in recommendation_data:
|
|
|
243 |
st.markdown(f"""
|
244 |
<div style="padding: 20px; border-radius: 10px;
|
245 |
background-color: #f8f9fa; margin-bottom: 20px;">
|
246 |
{recommendation_data['feedback']}
|
247 |
</div>
|
248 |
-
""", unsafe_allow_html=True)
|
249 |
else:
|
250 |
st.info(t.get('no_recommendations', 'No hay recomendaciones disponibles'))
|
251 |
|
|
|
77 |
|
78 |
|
79 |
###############################################################################################
|
80 |
+
|
81 |
def display_current_situation_activities(username: str, t: dict):
|
82 |
"""
|
83 |
Muestra análisis de situación actual junto con las recomendaciones de Claude
|
|
|
98 |
return
|
99 |
|
100 |
# Crear un diccionario para indexar análisis por timestamp
|
101 |
+
# Esto permite emparejar diagnósticos y recomendaciones del mismo momento
|
102 |
logger.info("Creando índice temporal de análisis")
|
103 |
analyses_by_timestamp = {}
|
104 |
|
105 |
# Indexar análisis de situación actual
|
106 |
for analysis in situation_analyses:
|
107 |
if 'timestamp' in analysis:
|
108 |
+
# Normalizar el formato de timestamp para comparación
|
109 |
+
timestamp_key = analysis['timestamp'].split('.')[0] # Remover milisegundos
|
110 |
if timestamp_key not in analyses_by_timestamp:
|
111 |
analyses_by_timestamp[timestamp_key] = {'situation': analysis}
|
112 |
|
113 |
# Indexar recomendaciones de Claude
|
114 |
for recommendation in claude_recommendations:
|
115 |
if 'timestamp' in recommendation:
|
116 |
+
# Normalizar el formato de timestamp para comparación
|
117 |
+
timestamp_key = recommendation['timestamp'].split('.')[0] # Remover milisegundos
|
118 |
if timestamp_key in analyses_by_timestamp:
|
119 |
analyses_by_timestamp[timestamp_key]['recommendation'] = recommendation
|
120 |
else:
|
|
|
145 |
if not situation_data and not recommendation_data:
|
146 |
continue
|
147 |
|
148 |
+
# Determinar qué texto mostrar (priorizar el de la situación)
|
149 |
text_to_show = situation_data.get('text', recommendation_data.get('text', ''))
|
150 |
text_type = situation_data.get('text_type', recommendation_data.get('text_type', ''))
|
151 |
|
152 |
# Formatear fecha para mostrar
|
153 |
try:
|
154 |
+
# Usar timestamp de situation_data si está disponible, sino usar el de recommendation_data
|
155 |
timestamp_str = situation_data.get('timestamp', recommendation_data.get('timestamp', timestamp_key))
|
156 |
timestamp = datetime.fromisoformat(timestamp_str.replace('Z', '+00:00'))
|
157 |
formatted_date = timestamp.strftime("%d/%m/%Y %H:%M:%S")
|
|
|
169 |
}.get(text_type, text_type)
|
170 |
title += f" - {text_type_display}"
|
171 |
|
172 |
+
# Generar clave única para este expander
|
173 |
+
expander_key = generate_unique_key("situation", f"expander_{i}", username)
|
174 |
+
|
175 |
# Mostrar el análisis en un expander
|
176 |
+
with st.expander(title, expanded=False, key=expander_key):
|
177 |
# Mostrar texto analizado
|
178 |
st.subheader(t.get('analyzed_text', 'Texto analizado'))
|
179 |
+
# Usar clave única para el text_area
|
180 |
+
text_area_key = generate_unique_key("situation", f"text_area_{i}", username)
|
181 |
st.text_area(
|
182 |
label="Texto analizado",
|
183 |
value=text_to_show,
|
184 |
height=100,
|
185 |
disabled=True,
|
186 |
+
key=text_area_key,
|
187 |
label_visibility="hidden"
|
188 |
)
|
189 |
|
190 |
# Crear tabs para separar diagnóstico y recomendaciones
|
191 |
+
tab_key = generate_unique_key("situation", f"tabs_{i}", username)
|
192 |
diagnosis_tab, recommendations_tab = st.tabs([
|
193 |
t.get('diagnosis_tab', 'Diagnóstico'),
|
194 |
t.get('recommendations_tab', 'Recomendaciones')
|
195 |
+
], key=tab_key)
|
196 |
|
197 |
# Tab de diagnóstico
|
198 |
with diagnosis_tab:
|
|
|
207 |
st.subheader(t.get('key_metrics', 'Métricas clave'))
|
208 |
|
209 |
# Mostrar cada métrica principal
|
210 |
+
for metric_name, metric_data in metrics.items():
|
211 |
if isinstance(metric_data, dict) and 'normalized_score' in metric_data:
|
212 |
score = metric_data['normalized_score']
|
213 |
|
|
|
223 |
color = "#ccffcc" # light green
|
224 |
|
225 |
# Mostrar la métrica con estilo
|
226 |
+
metric_key = generate_unique_key("situation", f"metric_{i}_{metric_name}", username)
|
227 |
st.markdown(f"""
|
228 |
<div style="background-color:{color}; padding:10px; border-radius:5px; margin-bottom:10px;">
|
229 |
<b>{emoji} {metric_name.capitalize()}:</b> {score:.2f}
|
230 |
</div>
|
231 |
+
""", unsafe_allow_html=True, key=metric_key)
|
232 |
|
233 |
# Mostrar detalles adicionales si están disponibles
|
234 |
with col2:
|
235 |
st.subheader(t.get('details', 'Detalles'))
|
236 |
|
237 |
+
# Recursivamente mostrar detalles de las métricas como JSON o texto plano
|
238 |
+
for metric_name, metric_data in metrics.items():
|
239 |
if isinstance(metric_data, dict) and 'details' in metric_data and metric_data['details']:
|
240 |
+
detail_key = generate_unique_key("situation", f"detail_{i}_{metric_name}", username)
|
241 |
+
with st.container():
|
242 |
+
st.markdown(f"**{metric_name.capitalize()}**")
|
243 |
+
st.json(metric_data['details'], key=detail_key)
|
244 |
else:
|
245 |
st.info(t.get('no_diagnosis', 'No hay datos de diagnóstico disponibles'))
|
246 |
|
247 |
# Tab de recomendaciones
|
248 |
with recommendations_tab:
|
249 |
if recommendation_data and 'recommendations' in recommendation_data:
|
250 |
+
recom_key = generate_unique_key("situation", f"recom_{i}", username)
|
251 |
st.markdown(f"""
|
252 |
<div style="padding: 20px; border-radius: 10px;
|
253 |
background-color: #f8f9fa; margin-bottom: 20px;">
|
254 |
{recommendation_data['recommendations']}
|
255 |
</div>
|
256 |
+
""", unsafe_allow_html=True, key=recom_key)
|
257 |
elif recommendation_data and 'feedback' in recommendation_data:
|
258 |
+
feedback_key = generate_unique_key("situation", f"feedback_{i}", username)
|
259 |
st.markdown(f"""
|
260 |
<div style="padding: 20px; border-radius: 10px;
|
261 |
background-color: #f8f9fa; margin-bottom: 20px;">
|
262 |
{recommendation_data['feedback']}
|
263 |
</div>
|
264 |
+
""", unsafe_allow_html=True, key=feedback_key)
|
265 |
else:
|
266 |
st.info(t.get('no_recommendations', 'No hay recomendaciones disponibles'))
|
267 |
|