Computing the optimal stop placement for transit

Like many people, I take the bus to work most days. My commute isn’t actually that far (about 3 miles), but I am incredibly lazy, and the bus lets me catch up on the magazines that would otherwise be accumulating dust on my table. (And if I keep up on my Harper’s, I can at least pretend I’m up to date on what’s going on).

Anyway, here’s my bus route:

http://pugetsound.onebusaway.org/where/standard/trip.action?id=1_28275667&serviceDate=1440572400000

bus route

The main thing to notice here is that it stops an awful lot.  During peak commute hours, I can sometimes walk faster than the bus.  Given that I’m out of shape and my commute involves a big hill, that’s not a good sign.

It’s been pointed out many times that perhaps stops are placed too close together in many locales:

So there are potentially good reasons why you want to have stops closer together than what might be optimal; though I would mostly bucket these into having a customer base that is old, fat, lazy, grumpy or some combination of those 4.  You can see in the humantransit post the outrage expressed at having stops more than 300 meters apart.  The horror of having to walk more than 1.5 blocks to your stop!

But let’s go ahead and assume we live in a world where people are happy to walk longer distances.  Let’s go further and assume they’re willing to walk as far as they need to ensure their overall trip time is minimized.  If we have such a cooperative public, then what’s our optimal stop distance?  I made up a trivial model of what happens in this case in a Ipython notebook here:

https://gist.github.com/rjpower/f78fba35235a5277ed85

Here’s the resulting plot:

This model is incredibly contrived, but still, it’s interesting to toy with the tradeoffs.  Note that even with a very slow walking pace (2 minutes/block, or 50 meters a minute), the optimal distance is over 5 blocks apart.  (Compare that with the spacing on my route at a ~2 blocks between stops.)
If you have ideas on how to improve the model, please let me know!

slackmail

We use Slack extensively at Iodine. It’s where most of our communication takes place, even within the same office! (You can argue that this isn’t especially healthy…)

Sadly, we’re still forced to use email to interact with some services that haven’t added a hook for Slack. These include some monitoring services, or just when we want a “read-only” address for people to send us updates.

The pain point I was feeling recently was with the Luigi package, which makes building data pipelines a snap. We use it extensively to build the data that backs the openfda API. Since some build steps can take several hours, it’s nice to start up a pipeline and go off to lunch (or to sleep). But when there’s a failure we want to know about it: Luigi conveniently supports email notifications for this task, but there’s no way to add a webhook.

Now the reasonable thing to do would be to just add support for a webhook notification to Luigi and send them a PR to get it merged. But then we’d still be stuck with email for all of our other services. So instead, I thought why not just proxy email to Slack directly? I know absolute nothing about SMTP or MX records, so how hard can it be?  But if I made such a service, we could use it for any service that supported email notifications. (My guess is that Slack will add support for such notifications like… 3 minutes after I post this, but anyway it will be useful until then).

With that in mind, I whipped up slackmail: a SMTP server that forwards messages to Slack. To make this super-extra-convenient, there’s 2 servers: one you can use locally for testing and another one that supports adding and removing hooks dynamically. To avoid getting spammed, you can specify an authorization token which must be present in the incoming mail for it to be forwarded. The code illustrates my almost perverse lack of knowledge about SMTP, but nonetheless appears to work.

If you don’t want to run your own server, feel free to play with my example server. To register a new hook, email [email protected]. Here’s an example using the mail command line client:

To remove a hook, just email [email protected] with the same content. Once you’ve registered a hook, any emails to [email protected] will be forwarded to your webhook. Feel free to email me at [email protected] to say hi!

(You can also email [email protected] if you like building interesting tools and helping make healthcare better!)

on dreams

The other night I dreamed about a plane full of people.  Somehow, I even knew the exact number (240).

Then I dreamed about something else.

Then I started feeling bad, because I realized the lives of those 240 people depended on me dreaming about them, and once I stopped, they disappeared.

On distractions

I just purchased a new phone.  I’m convinced that this was not a brilliant time to introduce a great source of distraction, given I’m frantically working towards finishing my thesis and preparing for my defense.  But it’s so shiny!

Transaction Chain Visualization

We had a paper at the last SOSP on transaction chains.  Our original analysis of chains was done by hand, which is quite a silly way to do it.  We then wrote a simple script to do the graph analysis, but it’s still difficult to picture the interaction of chains (a script telling you that you have an S-C cycle is great, but what should you do about it?)

To make this a bit easier, I made up a little webpage that lets  you enter in a list of chains and indicate commutative links.  This page very effectively illustrates 3 things:

  • My ineptness at Javascript
  • My lack of graph theory knowledge
  • That there are some neat Javascript libraries out there (hello Dagre!)

Try it out here: http://rjpower.org/transaction-chain/

Creating fancy images with Matplotlib

I have to give a short presentation at SOSP next week, and for it, I needed to have some nice pictures representing a distributed array. After trying out several tools for trying to create these, I began to lament and cry over the state of Linux drawing software. But that’s a different story. I ended up writing a simple matplotlib script to generate the pictures I needed, and since it worked out pretty well, I thought I’d share it here.

Here’s the kind of picture I’m referring to:

filter

It turns out this is pretty straightforward using matplotlib. Here’s the basic function:

The first part of this just turns off the various lines for the axes. We then iterate through the elements of the array and create a Rectangle() for each one; each “layer” (z-axis) is shifted off to the right a little bit from the previous, to give our illusion of depth. (We don’t want a normal perspective projection, as it would hide too much of the deeper layers).

The “sigh” comment is where I’m using a hack to determine the size of the text we’re going to put in so I can center it in the array cell. I couldn’t find an easier way to do this, and no, I don’t know why I have to divide the result by 30.

The input array has 3 fields which specify how to render each rectangle:

Now we can construct an arbitrary array and feed it into our function:

Once we have the basics out of the way, we can do some fancy rendering really easily. First, let’s make a little helper class to draw slices:

We can wrap an array in draw_slice() to make it easy to construct pictures of slices:


draw_slice(a)[:,:,1]

slice-z

We can be fancier if we like too, drawing the results of a filter operation:,


draw_slice(a)[a[‘name’] <= 1]

filter

If you are interested, the full code for creating these figures is here: https://gist.github.com/rjpower/7249729. All you need is matplotlib and numpy.

statically linking shared libraries with libtool

I run a lot of experiments on our local cluster.  Unfortunately, over time, the library versions on the cluster tend to diverge from those on my local machine. As a result, I’ve gotten used to seeing this:

If I was using Go this wouldn’t be a problem, as they statically link everything.  Despite the crowd of people who think shared libraries are the bees knees, I agree with this approach — it’s just far simpler than trying to deal with errors like the above. You can solve this most of the time by simply statically linking everything (–enable-static).  Sadly, if you’re trying to build a shared library (in my case, an extension module for Python), you can’t really go this route. (Statically linking Python API calls into a library which is then hoisted into Python is going to end very, very badly). What am I supposed to do with this error? If you trawl around the web, you find that depending on the exact error, you should either:

  • find an old version of GLIBC and link against that
  • insert assembly directives to indicate the old symbol

If you happen to have a single symbol that’s pulling the newer version, the latter is an easy fix (though it’s a bit annoying to ensure you’ve always got the directive declared before you use a function). If you’ve somehow acquired a dependency on the whole library things become more annoying. In my case, this dependency seemed to result from the chain:

Oddly enough, depending directly on libstdc++ isn’t the problem. If I remove the dependency on libspartan (just linking directly against all of the objects), we’re fine:

Notice, no reference to GLIBC_2.17. Luckily in this case there’s a simple solution: make all of the helper libraries into convenience libraries. This causes those libraries to be statically linked and avoids pulling in the extra dependencies:

If we weren’t lucky — we’re actually using the symbol that’s from a later version — than we can force static linking of your dependent library; you do this by listing it explicitly by name in your LIBADD variable:

libtool will complain that linking against a static library isn’t portable (which is true), but it should work correctly as long as the static library was built with -fPIC.

the Onion

We used to have the Onion (America’s Finest News Source) available for free here in New York, in those little weekly newspaper boxes you see lying around. After the hurricane last year, the supply seems to have dried up. This was a sad event. Not only did I get high quality journalism from the paper, they also had a very nice crossword puzzle for lazy Saturday mornings.

Enterprising individuals have begun reusing the boxes for temporary clothing storage, and some of them have been commandeered for other, not as interesting papers. (New York real estate is valuable, after all).

I don’t often check their website, as it adds to the already crippling amount of distraction that I experience in a day, but this article caught my eye. As a person who finds comfort in the knowledge that the universe will eventually empty out into a cold cinder, I can’t help but approve when others notice the same.

a blast from the past

While reading some EE articles, I happened across a link to a Webring site. Remember Webrings? Probably not. They were the rage back in the 90’s. Not so popular anymore, as all content gets swallowed up into the Facebook/Tumblr/Google ecosystems.

The nostalgia hit of clicking through the various pages in the ring was quite impressive. All of those pages “made with notepad”. The blink tags, marquees and counters, all used without irony. Ahh, those were the days.

For the curious, start here.

Citibike: Bike Flow

I’m a big fan of the Citibike bike share program that started here recently.  One common issue I and others seem to suffer from is the lack of bikes (when starting a trip) or docks (when ending a trip).  Our neighborhood tends to be a very popular destination in the evening, so when I try to ride a bike in, I often end up a few blocks away from my desired station.  Similarly, if I get a late start in the morning I often find there are no bikes left to ride.

I was curious about how the flow of bikes works around the city — where do the bikes go to when they leave the East Village?  I crawled the Citibike web site and created a simple website to visualize the flow of bikes around the city; the results are pretty interesting:

citibike

With some more work on the data, it might be possible to use it for predictions (“will I be able to return this bike to my station”) and to aid in balancing (choosing which stations to move bikes between, and at what time).

The source code for the application is available on Github.