Arthur-Attili commited on
Commit
67d28c6
·
verified ·
1 Parent(s): 372bfd9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -130
app.py CHANGED
@@ -6,59 +6,65 @@ Original file is located at
6
 
7
  # app.py
8
  import pandas as pd
9
- import requests
10
- import io
11
  import itertools
12
  from collections import defaultdict
13
  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
 
21
  # Variável global para armazenar o DataFrame
22
  df = None
23
 
24
  def carregar_planilha():
25
- """Carrega e prepara a planilha para análise."""
26
  global df
27
  try:
28
- print("⏳ Carregando planilha...")
29
- response = requests.get(URL)
30
- response.raise_for_status()
31
- data = io.BytesIO(response.content)
32
- df = pd.read_excel(data)
 
 
 
 
 
33
 
34
  # Padroniza nomes das colunas
35
  df.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
36
 
37
- # Converte colunas numéricas
38
- colunas_numericas = ['valor_credito', 'valor_entrada', 'valor_parcela', 'saldo_devedor', 'qtd_parcelas']
39
  for coluna in colunas_numericas:
40
  if coluna in df.columns:
41
  df[coluna] = pd.to_numeric(df[coluna], errors='coerce').fillna(0)
42
 
43
  # Verifica colunas essenciais
44
- if 'tipo_do_bem' not in df.columns or 'administradora' not in df.columns:
45
  raise ValueError("Colunas essenciais não encontradas")
46
 
47
  # Remove duplicatas
48
  df.drop_duplicates(inplace=True)
49
 
50
- print("✅ Planilha carregada com sucesso")
 
51
  return True
52
 
53
  except Exception as e:
54
- print(f"❌ Erro ao carregar planilha: {str(e)}")
55
  return False
56
 
57
  def agrupar_por_administradora(dataframe):
58
  """Agrupa cotas por administradora."""
59
  grupos = defaultdict(list)
60
  for _, row in dataframe.iterrows():
61
- grupos[row['administradora']].append(row.to_dict())
 
62
  return grupos
63
 
64
  def buscar_combinacoes(credito_desejado, entrada_desejada, parcela_desejada, administradoras=None):
@@ -67,15 +73,18 @@ def buscar_combinacoes(credito_desejado, entrada_desejada, parcela_desejada, adm
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)]
 
 
79
 
80
  if df_filtrado.empty:
81
  return "🚫 Nenhuma cota encontrada com os filtros aplicados. Tente ajustar os parâmetros."
@@ -92,15 +101,15 @@ def buscar_combinacoes(credito_desejado, entrada_desejada, parcela_desejada, adm
92
  for r in range(1, min(3, 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
 
@@ -123,11 +132,11 @@ def formatar_resultados(resultados):
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)
127
  total_entrada = total_entrada_base + (total_credito * 0.085)
128
- total_saldo = sum(c['saldo_devedor'] for c in combinacao)
129
- total_parcelas = sum(c['valor_parcela'] for c in combinacao)
130
- maior_prazo = max(int(c.get('qtd_parcelas', 0)) for c in combinacao)
131
 
132
  valor_final = round(total_entrada + total_saldo, 2)
133
  credito_real = round(total_credito - total_entrada, 2)
@@ -152,7 +161,7 @@ def formatar_resultados(resultados):
152
  """
153
  return resposta
154
 
155
- # Carrega a planilha uma vez quando o aplicativo inicia
156
  carregar_planilha()
157
 
158
  def ajustar_e_buscar(credito_desejado, entrada_desejada, parcela_desejada, administradoras):
@@ -162,108 +171,11 @@ def ajustar_e_buscar(credito_desejado, entrada_desejada, parcela_desejada, admin
162
  # Prepara a lista de administradoras para o Gradio
163
  def get_administradoras_options():
164
  if df is not None:
165
- adm_list = df[df['tipo_do_bem'].str.lower() == 'imovel']['administradora'].unique()
 
166
  return sorted(adm_list)
167
  return []
168
 
169
  # Criando a interface Gradio
170
  with gr.Blocks(title="Sistema de Busca de Consórcio Imóvel") as demo:
171
- gr.HTML("""
172
- <link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
173
- <style>
174
- * {
175
- font-family: 'Poppins', sans-serif !important;
176
- }
177
-
178
- body {
179
- background-color: #ff8f00 !important;
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;
187
- border-radius: 12px !important;
188
- color: black !important;
189
- padding: 10px !important;
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;
197
- border-radius: 12px !important;
198
- color: black !important;
199
- padding: 10px !important;
200
- }
201
-
202
- input::placeholder, textarea::placeholder {
203
- color: #333 !important;
204
- opacity: 0.7;
205
- }
206
-
207
- .gr-checkbox label {
208
- display: flex;
209
- align-items: center;
210
- gap: 8px;
211
- font-weight: 600;
212
- }
213
-
214
- input[type="checkbox"] {
215
- accent-color: black !important;
216
- width: 18px;
217
- height: 18px;
218
- }
219
-
220
- .gr-button {
221
- font-weight: bold;
222
- border-radius: 10px !important;
223
- background-color: white !important;
224
- color: black !important;
225
- border: 2px solid black !important;
226
- }
227
-
228
- .gr-button:hover {
229
- background-color: #fff3e0 !important;
230
- color: black !important;
231
- }
232
-
233
- label {
234
- font-weight: 600 !important;
235
- }
236
- </style>
237
- """)
238
-
239
-
240
- gr.Markdown("# 🏠 Busca de Combinações de Consórcio Imóvel")
241
- gr.Markdown("Insira os valores desejados para crédito, entrada e parcela, e filtre por administradora.")
242
-
243
- with gr.Row():
244
- credito_input = gr.Number(label="Crédito Desejado (R$)", value=300000, step=1000)
245
- entrada_input = gr.Number(label="Entrada Desejada (R$)", value=30000, step=1000)
246
- parcela_input = gr.Number(label="Parcela Desejada (R$)", value=1500, step=100)
247
-
248
- administradoras_multiselect = gr.CheckboxGroup(
249
- label="Filtrar por Administradoras",
250
- choices=get_administradoras_options(),
251
- value=get_administradoras_options() # Seleciona todas por padrão
252
- )
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,
260
- inputs=[credito_input, entrada_input, parcela_input, administradoras_multiselect],
261
- outputs=output_text
262
- )
263
-
264
- gr.Markdown("---")
265
- gr.Markdown("Desenvolvido para auxiliar na busca por cotas de consórcio ideais.")
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
 
6
 
7
  # app.py
8
  import pandas as pd
 
 
9
  import itertools
10
  from collections import defaultdict
11
  import gradio as gr
12
+ from supabase import create_client, Client
13
+ import os
14
 
15
+ # 🔧 CONFIGURAÇÕES GLOBAIS - SUPABASE
16
+ SUPABASE_URL = os.environ.get("SUPABASE_URL")
17
+ SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
18
+ supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
19
 
20
  # Variável global para armazenar o DataFrame
21
  df = None
22
 
23
  def carregar_planilha():
24
+ """Carrega e prepara os dados do Supabase para análise."""
25
  global df
26
  try:
27
+ print("⏳ Carregando dados do Supabase...")
28
+
29
+ # Busca todos os dados da tabela cotas
30
+ response = supabase.table("cotas").select("*").execute()
31
+
32
+ # Converte para DataFrame
33
+ df = pd.DataFrame(response.data)
34
+
35
+ if df.empty:
36
+ raise ValueError("Nenhum dado encontrado no Supabase")
37
 
38
  # Padroniza nomes das colunas
39
  df.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
40
 
41
+ # Converte colunas numéricas - USANDO OS NOMES CORRETOS DO SEU SUPABASE
42
+ colunas_numericas = ['valor_credito', 'entrada', 'valor_parcela', 'saldo', 'parcelas']
43
  for coluna in colunas_numericas:
44
  if coluna in df.columns:
45
  df[coluna] = pd.to_numeric(df[coluna], errors='coerce').fillna(0)
46
 
47
  # Verifica colunas essenciais
48
+ if 'categoria' not in df.columns or 'administradora_id' not in df.columns:
49
  raise ValueError("Colunas essenciais não encontradas")
50
 
51
  # Remove duplicatas
52
  df.drop_duplicates(inplace=True)
53
 
54
+ print("✅ Dados carregados com sucesso do Supabase")
55
+ print(f"📊 Colunas disponíveis: {list(df.columns)}")
56
  return True
57
 
58
  except Exception as e:
59
+ print(f"❌ Erro ao carregar dados do Supabase: {str(e)}")
60
  return False
61
 
62
  def agrupar_por_administradora(dataframe):
63
  """Agrupa cotas por administradora."""
64
  grupos = defaultdict(list)
65
  for _, row in dataframe.iterrows():
66
+ # CORRIGIDO: usando administradora_id consistentemente
67
+ grupos[row['administradora_id']].append(row.to_dict())
68
  return grupos
69
 
70
  def buscar_combinacoes(credito_desejado, entrada_desejada, parcela_desejada, administradoras=None):
 
73
  if df is None:
74
  # Tenta carregar se ainda não foi carregado
75
  if not carregar_planilha():
76
+ return "❌ Erro: Dados não carregados. Por favor, tente novamente."
77
 
78
  # Filtra por tipo de bem e administradoras
79
+ df_filtrado = df[df['categoria'].str.lower() == 'imovel']
80
+
81
  if administradoras:
82
  # Certifica-se de que administradoras é uma lista (Gradio retorna tupla)
83
  if isinstance(administradoras, tuple):
84
  administradoras = list(administradoras)
85
+
86
+ # CORRIGIDO: usando administradora_id consistentemente
87
+ df_filtrado = df_filtrado[df_filtrado['administradora_id'].isin(administradoras)]
88
 
89
  if df_filtrado.empty:
90
  return "🚫 Nenhuma cota encontrada com os filtros aplicados. Tente ajustar os parâmetros."
 
101
  for r in range(1, min(3, len(cotas)) + 1): # Máximo 3 cotas por combinação
102
  for combinacao in itertools.combinations(cotas, r):
103
  total_credito = sum(c['valor_credito'] for c in combinacao)
104
+ total_entrada_base = sum(c['entrada'] for c in combinacao) # CORRIGIDO: 'entrada'
105
  total_entrada = total_entrada_base + (total_credito * 0.085) # aplica os 8,5% sobre o crédito
106
+ total_parcelas = sum(c['valor_parcela'] for c in combinacao) # CORRIGIDO: 'valor_parcela'
107
 
108
  if (credito_min <= total_credito <= credito_max and
109
  entrada_min <= total_entrada <= entrada_max and
110
  parcela_min <= total_parcelas <= parcela_max):
111
 
112
+ total_saldo = sum(c['saldo'] for c in combinacao) # CORRIGIDO: 'saldo'
113
  valor_final = round(total_entrada + total_saldo, 2)
114
  diferenca = abs(valor_final - total_credito) # Diferença do valor final pelo crédito (para ordenação)
115
 
 
132
  for idx, (adm, combinacao, _) in enumerate(resultados[:15], 1):
133
  codigos = [str(c.get('codigo', 'N/A')) for c in combinacao]
134
  total_credito = sum(c['valor_credito'] for c in combinacao)
135
+ total_entrada_base = sum(c['entrada'] for c in combinacao) # CORRIGIDO: 'entrada'
136
  total_entrada = total_entrada_base + (total_credito * 0.085)
137
+ total_saldo = sum(c['saldo'] for c in combinacao) # CORRIGIDO: 'saldo'
138
+ total_parcelas = sum(c['valor_parcela'] for c in combinacao) # CORRIGIDO: 'valor_parcela'
139
+ maior_prazo = max(int(c.get('parcelas', 0)) for c in combinacao) # CORRIGIDO: 'parcelas'
140
 
141
  valor_final = round(total_entrada + total_saldo, 2)
142
  credito_real = round(total_credito - total_entrada, 2)
 
161
  """
162
  return resposta
163
 
164
+ # Carrega os dados uma vez quando o aplicativo inicia
165
  carregar_planilha()
166
 
167
  def ajustar_e_buscar(credito_desejado, entrada_desejada, parcela_desejada, administradoras):
 
171
  # Prepara a lista de administradoras para o Gradio
172
  def get_administradoras_options():
173
  if df is not None:
174
+ # CORRIGIDO: usando administradora_id consistentemente
175
+ adm_list = df[df['categoria'].str.lower() == 'imovel']['administradora_id'].unique()
176
  return sorted(adm_list)
177
  return []
178
 
179
  # Criando a interface Gradio
180
  with gr.Blocks(title="Sistema de Busca de Consórcio Imóvel") as demo:
181
+ # ... (o restante do código da interface permanece igual)