-
Notifications
You must be signed in to change notification settings - Fork 0
/
wpm_typing_test.py
85 lines (68 loc) · 2.73 KB
/
wpm_typing_test.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
# WPM TYPING TEST BY ARYAN ROSHAN
import curses,time, random
from curses import wrapper
def intro(stdscr):
# Displays welcome message and instructions.
stdscr.clear()
stdscr.addstr("Welcome to my WPM typing test! Created by Aryan Roshan.")
stdscr.addstr("\nPress any key to begin!")
stdscr.refresh()
stdscr.getkey()
def display_text(stdscr, given, user_in, wpm = 0):
# Updates the displayed text and WPM on screen.
stdscr.clear()
stdscr.addstr(given)
stdscr.addstr(1,0, f"WPM: {wpm}")
for i, char in enumerate(user_in):
correct_c = given[i]
color = curses.color_pair(1) # Highlights correct input in green.
if char != correct_c:
color = curses.color_pair(2) # Highlights incorrect input in red.
stdscr.addstr(0 , i, char, color)
def load_text():
# Loads a random phrase from a file.
with open("generated_phrases.txt", "r") as f:
lines = f.readlines()
return random.choice(lines).strip()
def wpm_test(stdscr):
given_phrase = load_text()
user_input = []
wpm = 0
start_t = time.time()
stdscr.nodelay(True) # Allows for real-time key input without blocking.
while True:
# Calculates the WPM based on elapsed time and correct inputs.
time_elapsed = max(time.time() - start_t, 1)
wpm = round((len(user_input) * (60 / time_elapsed)) / 5)
stdscr.clear()
display_text(stdscr, given_phrase, user_input, wpm)
stdscr.refresh()
if "".join(user_input) == given_phrase:
stdscr.nodelay(False) # Pause for result display.
break
try:
key = stdscr.getkey()
except:
continue
if ord(key) == 27: # Exit on ESC.
break
if key in ("KEY_BACKSPACE", '\b', "\x7f"):
if len(user_input) > 0:
user_input.pop() # Removes last char on backspace.
elif len(user_input) < len(given_phrase):
user_input.append(key) # Adds char to input.
def main(stdscr):
# Initializes color pairs for display.
curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_BLACK)
intro(stdscr)
while(True):
wpm_test(stdscr)
# Prompts for replay or exit after completing the test.
stdscr.addstr(2, 0, "You completed the text! Press any key to play again or press ESC to close.")
stdscr.addstr(3, 0, "Hope you enjoyed!")
key = stdscr.getkey()
if ord(key) == 27:
break
wrapper(main) # Starts the application with curses wrapper for proper terminal handling.