Spaces:
Sleeping
Sleeping
| """Scoring logic and enhanced score display functionality""" | |
| import random | |
| from .achievements import AchievementSystem | |
| class Scorer: | |
| """Handles scoring calculations and display generation""" | |
| def __init__(self, template_renderer=None): | |
| self.template_renderer = template_renderer | |
| def calculate_difficulty(self, user_input, partial_response, llm_manager): | |
| """Calculate difficulty based on user input tokens and partial completion length""" | |
| if not user_input.strip(): | |
| return "Easy", 0 | |
| # Count tokens for user input | |
| user_token_count = llm_manager.count_tokens(user_input) | |
| # Count tokens for partial response | |
| partial_token_count = llm_manager.count_tokens(partial_response) | |
| # Difficulty based on tokens and completion percentage | |
| completion_percentage = partial_token_count / 100 # Assume 100 is typical full response | |
| if user_token_count <= 2: | |
| if completion_percentage < 0.3: | |
| return "Medium", user_token_count | |
| else: | |
| return "Easy", user_token_count | |
| elif user_token_count <= 4: | |
| return "Medium", user_token_count | |
| else: | |
| return "Hard", user_token_count | |
| def calculate_rank_and_percentile(self, user_score, prompt_results, user_tokens, separate_by_token_count=False): | |
| """Calculate user's rank and percentile among users with same prompt and token count.""" | |
| # Filter to only same prompt and same token count | |
| if separate_by_token_count: | |
| comparable_scores = [r["cosine_distance"] for r in prompt_results | |
| if r["num_user_tokens"] == user_tokens] | |
| else: | |
| comparable_scores = [r["cosine_distance"] for r in prompt_results] | |
| if not comparable_scores: | |
| return None, None | |
| # Sort scores in descending order (higher cosine distance = better creativity) | |
| sorted_scores = sorted(comparable_scores, reverse=True) | |
| # Find rank (1-based) | |
| rank = None | |
| for i, score in enumerate(sorted_scores): | |
| if user_score >= score: | |
| rank = i + 1 | |
| break | |
| if rank is None: | |
| rank = len(sorted_scores) + 1 | |
| # Calculate percentile (0-100) | |
| if len(sorted_scores) <= 1: | |
| percentile = 50.0 | |
| else: | |
| # Compute raw percentile: proportion of users the current user is better than. | |
| raw_percentile = (len(sorted_scores) - rank) / len(sorted_scores) * 100.0 | |
| # Ensure percentile is always within 0-100 even if rank is out of expected bounds | |
| percentile = max(0.0, min(100.0, raw_percentile)) | |
| return rank, percentile | |
| def create_enhanced_score_display(self, cosine_distance, rank, percentile, user_tokens, same_category_attempts): | |
| """Create an enhanced score display with progress bars and metrics""" | |
| # Calculate progress bar width (cosine distance is 0-1, so multiply by 100 for percentage) | |
| score_percentage = min(100, cosine_distance * 100) | |
| # Determine score level and message | |
| if cosine_distance >= 0.7: | |
| score_level = "🌟 LEGENDARY CREATIVITY!" | |
| bar_color = "linear-gradient(45deg, #ff6b6b, #ffa726)" | |
| elif cosine_distance >= 0.5: | |
| score_level = "🔥 EXCEPTIONAL CREATIVITY!" | |
| bar_color = "linear-gradient(45deg, #4CAF50, #8bc34a)" | |
| elif cosine_distance >= 0.3: | |
| score_level = "✨ GREAT CREATIVITY!" | |
| bar_color = "linear-gradient(45deg, #2196F3, #03DAC6)" | |
| elif cosine_distance >= 0.15: | |
| score_level = "💡 GOOD CREATIVITY!" | |
| bar_color = "linear-gradient(45deg, #FF9800, #FFC107)" | |
| else: | |
| score_level = "🤔 ROOM FOR IMPROVEMENT" | |
| bar_color = "linear-gradient(45deg, #9E9E9E, #607D8B)" | |
| html_content = f""" | |
| <div class="score-container"> | |
| <div class="score-header">{score_level}</div> | |
| <div class="progress-bar-container"> | |
| <div class="progress-bar" style="width: {score_percentage}%; background: {bar_color};"></div> | |
| </div> | |
| <div style="text-align: center; margin: 10px 0;"> | |
| <span style="font-size: 24px; font-weight: bold;"> | |
| Creativity Score: {cosine_distance:.3f} | |
| <span class="help-tooltip">ℹ️ | |
| <span class="tooltip-text"> | |
| <strong>Creativity Score (0-1):</strong><br/> | |
| Measures how different your influenced response is from the AI's original response. | |
| Higher scores = more creative divergence!<br/><br/> | |
| • 0.7+: Legendary creativity<br/> | |
| • 0.5+: Exceptional creativity<br/> | |
| • 0.3+: Great creativity<br/> | |
| • 0.15+: Good creativity | |
| </span> | |
| </span> | |
| </span> | |
| </div> | |
| <div class="score-details"> | |
| """ | |
| if rank is not None and percentile is not None: | |
| html_content += f""" | |
| <div class="score-metric"> | |
| <div class="metric-value">#{rank}</div> | |
| <div class="metric-label">Rank out of {same_category_attempts}</div> | |
| </div> | |
| <div class="score-metric"> | |
| <div class="metric-value">{percentile:.1f}%</div> | |
| <div class="metric-label">Better than others</div> | |
| </div> | |
| """ | |
| html_content += f""" | |
| <div class="score-metric"> | |
| <div class="metric-value">{user_tokens}</div> | |
| <div class="metric-label">Token{'s' if user_tokens != 1 else ''} used | |
| <span class="help-tooltip">ℹ️ | |
| <span class="tooltip-text"> | |
| <strong>More tokens = Higher potential score!</strong><br/> | |
| Using more tokens gives you more ways to steer me in creative directions, | |
| but the real challenge is making any number of tokens count! | |
| </span> | |
| </span> | |
| </div> | |
| </div> | |
| </div> | |
| """ | |
| # Add achievement titles | |
| achievement_system = AchievementSystem() | |
| achievements = achievement_system.determine_achievement_titles(cosine_distance, user_tokens) | |
| if achievements: | |
| html_content += """ | |
| <div class="achievements-container"> | |
| <div class="achievements-title"> | |
| 🏆 Achievements Earned | |
| <span class="help-tooltip">ℹ️ | |
| <span class="tooltip-text"> | |
| <strong>Achievements:</strong><br/> | |
| Earned based on your performance this session:<br/><br/> | |
| • Creativity level (Genius, Master, Spark, etc.)<br/> | |
| • Token efficiency (Word Wizard, Phrase Magician)<br/> | |
| • Difficulty tackled (Challenge Conqueror)<br/> | |
| • Special combos (One-Word Wonder, Elite Performer) | |
| </span> | |
| </span> | |
| </div> | |
| <div class="achievement-badges"> | |
| """ | |
| for title in achievements: | |
| html_content += f'<div class="achievement-badge">{title}</div>' | |
| html_content += """ | |
| </div> | |
| </div> | |
| """ | |
| # Add smart contextual tip | |
| smart_tip = self.generate_smart_tip(cosine_distance, user_tokens, rank, percentile) | |
| html_content += f""" | |
| <div class="smart-tip-container"> | |
| <span class="smart-tip-icon">💡</span> | |
| <span class="smart-tip-text">{smart_tip}</span> | |
| </div> | |
| <div style="text-align: center; margin-top: 15px; opacity: 0.9; font-size: 14px;"> | |
| Higher scores indicate more creative divergence from the original response! | |
| </div> | |
| </div> | |
| """ | |
| return html_content | |
| def generate_smart_tip(self, cosine_distance, user_tokens, rank, percentile): | |
| """Generate personalized tips based on user performance""" | |
| tips = [] | |
| # Performance-based tips | |
| if cosine_distance < 0.1: | |
| tips.append("💡 Try using more unexpected or creative words to steer me in a completely new direction!") | |
| elif cosine_distance < 0.2: | |
| tips.append("✨ Good start! Try thinking more out-of-the-box to maximize your creativity score.") | |
| elif cosine_distance >= 0.5: | |
| tips.append("🌟 Excellent creativity! You're successfully making me generate very different responses.") | |
| # Token efficiency tips | |
| if user_tokens >= 4: | |
| tips.append("⚡ Challenge yourself: try achieving the same creative impact with fewer tokens!") | |
| elif user_tokens == 1 and cosine_distance >= 0.2: | |
| tips.append("🎯 Outstanding! You're a master of single-token creativity.") | |
| elif user_tokens <= 2 and cosine_distance >= 0.3: | |
| tips.append("🏆 Incredible efficiency - maximum creativity with minimal tokens!") | |
| # Ranking tips | |
| if rank and percentile: | |
| if percentile >= 80: | |
| tips.append("👑 You're in the top performers - keep up the amazing work!") | |
| elif percentile >= 50: | |
| tips.append("📈 You're above average! Push a bit further to join the top tier.") | |
| else: | |
| tips.append("🎯 Room to grow - try more unexpected word combinations!") | |
| # Return a random tip if multiple apply, or a default encouragement | |
| if tips: | |
| return random.choice(tips) | |
| else: | |
| return "🎮 Great job playing! Try a new prompt to test different creative strategies." |