There are many times when a task calls for a simple python script. It is
usually something small that takes some input file as a parameter, does some
processing, and then spits out some results. It might even take an options or
two. It’s tempting to just throw some lines of code into a file and be done with
it. This may work but often just makes things more difficult later.
Consider the following code (let’s creatively call it do_stuff.py)
which simply converts the input to uppercase:
What happens, however, when it grows a little bit and we add a function?
What happens if we want to include that function into another file? Then
importing do_stuff.py will cause the for loop to run. A much better solution is
to do all of the ‘scripty’ stuff in a main function that only gets called if
the file is called as a script (as opposed to being imported as a library):
That’s a lot of code for a simple task. Well it doesn’t necessarily require
much typing to enter thanks to the
SnipMate plugin for
vim. By adding the following code in ~/.vim/snippets/python.snippets we can
create almost all of the code by typing start and hitting tab right
at the beginning of the script.
This will create the main function and position the cursor within the usage string
thus making it a snap to write some quick documentation of what this script will do.
The num_args variable is there to make sure the user enters the right number of
arguments. Otherwise the script exits with an error. The rest of the processing code
should go directly after the if statement. When scripts are written in this manner,
they can be painlessly turned into libraries at a future point in time.
Scaled Colormap in Matplotlib
05 Sep 2014
I often have to create plots where the color of some element reflects an
underlying value. This mapping of color -> value is generally easily
accomplished by using colormaps in matplotlib. The standard provided colormaps
(such as cm.jet or cm.cool) map values over the interval [0,1]. Often times,
however, our data will have a different range and will need to be normalized in
order for it to be mapped to the full range of available colors.
The example below illustrates what the color range looks like without the
normalization (top two plots) and with the normalization (bottom plot).
Notice how the unnormalized [-1,1] input values have a dark blue color over the
left half of the second plot. This is because cm.jet(-1) = cm.jet(-.5) =
cm.jet(0.) Values outside of cm.jet’s accepted input range of [0,1] all
return the same color. By using the Normalize class, the input values are
scaled to the [0,1] input range and the output colors span the entire range of
the colormap (third plot).
Fast 3D Vector Operations in Cython
26 Feb 2014
The numpy library provides a plethora of fast functionality using for vectors. The question is, can we improve upon it by using cython and assuming vectors in three-dimensional space. Let’s take the following two functions which are not provided by numpy, but easily implemented. The first simply calculates the magnitude of a vector, while the second calculates the distance between two vectors.
Now let’s take the equivalent implementation in cython. The only major difference from the pure code is the definition of the data types and the handling of each value individually without any loops.
Finally, the timing:
Using the cython implementation leads to a nearly three-fold decrease in the running time for the vec_distance function and an almost two-fold decrease in the running time for the magnitude function. The cytvec implementation can simply be copied into a file (let’s say cytvec.pyx) and compiled into a module by following the instructions in the cython tutorial.
An already compiled implementation can be found in the forgi package under forgi.threedee.utilities.cytvec.