AIdeaText commited on
Commit
404e1f8
·
verified ·
1 Parent(s): b6ee9f7

Update modules/morphosyntax/morphosyntax_interface.py

Browse files
modules/morphosyntax/morphosyntax_interface.py CHANGED
@@ -34,50 +34,57 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
34
  .stTextArea textarea {
35
  font-size: 1rem;
36
  line-height: 1.5;
37
- resize: vertical;
 
 
 
 
 
 
 
38
  }
39
  .block-container {
40
  padding-top: 1rem;
41
  padding-bottom: 1rem;
42
  }
43
- .stExpander {
44
- border: none;
45
- box-shadow: 0 1px 2px rgba(0,0,0,0.1);
46
- margin-bottom: 1rem;
47
- }
48
- .legend-container {
49
- position: sticky;
50
- top: 0;
51
- background: white;
52
- z-index: 100;
53
- padding: 0.5rem 0;
54
- border-bottom: 1px solid #eee;
55
  }
56
  </style>
57
  """, unsafe_allow_html=True)
58
 
59
- # 1. Inicializar el estado
60
  if 'morphosyntax_state' not in st.session_state:
61
  st.session_state.morphosyntax_state = {
62
  'input_text': "",
63
  'analysis_count': 0,
64
  'last_analysis': None,
65
- 'current_tab': 0
66
  }
67
 
68
- # 2. Contenedor principal con diseño sticky
69
  with st.container():
70
- # Campo de entrada de texto
71
  input_key = f"morpho_input_{st.session_state.morphosyntax_state['analysis_count']}"
 
 
 
 
 
 
 
72
  sentence_input = st.text_area(
73
  morpho_t.get('morpho_input_label', 'Enter text to analyze'),
74
  height=150,
75
- placeholder=morpho_t.get('morpho_input_placeholder', 'Enter your text here...'),
76
  key=input_key,
77
- on_change=lambda: None # Previene recargas innecesarias
 
78
  )
79
 
80
- # 3. Botón de análisis centrado
81
  col1, col2, col3 = st.columns([2,1,2])
82
  with col1:
83
  analyze_button = st.button(
@@ -85,34 +92,39 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
85
  key=f"morpho_button_{st.session_state.morphosyntax_state['analysis_count']}",
86
  type="primary",
87
  icon="🔍",
88
- disabled=not bool(sentence_input.strip()),
89
  use_container_width=True
90
  )
91
 
92
- # 4. Procesar análisis
93
- if analyze_button and sentence_input.strip():
94
  try:
95
  with st.spinner(morpho_t.get('processing', 'Processing...')):
96
- doc = nlp_models[lang_code](sentence_input)
 
 
 
97
  advanced_analysis = perform_advanced_morphosyntactic_analysis(
98
- sentence_input,
99
  nlp_models[lang_code]
100
  )
101
 
 
102
  st.session_state.morphosyntax_result = {
103
  'doc': doc,
104
  'advanced_analysis': advanced_analysis
105
  }
 
 
106
  st.session_state.morphosyntax_state['analysis_count'] += 1
107
 
108
- # Guardar resultado
109
  if store_student_morphosyntax_result(
110
  username=st.session_state.username,
111
- text=sentence_input,
112
  arc_diagrams=advanced_analysis['arc_diagrams']
113
  ):
114
  st.success(morpho_t.get('success_message', 'Analysis saved successfully'))
115
- st.session_state.morphosyntax_state['current_tab'] = 0
116
  display_morphosyntax_results(
117
  st.session_state.morphosyntax_result,
118
  lang_code,
@@ -125,112 +137,51 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
125
  logger.error(f"Error en análisis morfosintáctico: {str(e)}")
126
  st.error(morpho_t.get('error_processing', f'Error processing text: {str(e)}'))
127
 
128
- # 5. Mostrar resultados previos
129
  elif 'morphosyntax_result' in st.session_state and st.session_state.morphosyntax_result:
130
  display_morphosyntax_results(
131
  st.session_state.morphosyntax_result,
132
  lang_code,
133
  morpho_t
134
  )
135
- elif not sentence_input.strip():
136
- st.info(morpho_t.get('morpho_initial_message', 'Enter text to begin analysis'))
137
 
138
  except Exception as e:
139
  logger.error(f"Error general en display_morphosyntax_interface: {str(e)}")
140
  st.error("Se produjo un error. Por favor, intente de nuevo.")
141
 
142
  def display_morphosyntax_results(result, lang_code, morpho_t):
 
 
 
143
  if result is None:
144
  st.warning(morpho_t.get('no_results', 'No results available'))
145
  return
146
 
147
  doc = result['doc']
148
- advanced_analysis = result['advanced_analysis']
149
-
150
- # Leyenda fija en la parte superior
151
- with st.container():
152
- st.markdown(f"##### {morpho_t.get('legend', 'Legend: Grammatical categories')}")
153
- legend_html = "<div class='legend-container'><div style='display: flex; flex-wrap: wrap;'>"
154
- for pos, color in POS_COLORS.items():
155
- if pos in POS_TRANSLATIONS[lang_code]:
156
- legend_html += f"<div style='margin-right: 10px;'><span style='background-color: {color}; padding: 2px 5px;'>{POS_TRANSLATIONS[lang_code][pos]}</span></div>"
157
- legend_html += "</div></div>"
158
- st.markdown(legend_html, unsafe_allow_html=True)
159
-
160
- # Palabras repetidas
161
- with st.expander(morpho_t.get('repeated_words', 'Repeated words'), expanded=True):
162
- word_colors = get_repeated_words_colors(doc)
163
- highlighted_text = highlight_repeated_words(doc, word_colors)
164
- st.markdown(highlighted_text, unsafe_allow_html=True)
165
 
166
  # Análisis sintáctico (diagramas de arco)
167
- with st.expander(morpho_t.get('arc_diagram', 'Syntactic analysis: Arc diagram'), expanded=True):
 
 
168
  sentences = list(doc.sents)
169
  for i, sent in enumerate(sentences):
170
- st.subheader(f"{morpho_t.get('sentence', 'Sentence')} {i+1}")
171
- html = displacy.render(sent, style="dep", options={"distance": 100})
172
- html = html.replace('height="375"', 'height="200"')
173
- html = re.sub(r'<svg[^>]*>', lambda m: m.group(0).replace('height="450"', 'height="300"'), html)
174
- html = re.sub(r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
175
- lambda m: f'<g transform="translate({m.group(1)},50)"', html)
176
- st.write(html, unsafe_allow_html=True)
177
-
178
- # Estructura de oraciones
179
- with st.expander(morpho_t.get('sentence_structure', 'Sentence structure'), expanded=True):
180
- for i, sent_analysis in enumerate(advanced_analysis['sentence_structure']):
181
- sentence_str = (
182
- f"**{morpho_t.get('sentence', 'Sentence')} {i+1}** "
183
- f"{morpho_t.get('root', 'Root')}: {sent_analysis['root']} ({sent_analysis['root_pos']}) -- "
184
- f"{morpho_t.get('subjects', 'Subjects')}: {', '.join(sent_analysis['subjects'])} -- "
185
- f"{morpho_t.get('objects', 'Objects')}: {', '.join(sent_analysis['objects'])} -- "
186
- f"{morpho_t.get('verbs', 'Verbs')}: {', '.join(sent_analysis['verbs'])}"
187
- )
188
- st.markdown(sentence_str)
189
-
190
- # Análisis de categorías gramaticales
191
- with st.expander(morpho_t.get('pos_analysis', 'Part of speech'), expanded=True):
192
- pos_df = pd.DataFrame(advanced_analysis['pos_analysis'])
193
- pos_df['pos'] = pos_df['pos'].map(lambda x: POS_TRANSLATIONS[lang_code].get(x, x))
194
- pos_df = pos_df.rename(columns={
195
- 'pos': morpho_t.get('grammatical_category', 'Grammatical category'),
196
- 'count': morpho_t.get('count', 'Count'),
197
- 'percentage': morpho_t.get('percentage', 'Percentage'),
198
- 'examples': morpho_t.get('examples', 'Examples')
199
- })
200
- st.dataframe(pos_df, use_container_width=True)
201
-
202
- # Análisis morfológico
203
- with st.expander(morpho_t.get('morphological_analysis', 'Morphological Analysis'), expanded=True):
204
- morph_df = pd.DataFrame(advanced_analysis['morphological_analysis'])
205
- column_mapping = {
206
- 'text': morpho_t.get('word', 'Word'),
207
- 'lemma': morpho_t.get('lemma', 'Lemma'),
208
- 'pos': morpho_t.get('grammatical_category', 'Grammatical category'),
209
- 'dep': morpho_t.get('dependency', 'Dependency'),
210
- 'morph': morpho_t.get('morphology', 'Morphology')
211
- }
212
- morph_df = morph_df.rename(columns=column_mapping)
213
-
214
- # Traducir categorías gramaticales
215
- grammatical_category = morpho_t.get('grammatical_category', 'Grammatical category')
216
- morph_df[grammatical_category] = morph_df[grammatical_category].map(
217
- lambda x: POS_TRANSLATIONS[lang_code].get(x, x)
218
- )
219
-
220
- # Aplicar traducciones de dependencias y morfología
221
- dependency = morpho_t.get('dependency', 'Dependency')
222
- morphology = morpho_t.get('morphology', 'Morphology')
223
-
224
- def translate_morph(morph_string, lang_code):
225
- for key, value in morph_translations[lang_code].items():
226
- morph_string = morph_string.replace(key, value)
227
- return morph_string
228
-
229
- morph_df[dependency] = morph_df[dependency].map(
230
- lambda x: dep_translations[lang_code].get(x, x)
231
- )
232
- morph_df[morphology] = morph_df[morphology].apply(
233
- lambda x: translate_morph(x, lang_code)
234
- )
235
-
236
- st.dataframe(morph_df, use_container_width=True)
 
34
  .stTextArea textarea {
35
  font-size: 1rem;
36
  line-height: 1.5;
37
+ padding: 0.5rem;
38
+ border-radius: 0.375rem;
39
+ border: 1px solid #e2e8f0;
40
+ background-color: white;
41
+ }
42
+ .stTextArea textarea:focus {
43
+ border-color: #3182ce;
44
+ box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5);
45
  }
46
  .block-container {
47
  padding-top: 1rem;
48
  padding-bottom: 1rem;
49
  }
50
+ .arc-diagram-container {
51
+ background-color: white;
52
+ padding: 1rem;
53
+ border-radius: 0.5rem;
54
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
55
+ margin-top: 1rem;
 
 
 
 
 
 
56
  }
57
  </style>
58
  """, unsafe_allow_html=True)
59
 
60
+ # Inicializar el estado
61
  if 'morphosyntax_state' not in st.session_state:
62
  st.session_state.morphosyntax_state = {
63
  'input_text': "",
64
  'analysis_count': 0,
65
  'last_analysis': None,
 
66
  }
67
 
68
+ # Contenedor principal con manejo de estado mejorado
69
  with st.container():
70
+ # Campo de entrada de texto con manejo de estado explícito
71
  input_key = f"morpho_input_{st.session_state.morphosyntax_state['analysis_count']}"
72
+
73
+ # Función para manejar cambios en el texto
74
+ def on_text_change():
75
+ text = st.session_state[input_key]
76
+ st.session_state.morphosyntax_state['input_text'] = text
77
+
78
+ # Campo de texto con callback
79
  sentence_input = st.text_area(
80
  morpho_t.get('morpho_input_label', 'Enter text to analyze'),
81
  height=150,
 
82
  key=input_key,
83
+ placeholder=morpho_t.get('morpho_input_placeholder', 'Enter your text here...'),
84
+ on_change=on_text_change
85
  )
86
 
87
+ # Botón de análisis
88
  col1, col2, col3 = st.columns([2,1,2])
89
  with col1:
90
  analyze_button = st.button(
 
92
  key=f"morpho_button_{st.session_state.morphosyntax_state['analysis_count']}",
93
  type="primary",
94
  icon="🔍",
95
+ disabled=not bool(st.session_state.morphosyntax_state['input_text'].strip()),
96
  use_container_width=True
97
  )
98
 
99
+ # Procesar análisis
100
+ if analyze_button and st.session_state.morphosyntax_state['input_text'].strip():
101
  try:
102
  with st.spinner(morpho_t.get('processing', 'Processing...')):
103
+ # Procesar el texto
104
+ doc = nlp_models[lang_code](st.session_state.morphosyntax_state['input_text'])
105
+
106
+ # Realizar análisis
107
  advanced_analysis = perform_advanced_morphosyntactic_analysis(
108
+ st.session_state.morphosyntax_state['input_text'],
109
  nlp_models[lang_code]
110
  )
111
 
112
+ # Guardar resultado en el estado
113
  st.session_state.morphosyntax_result = {
114
  'doc': doc,
115
  'advanced_analysis': advanced_analysis
116
  }
117
+
118
+ # Incrementar contador
119
  st.session_state.morphosyntax_state['analysis_count'] += 1
120
 
121
+ # Guardar en base de datos
122
  if store_student_morphosyntax_result(
123
  username=st.session_state.username,
124
+ text=st.session_state.morphosyntax_state['input_text'],
125
  arc_diagrams=advanced_analysis['arc_diagrams']
126
  ):
127
  st.success(morpho_t.get('success_message', 'Analysis saved successfully'))
 
128
  display_morphosyntax_results(
129
  st.session_state.morphosyntax_result,
130
  lang_code,
 
137
  logger.error(f"Error en análisis morfosintáctico: {str(e)}")
138
  st.error(morpho_t.get('error_processing', f'Error processing text: {str(e)}'))
139
 
140
+ # Mostrar resultados previos
141
  elif 'morphosyntax_result' in st.session_state and st.session_state.morphosyntax_result:
142
  display_morphosyntax_results(
143
  st.session_state.morphosyntax_result,
144
  lang_code,
145
  morpho_t
146
  )
 
 
147
 
148
  except Exception as e:
149
  logger.error(f"Error general en display_morphosyntax_interface: {str(e)}")
150
  st.error("Se produjo un error. Por favor, intente de nuevo.")
151
 
152
  def display_morphosyntax_results(result, lang_code, morpho_t):
153
+ """
154
+ Muestra solo el análisis sintáctico con diagramas de arco.
155
+ """
156
  if result is None:
157
  st.warning(morpho_t.get('no_results', 'No results available'))
158
  return
159
 
160
  doc = result['doc']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
  # Análisis sintáctico (diagramas de arco)
163
+ st.markdown(f"### {morpho_t.get('arc_diagram', 'Syntactic analysis: Arc diagram')}")
164
+
165
+ with st.container():
166
  sentences = list(doc.sents)
167
  for i, sent in enumerate(sentences):
168
+ with st.container():
169
+ st.subheader(f"{morpho_t.get('sentence', 'Sentence')} {i+1}")
170
+ try:
171
+ html = displacy.render(sent, style="dep", options={
172
+ "distance": 100,
173
+ "arrow_spacing": 20,
174
+ "word_spacing": 30
175
+ })
176
+ # Ajustar dimensiones del SVG
177
+ html = html.replace('height="375"', 'height="200"')
178
+ html = re.sub(r'<svg[^>]*>', lambda m: m.group(0).replace('height="450"', 'height="300"'), html)
179
+ html = re.sub(r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
180
+ lambda m: f'<g transform="translate({m.group(1)},50)"', html)
181
+
182
+ # Envolver en un div con clase para estilos
183
+ html = f'<div class="arc-diagram-container">{html}</div>'
184
+ st.write(html, unsafe_allow_html=True)
185
+ except Exception as e:
186
+ logger.error(f"Error rendering sentence {i}: {str(e)}")
187
+ st.error(f"Error displaying diagram for sentence {i+1}")