Coots commited on
Commit
e09d218
·
verified ·
1 Parent(s): 1139b4c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -22
app.py CHANGED
@@ -5,7 +5,7 @@ import numpy as np
5
  import json
6
  import math
7
  import xgboost as xgb
8
- import os
9
 
10
  app = Flask(__name__, static_folder='.', static_url_path='/')
11
  CORS(app)
@@ -20,11 +20,9 @@ except Exception as e:
20
  print(f"❌ Error loading models: {e}")
21
  raise e
22
 
23
- # Load tile data
24
  with open("tile_catalog.json", "r", encoding="utf-8") as f:
25
  tile_catalog = json.load(f)
26
- with open("tile_sizes.json", "r", encoding="utf-8") as f:
27
- tile_sizes = json.load(f)
28
 
29
  @app.route("/")
30
  def index():
@@ -34,14 +32,14 @@ def index():
34
  def recommend():
35
  try:
36
  data = request.get_json()
37
- tile_type = data.get("tile_type", "").lower()
38
  coverage = float(data.get("coverage", 1))
39
  area = float(data.get("area", 1))
40
  price_range = data.get("price_range", [1, 100])
41
  preferred_sizes = data.get("preferred_sizes", [])
42
 
43
- if coverage <= 0 or area <= 0:
44
- return jsonify({"error": "Please enter valid positive values for area and coverage."}), 400
45
 
46
  features = prepare_features(tile_type, coverage, area, price_range)
47
  xgb_pred = xgb_model.predict(xgb.DMatrix(features))[0]
@@ -64,27 +62,37 @@ def calculate():
64
  data = request.get_json()
65
  tile_type = data.get("tile_type", "").strip().lower()
66
  area = float(data.get("area", 0))
67
- tile_size = data.get("tile_size", "").strip()
68
 
69
  if not tile_type:
70
- return jsonify({"error": "Please select a tile type (e.g., Floor or Wall)."}), 400
71
  if area <= 0:
72
- return jsonify({"error": "Area must be a positive number."}), 400
73
- if tile_size not in tile_sizes:
74
- return jsonify({"error": f"Invalid tile size '{tile_size}'. Please select a valid size."}), 400
 
 
 
75
 
76
- # Fetch tile size info
77
- info = tile_sizes[tile_size]
78
- per_tile_area = info["area_sqft"]
79
- if per_tile_area <= 0:
80
- return jsonify({"error": f"Tile size '{tile_size}' has invalid area data."}), 400
81
 
82
- tiles_needed = math.ceil((area / per_tile_area) * 1.1)
83
- boxes = math.ceil(tiles_needed / info.get("tiles_per_box", 10))
 
84
 
85
- matches = [p for p in tile_catalog if p["type"].lower() == tile_type and p["size"] == tile_size]
 
 
 
 
86
 
87
  return jsonify({
 
 
 
88
  "tiles_needed": tiles_needed,
89
  "boxes_needed": boxes,
90
  "matching_products": matches[:3],
@@ -92,7 +100,7 @@ def calculate():
92
  })
93
  except Exception as e:
94
  print("❌ Error in /calculate:", str(e))
95
- return jsonify({"error": "Please ensure valid tile type, size, and area are provided."}), 500
96
 
97
  def prepare_features(tile_type, coverage, area, price_range):
98
  tile_type_num = 0 if tile_type == "floor" else 1
@@ -111,7 +119,6 @@ def filter_products(tile_type, price_range, preferred_sizes):
111
  continue
112
  if preferred_sizes and product["size"] not in preferred_sizes:
113
  continue
114
-
115
  price_score = 1 - (product["price"] - min_price) / (max_price - min_price + 1e-6)
116
  size_score = 1 if product["size"] in preferred_sizes else 0.5
117
  score = round((price_score + size_score) / 2, 2)
 
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)
 
20
  print(f"❌ Error loading models: {e}")
21
  raise e
22
 
23
+ # Load tile catalog
24
  with open("tile_catalog.json", "r", encoding="utf-8") as f:
25
  tile_catalog = json.load(f)
 
 
26
 
27
  @app.route("/")
28
  def index():
 
32
  def recommend():
33
  try:
34
  data = request.get_json()
35
+ tile_type = data.get("tile_type", "").strip().lower()
36
  coverage = float(data.get("coverage", 1))
37
  area = float(data.get("area", 1))
38
  price_range = data.get("price_range", [1, 100])
39
  preferred_sizes = data.get("preferred_sizes", [])
40
 
41
+ if area <= 0 or coverage <= 0:
42
+ return jsonify({"error": "Please enter valid area and coverage values."}), 400
43
 
44
  features = prepare_features(tile_type, coverage, area, price_range)
45
  xgb_pred = xgb_model.predict(xgb.DMatrix(features))[0]
 
62
  data = request.get_json()
63
  tile_type = data.get("tile_type", "").strip().lower()
64
  area = float(data.get("area", 0))
65
+ tile_size_raw = data.get("tile_size", "").strip()
66
 
67
  if not tile_type:
68
+ return jsonify({"error": "Please select a tile type (e.g., floor, wall)."}), 400
69
  if area <= 0:
70
+ return jsonify({"error": "Area must be greater than 0."}), 400
71
+
72
+ # Extract tile length and width in feet using regex
73
+ match = re.match(r"(\d+(\.\d+)?)\s*(ft|feet)?\s*[xX×*]\s*(\d+(\.\d+)?)\s*(ft|feet)?", tile_size_raw)
74
+ if not match:
75
+ return jsonify({"error": f"Invalid tile size format: '{tile_size_raw}'. Please enter like '2 x 2 ft'."}), 400
76
 
77
+ length_ft = float(match.group(1))
78
+ width_ft = float(match.group(4))
79
+ if length_ft <= 0 or width_ft <= 0:
80
+ return jsonify({"error": "Tile dimensions must be greater than 0."}), 400
 
81
 
82
+ tile_area = length_ft * width_ft # in sq.ft
83
+ tiles_needed = math.ceil((area / tile_area) * 1.1) # +10% buffer
84
+ boxes = math.ceil(tiles_needed / 10) # assuming 10 tiles per box
85
 
86
+ # Filter matching products by type and approximate size
87
+ matches = [
88
+ p for p in tile_catalog
89
+ if p["type"].lower() == tile_type
90
+ ]
91
 
92
  return jsonify({
93
+ "tile_type": tile_type,
94
+ "area_sqft": area,
95
+ "tile_size": f"{length_ft:.2f} ft x {width_ft:.2f} ft",
96
  "tiles_needed": tiles_needed,
97
  "boxes_needed": boxes,
98
  "matching_products": matches[:3],
 
100
  })
101
  except Exception as e:
102
  print("❌ Error in /calculate:", str(e))
103
+ return jsonify({"error": "An error occurred. Please check your input values."}), 500
104
 
105
  def prepare_features(tile_type, coverage, area, price_range):
106
  tile_type_num = 0 if tile_type == "floor" else 1
 
119
  continue
120
  if preferred_sizes and product["size"] not in preferred_sizes:
121
  continue
 
122
  price_score = 1 - (product["price"] - min_price) / (max_price - min_price + 1e-6)
123
  size_score = 1 if product["size"] in preferred_sizes else 0.5
124
  score = round((price_score + size_score) / 2, 2)