BATUTO-ART commited on
Commit
e5c55fb
·
verified ·
1 Parent(s): 5b4ddb4

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +629 -0
app.py ADDED
@@ -0,0 +1,629 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import requests
4
+ from huggingface_hub import InferenceClient
5
+ import json
6
+ import pandas as pd
7
+ import io
8
+ import base64
9
+ from PIL import Image
10
+ import time
11
+
12
+ # Inicializar cliente de Hugging Face
13
+ def get_client():
14
+ hf_token = os.getenv('HF_TOKEN')
15
+ if hf_token:
16
+ return InferenceClient(token=hf_token)
17
+ else:
18
+ print("❌ Por favor configura tu token de Hugging Face como variable de entorno HF_TOKEN")
19
+ print("Ve a [Hugging Face Tokens](https://huggingface.co/settings/tokens) para obtener tu token")
20
+ return None
21
+
22
+ client = get_client()
23
+
24
+ # ========== FUNCIONES COMPARTIDAS ==========
25
+ def analizar_sentimiento(texto):
26
+ if not texto:
27
+ return None
28
+ try:
29
+ resultado = client.text_classification(
30
+ texto,
31
+ model="cardiffnlp/twitter-roberta-base-sentiment-latest"
32
+ )
33
+ return resultado[0] if resultado else None
34
+ except Exception as e:
35
+ print(f"Error en análisis de sentimiento: {e}")
36
+ return None
37
+
38
+ # ========== 1. ASISTENTE VIRTUAL ==========
39
+ def asistente_virtual(mensaje, historial):
40
+ if not mensaje:
41
+ return "", historial, ""
42
+
43
+ # Analizar sentimiento del nuevo mensaje
44
+ sentiment = analizar_sentimiento(mensaje)
45
+
46
+ # Generar respuesta adaptativa
47
+ system_message = "Eres un asistente útil y amable."
48
+ if sentiment and sentiment['label'] == 'negative':
49
+ system_message += " El usuario parece estar expresando emociones negativas, sé especialmente empático y comprensivo."
50
+ elif sentiment and sentiment['label'] == 'positive':
51
+ system_message += " El usuario parece estar de buen humor, mantén un tono alegre y positivo."
52
+
53
+ try:
54
+ # Preparar mensajes para el modelo - usando un modelo de Hugging Face válido
55
+ messages = f"{system_message}\n\nHistorial de conversación:\n"
56
+
57
+ # Agregar historial reciente
58
+ for user_msg, assistant_msg in historial[-4:]:
59
+ messages += f"Usuario: {user_msg}\nAsistente: {assistant_msg}\n"
60
+
61
+ messages += f"Usuario: {mensaje}\nAsistente:"
62
+
63
+ # Usar un modelo de chat válido de Hugging Face
64
+ response = client.text_generation(
65
+ prompt=messages,
66
+ model="microsoft/DialoGPT-medium", # Modelo de chat válido
67
+ max_new_tokens=500,
68
+ temperature=0.7,
69
+ do_sample=True
70
+ )
71
+
72
+ respuesta = response.strip()
73
+
74
+ # Agregar al historial
75
+ historial.append([mensaje, respuesta])
76
+
77
+ info_sentimiento = ""
78
+ if sentiment:
79
+ info_sentimiento = f"Análisis de sentimiento: {sentiment['label']} (score: {sentiment['score']:.2f})"
80
+
81
+ return "", historial, info_sentimiento
82
+
83
+ except Exception as e:
84
+ error_msg = f"Error al generar respuesta: {e}"
85
+ historial.append([mensaje, error_msg])
86
+ return "", historial, f"Error: {str(e)}"
87
+
88
+ # ========== 2. GENERADOR MULTIMEDIA ==========
89
+ def generar_multimedia(tema, estilo_articulo, estilo_imagen):
90
+ if not tema:
91
+ return "Por favor ingresa un tema", None
92
+
93
+ try:
94
+ # Generar artículo con modelo válido
95
+ prompt_articulo = f"""
96
+ Escribe un artículo {estilo_articulo.lower()} sobre: {tema}
97
+
98
+ Requisitos:
99
+ - Título atractivo
100
+ - Introducción convincente
101
+ - 3-4 párrafos de desarrollo
102
+ - Conclusión impactante
103
+ - Incluir datos interesantes
104
+ """
105
+
106
+ articulo = client.text_generation(
107
+ prompt=prompt_articulo,
108
+ model="microsoft/DialoGPT-medium",
109
+ max_new_tokens=800,
110
+ temperature=0.7,
111
+ do_sample=True
112
+ )
113
+
114
+ articulo_texto = articulo.strip()
115
+
116
+ # Generar imagen - usando un modelo válido
117
+ try:
118
+ prompt_imagen = f"{tema}, estilo {estilo_imagen.lower()}, alta calidad, detallado"
119
+ imagen = client.text_to_image(
120
+ prompt=prompt_imagen,
121
+ model="runwayml/stable-diffusion-v1-5" # Modelo de imagen válido
122
+ )
123
+ return articulo_texto, imagen
124
+ except Exception as img_error:
125
+ print(f"Error generando imagen: {img_error}")
126
+ # Retornar una imagen placeholder o mensaje de error
127
+ return articulo_texto, None
128
+
129
+ except Exception as e:
130
+ return f"Error al generar contenido: {e}", None
131
+
132
+ # ========== 3. BÚSQUEDA INTELIGENTE ==========
133
+ documentos_ejemplo = {
134
+ "Tecnología": [
135
+ "Los transformers son arquitecturas de deep learning que han revolucionado el procesamiento de lenguaje natural.",
136
+ "Hugging Face proporciona acceso a miles de modelos pre-entrenados para diferentes tareas de IA.",
137
+ "El aprendizaje por transferencia permite usar modelos pre-entrenados y adaptarlos a tareas específicas."
138
+ ],
139
+ "Ciencia": [
140
+ "La teoría de la relatividad general de Einstein describe la gravedad como curvatura del espacio-tiempo.",
141
+ "El método científico consiste en observación, hipótesis, experimentación y conclusión.",
142
+ "La mecánica cuántica estudia el comportamiento de partículas a nivel subatómico."
143
+ ],
144
+ "Programación": [
145
+ "Python es un lenguaje de programación interpretado conocido por su sintaxis clara y legible.",
146
+ "Git es un sistema de control de versiones distribuido para gestionar cambios en el código.",
147
+ "Las APIs REST permiten la comunicación entre aplicaciones mediante protocolos web estándar."
148
+ ]
149
+ }
150
+
151
+ def buscar_informacion(consulta, categoria):
152
+ if not consulta:
153
+ return "Por favor ingresa una consulta", ""
154
+
155
+ try:
156
+ # Simular búsqueda semántica
157
+ documentos_relevantes = []
158
+ for doc in documentos_ejemplo[categoria]:
159
+ if any(palabra.lower() in doc.lower() for palabra in consulta.split()):
160
+ documentos_relevantes.append(doc)
161
+
162
+ if not documentos_relevantes:
163
+ documentos_relevantes = documentos_ejemplo[categoria][:2] # Fallback
164
+
165
+ contexto = " ".join(documentos_relevantes)
166
+
167
+ # Generar respuesta contextual
168
+ prompt = f"""
169
+ Basándote en el siguiente contexto, responde a la consulta del usuario de manera precisa y útil.
170
+
171
+ Contexto:
172
+ {contexto}
173
+
174
+ Consulta: {consulta}
175
+
176
+ Responde de forma clara y concisa, citando información del contexto cuando sea relevante.
177
+ """
178
+
179
+ respuesta = client.text_generation(
180
+ prompt=prompt,
181
+ model="microsoft/DialoGPT-medium",
182
+ max_new_tokens=400,
183
+ temperature=0.3,
184
+ do_sample=True
185
+ )
186
+
187
+ respuesta_texto = respuesta.strip()
188
+ documentos_usados = "\n".join([f"• {doc}" for doc in documentos_relevantes])
189
+
190
+ return respuesta_texto, documentos_usados
191
+
192
+ except Exception as e:
193
+ return f"Error en la búsqueda: {e}", ""
194
+
195
+ # ========== 4. TRADUCTOR CULTURAL ==========
196
+ def traducir_con_texto(texto_traducir, idioma_origen, idioma_destino, contexto_cultural):
197
+ if not texto_traducir:
198
+ return "Por favor ingresa texto para traducir"
199
+
200
+ try:
201
+ prompt = f"""
202
+ Traduce el siguiente texto del {idioma_origen} al {idioma_destino}, considerando cuidadosamente los matices culturales y lingüísticos.
203
+
204
+ {f"Contexto cultural específico: {contexto_cultural}" if contexto_cultural else ""}
205
+
206
+ Texto a traducir:
207
+ "{texto_traducir}"
208
+
209
+ Instrucciones:
210
+ 1. Mantén el tono y estilo original
211
+ 2. Adapta referencias culturales cuando sea necesario
212
+ 3. Conserva el significado preciso
213
+ 4. Usa lenguaje natural y fluido
214
+
215
+ Traducción:
216
+ """
217
+
218
+ respuesta = client.text_generation(
219
+ prompt=prompt,
220
+ model="microsoft/DialoGPT-medium",
221
+ max_new_tokens=600,
222
+ temperature=0.3,
223
+ do_sample=True
224
+ )
225
+
226
+ return respuesta.strip()
227
+
228
+ except Exception as e:
229
+ return f"Error en la traducción: {e}"
230
+
231
+ # ========== 5. ASISTENTE DE CÓDIGO ==========
232
+ def generar_codigo(problema, lenguaje, nivel_complejidad):
233
+ if not problema:
234
+ return "Por favor describe tu problema de programación"
235
+
236
+ try:
237
+ prompt = f"""
238
+ Como experto en {lenguaje}, resuelve el siguiente problema de programación para un nivel {nivel_complejidad.lower()}:
239
+
240
+ Problema: {problema}
241
+
242
+ Proporciona:
243
+ 1. Código completo y funcional
244
+ 2. Explicación clara de la solución
245
+ 3. Ejemplos de uso
246
+ 4. Consideraciones de mejores prácticas
247
+
248
+ Formatea el código adecuadamente y sé preciso en las explicaciones.
249
+
250
+ Respuesta:
251
+ """
252
+
253
+ respuesta = client.text_generation(
254
+ prompt=prompt,
255
+ model="microsoft/DialoGPT-medium",
256
+ max_new_tokens=800,
257
+ temperature=0.3,
258
+ do_sample=True
259
+ )
260
+
261
+ return respuesta.strip()
262
+
263
+ except Exception as e:
264
+ return f"Error al generar solución: {e}"
265
+
266
+ # ========== 6. ANALIZADOR DE DATOS ==========
267
+ datos_ejemplo = {
268
+ 'Producto': ['Laptop', 'Tablet', 'Smartphone', 'Monitor', 'Teclado'],
269
+ 'Ventas': [120, 85, 200, 75, 90],
270
+ 'Precio': [1200, 450, 800, 300, 80],
271
+ 'Región': ['Norte', 'Sur', 'Norte', 'Este', 'Oeste'],
272
+ 'Mes': ['Enero', 'Enero', 'Febrero', 'Febrero', 'Marzo']
273
+ }
274
+
275
+ def analizar_datos(pregunta, usar_ejemplo):
276
+ if not pregunta:
277
+ return "Por favor ingresa una pregunta sobre los datos", None, None
278
+
279
+ try:
280
+ if usar_ejemplo:
281
+ datos = pd.DataFrame(datos_ejemplo)
282
+ else:
283
+ return "Funcionalidad de subida de archivos disponible en implementación completa", None, None
284
+
285
+ # Convertir datos a formato legible
286
+ resumen_datos = f"""
287
+ Dataset con {len(datos)} filas y {len(datos.columns)} columnas.
288
+
289
+ Columnas disponibles: {list(datos.columns)}
290
+
291
+ Primeras filas:
292
+ {datos.head().to_string()}
293
+
294
+ Resumen estadístico:
295
+ {datos.describe().to_string()}
296
+ """
297
+
298
+ prompt = f"""
299
+ Eres un asistente de análisis de datos. Basándote en el siguiente resumen de datos, responde a la pregunta del usuario.
300
+
301
+ Resumen de Datos:
302
+ {resumen_datos}
303
+
304
+ Pregunta del Usuario: {pregunta}
305
+
306
+ Responde de forma clara y concisa, enfocándote en la pregunta.
307
+
308
+ Respuesta:
309
+ """
310
+
311
+ respuesta = client.text_generation(
312
+ prompt=prompt,
313
+ model="microsoft/DialoGPT-medium",
314
+ max_new_tokens=600,
315
+ temperature=0.3,
316
+ do_sample=True
317
+ )
318
+
319
+ # Crear una visualización simple
320
+ tabla_html = datos.head().to_html(classes='table table-striped')
321
+
322
+ return respuesta.strip(), tabla_html, datos.describe().to_html(classes='table table-striped')
323
+
324
+ except Exception as e:
325
+ return f"Error al analizar datos: {e}", None, None
326
+
327
+ # ========== INTERFAZ GRADIO ==========
328
+ with gr.Blocks(theme=gr.themes.Soft(), title="Asistente Multifuncional IA") as demo:
329
+ gr.Markdown("# 🤖 Asistente Multifuncional con Hugging Face")
330
+ gr.Markdown("Esta aplicación integra múltiples funcionalidades de IA usando Hugging Face Inference API")
331
+
332
+ with gr.Tab("🏠 Inicio"):
333
+ gr.Markdown("""
334
+ ## Bienvenido al Asistente Multifuncional
335
+
336
+ ### 🎯 Funcionalidades disponibles:
337
+
338
+ **1. Asistente Virtual Multifuncional**
339
+ - Chat inteligente con análisis de sentimiento
340
+ - Respuestas adaptativas según el estado emocional
341
+
342
+ **2. Generador de Contenido Multimedia**
343
+ - Creación de artículos e imágenes
344
+ - Contenido coherente y visualmente atractivo
345
+
346
+ **3. Sistema de Búsqueda Inteligente**
347
+ - Búsqueda semántica en documentos
348
+ - Respuestas contextuales
349
+
350
+ **4. Traductor con Contexto Cultural**
351
+ - Traducciones que consideran matices culturales
352
+ - Adaptación local del contenido
353
+
354
+ **5. Asistente de Código Inteligente**
355
+ - Generación y explicación de código
356
+ - Soporte para múltiples lenguajes de programación
357
+
358
+ **6. Analizador de Datos Conversacional**
359
+ - Análisis de datasets mediante lenguaje natural
360
+ - Insights y visualizaciones sugeridas
361
+
362
+ ### 🔧 Modelos utilizados:
363
+ - **Chat y Texto:** Microsoft DialoGPT-medium
364
+ - **Imágenes:** Stable Diffusion v1.5
365
+ - **Análisis de Sentimiento:** Twitter RoBERTa
366
+ """)
367
+
368
+ with gr.Tab("1️⃣ Asistente Virtual"):
369
+ gr.Markdown("## 🤖 Asistente Virtual Multifuncional")
370
+
371
+ chatbot = gr.Chatbot(
372
+ label="Conversación",
373
+ height=400,
374
+ show_copy_button=True
375
+ )
376
+ msg = gr.Textbox(
377
+ label="Escribe tu mensaje",
378
+ placeholder="¿En qué puedo ayudarte?",
379
+ max_lines=3
380
+ )
381
+ sentimiento_info = gr.Textbox(
382
+ label="Información de Sentimiento",
383
+ interactive=False
384
+ )
385
+
386
+ with gr.Row():
387
+ clear_btn = gr.Button("🧹 Limpiar Chat", variant="secondary")
388
+ submit_btn = gr.Button("📤 Enviar", variant="primary")
389
+
390
+ def clear_chat():
391
+ return [], ""
392
+
393
+ def send_message(message, history):
394
+ return asistente_virtual(message, history)
395
+
396
+ msg.submit(send_message, [msg, chatbot], [msg, chatbot, sentimiento_info])
397
+ submit_btn.click(send_message, [msg, chatbot], [msg, chatbot, sentimiento_info])
398
+ clear_btn.click(clear_chat, outputs=[chatbot, sentimiento_info])
399
+
400
+ with gr.Tab("2️⃣ Generador Multimedia"):
401
+ gr.Markdown("## 🎨 Generador de Contenido Multimedia")
402
+
403
+ with gr.Row():
404
+ with gr.Column():
405
+ tema = gr.Textbox(
406
+ label="Tema del contenido:",
407
+ placeholder="Ej: inteligencia artificial en la medicina moderna"
408
+ )
409
+ estilo_articulo = gr.Dropdown(
410
+ ["Informativo", "Persuasivo", "Narrativo", "Técnico"],
411
+ label="Estilo del artículo:",
412
+ value="Informativo"
413
+ )
414
+ estilo_imagen = gr.Dropdown(
415
+ ["Realista", "Artístico", "Futurista", "Minimalista"],
416
+ label="Estilo de imagen:",
417
+ value="Realista"
418
+ )
419
+ generar_btn = gr.Button("🎭 Generar Contenido Multimedia", variant="primary")
420
+
421
+ with gr.Column():
422
+ articulo_output = gr.Textbox(
423
+ label="📝 Artículo Generado",
424
+ lines=10,
425
+ show_copy_button=True
426
+ )
427
+ imagen_output = gr.Image(
428
+ label="🖼️ Imagen Generada",
429
+ height=300
430
+ )
431
+
432
+ generar_btn.click(
433
+ generar_multimedia,
434
+ inputs=[tema, estilo_articulo, estilo_imagen],
435
+ outputs=[articulo_output, imagen_output]
436
+ )
437
+
438
+ with gr.Tab("3️⃣ Búsqueda Inteligente"):
439
+ gr.Markdown("## 🔍 Sistema de Búsqueda Inteligente")
440
+
441
+ with gr.Row():
442
+ with gr.Column():
443
+ categoria = gr.Dropdown(
444
+ list(documentos_ejemplo.keys()),
445
+ label="Categoría:",
446
+ value="Tecnología"
447
+ )
448
+ consulta = gr.Textbox(
449
+ label="Consulta de búsqueda:",
450
+ placeholder="Escribe tu pregunta aquí..."
451
+ )
452
+ buscar_btn = gr.Button("🔎 Buscar", variant="primary")
453
+
454
+ gr.Markdown("### 📚 Documentos en la categoría:")
455
+ documentos_text = gr.Textbox(
456
+ lines=5,
457
+ interactive=False,
458
+ show_copy_button=True
459
+ )
460
+
461
+ with gr.Column():
462
+ respuesta_output = gr.Textbox(
463
+ label="💡 Respuesta Inteligente",
464
+ lines=8,
465
+ show_copy_button=True
466
+ )
467
+ documentos_usados = gr.Textbox(
468
+ label="📖 Documentos utilizados",
469
+ lines=4,
470
+ show_copy_button=True
471
+ )
472
+
473
+ def actualizar_documentos(categoria):
474
+ docs = documentos_ejemplo.get(categoria, [])
475
+ return "\n".join([f"• {doc}" for doc in docs])
476
+
477
+ categoria.change(
478
+ actualizar_documentos,
479
+ inputs=[categoria],
480
+ outputs=[documentos_text]
481
+ )
482
+
483
+ buscar_btn.click(
484
+ buscar_informacion,
485
+ inputs=[consulta, categoria],
486
+ outputs=[respuesta_output, documentos_usados]
487
+ )
488
+
489
+ with gr.Tab("4️⃣ Traductor Cultural"):
490
+ gr.Markdown("## 🌍 Traductor con Contexto Cultural")
491
+
492
+ with gr.Row():
493
+ with gr.Column():
494
+ texto_traducir = gr.Textbox(
495
+ label="Texto a traducir:",
496
+ lines=4,
497
+ placeholder="Ingresa el texto que quieres traducir..."
498
+ )
499
+ idioma_origen = gr.Dropdown(
500
+ ["español", "inglés", "francés", "alemán", "italiano", "portugués"],
501
+ label="Idioma origen:",
502
+ value="español"
503
+ )
504
+ idioma_destino = gr.Dropdown(
505
+ ["inglés", "español", "francés", "alemán", "italiano", "portugués"],
506
+ label="Idioma destino:",
507
+ value="inglés"
508
+ )
509
+ contexto_cultural = gr.Textbox(
510
+ label="Contexto cultural específico (opcional):",
511
+ placeholder="Ej: lenguaje formal, jerga juvenil, términos técnicos..."
512
+ )
513
+ traducir_btn = gr.Button("🔄 Traducir", variant="primary")
514
+
515
+ with gr.Column():
516
+ traduccion_output = gr.Textbox(
517
+ label="📄 Traducción Resultante",
518
+ lines=8,
519
+ show_copy_button=True
520
+ )
521
+
522
+ traducir_btn.click(
523
+ traducir_con_texto,
524
+ inputs=[texto_traducir, idioma_origen, idioma_destino, contexto_cultural],
525
+ outputs=[traduccion_output]
526
+ )
527
+
528
+ with gr.Tab("5️⃣ Asistente Código"):
529
+ gr.Markdown("## 💻 Asistente de Código Inteligente")
530
+
531
+ with gr.Row():
532
+ with gr.Column():
533
+ problema = gr.Textbox(
534
+ label="Describe tu problema de programación:",
535
+ lines=3,
536
+ placeholder="Ej: Necesito una función que calcule el factorial de un número..."
537
+ )
538
+ lenguaje = gr.Dropdown(
539
+ ["Python", "JavaScript", "Java", "C++", "C#", "Go", "Rust", "PHP", "SQL"],
540
+ label="Lenguaje de programación:",
541
+ value="Python"
542
+ )
543
+ nivel_complejidad = gr.Radio(
544
+ ["Básico", "Intermedio", "Avanzado"],
545
+ label="Nivel de complejidad:",
546
+ value="Intermedio"
547
+ )
548
+ generar_codigo_btn = gr.Button("👨‍💻 Generar Solución", variant="primary")
549
+
550
+ with gr.Column():
551
+ solucion_output = gr.Textbox(
552
+ label="💡 Solución de Código",
553
+ lines=12,
554
+ show_copy_button=True
555
+ )
556
+
557
+ generar_codigo_btn.click(
558
+ generar_codigo,
559
+ inputs=[problema, lenguaje, nivel_complejidad],
560
+ outputs=[solucion_output]
561
+ )
562
+
563
+ with gr.Tab("6️⃣ Analizador Datos"):
564
+ gr.Markdown("## 📊 Analizador de Datos Conversacional")
565
+ with gr.Row():
566
+ with gr.Column():
567
+ usar_ejemplo = gr.Checkbox(
568
+ label="Usar datos de ejemplo",
569
+ value=True
570
+ )
571
+ pregunta = gr.Textbox(
572
+ label="¿Qué quieres analizar?",
573
+ placeholder="Ej: ¿Cuáles son los productos más vendidos?"
574
+ )
575
+ analizar_btn = gr.Button("🔍 Analizar Datos", variant="primary")
576
+
577
+ gr.Markdown("### 📈 Vista Previa de Datos")
578
+ tabla_preview = gr.HTML()
579
+
580
+ with gr.Column():
581
+ analisis_output = gr.Textbox(
582
+ label="📊 Análisis",
583
+ lines=8,
584
+ show_copy_button=True
585
+ )
586
+ gr.Markdown("### 📋 Resumen Estadístico")
587
+ resumen_output = gr.HTML()
588
+
589
+ def actualizar_vista_previa(usar_ejemplo):
590
+ if usar_ejemplo:
591
+ datos = pd.DataFrame(datos_ejemplo)
592
+ return datos.head().to_html(classes='table table-striped', index=False)
593
+ return "<p>Sube un archivo CSV para ver la vista previa</p>"
594
+
595
+ analizar_btn.click(
596
+ analizar_datos,
597
+ inputs=[pregunta, usar_ejemplo],
598
+ outputs=[analisis_output, tabla_preview, resumen_output]
599
+ )
600
+
601
+ usar_ejemplo.change(
602
+ actualizar_vista_previa,
603
+ inputs=[usar_ejemplo],
604
+ outputs=[tabla_preview]
605
+ )
606
+
607
+ # Configuración CSS adicional
608
+ css = """
609
+ .table {
610
+ width: 100%;
611
+ border-collapse: collapse;
612
+ }
613
+ .table-striped tbody tr:nth-of-type(odd) {
614
+ background-color: rgba(0,0,0,.05);
615
+ }
616
+ .table td, .table th {
617
+ padding: 8px;
618
+ border: 1px solid #dee2e6;
619
+ }
620
+ """
621
+
622
+ # Ejecutar la aplicación
623
+ if __name__ == "__main__":
624
+ demo.launch(
625
+ share=True,
626
+ inbrowser=True,
627
+ show_error=True
628
+ )
629
+ ```