Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -173,8 +173,7 @@ def generate_game_comparison_chart(game_name):
|
|
| 173 |
print(f"Error generating comparison chart: {e}")
|
| 174 |
return None
|
| 175 |
|
| 176 |
-
#
|
| 177 |
-
# MODIFIED: Changed to only return 5 recommendations instead of 10
|
| 178 |
def recommend_games(user_game_name_input):
|
| 179 |
# Check cache first
|
| 180 |
if user_game_name_input in recommendation_cache:
|
|
@@ -217,11 +216,30 @@ def recommend_games(user_game_name_input):
|
|
| 217 |
recommendations = []
|
| 218 |
game_list = []
|
| 219 |
|
| 220 |
-
#
|
| 221 |
-
|
| 222 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
|
| 224 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
for i, (index, score) in enumerate(sorted_similar_games[1:11]): # Only process first 10 to find 5 good ones
|
| 226 |
if score < 0.2: # Higher threshold for better quality
|
| 227 |
continue
|
|
@@ -231,7 +249,7 @@ def recommend_games(user_game_name_input):
|
|
| 231 |
# Get platform info
|
| 232 |
platforms = data.iloc[index].get('platforms', '')
|
| 233 |
os_list = detect_platforms(platforms)
|
| 234 |
-
os_display = "
|
| 235 |
|
| 236 |
# Get price info
|
| 237 |
price = data.iloc[index].get('price', 0)
|
|
@@ -239,20 +257,40 @@ def recommend_games(user_game_name_input):
|
|
| 239 |
|
| 240 |
# Get genre info for additional context
|
| 241 |
genres = str(data.iloc[index].get('genres', '')).split(';')
|
| 242 |
-
genres_display = ", ".join(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
|
| 244 |
# Format recommendation with emoji and more details
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 249 |
|
| 250 |
recommendations.append(recommendation)
|
| 251 |
|
| 252 |
# Add to game list
|
| 253 |
game_list.append(game_name)
|
| 254 |
|
| 255 |
-
if len(recommendations) >=
|
| 256 |
break
|
| 257 |
|
| 258 |
result = ("\n".join(recommendations), game_list)
|
|
@@ -302,6 +340,23 @@ def evaluate_precision(user_game_name_input):
|
|
| 302 |
print(f"Precision calculation error: {str(e)}")
|
| 303 |
return 0.0
|
| 304 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
# Function to generate price distribution chart
|
| 306 |
def generate_price_chart():
|
| 307 |
try:
|
|
@@ -336,26 +391,6 @@ def generate_price_chart():
|
|
| 336 |
print(f"Error generating price chart: {e}")
|
| 337 |
return None
|
| 338 |
|
| 339 |
-
# Combined function with progress updates
|
| 340 |
-
def recommend_and_visualize(user_input):
|
| 341 |
-
if not user_input or user_input.strip() == "":
|
| 342 |
-
return "Please enter a game name", []
|
| 343 |
-
|
| 344 |
-
# Get recommendations
|
| 345 |
-
recommendations, game_list = recommend_games(user_input)
|
| 346 |
-
|
| 347 |
-
# Calculate precision
|
| 348 |
-
precision = evaluate_precision(user_input)
|
| 349 |
-
|
| 350 |
-
# Add platform legend and precision info
|
| 351 |
-
footer = "\n\n๐ **Recommendation Quality**: "
|
| 352 |
-
footer += f"Precision@5: {precision*100:.0f}%" if precision > 0 else "Unable to calculate precision"
|
| 353 |
-
|
| 354 |
-
footer += "\n\n**Platform Legend**:\n"
|
| 355 |
-
footer += "๐ฅ๏ธ Windows | ๐ macOS | ๐ง Linux | โ Unknown"
|
| 356 |
-
|
| 357 |
-
return recommendations + footer, game_list
|
| 358 |
-
|
| 359 |
# Function to create genre distribution chart
|
| 360 |
def create_genre_chart():
|
| 361 |
try:
|
|
@@ -388,7 +423,6 @@ def create_genre_chart():
|
|
| 388 |
return None
|
| 389 |
|
| 390 |
# Improved Gradio UI with added features
|
| 391 |
-
# MODIFIED: Removed game details feature
|
| 392 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
| 393 |
gr.Markdown("# ๐ฎ Steam Game Recommender")
|
| 394 |
gr.Markdown("Enter the name of a game you like and get recommendations based on similarity!")
|
|
@@ -405,10 +439,9 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 405 |
run_button = gr.Button("Find Recommendations", variant="primary")
|
| 406 |
|
| 407 |
with gr.Row():
|
| 408 |
-
|
| 409 |
-
|
| 410 |
-
|
| 411 |
-
interactive=False
|
| 412 |
)
|
| 413 |
|
| 414 |
with gr.Tab("Statistics"):
|
|
@@ -501,7 +534,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 501 |
return []
|
| 502 |
|
| 503 |
# Combined function to update recommendations and history
|
| 504 |
-
# MODIFIED: Removed dropdown from outputs
|
| 505 |
def recommend_and_update_history(user_input):
|
| 506 |
rec_text, game_list = recommend_and_visualize(user_input)
|
| 507 |
history = update_search_history(user_input)
|
|
|
|
| 173 |
print(f"Error generating comparison chart: {e}")
|
| 174 |
return None
|
| 175 |
|
| 176 |
+
# Enhanced recommendation function with better formatting and emojis
|
|
|
|
| 177 |
def recommend_games(user_game_name_input):
|
| 178 |
# Check cache first
|
| 179 |
if user_game_name_input in recommendation_cache:
|
|
|
|
| 216 |
recommendations = []
|
| 217 |
game_list = []
|
| 218 |
|
| 219 |
+
# Get searched game details
|
| 220 |
+
searched_game = data.iloc[index_of_the_game]
|
| 221 |
+
searched_game_genres = str(searched_game.get('genres', '')).split(';')
|
| 222 |
+
searched_game_genres_display = ", ".join([g for g in searched_game_genres if g])
|
| 223 |
+
searched_game_platforms = detect_platforms(searched_game.get('platforms', ''))
|
| 224 |
+
searched_game_platform_display = " ".join(searched_game_platforms)
|
| 225 |
+
searched_game_price = searched_game.get('price', 0)
|
| 226 |
+
searched_game_price_display = f"${searched_game_price:.2f}" if isinstance(searched_game_price, (int, float)) and searched_game_price > 0 else "Free" if searched_game_price == 0 else "N/A"
|
| 227 |
|
| 228 |
+
# Format the searched game with nicer styling
|
| 229 |
+
recommendations.append(f"## ๐ฎ You searched for: {closest_match}\n" +
|
| 230 |
+
f"**Genres:** {searched_game_genres_display}\n" +
|
| 231 |
+
f"**Platforms:** {searched_game_platform_display}\n" +
|
| 232 |
+
f"**Price:** {searched_game_price_display}\n")
|
| 233 |
+
|
| 234 |
+
game_list.append(closest_match)
|
| 235 |
+
|
| 236 |
+
# Add a divider
|
| 237 |
+
recommendations.append("---\n## ๐ Top Recommendations\n")
|
| 238 |
+
|
| 239 |
+
# Generate emoji for each position
|
| 240 |
+
position_emojis = ["๐ฅ", "๐ฅ", "๐ฅ", "4๏ธโฃ", "5๏ธโฃ"]
|
| 241 |
+
|
| 242 |
+
# Process recommendations
|
| 243 |
for i, (index, score) in enumerate(sorted_similar_games[1:11]): # Only process first 10 to find 5 good ones
|
| 244 |
if score < 0.2: # Higher threshold for better quality
|
| 245 |
continue
|
|
|
|
| 249 |
# Get platform info
|
| 250 |
platforms = data.iloc[index].get('platforms', '')
|
| 251 |
os_list = detect_platforms(platforms)
|
| 252 |
+
os_display = " ".join(os_list)
|
| 253 |
|
| 254 |
# Get price info
|
| 255 |
price = data.iloc[index].get('price', 0)
|
|
|
|
| 257 |
|
| 258 |
# Get genre info for additional context
|
| 259 |
genres = str(data.iloc[index].get('genres', '')).split(';')
|
| 260 |
+
genres_display = ", ".join([g for g in genres if g])
|
| 261 |
+
|
| 262 |
+
# Get positive ratings
|
| 263 |
+
positive_ratings = data.iloc[index].get('positive_ratings', 0)
|
| 264 |
+
|
| 265 |
+
# Determine emoji based on game type
|
| 266 |
+
category_emoji = "๐ซ" if "Action" in genres_display else "๐ง" if "RPG" in genres_display else "๐๏ธ" if "Racing" in genres_display else "๐งฉ" if "Puzzle" in genres_display else "๐" if "Adventure" in genres_display else "โ๏ธ" if "Strategy" in genres_display else "๐ก" if "Simulation" in genres_display else "๐ฒ"
|
| 267 |
+
|
| 268 |
+
# Calculate match percentage
|
| 269 |
+
match_percentage = int(score * 100)
|
| 270 |
+
|
| 271 |
+
# Create match bar
|
| 272 |
+
match_bar = "โ" * (match_percentage // 10) + "โ" * (10 - (match_percentage // 10))
|
| 273 |
+
|
| 274 |
+
# Create color indicator based on match percentage
|
| 275 |
+
color_indicator = "๐ข" if match_percentage >= 80 else "๐ก" if match_percentage >= 60 else "๐ " if match_percentage >= 40 else "๐ด"
|
| 276 |
|
| 277 |
# Format recommendation with emoji and more details
|
| 278 |
+
position_emoji = position_emojis[i] if i < len(position_emojis) else f"{i+1}."
|
| 279 |
+
|
| 280 |
+
recommendation = (
|
| 281 |
+
f"### {position_emoji} {category_emoji} {game_name}\n" +
|
| 282 |
+
f"**Match:** {color_indicator} {match_percentage}% {match_bar}\n" +
|
| 283 |
+
f"**Genres:** {genres_display}\n" +
|
| 284 |
+
f"**Platforms:** {os_display}\n" +
|
| 285 |
+
f"**Price:** {price_display}\n"
|
| 286 |
+
)
|
| 287 |
|
| 288 |
recommendations.append(recommendation)
|
| 289 |
|
| 290 |
# Add to game list
|
| 291 |
game_list.append(game_name)
|
| 292 |
|
| 293 |
+
if len(recommendations) >= 7: # searched game + divider + 5 recommendations
|
| 294 |
break
|
| 295 |
|
| 296 |
result = ("\n".join(recommendations), game_list)
|
|
|
|
| 340 |
print(f"Precision calculation error: {str(e)}")
|
| 341 |
return 0.0
|
| 342 |
|
| 343 |
+
# Combined function with progress updates
|
| 344 |
+
def recommend_and_visualize(user_input):
|
| 345 |
+
if not user_input or user_input.strip() == "":
|
| 346 |
+
return "Please enter a game name", []
|
| 347 |
+
|
| 348 |
+
# Get recommendations
|
| 349 |
+
recommendations, game_list = recommend_games(user_input)
|
| 350 |
+
|
| 351 |
+
# Calculate precision
|
| 352 |
+
precision = evaluate_precision(user_input)
|
| 353 |
+
|
| 354 |
+
# Add platform legend and precision info
|
| 355 |
+
footer = "\n\n---\n"
|
| 356 |
+
footer += f"๐ **Recommendation Quality:** {precision*100:.0f}% precision" if precision > 0 else "๐ **Recommendation Quality:** Unable to calculate precision"
|
| 357 |
+
|
| 358 |
+
return recommendations + footer, game_list
|
| 359 |
+
|
| 360 |
# Function to generate price distribution chart
|
| 361 |
def generate_price_chart():
|
| 362 |
try:
|
|
|
|
| 391 |
print(f"Error generating price chart: {e}")
|
| 392 |
return None
|
| 393 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 394 |
# Function to create genre distribution chart
|
| 395 |
def create_genre_chart():
|
| 396 |
try:
|
|
|
|
| 423 |
return None
|
| 424 |
|
| 425 |
# Improved Gradio UI with added features
|
|
|
|
| 426 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
| 427 |
gr.Markdown("# ๐ฎ Steam Game Recommender")
|
| 428 |
gr.Markdown("Enter the name of a game you like and get recommendations based on similarity!")
|
|
|
|
| 439 |
run_button = gr.Button("Find Recommendations", variant="primary")
|
| 440 |
|
| 441 |
with gr.Row():
|
| 442 |
+
# Changed to markdown for better formatting
|
| 443 |
+
output_text = gr.Markdown(
|
| 444 |
+
label="Recommendations"
|
|
|
|
| 445 |
)
|
| 446 |
|
| 447 |
with gr.Tab("Statistics"):
|
|
|
|
| 534 |
return []
|
| 535 |
|
| 536 |
# Combined function to update recommendations and history
|
|
|
|
| 537 |
def recommend_and_update_history(user_input):
|
| 538 |
rec_text, game_list = recommend_and_visualize(user_input)
|
| 539 |
history = update_search_history(user_input)
|