Using Nix to Create R Virtual Environments

Previously we saw how to use Nix to create virtual environments for Python. We can do the same for R. This means we can have different simultaneous R installations for different projects and keep the installed packages for each project separated. An important benefit of this is the ability to have different (incompatible) versions of the same packages for different projects.

The straightforward approach is to let Nix handle all R package management. However, sometimes it is useful to manage packages through the various R tools such as the built-in install.packages or install utilities provided by the devtools package.

R looks for installed packages in the R library directories, of which there are two types: the system library and the user library. By default these package management tools install packages in the first-specified user library directory. The user library directories can be specified through the R_LIBS_USER environment variable. We can use Nix to specify a unique library directory per project.

For example, create a nix.shell in your project root as follows:

with import <nixpkgs> {};
let
  my-r = rWrapper.override {
    packages = with rPackages; [ 
      ggplot2
      plyr
      tidyr
      devtools
    ];
  };
in  
  pkgs.mkShell {
    buildInputs = [
      bashInteractive
      my-r
    ];
    shellHook = ''
      mkdir -p "$(pwd)/_libs"
      export R_LIBS_USER="$(pwd)/_libs"
    '';
  }

Activate it in your shell by running $ nix-shell.

This makes available R with ggplot, plyr, tidyr and devtools. It creates a subdirectory in your project root, _libs, where the project’s R user library is located.

Using Nix to Create Python Virtual Environments

Nix and Python logos

Nix is a great tool to set up development environments. It allows us to have simultaneous installations of various versions of tools—such as Python—required for our projects. This means Nix makes it easy to have Python 2.7 installed for one project, and Python 3.6 for another. Projects using the same Python version can have different Python packages.

Of course, Python’s VirtualEnv also enables us to do this. Nix, however, is more powerful. It can handle all our system’s packages; not just Python’s. This means it enables us to hold different versions of any dependency. For example, if one project requires a specific version of OpenCL and another project requires an incompatible version, VirtualEnv won’t help us. Nix will.

There are many Python packages, and to install one such package through Nix requires it to be available in the Nix package repository. Understandably, not all Python packages are packaged for Nix—and those that are, often are not the newest version, nor at some other specific version we require.

We can use Nix to provision a Python environment for our project that works similarly to VirtualEnv’s. We can then use pip to handle such per-project Python dependencies, allowing us to grab Python packages directly from the regular Python package repositories without going through Nix. This also allows us to quickly get to work with others’ Python projects that are not set up to work with Nix.

Continue reading “Using Nix to Create Python Virtual Environments”

Creating Multiple Custom User Types Through Inheritance in Django

Django Logo

When developing applications in Django, the need might arise to customize the user model. Specifically, you might want to create different types of users. In my case, I’m interested in creating a person user and a kit user. A person user can own multiple kit users, and both need to be able to authenticate to access an API. Luckily, Django’s authentication system is very flexible, and there are multiple ways to achieve this goal.

The standard way to implement this is to stick with the default user model, django.contrib.auth.models.User, and create a complex user profile. The profile adds the desired fields and behaviors for the various user types in a new model, and links to the model through a field reference. This can get fairly complex quickly. It is especially difficult to express ownership of kits by users, without allowing ownership of users by users. Here, we will see how we can implement this using inheritance.

Continue reading “Creating Multiple Custom User Types Through Inheritance in Django”

mIRC Smart Join/Part Filtering

Though internet relay chat (IRC) is old technology, many people still use it daily. One of the most popular IRC clients for Windows is mIRC. This client is impressively feature-complete. However, it does not offer a way to satisfyingly solve one of the grievances of many IRC users: the flood of join and part messages in big channels, caused by the constant stream of people coming in and leaving. mIRC only offers the option to either show or hide all join and part messages completely; but does not allow for any fine-tuning.

What I was looking for was a way to show or hide join and part messages based on the size of the channel. If a channel has only few people, I’d like to see all joins and parts. If, however, a channel has many users (e.g., more than 25), this quickly becomes a nuisance. In addition, even in big channels, I’d like to see all joins and parts of people who were recently active in the channel, so as not to accidentally reply to someone who has left in the meantime.

With this specific need, I created a solution, which I have made available on github. It can be added to mIRC by loading it as a script (Tools -> Scripts Editor -> File -> Load). Configure it by right clicking in a chat window, and select Join/Part Filter -> Settings.

Smart join/part filter
The smart join/part filter setting screen

Programming this solution using mIRC’s scripting language was definitely a fun project: the scripting language is quite basic with little documentation, and as mIRC’s interpreter offers hardly any assistance when things go wrong, it quickly turns into a puzzle. However, it’s also quite powerful and allows you to access and modify many things within mIRC.

A Bot to Log Discord Voice Events

Discord is a great platform for text and voice chatting. However, one feature has been seriously lacking for a while now: the ability to see a log of people joining and leaving voice chat rooms.

Luckily, Discord provides a way to create bots. These bots have access to a variety of events occurring on a Discord server, including voice chat events. Of specific interest to us, bots can track events of people joining and leaving voice chat rooms.

I set out to create a simple bot able to log these events to a specific Discord channel. I programmed the bot in Python, using the discord.py library (v0.16.7). My code is open source and available on github. See the bot in action in the video below:

If you’d like to use this bot, feel free to use the code provided; you’ll probably need to create a new developer application on Discord and turn it into a bot user, and read the read-me.

Plotting a Heat Map Table in MATLAB

A heat map table with the "copper" colormap
A heat map table with the “copper” colormap.

A little while ago I found myself needing to plot a heat map table in MATLAB. Such a plot is a table where the cells have background colors; the colors depend on the value in the cell, e.g. a higher value could correspond with a warmer color. I found no existing function to do this easily, so I set out to create my own solution.

The code to plot a heat map table can be found here.

Usage is pretty simple. If you have a matrix $latex A$, just pass it into the function and it will do the rest! For example:

A = zeros(7,7);
for i = 1:7
    for j = 1:7
        A(i,j) = i+j-2;
    end
end
tabularHeatMap(A);

There are a number of options available. See the documentation in the code for more information about the options. To further adjust the generated figure, such as to add labels, proceed as you would with other plotting functions. For example:

confusion = crosstab(responses, correctAnswers);
h = tabularHeatMap(confusion, 'Colormap', 'winter');
title('Confusion Matrix');
xlabel('Correct');
ylabel('Response');
h.XAxisLocation = 'top';
h.XTick = [1 2 3];
h.XTickLabel = {'A', 'B', 'C'};
h.YTick = [1 2 3];
h.YTickLabel = {'A', 'B', 'C'};