Stories about Software


Fight or Flight

As software developers, or, more broadly, as techies, we are extremely fortunate. So many people want to give us money and jobs that we find it annoying. Let that sink in for a moment. A serious first world problem that we all share is how many times per week people cold call us to ask us to interview for other jobs. That’s our strange reality and, as someone who graduated with a CS degree right into the teeth of the dotcom bubble bursting, I can tell you that it isn’t the worst problem that one could have. Still, it’s shaped our collective outlook on work and, in my opinion, is pushing us toward free agency in which developers eventually stop having even the pretense of long associations with companies.

But what if you don’t want free agency? What if you don’t want to deal with the hassle of resumes and interviews involving silly brain teasers and other indignities? You can just ignore the recruiters in the short term, but is the writing on the wall for complete deterioration of the traditional association between developers and (non-consultancy) employers? I’ll get back to that.

My girlfriend told me a story once about a guy she had dated years earlier. They were driving down a highway when they came upon a guy broken down and with a flat on the side of the road. He looked like he could use some help. The ex-boyfriend, apparently in an inexplicably foul mood, took note of this situation, leaned out his window while driving by and gestured obscenely at this hapless and now bewildered motorist who was doing absolutely nothing but having a bit of bad luck. This random act of meanness, my girlfriend told me, was the exact moment at which she knew the relationship wouldn’t work out. They dated for a bit after that, but apparently from then on it was pretty much a matter of running out the clock until the inevitable, awkward conversation. It wasn’t as if in that moment she thought “that’s it, this is over” nor was that by any stretch the only problem with the relationship, but it became a defining Moment — a catalyst.

I think there’s a Moment like this in every job that you leave: being passed over for a big promotion, hearing an official announcement that you’re going to be switching everything to VB6, being verbally abused by a superior in a group setting, etc. It’s The Moment at which you know that it’s over and the rest is just details and formalities. I can think back to every job that I’ve had and remember this Moment (or perhaps 2-3 viable contenders) with amazing clarity. In this day and age, few programmers practically think that they’ll be somewhere until retirement, but the idea of leaving the company is some nebulous, abstract, future concept when they start, and it remains that way until The Moment. And then it becomes clear, concrete, and, while still in the future, not far off. Your departure is no longer a class in source code but an instantiated object in process memory just waiting to be triggered and exhibit real, actual behavior.

But what if you don’t want this? What if you’re not interested in moving around and don’t want a long list of one year stays on your resume? After all, if you’re a job-hopper, The Moment is like an old friend beckoning you onto a greener pasture. But if you’re content and more of a permanent worker type, The Moment is probably depressing and terrifying. So how do you avoid it?

Well I certainly can’t give you anything bulletproof, but I can sum it up with a simple mantra that you can hang onto when you’re contemplating taking a job: find a place worth fighting for. Maybe you’re a big advocate of green technologies and you find a job working for a solar panel manufacturing company. Maybe you really like Legos and you go work for Lego. Maybe you go work somewhere that all of your friends work and you’re invested in the camaraderie. Whatever the case may be, you have to find a reason that you’d fight to stay there. If you have that, then The Moment becomes one of galvanization and thrown gauntlets (within reason — if it’s something like harassment or a pay cut, all bets are off) rather than the centerpiece of a future story about why you changed jobs, anyway. When those Moments come, like a random driver with rage issues — and they will come — it’s fight or flight. And if you’re not willing to fight, it’s going to be flight.


Imagine a Process Regression

I was recently out to dinner with some friends that are fellow techies, and we were talking about software development methodologies. One of them, who works in a shop that practices pretty true-to-form Scrum, was talking about how management via the product owner was starting to put pressure on them to produce certain, lower point estimates during the planning poker game. He said that it struck the younger team members who’d only worked there as extremely strange and that he personally felt that the powers that be were sort of trying to steer them to a more “waterfall-ish” style. I had a random thought and, rudely, burst out laughing during his anecdote which was, in no way, intended to be funny.

The thing that I had thought of, I explained to my confused friends, was how incredibly weird and counter-intuitive moving to a waterfall development methodology would seem to his teammates who had come into the software development world knowing only Scrum. It’d be like coming home one day and telling your family that you were through buying soap because from now on all you needed was some lye, some elbow grease and the river on the other side of town. Of course, there would (and has been) culture shock going from Waterfall to Agile, but that’s mostly born of a kind of “that’s an impossible pipe dream” mentality. Going the other way has more of a “you want to do what…. and why?” vibe.

Think of this. You’ve never known anything but a disciplined agile approach to software. You have an automated build and deployment setup. Every time you check in code, the build executes, unit tests are run, and the code is pushed to a test environment for exploratory QA and validation of user stories. Checkins are frequent, collaboration is ubiquitous and refactoring and cleaning the code is something you do on a regular basis. Once every other week, you ship the code and it’s no big deal. The (business) day after shipping, you and the team collaboratively plan what you’re going to do for the next two weeks, trusting that someone is prioritizing the work you wind up doing toward a larger technical product/vision. Your users see regular progress and give you regular feedback, creating a tight communication loop and eliminating surprises. And, if the users change their mind about the features they want or don’t like what you’ve done over the last two weeks, you simply spend the next two weeks steering methodically back in the right direction. But don’t worry, that’s all about to change!

Forget about all of that bi-weekly shipping nonsense. We’re going to ship once, as far as we’re concerned. A second shipment is by no means a given because frankly, the first one is rather likely to fail and anger the users. So, let’s not concern ourselves with anything but the first shipment. For the first month or so, we’re going to gather the requirements for the project. We’ll skip through a meadow, plucking them off of the beautiful flora and placing them in our baskets. That’ll be a good month. At the end of that month, we’ll tell our users that they’d better be sure that our endless array of diagrams and thousands of statements about what the software “shall” do matches exactly what they want because once we move onto the next phase, there’s no going back or changing their minds without either expensive change requests or lawyers.

Next up comes the design phase. This is the part where we spend a month figuring out how to write all of the code that we’re going to write over the next several months, but without actually writing that code. While this may sound nuts, the reason that we have to do this is because the labor is going to be divided up in such a way that everyone will kind of go off into their own silo and write code for months prior to an extended “integration phase” where our architect, Dr. Frankenstein, assembles the various individually created pieces into a reasonable attempt at a piece of software and then attempts to breath life into it. In order for that task to be as minimally gruesome as possible, a lot of planning is needed.

The next phase is implementation. Implementation phase is where we start coding and the previous two months of ‘work’ become completely irrelevant. Everyone codes in their silos until integration time. Some attempts are made at early integrations, but those are abandoned when it’s discovered that they are time consuming and the project managers are worried about the fact that they’re already behind schedule. Everyone will then pray that somehow we make up the time that we’ve gotten behind at integration time, but, who are we kidding? That’s not going to happen. The next phase will ideally be the testing phase, but we won’t have time for that. Instead, we’ll start the death march phase, where everyone works 14 hour days, 7 days a week up to the deadline.

Then, my friend, we ship. Tada! Ooh, that wasn’t supposed to happen. Heh, heh, weird. I’m sure the rest of it will be fine if I just — ooh, yikes. What do you mean this screen doesn’t look at all like what you were picturing? Heh, heh, maybe we can reschedule this demo. This is the phase where the thing we chucked over the wall, behind schedule and with a minimum of testing, blows up in our faces. After another month or so of death march following the release, we manage to wrangle the software into a state where, while the source code looks hideous, it’s at least stable and no one is screaming at us anymore.

There, doesn’t that sound better than the one where you’re shipping software every two weeks and not working 90 hour weeks to make up for the fact that you’re not actually very good at predicting the future? But of course, I kid. It was just an interesting exercise for me to think of how the world would seem going from agile to waterfall. Agile methodologies are inherently developer-centric when done correctly. Developers like quick feedback, routine shipments, and process automation because this makes for sustainable, incremental progress. The main complaining I hear from waterfall developers isn’t that agile doesn’t sound good — it’s that it sounds too good to be true. Usually it’s things like “we couldn’t do agile because we’re a shop that does _______” where the blank is some excuse that isn’t actually reasonable unless the company is shipping Mars Rovers. So if you’re already doing agile — you’ve already seen how well it works — going back would seem certifiably crazy. And, you know what? I like that there’s a generation of developers out there that think Waterfall is just a bed time story that the old timers use to scare the newbies into behaving.


Basic Protections on Your Mobile Devices: A Stitch in Time

Today’s post is going to be one where I’ll regale you with a rather ridiculous tale of woe, relief, and redemption. And, it’s my hope that you can learn from my buffoonery just as I did, but without the part where you’re a buffoon.

It’s a story that starts out simply enough. I have a phone and a tablet, both of which are Android devices. With the last Android phone I had, I set up a pattern verification for login, but about a year ago, I got a new phone and never bothered. I also got a new tablet and never bothered with it, either. So, two devices, no security to prevent access to anyone who happens to find them, and no plan of action in case I lose them. My security is just me not losing them or having them stolen, which has actually historically gone pretty well. So, it always will, right? But wait, the plot dumbens.

Today, I went to the gym, which is what I do most days. I’m fortunate enough to have a gym in the same building as my office, and, due to the fact that the gym locker room is one of the weirdest and most annoying places on Earth, I typically have a process flow where I change in my office and go to the gym. So, I did that, leaving my office with my keys, wallet, and tablet in tow. I use the tablet to watch Pluralsight videos while I jog on the machines. After working out, I left the gym, changed in my office, got a bite to eat, and went home.

When I was ready to start thinking about bed earlier tonight, I noticed that I didn’t have my tablet in my gym bag or my laptop bag that I’d brought home. Checked the car, and nope. Guess I left it at the office. Or the gym. Ruh roh. Nah, couldn’t be. I must have left it at the office. Just to make myself feel better, I called the gym, and they told me that they hadn’t seen it. Good, must be in my office. Or… crap. I realize that I’m not going to be able to sleep without solving this mystery, since my tablet has no security and is synced up with all kinds of stuff that I don’t want people accessing. Why, oh why, didn’t I secure the tablet? Oh well, I’ll just drive the half hour to my office, see it on my desk, and feel better. Grumble, grumble.

I get to my office, half an hour later, and have trouble with my keycard for some reason. Luckily, the night custodian knows me and was there to let me in (the fact that the night custodian knows me means that I should probably think about scaling back my hours). I go upstairs, unlock the door to my office and there on my desk is… no tablet. It’s also not in any of my chairs, bookshelves or other places in there that I might have tossed it. It’s almost midnight, I’m back at work, and someone has taken my tablet. I start googling, and fast. I found this site, called Android Device Manager, which is pretty awesome. It lets you see where any of your devices are and, if you’ve set it up, it lets you lock or wipe them remotely. Too bad I hadn’t set it up. The only option I have is to send a loud, five minute “ring” to the tablet, but this app can’t locate the thing anyway, so nevermind.

I also found this “Android Lost” site along with a companion “Jump Start” app that you can use in tandem to remote install something that allows you to wipe the device. Whoah, seems ripe for abuse, but whatever, I’m desperate. No go, however, because it can’t seem to locate the tablet on wifi anywhere and I had already in a panic changed my google password and disabled twitter. Not much, but it was a start. But, it also seemed like it would now prevent me from engaging this option since my google store credentials were different. Oh well, I’d change my google password back. But, I discovered I couldn’t, unless this dude on the internet was to be believed and google caches exactly 110 old passwords before it lets you roll them back over. I can picture him laughing once every evening at each sucker that stumbles on that link and spends 45 minutes changing google passwords 110 times.

I was screwed. I sent one last “ring” signal to my lost tablet, locked my office, and wandered down toward the gym, which had closed at 11, to see if I could hear the thing or something, notwithstanding the apparent lack of wifi connection. When I got there, I couldn’t hear any joyous tablet noises, but the door was open for some reason, so I just went in. I was alone except the usual bad gym music that’s always blaring — something about a drum that, mercilessly and cruelly to the ears of anyone not in love with autotune, “won’t stop beating.” Given my despondence and general distaste for gym-garbage-pop, I so desperately wanted it to stop beating for just a second. Nonetheless, I wandered over to the elliptical that I had used and there, lo and behold, was the tablet, exactly where I’d forgotten to collect it when I was hurrying out of the gym.

Wow am I lucky. I almost didn’t go back to work. I almost didn’t make it into the building because of a key malfunction. I have no idea why I was able to wander into the gym, unsupervised, over an hour after closing and just help myself to whatever was in there, but I was. And now I have it back, and all it cost me was having to change my Google password and my Outlook password.

But I’ve learned my lesson. Phone and tablet now require a pattern swipe to sign in. And both devices are completely configured for remote wipe via the Android Device Manager. If you’re on Android, set both of these things up right now, I beg you. It will take you literally 20 seconds if you have your phone and a browser with you. If you have iThings or Microsoft stuff, I’m sure there’s some equivalent that you can find. It’s oh-so worth it, and you won’t realize it until you’re hit with that sinking feeling. Do yourself a favor, and avoid the late night drives and scrambles to change passwords and whatnot. If you go this route, you’ll just be kicking yourself for losing a few hundred bucks and not wondering what horrible things “you” will have broadcast over email, text message, and every social media platform on Earth by the time the dust settles.


Notes on Writing Discoverable Framework Code

A while back, I found myself plugged into working on a rather large .NET project. The project had been going on for a while, and I was helping out only in terms of implementation manpower; architectural decisions had long since been made. And, in fact, some of the architectural decisions had pre-dated the project altogether. There was a “framework” that these guys were using for the purpose of rapid implementations. The idea was that developers could sort of slap this framework into place and make a few tweaks to have new applications rather than having to take more time to write the code. This wasn’t especially effective, but that was the goal.

As I used (and kind of battled with) this framework, something bothered me about it that I couldn’t put my finger on at first. But as I worked with it, I started to figure it out. The framework wasn’t discoverable in the slightest and thus fought against its own goal of rapid ramp-up and development. I actually put a placeholder in my drafts folder all of those moons ago wherein I made notes about how to make a framework discoverable. I never wound up bothering to make suggestions for improvements to that framework since, luckily, it was the last time I had to use it. But I’m trying to reduce the number of unpublished drafts in my folder, so I figured I’d offer up the suggestions to the world at large so that maybe some of you reading can get some value out of them.

What Do You Mean, Discoverable?

In the last paragraph I used a word without defining it, so I’ll correct that here. To understand what I mean, ask yourself the question, “how do developers discover how to use code?” 10 years ago, the most common answer to that question would have been “read the documentation.” Ah, the bad old days. I remember doing some Linux kernel programming using a library called RTAI, and I had these binders full of documentation on the API. They described in detail what each of the hundreds of parameters for dozens of functions were and what they meant. You certainly couldn’t tell from the names of these things — they were abbreviated, cryptic, and unclear.

The API itself lent few obvious clues about how to use it, and documentation was necessary for understanding. This is an API that is not discoverable. Discoverability is the degree to which you can figure out how to use something simply by playing with and examining it. For instance, if some API had a method called “Connect_To_The_SQL_Server_Database_Using_The_Following_Connection_String(string connection_string)”, you’d be dealing with something highly discoverable; you know how to use this without doing anything but looking at the code.

Developers have a variety of strategies for discovering how to use code. Reading documentation is probably the most traditional and established method, and one with which most experienced developers are familiar. However, let’s be frank — it’s also kind of a bummer. When you’re coding, you just want to write code via experimentation, trial and error. Having to lug out a big binder and pore through it, parsing jargon-heavy text is definitely a fly in the ointment. And while I’ve seen a lot of people express the sentiment, “you have to fight through the burn or you’re not a real programmer,” the fact of the matter is that when something is drudgery, attention spans wander and productivity decreases. So while reading documentation is the most established way of discovering code, it’s also the least effective, typically.

By contrast, the most effective manner of code discovery is use. Developers start using an API in whatever way seems most intuitive to them, typically using tools like Intellisense or word completion. They have some class they’ve declared an instance of in their IDE and they type the variable name and then a period and then they see what the auto-completion tool gives them by way of options for methods. There are other ways for developers to discover APIs as well, such as reading the code when it’s available, pairing with the code’s author, discussing the code with others, etc. But by and large, discovery through experimentation and clarity of purpose is most effective.

So the important question for architects, API authors, and framework providers thus becomes “how do I make my stuff discoverable for the developers that will use it?” Here are some suggestions.

Favor composition over inheritance

Inheritance is one of the main facets of polymorphism and boy oh boy was it popular in the late 1990’s and early 2000’s, especially in Java-land. I recall working on and with inheritance hierarchies that were 10 deep before any useful functionality emerged. Inheritance was one of the best ways at the time to avoid code duplication, but we, as an industry, learned the ugly downside of this approach: confusing non-discoverability.

There is nothing quite like getting a bug report that your code isn’t working and then taking a look to see what went wrong. You look at the source control history and see no record of any change that would explain the bug. None of the classes that your class is using have changed. Is it a bug in the GUI technology or database driver or something? Nope. Turns out, someone checked in a change 3 levels above you in the inheritance hierarchy and suddenly your class behaves differently. /Sigh.

When you use composition (the practice where your class uses other classes or implements interfaces), this sort of mysterious behavior in your classes is eliminated. If your class’s behavior has changed and you haven’t changed it, you know that one of the things that you’re using must have been changed. Eliminating or minimizing inheritance gets rid of a source of confusing possible changes.

Favor few parameters over many

This is relatively straightforward, but avoid using a lot of parameters with your methods. The fewer the parameters, the fewer the amount of things that callers of your methods have to understand and remember. This is a “Golden Rule” kind of situation. When you find the method you want to use by name, but it takes 12 arguments, do you think to yourself, “perfect — just what I want!” or do you think to yourself, “ugh, why me?” Well, users of your API/framework are no different. Consolidate the parameters you require into objects if need be — this will still be easier to understand for clients of your work.

Be judicious with overload methods

Method overloads are a powerful tool, but use them sparingly. It’s nice to offer your clients options, but it’s easy to offer them too many options. Applying the “golden rule” concept from the previous section, imagine if your code autocomplete tool shows you the method that you want, but there are 20 different parameter lists. Ugh. Which one to use? This isn’t discoverable anymore because you’re going to start googling or reading documentation or something. If there’s only one option, you’re simply going to use it and move on.

Favor early binding over late binding

One of the nastiest facets of the framework that I mentioned in the introductory section of the post was rampant late binding. Late binding is a scheme where relationships are resolved at run time rather than compile time. A common example of late binding would be a scheme that uses reflection to resolve names of fields in code to strings and to sync them with values on a form. So, if you have a Customer object with a “Name” property, you use reflection to get the string “Name” and look for a matching string on the form to which to write that value. Contrast this with a scheme where you simply have a strongly typed form object and you assign a value to its “Name” property. In the former scheme, mis-typing the property name results in a confusing runtime exception whereas in the latter scenario, the code won’t compile.

Programmers understand non-compiling. It’s one of the first feedback schemes you learn with a new language and you’ll very quickly understand why the compiler complains at you. So when something doesn’t compile, it’s quick and easy to figure this out and fix it. But if something fails weirdly at runtime as with a late binding scheme, it becomes hard to figure out what’s wrong. And, more importantly, it’s very frustrating. Part of discoverability is that it’s easy to understand why the right things work and the wrong things don’t. Late binding makes this understanding far more difficult for people working with the code.

Fail as early as possible

Very closely related is the concept of failing fast and early. An important concept for programmers is a tight feedback loop — a minimum of time between when you take an action and see the result of that action. A framework that creates negligible lapses between action and reaction is a discoverable one because users can quickly understand what works and what doesn’t. If there’s a lag between action and reaction, things are harder to figure out. This is a big problem with late binding, but it would also apply to a framework that’s slow running or slow to build as well.

Make screwing up impossible

Perhaps most important to discoverability is to make screwing up as hard as possible. Have clients of your code “fall into the pit of success.” This means taking whatever steps are possible to disallow doing the wrong thing. If a class Car in your framework requires an Engine in order to work, force people using your framework to pass Engine to Car’s constructor so that if they don’t, the code won’t compile. If they pass null, throw an exception. Contrast this with a behavior where the code makes passing in an engine optional and simply limps along and maybe throws a null reference exception somewhere if it’s missing. The latter approach is confusing — you’re communicating through your API that the Engine isn’t needed, and yet you’re failing everywhere it’s not present. You’re creating a minefield for your users rather than a pit of success, and consequently making your stuff really non-discoverable.


Programmers, Teach Non-Geeks The True Cost of Interruptions

Interruptions are one of the biggest sources of inefficiency for programmers. Now, to be fair, they’re probably a big source of inefficiency for everyone, but relatively speaking, they’re worse for programmers. To understand what I mean, let’s take someone whose job is in sales. A lot of the day is probably spent on the phone or in transit to and from meetings. In a given meeting or while reviewing notes prior to a meeting, an interruption to a sales person means time spent dealing with the interruption, a shake of the head, and a “where was I… oh, right.” For a manager, the day is often just a series of never-ending interruptions. In a management capacity, I find it common to sit down at lunch, still not having done the first thing I planned to do that day. Paul Graham has an excellent article about the different natures of the day for managers and for people he calls “makers,” a group that clearly includes programmers.

For a programmer, an interruption is oh-so different. There you sit, 12 calls into the call stack. On one monitor is a carefully picked set of inputs to a complex form that was responsible for generating the issue and on the other monitor is the comforting dark theme of your IDE, with the current line in the debugger glowing an angry yellow. You’ve been building to this moment for 50 minutes — you finally typed in the right inputs, understood the sequence in which the events had been fired, and got past the exact right number of foreach and while loops that took a few minutes each to process, and set your breakpoint before the exception was triggered, whipping you into some handler on the complete other end of the code base. Right now, at this exact moment, you understand why there are 22 items in the Orders collection, you know what the exact value of _underbilledCustomerCount is and you’ve hastily scribbled down the string “8xZ204330Kd” because that was the auto-generated confirmation code resulting from some combination of random numbers and GUIDs that you don’t understand and don’t want to understand because you just need to know what it is. This is the moment where you’re completely amped up because you’re about to unlock the mysteries of what on earth could be triggering a null reference exception in this third party library call that you’re pretty sure —

“HI!!! How’s it going? So, listen, you know that customer order crashing thing is, like, bad, right? Any chance I can get an ETA on having that fixed?”



The project manager just startled you while you were getting ready to hit the next instruction and you hit “step over” instead of “step into!” He’s droning on and on about the importance of himself or the customer or something that you’re not listening to because you’re trying to control your rage at having lost all of your debugging context while also starting to think ahead to how you can get back to the point you were at in maybe 30 minutes instead of 50. But it’s no use. PM’s boss sees PM talking to you, walks over, and now there’s a full-blown discussion about the Initrode account going on next to your desk, loudly, complete with ridiculous buzzword BS bingo and sports metaphors about “closing out the game in the endzone” or something. By the time the dust settles and you’ve been Six-Sigma-ed into submission by 3rd degree black belts, you know that you’re going to be ordering a pizza and doing this again at 7 PM after everyone else leaves so that you can have some peace and quiet to work. All you can do is shake your head in sad disgust and wonder, “what on earth does 8xZ204330Kd mean and why did I write that down?”

But here’s the real insult-to-injury moment. When you try to explain to the PM how insanely destructive to your productivity that interaction was, he snorts at you and tells you not to be so melodramatic. He wanders off, wondering why programmers are such overdramatic prima donnas. Your non-techie peers just don’t get it, no matter how many times you try to make them understand. When part of your job is walking around all day demanding status updates and having the same demanded of you, it’s easy not to understand how different the programmer’s work paradigm is. I’ve been on both sides of it, and now that I spend a good portion of my day doing planning and overhead activities, I have to fight the impulse to drop by the area where my team sits and interrupt them regularly to get a piece of information so that I can put it in some email or add it to a list of resolved issues. PMs, managers, etc. all have real problems, many of which involve attempting to provide timely support to partners, clients, or internal staff, and issues and problems are interruptive, by their very nature.

Well, worry not, because I think I have a way that you can actually demonstrate to them just how devastating interruptions are to your productivity compared to, say, theirs. In other words, here’s how to make someone understand that, for you, an interruption isn’t just a delay after which you can get right back to work but a complete total of your efforts up to that point. Here’s how.

Invite the PM/manager/sales/whatever person to sit at his desk and tell him to humor you. Open up notepad and type a series of 3 or 4 digit numbers in sequence, like so:


Now, tell him to add those numbers in his head. He can look at the screen and talk/whisper/mutter to himself, but he can’t write anything down and he can’t type anything. He may laugh. Tell him that you bet him lunch he can’t get it done in five minutes, only getting one shot at getting the answer right. Maybe he’ll stop laughing and get to work.

Sit down, curl your hands behind your head and give him half a minute or so. Listen to him muttering. Then, get out your cell phone and call his office line. If he ignores it, ask him if he’s planning to answer it, since it could be important. He’ll grunt and mumble something about having to start over.

Give him another 30 seconds or so and say, “So, harder than you thought, huh? Which number are you on? You know which number always gets me? 333. Something about that number. Or maybe it’s 221. Or anything that adds to 9,365. Numbers, amirite! Oh, crap, sorry, you were concentrating. I’ll be quiet.”

Give him a minute. Pull out your phone and start talking loudly to no one on the other end, simulating a call. Start reciting imaginary phone numbers. Look sheepish and apologize.

Give him another minute. Blurt out that you’re low on work today, and ask him if he still wants you to add those three things about the four or five other things to six or seven of the upcoming performance presentation slides, and, oh, geez, numbers again, your bad.

Give him yet another minute. Then tell him that he’s only got 20 seconds left. Or is it 30? Maybe 25. Whatever the case may be, he’s getting into crunch time. Oh well, you guess he failed. Thank him in advance for lunch, but offer to let him keep his lunch money if he promises to stop constantly doing what you just did to him while you’re trying to code, which is a lot like keeping track of numbers all day in your head.