#SpillingMeSoftly

I’ve posted my data visualization of over 1700 pipeline spills in the US. It’s a fun single page app called “SpillingMeSoftly,” complete with a time slider to see the spills pop up over the course of 4 years. Try it now and be depressed all day!

Featured image

Choosing an Effective Whiteboard Problem

Whiteboard problems are like tests – hard to take, even harder to write well.

Scratch that. A whiteboard problem is a test. And like any test, its success is based on how well it reveals the capabilities of the person taking it. A bad whiteboard problem is therefore worse than none at all. It may show a competent person to be incompetent, or worse, allow an incompetent developer to appear capable. Why is that worse? Because if a good developer doesn’t get a job, that’s a tragedy for them. If an incompetent one does get a job, that’s a tragedy for their entire team.

Before I became a developer, I was an expert in adult education, writing such great books as How to Teach Adults, and How to Teach Adults, 2nd Edition. So I’ve done some deep thinking about tests. My conclusion is that the purpose of tests is not to make people fail. Their true purpose is to show how much people are capable of under pressure. With that in mind, I’d like to cover here what makes an effective whiteboard problem. I hope this is of value to founders at startups building their first-10 team, veteran recruiters looking for a new perspective, and other junior develoeprs looking for insight beyond “Here’s How to Hack Your Whiteboarding Session.”

So what does a whiteboard problem test?

Background Knowledge
This is low-hanging fruit, but important fruit. (Note to self: improve this metaphor later) Make a list of terms and concepts – stacks, factorial time, etc. – that succesful employees for the position for which you’re hiring must know. Then use them throughout the whiteboarding session. If the applicant doesn’t understand them, that’s a big red flag.

Clarity of Thought
How does the applicant approach the problem? Do they solve it by rote because they memorized the answer? Do they go at it by throwing darts, trying different ideas until one sticks? Do they waste time solving for complex edge cases first? Do they even ask about edge cases?

A good whiteboarding session is an x-ray into the applicant’s brain. Pro-tip: If the applicant works silently, give them a prompt or two to verbalize what they’re thinking. Speaking of which…

Ability to Communicate
“Without clear thinking there can be no clear communication.” A whiteboarding session is an applicant’s chance to show how good they are at communicating, and, therefore, how smart they are at thinking. (Note to self: Change blog tagline to “smart at thinking”)

In all seriousness, clear communication is the heart of effective collaboration. It’s been said that your success in technology is directly proportional to your ability to accurately communicate about technical ideas. Watch how well the applicant does when it comes to talking through their general approach, their understanding of edge cases, where they are in their mental state and so on.

Problem Solving
This goes without saying. Decide how much of the problem(s) applicants must be able to solve. Should they be able to solve the first one, then solve the base case for the second one and ID all edge cases? The above factors are important to better weed out people who have just memorized a book of interview algorithms. But at the same time, if applicants can’t solve problems to the degree that you need, they’re probably not a good hire.

Grace Under Pressure
I learned this one in the dojo. The whole point of testing, as my sensei once taught me, is to see how well people can perform under pressure. So make sure to apply some pressure. If an applicant looks like they’re solving the problem a bit too easily, it is your obligation to give them a challenge.

This may be as simple as telling them to solve for an edge case first. Check their response: To get riled up? To totally lose track of what they’re doing? To politely ask if they may continue with their approach before returning to the edge case?

The point is not necessarily for them to jump up, salute you and say “Yes, sir!” (unless you’re Jeff Bezos) Instead, see how they respond to the pressure. This is the person you may be working with through deadlines, server outages, and other crises. If they can’t handle a little pressure in the interview, you probably shouldn’t hire them.

In Conclusion
Whiteboarding is an important part of the hiring process. Make sure it serves that purpose by carefully choosing a problem that allows the applicant to demonstrate their knowledge and problem solving ability. Then see how well they can think, and communicate about what they’re thinking. Finally, make sure they can do all this under a little bit of pressure.

If you follow these steps you’ll be better than many, if not most people who present whiteboard problems. Who knows? You might even find the best person for the job.

Zen Programming: Gulp from the Ground Up

Young me in Japan.

Young me in Japan.

I’m no Zen Buddhist. I live in the material world, chasing productivity and happiness like almost everyone else. But, from having grown up partly in Japan, I respect Buddhist ideals – particularly perhaps the most challenging one of all: detachment.

So I was pleasantly surprised to spend an entire day in what felt like a Buddhist exercise with my development team. We’re building a web application to help people with their personal finances. In the past, when jumping into a big project, I would simply download Bootstrap and run with their beautiful and reliable default settings. After all, that’s the fastest way finish your app!

Not this time. Our team of four collectively decided we were going to build things from the ground up as much as we could. That offered several powerful advantages: First, we would understand everything we were doing. No more running default packages (with their default settings) and crossing our fingers! We could go line by line through our project’s base DNA and explain every bit of it.

Perhaps more importantly, our project would run faster and be more reliable as a result. It would include only what it needed and no more, thus reducing opportunities for conflicts to break it.

And that’s how we spent hours and hours on our Gruntfile.js. To those who don’t know, Grunt is an amazing tool for automating tasks while developing. It allows continuous testing and concatinating of your code while you write it, among many other things. In the past I ran with whatever default Grunt (or it’s still-popular predecessor, gulp) file my project came with before customizing it or, more likely, ignoring it altogether.

But not this time. I am fortunate enough to be working with three incredibly talented developers, and, with the help of MadEye, we went through our Gruntfile.js, adding to it and debugging it, figuring out specifics (like why it wouldn’t seem to work with Angular) while getting a better feel for our developing process overall.

This might not sound much like Buddhist meditation. But the two have a lot in common. In Zen Buddhism, meditation is hard work. If you lose focus, your master hits you loudly with a bamboo stick. (Another important part of Buddhism is not running away from pain.) Our team worked hard and got hit the “it didn’t work stick” time and again.

In the end, we didn’t achieve enlightenment. But we did get a Gulpfile that’s custom built for our project, containing everything we need so far and nothing more. Perhaps more importantly, by detaching ourselves from the rush to make something awesome as quickly as possible, we created an opportunity to focus on the process of writing good coding.

This is our Gulpfile.js. There are many others like it, but this one is ours.

var gulp = require('gulp');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var annotate = require('gulp-ng-annotate');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var rename = require('gulp-rename');
var notify = require('gulp-notify');
var livereload = require('gulp-livereload');
var nodemon = require('gulp-nodemon');

var paths = {
scripts: ['./client/app/**/*.js', '!./client/app/bower_components'],
html: ['./client/**/*.html'],
styles: ['./client/**/*.css'],
server: ['./**/*.js'],
images: []
};

// Lint Task
gulp.task('lint', function() {
return gulp.src(paths.scripts)
.pipe(jshint())
.pipe(jshint.reporter('default'));
});

// Concatenate & Minify JS
gulp.task('scripts', function() {
return gulp.src(paths.scripts)
.pipe(sourcemaps.init())
.pipe(concat('all.js'))
.pipe(gulp.dest('dist'))
.pipe(rename('all.min.js'))
.pipe(annotate()) // (for angular dependency injection)
.pipe(uglify())
.pipe(gulp.dest('dist'))
.pipe(livereload())
.pipe(notify({message: 'Scripts task complete'}));
});

gulp.task('html', function() {
return gulp.src(paths.html)
.pipe(livereload());
});

gulp.task('styles', function() {
return gulp.src(paths.styles)
.pipe(livereload());
});

// Watch Files For Changes
gulp.task('watch', function() {
gulp.watch(paths.scripts, ['lint', 'scripts']);
gulp.watch(paths.html);
gulp.watch(paths.styles);
gulp.watch(paths.server);
});

gulp.task('livereload', function() {
livereload.listen();
});

gulp.task('serve', function() {
nodemon({'script': './server/server.js'});
});

// Build Task
gulp.task('build', ['scripts', 'lint']);

// Default Task
gulp.task('default', ['build', 'livereload', 'serve', 'watch']);

OrientDB: The First Thing: Literally

I’m day 1 on a new dev team and loving it – and not just because they chose the name I suggested for our project. (More details soon – no spoilers!)

One immediate benefit is that I’m getting to deep dive into OrientDB. I’ve had a long love affair with Neo4j. I believe in graph databases for fast traversals, especially of social data, so I’ve been dying to try out Orient.

Here’s what I’ve found: It’s different than Neo4j. To the point where I struggled to find the console shell.

Because the otherwise amazing documentation doesn’t quite spell it out, here’s where console.sh is to be found when you install OrientDB using Homebrew on OSX:

/usr/local/Cellar/orientdb/1.7.10/libexec/bin

Confusingly, this is not what which orientdb returns. (your version number may vary) Here you will also find backup.sh, server.sh and a handful of other promising looking shell scripts.

I’ll keep you posted on our project. In the meantime, I hope you enjoyed this little ORIENTation. (!)

Lessons in Legacy Code

Archivr_screenshot

Behold the majesty of Archivr!

tl;dr : I inherited legacy code that made my life miserable. Then I learned who the real monster was.

Introduction

I just inherited my first legacy project. It’s a fun, bare bones web app that takes a screenshot of a URL of your choice. Then you can scribble annotations on the screenshot. It was called Archivr. (“Because adding ‘r’ to the end of a word makes it cool.”)

When I saw it deployed on Heroku, my first thought was that, at heart, this app wasn’t destined to help archivists. It was meant to facilitate people scribbling mustaches and cowboy hats on their friends, major buildings, and the Google search bar. And then sharing their scribbles with friends.

I felt a little bad for my friends who created Archivr. But then I had to suffer through the torment that they – unknowingly – inflicted upon me. I’m here to share my hard won lessons to make it easier for readers about to inherit a legacy project for the first time.

About the Author

My name is Dan Tennery-Spalding. I’m an adult educator-turned-developer here in Oakland. I am enjoying the process of making this silly app because 90% of the time I’m the guy who takes things way too seriously. But what I’ve slowly come to learn is that, before I can build kick ass enterprise-level apps to help Doctors Without Borders better treat injured civilians in war torn regions, I’m going to have build my own developer chops first. And the best way to do that is to just build something that works.

I’m working on Archivr at Hack Reactor, a programming boot camp in SF. I’m on a team with three other junior developers. We all want to do a good job. In fact, for much of the last two weeks, we built our own ‘greenfield’ web app that another Hack Reactor team has taken on as their legacy project. (More on that below.)

Our team kicks ass. Our greenfield app used Angular, Firebase and D3 to allow users on mobile devices to swipe on their touch screens to indicate how they’re feeling at that moment. Our motto was, “Swipe your feelz.”

It was a goofy project. And, in the course of creating it, we all learned how to code a lot better. Perhaps more importantly, we learned how to work together as a team, both in formal roles (with a product owner and scrum master) and informally as colleagues hacking together, day in and day out.

On presentation day our greenfield app worked as promise. We were proud that it worked at all, and, in some ways, even more proud at how easy we made it for the next team to pick up. Our work was (relatively) well documented, our code clearly written, and, due to some serious last-minute rebasing by my teammates, the process to clone and launch it were pretty clear.

Enter the Challenger

One of the reasons we chose Archivr was because it was so well documented. Ten pages of wiki docs on GitHub! And the app itself seemed like a lot of fun. It seemed so well thought out that I actually felt bad for taking it in such a goofy direction.

Then I saw what the original Archivr team did to us.

The first hint was when none of us could get the git clone to run on our machines. It turned out the documentation was missing instructions on additional gems to install; it didn’t help that everyone on our team is so much stronger on JavaScript than Ruby.

After that was resolved, there were additional snafus. Conflicting versions of node modules! And more problems we couldn’t even get to the bottom of!

The previous team had also implemented rigorous, continuous Grunt / Travis testing that made it extremely challenging for us to make any changes and see their results. We cursed them on an hourly basis while trying to see what our latest code actually did to the app. For the record, my pal Tole and I struggled with HTML5 canvas technology, coming up with a novel hack using MongoDb and Cloudinary to show both the user’s screenshot (Cloudinary) and the scribble (Mongo!) on top of one another.

Demonstration Day

My entire body was covered in a fine sheen of sweat on demonstration day. To make a long story slightly longer, we got the app working at the last minute. Our presentation went gangbusters thanks in no small part to my love of public speaking and we were proud of our accomplishments.

Resolution

So what was the lesson learned? At first, it was that we were the “good guys” who made our code easy to use, while the people we inherited our code from were a bunch of selfish jerks who were incapable of human compassion.

Two complications to this tidy denouement:
1. One of the original developers for Archivr actually gave us clutch help getting the scribble technology to work. (Thanks, Jackson!)

2. The people who inherited our code didn’t find it easy to work with at all. This surprised me because they were up and running and modifying code within hours. (For the record, they also took it in an irreverent direction, turning out mood-tracking app into a mobile game called “Finger Finger Fiesta.”)

But as they described their challenges using our codebase, it all came back to me, like last night’s dream, our fragments of a blacked out night from a friend’s bachelor party in Las Vegas or Thailand: We had multiple files named app.js, a temp.js file I had used as a notepad and never gotten around to deleting (we were on a deadline!) and a number of unused dependencies we never got rid of.

We’re all monsters. We all leave messes for others, whether those “others” are colleagues who inherit our code, members of the open source community who want to use and improve our work, or even ourselves in three months who have to make sense of work that we have already forgotten about.

I’m a better developer because of this experience. I’m already more diligent about cleaning up my code. But more importantly, I have a new perspective on legacy code. I don’t expect anyone to make their work effortless to pick up. Instead, I know that getting off the ground with a legacy codebase will be as much work as developing new features for it.

The Best Of: Portland

This is the first in a series of posts about the absolute, arbitrarily chosen best of what to do in major and mid-sized cities around the world. (Thanks for getting me to write this, Gabe.)

Just a goatie is all.

Bramble the kid stole our hearts when we visited Tryon Farms.

Best Coffee: Half Pint Cafe

These guys won’t just make you the best cuppa joe you’ll have all week; Marko, the proprietor, will make you feel like a regular from your first trip to the cafe. Pro Tip: Ask for the off-menu espresso drinks. #amaze

Best Noodles: Sen Yai Noodles

Sen Yai is affiliated with Pok Pok, which I consider to be the most overrated restaurant in Portland. But where Pok Pok strikes out – with its high prices, long waits and middling food – Sen Yai hits a home run. Their simple food is outstanding and their drinks are to die for. Order a Tamarind Whiskey Sour for me.

Best Urban Farm: Tryon Farm

Tryon is a breathtaking urban farm right outside downtown Portland. My wife almost cried when she got to hold a baby goat. Me, too. #truestory

Best Camping Gear Store: Snow Peak

People who know quality camping gear may not necessarily know about Snow Peak. This Japanese company fills kind of a quirky niche: Gear that’s expensive and impeccably crafted, but not necessarily the lightest or most extreme. Check out their Portland flagship store to see some boss kit. Sure, it may be better suited for car camping than K2, but you’ll still be happy to see all their beautifully designed stuff.

Best Obligatory Destination: Voodoo Doughnuts

Because everyone will tell you to go. Order the Ol’ Dirty Bastard with a side of insulin.

Best Bookstore: Microcosm

Unbelievable selection of zines as well as smartypants books for days. (What bookstore did you expect me to name?)

Best Portland Outdoor Store: Portland Outdoor Store

Portland may be the hipster capital of the Pacific Northwest, and therefore the universe, but it’s also on the Western edge of the American West. So it’s a mighty good place to buy some sweet western wear. That’s why no trip to Portland is complete without a stop at the creatively named Portland Outdoor Store. There’s the best selection of flannel shirts you’ll ever see, and my better half got me a beautiful belt buckle for our then-upcoming half-iversary. No place in the city is more down to earth and earnest than right here.

Did I miss anything? If so, message me on Twitter – @teachrdan – because WordPress comments are a mess of spam.

Teaching with Storytelling: Linkurious

I went to a cool tech event last night where the presenter nailed one of the techniques I’m always telling teachers to use – and sometimes forget to use myself. “Seb,” or Sebastien, told a powerful short story that perfectly complemented his presentation about Linkurious, his software company that uses graph databases to help financial institutions spot fraud, among other things.

His story described a common way criminals defraud banks:

How to Fraud: 1. Create fake ID, 2. Apply for bank loan, 3. Disappear w/$$$

Courtesy of Linkurious

 

 

 

 

 

 

 

 

This was effective for three reasons:

1. It hooked us. Everyone likes crime, and we all like to find out how it’s committed. It makes us feel like Gibbs from NCIS.

2. It raised the stakes. Especially in technology, so many dumb apps are developed to solve the dumb first world problems suffered by app developers: late-night food delivery, getting a lift to the Marina, etc. This story showed why Linkurious actually matters.

3. It matched his lesson. As Sebastien went through the process of correctly ID’ing a case of fraud, he necessarily explained how Linkurious works.

 

It helped that his slides were so good.  They use legible images and minimal text to illustrate (see what I did there?) the points he was making, like this one, which shows how rings of identity thieves share some of the same personal information, which becomes apparent upon using Linkurious:

How fraudsters share info helps Linkurious ID them.

The techniques that fraudsters share info help Linkurious correctly ID them.

 

 

 

 

 

 

 

 

 

 

I wish more teachers would do what Seb did. A powerful short story – which includes good visuals – will help make your lesson memorable and effective.

Follow

Get every new post delivered to your Inbox.

Join 37 other followers