Test Your Typing Speed with Python - Tkinter Project

Typing Speed Tester in Python

Introduction

Initially, when we start using a computer, our typing speed plays a very bad role. Day by day it improves with practice. There are many jobs that require good typing skills. If you're a programmer like me, you probably know how important good typing speed is. But how can you test how fast your hands are for keyboard typing?

Well, I made a GUI application to test Typing Speed using Python. You can easily give a typing test there to check your hand skill and also the accuracy rate. Throughout this tutorial, I will share the Source Code in several segments along with related information.

So, scroll slowly, go through each step ahead and stay tuned till the end. For more convenience, you can get the project file directly from the end.

👉Visit AlsoAn Image Viewer Application using Python Tkinter

Requirements

The project needs some basic requirements which you must fulfill. Details are given below.

☛Install Tkinter: pip install Tk (For managing the User Interface of this application)

☛Install Pillow: pip install Pillow (To display the background image)

☛Install pynput: pip install pynput (To manage the keyboard functionalities)

The Project Details

👉When you will run the main program, you will see a welcome window with a Title and a button to Start your Typing Test. The button will bring you to the next page where you will visit a randomly chosen paragraph from several choices also with an Entry box, where you can type.

👉Whenever you press any key there, a one-minute countdown will start and you will have to type text similar to the given paragraph. The more accurately you type, the higher your typing accuracy will be.

👉After the timer reaches zero, you will see a third window where the wpm (words per minute), accuracy, and net speed (wpm * accuracy) will be shown.

👉To maintain the beauty of this application, I have used an image instead of a black screen for the last window. So, you must present the image file in your current working directory (Image/resultImage.jpg) where the project files are present.

👉You will find two more python files there, one is 'settings.py' where every setting is present which is set for the main window. One more file, 'text.py' contains several paragraph choices from where the main program file chooses only one every time randomly.

main.py

I will cover the main program in several segments. I highly recommend you, create a different folder for this project, next create a folder called 'Image' inside there and put this image (resultImage.jpg) there. Now create a python file with this name ('main.py') and follow the rest.

Import the modules

Let's start writing your code by importing these modules.


import time
import random
import text as tt
from tkinter import *
import settings as st
from threading import *
from PIL import Image, ImageTk
from pynput.keyboard import Listener

Create a class

Create a different class to maintain all the tasks related to typing test.


class TypingTest:

Declare init() function

Here, we have created a GUI Tkinter window and configured all its settings.


def __init__(self, root):
# Window Settings
self.window = root
self.window.geometry(f"{st.width}x{st.height}")
self.window.title('Typing Tester')
self.window.resizable(width = False, height = False)
self.window.configure(bg=st.color2)

# Declaring some variables
self.key = None
self.typingStarted = False

# Text for use as a paragraph
self.textList = [tt.text1, tt.text2, tt.text3, tt.text4, tt.text5]

# Tkinter Frame
self.frame = Frame(self.window, bg=st.color2, width=st.width, \
height=st.height)
self.frame.place(x=0, y=0)

# Calling the function, startWindow()
self.startWindow()

Function for the welcome window

Declare a different function called startWindow() to show widgets present in the Welcome Window.

starting window of the typing tester application
Starting window of the Application

# Function to show the widgets present in the welcome window
def startWindow(self):
# A Tkinter Label to display the title
titleLabel = Label(self.frame, text="Typing Speed Test", bg=st.color2, \
fg=st.color1 ,font=(st.font3, 35, "bold"))
titleLabel.place(x=175, y=80)

startButton = Button(self.frame, text="Start Here", border=0, \
cursor='hand2' ,fg=st.color2, bg=st.color1, font=(st.font4, 18), \
command=self.startTest)
startButton.place(x=320, y=215)

The startTest() function

Here, all the widgets related to typing tests will be shown. For example, a text widget for showing the Paragraph, an Entry widget for taking the input text from the user, and a Label to show the remaining time of the test.

Whenever the user will press a key here, the time count down will start (60 seconds).

main window of the typing speed tester
Main window of the application

# Function to display widgets related to typing test
def startTest(self):
# Clearing the previous screen
self.clearScreen()

# Getting the total time allocated for the test
self.totalTime = st.totalTime

# Choosing a random paragraph from the list of several choices
self.paragraph = random.choice(self.textList)

# A Label widget for showing the remaining time
self.timeLabel = Label(self.frame, text="1:00", bg=st.color2, \
fg=st.color1, font=(st.font1, 15))
self.timeLabel.place(x=20, y=15)

# A Tkinter Text widget to display the paragraph
textBox = Text(self.frame, width=65, height=10, bg=st.color1, \
font=(st.color2, 13))
textBox.place(x=40, y=80)

# Inserting the text into the Text widget
textBox.insert(END, self.paragraph)
textBox.config(state='disabled')

# A Tkinter Entry widget to get input from the user
self.inputEntry = Entry(self.frame, fg=st.color2, bg=st.color1, \
width=35, font=(st.font4, 20))
self.inputEntry.place(x=100, y=360)

# Define the on press to capture key pressing
ls = Listener(on_press = self.listener)
# Starting a different thread for this task
ls.start()

The listener() function

I declared a function called listener() to detect the key pressing. Whenever a key press will detect, this function will call the multiThreading() function to create a different thread.


# Function to detect key press
def listener(self, key):
self.key = str(key)

# If any key is pressed, a different thread will create
# to Count Down the remaining time.
if self.key != None:
self.typingStarted = True
self.multiThreading()

# Returning False to stop the thread created to
# capture key pressing.
return False

The multiThreading() function

This function creates a different thread to handle the time management task (time count down) so that the main program can manage the Graphical Interface properly. As a target, I select the countDown() function to run on a different thread.


# Function to create a different Thread for Count Down Operation
def multiThreading(self):
x = Thread(target=self.countDown)
x.start()

The countDown() function

This function will count down the remaining time and display it on the Time label. When the time will touch zero, the calculateResult() function will be called.


# Function to Count Down the remaining time
def countDown(self):
while self.totalTime > 0:
# Updating the Time Label
self.timeLabel.config(text=f"{0}:{self.totalTime}")
time.sleep(1)
self.totalTime -= 1

self.timeLabel.config(text=f"{0}:{0}")
# Calling the Function to Calculate the Final Result
self.calculateResult()

Background Image Handling

Before declaring the calculateResult() function, let's do something else. To maintain the beauty of this application, I have set a background image for the result window. The below function will handle that task.


# Function to Handle a background image for the
# Final Window.
def backgroundImage(self, img):
# Opening the image
image = Image.open(img)
# Resize the image to fit the screen
resizedImg = image.resize((st.width, st.height))
# Creating an instance of PhotoImage class of ImageTk module
self.img = ImageTk.PhotoImage(resizedImg)

label = Label(self.frame, image=self.img)
label.pack()

Calculate the Result

Now declare the calculateResult() function to calculate the final result and display it in the window. Users can restart the test again through a button provided here.

showing the final result of the typing performance
Final result of the typing performance

# Function for calculating the Final Result and displaying
# it to the Window
def calculateResult(self):
# Getting the text from the Tkinter Entry Widget and storing
# it to a variable called text.
text = self.inputEntry.get()
# Splitting the text by choosing the SPACE as a delimiter and
# storing the words in a list.
text = text.split(" ")

# Clearing the previous screen
self.clearScreen()
# Setting a Background image
self.backgroundImage(st.resultImage)

# wpm(word per minute)
wpm = len(text)
# A variable for counting the correct answer from the given
correctAnswer = 0

# splliting the main paragraph by choosing the SPACE as a
# delimiter and store the words in a list.
mainText = self.paragraph.split(" ")
# Excluding the word redundancy from the list by converting
# it to a python set.
mainText = set(mainText)

# Iterate through the given text by the user
for word in text:
# If the word is is present in the Main Paragraph
# increment the correctAnswer variable by one.
if word in mainText:
correctAnswer += 1

# Calculating the accuracy of the given text by the user
accuracy = (correctAnswer/wpm)*100
# Calculating the net speed after applying the
# percentage of the accuracy
netSpeed = (wpm/100)*accuracy

# Label to show the wpm(word per minute)
wpmLabel = Label(self.frame, text=wpm, bg=st.color1, fg=st.color2, \
font=(st.font2, 24))
wpmLabel.place(x=160, y=186)

# Label to show the accuracy
accuracyLabel = Label(self.frame, text=f"{int(accuracy)}%", \
bg=st.color1, fg=st.color2, font=(st.font2, 24))
accuracyLabel.place(x=366, y=186)

# Label to show the net speed
netSpeedLabel = Label(self.frame, text=int(netSpeed), \
bg=st.color1, fg=st.color2, font=(st.font2, 24))
netSpeedLabel.place(x=612, y=186)

# A Button to start the test again
resetButton = Button(self.frame, text="Test Again", border=0, \
cursor='hand2' ,fg=st.color2, bg=st.color1, font=(st.font4, 18), \
command=self.startTest)
resetButton.place(x=320, y=360)

Clear the Screen

If you look closely, you may have seen a function called clearScreen() used multiple times in the program. Here is the function; it removes all the widgets present in the frame we declared in the init() function.


# Function to clear all the widgets from the frame
def clearScreen(self):
for widget in self.frame.winfo_children():
widget.destroy()

The main function


# The main function
if __name__ == "__main__":
# Instance of Tk class
root = Tk()
# Object of TypingTest class
obj = TypingTest(root)
root.mainloop()

Settings.py

All settings set in the main function are declared here. This is highly recommended from me to you, don't change anything here.


# All the settings set in the main function are declared here.
# It's highly recommended from me to you, do not change anything
# here.

# Width and Height
width = 800
height = 500

# Total Time
totalTime = 60

# The path of the image file
resultImage = "Images/resultImage.jpg"

# Colors
color1 = "white"
color2 = "black"

# Font choices
font1 = "Times new roman"
font2 = "Helvetica"
font3 = "Courier"
font4 = "Kokila"

Test.py

Remember, I told you in the project description section that the program randomly selects paragraphs from multiple choices. Here, we will declare a Python file named 'test.py' where each paragraph is stored in a separate variable.


text1 = "Allergies, also known as allergic diseases, are a number of \
conditions caused by hypersensitivity of the immune system to typically \
harmless substances in the environment. These diseases include hay \
fever, food allergies, atopic dermatitis, allergic asthma, and \
anaphylaxis. Symptoms may include red eyes, an itchy rash, sneezing, \
coughing, a runny nose, shortness of breath, or swelling. Food \
intolerances and food poisoning are separate conditions."

text2 = "We usually give inputs to the computer using the keyboard. \
Well, what if there is something that can record the keystroke given \
through our keyboard? Whatever you type, a password or a username, \
it would record everything. You might be thinking it's a fantasy. \
No, it's not. A Keylogger can do all of those tasks hiddenly. There \
are two types of keylogger, Software Keylogger and Hardware Keylogger. \
Literally it tracks keystrokes and stores all the activity in a log file."

text3 = "People have benefited a lot since the invention of the computer. \
Today, we can easily manage human management work using many software \
tools. Student management as such is a tool for handling students' data. \
For example, general information(name, address, DOB, etc.), admission \
details, grading system, attendance, and others relevant to the school \
or college students."

text4 = "Kali Linux is a Debian-derived Linux distribution designed for \
digital forensics and penetration testing. It is maintained and funded \
by Offensive Security. Kali Linux has around 600 penetration-testing \
programs (tools), including Armitage (a graphical cyber attack management \
tool), Nmap (a port scanner), Wireshark (a packet analyzer), metasploit \
(penetration testing framework), John the Ripper (a password cracker), \
sqlmap (automatic SQL injection and database takeover tool), Aircrack-ng \
(a software suite for penetration-testing wireless LANs), etc."

text5 = "Diabetes mellitus, commonly known as diabetes, is a group of \
metabolic disorders characterized by a high blood sugar level \
(hyperglycemia) over a prolonged period of time. Symptoms often include \
frequent urination, increased thirst and increased appetite. If left \
untreated, diabetes can cause many health complications. Acute \
complications can include diabetic ketoacidosis, hyperosmolar \
hyperglycemic state, or death. Serious long-term complications include \
cardiovascular disease, stroke, chronic kidney disease, foot ulcers, \
damage to the nerves, damage to the eyes and cognitive impairment."

Output

Watch the entire video to understand how the application works actually.

Download the Project File

Download the project file from my GitHub page through the Download button below.

Summary

In this tutorial, we built a beautiful project using our favorite programming language Python. This is a Typing Speed Tester Application in Python. We used the Tkinter library to manage the User Interface of this application.

The whole project is based on three python files ('main.py', 'settings.py', and 'text.py'). You will have to type text similar to the given paragraph. The more accurately you type, the higher your typing accuracy will be. Each time you will get only 60 seconds (one minute) to check your typing speed. 

The result will be shown in wpm (word per minute), accuracy (percentage of correct word typing), and net speed (wpm * accuracy).

So, let's check your typing speed using this beautiful Python Application. I scored 38 wpm with 96% accuracy highest, what is your score? Let me know in the comment section. You'll get a reply soon.

To get more lovely Tkinter Examples, visit the separate page created only for Python Projects. Some examples are given below.

👉Meditation App in Python Tkinter: Practice Deep Breathing

👉Language Translator App with Python Tkinter - Google Translate

👉Image to Pencil Sketch Converter in Python - Tkinter Project

👉An Advanced Alarm Clock using Python Tkinter

See you soon on the next topic. Have a nice day ahead, cheers!

PySeek

Subhankar Rakshit

Meet Subhankar Rakshit, a Computer Science postgraduate (M.Sc.) and the creator of PySeek. Subhankar is a programmer, specializes in Python language. With a several years of experience under his belt, he has developed a deep understanding of software development. He enjoys writing blogs on various topics related to Computer Science, Python Programming, and Software Development.

Post a Comment (0)
Previous Post Next Post