forked from vlw/misskey-microblogger
48 lines
No EOL
2.1 KiB
Python
48 lines
No EOL
2.1 KiB
Python
import typing
|
|
import random
|
|
|
|
from .User import User
|
|
from ..Enums import NoteTones, NoteMoods, NoteTypes
|
|
|
|
RECURSE_DEPTH_LIMIT = 10
|
|
|
|
class UserPersonality(User):
|
|
def __init__(self, username: str):
|
|
super().__init__(username)
|
|
|
|
@staticmethod
|
|
def _get_random_weighted_item_from_list(items: dict, bias: str | None = None, i: int = 0) -> str:
|
|
# Return a random item from the list if we've reached the recurse depth limit
|
|
if (i >= RECURSE_DEPTH_LIMIT):
|
|
return random.choice(list(items.keys()))
|
|
|
|
# Exponentially increase an existing weight with a multiplier of .25x
|
|
if (bias):
|
|
items[bias] = round(items[bias] + (items[bias] / 4))
|
|
|
|
# Iterate over items from lowest to highest by value
|
|
for k, v in dict(sorted(items.items(), key=lambda item: item[1])).items():
|
|
# Return key of item whose value rolled within range
|
|
if (random.randint(0, 100) <= v):
|
|
return k
|
|
|
|
# Try again if none of the rolls succeeded
|
|
i += 1
|
|
return UserPersonality._get_random_weighted_item_from_list(items, bias, i)
|
|
|
|
# Generate a tone for user given their personality probabilities
|
|
def get_text_tone(self, bias: NoteTones = None) -> NoteTones:
|
|
return NoteTones(self._get_random_weighted_item_from_list(self.config["personality"]["tone"]["probability"], bias.value if bias else None))
|
|
|
|
# Generate a tone for user given their personality probabilities
|
|
def get_text_mood(self, bias: NoteMoods = None) -> NoteMoods:
|
|
return NoteMoods(self._get_random_weighted_item_from_list(self.config["personality"]["mood"]["probability"], bias.value if bias else None))
|
|
|
|
# Generate a tone for user given their personality probabilities
|
|
def get_text_type(self, bias: NoteTypes = None) -> NoteTypes:
|
|
return NoteTypes(self._get_random_weighted_item_from_list(self.config["personality"]["type"]["probability"], bias.value if bias else None))
|
|
|
|
# Get what the length of a note would be for this user given their average text lenghth plus or minus some flux
|
|
def get_note_length(self) -> int:
|
|
flux = self.config["note"]["text_length"]["flux"]
|
|
return self.config["note"]["text_length"]["average"] + random.randint(flux * -1, flux) |