AIdeaText commited on
Commit
4ed3e92
·
verified ·
1 Parent(s): 388fcf3

Update modules/studentact/student_activities_v2.py

Browse files
modules/studentact/student_activities_v2.py CHANGED
@@ -538,11 +538,8 @@ def display_semantic_activities(username: str, t: dict):
538
 
539
  def display_discourse_activities(username: str, t: dict):
540
  """
541
- Función mejorada para mostrar análisis de discurso que:
542
- 1. Evita expanders anidados
543
- 2. Usa keys únicos para todos los elementos
544
- 3. Muestra los conceptos clave en formato horizontal
545
- 4. Maneja correctamente la verificación de colección MongoDB
546
  """
547
  try:
548
  # Importar directamente la colección
@@ -567,6 +564,49 @@ def display_discourse_activities(username: str, t: dict):
567
  st.info(t.get('no_discourse_analyses', 'No hay análisis comparados de textos registrados'))
568
  return
569
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
570
  # Mostrar cada resultado
571
  for i, doc in enumerate(results):
572
  try:
@@ -587,118 +627,165 @@ def display_discourse_activities(username: str, t: dict):
587
  # Crear expander
588
  expander_label = f"{t.get('analysis_date', 'Fecha')}: {formatted_date}"
589
  with st.expander(expander_label, expanded=False):
590
- # Mostrar texto si existe
591
- if 'text1' in doc and doc['text1']:
592
- st.text_area(
593
- "Texto analizado",
594
- value=doc['text1'],
595
- height=100,
596
- disabled=True,
597
- key=f"text1_{doc_id}" # Key único para este text_area
598
- )
599
 
600
- # Mostrar conceptos clave en formato horizontal
601
- if 'key_concepts1' in doc and doc['key_concepts1']:
602
- st.subheader(t.get('key_concepts', 'Conceptos clave'))
 
603
 
604
- # Formatear conceptos del texto 1 - Formato horizontal
605
- st.markdown(f"**{t.get('concepts_text_1', 'Conceptos Texto 1')}:**")
606
- try:
607
- concepts = doc['key_concepts1']
608
- if isinstance(concepts, list):
609
- if len(concepts) > 0:
610
- # Revisar el formato
611
- if isinstance(concepts[0], list) and len(concepts[0]) == 2:
612
- # Formato esperado: [["concepto", valor], ...]
613
- # Mostrar en formato horizontal
614
- concept_text = ", ".join([f"{c[0]} ({c[1]})" for c in concepts[:10]])
615
- st.markdown(f"*{concept_text}*")
616
- else:
617
- # Otro formato de lista
618
- st.markdown(", ".join(str(c) for c in concepts[:10]))
619
- else:
620
- st.info("No hay conceptos disponibles")
621
- else:
622
- st.write(str(concepts))
623
- except Exception as e:
624
- logger.error(f"Error mostrando conceptos 1: {str(e)}")
625
- st.error("Error mostrando conceptos")
626
-
627
- # Conceptos del texto 2 (si existen)
628
- if 'key_concepts2' in doc and doc['key_concepts2']:
629
- st.markdown(f"**{t.get('concepts_text_2', 'Conceptos Texto 2')}:**")
630
- try:
631
- concepts = doc['key_concepts2']
632
- if isinstance(concepts, list):
633
- if len(concepts) > 0:
634
- # Revisar el formato
635
- if isinstance(concepts[0], list) and len(concepts[0]) == 2:
636
- # Formato esperado: [["concepto", valor], ...]
637
- # Mostrar en formato horizontal
638
- concept_text = ", ".join([f"{c[0]} ({c[1]})" for c in concepts[:10]])
639
- st.markdown(f"*{concept_text}*")
640
- else:
641
- # Otro formato de lista
642
- st.markdown(", ".join(str(c) for c in concepts[:10]))
 
 
 
 
 
 
 
 
 
 
 
643
  else:
644
- st.info("No hay conceptos disponibles")
645
- else:
646
- st.write(str(concepts))
647
- except Exception as e:
648
- logger.error(f"Error mostrando conceptos 2: {str(e)}")
649
- st.error("Error mostrando conceptos")
650
-
651
- # Mostrar visualizaciones si existen
652
- st.markdown("---")
653
- st.subheader(t.get('visualizations', 'Visualizaciones'))
654
-
655
- # Variable para verificar si se mostró alguna visualización
656
- shown_images = 0
657
 
658
- # Mostrar todas las visualizaciones posibles con keys únicos
659
- for field_name in ['graph1', 'graph2', 'combined_graph']:
660
- if field_name in doc and doc[field_name]:
 
 
 
661
  try:
662
- data = doc[field_name]
 
 
 
 
 
 
 
 
 
 
663
 
664
- # Determinar título según tipo de gráfico
665
- if field_name == 'graph1':
666
- caption = t.get('graph1_title', 'Visualización del Texto 1')
667
- elif field_name == 'graph2':
668
- caption = t.get('graph2_title', 'Visualización del Texto 2')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
669
  else:
670
- caption = t.get('combined_graph_title', 'Visualización Comparativa')
671
-
672
- # Si es bytes, mostrar directamente
673
- if isinstance(data, bytes):
674
- st.image(data, caption=caption, use_column_width=True)
675
- shown_images += 1
676
-
677
- # Si es string, intentar como base64
678
- elif isinstance(data, str):
 
 
 
 
 
 
 
 
 
 
679
  try:
680
- import base64
681
- image_bytes = base64.b64decode(data)
682
- st.image(image_bytes, caption=caption, use_column_width=True)
683
- shown_images += 1
 
684
  except:
685
- # Si falla la decodificación, solo registrarlo
686
- logger.error(f"No se pudo decodificar {field_name}")
687
- except Exception as img_err:
688
- logger.error(f"Error mostrando {field_name}: {str(img_err)}")
 
 
689
 
690
- # Mensaje si no hay visualizaciones
691
- if shown_images == 0:
692
- st.info(t.get('no_visualization', 'No hay visualizaciones disponibles para este análisis'))
693
-
694
- # NO usar expander anidado - simplemente mostrar datos importantes
695
- st.markdown("---")
696
- st.markdown("**Información adicional:**")
697
- if 'analysis_type' in doc:
698
- st.markdown(f"Tipo de análisis: {doc.get('analysis_type', 'Desconocido')}")
699
- if 'timestamp' in doc:
700
- st.markdown(f"Fecha: {doc.get('timestamp', 'Desconocida')}")
701
-
702
  except Exception as doc_err:
703
  logger.error(f"Error procesando documento: {str(doc_err)}")
704
  st.error(f"Error procesando análisis: {str(doc_err)}")
@@ -706,6 +793,8 @@ def display_discourse_activities(username: str, t: dict):
706
  except Exception as e:
707
  logger.error(f"Error general: {str(e)}")
708
  st.error(f"Error recuperando análisis: {str(e)}")
 
 
709
 
710
 
711
 
 
538
 
539
  def display_discourse_activities(username: str, t: dict):
540
  """
541
+ Muestra actividades de análisis del discurso con visualizaciones gráficas
542
+ en el mismo formato que la interfaz principal
 
 
 
543
  """
544
  try:
545
  # Importar directamente la colección
 
564
  st.info(t.get('no_discourse_analyses', 'No hay análisis comparados de textos registrados'))
565
  return
566
 
567
+ # Estilo CSS similar al de la interfaz principal
568
+ st.markdown("""
569
+ <style>
570
+ .concepts-container {
571
+ display: flex;
572
+ flex-wrap: nowrap;
573
+ gap: 8px;
574
+ padding: 12px;
575
+ background-color: #f8f9fa;
576
+ border-radius: 8px;
577
+ overflow-x: auto;
578
+ margin-bottom: 15px;
579
+ white-space: nowrap;
580
+ }
581
+ .concept-item {
582
+ background-color: white;
583
+ border-radius: 4px;
584
+ padding: 6px 10px;
585
+ display: inline-flex;
586
+ align-items: center;
587
+ gap: 4px;
588
+ box-shadow: 0 1px 2px rgba(0,0,0,0.1);
589
+ flex-shrink: 0;
590
+ }
591
+ .concept-name {
592
+ font-weight: 500;
593
+ color: #1f2937;
594
+ font-size: 0.85em;
595
+ }
596
+ .concept-freq {
597
+ color: #6b7280;
598
+ font-size: 0.75em;
599
+ }
600
+ .graph-container {
601
+ background-color: white;
602
+ padding: 15px;
603
+ border-radius: 8px;
604
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
605
+ margin-top: 10px;
606
+ }
607
+ </style>
608
+ """, unsafe_allow_html=True)
609
+
610
  # Mostrar cada resultado
611
  for i, doc in enumerate(results):
612
  try:
 
627
  # Crear expander
628
  expander_label = f"{t.get('analysis_date', 'Fecha')}: {formatted_date}"
629
  with st.expander(expander_label, expanded=False):
630
+ # Crear columnas como en la interfaz principal
631
+ col1, col2 = st.columns(2)
 
 
 
 
 
 
 
632
 
633
+ # Columna 1: Documento 1
634
+ with col1:
635
+ st.subheader(t.get('doc1_title', 'Documento 1'))
636
+ st.markdown(t.get('key_concepts', 'Conceptos Clave'))
637
 
638
+ if 'key_concepts1' in doc and doc['key_concepts1']:
639
+ try:
640
+ # Usar el mismo formato visual de conceptos que en la interfaz principal
641
+ concepts_html = f"""
642
+ <div class="concepts-container">
643
+ {''.join([
644
+ f'<div class="concept-item"><span class="concept-name">{concept}</span>'
645
+ f'<span class="concept-freq">({freq})</span></div>'
646
+ for concept, freq in doc['key_concepts1']
647
+ ])}
648
+ </div>
649
+ """
650
+ st.markdown(concepts_html, unsafe_allow_html=True)
651
+
652
+ # Mostrar gráfico si existe
653
+ if 'graph1' in doc and doc['graph1']:
654
+ try:
655
+ st.markdown('<div class="graph-container">', unsafe_allow_html=True)
656
+
657
+ # Manejar diferentes formatos de gráfico
658
+ if isinstance(doc['graph1'], bytes):
659
+ st.image(doc['graph1'], caption=t.get('graph1_caption', 'Grafo del Texto 1'), use_column_width=True)
660
+ elif isinstance(doc['graph1'], str):
661
+ try:
662
+ import base64
663
+ # Intentar diferentes formatos de base64
664
+ try:
665
+ if doc['graph1'].startswith('data:image'):
666
+ image_bytes = base64.b64decode(doc['graph1'].split(',')[1])
667
+ else:
668
+ image_bytes = base64.b64decode(doc['graph1'])
669
+ st.image(image_bytes, caption=t.get('graph1_caption', 'Grafo del Texto 1'), use_column_width=True)
670
+ except:
671
+ st.warning(t.get('graph_decode_error', 'Error al decodificar el gráfico'))
672
+ except:
673
+ st.warning(t.get('graph_format_error', 'Formato de gráfico no soportado'))
674
+
675
+ # Interpretación como texto normal
676
+ st.markdown("**📊 Interpretación del grafo:**")
677
+ st.markdown("""
678
+ - 🔀 Las flechas indican la dirección de la relación entre conceptos
679
+ - 🎨 Los colores más intensos indican conceptos más centrales en el texto
680
+ - ⭕ El tamaño de los nodos representa la frecuencia del concepto
681
+ - ↔️ El grosor de las líneas indica la fuerza de la conexión
682
+ """)
683
+
684
+ st.markdown('</div>', unsafe_allow_html=True)
685
+ except Exception as graph_err:
686
+ logger.error(f"Error mostrando gráfico 1: {str(graph_err)}")
687
+ st.warning(t.get('graph_not_available', 'Gráfico no disponible'))
688
  else:
689
+ st.warning(t.get('graph_not_available', 'Gráfico no disponible'))
690
+ except Exception as e:
691
+ logger.error(f"Error mostrando conceptos 1: {str(e)}")
692
+ st.error("Error mostrando conceptos")
693
+ else:
694
+ st.warning(t.get('concepts_not_available', 'Conceptos no disponibles'))
 
 
 
 
 
 
 
695
 
696
+ # Columna 2: Documento 2
697
+ with col2:
698
+ st.subheader(t.get('doc2_title', 'Documento 2'))
699
+ st.markdown(t.get('key_concepts', 'Conceptos Clave'))
700
+
701
+ if 'key_concepts2' in doc and doc['key_concepts2']:
702
  try:
703
+ # Usar el mismo formato visual de conceptos que en la interfaz principal
704
+ concepts_html = f"""
705
+ <div class="concepts-container">
706
+ {''.join([
707
+ f'<div class="concept-item"><span class="concept-name">{concept}</span>'
708
+ f'<span class="concept-freq">({freq})</span></div>'
709
+ for concept, freq in doc['key_concepts2']
710
+ ])}
711
+ </div>
712
+ """
713
+ st.markdown(concepts_html, unsafe_allow_html=True)
714
 
715
+ # Mostrar gráfico si existe
716
+ if 'graph2' in doc and doc['graph2']:
717
+ try:
718
+ st.markdown('<div class="graph-container">', unsafe_allow_html=True)
719
+
720
+ # Manejar diferentes formatos de gráfico
721
+ if isinstance(doc['graph2'], bytes):
722
+ st.image(doc['graph2'], caption=t.get('graph2_caption', 'Grafo del Texto 2'), use_column_width=True)
723
+ elif isinstance(doc['graph2'], str):
724
+ try:
725
+ import base64
726
+ # Intentar diferentes formatos de base64
727
+ try:
728
+ if doc['graph2'].startswith('data:image'):
729
+ image_bytes = base64.b64decode(doc['graph2'].split(',')[1])
730
+ else:
731
+ image_bytes = base64.b64decode(doc['graph2'])
732
+ st.image(image_bytes, caption=t.get('graph2_caption', 'Grafo del Texto 2'), use_column_width=True)
733
+ except:
734
+ st.warning(t.get('graph_decode_error', 'Error al decodificar el gráfico'))
735
+ except:
736
+ st.warning(t.get('graph_format_error', 'Formato de gráfico no soportado'))
737
+
738
+ # Interpretación como texto normal
739
+ st.markdown("**📊 Interpretación del grafo:**")
740
+ st.markdown("""
741
+ - 🔀 Las flechas indican la dirección de la relación entre conceptos
742
+ - 🎨 Los colores más intensos indican conceptos más centrales en el texto
743
+ - ⭕ El tamaño de los nodos representa la frecuencia del concepto
744
+ - ↔️ El grosor de las líneas indica la fuerza de la conexión
745
+ """)
746
+
747
+ st.markdown('</div>', unsafe_allow_html=True)
748
+ except Exception as graph_err:
749
+ logger.error(f"Error mostrando gráfico 2: {str(graph_err)}")
750
+ st.warning(t.get('graph_not_available', 'Gráfico no disponible'))
751
  else:
752
+ st.warning(t.get('graph_not_available', 'Gráfico no disponible'))
753
+ except Exception as e:
754
+ logger.error(f"Error mostrando conceptos 2: {str(e)}")
755
+ st.error("Error mostrando conceptos")
756
+ else:
757
+ st.warning(t.get('concepts_not_available', 'Conceptos no disponibles'))
758
+
759
+ # Gráfico combinado (abajo de las columnas)
760
+ if 'combined_graph' in doc and doc['combined_graph']:
761
+ try:
762
+ st.subheader(t.get('combined_graph_title', 'Análisis Comparativo'))
763
+
764
+ # Manejar diferentes formatos de gráfico
765
+ if isinstance(doc['combined_graph'], bytes):
766
+ st.image(doc['combined_graph'], caption=t.get('combined_graph_caption', 'Visualización Comparativa'), use_column_width=True)
767
+ elif isinstance(doc['combined_graph'], str):
768
+ try:
769
+ import base64
770
+ # Intentar diferentes formatos de base64
771
  try:
772
+ if doc['combined_graph'].startswith('data:image'):
773
+ image_bytes = base64.b64decode(doc['combined_graph'].split(',')[1])
774
+ else:
775
+ image_bytes = base64.b64decode(doc['combined_graph'])
776
+ st.image(image_bytes, caption=t.get('combined_graph_caption', 'Visualización Comparativa'), use_column_width=True)
777
  except:
778
+ st.warning(t.get('graph_decode_error', 'Error al decodificar el gráfico'))
779
+ except:
780
+ st.warning(t.get('graph_format_error', 'Formato de gráfico no soportado'))
781
+ except Exception as graph_err:
782
+ logger.error(f"Error mostrando gráfico combinado: {str(graph_err)}")
783
+ st.warning(t.get('combined_graph_not_available', 'Gráfico combinado no disponible'))
784
 
785
+ # Nota informativa sobre la comparación
786
+ st.info(t.get('comparison_note',
787
+ 'La funcionalidad de comparación detallada estará disponible en una próxima actualización.'))
788
+
 
 
 
 
 
 
 
 
789
  except Exception as doc_err:
790
  logger.error(f"Error procesando documento: {str(doc_err)}")
791
  st.error(f"Error procesando análisis: {str(doc_err)}")
 
793
  except Exception as e:
794
  logger.error(f"Error general: {str(e)}")
795
  st.error(f"Error recuperando análisis: {str(e)}")
796
+ # Mostrar el error para depuración
797
+ st.exception(e)
798
 
799
 
800