Typing is a part of our modern routine, therefore, learning how to type optimally can have a huge benefit for people that, like me, work mostly on their computers.
In this post I will share my daily typing practice routine with the scripts and packages I use to log and visualize my performance.

Why typing?
I am a machine learning engineer, which means that I spend most of my time on my computer building models and writing code. 3 years ago, when I was doing my masters on an application of Generative Adversarial Networks, I started to notice that I could be more productive if I started to work a bit on my typing skills.
So, I learned how to touch type and, fast forward 3 months, I went from 60 wpm to 95 wpm (today I am at about 105 wpm average) on my standard typing performance and from 35 wpm to between 55 and 60 wpm on my coding speed.
This improvement helped me a lot across all of my work and hobby activities (like writing for example…) and I feel like everyone could benefit from a little bit of typing practice.
Streamlining your typing practice
Let’s get to the code! My basic routine for typing is super simple and lasts about 5–10 minutes a day.
I use mltype, which is an amazing cli tool to practice typing on your terminal. It is really flexible, open source and quite neat! Now, let’s get to the script to automate your typing practice.
1. Import dependencies
import os
import pathlib
import random
import pandas as pd
from datetime import datetime
import sys
import plotly.express as px
import plotly.graph_objs as go
2. Run typing practice with mltype
def typePractice(typingDataset):
files = list(typingDataset.iterdir())
file = random.choice(files)
with open(file, "r") as f:
numberOfLines = len(f.readlines()) - 1
if numberOfLines<=1:
numberOfLines=2
elif numberOfLines>10:
numberOfLines=10
os.system(f"mlt file --n-lines {numberOfLines} {file}")
typingDatasetFolder = "path/to/your/typingDataset"
typingDataset = pathlib.Path(typingDatasetFolder)
typingPerformance = "path/to/your/typingPerformance.csv"
df = pd.read_csv(typingPerformance)
typePractice(typingDataset)
Here, I am getting all of the Python files in a folder called: typingDataset
from which I select a random file that I feed into a call to the mltype cli tool. I give the number of lines I want from the file with the --n-lines
option and then I am good to go. The typing interface looks like this:

It is quite minimalistic and it works great.
3. Log performance and update the csv file with my typing performance
def updateTypingPerformance(df,datedPerformance, typingDfPath="path/to/typingPerformance.csv"):
df.loc[len(df)] = datedPerformance
df.to_csv(typingDfPath, index=False)
return df
cont = "y"
while cont=="y":
performance = []
typePractice(typingDataset)
date = str(datetime.now())
wpm = input("What was the wpm?")
acc = input("Waht was the accuracy?")
performance.append(date)
performance.append(wpm)
performance.append(acc)
updateTypingPerformance(df,performance)
cont = input("Continue typing?")
Here, I get the current time and log my performance with python’s builtin input()
method (I want to automate this part but could not find a simple way to do it directly from the mltype session).
I give an option to continue forever with a while loop, updating the csv file containing my performance each time.
4. Plotting option
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
from matplotlib import dates as mdates
from matplotlib import ticker
def plotTyping(typingDf):
typingDf["wpm"] = pd.to_numeric(typingDf["wpm"])
typingDf["accuracy"] = pd.to_numeric(typingDf["accuracy"])
typingDf["date"] = pd.to_datetime(typingDf["date"])
wpmAcc = typingDf.groupby("date")["wpm", "accuracy"].mean()
wpm = wpmAcc["wpm"]
acc = wpmAcc["accuracy"]
fig, ax = plt.subplots(figsize=(15,7))
ax.plot(wpm,label="wpm trend",color="red")
ax.plot(acc, label="accuracy", color="green")
# wpmAcc["wpm"].plot(label="wpm trend",color="red")
# wpmAcc["accuracy"].plot(label="accuracy",color="green")
ax.set_xticks(df["date"])
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
ax.xaxis.set_minor_formatter(mdates.DateFormatter("%Y-%m-%d"))
plt.gcf().autofmt_xdate()
ax.xaxis.set_major_locator(ticker.MultipleLocator(5))
plt.xticks(rotation=45)
plt.legend()
plt.show()
if len(sys.argv)>1:
if sys.argv[1]=="plot":
plotTyping(df)

Here, I wrote a simple plot option for my current typing performance showing words per minute in green and accuracy percentage in red. As we can see I kept my accuracy at an average of above 90% and my typing speed for coding at around 50 to 60 words per minute.
Final thoughts on typing
Typing is fun, and writing code to automate the process of practicing it is even more fun. For me, these kinds of simple scripts solutions are always a blast to do and share and I hope you enjoyed reading as much I enjoyed writing!
If you want to know more about touch typing and how to improve you can check out my post on the topic here:
If you liked this post connect with me on Twitter , LinkedIn and follow me on Medium. Thanks and see you next time! 🙂