Acecho / app.py
VirselClem's picture
Update app.py
c8c9f7d verified
import openai
import nltk
nltk.download('punkt')
nltk.download('punkt_tab')
from collections import Counter
import tempfile
from collections import defaultdict
#from googletrans import Translator, constants
#from googletrans import Translator
from pprint import pprint
import matplotlib.pyplot as plt
import re
import pandas as pd
import gradio as gr
import os
openai.api_key = os.getenv("ACECHO")
#from gradio.components import Textbox, Dropdown
#def calcular_promedio_longitud(texto):
# sent_tokenizer = nltk.sent_tokenize
# word_tokenizer = nltk.word_tokenize
# oraciones = sent_tokenizer(texto)
# parrafos = texto.split('\n')
# longitud_promedio_oraciones = sum(len(word_tokenizer(oracion)) for oracion in oraciones) / len(oraciones)
# longitud_promedio_parrafos = sum(len(word_tokenizer(parrafo)) for parrafo in parrafos) / len(parrafos)
# return longitud_promedio_oraciones, longitud_promedio_parrafos
def calcular_promedio_longitud(texto):
# Tokenizadores de NLTK
sent_tokenizer = nltk.sent_tokenize
word_tokenizer = nltk.word_tokenize
# Tokenizar oraciones
oraciones = sent_tokenizer(texto)
# Dividir en párrafos ignorando líneas vacías
parrafos = [p for p in texto.split('\n') if p.strip()]
# Calcular longitudes promedio
longitud_promedio_oraciones = sum(len(word_tokenizer(oracion)) for oracion in oraciones) / len(oraciones)
longitud_promedio_parrafos = sum(len(word_tokenizer(parrafo)) for parrafo in parrafos) / len(parrafos)
return longitud_promedio_oraciones, longitud_promedio_parrafos
def contar_palabras_conectoras(texto):
tokens = nltk.word_tokenize(texto)
palabras_conectoras = ['que', 'porque', 'aunque', 'si', 'cuando', 'mientras', 'como', 'para', 'después', 'antes', 'por', 'según', 'así', 'aun', 'sin', 'con', 'sino', 'en']
palabras_encontradas = [palabra for palabra in tokens if palabra in palabras_conectoras]
cantidad_palabras = len(palabras_encontradas)
valor_subordinacion = cantidad_palabras/len(tokens)
return valor_subordinacion,len(tokens)
def calcular_nota_estilo(valor_subordinacion, LongitudX_oraciones, LongitudX_parrafos):
nota_estilo = 1
if 0.06 <= valor_subordinacion <= 0.12:
nota_estilo += 2
elif 0.03 <= valor_subordinacion <= 0.18:
nota_estilo += 1
elif 0.015 <= valor_subordinacion <= 0.27:
nota_estilo += 0.5
if 10 <= LongitudX_oraciones <= 24:
nota_estilo += 2
elif 15 <= LongitudX_oraciones <= 36:
nota_estilo += 1
elif 8.5 <= LongitudX_oraciones <= 54:
nota_estilo += 0.5
if 50 <= LongitudX_parrafos <= 150:
nota_estilo += 2
elif 35 <= LongitudX_parrafos <= 200:
nota_estilo += 1
elif 25 <= LongitudX_parrafos <= 400:
nota_estilo += 0.5
return nota_estilo
#def TranslateENVIAR(question):
# translator = Translator()
# translation = translator.translate(question, dest="en")
# Len_Ori=translation.src
# questionTR=translation.text
# return questionTR,Len_Ori
#def TranslateRECIBIR(answerTR,Len_Ori):
# translator = Translator()
# translation = translator.translate(answerTR, dest=Len_Ori)
# respuesta=translation.text
# return respuesta
def TranslateENVIAR(question):
try:
translator = Translator()
translation = translator.translate(question, dest="en") # Ejecuta de forma síncrona
Len_Ori = translation.src # Detecta idioma de origen
questionTR = translation.text # Traducción al inglés
return questionTR, Len_Ori
except Exception as e:
print(f"Error en TranslateENVIAR: {e}")
return None, None
def TranslateRECIBIR(answerTR, Len_Ori):
try:
translator = Translator()
translation = translator.translate(answerTR, dest=Len_Ori) # Ejecuta de forma síncrona
respuesta = translation.text # Traducción de vuelta al idioma original
return respuesta
except Exception as e:
print(f"Error en TranslateRECIBIR: {e}")
return None
def generar_texto_AIDA(prompt_en):
messages = [
{"role": "system", "content": "You are using the AIDA methodology."\
"You must analyze a text by categorizing each sentence in its entirety. Each sentence must have a category. Use the '[Category]: Sentence' format for classification."\
"example '[Action]: invest in us' The categories and their descriptions are as follows:"\
"Attraction: Draws attention."\
"Interest: Maintains interest."\
"Desire: Generates desire."\
"Action: Guide towards an action."\
"None: Has no purpose "},
{"role": "system", "content":"You must make sure that each sentence, without missing any, has been classified"},
{"role": "user", "content": prompt_en}
]
response = openai.ChatCompletion.create(model="gpt-4o-mini", messages=messages)
#response = openai.ChatCompletion.create(model="gpt-4", messages=messages)
textoAIDA = response["choices"][0]["message"]["content"]
return textoAIDA
def generar_texto_NACBE(prompt_en):
messages = [
{"role": "system", "content": "You are using the NACB+E methodology."\
"You must analyze a text by categorizing each sentence in its entirety. Each sentence must have a category. Use the '[Category]: Sentence' format for classification."\
"example '[Other]:invest in us' The categories and their descriptions are as follows:"\
"Need: Identify the problem."\
"Approach: Propose and/or describe the solution"\
"Competition: Compare with other solutions or describe technical or commercial advantages such as a patent."\
"Benefit: Highlight the benefits."\
"Team: Introduce the team."\
"Other: Greetings, farewells or other information that is not from the previous categories."},
{"role": "system", "content":"You must make sure that each sentence, without missing any, has been classified"},
{"role": "user", "content": prompt_en}
]
response = openai.ChatCompletion.create(model="gpt-4o-mini", messages=messages)
#response = openai.ChatCompletion.create(model="gpt-4", messages=messages)
textoNACBE = response["choices"][0]["message"]["content"]
return textoNACBE
def generar_texto_Consejos(estadisticas):
messages = [
{"role": "system", "content": "Eres un experto en comunicación efectiva y pitch de innovación para audiencias empresariales"\
"Recibirás un análisis estructurado de un pitch, incluyendo métricas como duración estimada, estilo, cantidad de palabras, "\
"distribución según modelos NACBE y AIDA, y puntuaciones globales. Tu tarea es entregar una crítica constructiva breve y accionable"\
" enfocada en mejorar el pitch dentro de los límites dados. La meta no es alcanzar la nota máxima (7.0), sino llegar a una"\
" nota 5 o superior con una estructura balanceada. Prioriza lo que más impacta: mejora en las secciones con bajo porcentaje "\
"(por ejemplo: Team o Competition en NACBE, o Action en AIDA). Sugiere frases, reordenamientos o ideas que puedan insertarse "\
"sin alargar el pitch más de 15 segundos. Sé claro, directo, y evita la repetición innecesaria."},
#asdasd
{"role": "user", "content": estadisticas}
]
response = openai.ChatCompletion.create(model="gpt-4o-mini", messages=messages)
#response = openai.ChatCompletion.create(model="gpt-4", messages=messages)
textoConsejos = response["choices"][0]["message"]["content"]
return textoConsejos
class TextClassifierNACBE:
def __init__(self):
self.classifications = ["Need", "Approach", "Competition", "Benefit", "Team", "Other"]
self.category_lists = {classification: [] for classification in self.classifications}
self.classification_order = []
self.word_counts = defaultdict(int)
self.letter_counts = defaultdict(int)
def classify_text(self, text):
lines = text.split('\n')
pattern = r'\[(.*?)\]'
for line in lines:
classification_match = re.search(pattern, line)
if classification_match:
classification = classification_match.group(1)
sentence = line.split("]")[1].strip()
if classification in self.classifications:
self.category_lists[classification].append(sentence)
self.classification_order.append(classification)
self.word_counts[classification] += len(sentence.split())
self.letter_counts[classification] += len(sentence)
def get_results(self):
resultsNACBE = {
"Orden": ", ".join(self.classification_order),
"Palabras en Need": self.word_counts["Need"],
"Palabras en Approach": self.word_counts["Approach"],
"Palabras en Competition": self.word_counts["Competition"],
"Palabras en Benefit": self.word_counts["Benefit"],
"Palabras en Team": self.word_counts["Team"],
"Palabras en Other": self.word_counts["Other"]
}
return resultsNACBE
def plot_word_distributionNACBE(classifier):
results = classifier.get_results()
words_per_category = [
results["Palabras en Need"],
results["Palabras en Approach"],
results["Palabras en Competition"],
results["Palabras en Benefit"],
results["Palabras en Team"],
results["Palabras en Other"]
]
categories = ["Necesidad", "Aproximación", "Competencia", "Beneficio", "Equipo", "Otros"]
plt.figure(figsize=(8, 8))
plt.pie(words_per_category, labels=categories, autopct='%1.1f%%', startangle=140)
plt.title("Distribución de palabras por categoría")
plt.axis('equal')
plt.show()
class TextClassifierAIDA:
def __init__(self):
self.classifications = ["Attraction", "Interest", "Desire", "Action", "None"]
self.category_lists = {classification: [] for classification in self.classifications}
self.classification_order = []
self.word_counts = defaultdict(int)
self.letter_counts = defaultdict(int)
def classify_text(self, text):
lines = text.split('\n')
pattern = r'\[(.*?)\]'
for line in lines:
classification_match = re.search(pattern, line)
if classification_match:
classification = classification_match.group(1)
sentence = line.split("]")[1].strip()
if classification in self.classifications:
self.category_lists[classification].append(sentence)
self.classification_order.append(classification)
self.word_counts[classification] += len(sentence.split())
self.letter_counts[classification] += len(sentence)
def get_results(self):
resultsAIDA = {
"Orden": ", ".join(self.classification_order),
"Palabras en Attraction": self.word_counts["Attraction"],
"Palabras en Interest": self.word_counts["Interest"],
"Palabras en Desire": self.word_counts["Desire"],
"Palabras en Action": self.word_counts["Action"],
"Palabras en None": self.word_counts["None"],
}
return resultsAIDA
def calcular_porcentaje_palabras(palabras_en_categorias):
total_palabras = sum(valor for clave, valor in palabras_en_categorias.items() if isinstance(valor, int))
porcentaje_categorias = {}
for categoria, palabras in palabras_en_categorias.items():
if isinstance(palabras, int):
porcentaje = (palabras / total_palabras) * 100
porcentaje_categorias[categoria] = porcentaje
return porcentaje_categorias
def transformar_formato(diccionario_original):
resultado_transformado = {}
total_porcentaje = 0
for clave, valor in diccionario_original.items():
categoria = clave.replace('Palabras en ', '')
resultado_transformado[categoria] = f'{valor:.2f}%'
total_porcentaje += valor
if total_porcentaje != 0:
for categoria, porcentaje in resultado_transformado.items():
porcentaje_decimal = float(porcentaje.rstrip('%'))
resultado_transformado[categoria] = f'{(porcentaje_decimal / total_porcentaje * 100):.2f}%'
return resultado_transformado
data_aida = {
"Empresarios": ["Attraction: 20%", "Interest: 15%", "Desire: 20%", "Action: 25%", "None: 20%"],
"Organizaciones Sociales": ["Attraction: 15%", "Interest: 20%", "Desire: 20%", "Action: 20%", "None: 25%"],
"el Gobierno": ["Attraction: 10%", "Interest: 20%", "Desire: 25%", "Action: 20%", "None: 25%"],
"el Público en General": ["Attraction: 20%", "Interest: 15%", "Desire: 20%", "Action: 25%", "None: 20%"],
"Investigadores": ["Attraction: 20%", "Interest: 20%", "Desire: 20%", "Action: 25%", "None: 20%"],
"Inversionistas Ángeles": ["Attraction: 15%", "Interest: 15%", "Desire: 25%", "Action: 30%", "None: 15%"],
"Gestores Tecnológicos": ["Attraction: 15%", "Interest: 25%", "Desire: 15%", "Action: 20%", "None: 20%"],
"Reclutamiento de Personas al Equipo": ["Attraction: 20%", "Interest: 10%", "Desire: 20%", "Action: 30%", "None: 20%"],
"Publicidad": ["Attraction: 15%", "Interest: 20%", "Desire: 20%", "Action: 25%", "None: 20%"]
}
df_aida = pd.DataFrame(data_aida)
data_nacb = {
"Empresarios": ["Need: 15%", "Approach: 20%", "Competition: 15%", "Benefit: 20%", "Team: 15%", "Other: 15%"],
"Organizaciones Sociales": ["Need: 25%", "Approach: 15%", "Competition: 15%", "Benefit: 25%", "Team: 10%", "Other: 10%"],
"el Gobierno": ["Need: 20%", "Approach: 10%", "Competition: 25%", "Benefit: 15%", "Team: 15%", "Other: 15%"],
"el Público en General": ["Need: 15%", "Approach: 20%", "Competition: 10%", "Benefit: 20%", "Team: 20%", "Other: 15%"],
"Investigadores": ["Need: 20%", "Approach: 15%", "Competition: 15%", "Benefit: 20%", "Team: 15%", "Other: 15%"],
"Inversionistas Ángeles": ["Need: 15%", "Approach: 15%", "Competition: 20%", "Benefit: 25%", "Team: 15%", "Other: 10%"],
"Gestores Tecnológicos": ["Need: 10%", "Approach: 20%", "Competition: 25%", "Benefit: 20%", "Team: 15%", "Other: 10%"],
"Reclutamiento de Personas al Equipo": ["Need: 10%", "Approach: 20%", "Competition: 10%", "Benefit: 20%", "Team: 30%", "Other: 10%"],
"Publicidad": ["Need: 20%", "Approach: 15%", "Competition: 15%", "Benefit: 20%", "Team: 15%", "Other: 15%"]
}
df_nacb = pd.DataFrame(data_nacb)
audiencias = [
"Empresarios",
"Organizaciones Sociales",
"el Gobierno",
"el Público en General",
"Investigadores",
"Inversionistas Ángeles",
"Gestores Tecnológicos",
"Reclutamiento de Personas al Equipo",
"Publicidad"
]
def audiencia(df, grupo):
if grupo in df:
data = df[grupo].apply(lambda x: str(x).split(':'))
result = {entry[0].strip(): entry[1].strip() for entry in data}
return result
else:
return None
def formatear_porcentaje(porcentaje):
return f"{porcentaje:.2f}%"
def calcular_puntuacion_porcentajes(porcentajes_categorias, tablas, constante):
puntuacion = 0
for categoria, porcentaje in porcentajes_categorias.items():
if categoria in tablas:
porcentaje_tabla = float(tablas[categoria].replace('%', ''))
porcentaje = float(porcentaje.replace('%', ''))
if abs(porcentaje - porcentaje_tabla) <= 3.5:
puntuacion += 1
elif abs(porcentaje - porcentaje_tabla) <= 4.0:
puntuacion += 0.8
elif abs(porcentaje - porcentaje_tabla) <= 4.5:
puntuacion += 0.6
elif abs(porcentaje - porcentaje_tabla) <= 5.0:
puntuacion += 0.55
elif abs(porcentaje - porcentaje_tabla) <= 6.0:
puntuacion += 0.5
elif abs(porcentaje - porcentaje_tabla) <= 7.0:
puntuacion += 0.45
elif abs(porcentaje - porcentaje_tabla) <= 8.0:
puntuacion += 0.4
elif abs(porcentaje - porcentaje_tabla) <= 9.0:
puntuacion += 0.35
elif abs(porcentaje - porcentaje_tabla) <= 10.0:
puntuacion += 0.3
puntuacion = puntuacion * constante
puntuacion = puntuacion + 1
return puntuacion
def evaluar_puntuaciones(puntuacionAIDA, puntuacionNACBE, estilo_nota):
promedio = (puntuacionAIDA + puntuacionNACBE + estilo_nota) / 3
if 1 <= promedio < 3:
mensaje = "Hay mucho trabajo por hacer"
elif 3 <= promedio < 4:
mensaje = "Aún no aceptable"
elif 4 <= promedio < 5:
mensaje = "Ya es un buen pitch"
elif 5 <= promedio < 6:
mensaje = "Fantástico! es un magnifico Guión"
elif 6 <= promedio <= 7:
mensaje = "Impresionante! Estás capacitado para escribir pitch en concursos internacionales, felicidades"
else:
mensaje = "Puntuación fuera de rango"
return mensaje,promedio
def Preguntas(prompt):
messages = [
{"role": "system", "content": "Debes asumir el rol de un experto en negocios tecnologicos, a continuación se te presenta un Pitch."\
"Como juez debes formular 5 preguntas, enfocandote en aquello que no quede del todo claro o sea más interesante de profundizar."\
"Tambien seria bueno si dieras un par de consejos"},
{"role": "user", "content": prompt}
]
response = openai.ChatCompletion.create(model="gpt-4o-mini", messages=messages)
#response = openai.ChatCompletion.create(model="gpt-4", messages=messages)
PreguntasPrompt = response["choices"][0]["message"]["content"]
return PreguntasPrompt
def gradio_ini(prompt,Audiencia):
valor_subordinacion, cantidad_palabras = contar_palabras_conectoras(prompt)
LongitudX_oraciones, LongitudX_parrafos = calcular_promedio_longitud(prompt)
Tiempo_discurso_max=cantidad_palabras/100
Tiempo_discurso_min=cantidad_palabras/200
Tiempo_discurso_optimo=cantidad_palabras/170
estilo_nota = calcular_nota_estilo(valor_subordinacion, LongitudX_oraciones, LongitudX_parrafos)
#prompt_en,Len_Ori = TranslateENVIAR(prompt)
#textoAIDA = generar_texto_AIDA(prompt_en)
#textoNACBE = generar_texto_NACBE(prompt_en)
textoAIDA = generar_texto_AIDA(prompt)
textoNACBE = generar_texto_NACBE(prompt)
aida_classifier = TextClassifierAIDA()
aida_classifier.classify_text(textoAIDA)
aida_results = aida_classifier.get_results()
nacbe_classifier = TextClassifierNACBE()
nacbe_classifier.classify_text(textoNACBE)
nacbe_results = nacbe_classifier.get_results()
porcentajes_categoriasAIDA = calcular_porcentaje_palabras(aida_results)
porcentajes_categoriasNACBE = calcular_porcentaje_palabras(nacbe_results)
porcentajes_categoriasFIXAIDA = transformar_formato(porcentajes_categoriasAIDA)
porcentajes_categoriasFIXNACBE = transformar_formato(porcentajes_categoriasNACBE)
resultadoAIDA = audiencia(df_aida, Audiencia)
resultadoNACB = audiencia(df_nacb, Audiencia)
porcentaje_categorias_formateadoNACBE = ', '.join([f"{clave.replace('Palabras en ', '')}: {formatear_porcentaje(valor)}" for clave, valor in porcentajes_categoriasNACBE.items()])
porcentaje_categorias_formateadoAIDA = ', '.join([f"{clave.replace('Palabras en ', '')}: {formatear_porcentaje(valor)}" for clave, valor in porcentajes_categoriasAIDA.items()])
puntuacionNACBE = calcular_puntuacion_porcentajes(porcentajes_categoriasFIXNACBE, resultadoNACB, 6/6)
puntuacionAIDA = calcular_puntuacion_porcentajes(porcentajes_categoriasFIXAIDA, resultadoAIDA, 6/5)
mensaje,promedio=evaluar_puntuaciones(puntuacionAIDA, puntuacionNACBE, estilo_nota)
resultado = f"este discurso te tomará entre {Tiempo_discurso_min:.2f} min y {Tiempo_discurso_max:.2f} min. Un orador con experiencia lo hará en {Tiempo_discurso_optimo:.2f} min.\n" \
f"La nota de estilo es de {estilo_nota:.2f}.\n" \
f"Valor subordinación (0.06 a 0.12): {valor_subordinacion:.4f}, cantidad de palabras: {cantidad_palabras}.\n" \
f"Longitud promedio de oraciones (10 a 24): {LongitudX_oraciones:.2f}; y de párrafos (50 a 150): {LongitudX_parrafos}.\n" \
f"La audiencia es {Audiencia}.\n" \
f"Debería tener una composición de NACBE: {resultadoNACB} ±2.5.\n" \
f"En el texto se tiene: {porcentaje_categorias_formateadoNACBE}.\n" \
f"Debería tener una composición de AIDA: {resultadoAIDA} ±2.5.\n" \
f"En AIDA se tiene: {porcentaje_categorias_formateadoAIDA}.\n" \
f"Puntuación AIDA: {puntuacionAIDA}.\n" \
f"Puntuación NACBE: {puntuacionNACBE}.\n" \
f"Puntuación Estilo: {estilo_nota}.\n" \
f"Tienes una nota de {promedio:.2f}, {mensaje}."
resultado_NACBE = f"Texto NABCE: {textoNACBE}"
resultado_AIDA = f"Texto AIDA: {textoAIDA}"
textoConsejos=generar_texto_Consejos(resultado)
return resultado, resultado_AIDA,resultado_NACBE,textoConsejos
########################## Frontend
opciones_audiencia = [
"Empresarios",
"Organizaciones Sociales",
"el Gobierno",
"el Público en General",
"Investigadores",
"Inversionistas Ángeles",
"Gestores Tecnológicos",
"Reclutamiento de Personas al Equipo",
"Publicidad"
]
# Código CSS para personalizar estilos
css_code = '''
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
position: relative;
font-family: Arial, sans-serif;
background-color: #f4f4f4;
}
.background-video {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover; /* <-- Hace que el video siempre cubra todo */
z-index: 0;
filter: brightness(50%);
}
.z-index-1 {
z-index: 1 !important;
position: relative;
}
.images-container {
display: flex;
justify-content: space-between;
align-items: center;
width: 80%;
margin: 20px auto;
}
.image-item {
max-width: 30%;
height: auto;
border-radius: 10px;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.3);
}
.gr-textbox {
font-size: 0.5rem !important; /* Tamaño del texto en los cuadros */
}
.gr-textbox textarea {
height: 150px !important; /* Altura de los cuadros */
}
.gradio-container h1 {
font-size: 2rem !important; /* Agranda título */
color: #ffffff;
text-shadow: 2px 2px 4px #000000;
text-align: center;
}
.gradio-container p {
font-size: 1.2rem !important; /* Agranda la descripción */
color: #ffffff;
text-shadow: 1px 1px 2px #000000;
text-align: center; /* Centrar descripción */
margin: 20px auto;
max-width: 80%; /* Para que no se estire demasiado en pantallas grandes */
}
.gr-radio {
font-size: 0.8rem !important; /* Cambia el tamaño de las letras en las opciones */
}
.gr-button {
font-size: 0.5rem !important; /* Cambia el tamaño del botón */
}
#audiencia-radio label {
font-size: 0.8rem !important; /* Cambia el tamaño de las etiquetas */
color: orange !important; /* Aplica color naranja a las etiquetas */
}
#audiencia-radio .gr-radio {
font-size: 0.3rem !important; /* Cambia el tamaño de las letras en las opciones */
color: orange !important; /* Cambia las opciones a color naranja */
}
'''
title = 'ACECHO : PitchTrainer (Versión beta)'
description = """Asesor de comunicación, evaluador de contenidos y habilidades de oratoria. Puedes obtener estadísticas de tus discursos/pitch/postulaciones ;)"""
with gr.Blocks(css=css_code) as demo:
gr.HTML('<video class="background-video" autoplay loop muted><source src="https://cdn.pixabay.com/video/2024/06/19/217392_large.mp4" type="video/mp4"></video>')
gr.Markdown(f'<center><h1>{title}</h1></center>')
gr.Markdown(description)
# Contenedor de imágenes
gr.HTML(
'<div class="images-container">'
'<img src="https://fciencia.usach.cl/sites/fciencia/files/fciencia.png" class="image-item z-index-1">'
'<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSoYjmZ49DDLSOcc0DqwtHxDsf2cEZsC1Ysgg&s" class="image-item z-index-1">'
'<img src="https://www.quimicaybiologia.usach.cl/sites/quimica/files/qyb.png" class="image-item z-index-1">'
'</div>'
)
with gr.Row():
with gr.Column():
gr.Markdown(f'<p style="text-align:center">Si deseas participar y recibir ayuda en la formulación, escribe a <a href="mailto:Franco.lisboa@usach.cl">Franco Lisboa</a> </p>')
Audiencia = gr.Radio(opciones_audiencia, label="¿Quién es el oyente?", info="Elige una opción",elem_id="audiencia-radio")
prompt = gr.Textbox(label='Texto acá', lines=4)
btn = gr.Button(value='Submit')
with gr.Row():
resultado_AIDA = gr.Textbox(label='Resultado AIDA:', lines=10)
resultado_NACBE = gr.Textbox(label='Resultado NACBE:', lines=10)
resultado = gr.Textbox(label='Tus estadísticas:', lines=10)
textoConsejos = gr.Textbox(label='Tus Consejos:', lines=10)
btn.click(gradio_ini, inputs=[prompt, Audiencia], outputs=[resultado, resultado_AIDA, resultado_NACBE, textoConsejos])
demo.launch(share=True, debug=True)