AIdeaText commited on
Commit
7d2b8ec
·
verified ·
1 Parent(s): b5d52d5

Create ui.py

Browse files
Files changed (1) hide show
  1. modules/ui.py +231 -0
modules/ui.py ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import matplotlib.pyplot as plt
3
+ import pandas as pd
4
+ import io
5
+ import base64
6
+ from spacy import displacy
7
+ import re
8
+ from .morpho_analysis import POS_COLORS, POS_TRANSLATIONS
9
+ from .auth import authenticate_user, register_user, get_user_role
10
+ from .database import get_student_data, store_analysis_result
11
+ from .morpho_analysis import get_repeated_words_colors, highlight_repeated_words
12
+ from .syntax_analysis import visualize_syntax
13
+
14
+ def login_form():
15
+ username = st.text_input("Usuario")
16
+ password = st.text_input("Contraseña", type='password')
17
+ captcha_answer = st.text_input("Captcha: ¿Cuánto es 2 + 3?")
18
+
19
+ if st.button("Iniciar Sesión"):
20
+ if captcha_answer == "5":
21
+ if authenticate_user(username, password):
22
+ st.success(f"Bienvenido, {username}!")
23
+ st.session_state.logged_in = True
24
+ st.session_state.username = username
25
+ st.session_state.role = get_user_role(username)
26
+ st.experimental_rerun()
27
+ else:
28
+ st.error("Usuario o contraseña incorrectos")
29
+ else:
30
+ st.error("Captcha incorrecto")
31
+
32
+ def register_form():
33
+ new_username = st.text_input("Nuevo Usuario")
34
+ new_password = st.text_input("Nueva Contraseña", type='password')
35
+ carrera = st.text_input("Carrera")
36
+ captcha_answer = st.text_input("Captcha: ¿Cuánto es 3 + 4?")
37
+
38
+ if st.button("Registrarse"):
39
+ if captcha_answer == "7":
40
+ additional_info = {'carrera': carrera}
41
+ if register_user(new_username, new_password, additional_info):
42
+ st.success("Registro exitoso. Por favor, inicia sesión.")
43
+ else:
44
+ st.error("El usuario ya existe o ocurrió un error durante el registro")
45
+ else:
46
+ st.error("Captcha incorrecto")
47
+
48
+ def display_chat_interface():
49
+ st.markdown("### Chat con AIdeaText")
50
+
51
+ if 'chat_history' not in st.session_state:
52
+ st.session_state.chat_history = []
53
+
54
+ for i, (role, text) in enumerate(st.session_state.chat_history):
55
+ if role == "user":
56
+ st.text_area(f"Tú:", value=text, height=50, key=f"user_message_{i}", disabled=True)
57
+ else:
58
+ st.text_area(f"AIdeaText:", value=text, height=50, key=f"bot_message_{i}", disabled=True)
59
+
60
+ user_input = st.text_input("Escribe tu mensaje aquí:")
61
+
62
+ if st.button("Enviar"):
63
+ if user_input:
64
+ st.session_state.chat_history.append(("user", user_input))
65
+ response = get_chatbot_response(user_input)
66
+ st.session_state.chat_history.append(("bot", response))
67
+ st.experimental_rerun()
68
+
69
+ def display_student_progress(username, lang_code='es'):
70
+ student_data = get_student_data(username)
71
+
72
+ if student_data is None:
73
+ st.warning("No se encontraron datos para este estudiante.")
74
+ st.info("Intenta realizar algunos análisis de texto primero.")
75
+ return
76
+
77
+ st.title(f"Progreso de {username}")
78
+
79
+ if student_data['entries_count'] > 0:
80
+ if 'word_count' in student_data and student_data['word_count']:
81
+ st.subheader("Total de palabras por categoría gramatical")
82
+
83
+ df = pd.DataFrame(list(student_data['word_count'].items()), columns=['category', 'count'])
84
+ df['label'] = df.apply(lambda x: f"{POS_TRANSLATIONS[lang_code].get(x['category'], x['category'])}", axis=1)
85
+
86
+ df = df.sort_values('count', ascending=False)
87
+
88
+ fig, ax = plt.subplots(figsize=(12, 6))
89
+ bars = ax.bar(df['label'], df['count'], color=[POS_COLORS.get(cat, '#CCCCCC') for cat in df['category']])
90
+
91
+ ax.set_xlabel('Categoría Gramatical')
92
+ ax.set_ylabel('Cantidad de Palabras')
93
+ ax.set_title('Total de palabras por categoría gramatical')
94
+ plt.xticks(rotation=45, ha='right')
95
+
96
+ for bar in bars:
97
+ height = bar.get_height()
98
+ ax.text(bar.get_x() + bar.get_width()/2., height,
99
+ f'{height}',
100
+ ha='center', va='bottom')
101
+
102
+ plt.tight_layout()
103
+
104
+ buf = io.BytesIO()
105
+ fig.savefig(buf, format='png')
106
+ buf.seek(0)
107
+ st.image(buf, use_column_width=True)
108
+ else:
109
+ st.info("No hay datos de conteo de palabras disponibles.")
110
+
111
+ st.header("Diagramas de Arco")
112
+ with st.expander("Ver todos los Diagramas de Arco"):
113
+ for i, entry in enumerate(student_data['entries']):
114
+ if 'arc_diagrams' in entry and entry['arc_diagrams']:
115
+ st.subheader(f"Entrada {i+1} - {entry['timestamp']}")
116
+ st.write(entry['arc_diagrams'][0], unsafe_allow_html=True)
117
+
118
+ st.header("Diagramas de Red")
119
+ with st.expander("Ver todos los Diagramas de Red"):
120
+ for i, entry in enumerate(student_data['entries']):
121
+ if 'network_diagram' in entry and entry['network_diagram']:
122
+ st.subheader(f"Entrada {i+1} - {entry['timestamp']}")
123
+ try:
124
+ image_bytes = base64.b64decode(entry['network_diagram'])
125
+ st.image(image_bytes)
126
+ except Exception as e:
127
+ st.error(f"Error al mostrar el diagrama de red: {str(e)}")
128
+ else:
129
+ st.warning("No se encontraron entradas para este estudiante.")
130
+ st.info("Intenta realizar algunos análisis de texto primero.")
131
+
132
+ def display_text_analysis_interface(nlp_models, lang_code):
133
+ translations = {
134
+ 'es': {
135
+ 'title': "AIdeaText - Análisis morfológico y sintáctico",
136
+ 'input_label': "Ingrese un texto para analizar (máx. 5,000 palabras):",
137
+ 'input_placeholder': "El objetivo de esta aplicación es que mejore sus habilidades de redacción...",
138
+ 'analyze_button': "Analizar texto",
139
+ 'repeated_words': "Palabras repetidas",
140
+ 'legend': "Leyenda: Categorías gramaticales",
141
+ 'arc_diagram': "Análisis sintáctico: Diagrama de arco",
142
+ 'network_diagram': "Análisis sintáctico: Diagrama de red",
143
+ 'sentence': "Oración"
144
+ },
145
+ 'en': {
146
+ 'title': "AIdeaText - Morphological and Syntactic Analysis",
147
+ 'input_label': "Enter a text to analyze (max 5,000 words):",
148
+ 'input_placeholder': "The goal of this app is for you to improve your writing skills...",
149
+ 'analyze_button': "Analyze text",
150
+ 'repeated_words': "Repeated words",
151
+ 'legend': "Legend: Grammatical categories",
152
+ 'arc_diagram': "Syntactic analysis: Arc diagram",
153
+ 'network_diagram': "Syntactic analysis: Network diagram",
154
+ 'sentence': "Sentence"
155
+ },
156
+ 'fr': {
157
+ 'title': "AIdeaText - Analyse morphologique et syntaxique",
158
+ 'input_label': "Entrez un texte à analyser (max 5 000 mots) :",
159
+ 'input_placeholder': "Le but de cette application est d'améliorer vos compétences en rédaction...",
160
+ 'analyze_button': "Analyser le texte",
161
+ 'repeated_words': "Mots répétés",
162
+ 'legend': "Légende : Catégories grammaticales",
163
+ 'arc_diagram': "Analyse syntaxique : Diagramme en arc",
164
+ 'network_diagram': "Analyse syntaxique : Diagramme de réseau",
165
+ 'sentence': "Phrase"
166
+ }
167
+ }
168
+
169
+ t = translations[lang_code]
170
+
171
+ if 'input_text' not in st.session_state:
172
+ st.session_state.input_text = ""
173
+
174
+ sentence_input = st.text_area(
175
+ t['input_label'],
176
+ height=150,
177
+ placeholder=t['input_placeholder'],
178
+ value=st.session_state.input_text,
179
+ key=f"text_input_{lang_code}"
180
+ )
181
+ st.session_state.input_text = sentence_input
182
+
183
+ if st.button(t['analyze_button'], key=f"analyze_button_{lang_code}"):
184
+ if sentence_input:
185
+ doc = nlp_models[lang_code](sentence_input)
186
+
187
+ with st.expander(t['repeated_words'], expanded=True):
188
+ word_colors = get_repeated_words_colors(doc)
189
+ highlighted_text = highlight_repeated_words(doc, word_colors)
190
+ st.markdown(highlighted_text, unsafe_allow_html=True)
191
+
192
+ st.markdown(f"##### {t['legend']}")
193
+ legend_html = "<div style='display: flex; flex-wrap: wrap;'>"
194
+ for pos, color in POS_COLORS.items():
195
+ if pos in POS_TRANSLATIONS:
196
+ legend_html += f"<div style='margin-right: 10px;'><span style='background-color: {color}; padding: 2px 5px;'>{POS_TRANSLATIONS[pos]}</span></div>"
197
+ legend_html += "</div>"
198
+ st.markdown(legend_html, unsafe_allow_html=True)
199
+
200
+ with st.expander(t['arc_diagram'], expanded=True):
201
+ sentences = list(doc.sents)
202
+ arc_diagrams = []
203
+ for i, sent in enumerate(sentences):
204
+ st.subheader(f"{t['sentence']} {i+1}")
205
+ html = displacy.render(sent, style="dep", options={"distance": 100})
206
+ html = html.replace('height="375"', 'height="200"')
207
+ html = re.sub(r'<svg[^>]*>', lambda m: m.group(0).replace('height="450"', 'height="300"'), html)
208
+ html = re.sub(r'<g [^>]*transform="translate\((\d+),(\d+)\)"', lambda m: f'<g transform="translate({m.group(1)},50)"', html)
209
+ st.write(html, unsafe_allow_html=True)
210
+ arc_diagrams.append(html)
211
+
212
+ with st.expander(t['network_diagram'], expanded=True):
213
+ fig = visualize_syntax(sentence_input, nlp_models[lang_code], lang_code)
214
+ st.pyplot(fig)
215
+
216
+ if store_analysis_result(
217
+ st.session_state.username,
218
+ sentence_input,
219
+ word_colors,
220
+ arc_diagrams,
221
+ fig
222
+ ):
223
+ st.success("Análisis guardado correctamente.")
224
+ else:
225
+ st.error("Hubo un problema al guardar el análisis. Por favor, inténtelo de nuevo.")
226
+ st.error(f"Falló el guardado del análisis. Username: {st.session_state.username}")
227
+
228
+ def get_chatbot_response(input_text):
229
+ # Esta función debe ser implementada o importada de otro módulo
230
+ # Por ahora, retornamos un mensaje genérico
231
+ return "Lo siento, el chatbot no está disponible en este momento."