Skip to content

Commit 322c8a8

Browse files
authored
PR #95: Typing speed test
Typing speed test Merge pull request #95 from stellaappiok/typing-speed-test
2 parents 5e70ec3 + c3c9fc9 commit 322c8a8

4 files changed

Lines changed: 158 additions & 0 deletions

File tree

Typing-Speed-Test/ReadMe.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
## What it does
2+
3+
A terminal-based typing speed test built with Python's `curses` library.
4+
A random sentence is loaded from a text file and displayed on screen.
5+
As the user types, each character turns green for correct and red for
6+
incorrect in real time. Words per minute is calculated and displayed
7+
live throughout the test. The user can play multiple rounds or exit
8+
with ESC at any time.
9+
10+
## Setting Up This Project
11+
12+
### What is `requirements.txt`?
13+
14+
A `requirements.txt` file is a list of external packages your code needs to run, written in a plain text file. Instead of installing each package one by one, anyone can install everything in one command.
15+
16+
### Step 1 — Clone the repository
17+
18+
```bash
19+
git clone https://github.com/Grow-with-Open-Source/Python-Projects.git
20+
cd Python-Projects/typing-speed-test
21+
```
22+
23+
### Step 2 — Create a virtual environment (recommended)
24+
25+
A virtual environment keeps this project's packages separate from everything else on your computer.
26+
27+
```bash
28+
# Create it
29+
python -m venv venv
30+
31+
# Activate it — Windows
32+
venv\Scripts\activate
33+
34+
# Activate it — Mac/Linux
35+
source venv/bin/activate
36+
```
37+
38+
### Step 3 — Install the requirements
39+
40+
```bash
41+
pip install -r requirements.txt
42+
```
43+
44+
This reads `requirements.txt` and installs everything listed inside it automatically.
45+
46+
### Step 4 — Run the program
47+
48+
```bash
49+
python typing_test.py
50+
```
51+
52+
### A note on this project
53+
54+
The `curses` library comes built into Python automatically on Mac and Linux. On Windows it does not, so `requirements.txt` only installs `windows-curses` if you are on Windows — that is what the `; platform_system == "Windows"` condition means. Pip handles this automatically based on your operating system, so you do not need to do anything different.

Typing-Speed-Test/requirement.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
windows-curses; platform_system == "Windows"

Typing-Speed-Test/text.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The quick brown fox jumps over the lazy dog.
2+
Python is an amazing programming language.
3+
Practice makes perfect.
4+
Coding is a skill built through consistency.

Typing-Speed-Test/wpm_typing.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import curses
2+
from curses import wrapper
3+
import random
4+
import time
5+
6+
7+
def get_sentence():
8+
# ENTER THE RELATIVE PATH OF TEXT.TXT
9+
with open("ENTER THE RELATIVE PATH OF TEXT.TXT", "r") as file:
10+
sentences = file.readlines()
11+
12+
return random.choice(sentences).strip()
13+
14+
15+
def show_intro(screen):
16+
screen.clear()
17+
screen.addstr("⚡ Typing Speed Challenge")
18+
screen.addstr("\n\nPress any key to start...")
19+
screen.refresh()
20+
screen.getch()
21+
22+
23+
def draw_interface(screen, sentence, typed_chars, speed):
24+
screen.addstr(0, 0, sentence)
25+
screen.addstr(2, 0, f"Words Per Minute: {speed}")
26+
27+
for position, letter in enumerate(typed_chars):
28+
color = curses.color_pair(1)
29+
30+
if letter != sentence[position]:
31+
color = curses.color_pair(2)
32+
33+
screen.addstr(0, position, letter, color)
34+
35+
36+
def typing_game(screen):
37+
phrase = get_sentence()
38+
user_input = []
39+
40+
start = time.time()
41+
42+
screen.nodelay(True)
43+
44+
while True:
45+
elapsed = max(time.time() - start, 1)
46+
47+
speed = round((len(user_input) / 5) / (elapsed / 60))
48+
49+
screen.clear()
50+
draw_interface(screen, phrase, user_input, speed)
51+
screen.refresh()
52+
53+
if "".join(user_input) == phrase:
54+
screen.nodelay(False)
55+
break
56+
57+
try:
58+
pressed_key = screen.getkey()
59+
except:
60+
continue
61+
62+
if ord(pressed_key) == 27:
63+
return False
64+
65+
if pressed_key in ("KEY_BACKSPACE", "\b", "\x7f"):
66+
if user_input:
67+
user_input.pop()
68+
69+
elif len(user_input) < len(phrase):
70+
user_input.append(pressed_key)
71+
72+
return True
73+
74+
75+
def run_program(screen):
76+
curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
77+
curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
78+
79+
show_intro(screen)
80+
81+
while True:
82+
finished = typing_game(screen)
83+
84+
if not finished:
85+
break
86+
87+
screen.addstr(
88+
4,
89+
0,
90+
"Great job! Press any key for another round or ESC to quit."
91+
)
92+
93+
key = screen.getkey()
94+
95+
if ord(key) == 27:
96+
break
97+
98+
99+
wrapper(run_program)

0 commit comments

Comments
 (0)