team-1/backend/src/room.py

66 lines
1.8 KiB
Python
Raw Normal View History

2025-08-01 18:46:38 +02:00
from dataclasses import dataclass
2025-08-01 19:16:20 +02:00
from .song import Song
2025-08-01 18:46:38 +02:00
2025-08-01 19:13:09 +02:00
USER_SCORE_WEIGHT = 0.7
2025-08-01 19:31:47 +02:00
ARTIST_WEIGHT = 0.1
TAG_WEIGHT = 0.1
2025-08-01 19:13:09 +02:00
RANDOM_WEIGHT = 0.1
RECENT_PENALTY = 0.5
RECENT_COUNT = 10
2025-08-01 19:31:47 +02:00
type UserScoredSong = tuple[Song, int]
2025-08-01 18:46:38 +02:00
@dataclass
class Room:
id: int
coord: tuple[float, float]
name: str
pin: int | None
tags: set[str]
2025-08-01 21:39:46 +02:00
songs: dict[str, UserScoredSong] # canzoni + voto
history: list[Song] # canzoni riprodotte (in ordine)
playing: list[Song] # canzoni che sono i riproduzione
2025-08-01 19:13:09 +02:00
2025-08-01 19:31:47 +02:00
def rank_song(self, song: Song, user_score: int) -> float:
2025-08-01 19:13:09 +02:00
rank = 0.0
song_items = self.songs.items()
2025-08-01 19:31:47 +02:00
lowest_score = min(song_items, key=lambda item: item[1][1])[1][1]
highest_score = min(song_items, key=lambda item: item[1][1])[1][1]
rank += translate(user_score, lowest_score, highest_score, 0.0, USER_SCORE_WEIGHT)
recent_songs = self.history[-RECENT_COUNT:]
tag_counts = {}
artist_counts = {}
for song in recent_songs:
for tag in song.tags:
if tag not in tag_counts:
tag_counts[tag] = 0
tag_counts[tag] += 1
if song.artist not in artist_counts:
artist_counts[song.artist] = 0
artist_counts[song.artist] += 1
tag_total = 0
for tag in song.tags:
if tag in tag_counts:
tag_total += tag_counts[tag]
2025-08-01 19:13:09 +02:00
2025-08-01 19:31:47 +02:00
rank += translate(tag_total, 0, RECENT_COUNT, 0, TAG_WEIGHT)
rank += translate(artist_counts[song.artist], 0, RECENT_COUNT, 0, ARTIST_WEIGHT)
2025-08-01 19:13:09 +02:00
2025-08-01 19:31:47 +02:00
if song in recent_songs:
rank -= RECENT_PENALTY
2025-08-01 19:13:09 +02:00
return rank
def translate(value: float, in_min: float, in_max: float, out_min: float, out_max: float):
return (value - in_min) / (in_max - in_min) * (out_max - out_min) + out_min