AIdeaText commited on
Commit
0da4a53
·
verified ·
1 Parent(s): 6cfb47a

Update modules/studentact/student_activities_v2.py

Browse files
modules/studentact/student_activities_v2.py CHANGED
@@ -535,15 +535,22 @@ def display_semantic_activities(username: str, t: dict):
535
 
536
 
537
  ###################################################################################################
538
-
539
  def display_discourse_activities(username: str, t: dict):
540
  """
541
- Muestra actividades de análisis del discurso (mostrado como 'Análisis comparado de textos' en la UI)
542
- con mejor manejo de errores y datos incompletos
543
  """
544
  try:
545
  logger.info(f"Recuperando análisis del discurso para {username}")
546
- analyses = get_student_discourse_analysis(username)
 
 
 
 
 
 
 
 
547
 
548
  if not analyses:
549
  logger.info("No se encontraron análisis del discurso")
@@ -554,12 +561,9 @@ def display_discourse_activities(username: str, t: dict):
554
 
555
  for i, analysis in enumerate(analyses):
556
  try:
557
- # Usar un ID único para este análisis (usando índice si _id no está disponible)
558
- analysis_id = str(analysis.get('_id', f"analysis_{i}"))
559
-
560
  # Formatear fecha con manejo de errores
561
  try:
562
- timestamp = datetime.fromisoformat(analysis['timestamp'].replace('Z', '+00:00'))
563
  formatted_date = timestamp.strftime("%d/%m/%Y %H:%M:%S")
564
  except (KeyError, ValueError, TypeError) as e:
565
  logger.warning(f"Error formateando fecha: {str(e)}")
@@ -568,149 +572,139 @@ def display_discourse_activities(username: str, t: dict):
568
  # Crear título del expander
569
  expander_title = f"{t.get('analysis_date', 'Fecha')}: {formatted_date}"
570
 
 
 
 
 
 
571
  # Crear expander
572
  with st.expander(expander_title, expanded=False):
573
- # Determinar si tenemos datos suficientes para mostrar un análisis útil
574
- has_key_concepts = ('key_concepts1' in analysis and analysis['key_concepts1']) or \
575
- ('key_concepts2' in analysis and analysis['key_concepts2'])
576
-
577
- has_text = ('text1' in analysis and analysis['text1']) or \
578
- ('text2' in analysis and analysis['text2'])
 
 
579
 
580
- has_graphs = any(analysis.get(k) is not None for k in ['graph1', 'graph2', 'combined_graph'])
 
 
 
 
581
 
582
- # Si no hay suficiente información, mostrar mensaje adecuado
583
- if not (has_key_concepts or has_text or has_graphs):
584
- st.warning(t.get('insufficient_data', 'Datos insuficientes para mostrar un análisis completo'))
585
- # Mostrar datos disponibles en formato JSON para depuración (opcional)
586
- # NO usar expander aquí para evitar expanders anidados
587
- st.markdown("**Datos disponibles:**")
588
- st.json({k: v for k, v in analysis.items()
589
- if k not in ['_id', 'timestamp'] and v is not None})
590
- continue
591
 
592
- # Mostrar conceptos clave
593
- if has_key_concepts:
 
 
 
 
594
  col1, col2 = st.columns(2)
595
 
 
596
  with col1:
597
  st.markdown(f"**{t.get('concepts_text_1', 'Conceptos Texto 1')}**")
598
- if 'key_concepts1' in analysis and analysis['key_concepts1']:
599
- try:
600
- # Intentar diferentes formatos de conceptos clave
601
- if isinstance(analysis['key_concepts1'], list) and \
602
- len(analysis['key_concepts1']) > 0:
603
- # Verificar si es lista de listas (formato esperado)
604
- if isinstance(analysis['key_concepts1'][0], list) and \
605
- len(analysis['key_concepts1'][0]) == 2:
606
- df1 = pd.DataFrame(analysis['key_concepts1'],
607
- columns=['Concepto', 'Relevancia'])
608
- st.dataframe(df1, use_container_width=True)
609
- else:
610
- # Es una lista simple
611
- st.write(", ".join(str(c) for c in analysis['key_concepts1']))
612
- else:
613
- st.write(str(analysis['key_concepts1']))
614
- except Exception as e:
615
- logger.error(f"Error mostrando conceptos 1: {str(e)}")
616
- st.error(t.get('error_concepts1', 'Error mostrando conceptos del Texto 1'))
617
- else:
618
- st.info(t.get('no_concepts1', 'No hay conceptos disponibles para el Texto 1'))
619
 
 
620
  with col2:
621
  st.markdown(f"**{t.get('concepts_text_2', 'Conceptos Texto 2')}**")
622
- if 'key_concepts2' in analysis and analysis['key_concepts2']:
 
623
  try:
624
- # Intentar diferentes formatos de conceptos clave
625
- if isinstance(analysis['key_concepts2'], list) and \
626
- len(analysis['key_concepts2']) > 0:
627
- # Verificar si es lista de listas (formato esperado)
628
- if isinstance(analysis['key_concepts2'][0], list) and \
629
- len(analysis['key_concepts2'][0]) == 2:
630
- df2 = pd.DataFrame(analysis['key_concepts2'],
631
- columns=['Concepto', 'Relevancia'])
632
- st.dataframe(df2, use_container_width=True)
633
- else:
634
- # Es una lista simple
635
- st.write(", ".join(str(c) for c in analysis['key_concepts2']))
636
  else:
637
- st.write(str(analysis['key_concepts2']))
 
638
  except Exception as e:
639
  logger.error(f"Error mostrando conceptos 2: {str(e)}")
640
- st.error(t.get('error_concepts2', 'Error mostrando conceptos del Texto 2'))
641
  else:
642
- st.info(t.get('no_concepts2', 'No hay conceptos disponibles para el Texto 2'))
643
 
644
- # Mostrar gráficos si existen
645
- if has_graphs:
646
- st.markdown("---") # Separador
647
-
648
- # Intentar mostrar cada gráfico con manejo de excepciones específico para cada uno
649
- for graph_key, graph_title in [
650
- ('graph1', t.get('graph1_title', 'Visualización del Texto 1')),
651
- ('graph2', t.get('graph2_title', 'Visualización del Texto 2')),
652
- ('combined_graph', t.get('combined_graph_title', 'Visualización Comparativa'))
653
- ]:
654
- if graph_key in analysis and analysis[graph_key]:
655
- st.subheader(graph_title)
656
- try:
657
- image_data = analysis[graph_key]
658
-
659
- # Manejo según 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
- try:
664
- import base64
665
- # Intentar diferentes formatos de base64
666
- if image_data.startswith('data:image'):
667
- # Formato Data URI
668
- image_bytes = base64.b64decode(image_data.split(',')[1])
669
- else:
670
- # Base64 sin prefijo
671
- image_bytes = base64.b64decode(image_data)
672
-
673
- st.image(image_bytes, use_column_width=True)
674
- except Exception as decode_error:
675
- logger.error(f"Error decodificando {graph_key}: {str(decode_error)}")
676
- # Si no se puede decodificar, mostrar los primeros caracteres
677
- st.error(f"Error decodificando imagen. Primeros caracteres: {image_data[:50]}...")
678
- elif image_data is not None:
679
- # Intentar como figura matplotlib
680
- try:
681
- st.pyplot(image_data)
682
- except:
683
- st.error(f"Formato de gráfico no reconocido para {graph_key}")
684
- except Exception as e:
685
- logger.error(f"Error mostrando {graph_key}: {str(e)}")
686
- st.error(t.get(f'error_{graph_key}', f'Error mostrando {graph_title}'))
687
 
688
- # Si hay texto pero no hay visualizaciones, mostrar una nota
689
- if has_text and not has_graphs:
690
- st.markdown("---")
691
- st.info(t.get('no_visualizations', 'No hay visualizaciones disponibles para este análisis'))
692
 
693
- # Opcionalmente mostrar un botón para regenerar el análisis (si implementas esa funcionalidad)
694
- #if st.button(t.get('regenerate_analysis', 'Regenerar análisis'),
695
- # key=f"btn_regenerate_{analysis_id}"):
696
- # st.session_state.regenerate_analysis_id = analysis_id
697
- # st.rerun()
 
 
 
 
698
 
699
  except Exception as e:
700
  logger.error(f"Error procesando análisis individual: {str(e)}")
701
- st.error(f"Error en análisis: {str(e)}")
702
  continue
703
 
704
  except Exception as e:
705
- logger.error(f"Error mostrando análisis del discurso: {str(e)}")
706
  st.error(t.get('error_discourse', 'Error al mostrar análisis comparado de textos'))
707
-
708
- # Mostrar información de depuración para facilitar la solución de problemas
709
- # No usar expander aquí para evitar problemas con contextos
710
  st.markdown("**Detalles del error:**")
711
  st.exception(e)
712
 
713
-
714
  #################################################################################
715
  def display_chat_activities(username: str, t: dict):
716
  """
 
535
 
536
 
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_fixed(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")
 
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)}")
 
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):
710
  """