Satwickchikkala1 commited on
Commit
1f47760
Β·
verified Β·
1 Parent(s): 04acd78

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +289 -0
app.py ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import re
4
+ import numpy as np
5
+ from typing import List, Dict, Any
6
+
7
+ # Load and clean the dataset
8
+ df = pd.read_csv("indian_car_info.csv")
9
+
10
+ # Clean brand and model columns
11
+ df["brand"] = df["brand"].str.strip().str.lower()
12
+ df["model"] = df["model"].str.strip()
13
+ df["features"] = df["features"].astype(str).str.lower()
14
+
15
+ # Control long responses
16
+ MAX_TOTAL_CHARACTERS = 3000
17
+
18
+ def extract_numbers(text: str) -> List[float]:
19
+ """Extract all numbers from text"""
20
+ return [float(x) for x in re.findall(r'\d+\.?\d*', text)]
21
+
22
+ def find_brand_mentions(query: str) -> List[str]:
23
+ """Find all brand mentions in query"""
24
+ unique_brands = df["brand"].unique()
25
+ return [brand for brand in unique_brands if brand in query.lower()]
26
+
27
+ def find_model_mentions(query: str) -> List[str]:
28
+ """Find all model mentions in query"""
29
+ unique_models = df["model"].str.lower().unique()
30
+ return [model for model in unique_models if model.lower() in query.lower()]
31
+
32
+ def extract_price_range(query: str) -> tuple:
33
+ """Extract price range from query"""
34
+ min_price, max_price = None, None
35
+
36
+ # Pattern for "under X", "below X", "less than X"
37
+ under_match = re.search(r'(?:under|below|less than|up to)\s*β‚Ή?(\d+)', query.lower())
38
+ if under_match:
39
+ max_price = float(under_match.group(1))
40
+
41
+ # Pattern for "above X", "more than X", "at least X"
42
+ above_match = re.search(r'(?:above|more than|at least|over)\s*β‚Ή?(\d+)', query.lower())
43
+ if above_match:
44
+ min_price = float(above_match.group(1))
45
+
46
+ # Pattern for "between X and Y"
47
+ between_match = re.search(r'between\s*β‚Ή?(\d+)\s*(?:and|to)\s*β‚Ή?(\d+)', query.lower())
48
+ if between_match:
49
+ min_price = float(between_match.group(1))
50
+ max_price = float(between_match.group(2))
51
+
52
+ # Pattern for "around X", "approximately X"
53
+ around_match = re.search(r'(?:around|approximately|about)\s*β‚Ή?(\d+)', query.lower())
54
+ if around_match:
55
+ target = float(around_match.group(1))
56
+ min_price = target - 2
57
+ max_price = target + 2
58
+
59
+ return min_price, max_price
60
+
61
+ def extract_mileage_range(query: str) -> tuple:
62
+ """Extract mileage requirements from query"""
63
+ min_mileage, max_mileage = None, None
64
+
65
+ # Look for mileage-related keywords
66
+ mileage_keywords = ['mileage', 'fuel efficiency', 'kmpl', 'fuel economy']
67
+ has_mileage_context = any(keyword in query.lower() for keyword in mileage_keywords)
68
+
69
+ if has_mileage_context:
70
+ # Pattern for "above X kmpl", "more than X kmpl"
71
+ above_match = re.search(r'(?:above|more than|at least|over)\s*(\d+)', query.lower())
72
+ if above_match:
73
+ min_mileage = float(above_match.group(1))
74
+
75
+ # Pattern for "below X kmpl", "under X kmpl"
76
+ below_match = re.search(r'(?:below|under|less than)\s*(\d+)', query.lower())
77
+ if below_match:
78
+ max_mileage = float(below_match.group(1))
79
+
80
+ return min_mileage, max_mileage
81
+
82
+ def extract_features(query: str) -> List[str]:
83
+ """Extract feature requirements from query"""
84
+ feature_keywords = [
85
+ "sunroof", "automatic", "manual", "cruise control", "abs", "airbags",
86
+ "android auto", "touchscreen", "rear camera", "parking sensor",
87
+ "bluetooth", "usb", "keyless", "push button", "climate control",
88
+ "leather seats", "alloy wheels", "fog lights", "power steering",
89
+ "power windows", "central locking", "music system", "navigation"
90
+ ]
91
+
92
+ return [feat for feat in feature_keywords if feat in query.lower()]
93
+
94
+ def get_comparison_cars(query: str) -> List[Dict]:
95
+ """Handle comparison queries"""
96
+ # Look for comparison keywords
97
+ comparison_words = ['vs', 'versus', 'compare', 'comparison', 'better', 'best']
98
+ if not any(word in query.lower() for word in comparison_words):
99
+ return []
100
+
101
+ brands = find_brand_mentions(query)
102
+ models = find_model_mentions(query)
103
+
104
+ if len(brands) >= 2 or len(models) >= 2:
105
+ # Return cars for comparison
106
+ if models:
107
+ return df[df["model"].str.lower().isin(models)].to_dict('records')
108
+ else:
109
+ return df[df["brand"].isin(brands)].to_dict('records')
110
+
111
+ return []
112
+
113
+ def handle_specific_questions(query: str) -> str:
114
+ """Handle specific question types"""
115
+ query_lower = query.lower()
116
+
117
+ # Price questions
118
+ if any(word in query_lower for word in ['cheapest', 'lowest price', 'most affordable']):
119
+ cheapest = df.loc[df['price_lakh'].idxmin()]
120
+ return f"πŸ’° Cheapest car: {cheapest['brand'].title()} {cheapest['model']} at β‚Ή{cheapest['price_lakh']} Lakh"
121
+
122
+ if any(word in query_lower for word in ['most expensive', 'highest price', 'premium']):
123
+ expensive = df.loc[df['price_lakh'].idxmax()]
124
+ return f"πŸ’Ž Most expensive car: {expensive['brand'].title()} {expensive['model']} at β‚Ή{expensive['price_lakh']} Lakh"
125
+
126
+ # Mileage questions
127
+ if any(word in query_lower for word in ['best mileage', 'highest mileage', 'most fuel efficient']):
128
+ best_mileage = df.loc[df['mileage_kmpl'].idxmax()]
129
+ return f"β›½ Best mileage car: {best_mileage['brand'].title()} {best_mileage['model']} with {best_mileage['mileage_kmpl']} kmpl"
130
+
131
+ if any(word in query_lower for word in ['worst mileage', 'lowest mileage', 'least fuel efficient']):
132
+ worst_mileage = df.loc[df['mileage_kmpl'].idxmin()]
133
+ return f"β›½ Lowest mileage car: {worst_mileage['brand'].title()} {worst_mileage['model']} with {worst_mileage['mileage_kmpl']} kmpl"
134
+
135
+ # Count questions
136
+ if any(word in query_lower for word in ['how many', 'count', 'number of']):
137
+ if any(brand in query_lower for brand in df['brand'].unique()):
138
+ brand = next(brand for brand in df['brand'].unique() if brand in query_lower)
139
+ count = len(df[df['brand'] == brand])
140
+ return f"πŸ“Š {brand.title()} has {count} cars in our database"
141
+ else:
142
+ return f"πŸ“Š Total cars in database: {len(df)}"
143
+
144
+ # Average questions
145
+ if 'average' in query_lower:
146
+ if 'price' in query_lower:
147
+ avg_price = df['price_lakh'].mean()
148
+ return f"πŸ“Š Average car price: β‚Ή{avg_price:.2f} Lakh"
149
+ elif 'mileage' in query_lower:
150
+ avg_mileage = df['mileage_kmpl'].mean()
151
+ return f"πŸ“Š Average mileage: {avg_mileage:.2f} kmpl"
152
+
153
+ # Brand-specific questions
154
+ brands = find_brand_mentions(query)
155
+ if brands and any(word in query_lower for word in ['models', 'variants', 'options']):
156
+ brand = brands[0]
157
+ brand_cars = df[df['brand'] == brand]
158
+ models = brand_cars['model'].unique()
159
+ return f"πŸš— {brand.title()} models: {', '.join(models)}"
160
+
161
+ return ""
162
+
163
+ def format_car_details(car: Dict, show_features: bool = True) -> str:
164
+ """Format car details for display"""
165
+ features_text = ""
166
+ if show_features and 'features' in car:
167
+ features = car['features'][:200] + "..." if len(car['features']) > 200 else car['features']
168
+ features_text = f"- Features: {features.title()}\n"
169
+
170
+ return f"""πŸš— {car['brand'].title()} {car['model']}
171
+ - Engine: {car['engine']}
172
+ - Mileage: {car['mileage_kmpl']} kmpl
173
+ - Price: β‚Ή{car['price_lakh']} Lakh
174
+ {features_text}"""
175
+
176
+ def answer_question(query: str) -> str:
177
+ if not query.strip():
178
+ return "❓ Please ask me something about Indian cars!"
179
+
180
+ query = query.strip()
181
+
182
+ # Handle specific questions first
183
+ specific_answer = handle_specific_questions(query)
184
+ if specific_answer:
185
+ return specific_answer
186
+
187
+ # Handle comparisons
188
+ comparison_cars = get_comparison_cars(query)
189
+ if comparison_cars:
190
+ response = "πŸ“Š Car Comparison:\n\n"
191
+ for car in comparison_cars[:3]: # Limit to 3 cars
192
+ response += format_car_details(car, show_features=False) + "\n"
193
+ return response.strip()
194
+
195
+ # Check for specific car mention (brand + model)
196
+ for _, row in df.iterrows():
197
+ car_name = f"{row['brand']} {row['model']}".lower()
198
+ if car_name in query.lower():
199
+ return f"πŸ“Œ {row['brand'].title()} {row['model']} Details:\n" + format_car_details(row.to_dict())
200
+
201
+ # Start filtering
202
+ filtered_df = df.copy()
203
+
204
+ # Filter by brand
205
+ brands = find_brand_mentions(query)
206
+ if brands:
207
+ filtered_df = filtered_df[filtered_df["brand"].isin(brands)]
208
+
209
+ # Filter by model
210
+ models = find_model_mentions(query)
211
+ if models:
212
+ filtered_df = filtered_df[filtered_df["model"].str.lower().isin(models)]
213
+
214
+ # Filter by price
215
+ min_price, max_price = extract_price_range(query)
216
+ if min_price is not None:
217
+ filtered_df = filtered_df[filtered_df["price_lakh"] >= min_price]
218
+ if max_price is not None:
219
+ filtered_df = filtered_df[filtered_df["price_lakh"] <= max_price]
220
+
221
+ # Filter by mileage
222
+ min_mileage, max_mileage = extract_mileage_range(query)
223
+ if min_mileage is not None:
224
+ filtered_df = filtered_df[filtered_df["mileage_kmpl"] >= min_mileage]
225
+ if max_mileage is not None:
226
+ filtered_df = filtered_df[filtered_df["mileage_kmpl"] <= max_mileage]
227
+
228
+ # Filter by features
229
+ features = extract_features(query)
230
+ for feature in features:
231
+ filtered_df = filtered_df[filtered_df["features"].str.contains(feature, na=False)]
232
+
233
+ # Sort results based on query intent
234
+ if any(word in query.lower() for word in ['cheap', 'affordable', 'budget']):
235
+ filtered_df = filtered_df.sort_values('price_lakh')
236
+ elif any(word in query.lower() for word in ['expensive', 'premium', 'luxury']):
237
+ filtered_df = filtered_df.sort_values('price_lakh', ascending=False)
238
+ elif any(word in query.lower() for word in ['mileage', 'fuel efficient', 'economy']):
239
+ filtered_df = filtered_df.sort_values('mileage_kmpl', ascending=False)
240
+
241
+ # Generate response
242
+ if filtered_df.empty:
243
+ return "❌ No matching cars found for your query. Try adjusting your requirements!"
244
+
245
+ response = ""
246
+ if len(filtered_df) > 1:
247
+ response += f"Found {len(filtered_df)} matching cars:\n\n"
248
+
249
+ for _, row in filtered_df.head(5).iterrows(): # Show top 5 results
250
+ entry = format_car_details(row.to_dict()) + "\n"
251
+ if len(response + entry) > MAX_TOTAL_CHARACTERS:
252
+ break
253
+ response += entry
254
+
255
+ if len(filtered_df) > 5:
256
+ response += f"\n... and {len(filtered_df) - 5} more cars match your criteria."
257
+
258
+ return response.strip()
259
+
260
+ # Enhanced Gradio interface
261
+ examples = [
262
+ "Show me Maruti cars under 8 lakhs with sunroof",
263
+ "What's the mileage of Tata Nexon?",
264
+ "Compare Hyundai Creta vs Tata Harrier",
265
+ "Cheapest automatic car",
266
+ "Best mileage car under 10 lakhs",
267
+ "Mahindra cars with price and mileage",
268
+ "Cars between 5 and 15 lakhs",
269
+ "Which car has the best features?",
270
+ "Show me all Honda models",
271
+ "Average price of cars in database"
272
+ ]
273
+
274
+ gr.Interface(
275
+ fn=answer_question,
276
+ inputs=gr.Textbox(
277
+ lines=2,
278
+ placeholder="Ask me anything about Indian cars! E.g., 'Best mileage car under 10L', 'Compare Creta vs Harrier'",
279
+ label="Your Question"
280
+ ),
281
+ outputs=gr.Textbox(
282
+ lines=15,
283
+ label="Car Information"
284
+ ),
285
+ title="🚘 Enhanced Indian Car AI Assistant",
286
+ description="Ask me anything about Indian cars! I can help with comparisons, recommendations, specifications, and more.",
287
+ examples=examples,
288
+ theme="soft"
289
+ ).launch()