-
Notifications
You must be signed in to change notification settings - Fork 0
/
app_v2.py
297 lines (234 loc) · 11.3 KB
/
app_v2.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
import tkinter as tk
import shelve
from random import choice
import json
settings_db = shelve.open("settings")
try:
if settings_db["first_time"]:
pass
except KeyError:
__import__("os").system("python settings_v2.py")
exit()
program_just_started = True
current_theme, themes = None, None
nbr_minutes, in_chars, default_text = None, None, None
default_texts = []
def generate_new_text():
global default_text, avg, nbr_words_in_text
default_text = choice(default_texts)
text_to_type.delete("0.0", tk.END)
text_to_type.insert("0.0", default_text)
avg = [len(word) for word in default_text.split()]
nbr_words_in_text = len(avg)
avg = sum(avg)//nbr_words_in_text
remaining_chars.configure(
text="Remaining\n" + str(len(default_text) if in_chars else nbr_words_in_text))
total_chars.configure(
text="Total\n" + str(len(default_text) if in_chars else nbr_words_in_text))
def check_changes_in_db():
global nbr_minutes, in_chars, default_text, themes, current_theme, default_texts
nbr_minutes = settings_db["default_and_saved"]["minutes"][1]
if nbr_minutes == 4:
nbr_minutes += 1
if settings_db["default_and_saved"]["unit"][1] == 1:
in_chars = False # True IF WPM, False OTHERWISE
else:
in_chars = True
if settings_db["default_and_saved"]["theme"][1] == 1:
current_theme = "light_theme"
elif settings_db["default_and_saved"]["theme"][1] == 2:
current_theme = "dark_theme"
elif settings_db["default_and_saved"]["theme"][1] == 3:
current_theme = "dark_twilight_theme"
themes = settings_db["themes"]
if settings_db["custom_text"] != "" and settings_db["default_and_saved"]["text"][1] == 2:
default_text = settings_db["custom_text"]
else:
with open('default-texts.json') as json_file:
default_texts = json.load(json_file)
default_text = choice(default_texts)
def start_again():
global started, last_pos, chars, m, s, flash_time, completed_correctly, flash_mode
start_label.unbind("<1>")
start_label["text"] = "Start when you're ready :)"
start_label["font"] = "Caviar Dreams Bold", "10", "bold"
change_settings.unbind("<1>")
change_settings["text"] = "Change Text ?"
change_settings.bind("<1>", lambda key: generate_new_text())
typed_text.delete("0.0", tk.END)
passed_time["text"] = "Time\n00:00"
typed_chars["text"] = "Typed\n0"
remaining_chars["text"] = "Remaining\n" + \
str(len(default_text) if in_chars else nbr_words_in_text)
total_chars["text"] = "Total\n" + \
str(len(default_text) if in_chars else nbr_words_in_text)
typing_speed["text"] = "Typing Speed\n0 WPM"
text_to_type.tag_remove("correct", "0.0", tk.END)
text_to_type.tag_remove("wrong", "0.0", tk.END)
last_pos = 0
chars = 0 # FOR TYPING SPEED ONLY
flash_time = False
m, s = 0, -1
started = False
flash_mode = False
start_typing()
def start_typing(): # PREVENT CHEATING BY CHECKING WHETHER USER STARTED TYPING OR NOT
global started
typed_text.focus()
if not started:
if typed_text.get("0.0", tk.END).strip():
started = True
typing_speed.after(100, start_typing)
else:
start_label.unbind("<1>")
start_label["text"] = "Typing.."
start_label["font"] = "Caviar Dreams Bold", "10", "bold"
change_settings.unbind("<1>")
change_settings["text"] = "Reset"
change_settings.bind("<1>", lambda key: start_again())
root.bind("<Key>", lambda key: add_one_to_chars())
update_tags()
def add_one_to_chars():
global chars
chars += 1
def update_time():
global m, s, flash_time, started, settings_db, completed_correctly, flash_mode, program_just_started
def restart_program():
root.destroy()
__import__("os").system("python app_v2.py")
if settings_db["changes_exist"]:
settings_db["changes_exist"] = False
if not program_just_started:
start_label["text"] = "Changes detected, restart ?"
start_label["font"] = "Caviar Dreams Bold", "10", "bold underline"
start_label.bind("<1>", lambda key: restart_program())
else:
program_just_started = False
if started and m == nbr_minutes or completed_correctly:
start_label["text"] = "Start typing again ?"
start_label["font"] = "Caviar Dreams Bold", "10", "bold underline"
start_label.bind("<1>", lambda key: start_again())
# change_settings.place(
# relx=.4, rely=.8, relheight=.19, relwidth=.29)
change_settings.unbind("<1>")
change_settings["text"] = "Change Text ?"
change_settings.bind("<1>", lambda key: generate_new_text())
started = False
completed_correctly = False
flash_mode = True
elif (not started) and m == nbr_minutes or flash_mode:
if s == -1:
s = 0
if flash_time:
passed_time["text"] = f"Time\n{m:02}:{s:02}"
else:
passed_time["text"] = f"Time\n"
flash_time = not flash_time
elif started and m != nbr_minutes:
if typed_text.get("0.0", tk.END).strip(" \n") == default_text:
completed_correctly = True
else:
if s == 59:
m += 1
s = 0
else:
s += 1
passed_time["text"] = f"Time\n{m:02}:{s:02}"
passed_time.after(1000, update_time)
def update_tags():
global last_pos
text_to_type.delete("0.0", tk.END)
text_to_type.insert("0.0", default_text)
tt = len(typed_text.get("0.0", tk.END)) - 1
if default_text.startswith(typed_text.get("0.0", tk.END).strip("\n")):
text_to_type.tag_add("correct", "1.0", "1." + str(tt))
last_pos = tt
else:
text_to_type.tag_add("correct", "1.0", "1." + str(last_pos))
text_to_type.tag_add("wrong", "1." + str(last_pos), "1." + str(tt))
if in_chars:
typed_chars["text"] = "Typed\n" + str(tt)
remaining_chars["text"] = "Remaining\n" + str(len(default_text) - tt)
try:
typing_speed["text"] = "Typing Speed\n" + \
str(chars*60 // (m*60 + s)) + " CPM"
except ZeroDivisionError:
pass
else:
tw = len(typed_text.get("0.0", tk.END).split()) # TYPED WORDS
typed_chars["text"] = "Typed\n" + str(tw)
remaining_chars["text"] = "Remaining\n" + str(nbr_words_in_text - tw)
try:
typing_speed["text"] = "Typing Speed\n" + \
str(chars//6 * 60 // (m*60 + s)) + \
" WPM"
# 6 CHARS ON AVERAGE
except ZeroDivisionError:
pass
if started:
text_to_type.after(100, update_tags)
check_changes_in_db()
root = tk.Tk()
root.title("TSI")
root.iconbitmap(r"TSI.ico")
root.config(bg=themes[current_theme]["root"]["bg"])
root.geometry("0x0+450+220")
root.minsize(660, 440)
root.focus_force()
avg = [len(word) for word in default_text.split()]
nbr_words_in_text = len(avg)
avg = sum(avg)//nbr_words_in_text
last_pos = 0
chars = 0 # FOR TYPING SPEED ONLY
m, s = 0, -1
flash_time = True
started = False
completed_correctly = False
flash_mode = False
welcome_text = tk.Label(
root, text="Typing Speed Increaser", width=600, pady=10, font=(
"Caviar Dreams Bold", "16", "bold"), fg=themes[current_theme]["welcome_text"]["fg"], bg=themes[current_theme]["welcome_text"]["bg"], relief=tk.RIDGE, borderwidth=2)
welcome_text.pack(side=tk.TOP, fill=tk.BOTH,
anchor=tk.CENTER, padx=10, pady=10)
show_text_frame = tk.Frame(
root, bg=themes[current_theme]["show_text_frame"]["bg"], width=600)
show_text_frame.pack(side=tk.TOP, fill=tk.BOTH,
anchor=tk.CENTER, expand=True, padx=10, pady=10)
typed_text = tk.Text(show_text_frame, padx=5, pady=5, insertbackground=themes[current_theme]["typed_text"]["insert_bg"], font=(
"Caviar Dreams Bold", "10", "bold"), fg=themes[current_theme]["typed_text"]["fg"], bg=themes[current_theme]["typed_text"]["bg"], wrap=tk.WORD, relief=tk.RIDGE, borderwidth=2)
text_to_type = tk.Text(show_text_frame, padx=5, pady=5, selectbackground=themes[current_theme]["typed_text"]["insert_bg"], insertbackground=themes[current_theme]["typed_text"]["insert_bg"], font=(
"Caviar Dreams Bold", "10", "bold"), fg=themes[current_theme]["text_to_type"]["fg"], bg=themes[current_theme]["text_to_type"]["bg"], wrap=tk.WORD, relief=tk.RIDGE, borderwidth=2)
text_to_type.insert("0.0", default_text)
text_to_type.tag_add("correct", "1.0", "1.0")
text_to_type.tag_config("correct", foreground=themes[current_theme]["tag_correct"]
["fg"], background=themes[current_theme]["tag_correct"]["bg"])
text_to_type.tag_add("wrong", "1.0", "1.0")
text_to_type.tag_config("wrong", foreground=themes[current_theme]["tag_wrong"]
["fg"], background=themes[current_theme]["tag_wrong"]["bg"])
passed_time = tk.Label(show_text_frame, text="Time\n00:00", font=(
"Caviar Dreams Bold", "10", "bold"), fg=themes[current_theme]["passed_time"]["fg"], bg=themes[current_theme]["passed_time"]["bg"], relief=tk.RIDGE, borderwidth=2)
typed_chars = tk.Label(show_text_frame, text="Typed\n0", font=(
"Caviar Dreams Bold", "10", "bold"), fg=themes[current_theme]["typed_chars"]["fg"], bg=themes[current_theme]["typed_chars"]["bg"], relief=tk.RIDGE, borderwidth=2)
remaining_chars = tk.Label(show_text_frame, text="Remaining\n" + str(len(default_text) if in_chars else nbr_words_in_text), font=(
"Caviar Dreams Bold", "10", "bold"), fg=themes[current_theme]["remaining_chars"]["fg"], bg=themes[current_theme]["remaining_chars"]["bg"], relief=tk.RIDGE, borderwidth=2)
total_chars = tk.Label(show_text_frame, text="Total\n" + str(len(default_text) if in_chars else nbr_words_in_text), font=(
"Caviar Dreams Bold", "10", "bold"), fg=themes[current_theme]["total_chars"]["fg"], bg=themes[current_theme]["total_chars"]["bg"], relief=tk.RIDGE, borderwidth=2)
typing_speed = tk.Label(show_text_frame, text="Typing Speed\n0 CPM" if in_chars else "Typing Speed\n0 WPM", font=(
"Caviar Dreams Bold", "10", "bold"), fg=themes[current_theme]["typing_speed"]["fg"], bg=themes[current_theme]["typing_speed"]["bg"], relief=tk.RIDGE, borderwidth=2)
start_label = tk.Label(show_text_frame, text="Start when you're ready :)", font=(
"Caviar Dreams Bold", "10", "bold"), fg=themes[current_theme]["start_label"]["fg"], bg=themes[current_theme]["start_label"]["bg"])
change_settings = tk.Label(show_text_frame, text="Change Text ?", font=(
"Caviar Dreams Bold", "10", "bold underline"), fg=themes[current_theme]["change_settings"]["fg"], bg=themes[current_theme]["change_settings"]["bg"])
change_settings.bind("<1>", lambda key: generate_new_text())
typed_text.place(relx=.0, rely=.0, relheight=.39, relwidth=.8)
text_to_type.place(relx=.0, rely=.40, relheight=.39, relwidth=.8)
passed_time.place(relx=.81, rely=.0, relheight=.19, relwidth=.19)
typed_chars.place(relx=.81, rely=.2, relheight=.19, relwidth=.19)
remaining_chars.place(relx=.81, rely=.4, relheight=.19, relwidth=.19)
total_chars.place(relx=.81, rely=.6, relheight=.19, relwidth=.19)
typing_speed.place(relx=.81, rely=.8, relheight=.19, relwidth=.19)
start_label.place(relx=.1, rely=.8, relheight=.19, relwidth=.29)
change_settings.place(relx=.4, rely=.8, relheight=.19, relwidth=.29)
update_time()
start_typing()
root.mainloop()