Coots commited on
Commit
ea92343
Β·
verified Β·
1 Parent(s): 80471bd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +20 -18
app.py CHANGED
@@ -2,13 +2,15 @@ from flask import Flask, request, jsonify, send_from_directory
2
  from flask_cors import CORS
3
  import joblib
4
  import numpy as np
5
- import xgboost as xgb
6
  import math
 
 
7
 
8
  app = Flask(__name__, static_folder='.', static_url_path='/')
9
  CORS(app)
10
 
11
- # Load models
12
  try:
13
  rf = joblib.load("rf_model.pkl")
14
  xgb_model = xgb.Booster()
@@ -18,7 +20,7 @@ except Exception as e:
18
  print(f"❌ Error loading models: {e}")
19
  raise e
20
 
21
- # Hardcoded product catalog
22
  tile_catalog = [
23
  {"name": "Travertino Light Beige", "type": "Floor", "price": 780, "coverage": 15.5, "size": "1200x1200 MM", "url": "https://arqonz.ae/products/6775"},
24
  {"name": "Marquina Glossy Black", "type": "Wall", "price": 620, "coverage": 12.0, "size": "600x600 MM", "url": "https://arqonz.ae/products/6776"},
@@ -47,26 +49,25 @@ def recommend():
47
  tile_type = data.get("tile_type", "").strip().lower()
48
  coverage = float(data.get("coverage", 1))
49
  area = float(data.get("area", 1))
50
- price_range = data.get("price_range", [3, 10000])
51
  preferred_sizes = data.get("preferred_sizes", [])
52
 
53
  if area <= 0 or coverage <= 0:
54
- return jsonify({"error": "Invalid area or coverage"}), 400
55
 
56
  features = prepare_features(tile_type, coverage, area, price_range)
57
  xgb_pred = xgb_model.predict(xgb.DMatrix(features))[0]
58
  rf_pred = rf.predict_proba(features)[0][1]
59
  score = (xgb_pred + rf_pred) / 2
60
 
61
- matches = filter_products(tile_type, price_range, preferred_sizes)
62
-
63
  return jsonify({
64
  "recommendation_score": round(float(score), 3),
65
- "recommended_products": matches[:4],
66
- "total_matches": len(matches)
67
  })
68
  except Exception as e:
69
- print("❌ /recommend error:", e)
70
  return jsonify({"error": "Server error"}), 500
71
 
72
  def prepare_features(tile_type, coverage, area, price_range):
@@ -85,22 +86,23 @@ def filter_products(tile_type, price_range, preferred_sizes):
85
  if not (min_price <= p["price"] <= max_price):
86
  continue
87
 
88
- size_match = False
89
- for size in preferred_sizes:
90
- if similar_size(p["size"], size):
91
- size_match = True
92
  break
93
- if not size_match:
 
94
  continue
95
 
96
  price_score = 1 - (p["price"] - min_price) / (max_price - min_price + 1e-6)
97
  filtered.append({**p, "recommendation_score": round(price_score, 2)})
98
  return sorted(filtered, key=lambda x: x["recommendation_score"], reverse=True)
99
 
100
- def similar_size(size_a, size_b, tolerance=10):
101
  try:
102
- w1, h1 = map(int, size_a.lower().replace("mm", "").split("x"))
103
- w2, h2 = map(int, size_b.lower().replace("mm", "").split("x"))
104
  return abs(w1 - w2) <= tolerance and abs(h1 - h2) <= tolerance
105
  except:
106
  return False
 
2
  from flask_cors import CORS
3
  import joblib
4
  import numpy as np
5
+ import json
6
  import math
7
+ import xgboost as xgb
8
+ import re
9
 
10
  app = Flask(__name__, static_folder='.', static_url_path='/')
11
  CORS(app)
12
 
13
+ # Load ML models
14
  try:
15
  rf = joblib.load("rf_model.pkl")
16
  xgb_model = xgb.Booster()
 
20
  print(f"❌ Error loading models: {e}")
21
  raise e
22
 
23
+ # Product catalog
24
  tile_catalog = [
25
  {"name": "Travertino Light Beige", "type": "Floor", "price": 780, "coverage": 15.5, "size": "1200x1200 MM", "url": "https://arqonz.ae/products/6775"},
26
  {"name": "Marquina Glossy Black", "type": "Wall", "price": 620, "coverage": 12.0, "size": "600x600 MM", "url": "https://arqonz.ae/products/6776"},
 
49
  tile_type = data.get("tile_type", "").strip().lower()
50
  coverage = float(data.get("coverage", 1))
51
  area = float(data.get("area", 1))
52
+ price_range = data.get("price_range", [1, 10000])
53
  preferred_sizes = data.get("preferred_sizes", [])
54
 
55
  if area <= 0 or coverage <= 0:
56
+ return jsonify({"error": "Please enter valid area and coverage values."}), 400
57
 
58
  features = prepare_features(tile_type, coverage, area, price_range)
59
  xgb_pred = xgb_model.predict(xgb.DMatrix(features))[0]
60
  rf_pred = rf.predict_proba(features)[0][1]
61
  score = (xgb_pred + rf_pred) / 2
62
 
63
+ products = filter_products(tile_type, price_range, preferred_sizes)
 
64
  return jsonify({
65
  "recommendation_score": round(float(score), 3),
66
+ "recommended_products": products[:4],
67
+ "total_matches": len(products),
68
  })
69
  except Exception as e:
70
+ print("❌ Error in /recommend:", str(e))
71
  return jsonify({"error": "Server error"}), 500
72
 
73
  def prepare_features(tile_type, coverage, area, price_range):
 
86
  if not (min_price <= p["price"] <= max_price):
87
  continue
88
 
89
+ match_found = False
90
+ for pref in preferred_sizes:
91
+ if similar_size_mm(p["size"], pref):
92
+ match_found = True
93
  break
94
+
95
+ if not match_found:
96
  continue
97
 
98
  price_score = 1 - (p["price"] - min_price) / (max_price - min_price + 1e-6)
99
  filtered.append({**p, "recommendation_score": round(price_score, 2)})
100
  return sorted(filtered, key=lambda x: x["recommendation_score"], reverse=True)
101
 
102
+ def similar_size_mm(a, b, tolerance=10):
103
  try:
104
+ w1, h1 = map(int, a.lower().replace("mm", "").split("x"))
105
+ w2, h2 = map(int, b.lower().replace("mm", "").split("x"))
106
  return abs(w1 - w2) <= tolerance and abs(h1 - h2) <= tolerance
107
  except:
108
  return False