April 22, 2014

In defense of Larry Rawson

Running geeks love to pile on Larry Rawson, verbally rolling their eyes whenever he’s on TV. Some of this is over-familiarity with some of his oft-used metaphors as he makes an effort to communicate the speed of top runners to less-sophisticated viewers; some of it is a perception that, after decades on the air (yesterday was Rawson’s 40th Boston Marathon broadcast) maybe Rawson is a little out of touch.

The obvious defense is that calling a race on live television isn’t easy. You have to be talking not just when you have something to say, like most fans, but all the time. Which means you have to be watching and thinking and talking all the time. Not easy at all. What’s more, the amount of information you actually have while watching races on screens is less than you’d think. I say this as someone who occasionally goes to these big races with the express purpose of getting more information to the people talking on camera.

I think Rawson deserves some credit for a few specific moments in Monday’s Boston Marathon broadcast:

  • As Meb Keflezighi was running through the Newton Hills, Rawson drew the parallel between Boston and the Athens Olympic marathon course, where Meb won a silver medal ten years ago. Not only was there a historic parallel — the Boston course was intended to be an imitation of the Athens route’s profile — but pointing out that Meb got away once before on a hilly course was an nice comfort to those of us sitting on our figurative seat-edges wondering if he would get caught.

  • In Brookline, with Chebet closing the gap on Keflezighi almost inexorably, Rawson went out on a limb and suggested that the pursuers had left their move too late and would need to work too hard to actually catch Meb. And sure enough, Chebet got within six seconds of Meb but found himself too spent to finish the job. It was a risky prediction that panned out; you only do that on television if you have a lot of confidence in your sense of the race.

Now, you could argue that Rawson was also sitting next to one of the best marathon-watchers currently in the business, David Monti, and was therefore somewhat aided in this. But as I’ve noted before, it was Rawson doing the talking live. He still had to decide what to say and what to sit on, which theories he agreed with and which to sit on.

So, maybe let’s go easy on Larry this time?

Posted by pjm at 8:00 AM | Comments (0)

April 19, 2014

Found Money Report 2014

(If you’re interested in previous reports: 2012 2010, 2009, 2008, 2007, and 2006.)

It’s past time to count the found money bin. This count represents a move back to Massachusetts, and a lot more running in small towns and suburbs, but also a lot more time spent outdoors with children, where you don’t necessarily want to model “pick up this thing you just spotted on the ground and stuff it in your pocket” as good behavior.

Consequently the tally is way down, even for a two-year span: $10.20. I know I’ve left cash on the table — err, sidewalks — that might have gone in here, but I doubt it’s been multiple dollars worth. Maybe I just don’t get out enough.


  • Three one-dollar bills, crisp and folded together. I recall asking a few people if they were theirs, but got no takers, so here they are.
  • 13 quarters, 37 dimes, 16 nickels and 145 pennies. Only the pennies were worth rolling, even combined with other change on hand, the first time that’s happened.
  • I didn’t separate out the Canadian cash this time.
  • 2 10-kopeck coins. Combined with a 50-kopeck I found in my pocket the other day (probably a leftover from my trip to Russia last summer) that buys… practically nothing.
  • Probably even less valuable than the kopecks, a Romanian 5-bani coin. I suspect that was found in an airport on the Russian trip, most likely in Moscow.

And that’s the spare change news for this session.

Posted by pjm at 1:27 PM | Comments (0)

February 19, 2014

Don't group your problems

At some point in the early afternoon, I got a to-do list. I had the project manager in a screen share showing me the problems she was seeing, and in another window a tech lead giving me feedback on a Github pull request. They were all mostly linked to this one component, so with three new items on my list, I thought, hey, I can refactor this and take care of all of them.


By mid-afternoon I was hopelessly mired, with a new template taking a ridiculous number of arguments, and at the same time Not Working At All, and I couldn’t figure out which of the several parts I had in the air was causing the problem.

Instead of bulling through, though, I finally learned something. I stopped, and threw away all the changes I’d made. I looked at just one item on the list, the pull request feedback. It was just changing some IDs on some tags. I changed the IDs and updated the pull request. Simple.

Next item. A status indicator shared between windows wasn’t cleared if one window was closed while in an error state and another one was opened. I had been trying to reset it on window close in my Brand New Super Component, but instead I figured out how I could essentially initialize it on window open without touching the existing component. (In the process I learned a little about how to call controller methods from a route in Ember.js, which was a bonus.)

Now I had two items cleared off the list, and I was free to fix the third in any way that worked. And, yes, I created a new component slightly different from the original one, but now I only had to solve one problem, so my new one was not as ambitious and didn’t require as many complicated changes. And it worked.

We’re gonna make an engineer out of me yet.

Posted by pjm at 7:08 PM | Comments (0)

February 4, 2014

Bootstrapping exercism.io

I posted a few days ago about starting out with exercism.io, a platform for doing coding exercises and having your solutions workshopped by others.

It turns out that exercism is an interesting illustration of a classic social-software platform: scaling.

The mechanics of exercism work like this: you submit your first exercise solution. Then you wait for feedback, and iterate. Once you’re satisfied with your solution, you can mark the exercise finished, and once you’ve marked a solution finished, you can start giving feedback to others on that solution.

If you’ve submitted a solution to an exercise, you can start another one in that language, even if you’re still iterating on the first one. This makes a lot of sense, because it turns out that you may be waiting a while for feedback. Essentially, there’s no barrier to joining the site and starting to do exercises, but because you need to have completed an exercise (possibly iterating three, six, even ten times on it) before you can start critiquing others, every exercise is almost guaranteed to have a much higher number of programmers submitting solutions than programmers reading and critiquing.

This can get pretty frustrating for a beginner. I sat on my first Ruby exercise for almost a week with no feedback until I got some. I iterated, and waited another four days until I got a “looks good” which I took as enough reason to mark it completed. (My submission for the next exercise has been sitting for six days without feedback.) I have three Coffeescript exercises waiting for critique, and one each of Ruby and Coffeescript waiting for me to start working on solutions.

The only way around this is for those of us who’ve finished any exercises at all to provide as much feedback as we can to others, and try to increase the pool of readers that way. I’m making an effort to provide as much feedback as I can to others working on that exercise, but probably what I’m doing is creating more work for whoever has completed the next exercise. The Ruby community is clearly larger than Coffeescript - whenever I look there seem to be around 70 active Ruby solutions waiting for feedback, but often there aren’t any Coffeescript solutions. So if I want others to be reading my Coffeescript, I need to be critiquing theirs…

ETA: And after I hit publish, I look at Twitter and see they’re aware of the problem.

Posted by pjm at 8:55 AM | Comments (0)

January 26, 2014

My new coding workout

I’m not going to detail the web-surfing path which led me to discover exercism.io, but I am going to explain why I like it.

The concept is this: exercism by itself is a small command line utility. When you run exercism fetch it gets you a programming exercise, which amounts to a README file and a test suite. The website describes how to set up the command line utility, and how to run the tests in each language supported. It uses GitHub for authentication and to serve the activities; I suspect there’s some git involved in storing the completed solutions as well.

The interesting part is what you do once you have the activities. You don’t just write code to make the tests pass, although you could. You submit your code to the site, and people who have previously completed the activity critique it. There’s a lot of effort put into emphasizing that this should be constructive criticism, and so far it looks like it has been. You get to respond to the criticism or iterate your solution to incorporate it (hence the constructive criticism; it’s more like you’re workshopping your code than being graded on it).

Currently 12 languages are supported, mostly of the “trendy” variety. Perl5 is offered but not PHP. Go, Clojure, Haskell and Scala are offered but not Java or C.

I’m using Coffeescript a lot in my new job, so I’m using these exercises to get my mind used to the idioms of that language rather than leaning heavily on its Javascript basis. I’ve also started doing the Ruby exercises; it looks like there’s a much deeper user base in Ruby, and maybe more exercises there as well (it’s hard to tell until I get deeper). My motivation for trying Ruby is not that I think I need practice but that I think the exercises may teach me some new ways of approaching problems in any language, whereas in Coffeescript, so far, I’ve understood how to solve the problems, but not how to solve them in a Coffeescript way.

This isn’t a site for learning a language; if you’re not at least competent as a programmer the first exercise is going to be frustrating. The parallel with a spoken language would be a “conversation class” rather than a “teaching class”. I’m debating starting the process in Javascript, as a complement to the Coffeescript work; Python is another language where I only barely know it, but might benefit from some work in the idiom.

Posted by pjm at 8:34 PM | Comments (0)

June 27, 2013

Target your recruiting

I’m debugging some Javascript on a page which embeds a Prezi slideshow. It turns out that one of the scripts Prezi loads writes this to the Javascript console:

If you find digging around in stuff like this fun, you might want to take a look at our job page: http://prezi.com/jobs/ :)

I have to wonder if they find anyone this way, but given how specific it is—it’s unlikely this message reaches anyone who wouldn’t be at least a little qualified—and how low the cost, it’s a pretty efficient recruiting message.

Posted by pjm at 2:52 PM | Comments (0)

June 5, 2013

JavaScript testing for Rails 3.2 by integrating Jasmine

I wanted to write unit tests for JavaScript components of the Rails application I’ve been working on recently, and intended to use the Jasmine framework to do it. However, I found a lot of conflicting information about what the current incantations are for making this work properly, and a near-total lack of documentation for my particular setup. Consequently, I’m documenting my process here, in hopes that it will help someone else.

The application uses Rails 3.2 (actually 3.2.13 at the moment). I made a false start using the jasmine-rails gem, but in the end I had two big problems with that: the rake task which was supposed to run the tests couldn’t find the Jasmine library, and while Rails was able to mount the Jasmine engine, it wasn’t loading the scripts I intended to test.

I dumped that branch and went back to master and started over. Following the tip on the Jasmine page linked above, this time I tried using jasmine-gem. (It was v1.3.0.) I installed it as directed on the gem’s README page, specifically by adding gem 'jasmine' to the project’s Gemfile, running bundle install, and then rails g jasmine:install and rails g jasmine:examples.

(In the end I didn’t commit any of the code generated by the jasmine:examples generator, but it was illuminating.)

The gem then suggests starting a server with rake jasmine, and sure enough, that worked. It took a bit to get the server seeing the code to be tested, however. This involved tweaking the spec/javascripts/support/jasmine.yml file to include the proper set of scripts. Specifically:

  • The src_dir value needed to be public/assets. This Stack Overflow question pointed me in the right direction. I had to add a manifest file (i.e. assets/application.js) to the src_files array as well in order to include the script containing the code I wanted to test.
  • I needed jQuery to be available to Jasmine. jasmine-jquery turned out to be the solution here, not because it itself is useful (although it is) but because it pointed out that I needed to add jQuery to my src_files file. (It isn’t in my manifest because I’m loading it from a CDN.)

Now I had running Jasmine tests. (Once I wrote the tests, of course, within the spec/javascripts directory. More on this at the end.) However, my rspec unit tests for Ruby code run automatically when I change the relevant files (either the code, or the test code which tests it) so I don’t need to kick off a test run to see if I broke something. I use Guard for this. (Currently v1.6.2.) I wanted Guard to run my Jasmine tests as well, so I’d get the same kind of instant feedback for JavaScript that I get for Ruby.

For this I wound up installing guard-jasmine. (This was v1.16.0.) Once that was in my bundle (add to Gemfile, run bundle install, rinse, etc.) I ran guard init jasmine and it added a block to my Guardfile to watch the JavaScript files and Jasmine specs.

Running this was a little trickier, however, because once again I needed to train it to find the code I wanted to test against. This required me to install jasminerice (v0.0.10), even though I don’t need that gem’s primary function. Once I had that in my bundle and had created a spec/javascripts/spec.js.coffee file (essentially a manifest file for my Jasmine specs) and a placeholder spec/javascripts/spec.css file, this worked fine. I had to restart Guard to make sure it found and started a Jasmine server properly, but it was running the specs I’d written previously with the free-standing Jasmine and they were passing.

Now, about that test code:

There was a step 0 to this process which I had previously stumbled on but hadn’t really faced before, which was that in order to test JavaScript, one must have testable JavaScript. A recent article in A List Apart addressed this quite nicely; in short, instead of the usual written-three-lines-at-a-time soup of jQuery functions that normally come along with a Rails application, you want to build real JavaScript objects; then your test code can instantiate those objects and run assertions against their behavior.

Posted by pjm at 1:59 PM | Comments (0)

May 16, 2013

Running the 118th Boston Marathon

If you want to run the 2014 Boston Marathon (a.k.a. the 118th), you have a tough road in front of you. I’ve had a few people ask for advice for getting in. Until we hear more from the BAA, it boils down to: first, get a BQ. Second, get the best BQ you can. Third, pay attention.

There is a lot of discussion about the B.A.A. making allowances for the 118th, relaxing the standards or raising the entry cap. I’ll address this later. Until an official announcement is made, we’re playing by the usual rules, except that there are several thousand runners—those who weren’t able to finish the 117th when the finish line shut down—who will be offered automatic entry, thus beginning to fill the field before registration even opens.

If you already have your BQ, that makes things easier. If you don’t have a BQ, you’ll need to chase one (and if you do have one, you may still want a better time; I’ll get to that later too).

Chances to chase standards are pretty sparse right now. The reason is pretty simple: in most of the country, it’s already too hot to run a fast marathon, and if it isn’t, it will be soon. Entry is scheduled to open in September, so there may be a chance to run a BQ in September (the actual opening date hasn’t been announced yet), but October is almost certainly too late.

It sounds like relatively few people are trying to jump in marathons right away, which is sound; it may be possible to finish a marathon on a month’s training, but running a BQ is not that easy for most.

If you can be ready within six or eight weeks and can travel anywhere, some options open up. There’s Grandma’s in Minnesota, if that hasn’t filled; that’s in mid-June. Likewise the Mayor’s Midnight Sun Marathon in Anchorage, Alaska. There are plenty of races on the calendar but many of them are e.g. trail marathons, actually known for being challenging due to heat, or otherwie tough qualifiers. (There should be extra points for anyone who gets a BQ at the Johnny Miles Marathon.)

Even if you’ve got a BQ under your belt already, the increased demand for the 118th may pose a challenge. It’s been a few years since a BQ meant your entry was assured; more recently, faster is better. Essentially, the faster your BQ, the earlier you get to register, and the more likely your registration will be successful. Therefore, there are BQs, good BQs (5-10 minutes faster than cutoff) and really good BQs (10+ minutes faster than cutoff).

If you’ve got a really good BQ, you’re probably in. If you’ve got a good one, I wouldn’t make promises, but you’re probably OK. If you don’t have a good BQ, you might want to think about improving it. For that, you’ll want to look deep into the summer, even into early September, with the idea of getting into great shape in the summer and hitting one out of the park as close to the registration opening date as you can. You could do worse than to look at Clarence DeMar for this one. (Someone needs to come up with a circuit of races named for Boston champions.)

Finally, pay attention and be ready to change plans if things come up which help you. I’ve already heard of one pop-up marathon scheduled for late summer expressly to give people a shot at qualifying; odds are there will be more. Look for one with a speedy, certified course (I can’t emphasize this point enough), chip timing, and an early-morning start (or other accommodations for heat). It may even be a good idea to have a Plan A and a Plan B.

Now, about the BAA: One thing they understand is that while they own the Boston Marathon on paper, in practice it’s a sort of public trust. They are going to do whatever they can for the 118th, and I expect they are exploring the option of a one-time raising of the entry cap. (The idea of a lottery, the way they ran it in 1996, has been floated as well, but in my opinion that’s not going to go over well if they can’t first allow in all the BQs who wish to run, so if I wanted to run I would be looking for a BQ before I put my hopes in a lottery.)

The hangup is that the field limit is not set arbitrarily by the BAA; it’s a limit more or less imposed on them by the towns the course passes through, principally Hopkinton, which has to support the starting area. Hopkinton becomes the running community’s public urinal for a few hours every April and bears it with remarkable good grace, but they have much less open space now than they did in 1996. Staging 30,000 or 40,000 runners through that town, if it’s allowed to happen, will take a lot of time and patience.

If the cap is lifted for the 118th, we will all owe the towns, especially Hopkinton, a greater-than-usual debt of gratitude. So watch where you relieve yourself, please, and where you toss that empty gel packet. (I am still finding empty gel packets on the Natick roadsides a month after the race.)

The BAA is still clearing up the mess from the 117th, and they have a half-marathon to think about in October. I would not expect an announcement about the 118th until late June at the earliest, and July or August is more likely. Stay tuned, and if you want to run, start staking out that really good BQ.

Posted by pjm at 7:45 PM | Comments (0)

February 23, 2013

"Vehicle Protection Center": stay away!

Paper spam, today. An official-looking mailer (fold side edges, then remove top stub to open) starting with bold, underlined text, “THIS LETTER IS TO INFORM YOU that if your factory warranty has expired, you will be responsible for paying for any repairs.”

Read that sentence again, because I did. Rephrase it: “If your umbrella is closed, you will get wet when it rains.” When I read obfuscation like that, I get suspicious immediately. All caps PLEASE CALL IMMEDIATELY in the next block of the letter really raises my hackles, just because I get ornery when I feel like I’m being herded.

Sure enough, despite including the make, model (Honda) and year of one of our cars, this mailing had nothing to do with Honda, and probably not with any other manufacturer. In fine print at the bottom, “Vehicle Protection Center is an independent nationwide company marketing vehicle service contract on behalf of leading third party administrators.” Which means nothing. Third sentence of that paragraph: “Vehicle Protection Center is not affiliated with any auto dealer or manufacturer.”

Here’s the thing: I never had any intention of purchasing an extended warranty. I turned it down when we bought the vehicle. Our history is of driving cars for years—decades, now—beyond their warrantees, and if they break, we pay for it. (Revolutionary, I know.) So I looked these folks up online. Sure enough, I don’t have to scroll too far down in the search results to find a page titled “Don’t be fooled by this vehicle extended warranty mailer from Vehicle Protection Center”.

This mailer is sleazy, and I’m posting this not because I think my regular readers would be fooled, but because I want that link above to come up closer to the top of search results.

Posted by pjm at 8:14 PM | Comments (0)

December 8, 2012

The webmaster's guide to passwords

Here’s the short summary: if you’re storing user passwords unencrypted anywhere, you’re doing it wrong. If you don’t understand why, you should stick to using free open-source packages like Drupal and not roll your own login system. Also, if you’re not a webmaster, and you ever get an email from a website which provides your unencrypted password, you should know that this site is probably not doing a good job storing your password securely.

The problem is this: sites get hacked, and databases get compromised. Encrypting the connection (your SSL certificate, the https in the address bar, and all that) just protects the customer’s communication with your server. It’s nice that they’ve stopped crackers from harvesting passwords one by one as their users provide them, but what’s the point if a successful compromise of the server means everyone’s passwords are available to the cracker?

The first thing you need to know (if not understand) is that there are certain functions which are one-way; that is, the input cannot be determined by the output. Some of these are called hash functions. If you run a sufficiently strong hash function on a password, it is not possible to determine the password from the hash. (The output of a hash function is sometimes called a hash.) (Hash functions are like padlocks: some are stronger than others. But even a weak lock is better than none at all.)

“But wait,” the inexperienced webmaster says, “how can I tell if my user is providing the correct password when they return to the site?”

Well, think about it. They’ve stored a hash produced by running a hash function on their password. Why not run the same hash function on the password provided at login time and see if the resulting hash is the same as the one in the database? Problem solved.

(N.B. You might also want to read up on “salt.”)

Posted by pjm at 9:22 PM | Comments (0)

November 19, 2012

Tally another rodent

Most of my public internet trail recently has been about little girls, and Izzy has not been getting his proper attention.

Therefore, I should announce that this morning he presented for tagging his first mouse of the season. (Mouse hunting season in most of the states he’s lived in runs from September 1 to August 31.) This is his first mouse of his second decade of hunting.

I was thinking about his record today, and unless I’m forgetting some, of the six places we’ve lived with him, he’s caught mice in three, and in a fourth he caught three bats(!) which I count as mice with wings. He also caught a mouse once while visiting A’s parents, so I make his total somewhere around eight non-flying mice and three flying mice.

I have a hunch he’s not done in this house, either.

Posted by pjm at 9:37 PM | Comments (0)

November 12, 2012

What if?

I don’t remember when I started reading XKCD regularly, but their new “What If?” feature has me stifling inappropriate laughter on a regular basis.

An example: a recent piece on the probability of electoral ties compares the odds of nine swing states all producing equal vote totals for the top two candidates with the odds of some fairly unlikely events, including being struck by a bale of cocaine dropped from an airplane, a tornado, and a meteorite strike. (Along the way we learn that a typical location in Florida “…experiences an average 1.4 picotornados per second … a Florida resident suffers an average of 0.64 femtodeaths per second from meteorite impacts … the average person in Florida is struck by an average of 29 zeptobales of cocaine per second” and the average income of a typical acre of Florida land derived from falling bales of cocaine.)

So if you like the absurdum part of reductio ad absurdum, you’ll like What If?

Posted by pjm at 9:21 AM | Comments (0)