File size: 6,195 Bytes
5d4f445
c5a97b3
 
 
5d4f445
f2141ad
 
c038e47
5d4f445
 
07df588
c5a97b3
99aed09
53ae920
1a5aa7c
b4cb87b
99aed09
2598bbd
7a6bd46
 
 
 
2598bbd
 
 
 
 
 
 
c7f2259
2598bbd
 
7a6bd46
3992853
fb309c7
 
3992853
fb309c7
3992853
 
f691033
5d4f445
3b9e0c5
07df588
f691033
2598bbd
c1badbd
108a43e
2598bbd
 
c5a97b3
2fe5b5e
99aed09
d3db32a
 
 
 
 
99aed09
 
d310004
 
 
99aed09
 
f308877
 
 
 
 
 
aff5c22
f308877
 
9b0a7bb
5d4f445
 
 
 
 
9b0a7bb
5d4f445
 
 
9b0a7bb
5d4f445
074db95
9b0a7bb
5d4f445
9b0a7bb
3b9e0c5
074db95
5d4f445
 
c1badbd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2fe5b5e
074db95
 
c1badbd
074db95
2598bbd
c5a97b3
074db95
c1badbd
 
 
78ac961
 
 
074db95
 
4b652b7
1a9e4db
074db95
f2141ad
99aed09
 
3bd1e98
f308877
4d527e1
 
99aed09
 
c4f8c41
205d4a0
65d60d7
 
 
 
3bd1e98
78ac961
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

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 = "<span style='color: gray; font-size: 48px;'>Avaliação de Bens Móveis</span>",
                     description=f"""
                     <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>
                     """)

iface.launch()