Typing Speed Test Project Using Python














































Typing Speed Test Project Using Python



Typing Speed Test Project Using Python :

Have you ever tested your typing speed ? It is quite interesting to track your typing speed and improve it with regular practice. I hope after this article you will be able to build your own Typing Speed Test Game in Python.
Please Follow these steps given below and try to understand them.
 
About this Project :

In this Python project , our goal is to build a game in which user can check and even improve typing speed. For a graphical user interface, we will be going to use the pygame library in Python which is used for working with graphics. This is an OOPs approach. We will also show the images and text required to be displayed on the screen as per our need.

Prerequisites and Libraries need to be installed :



  • First of all you should have some basic knowledge of Python programming language .
  • You should have to install the PyGame; library using the following command.
          pip install pygame

  • You should have to know the working of random , time and sys package and knowledge of Object-Oriented Programming (OOPs) in Python . 

This project broadly consists of two types of file :

  • essay.txt - A text file consisting a number of sentences in which we will pick one of the sentence randomly and give it to the user as challenge.
  • TypingSpeedTest.py - The main python program file consisting all the codes.
Note that for making our project beautiful we used some image files like 

  • background_image.jpg - This image will be drawn in the background of our game window.

  • Icon.png - This will be our icon for reset button.

  • StartingImage.jpg - This image will be displayed everytime the game starts. 

Note that we can decorate our window as much we can but here we just have to learn its working and basic idea .


Steps to build the project :

1. Import the libraries needed :

As we have discussed earlier, we are using the pygame library in this project. So we need to import the pygame library alongwith python packages like random , sys and time.

2. Create a Test class:

We created a Test class which consists of many methods responsible for starting and reset the game. Also used some of the helper functions to perform calculations required like get_challenge() , results_show() etc.

Now we create the constructor for Test class which automatically define all the variables needed like width, height, start_time etc. The width and height of the window , the variables needed to calculate accuracy and also screen variable is used to display and render the text and images.

3. draw_text() method :

The draw_text() method of Test class is a helper function which draws the text on the screen. The argument it takes is the screen, the message to be drawn, the y coordinate of the screen to position our text, the size of the font and color of the font(rgb). We have drawn everything in the center of the screen. After drawing anything on the screen, pygame requires you to update the screen.

4. get_challenge() method:

As we have stored a collection of sentences in our essay.txt file. The get_challenge() method will open up the file and return a random sentence from the list using random package. We split the whole string according to a newline (\n) character.

5. results_show() method:

The results_show() method is used to calculate the user typing speed. The time starts when the user clicks on the input box and end when the user hits return key Enter then we perform the difference and calculate time elapsed in seconds.

We also want to calculate and display the accuracy. For that just count the correct typed characters by comparing input text with the display text which the user had to type.

The general formula for accuracy is:

((correct characters entered)x100) / (total characters in sentence)

The WPM is the words per minute. A typical word consists of around 5 characters, so we calculate the words per minute by dividing the total number of words with 5 and then the result is again divided that with the total time it took in minutes. Since our total time was in seconds, we had to convert it into minutes by dividing total time with 60. 

At last, we have to draw our reset icon image at the bottom of the screen which will be used as a reset button. When the user clicks it, our game would reset. We will discuss the reset_game() method at last.

6. run() method :

This is the main method of our class that will handle all the events. We call the reset_game() method at the starting of this method which resets all the variables we have used. Next, we run an infinite while loop which will capture all the mouse and keyboard events. Then, we draw the heading(it could be your choice ) and the input box on the screen.

We had to use another loop that will check for the mouse and keyboard events. When the mouse button is pressed, we store the position of the mouse if it is on the input box(which means user is ready to take challenge) then we start the time and set the active to True. If it is on the reset button, then we reset the game.


When the active is True and typing has not ended(which means user still wants to type more characters) then we look for keyboard events. If the user presses any key then we need to update the message(dynamically) on our input box. The enter key will end typing and we will calculate the scores to display it. Another event of a backspace is used to trim the input text by removing the last character(basically substring upto second last character).

7. reset_game() method:

The reset_game() method resets all variables so that user can start testing typing speed again. We also modified a random sentence by calling the get_challenge() method.Finally we created an object and called run() method. 


Implementation :

import sys
import time
import random
import pygame
from pygame.locals import *

class Test:

def __init__(self):
self.color_heading = (255,213,102)
self.color_text = (255,0,0)
self.color_results = (255,70,70)
self.w=750
self.h=500
self.reset=True
self.wpm = 0
self.end = False
self.active = False
self.input_text=''
self.word = ''
self.results = 'Time:0 Accuracy:0 % WPM:0 '
self.start_time = 0
self.overall_time = 0
self.accuracy = '0%'



pygame.init()
self.image_open = pygame.image.load('StartingImage.png')
self.image_open = pygame.transform.scale(self.image_open, (self.w,self.h))


self.bg = pygame.image.load('background_image.jpg')
self.bg = pygame.transform.scale(self.bg, (500,750))

self.screen = pygame.display.set_mode((self.w,self.h))
pygame.display.set_caption('Typing Speed Test')


def draw_text(self, screen, message, y_val ,f_size, color):
font = pygame.font.Font(None, f_size)
text = font.render(message, 1,color)
text_rect = text.get_rect(center=(self.w/2, y_val))
screen.blit(text, text_rect)
pygame.display.update()

def get_challenge(self):
return random.choice(open('essay.txt').read().split('\n'))

def results_show(self, screen):
if(not self.end):
# Calculate time ellapsed
self.overall_time = time.time() - self.start_time
count = 0
for i,c in enumerate(self.word):
try:
if self.input_text[i] == c:
count = count + 1
except:
pass
# count is the number of correct typed characters
# Calculate accuracy using given formula
self.accuracy = (count*100)/len(self.word)

#Calculate Words per Minute
self.wpm = (len(self.input_text)*60)/(5*self.overall_time)
self.end = True
print(self.overall_time)

self.results = 'Time:'+str(round(self.overall_time)) +" secs Accuracy:"+ str(round(self.accuracy)) + "%" + ' WPM: ' + str(round(self.wpm))

# Draw Icon image
self.time_img = pygame.image.load('Icon.png')
self.time_img = pygame.transform.scale(self.time_img, (150,150))
screen.blit(self.time_img, (self.w/2-75,self.h-140))
self.draw_text(screen,"Reset", self.h - 70, 26, (255,0,0))

print(self.results)
pygame.display.update()

def run(self):
# everytime we run it should automatically reset the variables
self.reset_game()

# a variable which shows the state of game whether
# it is running or not
self.running=True

# we will run an infinite loop till the running is True
while(self.running):
clock = pygame.time.Clock()
self.screen.fill((0,0,0), (50,250,650,50))
pygame.draw.rect(self.screen,self.color_heading, (50,250,650,50), 2)
# Update the text of user input dynamically
self.draw_text(self.screen, self.input_text, 274, 26,(250,250,250))
pygame.display.update()
for event in pygame.event.get():
if event.type == QUIT:
self.running = False
sys.exit()
elif event.type == pygame.MOUSEBUTTONUP:
# get the position of mouse pointer x,y
x,y = pygame.mouse.get_pos()

# position of input box
# these x and y values should lie as
# x = [50,650] and y = [250,300] because the timer
# will start when user clicks the input box

if(x>=50 and x<=650 and y>=250 and y<=300):
self.active = True
self.input_text = ''
self.start_time = time.time()

# position of reset box
if(x>=310 and x<=510 and y>=390 and self.end):
self.reset_game()
x,y = pygame.mouse.get_pos()


elif event.type == pygame.KEYDOWN:
if self.active and not self.end:
if event.key == pygame.K_RETURN:
print(self.input_text)
self.results_show(self.screen)
print(self.results)
self.draw_text(self.screen, self.results,350, 28, self.color_results)
self.end = True

# event handler for backspace
# i.e simply take the string upto the second last character
elif event.key == pygame.K_BACKSPACE:
self.input_text = self.input_text[:-1]
else:
try:
self.input_text += event.unicode
except:
pass

pygame.display.update()
# clock timer
clock.tick(60)

def reset_game(self):
self.screen.blit(self.image_open, (0,0))

pygame.display.update()
time.sleep(1)

# reset all the project variables.
self.reset=False
self.end = False

self.input_text=''
self.word = ''
self.start_time = 0
self.overall_time = 0
self.wpm = 0

self.word = self.get_challenge()
if (not self.word): self.reset_game()

self.screen.fill((0,0,0))
self.screen.blit(self.bg,(0,0))
message = "Typing Speed Test"
self.draw_text(self.screen, message,80, 80,self.color_heading)

pygame.draw.rect(self.screen,(255,192,25), (50,250,650,50), 2)

self.draw_text(self.screen, self.word,200, 28,self.color_text)

pygame.display.update()

if __name__=='__main__':
Test().run()


OUTPUT:








In this article, we had learnt to build our own game of typing speed testing with the help of pygame library in Python.

I hope you understood the basic idea of this project and you can now build your own Typing Speed Testing Game.

Thank You ! 



Comments