code

xsection.js | 30 Years in Data

The Earth has, just today, completed revolving around the sun three times for each finger on a typical human hand since the day I was born. To commemorate the occasion, I made an interactive visualization of my life. I've open-sourced the code as xsection.js and you can create your own custom version by modifying the data.js file.

Laminar Flow Fountain - Maker Faire 2013

This year at Maker Faire Detroit, I helped Matt Oehrlein and the team from i3 Detroit with their laminar flow fountain. The fountain is composed of three laminar jets. Each jet shoots into a barrel containing the next jet, creating a ring. The individual jets are controlled by an Arduino which wirelessly communicates with a Makey-Makey connected to three brass candle holders. Touching two of the candle holders causes a jet to connect the corresponding two barrels.

Since the project was built in Detroit, and I'm living in Boston these days, I wasn't able to help with the fountain construction. Instead I helped create a "screensaver" demo to show the fountain off when there isn't any activity on the controller. I didn't have access to the electronics when I started because 1. they were in Detroit and 2. they weren't finished yet, so instead I wrote a simulator for the fountain in Processing and worked on it in Boston.

Since the team from i3 was using an Arduino to control the fountain, and the Arduino language is a subset of Processing, I was able to copy my demo code straight from the simulator and into the controller code. You can see the result in the video above, showing the demo running on the fountain with the simulator in the upper right corner.

I wish I could take credit for the fountain itself, because it turned out amazingly well (despite a lot of wind throughout the Faire). The demo was still a lot of fun to work on, and this project now has me thinking about more ways the Arduino/Processing combo can be used for remote collaborations.

Drupal Hooks Should Use PubSub

Drupal is an incredibly flexible piece of software, but that flexibility often comes at the price of slow performance. After several years working on Seltzer CRM, which I modeled after Drupal 6, I've realized that there is a simple way to get the same flexibility without as much of a hit to performance.

Drupal achieves its flexibility through modules and hooks. A Drupal module is simply a self-contained chunk of code that can be installed and enabled to provide a set of features, like a shopping cart, or comment moderation. A hook is a function in one module that changes the behavior of another module, like taking a form produced by one module, and altering its contents. Drupal's takes an implicit approach. If I have a module foo and I want it to alter forms produced by other modules, I implement the hook_form_alter() hook like so:

function foo_form_alter(&$form, &$form_state, $form_id) { ... }

Whenever the form system creates a new form, it checks each module to see if hook_form_alter() is implemented, and if it is, passes the form data through that function. All my module needs to do is define the function. So what's the problem?

The performance problem is in plain sight. Every time a hook is called, every module needs to be checked for the existence of that function. The number of checks increases linearly with the number of modules, and in practice, most of those checks are unnecessary because any given hook will only be implemented by a small fraction of available modules. We can improve performance by switching to an explicit approach.

For our first try, let's invent a function called form_alter_register() that allows our module to explicitly register a callback:

form_alter_register('foo_form_alter');
function foo_form_alter(&$form, &$form_state, $form_id) { ... }

Now, the form system can check each callback in the list rather than checking each module, which could speed things up quite a bit!

However, we're not quite at the same level of flexibility yet. Let's imagine that there's another module called "widget" and if its installed we want to be able to alter widgets as well. We do the following, right?

widget_alter_register('foo_form_alter');
function foo_widget_alter(&$widget) { ... }

It works fine if the widget module is enabled, but what if the widget module is optional? Then widget_alter_register('foo_form_alter') won't be defined, and our code will crash! We could check whether the function exists before calling it, but that could get tedious. Better yet, we can use the same trick again, resulting in something like a publication-subscription approach.

Specifically, we define two core functions, one that allows modules to register the hooks they implement, and one that calls all hooks of a given name:

function hook_register($module_name, $hook_name) { ... }
function hook_invoke_all($hook_name) { ... }

Then our code to implement the hook looks like this:

hook_register('foo', 'widget_alter');
function foo_widget_alter(&$widget) { ... }

Now we have improved performance and the same level of flexibility. Some might argue that even calling hook_register() before each hook definition is tedious, and it may be. On the other hand, code is read more than it is written (as the adage goes) and this pattern explicitly identifies a hook as such, making it more readable, while Drupal's current pattern does not. So for improved performance and readability, the next time I'm writing a modular framework, I'm likely to use this pattern instead.

PS: Does anyone know if there is a proper design pattern name for either of these approaches?

Seltzer CRM - Penguicon 2013

Here's an outline from my Penguicon 2013 panel "Seltzer CRM."

Voip, SMS, and MMS - Penguicon 2013

Here's an outline from my Penguicon 2013 panel "Voip, SMS, and MMS."

Tags: 

Mind Flame: Maker Faire Detroit 2012

For Maker Faire Detroit this year, I collaborated with Matt Oehrlein to build MindFlame, a mind-controlled flame effect game.

MindFlame uses commercial EEG headsets from NeuroSky to read the brain waves of two contestants. The signal is sent to an arduino, which can determine (more or less) how hard the contestants are focusing. When a contestant focuses hard enough, the arduino activates a solenoid, releasing a burst of propane past a glowfly ignitor, causing a giant burst of flame. The goal was to be the first person to get to four bursts of flame.

This project was tons of fun, and collaborating with Matt was great because we had twice as much time and resources to throw at the project, and I think the end result was much more impressive than we could have done individually. Plus, controlling fire with your mind is just awesome. Josh “Bacon” McAninch (from the Gon KiRin project) helped us with the flame effects, and Maddy "Brodi3" Winans helped us design and decorate the apparatus.

(Photo by Doyle S. Huge)

Mystic Rose Generator

Here's yet another geometric math/art/code thing. It's a javascript-based Mystic Rose Generator. What's a mystic rose? Draw a circle with n evenly spaced points on it and draw a line connecting each point to all the others.

FlakePad - Maker Faire Detroit 2011

I wanted to do something interactive for Maker Faire last year. I had been drawing my PenFlakes, and thought it would be cool if people could design their own and print them out. So I created FlakePad, a javascript/HTML5 web app that enforces the basic symmetry of a snowflake, and provides a hexagonal grid to work off of.

Aside from being a great way to get my hands dirty with HTML5, the most interesting part of the app was creating the hexagonal grid. I wound up learning about and utilizing Isometric Cubic Coordinates. These coordinates provide an amazingly simple way to label hexagons on a grid, as well as a relatively simple transformation to and from standard Cartesian Coordinates. The basic trick is to recognize that a hexagonal grid, can be seen as a projection of a 3D arrangement of cubes centered on the plane x+y+z=0 (imagine Q*bert, the old NES game).

Seltzer CRM

Over the past couple years, I've been developing a Customer Relationship Management app (CRM) for hackerspaces, and it's now ready to release into the wild! Meet Seltzer CRM!

Seltzer CRM is an open source (GPL) CRM web app for hackerspaces. It's based on the LAMP stack, and has been in use at i3 Detroit for a couple years, growing with us to our current level of 75 members.

There are plenty of CRMs out there already, and even some open source ones, but all of the ones I've come across are rather complicated and have a learning curve before people can use them productively. Seltzer CRM is built around two goals: 1. Be significantly useful to the average hackerspace administrator without any training; 2. Be easy for a typical hackerspace web dev to hack on and extend.

The current features are:

  • Track member contact info
  • Track current and historical membership levels
  • Track keycard info
  • Provide attendance and voting sheets

You can try a demo here:
http://elplatt.com/seltzertest (user: admin, pass: beexcellent)

And the code is on github:
http://github.com/elplatt/seltzer

MIT Snowflake-A-Thon 2005

In January of 2005 I participated in the Snowflake-A-Thon hosted by the Simplicity group at the MIT Media Lab. The challenge was to write the simplest program that produced the most beautiful snowflake. You can see the gallery of all the snowflakes and a video of mine here.

My program created a hexagonal grid, and assigned a number to each hexagon. The center started as "1" and the rest started as "0". After every time step, the value of each hexagon was added to each of its neighbors, modulo 32. I ran the code for a few time steps and then mapped the numbers to a gradient from dark blue to white. I got the idea from playing around with 2d cellular automata on a hexagonal grid when I was in high school.

I thought the resulting snowflake was really nice. Apparently the Simplicity people thought I was a total weirdo for coding a snowflake in MATLAB, but I remain pleased with the results.

Tags: