-
Notifications
You must be signed in to change notification settings - Fork 0
/
controller.py
130 lines (119 loc) · 4.75 KB
/
controller.py
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
124
125
126
127
128
129
130
import log
from level_controller import LevelController
from key_logger import KeyLogger
from transition_aggregator import TransitionAggregator
from generators import FrequencyBasedGenerator
from transition_repository import save_transitions, load_transitions
from dictionaries import lazy_load_dict
from focus import (
focus,
calculate_main_focus_transitions,
calculate_secondary_focus,
calculate_secondary_focus_from_errors,
)
MAX_TRANSITIONS = 50000
MAX_CORRECT_CHARS = 30
zen_mode = True
class Controller:
def __init__(self, output):
self.output = output
self.aggregator = TransitionAggregator()
self.level_controller = LevelController(
lazy_load_dict(
"data", "pl-sci-fi.dict", "data/dictionaries", lambda x: x.lower()
)
)
self.generator = FrequencyBasedGenerator(
self.level_controller.dictionary_for_current_level()
)
self.start_next_stage()
def format_main_focus(self, main_focus, worst_value, focus_type):
if focus_type == "COUNT":
return "Count: {} - {:2d}".format(main_focus, worst_value)
if focus_type == "ACCURACY":
return "Accuracy: {} - {:.1f}%".format(main_focus, worst_value * 100)
if focus_type == "SPEED":
return "Speed: {} - {:.1f} WPM".format(main_focus, worst_value)
def update_stage(self, transitions, main_focus, focus_string):
if zen_mode:
self.output.goto_writing_position(0.1)
self.output.write(
"Level {}: {}".format(
self.level_controller.current_level,
self.level_controller.new_chars(),
),
justify="MIDDLE",
)
self.output.write("\n")
self.output.write(
main_focus if main_focus is not None else "", justify="MIDDLE"
)
self.output.write("\n")
self.output.write_stage(self.get_stage_text(), justify="MIDDLE")
else:
self.output.write(self.get_stage_text())
if len(transitions) > 0:
self.output.write(focus_string)
self.output.write("\n\nKey stats:\n")
self.output.write(
self.aggregator.summary(load_transitions(MAX_CORRECT_CHARS))
)
# TODO this call is now redunant with write_stage method
self.output.goto_writing_position()
def start_next_stage(self, transitions=[]):
def calculate_stage_lenght(seconds, transitions):
lenght = 0
min_lenght = 10
if len(transitions) > 0:
return max(
min_lenght,
round(self.aggregator.total_wpm(transitions) * 5 * seconds / 60),
)
else:
return min_lenght
stage_lenght = calculate_stage_lenght(5, transitions)
log.info("Stage lenght will be: {}".format(stage_lenght))
self.current_text = ""
self.n = 1
self.level_controller.advance_to_next_level_if_possible(transitions)
(
main_focus,
worst_value,
focus_type,
) = self.level_controller.main_focus_for_level(transitions)
secondary_focus = calculate_secondary_focus_from_errors(
self.aggregator.last_errors(transitions), limit=10
)
self.generator = FrequencyBasedGenerator(
focus(
self.level_controller.dictionary_for_current_level(),
main_focus,
secondary_focus,
)
)
self.text = self.generator.generateText(stage_lenght)
self.logger = KeyLogger()
short_focus = self.format_main_focus(main_focus, worst_value, focus_type)
focus_string = "\n\nFocus for stage:\n{}\tSecondary: [{}]".format(
short_focus, secondary_focus,
)
self.update_stage(transitions, short_focus, focus_string)
def get_stage_text(self):
return self.text
def sendKey(self, key):
if key.char:
self.current_text += key.char
if self.current_text == self.text[: self.n]:
self.logger.log_key(key, "CORRECT")
self.output.write_correct_char(key)
self.n += 1
else:
self.logger.log_key(key, "ERROR")
self.output.write_wrong_char(key)
elif key.special == "ERASE":
self.current_text = self.current_text[:-1]
self.logger.log_key(key, "ERASE")
if self.current_text == self.text:
self.output.redraw()
save_transitions(self.logger.transitions())
self.start_next_stage(load_transitions(MAX_CORRECT_CHARS))