Typing Speed Test Game using Python

Typing Speed Test Game using Python

Introduction:

In this article, we will create a Typing Speed Test Game using Python and Tkinter. This game will help users check how fast they can type in Words Per Minute (WPM) and also measure their typing accuracy. Whether you’re new to Python or have some experience, this project is a fun way to practice coding while improving your typing speed!

Typing is an important skill for everyone who uses computers, whether it’s for coding, writing, or everyday communication. In this article, we will show you how to make a Typing Speed Test Game that calculates your typing speed (WPM) and accuracy based on a text.

The game will help you track your typing performance, making it a great tool for improving your typing speed. We will use Python and Tkinter, which is a built-in library for creating simple graphical interfaces, to build the game. The game will have a basic interface where users can type random text, and it will track how well they do.

Required Modules or Packages:

To build this typing speed test game, you will need the following Python modules:

  • Tkinter: A built-in library in Python that helps create graphical user interfaces (GUIs).

  • Time: A Python module used to measure time intervals.

  • Random: A module used to generate random text for the typing challenge.

If Tkinter is not installed on your system, you can install it using the following command in your terminal:

				
					pip install tk
				
			

How to Run the Code:

Follow these steps to run the Typing Speed Test Game on your system:

  1. Make sure Python is installed on your computer.

  2. Install Tkinter using pip (if it’s not already installed).

  3. Copy the full code provided below into a Python file (e.g., typing_speed_test.py).

  4. Open your terminal or command prompt, go to the folder where the file is saved, and run the file using the command:

				
					python typing_speed_test.py
				
			

          5. The game window will open, and you can start typing the displayed text to test your speed and accuracy.

Code Explanation:

In this section, we will go through the key parts of the code that make the Typing Speed Test Game work.

Importing Libraries:

				
					import time
import random
import tkinter as tk
from tkinter import font
				
			

We import the required modules for time tracking, random text selection, and GUI creation using Tkinter.

Class Initialization (__init__ method):

The __init__ method sets up the main window, custom fonts, and prepares the layout by calling the setup_ui method and initializing the test.

				
					def __init__(self, root):
    self.root = root
    self.setup_ui()
    self.new_test()

				
			

UI Setup (setup_ui method):

The setup_ui method creates the layout of the game: adding labels for the title, sample text, input box for typing, and a restart button.

				
					def setup_ui(self):
    self.header = tk.Label(self.root, text="Typing Speed Test Game", font=self.title_font)
    self.sample_label = tk.Label(self.sample_frame, text="", font=self.text_font)
    self.input_text = tk.Text(self.root, font=self.text_font, height=5, width=60)
    self.restart_btn = tk.Button(self.btn_frame, text="New Test", command=self.new_test)
    self.result_label = tk.Label(self.root, text="", font=self.result_font)

				
			

Starting a New Test (new_test method):

The new_test method selects a random typing challenge text and prepares the game for a fresh start by resetting the input box and clearing results.

				
					def new_test(self):
    self.original_text = random.choice(self.texts)
    self.sample_label.config(text=self.original_text)
    self.input_text.delete(1.0, tk.END)
    self.result_label.config(text="")

				
			

Start Timer (start_timer method):

The start_timer method tracks the time when the user begins typing and starts the timer upon the first keystroke.

				
					def start_timer(self, event):
    if not self.running:
        self.running = True
        self.start_time = time.time()
        self.root.after(100, self.update_timer)

				
			

Update Timer (update_timer method):

This method updates the time every 100 milliseconds and displays the elapsed time.

				
					def update_timer(self):
    if self.running:
        elapsed_time = time.time() - self.start_time
        self.result_label.config(text=f"Time: {elapsed_time:.2f} seconds")
        self.root.after(100, self.update_timer)

				
			

Displaying Final Results (show_final_results method):

Once the user finishes typing, this method calculates the Words Per Minute (WPM), accuracy, and elapsed time, then displays the results.

				
					def show_final_results(self):
    elapsed_time = time.time() - self.start_time
    wpm = int(len(user_input.split()) / (elapsed_time / 60))
    accuracy = (correct / len(self.original_text)) * 100
    result_text = f"Time: {elapsed_time:.2f}s | WPM: {wpm} | Accuracy: {accuracy:.1f}%"
    self.result_label.config(text=result_text)

				
			

Running the Application:

Finally, we run the main Tkinter event loop to keep the game window open

				
					if __name__ == "__main__":
    root = tk.Tk()
    app = TypingSpeedTest(root)
    root.mainloop()

				
			

Source Code:

				
					import time
import random
import tkinter as tk
from tkinter import font

def get_text():
    texts = [
        "The quick brown fox jumps over the lazy dog.",
        "Python programming is fun and engaging.",
        "Typing tests improve your speed and accuracy.",
        "Practice makes perfect when it comes to typing."
    ]
    return random.choice(texts)

class TypingSpeedTest:
    def __init__(self, root):
        self.root = root
        self.root.title("Typing Speed Test")
        self.root.geometry("800x600")
        self.root.configure(bg='#F0F0F0')

        # Custom fonts
        self.title_font = font.Font(family="Helvetica", size=24, weight="bold")
        self.text_font = font.Font(family="Courier New", size=16)
        self.result_font = font.Font(family="Arial", size=14, weight="bold")

        # Initialize variables
        self.start_time = None
        self.running = False
        self.original_text = ""

        # Build UI
        self.setup_ui()
        self.new_test()

    def setup_ui(self):
        self.header = tk.Label(self.root, text="Typing Speed Test", font=self.title_font, bg='#F0F0F0', fg='#2C3E50')
        self.header.pack(pady=20)

        self.sample_frame = tk.Frame(self.root, bg='white', padx=20, pady=20)
        self.sample_frame.pack(pady=10, fill=tk.X, padx=40)

        self.sample_label = tk.Label(
            self.sample_frame,
            text="",
            font=self.text_font,
            bg='white',
            fg='#34495E',
            wraplength=700,
            justify=tk.LEFT
        )
        self.sample_label.pack()

        self.input_text = tk.Text(
            self.root,
            font=self.text_font,
            height=5,
            width=60,
            padx=10,
            pady=10,
            wrap=tk.WORD,
            bg='#FFFFFF'
        )
        self.input_text.pack(pady=20)
        self.input_text.bind("<KeyPress>", self.start_timer)  # 🛠️ Binding the typing event

        self.btn_frame = tk.Frame(self.root, bg='#F0F0F0')
        self.btn_frame.pack(pady=10)

        self.restart_btn = tk.Button(
            self.btn_frame,
            text="New Test",
            font=self.text_font,
            command=self.new_test,
            bg='#3498DB',
            fg='white'
        )
        self.restart_btn.pack(side=tk.LEFT, padx=10)

        self.result_label = tk.Label(
            self.root,
            text="Click the text area below to start typing!",
            font=self.result_font,
            bg='#F0F0F0',
            fg='#27AE60'
        )
        self.result_label.pack(pady=20)

    def new_test(self):
        self.original_text = get_text()
        self.sample_label.config(text=self.original_text)
        self.input_text.delete('1.0', tk.END)
        self.result_label.config(text="Click the text area below to start typing!", fg='#27AE60')
        self.running = False
        self.start_time = None
        self.input_text.config(bg='#FFFFFF', state=tk.NORMAL)
        self.input_text.focus_set()

    def start_timer(self, event):
        if not self.running:
            self.running = True
            self.start_time = time.time()
            self.input_text.config(bg='#F9EBEA')
            self.result_label.config(text="Typing...", fg='#E74C3C')
            self.root.after(100, self.update_timer)

        self.check_completion()

    def update_timer(self):
        if self.running:
            elapsed = time.time() - self.start_time
            wpm = self.calculate_wpm(elapsed)
            self.result_label.config(text=f"Elapsed Time: {elapsed:.1f}s | WPM: {wpm}")
            self.root.after(1000, self.update_timer)

    def calculate_wpm(self, elapsed):
        typed_text = self.input_text.get('1.0', 'end-1c')
        typed_words = len(typed_text.split())
        return int(typed_words / (elapsed / 60)) if elapsed > 0 else 0

    def check_completion(self):
        user_input = self.input_text.get('1.0', 'end-1c')
        if user_input == self.original_text:
            self.show_final_results()

    def show_final_results(self):
        self.running = False
        self.input_text.config(state=tk.DISABLED)
        elapsed_time = time.time() - self.start_time
        user_input = self.input_text.get('1.0', 'end-1c')

        min_length = min(len(self.original_text), len(user_input))
        correct = sum(1 for o, t in zip(self.original_text, user_input) if o == t)
        accuracy = (correct / len(self.original_text)) * 100 if len(self.original_text) > 0 else 0
        wpm = self.calculate_wpm(elapsed_time)

        result_text = (
            f"Time: {elapsed_time:.2f}s | WPM: {wpm} | Accuracy: {accuracy:.1f}%\n"
            "Press 'New Test' to try again!"
        )

        if user_input == self.original_text:
            result_text = "Perfect! " + result_text

        self.result_label.config(text=result_text, fg='#27AE60')
        self.input_text.config(bg='#EAFAF1')

if __name__ == "__main__":
    root = tk.Tk()
    app = TypingSpeedTest(root)
    root.mainloop()
				
			

Output

Get Huge Discounts
More Python Projects