IPython as a Calculator
I’ve always wanted to use an interactive python instance as a calculator for back-of-the-envelope calculations that are to small or specific to warrant a spreadsheet. Simply typing python
into a terminal didn’t work very well, however:
- The python interactive shell is very rudimentary, offering no syntax highlighting or auto complete. Multi-lkne editing is also a very clunky experience.
- IPhython solves this, but has pretty long startup times.
- Startup times get even worse if your work requires pandas, numpy, matplotlib & friends. Import times cause some friction, as does typing out imports.
- It would be nice to have a repository of utility functions like “plot this 2d function” or “import some of my personal data into a pandas
DataFrame
”.
My solution is to have one IPython instance created at startup inside a tmux session, with a custom init scrip that loads common packages and a custom utils package, taking advantage of the autoreload extension. To stop me from accidentally exiting the session, Ctrl+D is bound to tmux detach inside the session.
This can be very easily achieved with some bash magyxs. The first component is a script that sets up the tmux session:
# create_session.py
tmux new -ds calc ipython -i ~/.bin/scripts/ipython_calc/defaults.py
tmux bind-key -n C-d detach
Passing -d
means that the script won’t try attaching to the tmux session. -s
specifies calc
as the session name, and ipython -i ~/.bin/scripts/ipython_calc/defaults.py
the command that is run inside the session. This starts the ipython interactive shell after running defaults.py
, which sets up imports:
# defaults.py
import importlib
import math
import matplotlib.pyplot as plt
import numpy as np
import os
import pandas as pd
import sys
from IPython.core import getipython
getipython.get_ipython().run_line_magic("reload_ext", "autoreload")
getipython.get_ipython().run_line_magic("autoreload", "2")
# My own module with shorthands. Installed with
# > pip install -e ~/develop/ipython_utils/
import ipython_utils as iu
To open the calculator, I use a script which creates the calculator session if it doesn’t exist already, and attaches to it in a new terminal window:
# show_calc.py
tmux ls | grep calc || ~/.bin/scripts/ipython_calc/create_session.sh
alacritty -e tmux at -t calc
The final ingredient is to bind this script to a keybinding, for which I use i3:
# i3 configuration file
...
mode "launch" {
...
bindsym c exec --no-startup-id "~/.bin/scripts/ipython_calc/show_calc.sh", mode "default"
...
# back to normal: Enter or Escape or $mod+m
bindsym Escape mode "default"
bindsym $mod+m mode "default"
}
...
And that’s it! Pressing Win+m, c
opens up a new alacritty window with IPython. The first time after a reboot will take a moment, consecutive times will be instantaneous. I actually run create_session.sh
on startup to get rid of that first lag too, but that’s a matter of preference.
A side-benefit that I didn’t anticipate is that history is always consistent and preserved, so it’s relatively easy to go back to previous calculations.