Arthur-Attili commited on
Commit
057b5b2
·
verified ·
1 Parent(s): b95c8f9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +111 -16
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import pandas as pd
2
  import requests
3
  import io
@@ -5,68 +6,99 @@ import itertools
5
  from collections import defaultdict
6
  import gradio as gr
7
 
8
- # 🔧 CONFIGURAÇÕES
9
  FILE_ID = "1XvNz7DlWioT64uNdcfBSL8Ui2nRSi9gT"
10
  URL = f"https://drive.google.com/uc?export=download&id={FILE_ID}"
 
 
11
  df = None
12
  df_imovel = None
13
  grupos_imovel = None
14
  planilha_carregada = False
15
 
16
  def carregar_planilha():
 
17
  global df, df_imovel, grupos_imovel, planilha_carregada
 
18
  if planilha_carregada:
19
  return True
 
20
  try:
21
  print("⏳ Carregando planilha...")
22
  response = requests.get(URL)
23
  response.raise_for_status()
24
  data = io.BytesIO(response.content)
25
  df = pd.read_excel(data)
 
 
26
  df.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
 
 
27
  colunas_numericas = ['valor_credito', 'valor_entrada', 'valor_parcela', 'saldo_devedor', 'qtd_parcelas']
28
  for coluna in colunas_numericas:
29
  if coluna in df.columns:
30
  df[coluna] = pd.to_numeric(df[coluna], errors='coerce').fillna(0)
 
 
31
  if 'tipo_do_bem' not in df.columns or 'administradora' not in df.columns:
32
  raise ValueError("Colunas essenciais não encontradas")
 
33
  df.drop_duplicates(inplace=True)
 
 
34
  df_imovel = df[df['tipo_do_bem'].str.lower() == 'imovel'].copy()
35
  grupos_imovel = agrupar_por_administradora(df_imovel)
 
36
  planilha_carregada = True
37
- print("✅ Planilha carregada")
 
 
38
  return True
 
39
  except Exception as e:
40
- print(f"❌ Erro: {str(e)}")
41
  return False
42
 
 
43
  def agrupar_por_administradora(dataframe):
 
44
  grupos = defaultdict(list)
45
  for _, row in dataframe.iterrows():
46
  grupos[row['administradora']].append(row.to_dict())
47
  return grupos
48
 
 
49
  def formatar_moeda(valor):
50
  return f"R$ {valor:,.2f}".replace(",", "v").replace(".", ",").replace("v", ".")
51
 
 
52
  def calcular_tempo_parcelas(combinacao):
 
53
  if not combinacao:
54
  return ""
 
55
  try:
56
  cotas_ordenadas = sorted(combinacao, key=lambda x: int(x.get('qtd_parcelas', 0)))
57
  prazos = sorted(set(int(c.get('qtd_parcelas', 0)) for c in combinacao))
 
58
  if not prazos or prazos[0] <= 0:
59
  return ""
 
60
  resultado = []
61
  prazo_anterior = 0
 
62
  for prazo_atual in prazos:
63
  cotas_ativas = [c for c in cotas_ordenadas if int(c.get('qtd_parcelas', 0)) >= prazo_anterior + 1]
64
  valor_parcela_total = sum(c.get('valor_parcela', 0) for c in cotas_ativas)
 
65
  inicio = prazo_anterior + 1
66
  fim = prazo_atual
 
67
  if inicio <= fim and valor_parcela_total > 0:
68
  resultado.append(f"{inicio}x à {fim}x: {formatar_moeda(valor_parcela_total)}/mês")
 
69
  prazo_anterior = prazo_atual
 
70
  if prazos and prazo_anterior < max(prazos):
71
  cotas_ativas_finais = [c for c in cotas_ordenadas if int(c.get('qtd_parcelas', 0)) > prazo_anterior]
72
  if cotas_ativas_finais:
@@ -75,78 +107,126 @@ def calcular_tempo_parcelas(combinacao):
75
  fim_final = max(prazos)
76
  if valor_parcela_final > 0:
77
  resultado.append(f"{inicio_final}x à {fim_final}x: {formatar_moeda(valor_parcela_final)}/mês")
 
78
  return "\\n".join(resultado) if resultado else ""
 
79
  except Exception as e:
80
- print(f"❌ Erro ao calcular tempo: {str(e)}")
81
  return ""
82
 
 
83
  def definir_margens_absolutas(credito_desejado, entrada_desejada, parcela_desejada):
84
- margem_credito = 40000
85
- margem_entrada = 10000
86
- margem_parcela = 1000
 
 
 
87
  credito_min = max(0, credito_desejado - margem_credito)
88
  credito_max = credito_desejado + margem_credito
 
89
  entrada_min = max(0, entrada_desejada - margem_entrada)
90
  entrada_max = entrada_desejada + margem_entrada
 
91
  parcela_min = max(0, parcela_desejada - margem_parcela)
92
  parcela_max = parcela_desejada + margem_parcela
 
93
  return credito_min, credito_max, entrada_min, entrada_max, parcela_min, parcela_max
94
 
 
95
  def filtrar_cotas_por_faixa(cotas, credito_min, credito_max):
 
96
  return [c for c in cotas if c['valor_credito'] < credito_max * 2]
97
 
 
98
  def buscar_combinacoes_otimizado(credito_desejado, entrada_desejada, parcela_desejada, administradoras=None, max_combinacoes=15):
 
99
  global df_imovel, grupos_imovel
 
100
  if not planilha_carregada:
101
  if not carregar_planilha():
102
- return "❌ Erro: Planilha não carregada."
 
 
103
  if administradoras and len(administradoras) > 0:
104
  grupos_filtrados = {adm: cotas for adm, cotas in grupos_imovel.items() if adm in administradoras}
105
  else:
106
  grupos_filtrados = grupos_imovel
 
107
  if not grupos_filtrados:
108
- return "🚫 Nenhuma cota encontrada com os filtros aplicados."
 
 
 
 
109
  credito_min, credito_max, entrada_min, entrada_max, parcela_min, parcela_max = definir_margens_absolutas(
110
  credito_desejado, entrada_desejada, parcela_desejada
111
  )
 
 
 
 
 
112
  max_cotas_combinacao = 15
113
- max_combinacoes_por_adm = 4000
 
114
  resultados = []
115
  total_combinacoes_testadas = 0
 
116
  for adm, cotas in grupos_filtrados.items():
 
 
117
  cotas_filtradas = filtrar_cotas_por_faixa(cotas, credito_min, credito_max)
 
118
  for r in range(1, min(max_cotas_combinacao + 1, len(cotas_filtradas) + 1)):
119
  combinacoes_geradas = 0
120
  for combinacao in itertools.combinations(cotas_filtradas, r):
121
  if combinacoes_geradas >= max_combinacoes_por_adm:
122
  break
 
123
  total_combinacoes_testadas += 1
124
  combinacoes_geradas += 1
 
125
  total_credito = sum(c['valor_credito'] for c in combinacao)
126
  total_entrada_base = sum(c['valor_entrada'] for c in combinacao)
127
  total_entrada = total_entrada_base + (total_credito * 0.085)
128
  total_parcelas = sum(c['valor_parcela'] for c in combinacao)
 
 
129
  if (credito_min <= total_credito <= credito_max and
130
  entrada_min <= total_entrada <= entrada_max and
131
  parcela_min <= total_parcelas <= parcela_max):
 
132
  total_saldo = sum(c['saldo_devedor'] for c in combinacao)
133
  valor_final = round(total_entrada + total_saldo, 2)
134
  diferenca = abs(valor_final - total_credito)
 
135
  resultados.append((adm, combinacao, diferenca))
 
136
  if len(resultados) >= max_combinacoes * 2:
137
  break
 
138
  if len(resultados) >= max_combinacoes * 2:
139
  break
 
140
  if len(resultados) >= max_combinacoes * 2:
141
  break
 
 
 
 
142
  if not resultados:
143
- return "🚫 Nenhuma combinação adequada encontrada."
144
- resultados.sort(key=lambda x: x[2])
 
145
  return formatar_resultados(resultados[:max_combinacoes])
146
 
 
147
  def formatar_resultados(resultados):
 
148
  if not resultados:
149
- return "🚫 Nenhuma combinação adequada encontrada."
 
150
  resposta = ""
151
  for idx, (adm, combinacao, _) in enumerate(resultados, 1):
152
  codigos = [str(c.get('codigo', 'N/A')) for c in combinacao]
@@ -156,12 +236,15 @@ def formatar_resultados(resultados):
156
  total_saldo = sum(c['saldo_devedor'] for c in combinacao)
157
  total_parcelas = sum(c['valor_parcela'] for c in combinacao)
158
  maior_prazo = max(int(c.get('qtd_parcelas', 0)) for c in combinacao)
 
159
  valor_final = round(total_entrada + total_saldo, 2)
160
  credito_real = round(total_credito - total_entrada, 2)
161
  taxa_total = total_saldo - credito_real
162
  taxa_percentual = (taxa_total / credito_real) * 100 if credito_real > 0 else 0
163
  taxa_mensal = taxa_percentual / maior_prazo if maior_prazo > 0 else 0
 
164
  tempo_parcelas = calcular_tempo_parcelas(combinacao)
 
165
  resposta += f"""
166
  --- COMBINAÇÃO {idx} ---
167
  🏢 Administradora: {adm}
@@ -181,8 +264,11 @@ def formatar_resultados(resultados):
181
  """
182
  return resposta
183
 
 
 
184
  carregar_planilha()
185
 
 
186
  def ajustar_e_buscar(credito_desejado, entrada_desejada, parcela_desejada, administradoras):
187
  return buscar_combinacoes_otimizado(
188
  float(credito_desejado or 0),
@@ -192,12 +278,15 @@ def ajustar_e_buscar(credito_desejado, entrada_desejada, parcela_desejada, admin
192
  max_combinacoes=15
193
  )
194
 
 
195
  def get_administradoras_options():
196
  if df is not None and planilha_carregada:
197
  adm_list = df[df['tipo_do_bem'].str.lower() == 'imovel']['administradora'].unique()
198
  return sorted(adm_list)
199
  return []
200
 
 
 
201
  with gr.Blocks(title="Sistema de Busca de Consórcio Imóvel") as demo:
202
  gr.HTML("""
203
  <link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
@@ -221,27 +310,33 @@ with gr.Blocks(title="Sistema de Busca de Consórcio Imóvel") as demo:
221
  .gr-button:hover { background-color: #fff3e0 !important; }
222
  </style>
223
  """)
 
224
  gr.Markdown("# 🏠 Busca de Combinações de Consórcio Imóvel")
225
  gr.Markdown("Insira os valores desejados para crédito, entrada e parcela, e filtre por administradora.")
 
226
  with gr.Row():
227
  credito_input = gr.Number(label="Crédito Desejado (R$)", value=300000, step=1000)
228
  entrada_input = gr.Number(label="Entrada Desejada (R$)", value=30000, step=1000)
229
  parcela_input = gr.Number(label="Parcela Desejada (R$)", value=1500, step=100)
 
230
  administradoras_multiselect = gr.CheckboxGroup(
231
  label="Filtrar por Administradoras",
232
  choices=get_administradoras_options(),
233
  value=get_administradoras_options()
234
  )
 
235
  submit_btn = gr.Button("🔍 Buscar Combinações", variant="primary")
236
  output_text = gr.Textbox(label="Resultados da Busca", lines=20, max_lines=40, interactive=False, placeholder="Os resultados aparecerão aqui...")
 
237
  submit_btn.click(
238
  fn=ajustar_e_buscar,
239
  inputs=[credito_input, entrada_input, parcela_input, administradoras_multiselect],
240
- outputs=output_text,
241
- api_name="buscar" # ← ENDPOINT CUSTOMIZADO
242
  )
 
243
  gr.Markdown("---")
244
  gr.Markdown("Desenvolvido para auxiliar na busca por cotas de consórcio ideais.")
245
 
246
  if __name__ == "__main__":
247
- demo.launch(api_open=True) # ← API ATIVADA
 
 
1
+ # app.py - VERSÃO COM MARGEM ABSOLUTA FIXA
2
  import pandas as pd
3
  import requests
4
  import io
 
6
  from collections import defaultdict
7
  import gradio as gr
8
 
9
+ # 🔧 CONFIGURAÇÕES GLOBAIS
10
  FILE_ID = "1XvNz7DlWioT64uNdcfBSL8Ui2nRSi9gT"
11
  URL = f"https://drive.google.com/uc?export=download&id={FILE_ID}"
12
+
13
+ # Variáveis globais para armazenamento
14
  df = None
15
  df_imovel = None
16
  grupos_imovel = None
17
  planilha_carregada = False
18
 
19
  def carregar_planilha():
20
+ """Carrega e prepara a planilha para análise."""
21
  global df, df_imovel, grupos_imovel, planilha_carregada
22
+
23
  if planilha_carregada:
24
  return True
25
+
26
  try:
27
  print("⏳ Carregando planilha...")
28
  response = requests.get(URL)
29
  response.raise_for_status()
30
  data = io.BytesIO(response.content)
31
  df = pd.read_excel(data)
32
+
33
+ # Padroniza nomes das colunas
34
  df.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
35
+
36
+ # Colunas numéricas
37
  colunas_numericas = ['valor_credito', 'valor_entrada', 'valor_parcela', 'saldo_devedor', 'qtd_parcelas']
38
  for coluna in colunas_numericas:
39
  if coluna in df.columns:
40
  df[coluna] = pd.to_numeric(df[coluna], errors='coerce').fillna(0)
41
+
42
+ # Verifica colunas essenciais
43
  if 'tipo_do_bem' not in df.columns or 'administradora' not in df.columns:
44
  raise ValueError("Colunas essenciais não encontradas")
45
+
46
  df.drop_duplicates(inplace=True)
47
+
48
+ # Pré‑processa imóvel
49
  df_imovel = df[df['tipo_do_bem'].str.lower() == 'imovel'].copy()
50
  grupos_imovel = agrupar_por_administradora(df_imovel)
51
+
52
  planilha_carregada = True
53
+ print("✅ Planilha carregada e pré-processada com sucesso")
54
+ print(f"✅ Total de cotas de imóvel: {len(df_imovel)}")
55
+ print(f"✅ Administradoras disponíveis: {list(grupos_imovel.keys())}")
56
  return True
57
+
58
  except Exception as e:
59
+ print(f"❌ Erro ao carregar planilha: {str(e)}")
60
  return False
61
 
62
+
63
  def agrupar_por_administradora(dataframe):
64
+ """Agrupa cotas por administradora."""
65
  grupos = defaultdict(list)
66
  for _, row in dataframe.iterrows():
67
  grupos[row['administradora']].append(row.to_dict())
68
  return grupos
69
 
70
+
71
  def formatar_moeda(valor):
72
  return f"R$ {valor:,.2f}".replace(",", "v").replace(".", ",").replace("v", ".")
73
 
74
+
75
  def calcular_tempo_parcelas(combinacao):
76
+ """Calcula o tempo de parcelas baseado nas cotas da combinação."""
77
  if not combinacao:
78
  return ""
79
+
80
  try:
81
  cotas_ordenadas = sorted(combinacao, key=lambda x: int(x.get('qtd_parcelas', 0)))
82
  prazos = sorted(set(int(c.get('qtd_parcelas', 0)) for c in combinacao))
83
+
84
  if not prazos or prazos[0] <= 0:
85
  return ""
86
+
87
  resultado = []
88
  prazo_anterior = 0
89
+
90
  for prazo_atual in prazos:
91
  cotas_ativas = [c for c in cotas_ordenadas if int(c.get('qtd_parcelas', 0)) >= prazo_anterior + 1]
92
  valor_parcela_total = sum(c.get('valor_parcela', 0) for c in cotas_ativas)
93
+
94
  inicio = prazo_anterior + 1
95
  fim = prazo_atual
96
+
97
  if inicio <= fim and valor_parcela_total > 0:
98
  resultado.append(f"{inicio}x à {fim}x: {formatar_moeda(valor_parcela_total)}/mês")
99
+
100
  prazo_anterior = prazo_atual
101
+
102
  if prazos and prazo_anterior < max(prazos):
103
  cotas_ativas_finais = [c for c in cotas_ordenadas if int(c.get('qtd_parcelas', 0)) > prazo_anterior]
104
  if cotas_ativas_finais:
 
107
  fim_final = max(prazos)
108
  if valor_parcela_final > 0:
109
  resultado.append(f"{inicio_final}x à {fim_final}x: {formatar_moeda(valor_parcela_final)}/mês")
110
+
111
  return "\\n".join(resultado) if resultado else ""
112
+
113
  except Exception as e:
114
+ print(f"❌ Erro ao calcular tempo de parcelas: {str(e)}")
115
  return ""
116
 
117
+
118
  def definir_margens_absolutas(credito_desejado, entrada_desejada, parcela_desejada):
119
+ """Define margens fixas em R$ para crédito, entrada e parcela."""
120
+ # Margens em R$ (ex.: 500.000 → 480.000–520.000)
121
+ margem_credito = 40_000
122
+ margem_entrada = 10_000
123
+ margem_parcela = 1_000
124
+
125
  credito_min = max(0, credito_desejado - margem_credito)
126
  credito_max = credito_desejado + margem_credito
127
+
128
  entrada_min = max(0, entrada_desejada - margem_entrada)
129
  entrada_max = entrada_desejada + margem_entrada
130
+
131
  parcela_min = max(0, parcela_desejada - margem_parcela)
132
  parcela_max = parcela_desejada + margem_parcela
133
+
134
  return credito_min, credito_max, entrada_min, entrada_max, parcela_min, parcela_max
135
 
136
+
137
  def filtrar_cotas_por_faixa(cotas, credito_min, credito_max):
138
+ """Filtra cotas que pelo menos têm chance de entrar na faixa de crédito."""
139
  return [c for c in cotas if c['valor_credito'] < credito_max * 2]
140
 
141
+
142
  def buscar_combinacoes_otimizado(credito_desejado, entrada_desejada, parcela_desejada, administradoras=None, max_combinacoes=15):
143
+ """Busca combinações de cotas dentro de margens fixas absolutas."""
144
  global df_imovel, grupos_imovel
145
+
146
  if not planilha_carregada:
147
  if not carregar_planilha():
148
+ return "❌ Erro: Planilha não carregada. Por favor, tente novamente."
149
+
150
+ # Filtra administradoras
151
  if administradoras and len(administradoras) > 0:
152
  grupos_filtrados = {adm: cotas for adm, cotas in grupos_imovel.items() if adm in administradoras}
153
  else:
154
  grupos_filtrados = grupos_imovel
155
+
156
  if not grupos_filtrados:
157
+ return "🚫 Nenhuma cota encontrada com os filtros aplicados. Tente ajustar os parâmetros."
158
+
159
+ print(f"🔍 Total de administradoras no filtro: {len(grupos_filtrados)}")
160
+
161
+ # Usa margens fixas em R$
162
  credito_min, credito_max, entrada_min, entrada_max, parcela_min, parcela_max = definir_margens_absolutas(
163
  credito_desejado, entrada_desejada, parcela_desejada
164
  )
165
+
166
+ print(f"💰 Valores desejados: Crédito: R$ {credito_desejado:,.2f}, Entrada: R$ {entrada_desejada:,.2f}, Parcela: R$ {parcela_desejada:,.2f}")
167
+ print(f"🔍 Margem de crédito: de R$ {credito_min:,.2f} até R$ {credito_max:,.2f}")
168
+
169
+ # Limites de busca
170
  max_cotas_combinacao = 15
171
+ max_combinacoes_por_adm = 4000 # para evitar explosão de combinações [web:12][web:18]
172
+
173
  resultados = []
174
  total_combinacoes_testadas = 0
175
+
176
  for adm, cotas in grupos_filtrados.items():
177
+ print(f"🔍 Analisando administradora: {adm} ({len(cotas)} cotas)")
178
+
179
  cotas_filtradas = filtrar_cotas_por_faixa(cotas, credito_min, credito_max)
180
+
181
  for r in range(1, min(max_cotas_combinacao + 1, len(cotas_filtradas) + 1)):
182
  combinacoes_geradas = 0
183
  for combinacao in itertools.combinations(cotas_filtradas, r):
184
  if combinacoes_geradas >= max_combinacoes_por_adm:
185
  break
186
+
187
  total_combinacoes_testadas += 1
188
  combinacoes_geradas += 1
189
+
190
  total_credito = sum(c['valor_credito'] for c in combinacao)
191
  total_entrada_base = sum(c['valor_entrada'] for c in combinacao)
192
  total_entrada = total_entrada_base + (total_credito * 0.085)
193
  total_parcelas = sum(c['valor_parcela'] for c in combinacao)
194
+
195
+ # Verifica margens fixas
196
  if (credito_min <= total_credito <= credito_max and
197
  entrada_min <= total_entrada <= entrada_max and
198
  parcela_min <= total_parcelas <= parcela_max):
199
+
200
  total_saldo = sum(c['saldo_devedor'] for c in combinacao)
201
  valor_final = round(total_entrada + total_saldo, 2)
202
  diferenca = abs(valor_final - total_credito)
203
+
204
  resultados.append((adm, combinacao, diferenca))
205
+
206
  if len(resultados) >= max_combinacoes * 2:
207
  break
208
+
209
  if len(resultados) >= max_combinacoes * 2:
210
  break
211
+
212
  if len(resultados) >= max_combinacoes * 2:
213
  break
214
+
215
+ print(f"🔍 Total de combinações testadas: {total_combinacoes_testadas}")
216
+ print(f"🔍 Combinações válidas encontradas: {len(resultados)}")
217
+
218
  if not resultados:
219
+ return "🚫 Nenhuma combinação adequada encontrada com os parâmetros fornecidos."
220
+
221
+ resultados.sort(key=lambda x: x[2]) # ordena pela menor diferença
222
  return formatar_resultados(resultados[:max_combinacoes])
223
 
224
+
225
  def formatar_resultados(resultados):
226
+ """Formata os resultados para exibição incluindo tempo de parcelas."""
227
  if not resultados:
228
+ return "🚫 Nenhuma combinação adequada encontrada com os parâmetros fornecidos."
229
+
230
  resposta = ""
231
  for idx, (adm, combinacao, _) in enumerate(resultados, 1):
232
  codigos = [str(c.get('codigo', 'N/A')) for c in combinacao]
 
236
  total_saldo = sum(c['saldo_devedor'] for c in combinacao)
237
  total_parcelas = sum(c['valor_parcela'] for c in combinacao)
238
  maior_prazo = max(int(c.get('qtd_parcelas', 0)) for c in combinacao)
239
+
240
  valor_final = round(total_entrada + total_saldo, 2)
241
  credito_real = round(total_credito - total_entrada, 2)
242
  taxa_total = total_saldo - credito_real
243
  taxa_percentual = (taxa_total / credito_real) * 100 if credito_real > 0 else 0
244
  taxa_mensal = taxa_percentual / maior_prazo if maior_prazo > 0 else 0
245
+
246
  tempo_parcelas = calcular_tempo_parcelas(combinacao)
247
+
248
  resposta += f"""
249
  --- COMBINAÇÃO {idx} ---
250
  🏢 Administradora: {adm}
 
264
  """
265
  return resposta
266
 
267
+
268
+ # Carrega a planilha uma vez quando o aplicativo inicia
269
  carregar_planilha()
270
 
271
+
272
  def ajustar_e_buscar(credito_desejado, entrada_desejada, parcela_desejada, administradoras):
273
  return buscar_combinacoes_otimizado(
274
  float(credito_desejado or 0),
 
278
  max_combinacoes=15
279
  )
280
 
281
+
282
  def get_administradoras_options():
283
  if df is not None and planilha_carregada:
284
  adm_list = df[df['tipo_do_bem'].str.lower() == 'imovel']['administradora'].unique()
285
  return sorted(adm_list)
286
  return []
287
 
288
+
289
+ # Interface Gradio
290
  with gr.Blocks(title="Sistema de Busca de Consórcio Imóvel") as demo:
291
  gr.HTML("""
292
  <link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
 
310
  .gr-button:hover { background-color: #fff3e0 !important; }
311
  </style>
312
  """)
313
+
314
  gr.Markdown("# 🏠 Busca de Combinações de Consórcio Imóvel")
315
  gr.Markdown("Insira os valores desejados para crédito, entrada e parcela, e filtre por administradora.")
316
+
317
  with gr.Row():
318
  credito_input = gr.Number(label="Crédito Desejado (R$)", value=300000, step=1000)
319
  entrada_input = gr.Number(label="Entrada Desejada (R$)", value=30000, step=1000)
320
  parcela_input = gr.Number(label="Parcela Desejada (R$)", value=1500, step=100)
321
+
322
  administradoras_multiselect = gr.CheckboxGroup(
323
  label="Filtrar por Administradoras",
324
  choices=get_administradoras_options(),
325
  value=get_administradoras_options()
326
  )
327
+
328
  submit_btn = gr.Button("🔍 Buscar Combinações", variant="primary")
329
  output_text = gr.Textbox(label="Resultados da Busca", lines=20, max_lines=40, interactive=False, placeholder="Os resultados aparecerão aqui...")
330
+
331
  submit_btn.click(
332
  fn=ajustar_e_buscar,
333
  inputs=[credito_input, entrada_input, parcela_input, administradoras_multiselect],
334
+ outputs=output_text
 
335
  )
336
+
337
  gr.Markdown("---")
338
  gr.Markdown("Desenvolvido para auxiliar na busca por cotas de consórcio ideais.")
339
 
340
  if __name__ == "__main__":
341
+ demo.launch()
342
+ #