AIdeaText commited on
Commit
9616a51
verified
1 Parent(s): 21a58f8

Update modules/morphosyntax/morphosyntax_interface.py

Browse files
modules/morphosyntax/morphosyntax_interface.py CHANGED
@@ -1,6 +1,5 @@
1
- #modules/morphosyntax/morphosyntax_interface.py
2
 
3
- #Importaciones generales
4
  import streamlit as st
5
  from streamlit_float import *
6
  from streamlit_antd_components import *
@@ -12,7 +11,7 @@ import pandas as pd
12
  import base64
13
  import re
14
 
15
- #Importaciones locales
16
  from .morphosyntax_process import (
17
  process_morphosyntactic_input,
18
  format_analysis_results,
@@ -22,11 +21,8 @@ from .morphosyntax_process import (
22
  POS_COLORS,
23
  POS_TRANSLATIONS
24
  )
25
-
26
  from ..utils.widget_utils import generate_unique_key
27
 
28
- # from ..database.morphosintax_mongo_db import store_student_morphosyntax_result
29
-
30
  from ..database.morphosyntax_iterative_mongo_db import (
31
  store_student_morphosyntax_base,
32
  store_student_morphosyntax_iteration,
@@ -41,14 +37,14 @@ logger = logging.getLogger(__name__)
41
 
42
  ###########################################################################
43
  def initialize_arc_analysis_state():
44
- """Inicializa el estado del an谩lisis de arcos y el cach茅 si no existen"""
45
- # Inicializar estado de an谩lisis
46
  if 'arc_analysis_state' not in st.session_state:
47
  st.session_state.arc_analysis_state = {
48
- 'original_text': '',
49
- 'original_analysis': None,
50
- 'iteration_text': '',
51
- 'iteration_analysis': None,
 
52
  'analysis_count': 0
53
  }
54
  logger.info("Estado de an谩lisis de arcos inicializado")
@@ -58,75 +54,89 @@ def initialize_arc_analysis_state():
58
  st.session_state.analysis_cache = {}
59
  logger.info("Cach茅 de an谩lisis inicializado")
60
 
61
- ###########################################################################
62
 
63
  def reset_morpho_state():
64
- """Resetea el estado del an谩lisis morfosint谩ctico"""
65
  if 'arc_analysis_state' in st.session_state:
66
  st.session_state.arc_analysis_state = {
 
67
  'original_text': '',
68
  'original_analysis': None,
69
  'iteration_text': '',
70
  'iteration_analysis': None,
71
  'analysis_count': 0
72
  }
73
- ############################################################################
74
 
75
  def display_original_analysis(container, analysis, lang_code, morpho_t):
76
- """Muestra el an谩lisis original en el contenedor especificado"""
77
  with container:
78
  st.subheader("An谩lisis Original")
79
  display_morphosyntax_results(analysis, lang_code, morpho_t)
80
 
 
81
  def display_iteration_analysis(container, analysis, lang_code, morpho_t):
82
- """Muestra el an谩lisis de cambios en el contenedor especificado"""
83
  with container:
84
  st.subheader("An谩lisis de Cambios")
85
  display_morphosyntax_results(analysis, lang_code, morpho_t)
86
 
 
87
  def display_arc_diagram(doc, analysis):
88
- """Muestra un diagrama de arco sin t铆tulo"""
89
  try:
90
  for sent in doc.sents:
91
- html = displacy.render(sent, style="dep", options={
92
- "distance": 100,
93
- "arrow_spacing": 20,
94
- "word_spacing": 30
95
- })
96
-
 
 
 
97
  # Ajustar tama帽o y posici贸n
98
- html = html.replace('height="375"', 'height="200"')
99
- html = re.sub(r'<svg[^>]*>', lambda m: m.group(0).replace('height="450"', 'height="300"'), html)
100
- html = re.sub(r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
101
- lambda m: f'<g transform="translate({m.group(1)},50)"', html)
 
 
 
 
 
 
 
102
 
103
  # Envolver en contenedor con estilo
104
- html = f'<div class="arc-diagram-container">{html}</div>'
105
-
106
- st.write(html, unsafe_allow_html=True)
107
 
108
  except Exception as e:
109
  logger.error(f"Error en display_arc_diagram: {str(e)}")
110
 
111
- ############################################################################
112
 
113
  def cache_analysis_results(key, result):
114
- """Almacena resultados de an谩lisis en cach茅"""
115
  if not hasattr(st.session_state, 'analysis_cache'):
116
  initialize_arc_analysis_state()
117
  st.session_state.analysis_cache[key] = result
118
  logger.info(f"Resultado almacenado en cach茅 con clave: {key}")
119
 
 
120
  def get_cached_analysis(key):
121
- """Recupera resultados de an谩lisis del cach茅"""
122
  if not hasattr(st.session_state, 'analysis_cache'):
123
  initialize_arc_analysis_state()
124
  return None
125
  return st.session_state.analysis_cache.get(key)
126
 
127
 
128
- ############################################################################
129
  def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
 
 
 
 
130
  try:
131
  # CSS para layout estable
132
  st.markdown("""
@@ -151,12 +161,15 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
151
  </style>
152
  """, unsafe_allow_html=True)
153
 
154
- # Inicializar estados
155
- initialize_arc_analysis_state() # A帽adir esta l铆nea
156
 
157
- # Asegurar que el tab morfosint谩ctico permanece activo
158
- st.session_state.tab_states['morpho_active'] = True
159
- st.session_state.selected_tab = 1
 
 
 
160
 
161
  # Crear subtabs
162
  subtabs = st.tabs([
@@ -165,34 +178,30 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
165
  "An谩lisis Morfol贸gico"
166
  ])
167
 
168
- # Tab de Diagramas de Arco
169
  with subtabs[0]:
170
  # Bot贸n de reset
171
- col1, col2, col3 = st.columns([2,1,2])
172
  with col1:
173
  if st.button("Nuevo An谩lisis", type="secondary", use_container_width=True):
174
- st.session_state.arc_analysis_state = {
175
- 'base_id': None,
176
- 'original_text': '',
177
- 'iteration_text': '',
178
- 'analysis_count': 0
179
- }
180
  st.rerun()
181
 
182
- # Container principal para an谩lisis
183
  analysis_container = st.container()
184
-
185
  with analysis_container:
186
  # Entrada de texto original
 
187
  text_input = st.text_area(
188
- "",
189
  value=st.session_state.arc_analysis_state.get('original_text', ''),
190
- key=f"original_text_{st.session_state.arc_analysis_state['analysis_count']}",
191
  height=100
192
  )
193
 
194
  # Bot贸n de an谩lisis
195
- col1, col2, col3 = st.columns([2,1,2])
196
  with col1:
197
  analyze_button = st.button(
198
  "Analizar Texto",
@@ -203,14 +212,14 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
203
  # Procesar texto original
204
  if analyze_button and text_input.strip():
205
  try:
206
- # Realizar an谩lisis base
207
  doc = nlp_models[lang_code](text_input)
208
  analysis = perform_advanced_morphosyntactic_analysis(
209
  text_input,
210
  nlp_models[lang_code]
211
  )
212
 
213
- # Guardar an谩lisis base y obtener ID
214
  base_id = store_student_morphosyntax_base(
215
  st.session_state.username,
216
  text_input,
@@ -218,10 +227,11 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
218
  )
219
 
220
  if base_id:
221
- # Actualizar estado
222
  st.session_state.arc_analysis_state.update({
223
  'base_id': base_id,
224
  'original_text': text_input,
 
225
  'analysis_count': st.session_state.arc_analysis_state['analysis_count'] + 1
226
  })
227
 
@@ -231,14 +241,20 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
231
  # L铆nea divisora
232
  st.markdown('<hr class="divider">', unsafe_allow_html=True)
233
 
234
- # 脕rea de iteraci贸n
235
  with st.form("iteration_form"):
 
 
 
 
236
  iteration_text = st.text_area(
237
- "",
238
- value=text_input,
 
239
  height=100
240
  )
241
 
 
242
  col1, col2, col3 = st.columns([2,1,2])
243
  with col1:
244
  submitted = st.form_submit_button(
@@ -249,42 +265,51 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
249
 
250
  # Procesar iteraci贸n
251
  if submitted and iteration_text.strip():
252
- doc_iter = nlp_models[lang_code](iteration_text)
253
- analysis_iter = perform_advanced_morphosyntactic_analysis(
254
- iteration_text,
255
- nlp_models[lang_code]
256
- )
 
257
 
258
- # Guardar iteraci贸n
259
- iteration_id = store_student_morphosyntax_iteration(
260
- st.session_state.username,
261
- base_id,
262
- text_input,
263
- iteration_text,
264
- analysis_iter['arc_diagrams']
265
- )
266
 
267
- if iteration_id:
268
- # Mostrar diagrama de iteraci贸n
269
- display_arc_diagram(doc_iter, analysis_iter)
 
 
 
 
 
 
 
 
 
270
 
271
  except Exception as e:
272
- st.error("Error procesando an谩lisis")
273
- logger.error(f"Error: {str(e)}")
274
 
275
- # Otros subtabs mantienen su implementaci贸n actual...
276
  with subtabs[1]:
277
  st.info("An谩lisis de Categor铆as en desarrollo...")
278
-
 
279
  with subtabs[2]:
280
  st.info("An谩lisis Morfol贸gico en desarrollo...")
281
 
282
  except Exception as e:
283
- st.error("Error en la interfaz")
284
  logger.error(f"Error general en la interfaz: {str(e)}")
285
 
286
- ############################################################################
287
-
288
 
289
  def display_morphosyntax_results(result, lang_code, morpho_t):
290
  """
@@ -292,31 +317,40 @@ def display_morphosyntax_results(result, lang_code, morpho_t):
292
  Args:
293
  result: Diccionario con el documento procesado y su an谩lisis
294
  lang_code: C贸digo del idioma
295
- morpho_t: Diccionario de traducciones
296
  """
297
  if result is None:
298
  return
299
-
300
  try:
301
  doc = result['doc']
302
  sentences = list(doc.sents)
303
  for i, sent in enumerate(sentences):
304
  try:
305
  st.subheader(f"{morpho_t.get('sentence', 'Sentence')} {i+1}")
306
- html = displacy.render(sent, style="dep", options={
307
- "distance": 100,
308
- "arrow_spacing": 20,
309
- "word_spacing": 30
310
- })
311
- html = html.replace('height="375"', 'height="200"')
312
- html = re.sub(r'<svg[^>]*>', lambda m: m.group(0).replace('height="450"', 'height="300"'), html)
313
- html = re.sub(r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
314
- lambda m: f'<g transform="translate({m.group(1)},50)"', html)
315
- html = f'<div class="arc-diagram-container">{html}</div>'
316
- st.write(html, unsafe_allow_html=True)
317
- except Exception as e:
318
- logger.error(f"Error en diagrama {i}: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
319
  continue
320
  except Exception as e:
321
  logger.error(f"Error en display_morphosyntax_results: {str(e)}")
322
-
 
1
+ # modules/morphosyntax/morphosyntax_interface.py
2
 
 
3
  import streamlit as st
4
  from streamlit_float import *
5
  from streamlit_antd_components import *
 
11
  import base64
12
  import re
13
 
14
+ # Importaciones locales
15
  from .morphosyntax_process import (
16
  process_morphosyntactic_input,
17
  format_analysis_results,
 
21
  POS_COLORS,
22
  POS_TRANSLATIONS
23
  )
 
24
  from ..utils.widget_utils import generate_unique_key
25
 
 
 
26
  from ..database.morphosyntax_iterative_mongo_db import (
27
  store_student_morphosyntax_base,
28
  store_student_morphosyntax_iteration,
 
37
 
38
  ###########################################################################
39
  def initialize_arc_analysis_state():
40
+ """Inicializa el estado del an谩lisis de arcos y el cach茅 si no existen."""
 
41
  if 'arc_analysis_state' not in st.session_state:
42
  st.session_state.arc_analysis_state = {
43
+ 'base_id': None, # ID del an谩lisis base
44
+ 'original_text': '', # Texto original
45
+ 'original_analysis': None, # Resultado an谩lisis original
46
+ 'iteration_text': '', # Texto de iteraci贸n
47
+ 'iteration_analysis': None,# Resultado an谩lisis iteraci贸n
48
  'analysis_count': 0
49
  }
50
  logger.info("Estado de an谩lisis de arcos inicializado")
 
54
  st.session_state.analysis_cache = {}
55
  logger.info("Cach茅 de an谩lisis inicializado")
56
 
 
57
 
58
  def reset_morpho_state():
59
+ """Resetea el estado del an谩lisis morfosint谩ctico en sesi贸n."""
60
  if 'arc_analysis_state' in st.session_state:
61
  st.session_state.arc_analysis_state = {
62
+ 'base_id': None,
63
  'original_text': '',
64
  'original_analysis': None,
65
  'iteration_text': '',
66
  'iteration_analysis': None,
67
  'analysis_count': 0
68
  }
69
+
70
 
71
  def display_original_analysis(container, analysis, lang_code, morpho_t):
72
+ """Muestra el an谩lisis original en el contenedor especificado."""
73
  with container:
74
  st.subheader("An谩lisis Original")
75
  display_morphosyntax_results(analysis, lang_code, morpho_t)
76
 
77
+
78
  def display_iteration_analysis(container, analysis, lang_code, morpho_t):
79
+ """Muestra el an谩lisis de cambios en el contenedor especificado."""
80
  with container:
81
  st.subheader("An谩lisis de Cambios")
82
  display_morphosyntax_results(analysis, lang_code, morpho_t)
83
 
84
+
85
  def display_arc_diagram(doc, analysis):
86
+ """Muestra un diagrama de arco sin t铆tulo."""
87
  try:
88
  for sent in doc.sents:
89
+ svg_html = displacy.render(
90
+ sent,
91
+ style="dep",
92
+ options={
93
+ "distance": 100,
94
+ "arrow_spacing": 20,
95
+ "word_spacing": 30
96
+ }
97
+ )
98
  # Ajustar tama帽o y posici贸n
99
+ svg_html = svg_html.replace('height="375"', 'height="200"')
100
+ svg_html = re.sub(
101
+ r'<svg[^>]*>',
102
+ lambda m: m.group(0).replace('height="450"', 'height="300"'),
103
+ svg_html
104
+ )
105
+ svg_html = re.sub(
106
+ r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
107
+ lambda m: f'<g transform="translate({m.group(1)},50)"',
108
+ svg_html
109
+ )
110
 
111
  # Envolver en contenedor con estilo
112
+ svg_html = f'<div class="arc-diagram-container">{svg_html}</div>'
113
+ st.write(svg_html, unsafe_allow_html=True)
 
114
 
115
  except Exception as e:
116
  logger.error(f"Error en display_arc_diagram: {str(e)}")
117
 
 
118
 
119
  def cache_analysis_results(key, result):
120
+ """Almacena resultados de an谩lisis en cach茅."""
121
  if not hasattr(st.session_state, 'analysis_cache'):
122
  initialize_arc_analysis_state()
123
  st.session_state.analysis_cache[key] = result
124
  logger.info(f"Resultado almacenado en cach茅 con clave: {key}")
125
 
126
+
127
  def get_cached_analysis(key):
128
+ """Recupera resultados de an谩lisis del cach茅."""
129
  if not hasattr(st.session_state, 'analysis_cache'):
130
  initialize_arc_analysis_state()
131
  return None
132
  return st.session_state.analysis_cache.get(key)
133
 
134
 
 
135
  def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
136
+ """
137
+ Interfaz principal para el an谩lisis morfosint谩ctico.
138
+ Evita resets indebidos y conserva la pesta帽a activa.
139
+ """
140
  try:
141
  # CSS para layout estable
142
  st.markdown("""
 
161
  </style>
162
  """, unsafe_allow_html=True)
163
 
164
+ # Inicializar estados de an谩lisis si no existen
165
+ initialize_arc_analysis_state()
166
 
167
+ # ------------------------------------------------------------------
168
+ # Si tuvieras un control de tabs global, puedes comentarlo:
169
+ #
170
+ # st.session_state.tab_states['morpho_active'] = True
171
+ # st.session_state.selected_tab = 1
172
+ # ------------------------------------------------------------------
173
 
174
  # Crear subtabs
175
  subtabs = st.tabs([
 
178
  "An谩lisis Morfol贸gico"
179
  ])
180
 
181
+ # -------------------- Subtab 0: Diagramas de Arco --------------------
182
  with subtabs[0]:
183
  # Bot贸n de reset
184
+ col1, col2, col3 = st.columns([2, 1, 2])
185
  with col1:
186
  if st.button("Nuevo An谩lisis", type="secondary", use_container_width=True):
187
+ reset_morpho_state()
188
+ # Forzar el rec谩lculo limpio
 
 
 
 
189
  st.rerun()
190
 
191
+ # Container principal para an谩lisis base
192
  analysis_container = st.container()
 
193
  with analysis_container:
194
  # Entrada de texto original
195
+ text_input_key = f"original_text_{st.session_state.arc_analysis_state['analysis_count']}"
196
  text_input = st.text_area(
197
+ "Texto original",
198
  value=st.session_state.arc_analysis_state.get('original_text', ''),
199
+ key=text_input_key,
200
  height=100
201
  )
202
 
203
  # Bot贸n de an谩lisis
204
+ col1, col2, col3 = st.columns([2, 1, 2])
205
  with col1:
206
  analyze_button = st.button(
207
  "Analizar Texto",
 
212
  # Procesar texto original
213
  if analyze_button and text_input.strip():
214
  try:
215
+ # Realizar an谩lisis base (SpaCy)
216
  doc = nlp_models[lang_code](text_input)
217
  analysis = perform_advanced_morphosyntactic_analysis(
218
  text_input,
219
  nlp_models[lang_code]
220
  )
221
 
222
+ # Guardar an谩lisis base en BD y obtener ID
223
  base_id = store_student_morphosyntax_base(
224
  st.session_state.username,
225
  text_input,
 
227
  )
228
 
229
  if base_id:
230
+ # Actualizar el estado en session_state
231
  st.session_state.arc_analysis_state.update({
232
  'base_id': base_id,
233
  'original_text': text_input,
234
+ 'original_analysis': analysis, # guardamos el dict
235
  'analysis_count': st.session_state.arc_analysis_state['analysis_count'] + 1
236
  })
237
 
 
241
  # L铆nea divisora
242
  st.markdown('<hr class="divider">', unsafe_allow_html=True)
243
 
244
+ # 脕rea de iteraci贸n: usar un formulario
245
  with st.form("iteration_form"):
246
+ # Separamos la key para la iteraci贸n para que no se sobreescriba
247
+ iteration_text_key = f"iteration_text_{st.session_state.arc_analysis_state['analysis_count']}"
248
+
249
+ # Mostrar el texto de iteraci贸n que tengamos en session_state
250
  iteration_text = st.text_area(
251
+ "Texto de iteraci贸n",
252
+ value=st.session_state.arc_analysis_state.get('iteration_text', text_input),
253
+ key=iteration_text_key,
254
  height=100
255
  )
256
 
257
+ # Bot贸n de submit en el formulario
258
  col1, col2, col3 = st.columns([2,1,2])
259
  with col1:
260
  submitted = st.form_submit_button(
 
265
 
266
  # Procesar iteraci贸n
267
  if submitted and iteration_text.strip():
268
+ try:
269
+ doc_iter = nlp_models[lang_code](iteration_text)
270
+ analysis_iter = perform_advanced_morphosyntactic_analysis(
271
+ iteration_text,
272
+ nlp_models[lang_code]
273
+ )
274
 
275
+ # Guardar iteraci贸n
276
+ iteration_id = store_student_morphosyntax_iteration(
277
+ st.session_state.username,
278
+ base_id,
279
+ text_input, # Texto original
280
+ iteration_text, # Texto de iteraci贸n
281
+ analysis_iter['arc_diagrams']
282
+ )
283
 
284
+ if iteration_id:
285
+ # Actualizar el estado de iteraci贸n en session_state
286
+ st.session_state.arc_analysis_state.update({
287
+ 'iteration_text': iteration_text,
288
+ 'iteration_analysis': analysis_iter
289
+ })
290
+ # Mostrar diagrama de iteraci贸n
291
+ display_arc_diagram(doc_iter, analysis_iter)
292
+
293
+ except Exception as e:
294
+ st.error("Error procesando iteraci贸n")
295
+ logger.error(f"Error en iteraci贸n: {str(e)}")
296
 
297
  except Exception as e:
298
+ st.error("Error procesando an谩lisis base")
299
+ logger.error(f"Error base: {str(e)}")
300
 
301
+ # -------------------- Subtab 1: An谩lisis de Categor铆as ----------------
302
  with subtabs[1]:
303
  st.info("An谩lisis de Categor铆as en desarrollo...")
304
+
305
+ # -------------------- Subtab 2: An谩lisis Morfol贸gico ------------------
306
  with subtabs[2]:
307
  st.info("An谩lisis Morfol贸gico en desarrollo...")
308
 
309
  except Exception as e:
310
+ st.error("Error en la interfaz de morfosintaxis")
311
  logger.error(f"Error general en la interfaz: {str(e)}")
312
 
 
 
313
 
314
  def display_morphosyntax_results(result, lang_code, morpho_t):
315
  """
 
317
  Args:
318
  result: Diccionario con el documento procesado y su an谩lisis
319
  lang_code: C贸digo del idioma
320
+ morpho_t: Diccionario de traducciones (opcional)
321
  """
322
  if result is None:
323
  return
 
324
  try:
325
  doc = result['doc']
326
  sentences = list(doc.sents)
327
  for i, sent in enumerate(sentences):
328
  try:
329
  st.subheader(f"{morpho_t.get('sentence', 'Sentence')} {i+1}")
330
+ svg_html = displacy.render(
331
+ sent,
332
+ style="dep",
333
+ options={
334
+ "distance": 100,
335
+ "arrow_spacing": 20,
336
+ "word_spacing": 30
337
+ }
338
+ )
339
+ svg_html = svg_html.replace('height="375"', 'height="200"')
340
+ svg_html = re.sub(
341
+ r'<svg[^>]*>',
342
+ lambda m: m.group(0).replace('height="450"', 'height="300"'),
343
+ svg_html
344
+ )
345
+ svg_html = re.sub(
346
+ r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
347
+ lambda m: f'<g transform="translate({m.group(1)},50)"',
348
+ svg_html
349
+ )
350
+ svg_html = f'<div class="arc-diagram-container">{svg_html}</div>'
351
+ st.write(svg_html, unsafe_allow_html=True)
352
+ except Exception as exc:
353
+ logger.error(f"Error mostrando diagrama de la oraci贸n {i}: {str(exc)}")
354
  continue
355
  except Exception as e:
356
  logger.error(f"Error en display_morphosyntax_results: {str(e)}")