Speed Reader

Everyone has wished they could read faster at some point in their life, for example, to get through the required reading for their English class, to cram for an exam, or to simply get through their ever-growing list of novels to read. Since the 1950s, psychologists, linguists, and educators have devoted significant efforts into speed reading techniques that can dramatically increase your reading speed with relatively little loss of comprehension. In this homework, we will prototype one approach to speed reading called Rapid Serial Visual Presentation (RSVP)—recently popularized by Spritz Inc. and apps like Spreed—and run some small user studies to test its effectiveness.


Many modern speed reading techniques are based on the insights of school teacher Evelyn Wood. In the 1950s, Wood observed that, among other things, (1) using your finger or some other pointing device to train your eyes and focus while reading and (2) eliminating subvocalization, internally speaking words while reading them, can dramatically increase your reading speed.

Since then, countless speed reading courses have been developed to help students develop these skills. However, these courses rely on the student's discipline to develop good reading habits, and it is easy for an untrained student to learn "the wrong way" and thus never seen the purported benefits of speed reading. Computer programs in this context can act a tutor or personal support system, ensuring that students practice the right skills even while learning alone.

RSVP, in essence, takes these ideas of pointing-while-reading and removing subvocalization to their limit. With RSVP, a series of objects—here, words—are presented quickly in succession. By design, the reader is only able to focus on a single word at a time. And furthermore, the words appear at such a speed that the reader is unable to subvocalize like normal. Such a presentation style is only really practical with a computer program!

Here are some examples of RSVP:

Spritz 1

Note that while somewhat disorientating at first, the text becomes readable with a little bit of practice, especially once you consciously try to stop yourself from subvocalizing each word. This text is being presented at 250 words per minute. Here are examples of the technique used to read 350 and 500 words per minute, respectively.

Spritz 2

Spritz 3

Note that the average reading speed is approximately 250-300 words per minute for reading adult prose. So with some practice, you can use a speed reader to read at approximately 2x the average reading rate. In contrast the world record for speed reading is a blistering 4251 words per minute!.


In this assignment, you will use the Tkinter library to create a speed reading app that uses RSVP and study its effectiveness. Because you will be working a partner, you will be able to use each other to test the efficacy of this speed reading technology.

Animating Text

At its core, a speed reader app:

  1. Reads in a text file provided by the user.
  2. Breaks the text file into tokens. Recall that a token is a single word separate by whitespace (which includes both spaces and line breaks).
  3. Displays each token in succession with some sort of delay between tokens.

To implement this behavior, we would like you to write a core function

animate_text(root, canvas, filename, width, height, font_size, wpm)

which takes:

  1. The top-level Tk object,
  2. The Canvas object to draw on,
  3. The filename to speed read,
  4. The width of the canvas,
  5. The height of the canvas,
  6. The font_size of the rendered text, and
  7. The wpm, words per minute, that the text should be displayed at.

And renders the text to the canvas at the given rate.

The text should be centered both horizontally and vertically and rendered in the "Courier" (which is a monospace) font. Here are some notes on how you should implement this behavior:

  1. Animation in a computer program is accomplished by repeatedly drawing a scene with some fixed delay between redraws (i.e., in a loop). To achieve this delay, you should use the sleep(s) function of the time module. sleep takes a time in seconds (as a float) and causes the program to wait for that time to elapse before continuing. Note that you must convert the given rate (words per minute) to the amount of seconds you must wait between displaying subsequent words.
  2. You should use the create_text(x, y, text=t, font=f) method of the Canvas class to render the text. Note that text and font are optional, named arguments to the method. The text is centered at the coordinate (x, y). The font is specified a pair of a name of a font and its size, e.g., ("Courier", 16).
  3. Within animate_text, you should further decompose the problem of rendering text in the RSVP style into (at least) two additional helper functions. Recall that your helper functions should accomplish some meaningful work towards solving this problem.

The Overall Speed Reader Program

You should wrap all of this functionality into a complete program (i.e., a main function) that runs without going to the Python REPL. To do this, we will allow the user to specify command-line arguments when they invoke the program. The user needs to specify the filename of the text file to read, the width and height of the panel, the font size, and the speed at which the text should be displayed (in words per minute). For example, here is a valid invocation of the speed reader program (assuming the Python file is speed_reader.py)

python speed_reader.py example.txt 400 200 18 350

That would display the text in example.txt in a 400x200 window with font size 18 at a rate of 350 words per minute.

Recall that the arguments to a program invoked on the command-line can be retrieved using the argv variable of the sys module.

Finally, note that if you try to invoke animate_text after Tkinter.mainloop() you will find that nothing happens. This is because Tkinter.mainloop() fires off its own event loop to handle events, e.g., mouse clicks, on the Tkinter window. To invoke animate_text, you must call the after method of your Tk object and pass in animate_text along with its arguments, e.g.,

root = Tkinter.Tk()
# ...
root.after(3000, animate_text, root, canvas, filename, width, height, font_size, wpm)

The first argument to after gives the delay (in milliseconds) between the invocation of mainloop and animate_text. You can provide a delay of a few seconds so that your speed reader doesn't immediately start displaying words when the program starts.

Finally, to ensure that the Tkinter event loop processes its events, you must call root.update() within the rendering loop of animate_text.

Initial Experiments

Once you implement your prototype, you and your partner should train on using the speed reader. You can gather sample text from a variety of sources, for example, Wikipedia and Project Gutenberg. This training is necessary because as you use the speed reader during the course of experimentation, you will become more proficient in its use which can skew your results. Training up front, for example for a half and hour, mitigates some of this risk.

Once you and your partner are done training, we would like you to use your prototype to answer two questions:

  1. What is the highest rate that you can display text before it becomes effectively unreadable?
  2. What is the effect of display rate versus comprehension of the text?

To answer these questions, you will need to perform experiments and collect data with your speed reader program.

For the first question, you should gather up at least five to ten paragraph-length chunks of text. These can be randomly drawn from a variety of sources or a single, large source. Starting with 350 wpm and increasing by 50 wpm for each trial, test your partner to see if they are able to read a randomly chosen chunk of text at the given rate. To assess if they were able to read the text, you should ask a question about the content of the prose. For example, if the text in question (excerpted from Wikipedia's speed reading article) is:

It was not until the late 1950s that a portable, reliable and convenient device would be developed as a tool for increasing reading speed. Evelyn Wood, a researcher and schoolteacher, was committed to understanding why some people were naturally faster at reading and tried to force herself to read very quickly. In 1958, while brushing off the pages of a book she had thrown down in despair, she discovered that the sweeping motion of her hand across the page caught the attention of her eyes, and helped them move more smoothly across the page. She then used the hand as a pacer. Wood first taught the method at the University of Utah, before launching it to the public as Evelyn Wood's Reading Dynamics in Washington, D.C. in 1959.

You might ask a factual question such as "What two professions did Evelyn Wood do?" or "Where did Wood first teach her speed running method?".

To answer the second question, you should chose two technical text, for example, excerpts from Wikipedia articles. For each text, develop a small quiz of five questions about the prose similar to the examples above. Have your partner read the technical text without a speed reader and rate their reading comprehension with the quiz. Then, have your partner read the technical text with your speed reader set to the maximum rate that you discovered previously, rate their comprehension with the quiz.

You should perform both these experiments twice with each member of your pair functioning as the reader.

In addition to your code, you should provide a write-up of your experimental methodology, results, and your conclusion. In particular, include a plain text file, results.txt that contains:


Next, we would like you to implement a number of extensions to the basic speed reader and then evaluate their effectiveness:

Extension #1 Space Delays

The first extension to the system we would like you to implement and test is space delays. We naturally pause at certain punctuation marks: periods, commas, and semicolons. You may have found it difficult to process many sentences in a rapid fashion without those natural pauses. To fix this, we would like you to do the following

  1. Change your drawing logic so that when a token ends with a period, comma, or semicolon, you wait two times longer than usual before moving onto the next word and
  2. Modify the second experiment outlined above to determine if your modification affects your ability to read text with punctuation.

Extension #2: Noted Quoting

The second extension to the system we would like you implement and test is noted quoting. You may have noticed while speed reading text that it is sometimes difficult to keep track of quoted text (i.e., when a quote begins and ends) because only one word is displayed at a time. To fix this, we would like you to do the following:

  1. Within animate_text, track whether you are currently inside of quotes. To keep things simple, you can assume that you never encounter nested quotes.
  2. When rendering text, if a word is in quotes, devise some way to visually distinguish it from non-quoted text.
  3. Modify the second experiment outlined previously to determine if your modification makes it easier to read quoted text.

Note that this extension (and others) may not have a positive effect on comprehension. That is ok! We design prototypes to be able to quickly and cheaply evaluate new ideas, many of which do not pan out.

Extension #3: Centering

The final extension to the system is the centering of text around word length. You may have noticed that excessively long words can sometimes disrupt your speed reading when they are naively centered on the screen. Spritz and other systems use the following heuristic to align text on the screen:

Choose a focus letter based off the length of the overall word and center the word around the focus letter:
length = 0-1 => first letter
length = 2-5 => second letter
length = 6-9 => third letter
length = 10-13 => fourth letter
length >13 => fifth letter

Also, color the focus letter differently from the other letters.

Implement this rendering behavior and run an experiment to test its effect on text comprehension. To achieve this behavior, take advantage of the fact that the Courier font is monospace (so you can use spaces to "shift" characters into different columns) and smart overlaying of rendered strings to selectively some color characters and not others.

Like with the previous extensions, modify the experiments performed on the base system to assess whether the centering extension helps.

Submitting Your Work

You should submit your completed speed_reader.py program as well as your report.txt file describing the experiments you performed, the data you collected, and the answers to the questions asked in the write-up.