Spaces:
Sleeping
Sleeping
fschwartzer
commited on
Commit
•
601b79b
1
Parent(s):
70be9d3
Update app.py
Browse files
app.py
CHANGED
@@ -1,14 +1,7 @@
|
|
1 |
-
|
2 |
import gradio as gr
|
3 |
import requests
|
4 |
import pandas as pd
|
5 |
-
import re
|
6 |
-
import csv
|
7 |
-
import datetime
|
8 |
from rapidfuzz import process, fuzz
|
9 |
-
import requests
|
10 |
-
from difflib import get_close_matches
|
11 |
-
from fuzzywuzzy import process
|
12 |
|
13 |
bens_df = pd.read_excel('bens_tab.xlsx')
|
14 |
|
@@ -22,128 +15,71 @@ def fetch_data_to_dataframe(query, limit=50, source="mercadolibre"):
|
|
22 |
response = requests.get(BASE_URL, params=params)
|
23 |
if response.status_code == 200:
|
24 |
data = response.json()
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
df['Marketplace'] = "Mercado Livre"
|
31 |
-
return df
|
32 |
return pd.DataFrame()
|
33 |
|
34 |
def refinar_resultados(df):
|
35 |
-
df['Title'] = df['Title'].astype(str)
|
36 |
df_refinado = df[~df['Title'].str.contains("kit", case=False, na=False)]
|
37 |
-
|
38 |
-
df_refinado = df_refinado[~df_refinado['Title'].str.contains(padrao_unidades, case=False, regex=True, na=False)]
|
39 |
return df_refinado
|
40 |
|
41 |
def get_best_match(query, choices, limit=15):
|
42 |
matches = process.extract(query, choices, scorer=fuzz.WRatio, limit=limit)
|
43 |
-
return [match[0] for match in matches if match[1] >
|
44 |
|
45 |
def filtrar_itens_similares(df, termo_pesquisa, limit=15):
|
46 |
-
|
47 |
-
|
48 |
-
titulos_similares = get_best_match(termo_pesquisa, titulos, limit=limit)
|
49 |
-
df_filtrado = df[df['Title'].isin(titulos_similares)]
|
50 |
-
return df_filtrado
|
51 |
|
52 |
def calcular_fator_avaliacao(titulo, EC, PU):
|
53 |
-
# Buscar VU e VR baseado no título
|
54 |
filtered_df = bens_df[bens_df['TITULO'] == titulo]
|
55 |
if filtered_df.empty:
|
56 |
-
|
57 |
|
58 |
bem_info = filtered_df.iloc[0]
|
59 |
-
VU = bem_info['VIDA_UTIL']
|
60 |
-
|
61 |
-
|
62 |
-
pontuacoes = {'Excelente': 10, 'Bom': 8, 'Regular': 5, 'Péssimo': 2}
|
63 |
-
ec_pontuacao = pontuacoes[EC]
|
64 |
|
65 |
-
PU = float(PU)
|
66 |
-
PVU = 10 - ((PU - 1) * (10 / VU))
|
67 |
-
PVU = min(PVU, 10)
|
68 |
-
|
69 |
-
PUB = 10 - (((VU - PU) - 1) * (10 / VU))
|
70 |
-
PUB = min(PUB, 10)
|
71 |
-
|
72 |
fator_avaliacao = max((4 * ec_pontuacao + 6 * PVU - 3 * PUB) / 100, VR)
|
73 |
return fator_avaliacao
|
74 |
|
75 |
def select_nearest_items(df):
|
76 |
-
|
77 |
-
if len(mode_prices) > 0:
|
78 |
-
target_price = mode_prices.min() # Choose the smallest mode if multiple
|
79 |
-
else:
|
80 |
-
target_price = df['Price'].median() # Fallback to median if no mode
|
81 |
-
|
82 |
df['Distance'] = (df['Price'] - target_price).abs()
|
83 |
-
|
84 |
-
|
85 |
-
included_marketplaces = set()
|
86 |
-
nearest_items = []
|
87 |
-
for _, row in df_sorted.iterrows():
|
88 |
-
if row['Marketplace'] not in included_marketplaces:
|
89 |
-
nearest_items.append(row)
|
90 |
-
included_marketplaces.add(row['Marketplace'])
|
91 |
-
if len(included_marketplaces) >= 5:
|
92 |
-
break
|
93 |
-
|
94 |
-
return pd.DataFrame(nearest_items)
|
95 |
-
|
96 |
-
def search_with_fallback(query, df, limit=15):
|
97 |
-
# Split the query into parts
|
98 |
-
query_parts = query.split()
|
99 |
-
|
100 |
-
# Start with the most specific search (full query)
|
101 |
-
specificities = [
|
102 |
-
" ".join(query_parts[i:]) for i in range(len(query_parts))
|
103 |
-
]
|
104 |
|
105 |
-
for specificity in specificities:
|
106 |
-
df_filtrado = filtrar_itens_similares(df, specificity, limit=limit)
|
107 |
-
if not df_filtrado.empty:
|
108 |
-
# If we find results at this level of specificity, return them
|
109 |
-
return df_filtrado
|
110 |
-
|
111 |
-
# If no results are found at any level of specificity, return an empty DataFrame
|
112 |
-
return pd.DataFrame()
|
113 |
-
|
114 |
def integrated_app(query, titulo, EC, PU):
|
115 |
-
df_mercadolibre = fetch_data_to_dataframe(query
|
116 |
df_combined = pd.concat([df_mercadolibre, data_crawler], ignore_index=True)
|
117 |
-
|
118 |
if df_combined.empty:
|
119 |
return "Nenhum dado encontrado. Tente uma consulta diferente.", pd.DataFrame()
|
120 |
|
121 |
df_refined = refinar_resultados(df_combined)
|
122 |
-
|
123 |
-
df_similares = search_with_fallback(query, df_refined)
|
124 |
-
|
125 |
if df_similares.empty:
|
126 |
return "Nenhum item similar encontrado.", pd.DataFrame()
|
127 |
-
else:
|
128 |
-
df_nearest = select_nearest_items(df_similares)
|
129 |
-
mean_price = df_nearest['Price'].mean()
|
130 |
-
fator_avaliacao = calcular_fator_avaliacao(titulo, EC, PU)
|
131 |
-
valor_avaliacao = mean_price * fator_avaliacao
|
132 |
-
return f"Valor Médio do Bem: R$ {mean_price:.2f}, Fator de Avaliação: {fator_avaliacao*100:.2f}%, Valor de Avaliação: R$ {valor_avaliacao:.2f}", df_nearest
|
133 |
|
134 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
|
136 |
iface = gr.Interface(fn=integrated_app,
|
137 |
inputs=[gr.Textbox(label="Digite sua consulta"),
|
138 |
-
gr.Dropdown(label="Classificação Contábil do Bem", choices=
|
139 |
gr.Radio(label="Estado de Conservação do Bem", choices=['Excelente', 'Bom', 'Regular', 'Péssimo'], value="Excelente"),
|
140 |
-
gr.Number(label="Período utilizado (anos)", value=1)
|
141 |
-
],
|
142 |
outputs=[gr.Textbox(label="Cálculo"), gr.Dataframe(label="Resultados da Pesquisa")],
|
143 |
theme=gr.themes.Monochrome(),
|
144 |
-
title
|
145 |
-
description=
|
146 |
-
<p style="text-align: left;"><b><span style='color: gray; font-size: 40px;'>aval</span><span style='color: black; font-size: 40px;'>ia</span><span style='color: gray; font-size: 40px;'>.se</b></p>
|
147 |
-
""")
|
148 |
|
149 |
iface.launch()
|
|
|
|
|
1 |
import gradio as gr
|
2 |
import requests
|
3 |
import pandas as pd
|
|
|
|
|
|
|
4 |
from rapidfuzz import process, fuzz
|
|
|
|
|
|
|
5 |
|
6 |
bens_df = pd.read_excel('bens_tab.xlsx')
|
7 |
|
|
|
15 |
response = requests.get(BASE_URL, params=params)
|
16 |
if response.status_code == 200:
|
17 |
data = response.json()
|
18 |
+
items = data.get('results', [])
|
19 |
+
df = pd.DataFrame(items)[['title', 'price', 'currency_id', 'condition', 'permalink']]
|
20 |
+
df.columns = ['Title', 'Price', 'Currency', 'Condition', 'Link']
|
21 |
+
df['Marketplace'] = "Mercado Livre"
|
22 |
+
return df
|
|
|
|
|
23 |
return pd.DataFrame()
|
24 |
|
25 |
def refinar_resultados(df):
|
|
|
26 |
df_refinado = df[~df['Title'].str.contains("kit", case=False, na=False)]
|
27 |
+
df_refinado = df_refinado[~df_refinado['Title'].str.contains(r'\b(\d+)\s*(unidade|unidades|pacote|pacotes|caixa|caixas)\b', case=False, regex=True)]
|
|
|
28 |
return df_refinado
|
29 |
|
30 |
def get_best_match(query, choices, limit=15):
|
31 |
matches = process.extract(query, choices, scorer=fuzz.WRatio, limit=limit)
|
32 |
+
return [match[0] for match in matches if match[1] > 70]
|
33 |
|
34 |
def filtrar_itens_similares(df, termo_pesquisa, limit=15):
|
35 |
+
titulos_similares = get_best_match(termo_pesquisa, df['Title'].tolist(), limit=limit)
|
36 |
+
return df[df['Title'].isin(titulos_similares)]
|
|
|
|
|
|
|
37 |
|
38 |
def calcular_fator_avaliacao(titulo, EC, PU):
|
|
|
39 |
filtered_df = bens_df[bens_df['TITULO'] == titulo]
|
40 |
if filtered_df.empty:
|
41 |
+
return None # Or handle the error as needed
|
42 |
|
43 |
bem_info = filtered_df.iloc[0]
|
44 |
+
VU, VR = bem_info['VIDA_UTIL'], bem_info['VALOR_RESIDUAL']
|
45 |
+
ec_pontuacao = {'Excelente': 10, 'Bom': 8, 'Regular': 5, 'Péssimo': 2}[EC]
|
|
|
|
|
|
|
46 |
|
47 |
+
PU, PVU, PUB = float(PU), min(10 - ((PU - 1) * (10 / VU)), 10), min(10 - (((VU - PU) - 1) * (10 / VU)), 10)
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
fator_avaliacao = max((4 * ec_pontuacao + 6 * PVU - 3 * PUB) / 100, VR)
|
49 |
return fator_avaliacao
|
50 |
|
51 |
def select_nearest_items(df):
|
52 |
+
target_price = df['Price'].mode().min() if not df['Price'].mode().empty else df['Price'].median()
|
|
|
|
|
|
|
|
|
|
|
53 |
df['Distance'] = (df['Price'] - target_price).abs()
|
54 |
+
return pd.DataFrame([row for _, row in df.sort_values('Distance').iterrows() if row['Marketplace'] not in set()]).head(5)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
def integrated_app(query, titulo, EC, PU):
|
57 |
+
df_mercadolibre = fetch_data_to_dataframe(query)
|
58 |
df_combined = pd.concat([df_mercadolibre, data_crawler], ignore_index=True)
|
|
|
59 |
if df_combined.empty:
|
60 |
return "Nenhum dado encontrado. Tente uma consulta diferente.", pd.DataFrame()
|
61 |
|
62 |
df_refined = refinar_resultados(df_combined)
|
63 |
+
df_similares = filtrar_itens_similares(df_refined, query)
|
|
|
|
|
64 |
if df_similares.empty:
|
65 |
return "Nenhum item similar encontrado.", pd.DataFrame()
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
|
67 |
+
fator_avaliacao = calcular_fator_avaliacao(titulo, EC, PU)
|
68 |
+
if fator_avaliacao is None:
|
69 |
+
return "Erro ao calcular o fator de avaliação.", pd.DataFrame()
|
70 |
+
|
71 |
+
df_nearest = select_nearest_items(df_similares)
|
72 |
+
valor_avaliacao = df_nearest['Price'].mean() * fator_avaliacao
|
73 |
+
return f"Valor Médio do Bem: R$ {df_nearest['Price'].mean():.2f}, Fator de Avaliação: {fator_avaliacao*100:.2f}%, Valor de Avaliação: R$ {valor_avaliacao:.2f}", df_nearest
|
74 |
|
75 |
iface = gr.Interface(fn=integrated_app,
|
76 |
inputs=[gr.Textbox(label="Digite sua consulta"),
|
77 |
+
gr.Dropdown(label="Classificação Contábil do Bem", choices=bens_df['TITULO'].unique().tolist(), value="MOBILIÁRIO EM GERAL"),
|
78 |
gr.Radio(label="Estado de Conservação do Bem", choices=['Excelente', 'Bom', 'Regular', 'Péssimo'], value="Excelente"),
|
79 |
+
gr.Number(label="Período utilizado (anos)", value=1)],
|
|
|
80 |
outputs=[gr.Textbox(label="Cálculo"), gr.Dataframe(label="Resultados da Pesquisa")],
|
81 |
theme=gr.themes.Monochrome(),
|
82 |
+
title="<span style='color: gray; font-size: 48px;'>Avaliação de Bens Móveis</span>",
|
83 |
+
description="""<p style="text-align: left;"><b><span style='color: gray; font-size: 40px;'>aval</span><span style='color: black; font-size: 40px;'>ia</span><span style='color: gray; font-size: 40px;'>.se</b></p>""")
|
|
|
|
|
84 |
|
85 |
iface.launch()
|