Skip to content

Hacker School, Week 2

2013 June 25
by Richard Harrington

tl;dr a lot of stress about whether to try to make something practical, or whether to dive into totally new things that had no guaranteed practical value and that I had no idea whether I could complete by the end of the summer

Over the weekend before Week 2, I tried to read a little of the book Types and Programming Languages. I was looking forward to the arrival of Lindsey Kuper, the first of the summer residents, who is a PhD graduated student in programming language theory and had promised to help us with our reading group for that book.

So I spent most of the week continuing to read The Little Schemer, working on my little monkeys web page (which took an irritatingly long amount of time), and trying to read through TAPL. The first meeting of the TAPL reading group got kind of bogged down, mostly by me, in a basic discussion of what induction proofs are, which, as Lindsey pointed out, is not actually as interesting as discussing type systems.

As the week wore on, I grew increasingly stressed out about the fact that I wasn’t doing any coding, and that I didn’t know what I was going to do for the summer. I had a vague idea that I wanted to “learn Clojure,” but no specific project I wanted to tackle with it. I had some JavaScript projects I’d half-finished in the past (draw.jit.su, turtleherder.com) that I could pick up again, but I’d been advised to start something totally new at Hacker School — something I’d never thought of before I got there — and I was inclined to follow that advice.

The problem was, I’d thought it would all come to me magically and I’d be coding along in a field of intellectual and creative bliss, but instead I was struggling through things that seemed to take an inordinately long amount of time (TAPL book, my freaking monkey website), and not coming any closer to any big project ideas.

On top of that, I was getting increasingly anxious about finding a good job at the end of the summer. I saw (or seemed to see) people all around me working on practical projects that could be applied directly to their careers, using the latest libraries, and I felt maybe I should do that. For me, as a front-end developer, that would mean extending my knowledge of JavaScript and its related libraries, and working on some kind of medium- or large-scale web app. All this study of programming language theory, and learning Clojure, seemed unlikely to move me in that direction. On Tuesday, or Wednesday, I forget, I started to feel seriously claustrophobic in the Hacker School space and had to go down to Hudson River Park (which is very close to here) to lie on the grass for a while.

Later that day I went on a long walk with one of the facilitators, Mary Rose Cook, to talk out these issues, and she strongly advised me to err in the direction of tackling hard tasks that I might possibly not complete but that would certainly make me a better programmer, rather than making sure that I come out of Hacker School with a portfolio piece. That is the general vibe here at Hacker School — that the purpose of the place is to make you a better programmer, not to help you make things that you would have been able to make elsewhere, whose only difference from your previous work is primarily in content.

I thought about it a lot and I decided to go for it. I’d do a project in Clojure, a language that, as a front-end developer, I would probably not be using professionally when I got out (yes, I know there’s ClojureScript — we’ll discuss that later). Now I just needed a project. With any luck, I could come up with something that would satisfy both goals above: it would make me a better programmer, and it would be something I could show to the world.

The last official day that week, Thursday, Lindsey helped a few of us build a simple lambda calculus interpreter (kind of like the last chapter of The Little Schemer), which was pretty cool and gave us a sense of accomplishment.

Then in the afternoon, there was a talk about jobs by David Albert, one of the founders, the gist of which was, try not to think about them yet if at all possible. It was a lot of the same stuff I’d gone over with Mary earlier that week.

And finally, there were the presentations. Every Thursday afternoon there are presentations at Hacker School. I presented my monkey website and showed a little bit about how to refactor code to eliminate mutable variables, which was fun, and I saw a presentation by one of my fellow Hacker Schoolers about robots that could manouver around on the floor. It got me thinking about a game I used to play when I was a kid, called Robotwar, in which the players program robots using a language that comes with the game, and then they send them against each other in virtual battle. Screenshots and description can be found here. The language is sort of a combination of BASIC and Forth, but way stripped down. I thought, I wrote an interpreter today. Maybe I could recreate this game, and write an interpreter for it in Clojure, and use real robots!

I came in the next day (Friday) to flesh out the idea with Mary Rose Cook, and decided that I probably ought to stick with virtual robots, at least for the first incarnation. I’d do the project in steps, with each step being an accomplishment in and of itself. First just build the language interpreter, then display one robot using ASCII art in a terminal, then pit them against each other, then perhaps port it to the browser with ClojureScript, make it a real website with networking and everything, then maybe use real robots, then maybe have them programmable in other languages, like Scheme, etc. etc. etc.

But first, I’d spend some of the following week doing tic tac toe and Game of Life, in Clojure, just to warm up.

Hacker School, Week 1

2013 June 25
by Richard Harrington

tl;dr a lot of studying and meeting new people, not much coding — yet

So the first week was all about meeting people, studying, and pairing with other people on their projects. There are 70 of us in there, in a space that would be ideal at 50 or 60. So it’s a little crowded at times, although usually it doesn’t bother me.

It was, in fact, so fun talking to other folks about their lives and what they wanted to do at Hacker School, and having long conversations about programming over lunch, that I didn’t end up writing any code the first week.

Before the batch began, there was a lot of talk on the forums about pretty esoteric computer science topics, like type system theory. Since I’m a self-taught programmer, that is definitely my weak spot, so I got kind of excited about all the online classes I could go through with my fellow Hacker Schoolers, and all the books I could read that I never would have read on my own. When I got there, I started going over the last two chapters of The Little Schemer, line by line, with one of my fellow Hacker Schoolers, and I joined a reading group for a graduate-level book called Types and Programming Languages, by Benjamin Pierce. I also made my way through the first couple chapters of Programming Clojure, by Stuart Halloway and Aaron Bedra, because my stated goal for the summer was to learn Clojure. I’d done a few tutorials a few months ago in a half-assed way and I knew some Scheme, but I was mostly starting from scratch.

Hacker School is Monday through Thursday, but I ended up coming in on Friday (and in fact, I’m come in every Friday since then for the last three weeks), and at about 4pm, I got kind of freaked out that I hadn’t written any code, and I started writing a basic HTML page with some JavaScript behavior, just to be doing something. (The final version is now at http://turtleherder.com/monkeys.)

On the Difficulty of Finding Time to Record First Impressions of a Project

2013 June 23
by Richard Harrington

From time to time in my life, I’ve found myself immersed in a new project in a new place with a new group of people with whom I knew I’d be spending a great deal of time. And I’m not talking about jobs; I’m talking about those times when a bunch of people come together and start something at the same time, not having known each other beforehand, eager to engage with each other in some new endeavor. High school, college, my junior year abroad, various plays and theater workshops over the years — all of these things were wildly different but in some ways followed a similar trajectory:

I have certain expectations before I arrive. Then I get there, and I am completely consumed — new people to meet, new plans to make (and old plans to drop), a whole new world to take in. Things change a lot in those early days, from week to week. Then somewhere in the middle or after the end of the experience, I’d look back with amusement at some of the things I had thought when I’d first gotten there about the people, the physical space, and what I’d get out of it.

I haven’t been through anything like this in years, until three weeks ago, when I started Hacker School. I was very much looking forward to it, and having made the above observation about first impressions, I resolved to keep a journal of them, so that I could look back on them later.

Of course I did not do this. And I’ve realized now that such a thing would be impossible, at least for me. I get too wrapped up in that initial rush of the new to stop to write anything down. I’ve been spending long days at Hacker School, and sometimes long nights at home coding, or studying, or otherwise following various thought trails that I started down during the day, in some intense conversation with a fellow Hacker Schooler in that crazy office space over on Varick Street. I haven’t even blogged about anything I’ve actually done there, until now — only managed to describe the process leading up to it, in my previous post.

And though assiduous readers of this blog will have noted that I have more than once gone several months without making a post, I’d like to have a solid record of what I did in Hacker School, and so I’m going to jot down quickly what I did for each of the first three weeks, and then keep a more detailed day-to-day record, if only for my own sake when I look back on this all and wonder, what exactly did I do in the summer of 2013?

Hacker School

2013 June 16
by Richard Harrington

This past February, in a bar after a meeting of the LispNYC group, someone mentioned a place called Hacker School. I’d briefly heard of it about a year before, but all I knew was that it lasted three months and was full-time, during the day. I’d dismissed it out of hand as a training program that might teach me a few things, but would be far too expensive to be worth whatever benefit it might give me over what I would learn just by working as a programmer.

The picture that was painted for me in that bar, though, sounded idyllic. It was not, in fact, expensive. No money changed hands at all. And it also wasn’t a training program. It was just a place to go to work on whatever you wanted to work on, surrounded by about fifty other programmers with a wide range of experience, all selected for their intellectual curiosity, and all working on their own projects. There were no instructors, but instead there were “facilitators,” who provided just enough structure to keep you on track, and occasionally they brought in experts in the field to be residents for a week or two. If you ever had a question about anything, or wanted someone to collaborate on a project with, someone in that diverse group would surely be able to help you.

And to top it all off, at the end, Hacker School helped you find a job. It was like a hippie artist’s commune, which after three months magically transformed itself into a career placement service.

Now, before I started actually working as a software developer, I’d imagined that working in the industry would be a bit like my description of Hacker School above. It sounds absurd, I know. But I had come to really enjoy programming in my spare time in the previous few years, and had the delusional belief that doing it for a living would just be a paid version of that.

Of course, that’s not the way it turned out. Which is not to say anything against my recent place of employment — I was learning a lot there, but the nature of ALL work is that you’re usually asked to do things you know how to do well, not things you don’t know how to do at all but which will allow you to make great leaps in your understanding if you take them on. And the Catch-22 is that to make advances in your career, you’ll need to make those great leaps. Which is probably one of the reasons people in the programming world move around so much.

On the way home from the bar, I was giddy. I did a quick Internet search to confirm that Hacker School was as it had been described to me, and then I decided to go. Before the next batch started in June, I’d have just enough time to save up almost enough to live on for the summer.

I am not normally a person who makes major life decisions lightly. I’d only just the previous year quit a job I’d had for fifteen years, and I’d only had my new job and my new career for about seven months, but Hacker School seemed like exactly what I needed to push myself to the next level as a programmer. Not to mention it sounded incredibly fun.

So later that spring I applied, made it through the (quick and efficient) interview process, quit my job, and here I am in the middle of June, two weeks into Hacker School.

Which I’ll tell you all about in the posts to come…

window.postMessage

2013 January 16
by Richard Harrington

Some time ago at work, one of our partner companies needed us to use an iframe because our users needed to type their usernames and passwords for their accounts with that partner into our website, but our partner didn’t want us to have access to those usernames and passwords. So they asked for the whole thing to be conducted in an iframe, served by them but embedded in our site, and then their iframe would pass a token to us, which we could use to query their site for the user’s information.

At first they tried to pass the token by having us implement a globally available function called “setToken”, and then once the user had typed in their username and password and the server had converted those into a token for us to use, they would call the “setToken” function in our page from inside their iframe, like so:

parent.setToken(token)

And our “setToken” function would have looked something like this:

window.setToken = function(token) {
    // some code
    someDataStructureInOurSiteSomewhere[someUserId] = token;
    // some more code
}

(Note that we could have said just “setToken” or “var setToken” in place of “window.setToken” and it would have had the same effect for most intents and purposes — it would be declaring a global variable — but I like to make it absolutely clear when I’m polluting the global namespace, by explicitly stating that I’m adding a property to the window object).

Many of you will be aware, as neither I nor my counterpart at the other company was, that the above strategy won’t work at all. When two frames are being served from different domains, there are serious security concerns that prevent one frame from simply going into the other frame and executing one of its functions, such as “parent.setToken.” Not only can you not execute functions, you can’t even send messages in the form of strings. These are the same security concerns, in fact, that led our partner to insist on this iframe arrangement in the first place.

So what do you do if you need to pass information back and forth between frames being served from different domains? I did a bunch of research and discovered a crazy array of hacks to get around this cross-domain problem, most of which compromise security to one degree or another. They are well catalogued in this blog post.

But part of the HTML5 specification is a message-passing system intended specifically to address this very issue, centered around the window.postMessage method and its associated events. This method is supported by Firefox, Safari and Chrome going back pretty far, and IE back as far as IE8, which is all I have to support on the two projects I have going at work (and certainly in my own side projects).

Using window.postMessage, one frame can send a message to another frame as long as it can correctly identify the origin (the protocol plus the ‘//’ plus the domain, i.e. ‘http://www.somedomain.com’) of the target frame. The target frame then has to have a listener set up for ‘message’ events. The message event contains the message itself (which can be an object in decent browsers but must be a string if you want it to work in IE9 and below), and it also contains the origin of the sender, as well as a reference to the sender’s window object. The value of both of these last two things can be verified by the recipient, for added security.

The best description of how this works can be found here, and the full rundown on browser support can be found here (make sure to click on “Show all versions”). Last but not least, I have made a simple demo myself, which can be found here.

When the user clicks on the button to run my demo, the parent frame sends a message to the child frame, which prints a message and sends another one back to the parent frame. Here are the essential bits from the code for the demo:

1) The code in the parent page, html then JavaScript:

<button id="runDemo">Run the demo</button>
<iframe id="inlineFrame" src="http://childdomain.com/index.html"></iframe>
<p>
    After the child received the message, 
    it sent the following response back to the parent: 
    <span id="responseFromChild"></span>
</p>
var childOrigin = 'http://childdomain.com';
var childWindow = document.getElementById('inlineFrame').contentWindow;
 
// Listen for the response from the child
window.addEventListener('message', function(event) {
 
    // This 'if' block is optional, but good for security.
    if (event.origin !== childOrigin || event.source !== childWindow) {
        throw new Error('The domain of the child does not match 
                what the parent thought it was going to be.');
    }
 
    // Show that we've received the message
    document.getElementById('responseFromChild').innerHTML = event.data;
 
}, false);
 
// Activate the button
var demoButton = document.getElementById('runDemo');            
demoButton.addEventListener('click', function() {
 
    // Post a message to the child window
    childWindow.postMessage('Child, heed my call.', childOrigin);
 
}, false);

2) The code in the child page, html then JavaScript:

<p>
    Here is the message the child received from the parent: 
    <span id="messageFromParent"></span>
</p>
var parentOrigin = 'http://parentdomain.com';
var parentWindow = window.parent;
 
// Listen for the message from the parent
window.addEventListener('message', function(event) {
 
    // This 'if' block is optional, but good for security
    if (event.origin !== parentOrigin || event.source !== parentWindow) {
        throw new Error('The domain of the parent does not match 
                what the child thought it was going to be.');
    }
 
    // Show that we've received the message
    document.getElementById('messageFromParent').innerHTML = event.data;
 
    // Post a message back to the parent window
    parentWindow.postMessage('Right back atcha.', parentOrigin);
 
}, false);

And a Happy New Year to all!

The hurricane

2012 November 1
by Richard Harrington

This post will be somewhat OT from learning programming.

Hurricane Sandy came through a couple days ago. It had the name of my mother and it hit on my father’s birthday. My family has never otherwise been cursed, though.

I got to my apartment in the East Village of Manhattan (below 14th Street) before the subways shut down preemptively at 7 pm on Sunday, and my girlfriend and I stayed there for three nights. On Monday night the power went out (we actually heard the explosion at the Con Ed plant on 14th Street and the river, which caused the power outage). 

By Tuesday, the worst of the actual weather was over. The amount of rainfall itself was never really anything — it was just very windy all night on Monday. Then we went over to the East River Tuesday morning, and we saw what the real problem had been: the water line (left by leaves and debris) on the cars and buildings during high tide had been about two or three feet high as far inland as Avenue D, which is a few hundred yards from the river.

Everywhere on the island below 38th on the east side and 34th on the west had no power (and still doesn’t). A friend texted us before our cellphone batteries ran out, and we walked up to his apartment on East 54th Street to charge our devices, then headed back down for the night, where it was really quiet and peaceful. We stopped at a couple bars and restaurants on our way home that had candles out and were selling beer, but later in the apartment it started to be a little creepy. There were no lights on in any of the apartments across the street, even candles.

Yesterday morning (Wednesday) my girlfriend went to work, and I threw away all my food, packed my stuff into a suitcase, and made my way uptown to her apartment to join her there after work. There was total gridlock all the way. I took buses for a while but then walked because it was faster. I’m now here at her apartment in Inwood (northern tip of Manhattan), where it’s warm, and there’s power, and it’s like nothing ever happened. I feel survivor’s guilt for getting out of my neighborhood when so many others don’t have people they can stay with elsewhere (not to mention all the people stuck in the REALLY hard-hit places like Staten Island, Long Island, the Rockaways, and the Jersey Shore), but then I realized that it’s good for me to be gone from there if I can. If the power doesn’t come back soon, things will get desperate down there, and I’d just be a drain on resources.

On that note, stay safe, everyone.

Richard

Story Hack 2012

2012 October 17
by Richard Harrington

Over the summer, I participated in a hackathon called Story Hack (that’s me on the far right), run by an organization called Story Code, dedicated to “supporting, incubating and showcasing projects created by independent immersive and cross-platform storytellers.”

I wasn’t sure what that meant, but the project was really fun. It was actually kind of a two-weekend affair — the primary event was the second weekend, but there was an orientation on the first weekend for the core participants, and some members of the team had several more meetings during the week and actually shot a video.

Unlike most hackathons, this one was focused on storytelling, and was held at Lincoln Center. I get the feeling Story Code is made up mostly of film people who are trying to look at the big picture and figure out what the next dominant incarnation of the art of storytelling will look like, as film slowly morphs into its successor. But maybe that’s just me.

Because it was all about narrative and the use of different platforms to tell a story, some amount of theatricality was encouraged, but most teams still made their presentations more like pitches for products that had not been completely built yet. Ours was a show from beginning to end, complete with a post-apocalyptic storyline with MCs, a hilarious website (futuremate.us), a Twilio setup that connected random members of the audience to each other in conference calls (front-end manifestation at futuremate.us/speed_date.html — it’s a little buggy but you can see what it was supposed to do, and it went by quickly during the presentation so it served its purpose), and then a giant mutant zombie puppet as a deus ex machina at the end (operated by me).

We won the first prize of $1,000. Many of our competitors’ tech elements were as impressive as ours, but only we were in character during our entire presentation.

Now granted, most hackathons are not like that one — they’re not explicitly about narrative, they don’t give you ten minutes for their presentation, and they have more than eight teams. But I would suspect that at any hackathon, all else being equal, judges will give consideration to a project whose presentation was fun for the audience to watch, and participate in. Because we all know those presentation sessions can be pretty deadly, especially for the half of the audience who hasn’t slept.

Something to think about, anyway.

The triangle problem

2012 October 7
by Richard Harrington

Recently I had to hire someone to help me out at work, and I was running the interviews, which I’d never done before.

My two co-workers (Ruby guys) told me that when one of them had been interviewing to work at our company, he was sent an exercise to complete. My other co-worker was already working there. He had tried the problem also, and had come up with a long, convoluted solution. So when the new guy emailed back with something that was about fifteen lines long, they hired him.

Here’s the problem: You have a triangle of numbers, like

     1
    4 3
   1 9 7 
  1 1 5 9

and the question is, what is the greatest of all the sums that you can get by tracing a path of adjacent numbers from the top of the triangle and adding one number per row as you go down the rows?

For instance, in this case the answer is 20: the sum of the numbers 1, 3, 7, and 9, tracing a path down the right edge.

(On the github page which goes along with this blog post, a text file called ‘triangle.txt’ is provided for this exercise which has 100 rows, too many to calculate without automating it. The answer to the problem for that text file is 732506.)

Before looking at either of my co-workers’ solutions, I tried it myself and thought I had come up with a pretty elegant solution using recursion and memoization to calculate all of the possible answers and store the partial ones as it goes along so it doesn’t take forever. The array it creates is, instead of numbers, an array of objects, where each object is a node in a tree containing pointers to the next two nodes down, as well as the value of the current node.

Here’s my code. It is intended to be run in Node.js on a file in the current directory, but you could change the beginning a little bit and run it on a string or something in the browser:

var fs = require('fs');
 
var max = function (file) {
 
  var text = fs.readFileSync(file, 'ascii');
  var array = text.split('\n').map(function(row) {
    return row.trim().split(' ').map(function(word) {
      return { num: parseInt(word) };
    });
  });
 
  array.forEach(function(row, i) {
    row.forEach(function(node, j) {
      var next_row = array[i+1];
      if (next_row) {
        node.left = next_row[j];
        node.right = next_row[j+1];
      };
    });
  });
  var root = array[0][0];
 
  return (function walk_tree(node) {
    if (!node) return 0;
    if (typeof node.memo_sum !== 'undefined') return node.memo_sum;
    node.memo_sum = node.num + Math.max(walk_tree(node.left), walk_tree(node.right));
    return node.memo_sum;
  })(root);
 
}  
 
console.log(max('triangle.txt'))

Then I looked at my co-worker’s solution, which is here (I have slightly modified it and translated it from Ruby to JavaScript, but this is the basic gist). It turns the triangle upside down and goes through it from the wide top to the single-element bottom, replacing each number in the triangle with the partial results based on the ones above it:

var fs = require('fs');
 
var max = function (file) {
 
  var text = fs.readFileSync(file, 'ascii');
  var array = text.split('\n').map(function(row) {
    return row.trim().split(' ').map(function(word) {
      return parseInt(word);
    });
  });
 
  array.reverse();
  array.forEach(function(row, i) {
    row.forEach(function(num, j) {
      if (i > 0) {
        var previousRow = array[i - 1];
        row[j] += Math.max(previousRow[j], previousRow[j + 1]);
      }
    });
  });
 
  return array[array.length - 1][0];
}  
 
console.log(max('triangle.txt'));

His was a lot shorter than mine, and more elegant. It was a lesson to me: recursion may seem cool, but it’s not always the best idea.

However, taking it up where my co-worker left off, I was able to make his version even more elegant by using the reduceRight array method, thus making it more pure, functional-programming-wise. My new function starts from the bottom of the triangle and works its way up, constantly updating an accumulator (called ‘sumRow’) that is a row of partial results, but it doesn’t touch the original array:

var fs = require('fs');
 
var max = function (file) {
 
  var text = fs.readFileSync(file, 'ascii');
  var array = text.split('\n').map(function(row) {
    return row.trim().split(' ').map(function(word) {
      return parseInt(word);
    });
  });
 
  return array.reduceRight(function(sumRow, row) {
    return row.map(function(num, i) {
      return num + Math.max(sumRow[i], sumRow[i + 1]);
    });
  })[0];
 
};
 
console.log(max('triangle.txt'));

As an exercise, I made versions of all these files in JavaScript, Ruby, and CoffeeScript, to see how they compared. You can see them on the github page. On that page I also added one final version in CoffeeScript which uses comprehensions to make it incredibly short, although it’s a little hard to read, I think. I’ll give it the benefit of the doubt in this case, though, and assume that I just don’t know how to write proper idiomatic CoffeeScript yet:

fs = require 'fs'
 
max = (file) ->
 
  array = ((parseInt word for word in row.trim().split(' ')) for row in fs.readFileSync(file, 'ascii').split('\n'))
 
  result = array.reduceRight (sumRow, row) ->
    num + Math.max sumRow[i], sumRow[i + 1] for num, i in row
 
  result[0]
 
console.log max 'triangle.txt'

Turning a cruise ship

2012 October 7
by Richard Harrington

tl;dr I found a job!

During the six-month hiatus between the last blog post and this one, I quit a job I’d been at for fifteen years, and ventured into the new world (for me) of programming professionally. It wasn’t easy. At times I felt like I was trying to turn a cruise ship. And I couldn’t really blog about the process because of the whole don’t-let-your-boss-see-your-job-hunting-blog-post thing.

It took a bit longer than I expected, but here’s how I did it, in a nutshell, in case you’re thinking of making a similar move:

  1. I found a problem in my life that could be eliminated (or ameliorated) by using software. I was on a co-ed soccer team at the time, and we were sending each other 80 emails each week trying to make sure enough people were going to show up for the game, so I taught myself PHP and MySQL and made a simple attendance website. You can still find a demo version at turtleherder.com/bobcats. Feel free to mess around with it — it’s a fake team.
  2. I was working as a print designer, so I spent the next couple years slowly learning JavaScript for InDesign. (Adobe uses it as an embedded scripting language for all its products.) I made life easier for myself and my co-workers by automating a lot of already-existing tasks and coming up with new workflows that couldn’t even have been done without scripting.
  3. I’d dabbled in web design pre-CSS, but I’d let my skills lapse, so I started getting them up to date again: HTML, CSS, the DOM and all the fancy new object-oriented JavaScript techniques to go with them.
  4. I started to think about making the jump into programming as my primary living, but I suffered a bit of an existential crisis for a while, in that I was afraid it was going to take over my mind. I enjoyed programming, but I got very intensely focused on whatever project I was working on, and I was afraid that I wouldn’t be able to turn it off at the end of each day when I got home from work. I resolved this issue by talking to a lot of working programmers. I met some people around the country who worked remotely and seemed to have a good work-life balance, and also a lot of people at tech Meetups in New York. Eventually, I decided I would be able to handle it. As indeed I have.
  5. Once I got over my existential issue, I took a couple classes in JavaScript at the NYU School for Continuing and Professional Studies. The first one sucked. I’m not sure why I took the second one, but I did, and it was awesome. That class got me excited to be a programmer.
  6. Three months after the end of the inspiring class, at the beginning of 2012, I dropped my hours at work down to two days a week and started spending all my free time studying programming (JavaScript, HTML and CSS mostly), going to Meetups and hackathons, and working on side projects, the main one of which was a multi-user drawing program (using Node and Socket.io) based on a static version we worked on in the aforementioned class. That can be found at here (with code here).
  7. Last but not least, I wrote a resume and started slowly looking for jobs. It took me months just to get around to writing the resume itself — the psychological block that gets built up around that after fifteen years at the same job is quite formidable — but eventually I did it, and then I made a blitz, both on my own and through recruiters. One week in late May I went to six interviews, the last of which was four and a half hours long. I got a few rejections, but just when my savings were almost gone (going down to two days a week had been a calculated risk that began to seem a little scary towards the end there, financially), I ended up with two offers for half-year contract positions. I took the one that was the smaller company, 35 minutes closer to my house, $5 more an hour, and had a pit bull puppy in the office.

The job turned out great, but that’s a topic for another post. I’m over half-way through it now, and looking for my next gig. Whatever happens, I’m sure the process will be a piece of cake this time, in comparison.

Roman numerals

2012 April 10
by Richard Harrington

When anyone mentions a coding exercise they had to do for an interview or a class, I have a habit of getting it stuck in my mind and having to go home and work it out myself.

One of my co-workers, a reporter, has recently started to teach himself Ruby. He took a Java class in college and always had a kind of hankering to get back into programming, so when he and his girlfriend had a fight about chores, he decided to make a web app to help them figure out who was doing what, and to keep track of compliance and send email reminders. Everyone who’s looking for the motivation to re-learn programming needs some precipitating excuse, and that’s his, apparently. Certainly as good a reason as any. He’s been going through a Ruby book meant for the absolute beginner to programming, “Learn to Program,” by Chris Pine.

Yesterday he (my co-worker, not Chris Pine) mentioned that he was working on an exercise to convert Roman numerals into Arabic notation. He was having some trouble. I don’t know Ruby (it’s next on my list), but I went home that night and figured it out in Javascript.

My basic realization for the central algorithm was that all you need to know to add up Roman numerals (in their standardized modern variety anyway) is that the value of each letter is added to the total, unless it’s worth less than the one after it, in which case it gets subtracted from the total. That’s the simplest way to compute it, anyway.

Alternatively, you could go through the two-step process of identifying one- and two-letter sequences (like ‘X’ and ‘IV’) and then adding them. One could argue that that’s easier to read because the one- and two-letter sequences map very well conceptually to the Arabic notation that we think in.

Which would be an interesting question to ask an expert, but in the meantime, here are two solutions that are as concise as I could make them without getting into obnoxious trickiness for its own sake. The first one uses a classic ‘for’ loop, and the second one uses the more elegant functional programming methods map and reduce from the ECMAScript 5 spec, which you unfortunately can’t count on being available in every browser, but are pretty awesome:

The For Loop Version

var romanToArabic = function(romanNumeral) {
  var numberMap = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 },
      sum = 0,
      i, len, num, nextNum,
      romanNumeralArray = romanNumeral.split('');
 
  for (i = 0, len = romanNumeralArray.length; i < len; i++) {
    num = numberMap[romanNumeralArray[i].toUpperCase()];
 
    // Check to see if we're at the end of the array, and if so,
    // set it up so the last element will be compared to zero.
    nextNum = (i + 1 < len) 
      ? numberMap[romanNumeralArray[i + 1].toUpperCase()]
      : 0;
 
    // The value of a letter in a roman numeral gets added to the 
    // running total unless it's less than the value of the one 
    // after it, in which case it gets subtracted.
    sum += (num < nextNum)
      ? num * -1
      : num;
  }
  return sum;
}

The Functional Programming Version

var romanToArabicMoreConcise = function(romanNumeral) {
  var numberMap = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 };
 
  return romanNumeral
    .split('')
    .map(function(romanDigit) {
      return numberMap[romanDigit.toUpperCase()];
    })
    .reduceRight(function(sum, num, i, array) {
 
      // The value of each letter in a roman numeral gets added 
      // to the running total, unless it's less than the value 
      // of the one after it, in which case it gets subtracted. 
      // (If it's the last element, it gets compared to zero.)
 
      return sum += (num < (array[i + 1] || 0))
        ? num * -1
        : num;
    });
}

Explaining map and reduce is beyond the scope of this blog post (try here instead), but just notice that there are no local variables in the second version, except the number map itself, and the function arguments. I find that easier to read, personally. Fewer things to keep track of in my head.

After I completed this post, I noticed that there’s an entire website devoted to answering a wide range of simple programming exercises in like a thousand different languages. And yes, of course this one’s there. Check out the ones for JavaScript and CoffeeScript (a language that compiles down to JavaScript — see this post) and see how they differ from mine.

Then check out the Ruby version:

def fromRoman(roman)
  r = roman.dup.upcase
  n = 0
  until r.empty? do
    case
    when r.start_with?('M')  then v = 1000; len = 1
    when r.start_with?('CM') then v = 900;  len = 2
    when r.start_with?('D')  then v = 500;  len = 1
    when r.start_with?('CD') then v = 400;  len = 2
    when r.start_with?('C')  then v = 100;  len = 1
    when r.start_with?('XC') then v = 90;   len = 2
    when r.start_with?('L')  then v = 50;   len = 1
    when r.start_with?('XL') then v = 40;   len = 2
    when r.start_with?('X')  then v = 10;   len = 1
    when r.start_with?('IX') then v = 9;    len = 2
    when r.start_with?('V')  then v = 5;    len = 1
    when r.start_with?('IV') then v = 4;    len = 2
    when r.start_with?('I')  then v = 1;    len = 1
    else
      raise ArgumentError.new("invalid roman numerals: " + roman)
    end
    n += v
    r[0 .. len-1] = ""
  end
  n
end

Looks a little repetitive in the middle there. I bet it’s possible to write something a bit more succinct — Ruby people are always saying that you could write a fully-featured word-processing program in seven lines. I guess I’ll find out when I learn the language myself.