"""Stable public feature preprocessing for Forge2Vec.""" from __future__ import annotations from typing import Optional GENRE_VOCABULARY = { "Comedy": 1, "Fantasy": 2, "Romance": 3, "Action": 4, "Drama": 5, "School": 6, "Shoujo": 7, "Shounen": 8, "Adventure": 9, "Supernatural": 10, "Kids": 11, "Slice of Life": 12, "Sci-Fi": 13, "Music": 14, "Historical": 15, "Mystery": 16, "Boys Love": 17, "Adult Cast": 18, "Horror": 19, "Isekai": 20, "Sports": 21, "Mecha": 22, "Psychological": 23, "Anthropomorphic": 24, "Martial Arts": 25, "Girls Love": 26, "Super Power": 27, "Mythology": 28, "Military": 29, "Avant Garde": 30, "Seinen": 31, "Parody": 32, "Harem": 33, "Gourmet": 34, "Workplace": 35, "Space": 36, "Ecchi": 37, "Award Winning": 38, "Detective": 39, "Gag Humor": 40, "Strategy Game": 41, "Gore": 42, "Vampire": 43, "Mahou Shoujo": 44, "Samurai": 45, "Idols (Female)": 46, "Suspense": 47, "CGDCT": 48, "Educational": 49, "Villainess": 50, "Love Polygon": 51, "Racing": 52, "Childcare": 53, "Iyashikei": 54, "Team Sports": 55, "Combat Sports": 56, "Delinquents": 57, "Idols (Male)": 58, "Medical": 59, "Memoir": 60, "Reincarnation": 61, "Video Game": 62, "Magical Sex Shift": 63, "Time Travel": 64, "Performing Arts": 65, "High Stakes Game": 66, "Pets": 67, "Josei": 68, "Otaku Culture": 69, "Organized Crime": 70, "Survival": 71, "Visual Arts": 72, "Erotica": 73, "Reverse Harem": 74, "Romantic Subtext": 75, "Crossdressing": 76, "Showbiz": 77, "Hentai": 78, } def genre_indices(names: list[str], max_length: int = 10) -> list[int]: values = [GENRE_VOCABULARY.get(name, 0) for name in names[:max_length]] return values + [0] * (max_length - len(values)) def metadata_vector(content_type: str, year: Optional[int], score: Optional[float]) -> list[float]: return [ 1.0 if content_type.lower() == "anime" else 0.0, 1.0 if content_type.lower() == "manga" else 0.0, max(0.0, min(1.0, (year - 1960) / 70.0)) if year else 0.5, max(0.0, min(1.0, score / 10.0)) if score is not None else 0.5, ]