"""File for Category class.""" import json from data.score import Score, ScoreTime # pylint: disable=import-error class Category: """Stores a category's information and relative scores.""" def __init__(self, name: str, ascending: bool, time_record: bool, score_map: dict) -> None: """ Default constructor for Category class. Args: name (str): Category's name ascending (bool): If category is ascending or decending time_record (bool): If category is time record or not score_map (dict): map of Scores """ self._name: str = name self._ascending: bool = ascending self._time_record: bool = time_record self._scores_map: dict = score_map def __str__(self) -> str: """ Returns Category class as a string for printing. Returns: str: Category class as a string """ return json.dumps(self.to_dict(), indent=4) @classmethod def from_dict(cls, name: str, data: dict): """ Creates a Category class from the passed data. Args: name (str): Category name data (dict): Rest of Category data in dictionary format Returns: Category: Populated Category object """ ascending = data["ascending"] time_record = data["time_record"] score_map = {} for user, score in data["scores"].items(): if time_record: score_map[user] = ScoreTime(user, score) else: score_map[user] = Score(user, score) return cls(name, ascending, time_record, score_map) @property def ascending(self) -> bool: """ Getter for is ascending Returns: bool: is ascending """ return self._ascending @property def name(self) -> str: """ Getter for name. Returns: str: name """ return self._name @property def time_record(self) -> bool: """ Getter for is time record. Returns: bool: is time record """ return self._time_record @property def scores(self) -> "list[Score]": """ Getter for Scores list. Returns: list[Score]: List of Scores in this Category """ return self._scores_map.values() def add_score(self, score: Score) -> None: """ Adds score to dictionary storage map. Sorts dictionary by score value. Args: score (Score): Score to be added """ if score.user in self._scores_map: self._scores_map[score.user].value = score.value else: self._scores_map[score.user] = score self._scores_map = dict( sorted(self._scores_map.items(), key=lambda x: x[1].value, reverse=not self.ascending) ) def get_user_score(self, user: str) -> Score: """ Gets a user's score. Returns None if user is not found. Args: user (str): Name of score to find Returns: Score: User's Score or None """ if user in self._scores_map: return self._scores_map[user] return None def remove_score(self, score: str) -> None: """ Removes a user's score from dictionary storage. Args: score (str): user whose score to remove """ score = self._scores_map.pop(score) del score def to_dict(self) -> dict: """ Saves category data as a python dictionary. Does not include category name. It should be the key of above data structure. Returns: dict: Category class in dictionary format """ data = {} data["ascending"] = self.ascending data["time_record"] = self.time_record data["scores"] = {} for score in self.scores: data["scores"][score.user] = score.value return data