fortuala commited on
Commit
0a731d7
·
verified ·
1 Parent(s): 292eaac

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -105
app.py CHANGED
@@ -2,127 +2,98 @@
2
 
3
  import gradio as gr
4
  import pandas as pd
 
5
  from sentence_transformers import SentenceTransformer, util
6
 
7
  # 1) Load your committed Excel database
8
  df = pd.read_excel("BuyWellDataBase.xlsx")
9
 
10
- # 2) Prepare for embedding
11
  df["combined"] = df["Company Name"] + " — " + df["Product or Services"]
12
  model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
13
- embeddings = model.encode(df["combined"].tolist(), convert_to_tensor=True)
14
 
15
- # 3) Define blocked‐brand sector map (fully extended)
16
- BLOCKED = {
17
- # Original “everyday” brands
18
- "amazon": "Online Store",
19
- "booking": "Booking",
20
- "siemens": "Home Appliances",
21
-
22
- # BDS “Act Now” consumer‐boycott targets
23
- "barclays": "Banking",
24
- "bae systems": "Electronics",
25
- "boeing": "Electronics",
26
- "caterpillar": "Electronics",
27
- "elbit systems": "Electronics",
28
- "lockheed martin": "Electronics",
29
- "general dynamics": "Electronics",
30
- "israel aerospace industries": "Electronics",
31
-
32
- # Your added consumer‐boycott targets
33
- "hp": "Electronics",
34
- "hpe": "Electronics",
35
- "chevron": "Energy Providers",
36
- "caltex": "Energy Providers",
37
- "texaco": "Energy Providers",
38
- "carrefour": "Food",
39
- "axa": "Insurance",
40
- "sodastream": "Home Appliances",
41
- "ahava": "Online Store",
42
- "re/max": "Booking",
43
-
44
- # Divestment & exclusion targets
45
- "intel": "Electronics",
46
- "hd hyundai": "Electronics",
47
- "volvo": "Car",
48
- "cat": "Electronics", # Caterpillar
49
- "jcb": "Electronics",
50
- "caf": "Electronics",
51
- "noble energy": "Energy Providers",
52
-
53
- # Pressure targets
54
- "google": "Search Engines",
55
- "airbnb": "Booking",
56
- "expedia": "Booking",
57
- "disney": "Media Outlets",
58
- "teva": "Online Store",
59
-
60
- # Grassroots organic boycott
61
- "mcdonald": "Food",
62
- "burger king": "Food",
63
- "papa john": "Food",
64
- "pizza hut": "Food",
65
- "wix": "Telecom & Internet",
66
- }
67
 
68
  def recommend_store(query: str) -> str:
69
- query_clean = query.strip().lower()
70
- if not query_clean:
71
- return "❗ Please enter what you’d like to buy."
72
-
73
- # 1) Check if the query mentions any blocked brand
74
- for brand, sector in BLOCKED.items():
75
- if brand in query_clean:
76
- # Recommend the top 5 sustainable alternatives in that sector
77
- alts = (
78
- df[df["Sector"] == sector]
79
- .sort_values("Rating", ascending=False)
80
- .head(5)
81
- )
82
- lines = [
83
- f"- **{row['Company Name']}** {row['Product or Services']}\n"
84
- f" Rating: {row['Rating']} | [Website]({row['Website']})"
85
- for _, row in alts.iterrows()
86
- ]
87
- return (
88
- f"### Oops—“{brand.title()}” isn’t in our sustainable list! \n"
89
- f"Here are 5 ethical alternatives in **{sector}**:\n\n"
90
- + "\n".join(lines)
91
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
- # 2) Otherwise, do the normal semantic search
94
- q_emb = model.encode(query, convert_to_tensor=True)
95
- scores = util.cos_sim(q_emb, embeddings)[0]
96
- best = df.iloc[int(scores.argmax())]
97
- return (
98
- f"### {best['Company Name']}\n\n"
99
- f"**Sector:** {best['Sector']}\n\n"
100
- f"**Product / Services:** {best['Product or Services']}\n\n"
101
- f"**Rating:** {best['Rating']}\n\n"
102
- f"**Location:** {best['Google Map Location']}\n\n"
103
- f"**Website:** [Visit site]({best['Website']})"
104
- )
105
 
106
- # 4) Build Gradio UI
107
  with gr.Blocks(title="GoodBuy Guide") as demo:
108
- gr.Markdown(
109
- """
110
- # 🌿 GoodBuy Guide
111
-
112
- Discover ethical, democratic & sustainable alternatives—one “good buy” at a time!
113
-
114
- *Feedback or issues?* 📧 **msalanfortuny@gmail.com**
115
- """
116
- )
117
  with gr.Row():
118
  inp = gr.Textbox(
119
- placeholder="e.g. organic coffee, Amazon Prime, Siemens fridge…",
120
- label="What do you want to buy?"
 
121
  )
122
- btn = gr.Button("Find a Good Buy")
123
- out = gr.Markdown()
124
- btn.click(recommend_store, inp, out)
125
- inp.submit(recommend_store, inp, out)
126
 
127
  if __name__ == "__main__":
128
  demo.launch()
 
2
 
3
  import gradio as gr
4
  import pandas as pd
5
+ import torch
6
  from sentence_transformers import SentenceTransformer, util
7
 
8
  # 1) Load your committed Excel database
9
  df = pd.read_excel("BuyWellDataBase.xlsx")
10
 
11
+ # 2) Prepare the "combined" field and compute embeddings for each row
12
  df["combined"] = df["Company Name"] + " — " + df["Product or Services"]
13
  model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
14
+ row_embeddings = model.encode(df["combined"].tolist(), convert_to_tensor=True)
15
 
16
+ # 3) Build a centroid embedding for each sector
17
+ sectors = df["Sector"].unique().tolist()
18
+ sector_embeddings = {}
19
+ for sector in sectors:
20
+ # indices of rows in this sector
21
+ idxs = df.index[df["Sector"] == sector].tolist()
22
+ # mean of their embeddings
23
+ sector_embeddings[sector] = row_embeddings[idxs].mean(dim=0, keepdim=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  def recommend_store(query: str) -> str:
26
+ q = query.strip()
27
+ if not q:
28
+ return "<p style='color:red;'>❗ Please enter what you’d like to buy.</p>"
29
+
30
+ # 1) Embed the query
31
+ q_emb = model.encode(q, convert_to_tensor=True, normalize_embeddings=True)
32
+
33
+ # 2) Find the best-matching sector via cosine similarity
34
+ sector_sims = {
35
+ sector: util.cos_sim(q_emb, emb).item()
36
+ for sector, emb in sector_embeddings.items()
37
+ }
38
+ best_sector = max(sector_sims, key=sector_sims.get)
39
+
40
+ # 3) Within that sector, score all rows and pick top 5
41
+ mask = df["Sector"] == best_sector
42
+ sector_idxs = df.index[mask].tolist()
43
+ sims = util.cos_sim(q_emb, row_embeddings[sector_idxs])[0]
44
+ top5 = torch.topk(sims, k=min(5, len(sector_idxs))).indices.tolist()
45
+
46
+ # 4) Build an HTML table of the top 5
47
+ rows = []
48
+ for rank_idx in top5:
49
+ df_idx = sector_idxs[rank_idx]
50
+ row = df.loc[df_idx]
51
+ rows.append(f"""
52
+ <tr>
53
+ <td><strong>{row['Company Name']}</strong></td>
54
+ <td>{row['Product or Services']}</td>
55
+ <td style="text-align:center;">{row['Rating']}</td>
56
+ <td>{row['Google Map Location']}</td>
57
+ <td><a href="{row['Website']}" target="_blank">Visit site</a></td>
58
+ </tr>
59
+ """)
60
+ table_html = f"""
61
+ <h3>Top 5 alternatives in <em>{best_sector}</em></h3>
62
+ <table border="1" cellpadding="4" cellspacing="0">
63
+ <thead style="background:#f0f0f0;">
64
+ <tr>
65
+ <th>Company</th>
66
+ <th>Product / Services</th>
67
+ <th>Rating</th>
68
+ <th>Location</th>
69
+ <th>Website</th>
70
+ </tr>
71
+ </thead>
72
+ <tbody>
73
+ {''.join(rows)}
74
+ </tbody>
75
+ </table>
76
+ """
77
 
78
+ return table_html
 
 
 
 
 
 
 
 
 
 
 
79
 
80
+ # 5) Build Gradio UI
81
  with gr.Blocks(title="GoodBuy Guide") as demo:
82
+ gr.HTML("""
83
+ <h1 style="text-align:center; color: #2a7f4f;">🌿 GoodBuy Guide</h1>
84
+ <p style="text-align:center;">Discover ethical, democratic & sustainable alternatives—one “good buy” at a time!</p>
85
+ <p style="text-align:center; font-size:0.9em;">*Feedback or issues?* 📧 <a href="mailto:msalanfortuny@gmail.com">msalanfortuny@gmail.com</a></p>
86
+ """)
 
 
 
 
87
  with gr.Row():
88
  inp = gr.Textbox(
89
+ placeholder="e.g. coffee beans, Amazon Prime, Siemens fridge…",
90
+ label="What do you want to buy?",
91
+ interactive=True
92
  )
93
+ btn = gr.Button("Find a Good Buy", variant="primary")
94
+ out = gr.HTML()
95
+ btn.click(fn=recommend_store, inputs=inp, outputs=out)
96
+ inp.submit(fn=recommend_store, inputs=inp, outputs=out)
97
 
98
  if __name__ == "__main__":
99
  demo.launch()