Arthur-Attili commited on
Commit
131e309
·
verified ·
1 Parent(s): 4ecc33f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -15
app.py CHANGED
@@ -1,75 +1,104 @@
1
- # app.py - VERSÃO COM TRATAMENTO DE ERRO MELHORADO
2
  import pandas as pd
3
  import requests
4
  import io
5
  import itertools
6
  from collections import defaultdict
7
  import gradio as gr
8
- import os
9
 
10
  # 🔧 CONFIGURAÇÕES GLOBAIS
11
  FILE_ID = "1XvNz7DlWioT64uNdcfBSL8Ui2nRSi9gT"
12
  URL = f"https://drive.google.com/uc?export=download&id={FILE_ID}"
13
 
 
14
  df = None
15
  df_imovel = None
16
  grupos_imovel = None
17
  planilha_carregada = False
18
 
19
  def carregar_planilha():
 
20
  global df, df_imovel, grupos_imovel, planilha_carregada
 
21
  if planilha_carregada:
22
  return True
 
23
  try:
24
  print("⏳ Carregando planilha...")
25
- response = requests.get(URL, timeout=10)
26
  response.raise_for_status()
27
  data = io.BytesIO(response.content)
28
  df = pd.read_excel(data)
 
 
29
  df.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
 
 
30
  colunas_numericas = ['valor_credito', 'valor_entrada', 'valor_parcela', 'saldo_devedor', 'qtd_parcelas']
31
  for coluna in colunas_numericas:
32
  if coluna in df.columns:
33
  df[coluna] = pd.to_numeric(df[coluna], errors='coerce').fillna(0)
 
 
34
  if 'tipo_do_bem' not in df.columns or 'administradora' not in df.columns:
35
  raise ValueError("Colunas essenciais não encontradas")
 
36
  df.drop_duplicates(inplace=True)
 
 
37
  df_imovel = df[df['tipo_do_bem'].str.lower() == 'imovel'].copy()
38
  grupos_imovel = agrupar_por_administradora(df_imovel)
 
39
  planilha_carregada = True
40
- print(f"✅ Planilha carregada. Cotas: {len(df_imovel)}")
 
 
41
  return True
 
42
  except Exception as e:
43
  print(f"❌ Erro ao carregar planilha: {str(e)}")
44
  return False
45
 
 
46
  def agrupar_por_administradora(dataframe):
 
47
  grupos = defaultdict(list)
48
  for _, row in dataframe.iterrows():
49
  grupos[row['administradora']].append(row.to_dict())
50
  return grupos
51
 
 
52
  def formatar_moeda(valor):
53
  return f"R$ {valor:,.2f}".replace(",", "v").replace(".", ",").replace("v", ".")
54
 
 
55
  def calcular_tempo_parcelas(combinacao):
 
56
  if not combinacao:
57
  return ""
 
58
  try:
59
  cotas_ordenadas = sorted(combinacao, key=lambda x: int(x.get('qtd_parcelas', 0)))
60
  prazos = sorted(set(int(c.get('qtd_parcelas', 0)) for c in combinacao))
 
61
  if not prazos or prazos[0] <= 0:
62
  return ""
 
63
  resultado = []
64
  prazo_anterior = 0
 
65
  for prazo_atual in prazos:
66
  cotas_ativas = [c for c in cotas_ordenadas if int(c.get('qtd_parcelas', 0)) >= prazo_anterior + 1]
67
  valor_parcela_total = sum(c.get('valor_parcela', 0) for c in cotas_ativas)
 
68
  inicio = prazo_anterior + 1
69
  fim = prazo_atual
 
70
  if inicio <= fim and valor_parcela_total > 0:
71
  resultado.append(f"{inicio}x à {fim}x: {formatar_moeda(valor_parcela_total)}/mês")
 
72
  prazo_anterior = prazo_atual
 
73
  if prazos and prazo_anterior < max(prazos):
74
  cotas_ativas_finais = [c for c in cotas_ordenadas if int(c.get('qtd_parcelas', 0)) > prazo_anterior]
75
  if cotas_ativas_finais:
@@ -78,77 +107,126 @@ def calcular_tempo_parcelas(combinacao):
78
  fim_final = max(prazos)
79
  if valor_parcela_final > 0:
80
  resultado.append(f"{inicio_final}x à {fim_final}x: {formatar_moeda(valor_parcela_final)}/mês")
 
81
  return "\\n".join(resultado) if resultado else ""
 
82
  except Exception as e:
 
83
  return ""
84
 
 
85
  def definir_margens_absolutas(credito_desejado, entrada_desejada, parcela_desejada):
86
- margem_credito = 40000
87
- margem_entrada = 10000
88
- margem_parcela = 1000
 
 
 
89
  credito_min = max(0, credito_desejado - margem_credito)
90
  credito_max = credito_desejado + margem_credito
 
91
  entrada_min = max(0, entrada_desejada - margem_entrada)
92
  entrada_max = entrada_desejada + margem_entrada
 
93
  parcela_min = max(0, parcela_desejada - margem_parcela)
94
  parcela_max = parcela_desejada + margem_parcela
 
95
  return credito_min, credito_max, entrada_min, entrada_max, parcela_min, parcela_max
96
 
 
97
  def filtrar_cotas_por_faixa(cotas, credito_min, credito_max):
 
98
  return [c for c in cotas if c['valor_credito'] < credito_max * 2]
99
 
 
100
  def buscar_combinacoes_otimizado(credito_desejado, entrada_desejada, parcela_desejada, administradoras=None, max_combinacoes=15):
 
101
  global df_imovel, grupos_imovel
 
102
  if not planilha_carregada:
103
  if not carregar_planilha():
104
- return "❌ Erro: Planilha não carregada. Tente novamente mais tarde."
 
 
105
  if administradoras and len(administradoras) > 0:
106
  grupos_filtrados = {adm: cotas for adm, cotas in grupos_imovel.items() if adm in administradoras}
107
  else:
108
  grupos_filtrados = grupos_imovel
 
109
  if not grupos_filtrados:
110
- return "🚫 Nenhuma cota encontrada com os filtros aplicados."
 
 
 
 
111
  credito_min, credito_max, entrada_min, entrada_max, parcela_min, parcela_max = definir_margens_absolutas(
112
  credito_desejado, entrada_desejada, parcela_desejada
113
  )
 
 
 
 
 
114
  max_cotas_combinacao = 15
115
- max_combinacoes_por_adm = 4000
 
116
  resultados = []
117
  total_combinacoes_testadas = 0
 
118
  for adm, cotas in grupos_filtrados.items():
 
 
119
  cotas_filtradas = filtrar_cotas_por_faixa(cotas, credito_min, credito_max)
 
120
  for r in range(1, min(max_cotas_combinacao + 1, len(cotas_filtradas) + 1)):
121
  combinacoes_geradas = 0
122
  for combinacao in itertools.combinations(cotas_filtradas, r):
123
  if combinacoes_geradas >= max_combinacoes_por_adm:
124
  break
 
125
  total_combinacoes_testadas += 1
126
  combinacoes_geradas += 1
 
127
  total_credito = sum(c['valor_credito'] for c in combinacao)
128
  total_entrada_base = sum(c['valor_entrada'] for c in combinacao)
129
  total_entrada = total_entrada_base + (total_credito * 0.085)
130
  total_parcelas = sum(c['valor_parcela'] for c in combinacao)
 
 
131
  if (credito_min <= total_credito <= credito_max and
132
  entrada_min <= total_entrada <= entrada_max and
133
  parcela_min <= total_parcelas <= parcela_max):
 
134
  total_saldo = sum(c['saldo_devedor'] for c in combinacao)
135
  valor_final = round(total_entrada + total_saldo, 2)
136
  diferenca = abs(valor_final - total_credito)
 
137
  resultados.append((adm, combinacao, diferenca))
 
138
  if len(resultados) >= max_combinacoes * 2:
139
  break
 
140
  if len(resultados) >= max_combinacoes * 2:
141
  break
 
142
  if len(resultados) >= max_combinacoes * 2:
143
  break
 
 
 
 
144
  if not resultados:
145
- return "🚫 Nenhuma combinação adequada encontrada."
146
- resultados.sort(key=lambda x: x[2])
 
147
  return formatar_resultados(resultados[:max_combinacoes])
148
 
 
149
  def formatar_resultados(resultados):
 
150
  if not resultados:
151
- return "🚫 Nenhuma combinação adequada encontrada."
 
152
  resposta = ""
153
  for idx, (adm, combinacao, _) in enumerate(resultados, 1):
154
  codigos = [str(c.get('codigo', 'N/A')) for c in combinacao]
@@ -158,12 +236,15 @@ def formatar_resultados(resultados):
158
  total_saldo = sum(c['saldo_devedor'] for c in combinacao)
159
  total_parcelas = sum(c['valor_parcela'] for c in combinacao)
160
  maior_prazo = max(int(c.get('qtd_parcelas', 0)) for c in combinacao)
 
161
  valor_final = round(total_entrada + total_saldo, 2)
162
  credito_real = round(total_credito - total_entrada, 2)
163
  taxa_total = total_saldo - credito_real
164
  taxa_percentual = (taxa_total / credito_real) * 100 if credito_real > 0 else 0
165
  taxa_mensal = taxa_percentual / maior_prazo if maior_prazo > 0 else 0
 
166
  tempo_parcelas = calcular_tempo_parcelas(combinacao)
 
167
  resposta += f"""
168
  --- COMBINAÇÃO {idx} ---
169
  🏢 Administradora: {adm}
@@ -183,9 +264,11 @@ def formatar_resultados(resultados):
183
  """
184
  return resposta
185
 
186
- # Carrega a planilha (tenta, mas não para o app se falhar)
 
187
  carregar_planilha()
188
 
 
189
  def ajustar_e_buscar(credito_desejado, entrada_desejada, parcela_desejada, administradoras):
190
  return buscar_combinacoes_otimizado(
191
  float(credito_desejado or 0),
@@ -195,12 +278,14 @@ def ajustar_e_buscar(credito_desejado, entrada_desejada, parcela_desejada, admin
195
  max_combinacoes=15
196
  )
197
 
 
198
  def get_administradoras_options():
199
  if df is not None and planilha_carregada:
200
  adm_list = df[df['tipo_do_bem'].str.lower() == 'imovel']['administradora'].unique()
201
  return sorted(adm_list)
202
  return []
203
 
 
204
  # Interface Gradio
205
  with gr.Blocks(title="Sistema de Busca de Consórcio Imóvel") as demo:
206
  gr.HTML("""
@@ -225,26 +310,33 @@ with gr.Blocks(title="Sistema de Busca de Consórcio Imóvel") as demo:
225
  .gr-button:hover { background-color: #fff3e0 !important; }
226
  </style>
227
  """)
 
228
  gr.Markdown("# 🏠 Busca de Combinações de Consórcio Imóvel")
229
  gr.Markdown("Insira os valores desejados para crédito, entrada e parcela, e filtre por administradora.")
 
230
  with gr.Row():
231
  credito_input = gr.Number(label="Crédito Desejado (R$)", value=300000, step=1000)
232
  entrada_input = gr.Number(label="Entrada Desejada (R$)", value=30000, step=1000)
233
  parcela_input = gr.Number(label="Parcela Desejada (R$)", value=1500, step=100)
 
234
  administradoras_multiselect = gr.CheckboxGroup(
235
  label="Filtrar por Administradoras",
236
  choices=get_administradoras_options(),
237
  value=get_administradoras_options()
238
  )
 
239
  submit_btn = gr.Button("🔍 Buscar Combinações", variant="primary")
240
  output_text = gr.Textbox(label="Resultados da Busca", lines=20, max_lines=40, interactive=False, placeholder="Os resultados aparecerão aqui...")
 
241
  submit_btn.click(
242
  fn=ajustar_e_buscar,
243
  inputs=[credito_input, entrada_input, parcela_input, administradoras_multiselect],
244
  outputs=output_text
245
  )
 
246
  gr.Markdown("---")
247
  gr.Markdown("Desenvolvido para auxiliar na busca por cotas de consórcio ideais.")
248
 
249
  if __name__ == "__main__":
250
- demo.launch(api=True)
 
 
1
+ # app.py - VERSÃO COM MARGEM ABSOLUTA FIXA
2
  import pandas as pd
3
  import requests
4
  import io
5
  import itertools
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("""
 
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
+ #