Bored at work? Play networked pong in your terminal.

The game interface was inspired by this excellent tutorial on using tcell to develop a TUI. I extended the game to support networked play between two players using a streaming gRPC API.


The missing range functions for Go in one tidy package. Use it to easily generate intervals of integers, floats, runes, and strings.


I wrote an implementation of Conway's Game of Life using React and Redux.

When developing this, I tried to clearly separate the domain of the game of life (which is written in ordinary Javascript) from the view and state management layers (which are written using React and Redux Zero respectively).

Play the game:


Heads up! I don't maintain this anymore. No guarantee that it still works.

I wrote some handy tools for scraping OkCupid using Node. 'uscraper' scrapes OkCupid usernames and dumps them in a file. 'okscraper' reads a file of usernames, scrapes their profile essays, and dumps them in another file.

Why did I build these tools? My ultimate goal is an algorithm that determines how unoriginal your OkCupid profile is. This will probably rely on some version of the Rabin-Karp string searching algorithm, which requires a set of patterns. Since OkCupid doesn't provide an API, I've got to scrape 'em.

Is it green?

Heads up! I don't maintain this anymore. No guarantee that it still works.

Alameda county certifies local businesses that conserve energy and water, minimize waste, and reduce their carbon footprints. Unless businesses advertise their "green certified" status however, there is no easy way to identify certified businesses.

A few apps have already been made to address this problem. Jon Wu's "Green by me" maps green businesses near a user organized by sector. Alameda county has an official app that allows users to search green businesses by city and sector.

I thought that these apps, while useful, lacked a core feature: the ability to search for green certified businesses by name. This app implements that feature within an appealing front-end interface.

BAC Monkey

Heads up! I don't maintain this anymore. No guarantee that it still works.

BAC Monkey is a personal tracker for alcohol, caffeine, and nicotine. Users can enter the number of drinks they consumed and see their estimated Blood Alcohol Content (BAC %) graphed over time. Caffeine and Nicotine dosage is graphed in milligrams.

If a user creates an account with BAC monkey, he or she can begin tracking her long term habits. A user's profile page provides their average daily consumption, how they compare to other users, and information on the maximum intake doctors recommend.

I developed BAC Monkey in Rails along with Patrick Vilhena, Darcey Lachtman, and David Goodman. I was team lead and my particular contribution was the development of the models required to generate the graphs.

Macronutrient search

Heads up! I don't maintain this anymore. No guarantee that it still works.

I like to keep track of what I eat, but I hate most online nutrition apps. They're filled with ads and usually give me way more information than I actually need. So I decided to make my own.

Macronutrient search does what it advertises: it returns the macronutrients of a food only. Food "macros" include calorie count, carbohydrates, fat, and protein. You know, the things you actually pay attention to on a nutrition label.

It's powered by the FatSecret API which provides a solid nutritional database. Ibrahim Muhammad wrote a nice ruby gem for the API. The app is optimized with database caching; the results of each user query are written to a database by a background job to avoid repeat API requests. Note that background jobs are disabled in the heroku deployed version of the app.

Roy Lee, Patrick Vilhena, and Eli Shkurkin recently helped me redesign the frontend with the D3.js library. The macronutrients for each result are now visualized in a radar graph.

Cluny preambles database

In my free time I maintain a SQLite database of preambles (also known as "arengae") from the Cartularies of Cluny, 987 to 997.

Historians are interested in preambles because they are highly rhetorical, and therefore offer us a window into the ideology advanced by a monastery. The database has one table with the following schema:

charter_num refers to the categorization of charters found in Bernard & Bruel, "Recueil des chartes de l'abbaye de Cluny", Paris 1876-1903.

This database is free for anyone to play around with, if medieval history is your thing. "arenga_types.txt" is a guide to the arenga categories found in the database.