AIdeaText commited on
Commit
486e90d
·
verified ·
1 Parent(s): 4f94a7c

Update modules/studentact/student_activities_v2.py

Browse files
modules/studentact/student_activities_v2.py CHANGED
@@ -538,239 +538,111 @@ def display_semantic_activities(username: str, t: dict):
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
  """
543
  try:
544
  logger.info(f"Recuperando análisis del discurso para {username}")
545
-
546
- # Obtener análisis del discurso con el tipo correcto
547
- from ..database.discourse_mongo_db import get_student_discourse_analysis
548
  analyses = get_student_discourse_analysis(username)
549
 
550
  if not analyses:
551
  logger.info("No se encontraron análisis del discurso")
552
- # Usamos el término "análisis comparado de textos" en la UI
553
  st.info(t.get('no_discourse_analyses', 'No hay análisis comparados de textos registrados'))
554
  return
555
 
556
  logger.info(f"Procesando {len(analyses)} análisis del discurso")
557
  for analysis in analyses:
558
  try:
559
- # Verificar campos mínimos necesarios
560
- if 'timestamp' not in analysis:
561
- logger.warning(f"Análisis sin timestamp: {analysis.keys()}")
562
- continue
563
-
564
  # Formatear fecha
565
- try:
566
- timestamp = datetime.fromisoformat(analysis['timestamp'].replace('Z', '+00:00'))
567
- formatted_date = timestamp.strftime("%d/%m/%Y %H:%M:%S")
568
- except Exception as e:
569
- logger.error(f"Error al formatear timestamp: {str(e)}")
570
- formatted_date = str(analysis.get('timestamp', 'Fecha desconocida'))
571
 
572
- # Crear el título del expander
573
  expander_title = f"{t.get('analysis_date', 'Fecha')}: {formatted_date}"
574
 
575
  with st.expander(expander_title, expanded=False):
576
- # Crear pestañas para los textos y la comparación
577
- tabs = st.tabs([
578
- t.get('text1_tab', 'Texto 1 (Patrón)'),
579
- t.get('text2_tab', 'Texto 2 (Comparación)'),
580
- t.get('comparison_tab', 'Análisis Comparativo')
581
- ])
 
 
 
 
 
 
 
 
 
582
 
583
- # Tab para Texto 1
584
- with tabs[0]:
585
- if 'text1' in analysis and analysis['text1']:
586
- st.text_area(
587
- "Texto 1",
588
- value=analysis['text1'],
589
- height=150,
590
- disabled=True,
591
- label_visibility="collapsed",
592
- key=f"text1_{str(analysis['_id'])}"
593
- )
594
-
595
- # Mostrar conceptos clave del texto 1
596
- if 'key_concepts1' in analysis and analysis['key_concepts1']:
597
- st.subheader(t.get('key_concepts1', 'Conceptos clave (Texto 1)'))
598
-
599
- # Crear una tabla/dataframe de conceptos
600
- concept_data = analysis['key_concepts1']
601
- if concept_data and len(concept_data) > 0:
602
- # Verificar formato de los datos
603
- if isinstance(concept_data[0], list) and len(concept_data[0]) == 2:
604
- # Formato esperado: [["concepto", valor], ...]
605
- df = pd.DataFrame(concept_data, columns=['Concepto', 'Relevancia'])
606
- st.dataframe(df, use_container_width=True)
607
- else:
608
- st.write(concept_data) # Mostrar como está si no tiene el formato esperado
609
- else:
610
- st.info(t.get('no_concepts1', 'No hay conceptos clave disponibles para el Texto 1'))
611
-
612
- # Mostrar gráfico si existe
613
- if 'graph1' in analysis and analysis['graph1']:
614
- st.subheader(t.get('graph1', 'Visualización del Texto 1'))
615
- try:
616
- if isinstance(analysis['graph1'], str) and analysis['graph1'].startswith('data:image'):
617
- # Manejo para string base64
618
- import base64
619
- image_bytes = base64.b64decode(analysis['graph1'].split(',')[1])
620
- st.image(image_bytes, use_column_width=True)
621
- elif isinstance(analysis['graph1'], bytes):
622
- # Manejo para bytes directos
623
- st.image(analysis['graph1'], use_column_width=True)
624
- else:
625
- # Otro tipo de gráfico (matplotlib, etc.)
626
- st.pyplot(analysis['graph1'])
627
- except Exception as e:
628
- logger.error(f"Error mostrando gráfico 1: {str(e)}")
629
- st.error(t.get('error_graph1', 'Error al mostrar el gráfico del Texto 1'))
630
- else:
631
- st.info(t.get('no_text1', 'Texto 1 no disponible'))
632
 
633
- # Tab para Texto 2
634
- with tabs[1]:
635
- if 'text2' in analysis and analysis['text2']:
636
- st.text_area(
637
- "Texto 2",
638
- value=analysis['text2'],
639
- height=150,
640
- disabled=True,
641
- label_visibility="collapsed",
642
- key=f"text2_{str(analysis['_id'])}"
643
- )
644
-
645
- # Mostrar conceptos clave del texto 2
646
- if 'key_concepts2' in analysis and analysis['key_concepts2']:
647
- st.subheader(t.get('key_concepts2', 'Conceptos clave (Texto 2)'))
648
-
649
- # Crear una tabla/dataframe de conceptos
650
- concept_data = analysis['key_concepts2']
651
- if concept_data and len(concept_data) > 0:
652
- # Verificar formato de los datos
653
- if isinstance(concept_data[0], list) and len(concept_data[0]) == 2:
654
- # Formato esperado: [["concepto", valor], ...]
655
- df = pd.DataFrame(concept_data, columns=['Concepto', 'Relevancia'])
656
- st.dataframe(df, use_container_width=True)
657
- else:
658
- st.write(concept_data) # Mostrar como está si no tiene el formato esperado
659
- else:
660
- st.info(t.get('no_concepts2', 'No hay conceptos clave disponibles para el Texto 2'))
661
-
662
- # Mostrar gráfico si existe
663
- if 'graph2' in analysis and analysis['graph2']:
664
- st.subheader(t.get('graph2', 'Visualización del Texto 2'))
665
- try:
666
- if isinstance(analysis['graph2'], str) and analysis['graph2'].startswith('data:image'):
667
- # Manejo para string base64
668
- import base64
669
- image_bytes = base64.b64decode(analysis['graph2'].split(',')[1])
670
- st.image(image_bytes, use_column_width=True)
671
- elif isinstance(analysis['graph2'], bytes):
672
- # Manejo para bytes directos
673
- st.image(analysis['graph2'], use_column_width=True)
674
- else:
675
- # Otro tipo de gráfico (matplotlib, etc.)
676
- st.pyplot(analysis['graph2'])
677
- except Exception as e:
678
- logger.error(f"Error mostrando gráfico 2: {str(e)}")
679
- st.error(t.get('error_graph2', 'Error al mostrar el gráfico del Texto 2'))
680
- else:
681
- # Caso especial: si text2 está ausente pero text1 está presente
682
- # mostrar text1 aquí también (para documentos de un solo texto)
683
- if 'text1' in analysis and analysis['text1']:
684
- st.info(t.get('using_text1', 'Usando el mismo texto como referencia.'))
685
- st.text_area(
686
- "Texto 1 como referencia",
687
- value=analysis['text1'],
688
- height=150,
689
- disabled=True,
690
- label_visibility="collapsed",
691
- key=f"text1_ref_{str(analysis['_id'])}"
692
- )
693
- else:
694
- st.info(t.get('no_text2', 'Texto 2 no disponible'))
695
 
696
- # Tab para Comparación
697
- with tabs[2]:
698
- # Mostrar gráfico combinado si existe
699
- if 'combined_graph' in analysis and analysis['combined_graph']:
700
- st.subheader(t.get('combined_visualization', 'Visualización comparativa'))
701
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
702
  if isinstance(analysis['combined_graph'], str):
703
- # Si es string base64
704
- if analysis['combined_graph'].startswith('data:image'):
705
  import base64
706
- image_bytes = base64.b64decode(analysis['combined_graph'].split(',')[1])
707
- else:
708
- # Podría ser base64 sin prefijo
709
- try:
710
- import base64
711
  image_bytes = base64.b64decode(analysis['combined_graph'])
712
- except:
713
- st.text(analysis['combined_graph'][:100] + "...") # Mostrar parte como texto
714
- raise ValueError("Formato de gráfico combinado no reconocido")
715
-
716
- st.image(image_bytes, use_column_width=True)
717
  elif isinstance(analysis['combined_graph'], bytes):
718
- # Si son bytes directos
719
  st.image(analysis['combined_graph'], use_column_width=True)
720
- else:
721
- # Otro tipo de gráfico
722
  st.pyplot(analysis['combined_graph'])
723
  except Exception as e:
724
  logger.error(f"Error mostrando gráfico combinado: {str(e)}")
725
- st.error(t.get('error_combined_graph', 'Error al mostrar la visualización comparativa'))
726
- else:
727
- # Mostrar comparación de conceptos lado a lado
728
- if ('key_concepts1' in analysis and analysis['key_concepts1'] and
729
- 'key_concepts2' in analysis and analysis['key_concepts2']):
730
-
731
- st.subheader(t.get('concept_comparison', 'Comparación de conceptos clave'))
732
- col1, col2 = st.columns(2)
733
-
734
- with col1:
735
- st.markdown(f"**{t.get('text1_concepts', 'Conceptos del Texto 1')}**")
736
- concept_data1 = analysis['key_concepts1']
737
- if concept_data1 and len(concept_data1) > 0:
738
- if isinstance(concept_data1[0], list) and len(concept_data1[0]) == 2:
739
- df1 = pd.DataFrame(concept_data1, columns=['Concepto', 'Relevancia'])
740
- st.dataframe(df1, use_container_width=True)
741
- else:
742
- st.write(concept_data1)
743
-
744
- with col2:
745
- st.markdown(f"**{t.get('text2_concepts', 'Conceptos del Texto 2')}**")
746
- concept_data2 = analysis['key_concepts2']
747
- if concept_data2 and len(concept_data2) > 0:
748
- if isinstance(concept_data2[0], list) and len(concept_data2[0]) == 2:
749
- df2 = pd.DataFrame(concept_data2, columns=['Concepto', 'Relevancia'])
750
- st.dataframe(df2, use_container_width=True)
751
- else:
752
- st.write(concept_data2)
753
-
754
- # Mostrar conceptos en común (intersección)
755
- if (isinstance(analysis['key_concepts1'], list) and
756
- isinstance(analysis['key_concepts2'], list)):
757
-
758
- concepts1 = [item[0] for item in analysis['key_concepts1'] if isinstance(item, list) and len(item) == 2]
759
- concepts2 = [item[0] for item in analysis['key_concepts2'] if isinstance(item, list) and len(item) == 2]
760
-
761
- common_concepts = set(concepts1).intersection(set(concepts2))
762
-
763
- if common_concepts:
764
- st.subheader(t.get('common_concepts', 'Conceptos en común'))
765
- st.write(", ".join(common_concepts))
766
- else:
767
- st.info(t.get('no_common_concepts', 'No se encontraron conceptos en común entre los textos'))
768
- else:
769
- st.info(t.get('no_comparison_data', 'No hay datos suficientes para la comparación'))
770
-
771
- # Nota sobre la comparación
772
- st.info(t.get('comparison_note',
773
- 'La funcionalidad de comparación avanzada estará disponible en una próxima actualización.'))
774
 
775
  except Exception as e:
776
  logger.error(f"Error procesando análisis individual: {str(e)}")
@@ -778,9 +650,14 @@ def display_discourse_activities(username: str, t: dict):
778
 
779
  except Exception as e:
780
  logger.error(f"Error mostrando análisis del discurso: {str(e)}")
781
- # Usamos el término "análisis comparado de textos" en la UI
782
  st.error(t.get('error_discourse', 'Error al mostrar análisis comparado de textos'))
783
 
 
 
 
 
 
 
784
  #################################################################################
785
  def display_chat_activities(username: str, t: dict):
786
  """
 
538
 
539
  def display_discourse_activities(username: str, t: dict):
540
  """
541
+ Muestra actividades de análisis del discurso centradas en las visualizaciones comparativas
542
  """
543
  try:
544
  logger.info(f"Recuperando análisis del discurso para {username}")
 
 
 
545
  analyses = get_student_discourse_analysis(username)
546
 
547
  if not analyses:
548
  logger.info("No se encontraron análisis del discurso")
 
549
  st.info(t.get('no_discourse_analyses', 'No hay análisis comparados de textos registrados'))
550
  return
551
 
552
  logger.info(f"Procesando {len(analyses)} análisis del discurso")
553
  for analysis in analyses:
554
  try:
 
 
 
 
 
555
  # Formatear fecha
556
+ timestamp = datetime.fromisoformat(analysis['timestamp'].replace('Z', '+00:00'))
557
+ formatted_date = timestamp.strftime("%d/%m/%Y %H:%M:%S")
 
 
 
 
558
 
559
+ # Título del expander
560
  expander_title = f"{t.get('analysis_date', 'Fecha')}: {formatted_date}"
561
 
562
  with st.expander(expander_title, expanded=False):
563
+ # Mostrar conceptos clave en dos columnas
564
+ if 'key_concepts1' in analysis and 'key_concepts2' in analysis:
565
+ col1, col2 = st.columns(2)
566
+
567
+ with col1:
568
+ st.subheader(t.get('concepts_text_1', 'Conceptos Texto 1'))
569
+ if analysis['key_concepts1']:
570
+ df1 = pd.DataFrame(analysis['key_concepts1'], columns=['Concepto', 'Relevancia'])
571
+ st.dataframe(df1, use_container_width=True)
572
+
573
+ with col2:
574
+ st.subheader(t.get('concepts_text_2', 'Conceptos Texto 2'))
575
+ if analysis['key_concepts2']:
576
+ df2 = pd.DataFrame(analysis['key_concepts2'], columns=['Concepto', 'Relevancia'])
577
+ st.dataframe(df2, use_container_width=True)
578
 
579
+ # Mostrar visualizaciones semánticas
580
+ st.subheader(t.get('semantic_visualization', 'Visualización Semántica'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
581
 
582
+ # Mostrar gráficos en fila
583
+ graph_cols = st.columns(3)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
584
 
585
+ # Gráfico 1 (si existe)
586
+ with graph_cols[0]:
587
+ if analysis.get('graph1'):
 
 
588
  try:
589
+ st.caption(t.get('graph1_caption', 'Grafo Texto 1'))
590
+ if isinstance(analysis['graph1'], str) and analysis['graph1'].startswith('data:image'):
591
+ import base64
592
+ image_bytes = base64.b64decode(analysis['graph1'].split(',')[1])
593
+ st.image(image_bytes, use_column_width=True)
594
+ elif isinstance(analysis['graph1'], bytes):
595
+ st.image(analysis['graph1'], use_column_width=True)
596
+ elif analysis['graph1'] is not None:
597
+ st.pyplot(analysis['graph1'])
598
+ except Exception as e:
599
+ logger.error(f"Error mostrando gráfico 1: {str(e)}")
600
+ st.error(t.get('error_graph1', 'Error mostrando gráfico 1'))
601
+
602
+ # Gráfico 2 (si existe)
603
+ with graph_cols[1]:
604
+ if analysis.get('graph2'):
605
+ try:
606
+ st.caption(t.get('graph2_caption', 'Grafo Texto 2'))
607
+ if isinstance(analysis['graph2'], str) and analysis['graph2'].startswith('data:image'):
608
+ import base64
609
+ image_bytes = base64.b64decode(analysis['graph2'].split(',')[1])
610
+ st.image(image_bytes, use_column_width=True)
611
+ elif isinstance(analysis['graph2'], bytes):
612
+ st.image(analysis['graph2'], use_column_width=True)
613
+ elif analysis['graph2'] is not None:
614
+ st.pyplot(analysis['graph2'])
615
+ except Exception as e:
616
+ logger.error(f"Error mostrando gráfico 2: {str(e)}")
617
+ st.error(t.get('error_graph2', 'Error mostrando gráfico 2'))
618
+
619
+ # Gráfico combinado (si existe) - en la última columna
620
+ with graph_cols[2]:
621
+ if analysis.get('combined_graph'):
622
+ try:
623
+ st.caption(t.get('combined_graph_caption', 'Grafo Comparativo'))
624
  if isinstance(analysis['combined_graph'], str):
625
+ try:
 
626
  import base64
627
+ # Intentar diferentes formatos de base64
628
+ if analysis['combined_graph'].startswith('data:image'):
629
+ image_bytes = base64.b64decode(analysis['combined_graph'].split(',')[1])
630
+ else:
 
631
  image_bytes = base64.b64decode(analysis['combined_graph'])
632
+ st.image(image_bytes, use_column_width=True)
633
+ except:
634
+ logger.error("Error decodificando imagen combinada")
 
 
635
  elif isinstance(analysis['combined_graph'], bytes):
 
636
  st.image(analysis['combined_graph'], use_column_width=True)
637
+ elif analysis['combined_graph'] is not None:
 
638
  st.pyplot(analysis['combined_graph'])
639
  except Exception as e:
640
  logger.error(f"Error mostrando gráfico combinado: {str(e)}")
641
+ st.error(t.get('error_combined_graph', 'Error mostrando gráfico combinado'))
642
+
643
+ # Si no hay ningún gráfico disponible
644
+ if all(analysis.get(k) is None for k in ['graph1', 'graph2', 'combined_graph']):
645
+ st.info(t.get('no_visualizations', 'No hay visualizaciones disponibles para este análisis'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
646
 
647
  except Exception as e:
648
  logger.error(f"Error procesando análisis individual: {str(e)}")
 
650
 
651
  except Exception as e:
652
  logger.error(f"Error mostrando análisis del discurso: {str(e)}")
 
653
  st.error(t.get('error_discourse', 'Error al mostrar análisis comparado de textos'))
654
 
655
+
656
+
657
+
658
+
659
+
660
+
661
  #################################################################################
662
  def display_chat_activities(username: str, t: dict):
663
  """