from typing import Iterator, Callable from .card import Card from .scheduler import getSchedulerClass from .parser import parseFiles from .state_json import load, save class Session: """ Represents a play session. During a session, multiple practice and test runs can be made with the same scheduler. """ def __init__(self, scheduler_name: str, card_files: list[str], state_file: str): self._cards = parseFiles(card_files) self._state_file = state_file self._scheduler = getSchedulerClass(scheduler_name)(self._cards, load(state_file)) def practice(self, size: int) -> Iterator[Card]: """ Yields cards for a practice run of the requested size. Practice runs do not affect the scheduler state. """ ids = self._scheduler.practice(size) for id in ids: yield self._cards[id] def test(self, size: int) -> Iterator[tuple[Card, Callable]]: """ Yields cards for a test run of the requested size. A function is yielded with each card that takes single boolean argument. The UI is expected to call the function for each card to indicate whether the user correctly guessed the card (True) or not (False). Multiple subsequent calls to the same function overwrite past results. When the test run is done, the scheduler state is updated with the collected results """ ids = self._scheduler.practice(size) results = {} for id in ids: def result(correct: bool) -> None: results[id] = int(correct) yield self._cards[id], result self._scheduler.update(results) save(self._state_file, self._scheduler.getState())