import gradio as gr import requests import pandas as pd import re import csv import datetime from rapidfuzz import process, fuzz import requests from difflib import get_close_matches from fuzzywuzzy import process bens_df = pd.read_excel('bens_tab.xlsx') data_crawler = pd.read_csv('data_crawler.csv', index_col=False) data_crawler = data_crawler[['Title', 'Price', 'Currency', 'Condition', 'Link', 'Marketplace']] def fetch_data_to_dataframe(query, limit=50, source="mercadolibre"): if source == "mercadolibre": BASE_URL = "https://api.mercadolibre.com/sites/MLB/search" params = {'q': query, 'limit': limit} response = requests.get(BASE_URL, params=params) if response.status_code == 200: data = response.json() if 'results' in data: items = data['results'] df = pd.DataFrame(items) df = df[['title', 'price', 'currency_id', 'condition', 'permalink']] df.columns = ['Title', 'Price', 'Currency', 'Condition', 'Link'] df['Marketplace'] = "Mercado Livre" return df return pd.DataFrame() def refinar_resultados(df): df['Title'] = df['Title'].astype(str) df_refinado = df[~df['Title'].str.contains("kit", case=False, na=False)] padrao_unidades = r'\b(\d+)\s*(unidade|unidades|pacote|pacotes|caixa|caixas)\b' df_refinado = df_refinado[~df_refinado['Title'].str.contains(padrao_unidades, case=False, regex=True, na=False)] return df_refinado def get_best_match(query, choices, limit=15): matches = process.extract(query, choices, scorer=fuzz.WRatio, limit=limit) return [match[0] for match in matches if match[1] > 30] def filtrar_itens_similares(df, termo_pesquisa, limit=15): titulos = df['Title'].tolist() # Use RapidFuzz for improved performance and fuzzy matching titulos_similares = get_best_match(termo_pesquisa, titulos, limit=limit) df_filtrado = df[df['Title'].isin(titulos_similares)] return df_filtrado def calcular_fator_avaliacao(titulo, EC, PU): # Buscar VU e VR baseado no título filtered_df = bens_df[bens_df['TITULO'] == titulo] if filtered_df.empty: raise ValueError(f"Nenhum bem encontrado com o título: {titulo}") bem_info = filtered_df.iloc[0] VU = bem_info['VIDA_UTIL'] VR = bem_info['VALOR_RESIDUAL'] pontuacoes = {'Excelente': 10, 'Bom': 8, 'Regular': 5, 'Péssimo': 2} ec_pontuacao = pontuacoes[EC] PU = float(PU) PVU = 10 - ((PU - 1) * (10 / VU)) PVU = min(PVU, 10) PUB = 10 - (((VU - PU) - 1) * (10 / VU)) PUB = min(PUB, 10) fator_avaliacao = max((4 * ec_pontuacao + 6 * PVU - 3 * PUB) / 100, VR) return fator_avaliacao def select_nearest_items(df): mode_prices = df['Price'].mode() if len(mode_prices) > 0: target_price = mode_prices.min() # Choose the smallest mode if multiple else: target_price = df['Price'].median() # Fallback to median if no mode df['Distance'] = (df['Price'] - target_price).abs() df_sorted = df.sort_values('Distance') included_marketplaces = set() nearest_items = [] for _, row in df_sorted.iterrows(): if row['Marketplace'] not in included_marketplaces: nearest_items.append(row) included_marketplaces.add(row['Marketplace']) if len(included_marketplaces) >= 5: break return pd.DataFrame(nearest_items) def search_with_fallback(query, df, limit=15): # Split the query into parts query_parts = query.split() # Start with the most specific search (full query) specificities = [ " ".join(query_parts[i:]) for i in range(len(query_parts)) ] for specificity in specificities: df_filtrado = filtrar_itens_similares(df, specificity, limit=limit) if not df_filtrado.empty: # If we find results at this level of specificity, return them return df_filtrado # If no results are found at any level of specificity, return an empty DataFrame return pd.DataFrame() def integrated_app(query, titulo, EC, PU): df_mercadolibre = fetch_data_to_dataframe(query, 50, "mercadolibre") df_combined = pd.concat([df_mercadolibre, data_crawler], ignore_index=True) if df_combined.empty: return "Nenhum dado encontrado. Tente uma consulta diferente.", pd.DataFrame() df_refined = refinar_resultados(df_combined) # Use the new search_with_fallback function df_similares = search_with_fallback(query, df_refined) if df_similares.empty: return "Nenhum item similar encontrado.", pd.DataFrame() else: df_nearest = select_nearest_items(df_similares) mean_price = df_nearest['Price'].mean() fator_avaliacao = calcular_fator_avaliacao(titulo, EC, PU) valor_avaliacao = mean_price * fator_avaliacao 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 titulos = bens_df['TITULO'].unique().tolist() iface = gr.Interface(fn=integrated_app, inputs=[gr.Textbox(label="Digite sua consulta"), gr.Dropdown(label="Classificação Contábil do Bem", choices=titulos, value="MOBILIÁRIO EM GERAL"), gr.Radio(label="Estado de Conservação do Bem", choices=['Excelente', 'Bom', 'Regular', 'Péssimo'], value="Excelente"), gr.Number(label="Período utilizado (anos)", value=1) ], outputs=[gr.Textbox(label="Cálculo"), gr.Dataframe(label="Resultados da Pesquisa")], theme=gr.themes.Monochrome(), title = "Avaliação de Bens Móveis", description=f"""
avalia.se
""") iface.launch()