Coots commited on
Commit
9798986
Β·
verified Β·
1 Parent(s): 74136c1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +55 -36
app.py CHANGED
@@ -8,17 +8,18 @@ from fpdf import FPDF
8
  import tempfile
9
  from deep_translator import GoogleTranslator
10
  import warnings
11
- import xgboost as xgb # βœ… Correct import for native XGBoost model
12
 
13
  warnings.filterwarnings("ignore")
14
 
15
- # βœ… Load models
16
  xgb_model = xgb.Booster()
17
- xgb_model.load_model("xgb_model.json") # βœ… Load native .json format
18
 
 
19
  rf = joblib.load("rf_model.pkl")
20
 
21
- # βœ… Load catalog and sizes
22
  with open("tile_catalog.json", "r", encoding="utf-8") as f:
23
  tile_catalog = json.load(f)
24
 
@@ -50,29 +51,30 @@ def create_pdf(text):
50
  return tmp.name
51
 
52
  def extract_tile_area(msg, unit):
53
- msg = msg.lower().replace("Γ—", "x").replace("into", "x").replace("*", "x")
54
- msg = msg.replace("mm", "").replace("ft", "").replace("feet", "").strip()
55
- if "x" in msg:
56
- parts = msg.split("x")
57
- if len(parts) == 2:
58
- try:
59
- val1 = float(re.sub(r"[^\d.]", "", parts[0]))
60
- val2 = float(re.sub(r"[^\d.]", "", parts[1]))
61
- if unit == "mm":
62
- sqft = (val1 * val2) / 92903.04
63
- else:
64
- sqft = val1 * val2
65
- return round(sqft, 2)
66
- except:
67
- return None
 
 
 
68
  return None
69
 
70
  def chat_fn(message, history, user_state={}):
71
- # Reset state if user types Floor or Wall
72
  if message.strip().lower() in ["floor", "wall"]:
73
  user_state.clear()
74
 
75
- # Language detection
76
  if "lang" not in user_state:
77
  try:
78
  user_state["lang"] = GoogleTranslator(source="auto", target="en").detect(message)
@@ -81,7 +83,6 @@ def chat_fn(message, history, user_state={}):
81
  lang = user_state["lang"]
82
  def reply(text): return translate(text, lang)
83
 
84
- # Handle PDF command
85
  if message.strip().lower() in ["pdf", "report", "download"]:
86
  if "summary" in user_state:
87
  pdf_path = create_pdf(user_state["summary"])
@@ -89,7 +90,6 @@ def chat_fn(message, history, user_state={}):
89
  else:
90
  return reply("No estimate yet. Please start by typing 'Floor' or 'Wall'."), None, user_state
91
 
92
- # Start flow
93
  if "step" not in user_state:
94
  if message.lower() in ["floor", "wall"]:
95
  user_state["tile_type"] = message.capitalize()
@@ -111,12 +111,12 @@ def chat_fn(message, history, user_state={}):
111
  user_state["unit"] = message.lower()
112
  user_state["step"] = "get_tile_size"
113
  unit_label = "mm" if user_state["unit"] == "mm" else "feet"
114
- return reply(f"Please enter the tile size in {unit_label} (e.g. 600 x 600):"), None, user_state
115
 
116
  if user_state["step"] == "get_tile_size":
117
  area = extract_tile_area(message, user_state["unit"])
118
  if area is None:
119
- return reply("I couldn’t understand that size. Try something like 600 x 600 or 2 x 2."), None, user_state
120
 
121
  user_state["tile_area"] = area
122
  user_state["step"] = "done"
@@ -163,20 +163,39 @@ def chat_fn(message, history, user_state={}):
163
 
164
  return reply("Type 'Floor' or 'Wall' to begin a new estimate."), None, user_state
165
 
166
- # βœ… Launch with clean intro
167
- with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  chatbot = gr.ChatInterface(
169
  fn=chat_fn,
170
- title="🧱 TileBot – Your Tile Estimation Assistant",
171
- description=(
172
- "🧱 TileBot is here to help you estimate tiles for your space.\n\n"
173
- "Start by telling me if you're working on a Floor or Wall. Then share your room size and tile size in mm or feet β€” "
174
- "I'll do the rest.\n\n"
175
- "I’ll calculate how many tiles you need, recommend suitable products, and give you a PDF report.\n\n"
176
- "Type 'Floor' or 'Wall' to begin!"
177
- ),
178
  type="messages",
179
- additional_outputs=[gr.File(label="πŸ“„ Download Report")]
 
 
 
 
 
 
 
 
 
 
 
180
  )
181
 
182
  demo.launch()
 
8
  import tempfile
9
  from deep_translator import GoogleTranslator
10
  import warnings
11
+ import xgboost as xgb
12
 
13
  warnings.filterwarnings("ignore")
14
 
15
+ # Load XGBoost model (native JSON format)
16
  xgb_model = xgb.Booster()
17
+ xgb_model.load_model("xgb_model.json")
18
 
19
+ # Load Random Forest model
20
  rf = joblib.load("rf_model.pkl")
21
 
22
+ # Load tile catalog and sizes
23
  with open("tile_catalog.json", "r", encoding="utf-8") as f:
24
  tile_catalog = json.load(f)
25
 
 
51
  return tmp.name
52
 
53
  def extract_tile_area(msg, unit):
54
+ msg = msg.lower().replace("feet", "").replace("ft", "").replace("mm", "").strip()
55
+ parts = re.split(r"\s*[xΓ—*into]+\s*", msg)
56
+ if len(parts) == 2:
57
+ try:
58
+ val1 = float(re.sub(r"[^\d.]", "", parts[0]))
59
+ val2 = float(re.sub(r"[^\d.]", "", parts[1]))
60
+ if unit == "mm":
61
+ sqft = (val1 * val2) / 92903.04
62
+ else:
63
+ sqft = val1 * val2
64
+ return round(sqft, 2)
65
+ except:
66
+ return None
67
+ elif len(parts) == 1:
68
+ try:
69
+ return float(parts[0]) # Direct sqft entry
70
+ except:
71
+ return None
72
  return None
73
 
74
  def chat_fn(message, history, user_state={}):
 
75
  if message.strip().lower() in ["floor", "wall"]:
76
  user_state.clear()
77
 
 
78
  if "lang" not in user_state:
79
  try:
80
  user_state["lang"] = GoogleTranslator(source="auto", target="en").detect(message)
 
83
  lang = user_state["lang"]
84
  def reply(text): return translate(text, lang)
85
 
 
86
  if message.strip().lower() in ["pdf", "report", "download"]:
87
  if "summary" in user_state:
88
  pdf_path = create_pdf(user_state["summary"])
 
90
  else:
91
  return reply("No estimate yet. Please start by typing 'Floor' or 'Wall'."), None, user_state
92
 
 
93
  if "step" not in user_state:
94
  if message.lower() in ["floor", "wall"]:
95
  user_state["tile_type"] = message.capitalize()
 
111
  user_state["unit"] = message.lower()
112
  user_state["step"] = "get_tile_size"
113
  unit_label = "mm" if user_state["unit"] == "mm" else "feet"
114
+ return reply(f"Please enter the tile size in {unit_label} (e.g. 600 x 600 or 2 x 2 or 4):"), None, user_state
115
 
116
  if user_state["step"] == "get_tile_size":
117
  area = extract_tile_area(message, user_state["unit"])
118
  if area is None:
119
+ return reply("I couldn’t understand that size. Try something like 600 x 600 or 2 x 2 or 4."), None, user_state
120
 
121
  user_state["tile_area"] = area
122
  user_state["step"] = "done"
 
163
 
164
  return reply("Type 'Floor' or 'Wall' to begin a new estimate."), None, user_state
165
 
166
+
167
+ # --- Modern Gradio UI with Theme ---
168
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", radius_size="full")) as demo:
169
+ gr.Markdown(
170
+ """
171
+ # 🧱 <span style="color:#3B82F6">TileBot</span> – Smart Tile Estimator
172
+ Welcome! I'm here to help you estimate tile needs for your floor or wall.
173
+
174
+ πŸ‘‰ Start by typing **"Floor"** or **"Wall"**
175
+ πŸ“ Then give me the **area** and **tile size** in `mm` or `ft`
176
+ ✏️ Example: `600 x 600`, `2 x 2`, or just `4` sq.ft
177
+ πŸ“‹ I’ll recommend tiles and generate a **PDF Report**!
178
+ """,
179
+ elem_id="header"
180
+ )
181
+
182
  chatbot = gr.ChatInterface(
183
  fn=chat_fn,
184
+ title=None,
185
+ description=None,
 
 
 
 
 
 
186
  type="messages",
187
+ chatbot=gr.Chatbot(height=500, bubble_full_width=False),
188
+ additional_outputs=[gr.File(label="πŸ“„ Download Report")],
189
+ clear_btn="Clear",
190
+ )
191
+
192
+ gr.Markdown(
193
+ """
194
+ ---
195
+ πŸ’‘ Tip: Type `"pdf"` anytime to get a downloadable report.
196
+ πŸš€ Need a new estimate? Just say `"Floor"` or `"Wall"` to start over.
197
+ """,
198
+ elem_id="footer"
199
  )
200
 
201
  demo.launch()