Friday Fun: Speed Reading With Python

How fast can you read?

For some Friday Fun this week we shall create a Python application that will help us to read MUCH more quickly.

Reading generally involves our eyes scanning a page of text looking for the next word in the sequence. But we can improve our speed using a little logic and a some Python code. If the words are printed in one location we can increase the speed at which we can read, in fact we can increase the speed quite dramatically.

The code to accomplish this project uses the PyGame library a library of code that enables users to create games and multimedia content using Python. This powerful library comes pre-loaded with Raspbian for your Raspberry Pi so there is no installation necessary. But it can be easily installed using pip3.

pip3 install Pygame  

So lets assume that we are using a Raspberry Pi. Go the Programming menu and select Python3

alt

Now when the editor opens, we will see a Python Shell, in here we can issue quick commands to Python, and get instant responses. Handy for testing logic, but not useful for writing a large amount of code. So click on File >> New to open a new blank window. In the new window click on File >> Save and name your file speed-reader.py
alt

Importing Libraries

We start our code by importing two libraries of pre-written code. The first is Pygame, which we shall later use to create a custom window to contain our text. The second library is time and it is used to control the speed of text to our window.

import pygame  
import time  

Initialising Pygame

To use Pygame we need to initialise it, in particular we will be using the font class.

pygame.font.init()  

Setting up the window

Our text will be contained inside a window, which we shall call screen so lets set our window to 800 by 600 pixels

screen = pygame.display.set_mode((800,600))  

Now lets create a background colour, in this case 0,0,0 (R,G,B) which is Black. Then we shall fill our window with a black background.

background = (0, 0, 0)  
screen.fill((background))  

Font Setup

Now lets create an object that will store the setup of our font. In this case it will be 90 pixels tall.

myfont = pygame.font.Font(None, 90)  

Opening an external file

Now we come to opening an external file that contains the text that we wish to speed read. We create an object called f (short for file) and in there we store the output of opening a file and reading its contents. The file name is the full path to find the file, in this case I used /home/les/text.txt and use "r" to open in read only mode.

f = open("/home/les/text.txt","r")  

Remember to change the filename to something that you want to read! And for best results use a plain text file, not a Office or other filetype.

Reading line by line

We use a for loop to read the text from our file, line by line.

for line in f:  

Reading word by word

Now from each line we want to read word by word, so another for loop, nested inside the previous, is used to split the line into a series of words, exactly how a sentence is constructed. The Python editor will automatically indent our code, but remember that it is either four spaces, or one tab key press.

    for word in line.split():

Rendering the text to the screen.

Inside of the for loop we now create an object called text and this is used to render each word that we have split. It will render the text green (0,255,0 is R,G,B) as we set Green to 255, the maximum value possible. We then use the blitter to load the text into memory and place it in a certain position on the screen. In this case we set it to 300 pixels (x axis) and 300 pixels (y axis). Lastly we update the display to show the text in the window.

        text = myfont.render(word,1,(0,255,0))
        screen.blit(text, (300,300))
        pygame.display.update()

Clearing the screen

After each word is rendered to the screen, we need to clear the display otherwise we get word soup...words rendered on top of words that become unreadable. So after rendering the word we need to give the reader time to read it, so 1/5 of a second 0.2 seconds is plenty of time. Then we fill the window with our background black colour. Then we update the display to ensure that the changes are are rendered correctly.

        time.sleep(0.2)
        screen.fill((background))
        pygame.display.update()

You just don't know when to quit!

We now come out of the two for loops and our last line of code is used to close the Pygame window once all of the text has been read.

pygame.display.quit()  

Complete code listing

import pygame  
import time

pygame.font.init()  
screen = pygame.display.set_mode((800,600))  
background = (0, 0, 0)  
screen.fill((background))  
myfont = pygame.font.Font(None, 90)  
f = open("/home/les/text.txt","r")  
for line in f:  
    for word in line.split():
        text = myfont.render(word,1,(0,255,0))
        screen.blit(text, (300,300))
        pygame.display.update()
        time.sleep(0.2)
        screen.fill((background))
        pygame.display.update()
pygame.display.quit()  

Run the code

In the Python 3 editor, click on Run >> Run Module to start the code...now brace yourself for some super sonic speed reading!

Taking it further

How can we improve this project?

  • Perhaps a slider to control the speed of the text?
  • A GUI to load the file that we wish to read?
  • Change the size and colour of the window?

Download

All of the code and the video to illustrate how this works can be downloaded from Github If you would like to use it / remix it...GO FOR IT!
If you would like to fork the code, then please do so.