Files
agon/classes/category.py
T

202 lines
5.1 KiB
Python

"""File for Category class."""
import json
from classes.score import Score, ScoreTime # pylint: disable=import-error
class Category:
"""Stores a category's information and relative scores."""
def __init__(self, name: str) -> None:
"""
Default constructor for Category class. Creates empty category and populates with defaults.
Args:
name (str): Category's name
"""
self._name: str = name
self._ascending: bool = False
self._time_record: bool = False
self._scores_map: dict = {}
def __str__(self) -> str:
"""
Returns Category class as a string for printing.
Returns:
str: Category class as a string
"""
return self.to_str()
@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
"""
category = cls(name)
category.ascending = data["ascending"]
category.time_record = data["time_record"]
for user, score in data["scores"].items():
if category.time_record:
score_obj: ScoreTime = ScoreTime(user)
score_obj.value = float(score)
category.add_score(score_obj)
else:
score_obj: Score = Score(user)
score_obj.value = int(score)
category.add_score(score_obj)
return category
@property
def ascending(self) -> bool:
"""
Getter for is ascending.
Returns:
bool: is ascending
"""
return self._ascending
@ascending.setter
def ascending(self, ascending: bool) -> None:
"""
Setter for is ascending.
Args:
ascending (bool): is ascending
"""
self._ascending = 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
@time_record.setter
def time_record(self, time_record: bool) -> None:
"""
Setter for is time record.
Args:
time_record (bool): is time record
"""
self._time_record = 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 clear(self) -> None:
"""
Clears all Scores tracked in score map.
This is a test function and shouldn't really be used.
"""
self._scores_map.clear()
def get_users(self) -> "list[str]":
"""
Returns list of users in this category.
Returns:
list[str]: List of all users in category.
"""
return self._scores_map.keys()
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, user: str) -> Score:
"""
Removes a user's score from dictionary storage.
Args:
user (str): user whose score to remove
Returns:
Score: User's Score or None
"""
if user in self._scores_map:
return self._scores_map.pop(user)
return None
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
def to_str(self) -> str:
"""
Returns Category object as a string.
Returns:
str: string of json representation of Category
"""
return json.dumps(self.to_dict(), indent=4)