""" """ from scheduler import Scheduler from card import Card from random import shuffle HISTORY_DEPTH = 8 class SchedulerBrutal(Scheduler): def __init__(self, cards: dict[int, Card], state: dict): self._cards = cards self._state = {} # Synchronise state with current card collection for id, card in self._cards.items(): history = state.get(id, [None] * HISTORY_DEPTH) # Adjust history if depth has changed if len(history) > HISTORY_DEPTH: history = history[-HISTORY_DEPTH:] elif len(history) < HISTORY_DEPTH: history = ([None] * (HISTORY_DEPTH - len(history))) + history self._state[id] = history def practice(self, size: int) -> list[int]: return self._schedule(size) def test(self, size: int) -> list[int]: return self._schedule(size) def update(self, results: dict[int, int]) -> None: # Add card result to sliding window, or None if card was not shown self._state = {id: history[1:] + [results.get(id, None)] for id, history in self._state.items()} def getState(self) -> dict: return self._state # Consolidation index is a measure of how well the card has been memorised @staticmethod def _consolidationIndex(history: list, weights: range) -> float: relevant_history = [(h, w) for h, w in zip(history, weights) if h is not None] weighted_history = sum([h * w for h, w in relevant_history]) total_weights = sum([w for h, w in relevant_history]) return weighted_history / total_weights if total_weights > 0 else 0.0 # Exposure index is a measure of how much and how recently a card has been shown @staticmethod def _exposureIndex(history: list) -> float: return sum([i + 1 for i, h in enumerate(history) if h is not None]) def _schedule(self, size: int) -> list[int]: weights = range(10, 10 + HISTORY_DEPTH) cards = [id for id, card in self._cards.items()] # First sort by consolidation index cards.sort(key=lambda id: SchedulerBrutal._consolidationIndex(self._state[id], weights)) # Next sort by exposure index cards.sort(key=lambda id: SchedulerBrutal._exposureIndex(self._state[id])) # Return least exposed and least consolidated cards, shuffled cards = cards[0:size] shuffle(cards) return cards