Giter VIP home page Giter VIP logo

wpm's Introduction

wpm — measure and improve your typing speed

Supported Python versions Project License pypi

wpm is a curses-based UNIX terminal program for measuring and improving your typing speed (measured in words per minute, or WPM).

It depends only on standard Python libraries and therefore works with Python 2, 3 and PyPy.

Features

  • Over 4900 quotes in the database, shamelessly stolen from typeracerdata.com
  • Extremely low typing latency!
  • Timer starts when you strike the first key
  • Completed text is darkened, helping you to focus ahead
  • Keep separate scores for, e.g. type of keyboard, layout etc.
  • Saves race scores in a CSV file that is a superset of TypeRacer's export format. Loads fine in Excel as well.
  • Launches quickly in your terminal window for "in-between moments"

How to install

The recommended way is to install via PyPi

$ pip install wpm

The above usually requires sudo. If you don't want to install it system-wide, you can use pip install wpm --user.

Remember to check for upgrades with pip install --upgrade wpm. You can also install it from the source repository with

$ pip install . [--user]

To just test the app without installing, type make run.

How to run

Just type wpm to start the program. The timer will start when you press the first key. At any time, you can hit ESCAPE to quit.

You can backspace for the current word you're editing, if you make a mistake. Mistakes will lower the accuracy score.

If you have problems finding the wpm file, you can also start it by typing python -m wpm. You can also see options with python -m wpm --help.

Calculating WPM

The WPM is calculated by dividing characters per second by five and then multiplying that with 60. This is a well-known formula, but gives slightly higher scores than on sites like typeracer.com. It is, however, good enough to gauge your typing speed. And it works offline, and with your own texts.

Regarding TypeRacer, I really suggest everyone check it out. I use this program merely to warm up before heading over to typeracer.com, where you can race against others.

How to get the lowest typing latency

Run outside of tmux, and use a really speedy terminal window. On my macOS system, I found the best latency using the built-in Terminal.app, which easily beats iTerm. I also found the Kitty terminal to provide very low latency.

On Linux, the ultimate typing latency is achieved if you open up one of the virtual consoles. For example, hit CTRL+ALT+F2 and log in, set your TERM=xterm-color and run wpm. Many terms also have quite a high latency. Try using uxterm if you need to run it inside X.

How to improve your typing speed

I believe that everyone can type at 100 WPM with enough practice. If you are currently typing slower than that, my suggestions are:

  • Learn to type without looking at the keyboard
  • Learn to use all your fingers
  • Sit up straight and type in a comfortable situation

If you are consistently above 100 WPM:

  • Focus on the next word
  • Type words instead of characters
  • Train muscle memory
  • Type hard parts slower
  • Raise your wrists

Practice a little bit every few days, but don't overdo it. Stop when you're tired or feeling unmotivated.

Loading custom texts

If you want to type a custom text, run

$ wpm --load yourfile.txt

If you use --load, the author will currently be empty, the title will be the basename of the file. The text ID will be its inode, just to make them somewhat unique, so your stats will work.

You can also bundle up several texts into a single JSON file, using wpm --load-json yourfile.json. It must have the following format:

[
  {
    "author": "Author Name",
    "title": "Title of Work",
    "text": "The text to type here ..."
    "id": 123,
  },
  ...
]

The id is an optional integer. If you leave it out, an increasing, zero-based integer will be used.

Format of race history

wpm will save scores in a CSV file in ~/.wpm.csv. This file can be loaded directly into Excel. It uses the same format as TypeRacer, with the addition of a few extra columns at the end. That means is should be possible to use existing TypeRacer score history tools with this file with minor modifications.

The column order is:

Column Datatype Explanation
race int Race number, always increasing and tied to timestamp
wpm float The average WPM for that quote that single time
accuracy float From 0 to 1, where 1 means no mistakes
rank int Always 1
racers int Always 1
text_id int Item number of text in given database
timestamp str UTC timestamp in strptime format %Y-%m-%d %H:%M:%S.%f
database str Either "default" or the basename of the file used
tag str A user supplied tag for that score (e.g., keyboard)

Should there be any problem saving or loading the score history, it will copy the existing file into ~/.wpm.csv.backup and create a new one.

Tagging races

If you use --tag=... to tag your scores, this will be used until you change it. It is just a free text field that is saved along with each race result. It is useful to compare how well you are typing in various situations.

For example, perhaps you want to check if you are typing faster (but perhaps less accurate?) on different keyboards, or you are learning a new keyboard layout like Dvorak or Colemak and then use the tags --tag=qwerty and --tag=dvorak. If you are learning to touch type, or type with more fingers, you often start out slower than your normal speed. Tagging is a great way to keep track of your progress.

By running wpm --stats (or just -s), you will see a table of statistics, grouped by each tag. It shows things like the average over time, along with confidence and prediction intervals. An item like n-10 means "the last 10 games".

The ~/.wpmrc file

The first time you start wpm, it writes a .wpmrc file to your home directory. It contains user settings that you can change. They are given in the table below.

Section Name Default Description
curses escdelay 15 Time in ms to wait for follow-up key after ESC
curses window_timeout 20 Time in ms until giving up waiting for a keypress. If negative, wait forever.
wpm confidence_level 0.95 The confidence level for WPM statistics
wpm cpm 0 If positive, report CPM in stats instead of WPM
wpm tab_spaces 1 Number of spaces to expand tabs to
wpm wrap_width -1 If positive, wrap text at this width
xterm256colors     Color codes for 256-color terminals (foreground, background)
xtermcolors     Color codes for ordinary terminals (foreground, background)

Development features

You can enable certain unofficial features by seting the environment variable WPM_DEVFEATURES=feature1:feature2:etc..

Look in the file wpm/devfeatures.py for a list.

License

Copyright 2017, 2018 Christian Stigen Larsen

Distributed under the GNU Affero General Public License (AGPL) v3 or later. See the file LICENSE.txt for the full license text. This software makes use of open source software.

The quotes database is not covered by the AGPL!

wpm's People

Contributors

bartenbach avatar cslarsen avatar mandyedi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wpm's Issues

Change up the mode before typing

Hitting a key should immediately start typing, always.
Hitting space should give a new text. This is equivalent to arrow-right. Arrow-left goes to the previous one.
There shouldn't be different modes in this view, only one mode.

Allow for highlighted non-256 colors

For non-256 color terminals, we don't currently use highlighting to increase the available range of colors. This makes it look really bad on those terminals.

Could not use line-break in loaded text

I would like to use song lyrics as a text. These are formatted verse per-line and an extra line-break between the parts.

When I load the lyrics, when I get to the new-line character, and I input it the program does not moves to the next line, as would be expected.

This might be connected to #37

not working on windows wint mingw64 console

Trerminal windows 10 > MINGW64
$ python --version
Python 3.6.5

$ python -m wpm
Traceback (most recent call last):
File "C:\Python36\lib\runpy.py", line 193, in run_module_as_main
"main", mod_spec)
File "C:\Python36\lib\runpy.py", line 85, in run_code
exec(code, run_globals)
File "C:\temp\wpm\wpm_main
.py", line 14, in
import wpm.commandline
File "C:\temp\wpm\wpm\commandline.py", line 22, in
import wpm.config
File "C:\temp\wpm\wpm\config.py", line 14, in
import curses
File "C:\Python36\lib\curses_init
.py", line 13, in
from _curses import *
ModuleNotFoundError: No module named '_curses'

Quote browsing

Use random.shuffle on the quotes, then move through that list. That way, you won't get the same quote twice in a row. Also, you could use the arrow keys to move between them, in case you accidentally moved on to the next.

CSV doesn't scale

The code doesn't scale when the CSV file gets big. Can fix that later. But in short: Saving to it would probably best be done by just appending a pure text line to that file, which is fast. Loading it is another matter. For normal startups, we're only interested in the average WPM and the last keyboard used. Those could be stored in a separate file, with the potential of getting out of sync. Just want to flag it as an issue.

Request for the use of Ctrl key

I would like to request a feature, if its possible to add the use of ctrl key. like when I'm correcting a typo, I prefer doing it using ctrl + backspace instead of backspace along all the way to the wrong character. is it possible or is it gonna conflict with the terminal keybindings?

wpm --load source code

I just installed wpm, It works totally fine. I wanted to do typing practice on source code, the source code was opening fine and I was able to type. But I am facing one issue, the application is not registering a new line '\n'.

gif

Crash

Hi, and thanks for this nice tool.
When typing, I crashed the program while clicking on space or alt:

Traceback (most recent call last):
  File "/usr/local/bin/wpm", line 13, in <module>
    main()
  File "/usr/local/lib/python3.6/site-packages/wpm/commandline.py", line 239, in main
    gm.run(to_front=text_ids)
  File "/usr/local/lib/python3.6/site-packages/wpm/game.py", line 111, in run
    key)
  File "/usr/local/lib/python3.6/site-packages/wpm/screen.py", line 485, in show_keystroke
    self.update_prompt("> " + typed)
  File "/usr/local/lib/python3.6/site-packages/wpm/screen.py", line 354, in update_prompt
    Screen.COLOR_PROMPT)
  File "/usr/local/lib/python3.6/site-packages/wpm/screen.py", line 270, in addstr
    self.window.addstr(y_pos, x_pos, text, color)
ValueError: embedded null byte

I am not able to reproduce it.

UTF-8 input problems

In general, UTF-8 characters not only do not work properly, hitting one involuntarily will give a warning, obscuring the text. Need to fix that across python 2 and 3.

Restructure the game code

It's very nasty right now. In particular, should look into how to reduce typing latency as much as possible. Right now the entire line is redrawn for every keystroke!

Rewrite entire quote database from scratch

I would like to go back to the original sources and write down every single quote again, from scratch.

As it is now, nearly every quote contains some kind of error/rewording/canary. Also, some of the sources could be more explicit. For example, for very old texts, it would be very nice to note which translation has been used.

To do this, I will need help. Please put it in a JSON format, but add additional information in new tags that are not recognized by WPM (they should all be optional, making WPM ignore them).

So you have

{
 "author": "...",
 "title": "...", # only canonical title here, short and nothing else
 "text": "...",
 "translation": "translation info",
 "copyright": "if applicable",
 "edition": "...",
 "url": "if applicable",
}

If you don't have anything to put into the optional fields, then leave them out. It would be very good with a URL to e.g. google books (see below) so things can be double-checked.

The required fields are author, title and text.

How to actually find the quotes?

  • Go to Google Books: https://books.google.com
  • Find a quote you want to transcribe and search for it
  • Try to find the correct one; sometimes you get several hits, choose the most canonical of them.
  • Write up the above JSON. Double check that you got everything correct.

Details on submitting new quotes

  • Gunzip the existing quotes at wpm/wpm/data/examples.json.gz to find the quotes and their text IDs.
  • Add new quotes with the same text id and the URL you found it at in wpm/wpm/data/rewritten.json (note: no gzip), on a new branch rewritten-quotes
  • I will make tools available for comparing the two JSON files when needed.
  • Remember that it's not enough to just transcribe the quotes as-is. They contain many errors, and should be exactly the same as the source. The best is to double-check with physical books if you have them. If so, please add which edition (and translation etc.) you are using. If you're using the web, add the URL as stated above.

Build a quote database for beginners

Would it be useful to have a quotes database with things for those starting out touch typing. For example "j j j k k k", and "jjj kkk jjj kkk jkjk jkjk" and so on?

Append to .wpm.csv instead of overwriting

If you open two wpm sessions, the last one will overwrite the entire file, discarding results from the first session. A way to fix this is to read the last row and continue race numbers from there by appending to the file instead of overwriting the entire thing. It's also much faster, just keep track of which results are new to the set.

Non-apostrophe character found in database

Not sure if this belongs here or against typeracer's data, but I found an apostrophe lookalike in the database in the quote below. In particular, the second to last "don't" would not let me continue typing with a regular apostrophe.

"Bright Eyes",
"First Day of My Life",
"This is the first day of my life. I swear I was born right in the doorway. I went out in the rain, suddenly everything changed; they're spreading blankets on the beach. Yours is the first face that I saw. I think I was blind before I met you. Now I don’t know where I am, I don’t know where I’ve been, but I know where I want to go.",
3550849

Option to launch monochrome

I would love the option to launch wpm in "monochrome" with just the foreground and background colors so it blends in better with my other terminal windows.

Go directly to given text

A key and command line option to go to a specific text it. Must then show the text when typing (or after). Textids should persist across updates of quotes database.

See typing and corpus on same line

Would love to make a version that shows what you're typing on top of what needs to be typed. For me it reflects text area writing where you see your inputs live. maybe it just looks like you overwriting in red when youve mad a mistake

I'd actually love to try my hand at this if you could point me in the right direction.

loading text file or json not working

loading text file or json as suggested in readme is giving following output.

Traceback (most recent call last):
File "/home/murali/.pyenv/versions/2.7.10/bin/wpm", line 11, in
wpm.commandline.main()
File "/home/murali/.pyenv/versions/2.7.10/lib/python2.7/site-packages/wpm/commandline.py", line 130, in main
with wpm.game.Game(quotes, stats) as game:
File "/home/murali/.pyenv/versions/2.7.10/lib/python2.7/site-packages/wpm/game.py", line 246, in init
self.quotes = quotes.random_iterator()
AttributeError: 'list' object has no attribute 'random_iterator'

Bug when downsizing window

For some quotes, when you keep downsizing, it will throw an error. Better to just print INSIDE THE DISPLAY that "sorry, the window is too small!"

Errors loading custom text

While loading a custom txt file, but formatted in C programming language, spaces like 'new line' and 'tabs' are not calculated properly and will not work normally.

Disable randomisation of quotes

Hey, I'd like to disable randomisation of quotes while using my custom json input file. I'm not really into python and I don't know where to find the part I want to change. Could you please help?

Please put the cpm as a statistic.

Hi,

Amazing job!, I use this, it´s a really useful piece of software.

Only one thing, at least for the people in Spain, the wpm don´t say any (but it´s useful) normally you check your speed based on the CPM, so each time I need to multiply the CPS * 60 seconds.

If you can add this to the statistic will be really appreciated�.

Thanks again for this software.

support "delete a word"

I have a habit of hitting ctrl+w to delete a word on the command line and in my text editor. I believe browsers honor ctrl+backspace to delete a word. I am not sure what the standard chord for this is but I would love to provide a bind for this in .wpmrc.

ImportError: No module named pkg_resources

When I type wpm or python -m wpm I get this error:

Traceback (most recent call last): File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main "__main__", fname, loader, pkg_name) File "/usr/lib/python2.7/runpy.py", line 72, in _run_code exec code in run_globals File "/usr/local/lib/python2.7/dist-packages/wpm/__main__.py", line 14, in <module> import wpm.commandline File "/usr/local/lib/python2.7/dist-packages/wpm/commandline.py", line 27, in <module> import wpm.quotes File "/usr/local/lib/python2.7/dist-packages/wpm/quotes.py", line 23, in <module> import pkg_resources ImportError: No module named pkg_resources

Jump to line

Hello author of this awesome plugin. I am using wpm to load my thesis and proofread it. It works great for that and it has helped me so much spot typos I would have otherwise missed. There is only one feature that I am missing. When I load a text would it be possible to jump to a line when I want to avoid a certain paragraph. This helps on repeatedly running the file when I want to jump to the second or third sentence. Thank you!

Custom text in JSON file

I tried out your project, @cslarsen , and it worked very well.
You have made a very good wpm measurement terminal app.
One thing that didn't work for me is that when i try to make a custom text in a JSON file
and load it with wpm --load-json texts.json, it gives me this error:

Traceback (most recent call last):
File "/usr/local/bin/wpm", line 4, in
import('pkg_resources').run_script('wpm==1.50.4', 'wpm')
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources/init.py", line 742, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources/init.py", line 1674, in run_script
exec(script_code, namespace, namespace)
File "/Library/Python/2.7/site-packages/wpm-1.50.4-py2.7.egg/EGG-INFO/scripts/wpm", line 11, in

File "build/bdist.macosx-10.13-intel/egg/wpm/commandline.py", line 183, in main
File "build/bdist.macosx-10.13-intel/egg/wpm/commandline.py", line 95, in load_json_quotes
File "build/bdist.macosx-10.13-intel/egg/wpm/quotes.py", line 169, in load_json
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/init.py", line 290, in load
**kw)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/init.py", line 338, in loads
return _default_decoder.decode(s)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 366, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 384, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

Is there something i have done wrong?

Add more statistics to the --stats command

Confidence intervals, clusters and so on. Perhaps a linear regression on the wpm by the length of the text, or for wpm/precision. Or some correlation metric between interesting pairs. It would also be nice to capture in a much smarter way which words are typically hard to type. This depends on the immediately preceding words, so capturing that information would actually help to figure out what words are hard to type given the way the fingers are currently positioned over the keyboard.

Calculate confidence intervals based on race means

First calculate the mean per race, then use that to calculate the confidence interval. I feel it should be more representative of the actual typing performance, because some texts are really short and may have been typed several times.

Should investigate the mathematical theory behind this. I know there is a trick that can be done with variances, but I need to dig into it some more.

--load not working

Launching wpm with --load filename results in UnboundLocalError: local variable 'quotes' referenced before assignment at commandline.py:174. This makes sense because quotes really was not assigned at this point. It also seems like the order of arguments is wrong: load_plain_text_quote takes filename as the second argument while opts.load is provided as the first argument. After fixing this two things there are no more errors, the text still doesn't load properly but I didn't investigate further.
I could probably fix that if the bug gets approved.

Feature Request - Add Custom Examples

While the program allows the user to add custom text-sets using a external JSON-encoded file. This is inconvenient for the following reasons -

  • The creation of a JSON encoded file is time consuming and while the format of the external file has been clearly specified, any error might cause the program to break, which would cause the user to go through the tedious process of creating the file again.

  • A user might not find it convenient to make a new JSON-encoded file to add just one or two custom examples. Moreover the parameter call needs to be written every time to add the sample texts from the user-specified file

  • Another case when the current way hampers the proper use is when the user wishes to maintain a set of sample texts which are updated over time. In this case one might be forced to deal with JSON files every now and then, which is not required.


A solution to this problem (that I have implemented in my fork) can be the inclusion of a script that allows the user to add custom sample texts to the default data file which can then be used anytime and can be updated over time to the liking of the user too.

A simple CLI can be built that saves that works as an interface to format and encode the example text in the format required so that any user, without any JSON knowledge can also add custom-examples to practice on.

Moreover a simple command line flag can be used, so that such custom examples can be added with ease, as and when required.

utf-8 not working on custom json file

Hi, I'm trying to load a json file with my custom quotes, but I get this error
Could not read JSON file: 'utf8' codec can't decode byte 0xe1 in position 59: invalid continuation byte
I've tried different export and encoding options when creating the file, but I can't make it work keeping characters like ñ or Á, etc

Example of my quotes:

[
  {
    "author": "Refraneiro Galego",
    "title": "Refrán",
    "text": "Inda o demo ten cara de coello!",
  },
  {
    "author": "Refraneiro Galego",
    "title": "Refrán",
    "text": "Máis vale pillo que pillado!",
  }
]

Can you help me?

Also, it would be great if people could add quotes collections to this repository and that they could be selected from the app (like 'Movie quotes' or 'Philsophy quotes' or in this case 'Galicians proverbs')

Thanks!

Text not rendering when using characters bigger than one byte.

While loading custom texts, that contains characters from iso-8859-2 text is not rendering. In my case I have 181 columns in my terminal, last one is used for spacing. When my text that is intended to be in one line exceeded 180 bytes, that line of text is not visible.

Move .wpmrc to .config/

It would be nice if this app followed XDG directory standards and put the .wpmrc file in the .config/ directory. This makes the user's home directory less cluttered.

High cpu usage on idle

Usually, wpm uses about 3% of my cpu just sitting in the background doing nothing. This is unfortunate, but perfectly acceptable.

However, this number seems to skyrocket for short texts! If wpm is run with wpm --short, then most of the texts causes it to use around 15%, which is more than I am willing to spend just leaving it in a terminal.

Save .wpm stats as csv

Preferrably, use the same format as typeracer, or one that is compatible. Put each text it in there, but also save which keyboard and quote database was used. Also include more than just the wpm of the text, perhaps the mean and variance (for that particular run) would be good to have.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.