Arthur-Attili commited on
Commit
1800768
·
verified ·
1 Parent(s): 66f8b67

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +115 -55
app.py CHANGED
@@ -1,9 +1,3 @@
1
- """Imovel.ipynb
2
- Automatically generated by Colab.
3
- Original file is located at
4
- https://colab.research.google.com/drive/1DZAQZfrXvTy358Vg2qfUg_ge6b3kcgBy
5
- """
6
-
7
  # app.py
8
  import pandas as pd
9
  import requests
@@ -14,7 +8,6 @@ import gradio as gr
14
  import time
15
 
16
  # 🔧 CONFIGURAÇÕES GLOBAIS
17
- # Certifique-se de que este FILE_ID esteja acessível publicamente ou para "Qualquer pessoa com o link"
18
  FILE_ID = "1XvNz7DlWioT64uNdcfBSL8Ui2nRSi9gT"
19
  URL = f"https://drive.google.com/uc?export=download&id={FILE_ID}"
20
 
@@ -61,18 +54,45 @@ def agrupar_por_administradora(dataframe):
61
  grupos[row['administradora']].append(row.to_dict())
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
  # Garante que o DataFrame está carregado
67
  if df is None:
68
- # Tenta carregar se ainda não foi carregado
69
  if not carregar_planilha():
70
  return "❌ Erro: Planilha não carregada. Por favor, tente novamente."
71
 
72
  # Filtra por tipo de bem e administradoras
73
  df_filtrado = df[df['tipo_do_bem'].str.lower() == 'imovel']
74
  if administradoras:
75
- # Certifica-se de que administradoras é uma lista (Gradio retorna tupla)
76
  if isinstance(administradoras, tuple):
77
  administradoras = list(administradoras)
78
  df_filtrado = df_filtrado[df_filtrado['administradora'].isin(administradoras)]
@@ -80,47 +100,82 @@ def buscar_combinacoes(credito_desejado, entrada_desejada, parcela_desejada, adm
80
  if df_filtrado.empty:
81
  return "🚫 Nenhuma cota encontrada com os filtros aplicados. Tente ajustar os parâmetros."
82
 
83
- # Define faixas de tolerância
84
- credito_min, credito_max = credito_desejado * 0.93, credito_desejado * 1.07
85
- entrada_min, entrada_max = entrada_desejada * 0.93, entrada_desejada * 1.07
86
- parcela_min, parcela_max = parcela_desejada * 0.75, parcela_desejada * 1.25
87
-
88
  grupos = agrupar_por_administradora(df_filtrado)
89
- resultados = []
 
 
 
 
 
90
 
91
  for adm, cotas in grupos.items():
92
- for r in range(1, min(4, len(cotas)) + 1): # Máximo 3 cotas por combinação
93
- for combinacao in itertools.combinations(cotas, r):
94
- total_credito = sum(c['valor_credito'] for c in combinacao)
95
- total_entrada_base = sum(c['valor_entrada'] for c in combinacao)
96
- total_entrada = total_entrada_base + (total_credito * 0.085) # aplica os 8,5% sobre o crédito
97
- total_parcelas = sum(c['valor_parcela'] for c in combinacao)
98
-
99
- if (credito_min <= total_credito <= credito_max and
100
- entrada_min <= total_entrada <= entrada_max and
101
- parcela_min <= total_parcelas <= parcela_max):
102
-
103
- total_saldo = sum(c['saldo_devedor'] for c in combinacao)
104
- valor_final = round(total_entrada + total_saldo, 2)
105
- diferenca = abs(valor_final - total_credito) # Diferença do valor final pelo crédito (para ordenação)
106
-
107
- resultados.append((adm, combinacao, diferenca))
108
-
109
- if not resultados:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  return "🚫 Nenhuma combinação adequada encontrada com os parâmetros fornecidos."
111
 
112
- resultados.sort(key=lambda x: x[2]) # Ordena pela diferença
113
-
114
- return formatar_resultados(resultados)
 
115
 
116
  def formatar_moeda(valor):
117
  return f"R$ {valor:,.2f}".replace(",", "v").replace(".", ",").replace("v", ".")
118
 
119
  def formatar_resultados(resultados):
120
  """Formata os resultados para exibição."""
121
- resposta = ""
122
- # Limita a 15 resultados para evitar saídas muito longas
123
- for idx, (adm, combinacao, _) in enumerate(resultados[:15], 1):
 
 
 
 
 
 
124
  codigos = [str(c.get('codigo', 'N/A')) for c in combinacao]
125
  total_credito = sum(c['valor_credito'] for c in combinacao)
126
  total_entrada_base = sum(c['valor_entrada'] for c in combinacao)
@@ -137,19 +192,26 @@ def formatar_resultados(resultados):
137
 
138
  resposta += f"""
139
  --- COMBINAÇÃO {idx} ---
140
- 🏢 Administradora: {adm}
141
- 🔢 Códigos: {', '.join(codigos)}
142
- 💰 Crédito Total: {formatar_moeda(total_credito)}
143
- 💵 Entrada (+comissão): {formatar_moeda(total_entrada)}
144
- 📉 Saldo Devedor: {formatar_moeda(total_saldo)}
145
- 💲 Parcela: {formatar_moeda(total_parcelas)}
146
- ⏳ Prazo: {maior_prazo} meses
147
- 🔚 Valor Final: {formatar_moeda(valor_final)}
148
- 💠 Crédito Líquido: {formatar_moeda(credito_real)}
149
- 📊 Taxa Total: {taxa_percentual:.2f}% ({formatar_moeda(taxa_total)})
150
- 🗓️ Taxa Mensal: {taxa_mensal:.2f}%
151
- 🗓️ Taxa Anual: {taxa_mensal * 12:.2f}%
152
  """
 
 
 
 
 
 
 
 
153
  return resposta
154
 
155
  # Carrega a planilha uma vez quando o aplicativo inicia
@@ -180,7 +242,6 @@ with gr.Blocks(title="Sistema de Busca de Consórcio Imóvel") as demo:
180
  color: black !important;
181
  }
182
 
183
- /* Inputs Numéricos: Crédito, Entrada, Parcela */
184
  input[type="number"] {
185
  background-color: white !important;
186
  border: 2px solid #000 !important;
@@ -190,7 +251,6 @@ with gr.Blocks(title="Sistema de Busca de Consórcio Imóvel") as demo:
190
  font-weight: 500;
191
  }
192
 
193
- /* Inputs de texto e áreas de texto (como a saída e código) */
194
  input[type="text"], textarea {
195
  background-color: white !important;
196
  border: 2px solid black !important;
@@ -253,7 +313,7 @@ with gr.Blocks(title="Sistema de Busca de Consórcio Imóvel") as demo:
253
 
254
  submit_btn = gr.Button("🔍 Buscar Combinações", variant="primary")
255
 
256
- output_text = gr.Textbox(label="Resultados da Busca", lines=20, max_lines=40, interactive=False, placeholder="Os resultados aparecerão aqui...")
257
 
258
  submit_btn.click(
259
  fn=ajustar_e_buscar,
@@ -266,4 +326,4 @@ with gr.Blocks(title="Sistema de Busca de Consórcio Imóvel") as demo:
266
 
267
  # Inicia o aplicativo Gradio
268
  if __name__ == "__main__":
269
- demo.launch() # Você não precisa disso no Colab, mas sim no arquivo que você fará o deploy
 
 
 
 
 
 
 
1
  # app.py
2
  import pandas as pd
3
  import requests
 
8
  import time
9
 
10
  # 🔧 CONFIGURAÇÕES GLOBAIS
 
11
  FILE_ID = "1XvNz7DlWioT64uNdcfBSL8Ui2nRSi9gT"
12
  URL = f"https://drive.google.com/uc?export=download&id={FILE_ID}"
13
 
 
54
  grupos[row['administradora']].append(row.to_dict())
55
  return grupos
56
 
57
+ def buscar_combinacoes_eficiente(cotas, credito_min, credito_max, entrada_min, entrada_max, parcela_min, parcela_max):
58
+ """Busca combinações de forma eficiente com limites inteligentes."""
59
+ resultados = []
60
+ n = len(cotas)
61
+
62
+ # Para combinações de 1 a 3 cotas (mais eficiente)
63
+ for r in range(1, min(4, n) + 1):
64
+ for combinacao in itertools.combinations(cotas, r):
65
+ total_credito = sum(c['valor_credito'] for c in combinacao)
66
+ total_entrada_base = sum(c['valor_entrada'] for c in combinacao)
67
+ total_entrada = total_entrada_base + (total_credito * 0.085)
68
+ total_parcelas = sum(c['valor_parcela'] for c in combinacao)
69
+
70
+ if (credito_min <= total_credito <= credito_max and
71
+ entrada_min <= total_entrada <= entrada_max and
72
+ parcela_min <= total_parcelas <= parcela_max):
73
+
74
+ total_saldo = sum(c['saldo_devedor'] for c in combinacao)
75
+ valor_final = round(total_entrada + total_saldo, 2)
76
+ diferenca = abs(valor_final - total_credito)
77
+
78
+ resultados.append((combinacao, diferenca))
79
+
80
+ # Limita a 30 combinações por administradora
81
+ if len(resultados) >= 30:
82
+ return resultados
83
+
84
+ return resultados
85
+
86
  def buscar_combinacoes(credito_desejado, entrada_desejada, parcela_desejada, administradoras=None):
87
  """Busca combinações de cotas dentro dos parâmetros especificados."""
88
  # Garante que o DataFrame está carregado
89
  if df is None:
 
90
  if not carregar_planilha():
91
  return "❌ Erro: Planilha não carregada. Por favor, tente novamente."
92
 
93
  # Filtra por tipo de bem e administradoras
94
  df_filtrado = df[df['tipo_do_bem'].str.lower() == 'imovel']
95
  if administradoras:
 
96
  if isinstance(administradoras, tuple):
97
  administradoras = list(administradoras)
98
  df_filtrado = df_filtrado[df_filtrado['administradora'].isin(administradoras)]
 
100
  if df_filtrado.empty:
101
  return "🚫 Nenhuma cota encontrada com os filtros aplicados. Tente ajustar os parâmetros."
102
 
 
 
 
 
 
103
  grupos = agrupar_por_administradora(df_filtrado)
104
+ todas_combinacoes = []
105
+
106
+ # PRIMEIRA TENTATIVA: Critérios normais
107
+ credito_min1, credito_max1 = credito_desejado * 0.93, credito_desejado * 1.07
108
+ entrada_min1, entrada_max1 = entrada_desejada * 0.93, entrada_desejada * 1.07
109
+ parcela_min1, parcela_max1 = parcela_desejada * 0.75, parcela_desejada * 1.25
110
 
111
  for adm, cotas in grupos.items():
112
+ cotas = cotas[:35] # 35 cotas por administradora
113
+
114
+ combinacoes = buscar_combinacoes_eficiente(
115
+ cotas, credito_min1, credito_max1, entrada_min1, entrada_max1, parcela_min1, parcela_max1
116
+ )
117
+
118
+ for combinacao, diferenca in combinacoes:
119
+ todas_combinacoes.append((adm, combinacao, diferenca))
120
+
121
+ # SEGUNDA TENTATIVA: Se não encontrou pelo menos 15, amplia os critérios
122
+ if len(todas_combinacoes) < 15:
123
+ print("⚠️ Ampliando critérios de busca...")
124
+ credito_min2, credito_max2 = credito_desejado * 0.90, credito_desejado * 1.10
125
+ entrada_min2, entrada_max2 = entrada_desejada * 0.90, entrada_desejada * 1.10
126
+ parcela_min2, parcela_max2 = parcela_desejada * 0.65, parcela_desejada * 1.35
127
+
128
+ for adm, cotas in grupos.items():
129
+ if len(todas_combinacoes) >= 30: # Limite total
130
+ break
131
+
132
+ cotas = cotas[:40] # 40 cotas por administradora
133
+
134
+ combinacoes = buscar_combinacoes_eficiente(
135
+ cotas, credito_min2, credito_max2, entrada_min2, entrada_max2, parcela_min2, parcela_max2
136
+ )
137
+
138
+ for combinacao, diferenca in combinacoes:
139
+ # Verifica se já não temos esta combinação (por códigos)
140
+ codigos_novos = set(str(c.get('codigo', '')) for c in combinacao)
141
+ ja_existe = False
142
+
143
+ for adm_existente, comb_existente, _ in todas_combinacoes:
144
+ if adm_existente != adm:
145
+ continue
146
+ codigos_existentes = set(str(c.get('codigo', '')) for c in comb_existente)
147
+ if codigos_novos == codigos_existentes:
148
+ ja_existe = True
149
+ break
150
+
151
+ if not ja_existe:
152
+ todas_combinacoes.append((adm, combinacao, diferenca))
153
+
154
+ if len(todas_combinacoes) >= 30:
155
+ break
156
+
157
+ if not todas_combinacoes:
158
  return "🚫 Nenhuma combinação adequada encontrada com os parâmetros fornecidos."
159
 
160
+ # Ordena por diferença (melhores combinações primeiro)
161
+ todas_combinacoes.sort(key=lambda x: x[2])
162
+
163
+ return formatar_resultados(todas_combinacoes)
164
 
165
  def formatar_moeda(valor):
166
  return f"R$ {valor:,.2f}".replace(",", "v").replace(".", ",").replace("v", ".")
167
 
168
  def formatar_resultados(resultados):
169
  """Formata os resultados para exibição."""
170
+ if not resultados:
171
+ return "Nenhuma combinação encontrada."
172
+
173
+ resposta = f"📊 **Encontradas {len(resultados)} combinações**\n\n"
174
+
175
+ # Garante pelo menos 15 combinações na exibição (ou todas se tiver menos)
176
+ resultados_exibicao = resultados[:20]
177
+
178
+ for idx, (adm, combinacao, diferenca) in enumerate(resultados_exibicao, 1):
179
  codigos = [str(c.get('codigo', 'N/A')) for c in combinacao]
180
  total_credito = sum(c['valor_credito'] for c in combinacao)
181
  total_entrada_base = sum(c['valor_entrada'] for c in combinacao)
 
192
 
193
  resposta += f"""
194
  --- COMBINAÇÃO {idx} ---
195
+ 🏢 **Administradora:** {adm.upper()}
196
+ 🔢 **Códigos ({len(combinacao)} cotas):** {', '.join(codigos)}
197
+ 💰 **Crédito Total:** {formatar_moeda(total_credito)}
198
+ 💵 **Entrada (+comissão):** {formatar_moeda(total_entrada)}
199
+ 📉 **Saldo Devedor:** {formatar_moeda(total_saldo)}
200
+ 💲 **Parcela:** {formatar_moeda(total_parcelas)}
201
+ **Prazo:** {maior_prazo} meses
202
+ 🔚 **Valor Final:** {formatar_moeda(valor_final)}
203
+ 💠 **Crédito Líquido:** {formatar_moeda(credito_real)}
204
+ 📊 **Taxa Total:** {taxa_percentual:.2f}% ({formatar_moeda(taxa_total)})
205
+ 🗓️ **Taxa Mensal:** {taxa_mensal:.2f}%
 
206
  """
207
+
208
+ # Mensagem informativa
209
+ if len(resultados) < 15:
210
+ resposta += f"\n⚠️ **Atenção:** Foram encontradas apenas {len(resultados)} combinações. "
211
+ resposta += "Tente ampliar os parâmetros de busca para mais resultados."
212
+ elif len(resultados) > 20:
213
+ resposta += f"\n📈 Mostrando 20 de {len(resultados)} combinações encontradas."
214
+
215
  return resposta
216
 
217
  # Carrega a planilha uma vez quando o aplicativo inicia
 
242
  color: black !important;
243
  }
244
 
 
245
  input[type="number"] {
246
  background-color: white !important;
247
  border: 2px solid #000 !important;
 
251
  font-weight: 500;
252
  }
253
 
 
254
  input[type="text"], textarea {
255
  background-color: white !important;
256
  border: 2px solid black !important;
 
313
 
314
  submit_btn = gr.Button("🔍 Buscar Combinações", variant="primary")
315
 
316
+ output_text = gr.Textbox(label="Resultados da Busca", lines=25, max_lines=50, interactive=False, placeholder="Os resultados aparecerão aqui...")
317
 
318
  submit_btn.click(
319
  fn=ajustar_e_buscar,
 
326
 
327
  # Inicia o aplicativo Gradio
328
  if __name__ == "__main__":
329
+ demo.launch()