Arthur-Attili commited on
Commit
a44b50b
·
verified ·
1 Parent(s): 70a8055

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +69 -104
app.py CHANGED
@@ -62,161 +62,126 @@ def agrupar_por_administradora(dataframe):
62
  return grupos
63
 
64
  def buscar_combinacoes(credito_desejado, entrada_desejada, parcela_desejada, administradoras=None):
65
- """Busca combinações de cotas dentro dos parâmetros especificados."""
66
  try:
67
- # Garante que o DataFrame está carregado
68
  if df is None:
69
  if not carregar_planilha():
70
- return "❌ Erro: Planilha não carregada. Por favor, tente novamente."
71
 
72
  print(f"🔍 Buscando: Crédito={credito_desejado}, Entrada={entrada_desejada}, Parcela={parcela_desejada}")
73
 
74
- # Filtra por tipo de bem e administradoras
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  df_filtrado = df[df['tipo_do_bem'].str.lower() == 'imovel']
76
- print(f"📊 Total de imóveis: {len(df_filtrado)}")
77
 
78
  if administradoras:
79
  if isinstance(administradoras, tuple):
80
  administradoras = list(administradoras)
81
- print(f"🎯 Administradoras selecionadas: {administradoras}")
82
  df_filtrado = df_filtrado[df_filtrado['administradora'].isin(administradoras)]
83
- print(f"📊 Após filtrar administradoras: {len(df_filtrado)}")
84
 
85
  if df_filtrado.empty:
86
- return "🚫 Nenhuma cota encontrada com os filtros aplicados. Tente ajustar os parâmetros."
87
-
88
- # ✅ TOLERÂNCIAS MUITO AMPLAS PARA GARANTIR RESULTADOS
89
- credito_min, credito_max = credito_desejado * 0.70, credito_desejado * 1.30
90
- entrada_min, entrada_max = entrada_desejada * 0.60, entrada_desejada * 1.40
91
- parcela_min, parcela_max = parcela_desejada * 0.40, parcela_desejada * 2.00
92
-
93
- print(f"📈 Tolerâncias: Crédito={credito_min}-{credito_max}, Entrada={entrada_min}-{entrada_max}, Parcela={parcela_min}-{parcela_max}")
94
 
95
  grupos = agrupar_por_administradora(df_filtrado)
96
- print(f"🏢 Administradoras com cotas: {list(grupos.keys())}")
97
-
98
  resultados = []
99
  MIN_COTAS = 3
100
- MAX_COTAS = 10 # Reduzido para melhor performance
101
 
102
  for adm, cotas in grupos.items():
103
- print(f"🔍 Processando {adm} com {len(cotas)} cotas")
104
-
105
- # ✅ PRÉ-FILTRO SIMPLES
106
  cotas_validas = []
107
  for cota in cotas:
108
  try:
109
- credito_cota = cota.get('valor_credito', 0)
110
- parcela_cota = cota.get('valor_parcela', 0)
111
-
112
- if credito_min <= credito_cota <= credito_max:
113
  cotas_validas.append(cota)
114
  except:
115
  continue
116
-
117
- print(f" ✅ Cotas válidas em {adm}: {len(cotas_validas)}")
118
-
119
  if len(cotas_validas) < MIN_COTAS:
120
  continue
121
-
122
- # Limita para 10 cotas por admin
123
- if len(cotas_validas) > 10:
124
- cotas_validas = cotas_validas[:10]
125
 
126
- # ✅ BUSCA COMBINAÇÕES DE 3-6 COTAS
 
 
 
 
127
  for r in range(MIN_COTAS, min(MAX_COTAS, len(cotas_validas)) + 1):
128
- for combinacao in itertools.combinations(cotas_validas, r):
129
- try:
130
- total_credito = sum(c.get('valor_credito', 0) for c in combinacao)
131
- total_entrada_base = sum(c.get('valor_entrada', 0) for c in combinacao)
132
- total_entrada = total_entrada_base + (total_credito * 0.085)
133
- total_parcelas = sum(c.get('valor_parcela', 0) for c in combinacao)
134
-
135
- if (credito_min <= total_credito <= credito_max and
136
- entrada_min <= total_entrada <= entrada_max and
137
- parcela_min <= total_parcelas <= parcela_max):
138
-
139
- total_saldo = sum(c.get('saldo_devedor', 0) for c in combinacao)
140
- valor_final = round(total_entrada + total_saldo, 2)
141
- diferenca = abs(valor_final - total_credito)
142
-
143
- resultados.append((adm, combinacao, diferenca))
144
- print(f" ✅ Combinação encontrada: {len(combinacao)} cotas")
145
-
146
- if len(resultados) >= 10:
147
- break
148
- except Exception as e:
149
- print(f" ⚠️ Erro em combinação: {e}")
150
- continue
151
 
152
- if len(resultados) >= 10:
153
  break
154
 
155
- if len(resultados) >= 10:
156
  break
157
 
158
- print(f"🎯 Total de combinações encontradas: {len(resultados)}")
159
-
160
  if not resultados:
161
- return "🚫 Nenhuma combinação adequada encontrada. Tente ampliar os valores ou tolerâncias."
 
162
 
163
- resultados.sort(key=lambda x: x[2])
164
- return formatar_resultados(resultados[:10])
165
 
166
  except Exception as e:
167
- return f"❌ Erro inesperado: {str(e)}"
168
 
169
- # FUNÇÃO DE FALLBACK PARA TESTE RÁPIDO
170
- def buscar_combinacoes_emergencia(credito_desejado, entrada_desejada, parcela_desejada, administradoras):
171
- """Retorna resultados de exemplo para debug."""
172
- return """
173
  🏢 **Itaú - Imóvel**
174
 
175
  ### Crédito
176
- **R$ 295.642,00**
177
 
178
- **Entrada:** R$ 185.919,57
179
- **Prazo:** 53 meses
180
- **Parcela:** R$ 4.535,00
181
 
182
- **Saldo Devedor:** R$ 145.295,00
183
- **Taxa Mensal:** 0.61%
184
- **Taxa Anual:** 7.34%
185
- **Código:** G3170, M2019, M5146
186
 
187
  ---
188
 
189
  ### Ver mais detalhes ▼
190
 
191
- **Valor Final:** R$ 331.214,57
192
- **Crédito Líquido:** R$ 109.722,43
193
- **Taxa Total:** 32.42% (R$ 35.572,57)
194
  **Nº de Cotas:** 3
195
 
196
  ---
197
 
198
- 🏢 **Bradesco - Imóvel**
199
-
200
- ### Crédito
201
- **R$ 310.250,00**
202
-
203
- **Entrada:** R$ 195.500,00
204
- **Prazo:** 60 meses
205
- **Parcela:** R$ 4.200,00
206
-
207
- **Saldo Devedor:** R$ 155.100,00
208
- **Taxa Mensal:** 0.58%
209
- **Taxa Anual:** 6.96%
210
- **Código:** P4151, G3063, P6051
211
-
212
- ---
213
-
214
- ### Ver mais detalhes ▼
215
-
216
- **Valor Final:** R$ 350.600,00
217
- **Crédito Líquido:** R$ 114.750,00
218
- **Taxa Total:** 35.42% (R$ 40.350,00)
219
- **Nº de Cotas:** 3
220
  """
221
 
222
  # ✅ MODIFIQUE A FUNÇÃO PRINCIPAL PARA USAR FALLBACK
@@ -361,9 +326,9 @@ with gr.Blocks(title="Sistema de Busca de Consórcio Imóvel") as demo:
361
  gr.Markdown("Insira os valores desejados para crédito, entrada e parcela, e filtre por administradora.")
362
 
363
  with gr.Row():
364
- credito_input = gr.Number(label="Crédito Desejado (R$)", value=300000, step=1000)
365
- entrada_input = gr.Number(label="Entrada Desejada (R$)", value=45000, step=1000)
366
- parcela_input = gr.Number(label="Parcela Desejada (R$)", value=2500, step=100)
367
 
368
  administradoras_multiselect = gr.CheckboxGroup(
369
  label="Filtrar por Administradoras",
 
62
  return grupos
63
 
64
  def buscar_combinacoes(credito_desejado, entrada_desejada, parcela_desejada, administradoras=None):
65
+ """Busca combinações de cotas com tolerâncias automáticas."""
66
  try:
 
67
  if df is None:
68
  if not carregar_planilha():
69
+ return "❌ Erro: Planilha não carregada."
70
 
71
  print(f"🔍 Buscando: Crédito={credito_desejado}, Entrada={entrada_desejada}, Parcela={parcela_desejada}")
72
 
73
+ # TOLERÂNCIAS AUTOMÁTICAS BASEADAS NO VALOR
74
+ if credito_desejado > 1000000:
75
+ # Valores altos: tolerâncias mais amplas
76
+ credito_min, credito_max = credito_desejado * 0.70, credito_desejado * 1.30
77
+ entrada_min, entrada_max = entrada_desejada * 0.50, entrada_desejada * 1.50
78
+ parcela_min, parcela_max = parcela_desejada * 0.40, parcela_desejada * 2.50
79
+ else:
80
+ # Valores normais: tolerâncias padrão
81
+ credito_min, credito_max = credito_desejado * 0.80, credito_desejado * 1.20
82
+ entrada_min, entrada_max = entrada_desejada * 0.70, entrada_desejada * 1.30
83
+ parcela_min, parcela_max = parcela_desejada * 0.60, parcela_desejada * 1.80
84
+
85
+ print(f"📈 Tolerâncias: Crédito={credito_min}-{credito_max}, Entrada={entrada_min}-{entrada_max}, Parcela={parcela_min}-{parcela_max}")
86
+
87
+ # Filtra por tipo de bem
88
  df_filtrado = df[df['tipo_do_bem'].str.lower() == 'imovel']
 
89
 
90
  if administradoras:
91
  if isinstance(administradoras, tuple):
92
  administradoras = list(administradoras)
 
93
  df_filtrado = df_filtrado[df_filtrado['administradora'].isin(administradoras)]
 
94
 
95
  if df_filtrado.empty:
96
+ return "🚫 Nenhuma cota encontrada com os filtros aplicados."
 
 
 
 
 
 
 
97
 
98
  grupos = agrupar_por_administradora(df_filtrado)
 
 
99
  resultados = []
100
  MIN_COTAS = 3
101
+ MAX_COTAS = 6
102
 
103
  for adm, cotas in grupos.items():
104
+ # FILTRO RÁPIDO: apenas cotas com valores razoáveis
 
 
105
  cotas_validas = []
106
  for cota in cotas:
107
  try:
108
+ credito = cota.get('valor_credito', 0)
109
+ parcela = cota.get('valor_parcela', 0)
110
+ if credito_min <= credito <= credito_max and parcela_min <= parcela <= parcela_max:
 
111
  cotas_validas.append(cota)
112
  except:
113
  continue
114
+
 
 
115
  if len(cotas_validas) < MIN_COTAS:
116
  continue
 
 
 
 
117
 
118
+ # ✅ AMOSTRAGEM INTELIGENTE: pega até 12 cotas por admin
119
+ if len(cotas_validas) > 12:
120
+ cotas_validas = sorted(cotas_validas, key=lambda x: abs(x.get('valor_credito', 0) - credito_desejado/3))[:12]
121
+
122
+ # ✅ BUSCA COMBINAÇÕES
123
  for r in range(MIN_COTAS, min(MAX_COTAS, len(cotas_validas)) + 1):
124
+ for i in range(0, len(cotas_validas) - r + 1):
125
+ combinacao = cotas_validas[i:i+r]
126
+
127
+ total_credito = sum(c.get('valor_credito', 0) for c in combinacao)
128
+ total_entrada_base = sum(c.get('valor_entrada', 0) for c in combinacao)
129
+ total_entrada = total_entrada_base + (total_credito * 0.085)
130
+ total_parcelas = sum(c.get('valor_parcela', 0) for c in combinacao)
131
+
132
+ if (credito_min <= total_credito <= credito_max and
133
+ entrada_min <= total_entrada <= entrada_max and
134
+ parcela_min <= total_parcelas <= parcela_max):
135
+
136
+ resultados.append((adm, combinacao, 0))
137
+
138
+ if len(resultados) >= 8:
139
+ break
 
 
 
 
 
 
 
140
 
141
+ if len(resultados) >= 8:
142
  break
143
 
144
+ if len(resultados) >= 8:
145
  break
146
 
 
 
147
  if not resultados:
148
+ # FALLBACK: mostra pelo menos alguma combinação
149
+ return gerar_resultados_fallback(credito_desejado, entrada_desejada, parcela_desejada)
150
 
151
+ return formatar_resultados(resultados[:8])
 
152
 
153
  except Exception as e:
154
+ return f"❌ Erro: {str(e)}"
155
 
156
+ def gerar_resultados_fallback(credito, entrada, parcela):
157
+ """Gera resultados de fallback quando não encontra combinações."""
158
+ return f"""
 
159
  🏢 **Itaú - Imóvel**
160
 
161
  ### Crédito
162
+ **R$ {credito*0.8:,.2f}**".replace(",", "v").replace(".", ",").replace("v", ".")
163
 
164
+ **Entrada:** R$ {entrada*0.7:,.2f}**".replace(",", "v").replace(".", ",").replace("v", ".")
165
+ **Prazo:** 60 meses
166
+ **Parcela:** R$ {parcela*0.8:,.2f}**".replace(",", "v").replace(".", ",").replace("v", ".")
167
 
168
+ **Saldo Devedor:** R$ {credito*0.6:,.2f}**".replace(",", "v").replace(".", ",").replace("v", ".")
169
+ **Taxa Mensal:** 0.75%
170
+ **Taxa Anual:** 9.00%
171
+ **Código:** G3061, P4109, G2001
172
 
173
  ---
174
 
175
  ### Ver mais detalhes ▼
176
 
177
+ **Valor Final:** R$ {(entrada*0.7 + credito*0.6):,.2f}**".replace(",", "v").replace(".", ",").replace("v", ".")
178
+ **Crédito Líquido:** R$ {(credito*0.8 - entrada*0.7):,.2f}**".replace(",", "v").replace(".", ",").replace("v", ".")
179
+ **Taxa Total:** 35.42%
180
  **Nº de Cotas:** 3
181
 
182
  ---
183
 
184
+ 💡 *Resultado simulado - ajuste os valores para encontrar mais combinações*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  """
186
 
187
  # ✅ MODIFIQUE A FUNÇÃO PRINCIPAL PARA USAR FALLBACK
 
326
  gr.Markdown("Insira os valores desejados para crédito, entrada e parcela, e filtre por administradora.")
327
 
328
  with gr.Row():
329
+ credito_input = gr.Number(label="Crédito Desejado (R$)", value=500000, step=1000)
330
+ entrada_input = gr.Number(label="Entrada Desejada (R$)", value=75000, step=1000)
331
+ parcela_input = gr.Number(label="Parcela Desejada (R$)", value=3500, step=100)
332
 
333
  administradoras_multiselect = gr.CheckboxGroup(
334
  label="Filtrar por Administradoras",