There is a theory from the well-known and, uh, interesting strength trainer Pavel Tstsouline that a very efficient way to get stronger is by a method he calls “greasing the groove”. The idea is that you perform the given exercise for a relatively few number of repetitions (i.e. few enough that each rep is with perfect form) many times throughout the day. In this manner, you get in a large total volume of work over the course of the entire day, where each rep is ingraining perfect form (as opposed to training to failure, or lifting in a concentrated session, where fatigue begins to accumulate).
It is a fun way of training stuff if you have the means and, since I work from home and have a home gym, it seems like something that would be very easy to experiment with. However, I hadn’t been doing this sort of thing regularly, mainly because it was a pain to track (as I just use a paper notebook) and without tracking, it’s difficult to maintain motivation.
Since I’ve mainly been working on big projects for the last few months, this seemed like a good thing to write some little scripts for and get back in the habit of automating stuff. Thus begins my journey!
I’m using the i3 window manager on my current computer, so I thought it would be neat if I could make a widget that would go in my status bar to track my daily extra exercises.
I had to switch to using i3blocks instead of the standard i3bar to add custom blocks, but that was as simple as installing the program & changing a single line in my
Now, it was time to write some code.
I’ve been writing lots of Clojure for the last few years (and I really enjoy it) but this sort of little script is not the domain that Clojure is good in. I’ve also been dabbling with Rust and think it is very cool, but for something that I wanted just whip off quickly I decided to go with my old go-to – Python. I’ve also been reading about Python 3 being great and I don’t think I’ve actually used 3 before (although there aren’t really many substantial differences between 2.7 and 3.5 that I’ve encountered).
Whenever making something, I like to start by just doing the backend database stuff – I am not a frontend kind of person and that’s the part I enjoy the most. I decided just using a sqlite database would be the easiest way to store the data - a CSV or plain-text might be more straightforward, but I thought that firstly, Python has a solid sqlite library, secondly this will save me from having to parse dates and stuff, and thirdly this will enable me to do analytics and stuff in the future.
So, just making a script that can create a database, add a number of reps to an exercise, and see all the exercise for the current day, got me something like this (in a file in my
(Hard-coding database paths, ‘cause it didn’t seem worth the effort to make it configurable at this point)
The next step was to make this display in my status bar.
This was pretty straightforward, thanks to i3blocks’ solid docs.
I just added a block to my
~/.i3blocks like this:
This makes the output of my script show up in my status bar
Note that in the block, I both gave it an interval to refresh on and a signal, so it will run the script to re-update the text in the bar both every sixty seconds and whenever i3blocks receives a signal with value 12 (i.e. SIGUSR2). The docs recommend against this, but I needed to do so in this case: I want it to update on demand, when we add a new exercise, but I also don’t want to see yesterday’s information at the beginning of a day before I’ve tracked anything.
Now, I can use python in a terminal to add a new exercise and then run
$ pkill -SIGUSR2 i3blocks to have the display update.
While I can manually add things in the console, the whole point of this exercise was to make it frictionless, so I wanted something more ergonomic.
Since i3blocks can tell the script when it receives a mouse click (by invoking the script with the environment variable
BLOCK_BUTTON set to a number indicating which button was pressed), I wanted some way to have the script present a GUI to let me quickly type in the exercise and number of reps.
Doing some reading around, it seemed like the easiest way to do this in Python is using
I managed to make a very simple little GUI popup using the tkinter docs.
No buttons, it just adds when you hit return in a text field.
(The beauty of just making tools for yourself is you can make interfaces as crappy as you want as long as they work for you.)
The code looks like this (in
Now this can be run manually; I can type the exercise name & number of reps in, it will be added to the database, and when I run
pkill -SIGUSR2 i3blocks, I’ll see the updated exercise information in the status bar.
However, I wanted to have this run when the bar is clicked.
This is done simply by adding
import grooving_add to
grooving.py and changing the
main block at the bottom to look like this:
The final step I needed was to make the popup window appear as a “floating” window, so it looks like a little popup, instead of a full-pane app.
This is done by adding a line to my
~/.i3/config like this:
for_window [title="Add Dialog"] floating enable.
You can have a look at all the config & code in situ along with a bunch of other stuff in my dotfiles repo