summaryrefslogtreecommitdiffstats
path: root/gui-project/main_ui.py
blob: fcb1f5aebca3ca934b8b79f3f2712ebd8c9d1a73 (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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from nicegui import ui
import os
import random
import sys
from cards import CardUI, CardComponent
from flashcards import Session

FLASHCARDS_ROOT="/home/andreear/git/schwiizertuutsch/flashcards"
STATE_FILE="/home/andreear/git/flashcards/state.txt"

class MainUI():
    def __init__(self):
        # ===== default value for a session ========
        self.nb_questions = 1
        self.prompt_type = "Front"
        self.fcards = ["saetze-allgemein.fcard"]
        self.run_mode = "practice"

        # ========= start initializing UI ===========
        with ui.header() as self.header:
            self.header_element = ui.markdown("Session Configuration")
        self.root_ui = ui.row().classes("fixed-center")
        with self.root_ui:
            with ui.card(align_items="baseline") as self.session_configuration:
                self.initialize_session_ui()

    def initialize_session_ui(self):
        all_fcards = os.listdir(FLASHCARDS_ROOT)

        with ui.row(align_items="center"):
            ui.label("Number of questions:")
            self.nb_questions_ui = ui.number(placeholder='e.g.: 20', min=1, step=1, precision=0, value=15).props(
                'rounded outlined dense')
        with ui.row(align_items="center"):
            ui.label("Prompt type:")
            self.prompt_sel_ui = ui.select(["Front", "Back", "Random"], value="Back")
        with ui.row(align_items="center"):
            ui.label("Select cards to play from:")
            self.cards_sel_ui = ui.select(all_fcards, multiple=True, value=all_fcards[:2]) \
                .classes('w-64').props('use-chips')
        with ui.button_group():
            ui.button("Practice mode", color="positive",
                      on_click=lambda: self.prepare_session("practice"))
            ui.button("Test mode", color="negative",
                      on_click=lambda: self.prepare_session("test"))

    async def prepare_session(self, run_mode : str):
        self.header.clear()
        self.run_mode = run_mode
        if run_mode == "practice":
            self.header.classes("bg-positive")
        else:
            self.header.classes("bg-negative")

        with self.header:
            self.header_element = ui.markdown(f"Currently in **{run_mode}** mode\nQuestion 1/{self.nb_questions_ui.value}")
        self.run_mode = run_mode
        # read values from UI and set session configuration
        self.nb_questions = int(self.nb_questions_ui.value)
        self.prompt_type = self.prompt_sel_ui.value
        self.fcards = self.cards_sel_ui.value

        assert type(self.fcards) is list
        assert type(self.nb_questions) is int
        assert type(self.prompt_type) is str

        self.session_configuration.set_visibility(False)
        await self.start_session()

    async def start_session(self):
        ui.notify("Started session")
        # initialize cards paths
        cards_paths = [os.path.join(FLASHCARDS_ROOT, x) for x in self.fcards]
        # initialize session
        session = Session("brutal", cards_paths, STATE_FILE)
        # initialize final score
        final_score = 0
        # set ui.colors to be used
        ui.colors(frontc='#bcdbc6', back="#c4bcdb", final="#9cfcfc")

        # Start session
        if self.run_mode == "practice":
            for i, card in enumerate(session.practice(self.nb_questions)):
                correctly_answered = await self.showCard(i, card)
                final_score += 1 if correctly_answered else 0
        elif self.run_mode == "test":
            for i, (card, correct) in enumerate(session.test(self.nb_questions)):
                correctly_answered = await self.showCard(i, card)
                correct(correctly_answered)
                final_score += 1 if correctly_answered else 0

        # Wrap up session
        with self.root_ui:
            with ui.card(align_items="center").classes("bg-final"):
                ui.markdown("## Finished")
                ui.label(f"Your final score is: {final_score}/{self.nb_questions}")
                ui.label("To start again, refresh the page")

    async def showCard(self, idx : int, card):
        self.header_element.set_content(
            f"Currently in **{self.run_mode}** mode\n\nQuestion {idx + 1}/{int(self.nb_questions_ui.value)}")
        prompt_type_binary = self.prompt_type.lower()
        if self.prompt_type.lower() == "random":
            random_nb = random.randint(0, sys.maxsize)
            if random_nb % 2 == 0:
                prompt_type_binary = "front"
            else:
                prompt_type_binary = "back"

        if prompt_type_binary == "front":
            card_component = CardComponent(card.front, card.back)
        else:
            card_component = CardComponent(card.back, card.front)

        card_ui = CardUI(self.root_ui, card_component)

        card_ui.show_front()
        await card_ui.is_answered()
        card_ui.hide_card()
        return card_ui.correctly_answered