"""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"""