summaryrefslogtreecommitdiffstats
path: root/src/session.py
blob: f30160fdc7723bbefce2628ba267c0b1c935f8e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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())