Test Typing Speed using Python App

Test Typing Speed using Python

Hello folks! Today we are back with one another tutorial on How to Test Typing Speed using Python. This is one of the most requested articles. Each and every beginner-level developer once thought of checking his/her typing speed and in doing so, we usually visit ample websites. but, what if you have your own application that helps you to test your typing speed whenever you want?

So today, in order to help you build this project, we have decided to come up with this article on How to Test Typing Speed using Python? In this tutorial, we will not only provide you with the source code but also explain each concept and line of code so that you get a tight grip on all the different concepts involved in this project.

Project Overview: Test Typing Speed using Python

Project Name:Test Typing Speed using Python
AbstractIt’s a GUI-based project used with the tkinter and ctypes modules to organize all the elements that work under Test Typing Speed using Python.
Language/s Used:Python
IDEPyCharm and Thonny
Python version (Recommended):Python 3.x
Database:Not required
Type:Desktop Application
Recommended forIntermediates of Python and final year students

Basically, we will be developing a GUI with some features that will help a user get to know about his/her typing speed. For the purpose of building this project, we will use a famous library in Python i.e Tkinter. Tkinter will really help us in building this GUI with some of its built-in functions and features. So, now let us get started.

Before starting with the actual coding of the project, let us go through the list of features that we will include in this project, and then we will move on to the coding of this project which is How to Test Typing Speed using Python?

Features of Typing Speed Tester

  • A one-minute timer
  • A feature that shows the user which letter he/she now has to press
  • Different colors for the letter that is already typed
  • Show the current position of the writer (live rolling of alphabets)
  • A restart button

Now that with a basic idea of what exactly needs to be built, let us move on to the next phase of this project.

Code to Test Typing Speed using Python

Basic imports

from tkinter import *
import ctypes
import random
import tkinter

Setting up the window and its look

# For a sharper window
ctypes.windll.shcore.SetProcessDpiAwareness(1)

# Setup
storage = Tk()
storage.title('CopyAssignment - Typing Speed Test')

# Setting the starting window dimensions
storage.geometry('1400x700')

# Setting the Font for all Labels and Buttons
storage.option_add("*Label.Font", "consolas 30")
storage.option_add("*Button.Font", "consolas 30")

Explanation:
In this section, we have used the title() function to give a title to our window, wherein all the content of our project will be displayed. Since the Tkinter windows typically have a poor appearance by default, we import ctypes to enable us to determine the dpi of our computer and improve the appearance of the window thus we used ctypes.windll.shcore.SetProcessDpiAwareness(1).

For loading dynamic link libraries, ctypes exports the cdll, as well as the windll and oledll objects on Windows. Apart from that geometry() function helps us to set the size of the window. Using the option_add() function we have set the fonts to Consolas in size 30 of all the buttons and labels that are included in this GUI

Main logic and selecting random lines to display

def handlingLabels():
    # Text List
    random_selection = [
        'A random statement can inspire authors and help them start writing. It challenges the author to use their imagination because the sentences subject is utterly ambiguous. The random sentence may be creatively used in a variety of ways by writers. The statement is most frequently used to start a tale. Another choice is to include it into the narrative. The issue of using it to conclude a tale is far more challenging. In all of these scenarios, the writer is compelled to use their imagination because they have no idea what words will come out of the tool.',
        'Python Code aims to teach beginning and intermediate programmers Python through tutorials, recipes, articles, and problem-solving techniques while also disseminating information globally. Everyone in the globe will be able to learn how to code for free thanks to Python Code. Python is a general-purpose, high-level, interpreted programming language. Code readability is prioritised in its design philosophy, which makes heavy use of indentation. Python uses garbage collection and has dynamic typing. It supports a variety of programming paradigms, including procedural, object-oriented, and functional programming as well as structured programming (especially this). Due to its extensive standard library, it is frequently referred to as a "batteries included" language.',
        'We begin with the imports as usual. We must import tkinter since we utilise it to create the user interface. In order to subsequently modify the typefaces on our components, we additionally import the font module from tkinter. The partial function is obtained from functools and is a brilliant function that accepts another function as a first argument, along with certain args and kwargs, and returns a reference to this function with those arguments. When we wish to add one of our functions to a command argument of a button or key binding, this is extremely helpful.',
        'A computer programmer is a person who writes computer programmes, frequently for bigger pieces of software. They are also known as software developers, software engineers, programmers, or coders. A programmer is a person who uses a particular programming language to construct or write computer software or applications. The majority of programmers have substantial computer and coding expertise across a wide range of platforms and programming languages, including SQL, Perl, XML, PHP, HTML, C, C++, and Java. The terms "programmer" and "software engineer" may be used to describe the same position at various businesses because there is no industry-wide vocabulary standard. Usually, a "programmer" or "software developer" will concentrate on translating a precise specification into computer code.'
    ]
    # Chosing one of the texts randomly with the choice function
    text = random.choice(random_selection).lower()

Explanation:
In the code, we first define a list of random_selection, and then we use the random.choice() method to randomly select one of the sentences in the list. This function creates the widgets and launches the writing test. We have included four paragraphs and every time a user restarts the window, a random paragraph will get selected and will be displayed.

Setting the position of various labels

Note: The below code is part of the above function.

# defining where the text is split
    splitPoint = 0
    # This is where the text is that is already written
    global nameLabelLeft
    nameLabelLeft = Label(storage, text=text[0:splitPoint], fg='green')
    nameLabelLeft.place(relx=0.5, rely=0.5, anchor=E)

    # Here is the text which will be written
    global nameLabelRight
    nameLabelRight = Label(storage, text=text[splitPoint:])
    nameLabelRight.place(relx=0.5, rely=0.5, anchor=W)

    # This label shows the user which letter he now has to press
    global currentAlphabetLabel
    currentAlphabetLabel = Label(storage, text=text[splitPoint], fg='grey')
    currentAlphabetLabel.place(relx=0.5, rely=0.6, anchor=N)

    # this label shows the user how much time has gone by
    global secondsLeft
    headingLabel = Label(storage, text=f'CopyAssignment - Typing Speed Test', fg='blue')
    headingLabel.place(relx=0.5, rely=0.2, anchor=S)
    secondsLeft = Label(storage, text=f'0 Seconds', fg='red')
    secondsLeft.place(relx=0.5, rely=0.4, anchor=S)

    global writeAble
    writeAble = True
    storage.bind('<Key>', handlekeyPress)

    global secondsPassed
    secondsPassed = 0

    # Binding callbacks to functions after a certain amount of time.
    storage.after(60000, stopGame)
    storage.after(1000, timeAddition)

Explanation:
For the labels, we provide the starting and ending points of the text. Since there are two labels—one indicating where the written text is and the other where the text that will be written—this is done. The user won’t see that these two are separate labels because they are positioned next to one another. We create a label, store it to the variable with the proper name, and then position it inside the window using put (). The widget is placed precisely, or at least more precisely than the pack, using this method (). The elements will always be in the middle with respect to the window itself if the relax and depend parameters are set to 0.5.

The bounding rectangle’s starting point is specified by the anchor parameter, which is used in coordinate systems. To make them appear near to one another and seamless, one must be E for east and one W for west. If the test is still running, the writeable variable is True; if it’s False, the test will be over. Then, we associate each key event with the handlekeyPress() method, which we’ll discuss later. The aforementioned label receives it via the secondsPassed variable. Finally, we will configure our root to call the timeAddition() method every second and the stopGame() function after 60 seconds. The after() method of our storage is used for this.

Function to make required calculations and destroy widgets

def stopGame():
    global writeAble
    writeAble = False

    # Calculating the amount of words
    amountWords = len(nameLabelLeft.cget('text').split(' '))

    # Destroy all unwanted widgets.
    secondsLeft.destroy()
    currentAlphabetLabel.destroy()
    nameLabelRight.destroy()
    nameLabelLeft.destroy()

    global labelOfResult
    labelOfResult = Label(storage, text=f'Words per Minute (WPM): {amountWords}', fg='black')
    labelOfResult.place(relx=0.5, rely=0.4, anchor=CENTER)
    # Display a button to restartGame the game
    global showcaseResults
    showcaseResults = Button(storage, text=f'Retry', command=restartGame)
    showcaseResults.place(relx=0.5, rely=0.6, anchor=CENTER)

Explanation:
In the beginning, we used the amountWords that will keep the track of the number of words that were typed. To do this, we just take the text from the left label, separate it by blank spaces, and then count the number of items in the list that results. This is done using the len() function in Python. The labels from the test are then destroyed using their destroy method. The test result is then displayed on a label, and a button to restart the test is placed beneath the labelOfResult variable.

Function to restart the Typing Speed Tester

def restartGame():
    # Destry result widgets
    labelOfResult.destroy()
    showcaseResults.destroy()
    # re-setup writing labels.
    handlingLabels()

Explanation:
In this section of code of How to Test Typing Speed using Python?, we have to simply destroy all the different widgets that are available on the screen, once the typing is done and results are displayed by the GUI. So, basically after the typing, the result widget (showcaseResults) and the label of result (labelOfResult) are displayed and we simply have to destroy it.

In order to do so, we have used the destroy() function of the Tkinter. Now that all our old widgets are destroyed, we will have to display all the widgets that should be there whenever a user starts a GUI again. This is handled by our handlingLabels() function. This is the same function that comes into action when a new Typing Speed Tester GUI is opened.

Handling the time widget

def timeAddition():
    # Add a second to the counter.

    global secondsPassed
    secondsPassed += 1
    secondsLeft.configure(text=f'{secondsPassed} Seconds')

    # call this function again after one second if the time is not over.
    if writeAble:
        storage.after(1000, timeAddition)

Explanation:
This function is one of the most important block of code in this whole project of How to Test Typing Speed using Python. This function does the work of handling the time. As one of our project’s features is to showcase a one-minute timer thus we defined this function.

It simply adds 1 second to the previous second and as a result updates the time label. The secondsLeft variable will be updated by this function. If the test is still running, it will simply add one to secondsPassed, set the label’s text appropriately, and then call itself once again a second later.

Handling all the key presses by the user

def handlekeyPress(event=None):
    try:
        if event.char.lower() == nameLabelRight.cget('text')[0].lower():
            # Deleting one from the right side.
            nameLabelRight.configure(text=nameLabelRight.cget('text')[1:])
            # Deleting one from the right side.
            nameLabelLeft.configure(text=nameLabelLeft.cget('text') + event.char.lower())
            #set the next Letter Lavbel
            currentAlphabetLabel.configure(text=nameLabelRight.cget('text')[0])
    except tkinter.TclError:
        pass

Explanation:
The handlekeyPress function, which processes key presses, is the test’s main structural component. Any key that is pressed by the user is handled by this function. As a result, it will always get an event object that contains information about the keys that were pushed.

In order to make it appear as though the user is typing, we first determine whether the character of the event matches the next letter that must be pushed. If this evaluates to True, we delete the letter from the right side and put the same letter on the left label. The label for the current letter was also set to display the appropriate one. This function also plays the role of handling the conflict between the letter that needs to be pressed by the user and the letter which actually needs to be pressed as shown in the line.

To start the test

handlingLabels()
storage.mainloop()

Explanation:
This mainloop is the function of the Tkinter library. It will initialize the main loop of the Tkinter window. Above that, we have called our main function handlingLabels() which basically holds the overall logic of the code of How to Test Typing Speed using Python?

Output:

Image output to Test Typing Speed using Python:

Output 1 to Test Typing Speed using Python
A grey-colored letter at the bottom that needs to be typed
Output 2 to Test Typing Speed using Python
Green-colored letters that were already typed

Video output to Test Typing Speed using Python:

Complete Code to Test Typing Speed using Python

from tkinter import *
import ctypes
import random
import tkinter

ctypes.windll.shcore.SetProcessDpiAwareness(1)

# Setup
storage = Tk()
storage.title('CopyAssignment - Typing Speed Test')

storage.geometry('1400x700')

storage.option_add("*Label.Font", "consolas 30")
storage.option_add("*Button.Font", "consolas 30")

def handlingLabels():
    # Text List
    random_selection = [
        'A random statement can inspire authors and help them start writing. It challenges the author to use their imagination because the sentences subject is utterly ambiguous. The random sentence may be creatively used in a variety of ways by writers. The statement is most frequently used to start a tale. Another choice is to include it into the narrative. The issue of using it to conclude a tale is far more challenging. In all of these scenarios, the writer is compelled to use their imagination because they have no idea what words will come out of the tool.',
        'Python Code aims to teach beginning and intermediate programmers Python through tutorials, recipes, articles, and problem-solving techniques while also disseminating information globally. Everyone in the globe will be able to learn how to code for free thanks to Python Code. Python is a general-purpose, high-level, interpreted programming language. Code readability is prioritised in its design philosophy, which makes heavy use of indentation. Python uses garbage collection and has dynamic typing. It supports a variety of programming paradigms, including procedural, object-oriented, and functional programming as well as structured programming (especially this). Due to its extensive standard library, it is frequently referred to as a "batteries included" language.',
        'We begin with the imports as usual. We must import tkinter since we utilise it to create the user interface. In order to subsequently modify the typefaces on our components, we additionally import the font module from tkinter. The partial function is obtained from functools and is a brilliant function that accepts another function as a first argument, along with certain args and kwargs, and returns a reference to this function with those arguments. When we wish to add one of our functions to a command argument of a button or key binding, this is extremely helpful.',
        'A computer programmer is a person who writes computer programmes, frequently for bigger pieces of software. They are also known as software developers, software engineers, programmers, or coders. A programmer is a person who uses a particular programming language to construct or write computer software or applications. The majority of programmers have substantial computer and coding expertise across a wide range of platforms and programming languages, including SQL, Perl, XML, PHP, HTML, C, C++, and Java. The terms "programmer" and "software engineer" may be used to describe the same position at various businesses because there is no industry-wide vocabulary standard. Usually, a "programmer" or "software developer" will concentrate on translating a precise specification into computer code.'
    ]
    # Chosing one of the texts randomly with the choice function
    text = random.choice(random_selection).lower()

    splitPoint = 0

    global nameLabelLeft
    nameLabelLeft = Label(storage, text=text[0:splitPoint], fg='green')
    nameLabelLeft.place(relx=0.5, rely=0.5, anchor=E)

    global nameLabelRight
    nameLabelRight = Label(storage, text=text[splitPoint:])
    nameLabelRight.place(relx=0.5, rely=0.5, anchor=W)

    global currentAlphabetLabel
    currentAlphabetLabel = Label(storage, text=text[splitPoint], fg='grey')
    currentAlphabetLabel.place(relx=0.5, rely=0.6, anchor=N)

    global secondsLeft
    headingLabel = Label(storage, text=f'CopyAssignment - Typing Speed Test', fg='blue')
    headingLabel.place(relx=0.5, rely=0.2, anchor=S)
    secondsLeft = Label(storage, text=f'0 Seconds', fg='red')
    secondsLeft.place(relx=0.5, rely=0.4, anchor=S)

    global writeAble
    writeAble = True
    storage.bind('<Key>', handlekeyPress)

    global secondsPassed
    secondsPassed = 0

    storage.after(60000, stopGame)
    storage.after(1000, timeAddition)


def stopGame():
    global writeAble
    writeAble = False

    # Calculating the amount of words
    amountWords = len(nameLabelLeft.cget('text').split(' '))

    secondsLeft.destroy()
    currentAlphabetLabel.destroy()
    nameLabelRight.destroy()
    nameLabelLeft.destroy()

    global labelOfResult
    labelOfResult = Label(storage, text=f'Words per Minute (WPM): {amountWords}', fg='black')
    labelOfResult.place(relx=0.5, rely=0.4, anchor=CENTER)

    # Display a button to restartGame the game
    global showcaseResults
    showcaseResults = Button(storage, text=f'Retry', command=restartGame)
    showcaseResults.place(relx=0.5, rely=0.6, anchor=CENTER)

def restartGame():
    # Destry result widgets
    labelOfResult.destroy()
    showcaseResults.destroy()
    handlingLabels()


    

def timeAddition():
    global secondsPassed
    secondsPassed += 1
    secondsLeft.configure(text=f'{secondsPassed} Seconds')

    if writeAble:
        storage.after(1000, timeAddition)

def handlekeyPress(event=None):
    try:
        if event.char.lower() == nameLabelRight.cget('text')[0].lower():
            nameLabelRight.configure(text=nameLabelRight.cget('text')[1:])
            nameLabelLeft.configure(text=nameLabelLeft.cget('text') + event.char.lower())
            currentAlphabetLabel.configure(text=nameLabelRight.cget('text')[0])
    except tkinter.TclError:
        pass

handlingLabels()

storage.mainloop()

Reference Links and Materials

Conclusion

Here’s the end of our tutorial. The article How to Test Typing Speed Using Python? is now finished. We did our best to thoroughly explain every idea in this lesson. We really hope that you find this article to be a helpful resource for you.

At CopyAssignments, we strongly believe that creating projects is the only way to lead the way in Python. It is now up to you to add more complex functions and take this project, How to Test Typing Speed using Python? to the next level. We have already implemented several basic to intermediate-level functions and used a variety of libraries. We’ll be back with another lesson soon; in the meanwhile, keep learning, doing, and building. Thank you for visiting our website.

Share:
Avatar of Dhvanil V

Author: Dhvanil V