AIdeaText commited on
Commit
54c403e
·
verified ·
1 Parent(s): acb2968

Update modules/studentact/student_activities_v2.py

Browse files
modules/studentact/student_activities_v2.py CHANGED
@@ -536,113 +536,178 @@ def display_semantic_activities(username: str, t: dict):
536
 
537
  ###################################################################################################
538
 
539
- def display_discourse_comparison(analysis: dict, t: dict):
 
540
  """
541
- Muestra la comparación de análisis del discurso de manera minimalista pero efectiva.
542
- Incluye tanto las tablas de conceptos como los gráficos disponibles.
543
  """
544
- st.subheader(t.get('comparison_results', 'Resultados de la comparación'))
545
-
546
- # 1. Mostrar conceptos en columnas
547
- col1, col2 = st.columns(2)
548
- with col1:
549
- st.markdown(f"**{t.get('concepts_text_1', 'Conceptos Texto 1')}**")
550
- if 'key_concepts1' in analysis and analysis['key_concepts1']:
551
- try:
552
- df1 = pd.DataFrame(analysis['key_concepts1'],
553
- columns=['Concepto', 'Relevancia'])
554
- st.dataframe(df1)
555
- except Exception as e:
556
- # En caso de error, mostrar los datos sin procesar
557
- st.write(analysis['key_concepts1'])
558
- else:
559
- st.info(t.get('no_concepts1', 'No hay conceptos disponibles'))
560
-
561
- with col2:
562
- st.markdown(f"**{t.get('concepts_text_2', 'Conceptos Texto 2')}**")
563
- if 'key_concepts2' in analysis and analysis['key_concepts2']:
564
  try:
565
- df2 = pd.DataFrame(analysis['key_concepts2'],
566
- columns=['Concepto', 'Relevancia'])
567
- st.dataframe(df2)
568
- except Exception as e:
569
- # En caso de error, mostrar los datos sin procesar
570
- st.write(analysis['key_concepts2'])
571
- else:
572
- st.info(t.get('no_concepts2', 'No hay conceptos disponibles'))
573
-
574
- # 2. Mostrar los gráficos si están disponibles
575
- st.markdown("---") # Separador
576
-
577
- # Verificar y mostrar gráficos
578
- has_graphs = False
579
-
580
- # Gráfico 1
581
- if 'graph1' in analysis and analysis['graph1']:
582
- has_graphs = True
583
- st.markdown(f"### {t.get('graph1_title', 'Gráfico Texto 1')}")
584
- try:
585
- # Intentar mostrar gráfico (asumiendo que es bytes o base64)
586
- if isinstance(analysis['graph1'], bytes):
587
- st.image(analysis['graph1'], use_column_width=True)
588
- elif isinstance(analysis['graph1'], str):
589
- import base64
590
- try:
591
- image_bytes = base64.b64decode(analysis['graph1'])
592
- st.image(image_bytes, use_column_width=True)
593
- except:
594
- st.error(t.get('error_decoding', 'Error decodificando imagen'))
595
- else:
596
- # Intentar como objeto matplotlib
597
- st.pyplot(analysis['graph1'])
598
- except Exception as e:
599
- st.error(t.get('error_graph1', 'Error mostrando gráfico 1'))
600
-
601
- # Gráfico 2
602
- if 'graph2' in analysis and analysis['graph2']:
603
- has_graphs = True
604
- st.markdown(f"### {t.get('graph2_title', 'Gráfico Texto 2')}")
605
- try:
606
- # Intentar mostrar gráfico (asumiendo que es bytes o base64)
607
- if isinstance(analysis['graph2'], bytes):
608
- st.image(analysis['graph2'], use_column_width=True)
609
- elif isinstance(analysis['graph2'], str):
610
- import base64
611
- try:
612
- image_bytes = base64.b64decode(analysis['graph2'])
613
- st.image(image_bytes, use_column_width=True)
614
- except:
615
- st.error(t.get('error_decoding', 'Error decodificando imagen'))
616
- else:
617
- # Intentar como objeto matplotlib
618
- st.pyplot(analysis['graph2'])
619
- except Exception as e:
620
- st.error(t.get('error_graph2', 'Error mostrando gráfico 2'))
621
-
622
- # Gráfico combinado
623
- if 'combined_graph' in analysis and analysis['combined_graph']:
624
- has_graphs = True
625
- st.markdown(f"### {t.get('combined_graph_title', 'Gráfico Comparativo')}")
626
- try:
627
- # Intentar mostrar gráfico (asumiendo que es bytes o base64)
628
- if isinstance(analysis['combined_graph'], bytes):
629
- st.image(analysis['combined_graph'], use_column_width=True)
630
- elif isinstance(analysis['combined_graph'], str):
631
- import base64
632
  try:
633
- image_bytes = base64.b64decode(analysis['combined_graph'])
634
- st.image(image_bytes, use_column_width=True)
635
- except:
636
- st.error(t.get('error_decoding', 'Error decodificando imagen'))
637
- else:
638
- # Intentar como objeto matplotlib
639
- st.pyplot(analysis['combined_graph'])
640
- except Exception as e:
641
- st.error(t.get('error_combined_graph', 'Error mostrando gráfico comparativo'))
642
-
643
- # Mensaje si no hay gráficos
644
- if not has_graphs:
645
- st.info(t.get('no_graphs_available', 'No hay visualizaciones disponibles para este análisis.'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
646
 
647
 
648
  #################################################################################
@@ -696,18 +761,3 @@ def display_chat_activities(username: str, t: dict):
696
  st.error(t.get('error_chat', 'Error al mostrar historial del chat'))
697
 
698
  #################################################################################
699
- def display_discourse_comparison(analysis: dict, t: dict):
700
- """Muestra la comparación de análisis del discurso"""
701
- # Cambiado para usar "textos comparados" en la UI
702
- st.subheader(t.get('comparison_results', 'Resultados de la comparación'))
703
-
704
- col1, col2 = st.columns(2)
705
- with col1:
706
- st.markdown(f"**{t.get('concepts_text_1', 'Conceptos Texto 1')}**")
707
- df1 = pd.DataFrame(analysis['key_concepts1'])
708
- st.dataframe(df1)
709
-
710
- with col2:
711
- st.markdown(f"**{t.get('concepts_text_2', 'Conceptos Texto 2')}**")
712
- df2 = pd.DataFrame(analysis['key_concepts2'])
713
- st.dataframe(df2)
 
536
 
537
  ###################################################################################################
538
 
539
+ # Esta función debería reemplazar o complementar la actual display_discourse_activities
540
+ def display_discourse_activities(username: str, t: dict):
541
  """
542
+ Muestra actividades de análisis del discurso (mostrado como 'Análisis comparado de textos' en la UI)
543
+ con mejor manejo de errores y datos incompletos
544
  """
545
+ try:
546
+ logger.info(f"Recuperando análisis del discurso para {username}")
547
+ analyses = get_student_discourse_analysis(username)
548
+
549
+ if not analyses:
550
+ logger.info("No se encontraron análisis del discurso")
551
+ st.info(t.get('no_discourse_analyses', 'No hay análisis comparados de textos registrados'))
552
+ return
553
+
554
+ logger.info(f"Procesando {len(analyses)} análisis del discurso")
555
+
556
+ for i, analysis in enumerate(analyses):
 
 
 
 
 
 
 
 
557
  try:
558
+ # Usar un ID único para este análisis (usando índice si _id no está disponible)
559
+ analysis_id = str(analysis.get('_id', f"analysis_{i}"))
560
+
561
+ # Formatear fecha con manejo de errores
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
562
  try:
563
+ timestamp = datetime.fromisoformat(analysis['timestamp'].replace('Z', '+00:00'))
564
+ formatted_date = timestamp.strftime("%d/%m/%Y %H:%M:%S")
565
+ except (KeyError, ValueError, TypeError) as e:
566
+ logger.warning(f"Error formateando fecha: {str(e)}")
567
+ formatted_date = str(analysis.get('timestamp', 'Fecha desconocida'))
568
+
569
+ # Crear título del expander
570
+ expander_title = f"{t.get('analysis_date', 'Fecha')}: {formatted_date}"
571
+
572
+ # Crear expander
573
+ with st.expander(expander_title, expanded=False):
574
+ # Determinar si tenemos datos suficientes para mostrar un análisis útil
575
+ has_key_concepts = ('key_concepts1' in analysis and analysis['key_concepts1']) or \
576
+ ('key_concepts2' in analysis and analysis['key_concepts2'])
577
+
578
+ has_text = ('text1' in analysis and analysis['text1']) or \
579
+ ('text2' in analysis and analysis['text2'])
580
+
581
+ has_graphs = any(analysis.get(k) is not None for k in ['graph1', 'graph2', 'combined_graph'])
582
+
583
+ # Si no hay suficiente información, mostrar mensaje adecuado
584
+ if not (has_key_concepts or has_text or has_graphs):
585
+ st.warning(t.get('insufficient_data', 'Datos insuficientes para mostrar un análisis completo'))
586
+ # Mostrar datos disponibles en formato JSON para depuración (opcional)
587
+ with st.expander("Ver datos disponibles", expanded=False):
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
+ with st.expander("Detalles del error", expanded=False):
710
+ st.exception(e)
711
 
712
 
713
  #################################################################################
 
761
  st.error(t.get('error_chat', 'Error al mostrar historial del chat'))
762
 
763
  #################################################################################