AIdeaText commited on
Commit
76d8286
·
verified ·
1 Parent(s): ca972be

Update modules/studentact/student_activities_v2.py

Browse files
modules/studentact/student_activities_v2.py CHANGED
@@ -537,173 +537,184 @@ def display_semantic_activities(username: str, t: dict):
537
  ###################################################################################################
538
  def display_discourse_activities(username: str, t: dict):
539
  """
540
- Versión mejorada de display_discourse_activities que maneja mejor
541
- los datos faltantes y la depuración.
542
  """
543
  try:
544
  logger.info(f"Recuperando análisis del discurso para {username}")
545
 
546
- # Usar la función mejorada de recuperación
547
- analyses = get_student_discourse_analysis(username)
548
 
549
- # Información de depuración
550
- logger.info(f"Recuperados {len(analyses)} análisis de discurso")
551
- for i, analysis in enumerate(analyses):
552
- keys = list(analysis.keys())
553
- logger.info(f"Análisis {i+1}: claves disponibles = {keys}")
 
 
 
 
 
 
 
 
 
 
 
554
 
555
  if not analyses:
556
- logger.info("No se encontraron análisis del discurso")
557
  st.info(t.get('no_discourse_analyses', 'No hay análisis comparados de textos registrados'))
558
  return
559
 
560
- logger.info(f"Procesando {len(analyses)} análisis del discurso")
561
-
562
- for i, analysis in enumerate(analyses):
563
  try:
564
- # Formatear fecha con manejo de errores
565
  try:
566
  timestamp = datetime.fromisoformat(analysis.get('timestamp', '').replace('Z', '+00:00'))
567
  formatted_date = timestamp.strftime("%d/%m/%Y %H:%M:%S")
568
- except (KeyError, ValueError, TypeError) as e:
569
- logger.warning(f"Error formateando fecha: {str(e)}")
570
  formatted_date = str(analysis.get('timestamp', 'Fecha desconocida'))
571
 
572
  # Crear título del expander
573
  expander_title = f"{t.get('analysis_date', 'Fecha')}: {formatted_date}"
574
 
575
- # Mostrar más información en el título para facilitar identificación
576
- if 'text1' in analysis and analysis['text1']:
577
- text_preview = analysis['text1'][:50] + "..." if len(analysis['text1']) > 50 else analysis['text1']
578
- expander_title += f" | {text_preview}"
579
-
580
- # Crear expander
581
  with st.expander(expander_title, expanded=False):
582
- # Mostrar los datos brutos para depuración (solo durante desarrollo)
583
- st.markdown("**Datos del análisis:**")
584
- # Filtrar keys innecesarias o con datos muy grandes
585
- filtered_data = {k: v for k, v in analysis.items()
586
- if k not in ['_id', 'timestamp', 'text1', 'text2']
587
- and not isinstance(v, bytes)
588
- and not (isinstance(v, str) and len(v) > 500)}
589
- st.json(filtered_data)
590
-
591
- # Mostrar textos analizados (si están disponibles)
592
  if 'text1' in analysis and analysis['text1']:
593
- with st.expander("Ver texto analizado", expanded=False):
594
- st.markdown("**Texto analizado:**")
595
- st.text_area("Texto", value=analysis['text1'], height=150, disabled=True)
 
 
 
 
 
596
 
597
- # Mostrar conceptos clave (si están disponibles)
598
- has_concepts = False
599
-
600
- # Verificar si hay conceptos y son del formato correcto
601
- if ('key_concepts1' in analysis and analysis['key_concepts1'] and
602
- isinstance(analysis['key_concepts1'], list)):
603
- has_concepts = True
604
 
605
- # Crear dos columnas para los conceptos
606
  col1, col2 = st.columns(2)
607
 
608
- # Primera columna: conceptos del texto 1
609
  with col1:
610
  st.markdown(f"**{t.get('concepts_text_1', 'Conceptos Texto 1')}**")
611
  try:
612
- # Intentar crear DataFrame
613
- if (isinstance(analysis['key_concepts1'][0], list) and
614
- len(analysis['key_concepts1'][0]) == 2):
615
- df1 = pd.DataFrame(analysis['key_concepts1'],
616
- columns=['Concepto', 'Relevancia'])
617
- st.dataframe(df1, use_container_width=True)
 
 
618
  else:
619
- # Mostrar como lista simple
620
- st.write(", ".join([str(item) for item in analysis['key_concepts1']]))
621
- except Exception as e:
622
- logger.error(f"Error mostrando conceptos 1: {str(e)}")
623
- st.error("Error al mostrar conceptos del Texto 1")
624
 
625
- # Segunda columna: conceptos del texto 2 (si existen)
626
  with col2:
627
- st.markdown(f"**{t.get('concepts_text_2', 'Conceptos Texto 2')}**")
628
- if ('key_concepts2' in analysis and analysis['key_concepts2'] and
629
- isinstance(analysis['key_concepts2'], list)):
630
  try:
631
- # Intentar crear DataFrame
632
- if (isinstance(analysis['key_concepts2'][0], list) and
633
- len(analysis['key_concepts2'][0]) == 2):
634
- df2 = pd.DataFrame(analysis['key_concepts2'],
635
- columns=['Concepto', 'Relevancia'])
636
- st.dataframe(df2, use_container_width=True)
 
 
637
  else:
638
- # Mostrar como lista simple
639
- st.write(", ".join([str(item) for item in analysis['key_concepts2']]))
640
- except Exception as e:
641
- logger.error(f"Error mostrando conceptos 2: {str(e)}")
642
- st.error("Error al mostrar conceptos del Texto 2")
643
- else:
644
- st.info("No hay conceptos disponibles para el Texto 2")
645
 
646
- # Mostrar gráficos (si existen)
647
- has_graphs = False
648
- for graph_key, graph_title in [
649
- ('graph1', t.get('graph1_title', 'Visualización del Texto 1')),
650
- ('graph2', t.get('graph2_title', 'Visualización del Texto 2')),
651
- ('combined_graph', t.get('combined_graph_title', 'Visualización Comparativa'))
652
- ]:
653
- if graph_key in analysis and analysis[graph_key]:
654
- has_graphs = True
655
- st.markdown(f"### {graph_title}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656
  try:
657
- image_data = analysis[graph_key]
 
 
658
 
659
- # Mostrar según el tipo de dato
660
- if isinstance(image_data, bytes):
661
- st.image(image_data, use_column_width=True)
662
- elif isinstance(image_data, str):
663
- # Intentar decodificar si es base64
664
  try:
665
  import base64
666
- if image_data.startswith('data:image'):
667
- image_bytes = base64.b64decode(image_data.split(',')[1])
 
668
  else:
669
- image_bytes = base64.b64decode(image_data)
 
670
  st.image(image_bytes, use_column_width=True)
671
- except Exception as decode_err:
672
- logger.error(f"Error decodificando imagen: {str(decode_err)}")
673
- st.error("Error decodificando imagen")
674
- elif hasattr(image_data, 'figure'):
675
- # Si es un objeto matplotlib
676
- st.pyplot(image_data)
 
 
677
  else:
678
- st.error(f"Formato de gráfico no reconocido")
679
  except Exception as e:
680
- logger.error(f"Error mostrando gráfico {graph_key}: {str(e)}")
681
- st.error(f"Error mostrando {graph_title}")
682
 
683
- # Mensaje si no hay gráficos ni conceptos
684
- if not has_graphs and not has_concepts:
685
- st.warning("No se encontraron visualizaciones ni conceptos para este análisis")
686
-
687
- # Sugerir regenerar el análisis
688
- st.markdown("""
689
- Este análisis parece estar incompleto. Posibles razones:
690
- 1. El proceso de análisis no terminó correctamente
691
- 2. El texto era demasiado corto o no contenía suficiente información
692
- 3. Hubo un error durante la generación de visualizaciones
 
 
 
 
 
 
693
 
694
- Considera realizar un nuevo análisis con más contenido textual.
695
- """)
 
 
696
 
697
  except Exception as e:
698
  logger.error(f"Error procesando análisis individual: {str(e)}")
699
- st.error(f"Error en análisis #{i+1}: {str(e)}")
700
  continue
701
 
702
  except Exception as e:
703
- logger.error(f"Error general mostrando análisis del discurso: {str(e)}")
704
  st.error(t.get('error_discourse', 'Error al mostrar análisis comparado de textos'))
705
- st.markdown("**Detalles del error:**")
706
- st.exception(e)
707
 
708
  #################################################################################
709
  def display_chat_activities(username: str, t: dict):
 
537
  ###################################################################################################
538
  def display_discourse_activities(username: str, t: dict):
539
  """
540
+ Muestra actividades de análisis del discurso (mostrado como 'Análisis comparado de textos' en la UI)
541
+ Versión simplificada que muestra cualquier dato disponible
542
  """
543
  try:
544
  logger.info(f"Recuperando análisis del discurso para {username}")
545
 
546
+ # Importación inline para evitar circularidad
547
+ from ..database.mongo_db import get_collection
548
 
549
+ # Obtener la colección directamente para evitar cualquier filtrado
550
+ collection = get_collection('student_discourse_analysis')
551
+ if not collection:
552
+ st.info(t.get('no_discourse_analyses', 'No hay análisis comparados de textos registrados'))
553
+ return
554
+
555
+ # Consulta básica - solo por username para capturar todos los registros posibles
556
+ query = {"username": username}
557
+
558
+ # Ejecutar consulta
559
+ try:
560
+ analyses = list(collection.find(query).sort("timestamp", -1))
561
+ logger.info(f"Recuperados {len(analyses)} análisis para {username}")
562
+ except Exception as e:
563
+ logger.error(f"Error recuperando análisis: {str(e)}")
564
+ analyses = []
565
 
566
  if not analyses:
 
567
  st.info(t.get('no_discourse_analyses', 'No hay análisis comparados de textos registrados'))
568
  return
569
 
570
+ # Procesar cada análisis
571
+ for analysis in analyses:
 
572
  try:
573
+ # Formatear fecha
574
  try:
575
  timestamp = datetime.fromisoformat(analysis.get('timestamp', '').replace('Z', '+00:00'))
576
  formatted_date = timestamp.strftime("%d/%m/%Y %H:%M:%S")
577
+ except:
 
578
  formatted_date = str(analysis.get('timestamp', 'Fecha desconocida'))
579
 
580
  # Crear título del expander
581
  expander_title = f"{t.get('analysis_date', 'Fecha')}: {formatted_date}"
582
 
583
+ # Mostrar expander
 
 
 
 
 
584
  with st.expander(expander_title, expanded=False):
585
+ # 1. Mostrar texto analizado si existe
 
 
 
 
 
 
 
 
 
586
  if 'text1' in analysis and analysis['text1']:
587
+ st.subheader(t.get('analyzed_text', 'Texto analizado'))
588
+ st.text_area(
589
+ "Texto",
590
+ value=analysis['text1'],
591
+ height=100,
592
+ disabled=True,
593
+ key=f"text_{str(analysis.get('_id', 'unknown'))}"
594
+ )
595
 
596
+ # 2. Mostrar conceptos clave si existen
597
+ if 'key_concepts1' in analysis and analysis['key_concepts1']:
598
+ st.subheader(t.get('key_concepts', 'Conceptos clave'))
 
 
 
 
599
 
 
600
  col1, col2 = st.columns(2)
601
 
 
602
  with col1:
603
  st.markdown(f"**{t.get('concepts_text_1', 'Conceptos Texto 1')}**")
604
  try:
605
+ # Mostrar como dataframe o texto según formato
606
+ if isinstance(analysis['key_concepts1'], list):
607
+ if len(analysis['key_concepts1']) > 0:
608
+ if isinstance(analysis['key_concepts1'][0], list):
609
+ df = pd.DataFrame(analysis['key_concepts1'], columns=['Concepto', 'Relevancia'])
610
+ st.dataframe(df)
611
+ else:
612
+ st.write(", ".join(str(c) for c in analysis['key_concepts1']))
613
  else:
614
+ st.write(str(analysis['key_concepts1']))
615
+ except:
616
+ st.write(str(analysis['key_concepts1']))
 
 
617
 
 
618
  with col2:
619
+ if 'key_concepts2' in analysis and analysis['key_concepts2']:
620
+ st.markdown(f"**{t.get('concepts_text_2', 'Conceptos Texto 2')}**")
 
621
  try:
622
+ # Mostrar como dataframe o texto según formato
623
+ if isinstance(analysis['key_concepts2'], list):
624
+ if len(analysis['key_concepts2']) > 0:
625
+ if isinstance(analysis['key_concepts2'][0], list):
626
+ df = pd.DataFrame(analysis['key_concepts2'], columns=['Concepto', 'Relevancia'])
627
+ st.dataframe(df)
628
+ else:
629
+ st.write(", ".join(str(c) for c in analysis['key_concepts2']))
630
  else:
631
+ st.write(str(analysis['key_concepts2']))
632
+ except:
633
+ st.write(str(analysis['key_concepts2']))
 
 
 
 
634
 
635
+ # 3. Mostrar cualquier gráfico disponible
636
+ st.subheader(t.get('visualizations', 'Visualizaciones'))
637
+
638
+ # Revisar todos los campos que podrían contener gráficos
639
+ graph_fields = ['graph1', 'graph2', 'combined_graph']
640
+ found_graphs = False
641
+
642
+ for field in graph_fields:
643
+ if field in analysis and analysis[field]:
644
+ found_graphs = True
645
+
646
+ # Título según el tipo de gráfico
647
+ if field == 'graph1':
648
+ title = t.get('graph1_title', 'Gráfico Texto 1')
649
+ elif field == 'graph2':
650
+ title = t.get('graph2_title', 'Gráfico Texto 2')
651
+ else:
652
+ title = t.get('combined_graph_title', 'Gráfico Combinado')
653
+
654
+ st.markdown(f"**{title}**")
655
+
656
+ # Mostrar el gráfico según su tipo
657
+ graph_data = analysis[field]
658
+
659
  try:
660
+ # Si es bytes, mostrar directamente
661
+ if isinstance(graph_data, bytes):
662
+ st.image(graph_data, use_column_width=True)
663
 
664
+ # Si es string, intentar decodificar como base64
665
+ elif isinstance(graph_data, str):
 
 
 
666
  try:
667
  import base64
668
+ # Intentar diferentes formatos de base64
669
+ if graph_data.startswith('data:image'):
670
+ image_bytes = base64.b64decode(graph_data.split(',')[1])
671
  else:
672
+ image_bytes = base64.b64decode(graph_data)
673
+
674
  st.image(image_bytes, use_column_width=True)
675
+ except:
676
+ # Si falla la decodificación, mostrar como texto si no es muy largo
677
+ if len(graph_data) < 100:
678
+ st.text(f"Datos no decodificables: {graph_data}")
679
+ else:
680
+ st.text(f"Datos no decodificables (muy largos)")
681
+
682
+ # Otros tipos (matplotlib, etc.)
683
  else:
684
+ st.write(f"Gráfico presente pero en formato no mostrable")
685
  except Exception as e:
686
+ st.error(f"Error mostrando gráfico: {str(e)}")
 
687
 
688
+ # Si no hay gráficos, mostrar mensaje
689
+ if not found_graphs:
690
+ st.info(t.get('no_graphs', 'No hay gráficos disponibles para este análisis'))
691
+
692
+ # Mostrar botón para generar nuevos gráficos (para futura implementación)
693
+ # st.button("Regenerar gráficos", key=f"btn_regenerate_{str(analysis.get('_id', 'unknown'))}")
694
+
695
+ # 4. Mostrar campos adicionales que puedan ser útiles
696
+ with st.expander("Ver datos adicionales", expanded=False):
697
+ # Filtrar campos para mostrar solo los relevantes
698
+ filtered_data = {k: v for k, v in analysis.items()
699
+ if k not in ['_id', 'username', 'timestamp', 'text1', 'text2',
700
+ 'graph1', 'graph2', 'combined_graph',
701
+ 'key_concepts1', 'key_concepts2']
702
+ and not isinstance(v, bytes)
703
+ and not (isinstance(v, str) and len(v) > 200)}
704
 
705
+ if filtered_data:
706
+ st.json(filtered_data)
707
+ else:
708
+ st.text("No hay datos adicionales disponibles")
709
 
710
  except Exception as e:
711
  logger.error(f"Error procesando análisis individual: {str(e)}")
712
+ st.error(f"Error procesando análisis: {str(e)}")
713
  continue
714
 
715
  except Exception as e:
716
+ logger.error(f"Error general en display_discourse_activities: {str(e)}")
717
  st.error(t.get('error_discourse', 'Error al mostrar análisis comparado de textos'))
 
 
718
 
719
  #################################################################################
720
  def display_chat_activities(username: str, t: dict):