diff --git a/Typing-Speed-Test/ReadMe.md b/Typing-Speed-Test/ReadMe.md new file mode 100644 index 0000000..6900899 --- /dev/null +++ b/Typing-Speed-Test/ReadMe.md @@ -0,0 +1,54 @@ +## What it does + +A terminal-based typing speed test built with Python's `curses` library. +A random sentence is loaded from a text file and displayed on screen. +As the user types, each character turns green for correct and red for +incorrect in real time. Words per minute is calculated and displayed +live throughout the test. The user can play multiple rounds or exit +with ESC at any time. + +## Setting Up This Project + +### What is `requirements.txt`? + +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. + +### Step 1 — Clone the repository + +```bash +git clone https://github.com/Grow-with-Open-Source/Python-Projects.git +cd Python-Projects/typing-speed-test +``` + +### Step 2 — Create a virtual environment (recommended) + +A virtual environment keeps this project's packages separate from everything else on your computer. + +```bash +# Create it +python -m venv venv + +# Activate it — Windows +venv\Scripts\activate + +# Activate it — Mac/Linux +source venv/bin/activate +``` + +### Step 3 — Install the requirements + +```bash +pip install -r requirements.txt +``` + +This reads `requirements.txt` and installs everything listed inside it automatically. + +### Step 4 — Run the program + +```bash +python typing_test.py +``` + +### A note on this project + +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. diff --git a/Typing-Speed-Test/requirement.txt b/Typing-Speed-Test/requirement.txt new file mode 100644 index 0000000..1386bc4 --- /dev/null +++ b/Typing-Speed-Test/requirement.txt @@ -0,0 +1 @@ +windows-curses; platform_system == "Windows" \ No newline at end of file diff --git a/Typing-Speed-Test/text.txt b/Typing-Speed-Test/text.txt new file mode 100644 index 0000000..cb0c7e2 --- /dev/null +++ b/Typing-Speed-Test/text.txt @@ -0,0 +1,4 @@ +The quick brown fox jumps over the lazy dog. +Python is an amazing programming language. +Practice makes perfect. +Coding is a skill built through consistency. \ No newline at end of file diff --git a/Typing-Speed-Test/wpm_typing.py b/Typing-Speed-Test/wpm_typing.py new file mode 100644 index 0000000..434fe1d --- /dev/null +++ b/Typing-Speed-Test/wpm_typing.py @@ -0,0 +1,99 @@ +import curses +from curses import wrapper +import random +import time + + +def get_sentence(): + # ENTER THE RELATIVE PATH OF TEXT.TXT + with open("ENTER THE RELATIVE PATH OF TEXT.TXT", "r") as file: + sentences = file.readlines() + + return random.choice(sentences).strip() + + +def show_intro(screen): + screen.clear() + screen.addstr("⚡ Typing Speed Challenge") + screen.addstr("\n\nPress any key to start...") + screen.refresh() + screen.getch() + + +def draw_interface(screen, sentence, typed_chars, speed): + screen.addstr(0, 0, sentence) + screen.addstr(2, 0, f"Words Per Minute: {speed}") + + for position, letter in enumerate(typed_chars): + color = curses.color_pair(1) + + if letter != sentence[position]: + color = curses.color_pair(2) + + screen.addstr(0, position, letter, color) + + +def typing_game(screen): + phrase = get_sentence() + user_input = [] + + start = time.time() + + screen.nodelay(True) + + while True: + elapsed = max(time.time() - start, 1) + + speed = round((len(user_input) / 5) / (elapsed / 60)) + + screen.clear() + draw_interface(screen, phrase, user_input, speed) + screen.refresh() + + if "".join(user_input) == phrase: + screen.nodelay(False) + break + + try: + pressed_key = screen.getkey() + except: + continue + + if ord(pressed_key) == 27: + return False + + if pressed_key in ("KEY_BACKSPACE", "\b", "\x7f"): + if user_input: + user_input.pop() + + elif len(user_input) < len(phrase): + user_input.append(pressed_key) + + return True + + +def run_program(screen): + curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK) + curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK) + + show_intro(screen) + + while True: + finished = typing_game(screen) + + if not finished: + break + + screen.addstr( + 4, + 0, + "Great job! Press any key for another round or ESC to quit." + ) + + key = screen.getkey() + + if ord(key) == 27: + break + + +wrapper(run_program)