Stories about Software


I Have a New Book

It’s been an interesting week with respect to my philosophy about the future of labor for knowledge workers. This post about corporate idealists and seniority got relatively popular and attracted around 10,000 readers. If you’re a regular follower of this blog, you know that one was just the latest in a series of a few posts I’ve done on this topic and you probably also know that these are coming from my work on a book. But this understandably wasn’t immediately clear to new readers, and so I got a smattering of inquiries as to where the book was for sale or whether it could be pre-ordered. I invited those folks to stay tuned or sign up for my mailing list, but alas I had nothing to offer.

A few days later, I noticed the hashtag #talkpay on Twitter, promoting the controversial but clearly forward-thinking idea that making salary information confidential is problematic in a variety of ways (specifically, in this case, that it facilitates gender and racial pay inequality). I’m not a salaried employee, so I couldn’t offer information about my salary, but it did prompt me to tweet this:

As you can see, this was a pretty popular sentiment, which jived with the reception my post about salary negotiation hacks received. There appears to be a great deal of appetite for reconsidering the knowledge worker’s relationship with the corporate structure.

To this end, I decided over the weekend to put an end to my large-batch approach to writing this book and include anyone that wants to come along for the ride right from the outset. I wrote my initial introduction to the book and published it on Leanpub (most of the material I’d been gathering is still scattered in a large document on my personal google drive). Beware, there’s not much there, but that will change. In the coming months, I’ll be writing to the book almost the way I would to a second blog. So, stay tuned.

The infant book is now officially on Leanpub and officially for sale. I have absolutely no idea what I’m doing when it comes to marketing or setting price, so please bear with me. It’s doubly confusing because Leanpub offers a lot of different options for differentiated pricing. The minimum price for the book is $1 and the suggested price is $4.99. The suggested price was just the default, and the minimum price is 1 cent more than the default for no particular reason other than selling things for 99 cents seems somehow hokey to me. I considered making the initial minimum price free, since there’s not much book there, but data about whether people would pay for the thing or not is a lot more meaningful if people have to pay for it. If I made it free, I might get a lot of spurious information (lessons learned from Lean Startup and 4 Hour Work Week).


Now, here’s the nuance. You can get the book for free. I wanted to be sure to offer that option to people that are regular fans and followers of the blog and will provide feedback as I write it along with support and shares. So I created a coupon that I’ll send out to the DaedTech mailing list as well as anyone who signs up for it from here forward. Also, I’m not going to lie. If you just email me, I’ll send you the coupon too, but I’d prefer to do it through the mailing list. For those of you on the mailing list, look for the coupon email in the next few days.

As I said, I have no idea what I’m doing when it comes to marketing, so I hope this makes sense and isn’t crazy. I wanted to err on the side of giving too much away if I erred in any direction. Weird as it sounds to say, I’ve never regretted erring on the side of giving away content. People seem to live life petrified that they’ll give something away for free when they could have wrung a few dollars out of it, but for me, the goodwill and engagement created by giving away content has paid far more dividends down the line than a few dollars.

So I cordially invite you to join me on this book journey. And, naturally, I invite you to invite as many of your friends and colleagues as you please! :) I’m excited and looking forward to this, and fascinated to see how it goes.


ChessTDD 33: Scenario Housekeeping

Having fixed some bugs in the last few episodes, it would have been nice to make some progress with functionality, but there was housekeeping to be done first. I did some refactoring for board setup using the tables, compacting methods, and made the implementation of the moves checker correct. This will put me on much more sustainable ground as I go forward implementing game scenarios.

What I accomplish in this clip:

  • Fixed incorrect/incomplete implementation of checking for moves.
  • Refactored BuildBoardFromTable method.

Here are some lessons to take away:

  • When you make a test go red, don’t then take the opportunity to do a refactoring — even a small or inconsequential one.  Go back to green and then do it.  You want to be taking actions in batches as small as possible.  Doing 2 things at once is a recipe for confusing cause and effect.
  • I’m not sure how others feel about this, but I did something in this video that I do from time to time.  I had a green test covering an implementation that was too permissive — too easy to get right.  So I altered the test temporarily to green in a situation where it should have been red.  I then modified the production code to get the expected red, then reverted the test and verified that it was green.  This is the equivalent of writing another test, framed in the negative, and then taking that test from red to green.  I shortcutted that process because I didn’t want that other test to be left around when I was done.
  • I consider baking the names of types into class, method, and variable names to be a bad practice.  You might change the type they use and forget to update the name accordingly, and you’re also leaking implementation details.
  • A refactoring may well never seem perfect to you.  If you make sure it seems cleaner or better as compared to where it was, that’s progress.  Stick a pin it it and make a note to revisit later.  Not only is this good for avoiding diminishing returns on a given day’s effort, but it also removes you from the problem so that you can better assess readability later.


What Is a Best Practice in Software Development?

(Editorial Note: Hello, Code Project, folks and thanks for stopping by! I’m really excited about the buzz around this post, but an unintended consequence of the sudden popularity is that so many people have signed up that I’ve run out of Pluralsight trial cards. Please still feel free to sign up for the mailing list, but understand that it may be a week or so before I can get you a signup code for the 30 day trial. I will definitely send it out to you, though, when I get more. If you’d like to sign up for a 10 day trial, here is a link to the signup that’s also under my courses on the right.)

A while ago, I released a course on Pluralsight entitled, “Making the Business Case for Best Practices.”  (If you want to check it out, but don’t have a Pluralsight account, sign up for my mailing list in the side bar to the right and I’ll send you a free 30 day subscription).  There was an element of tongue-in-cheek to the title, which might not necessarily have been the best idea in a medium where my profitability is tied to maximizing the attractiveness of the title.  But, life is more fun if you’re smiling.

Anyway, the reason it was a bit tongue in cheek is that I find the term “best practice” to be spurious in many contexts.  At best, it’s vague, subjective, and highly context dependent.  The aim of the course was, essentially, to say, “hey, if you think that your team should be adopting practice X, you’d better figure out how to make a dollars and cents case for it to management — ‘best’ practices are the ones that are profitable.”  So, I thought I’d offer up a transcript from the introductory module of the course, in which I go into more detail about this term.  The first module, in fact, is called “What is a ‘Best Practice’ Anyway?”

Best Practice: The Ideal, Real and Cynical

The first definition that I’ll offer for “best practice” is what one might describe as the “official” version, but I’ll refer to it as the “ideal version.”  Wikipedia defines it as, “method or technique that has consistently shown results superior to those achieved with other means, and that is used as a benchmark.”  In other words, a “best practice” is a practice that has been somehow empirically proven to be the best.  As an example, if there were three possible ways to prepare chicken: serve it raw, serve it rare, and serve it fully cooked, fully cooked would emerge as a best practice as measured by the number of incidents of death and illness.  The reason that I call this definition “ideal” is that it implies that there is clearly a single best way to do something, and real life is rarely that neat.  Take the chicken example.  Cooked is better than undercooked, but there is no shortage of ways to fully cook a chicken – you can grill it, broil it, bake it, fry it, etc.  Is one of these somehow empirically “best” or does it become a matter of preference and opinion?


Read More


ChessTDD 32: Squashing a Subtle Bug

This was kind of a wild episode, inasmuch as recording oneself writing code gets wild.  This was the second bug driven out by the acceptance tests, but this one was subtle and buried fairly deep in the application logic.  This was another half hour episode as I employed a variety of techniques for hunting down and fixing a bug.

What I accomplish in this clip:

  • Fixed the bug discovered last time.
  • Left a few legitimate tests as breadcrumbs along the trail.

Here are some lessons to take away:

  • Use binary search kinds of techniques when solving problems.  For instance, if a two part boolean expression is causing a test to fail by returning the wrong result, comment out/delete one of the branches to see which one it is.  This helps you narrow the search without invoking the debugger or squinting at the code, scratching your head.
  • It’s important, when you have a failing acceptance test, to drill in and recreate the scenario in unit tests with less setup context around it.  This ensures that the problem is, in fact, a problem of the code under test rather than something going on with the acceptance test setup.  Getting this second failing test prevents you from chasing phantom bugs in your production code.
  • I try to use the debugger as little as possible when doing TDD, especially with the continuous testing tool.  But, for the occasion that you’d have to write a lot of assumption checking asserts, the debugger can be a handy way to see a number of different values that you want to check.  This was relevant when I wanted to see 4 different coordinate values.


Carnival Cash: The Cult of Seniority

Alright, screw it. Let’s burn the boats. I said I wasn’t going to get into this until I released the book, but the idealist career advice post I had planned doesn’t make sense without a discussion of corporate seniority.  If you haven’t read this recent post, in which I outline the terms pictured below, you’ll probably want to read it for reference or this one might not make as much sense to you.  In this post, I’m going to defend a thesis that the best career advice I could offer to any knowledge worker, counter-intuitive though it may seem, would be to avoid earning seniority at a company.

In a prequel to this series I seem to be starting, I define the essential conundrum of the corporate pragmatist.  This post is going to focus on corporate idealists and the essential conundrum that they face, and it’s going to address a reader’s question while we’re at it.  That question provides a good lead-in to the context here.  Paraphrased, it was, “while going it alone may be good advice for seasoned, senior developers, shouldn’t junior developers hitch their wagons to a company for a while, giving a lot of extra effort and working their way up while learning the ropes?”  My simple, off-the-cuff response is, “oh, dear God, no!”  But the more nuanced response I’ll expand on here is, “that may be a strategy, but be very, very careful, because here be dragons.”


Read More


ChessTDD 31: Look, We Caught a Bug!

A bit of time went by between when I recorded the code and when I narrated it, so pardon the unusual amount of rust there. But this episode was particularly interesting because an actual bug emerged and I fixed it. Yay for acceptance tests. After that, a second bug emerged, but I ran out of time. So there’s definitely a todo for episode 32.

What I accomplish in this clip

  • Got away from the C&P implementation of “then” for the new style of tests and implemented a usable one.
  • Discovered and fixed a bug in king’s moves.
  • Discovered another bug to fix next time.

Here are some lessons to take away:

  • When you’re stumped by behavior, particularly in integration tests, the continuous testing tool can help you run experiments very quickly.  Add a precondition assert to verify that your assumptions are correct.
  • TDD is not a catch-all against bugs, by any stretch.  I had a dumb bug in the implementation of the King class that I failed to catch, and everyone following along failed to catch (assuming someone would have reported it, anyway).  It wasn’t until I started simulating real production usage that these bugs started to be revealed.  Acceptance tests are critical.
  • The balance between ATDD and TDD is beneficial.  You’ll see going forward that when I find problems, I tend to use increasingly specific tests the way that you might be used to using step-through in the debugger.  Narrowing the scope of the problem with tests rather than the debugger has the advantage of leaving a trail of breadcrumbs that become guards against regressions as you go on.
  • This ATDD/TDD stuff works.  As you can see, I caught 2 bugs that could have escaped into production.
  • Never commit with red tests, obviously, but I also say never take a break with red tests (the way I would have to between clips).  If you have to go, comment or delete that red test, so that you can start fresh with green next time and reintroduce it.


Defining The Corporate Hierarchy

Rites of Passage

Think back to being a kid, and you can probably remember a rather dubious rite of passage that occurred when you figured out that you weren’t going to be a sports player, lead singer, or Hollywood star.  You probably felt sad, but your parents and older siblings likely breathed sighs of relief that you’d never be explaining to people that a manual labor gig was your “day job.”  State lotteries notwithstanding, giving up on improbable dreams is considered by adults to be a sign of maturity in budding adults.

If you think about this, the easy message to hear is “you’re not going to be great, so give up.”  It’s depressing and oft-lamented by college kids having mini crises of identity, but it’s actually a more nuanced and pragmatic message, if a poorly communicated one.  It’s that the expected value of these vocations is horrendous.  For baseball players, actresses, and rock stars, there’s a one in a million chance that you’ll make ridiculous sums of money and a 999,999 in a million chance that you’ll make $4,000 per year and have half of it paid to you in beer nuts.  So the expected value of going into these positions is about a $4,200 per year salary and a handful of beer nuts.  So the message isn’t really “give up because you’ll never make it” but rather “steer clear because anything but meteoric success is impoverishing.”

The better play, we tell our children, is to head for the corporate world where the salaries range from minimum wage in the mailroom to tens of millions per year for CEOs of companies that create stock market volatility. Most importantly, you can find every salary in between.   So if you aim for the heights of CEO and fall short, mid-level manager making $140K per year isn’t a bad consolation prize. And so a funny thing happens. We consider it to be a rite of passage to abandon the delusion that you’ll be Michael Jordan, but we encourage the delusion that you’ll be Bill Gates until people are well into middle age.

That’s right, “the delusion that you’ll be Bill Gates.” You won’t be him. You won’t be a CEO, either, unless you pop for your state’s incorporation fee and give yourself that title. You’re about as likely to “work your way up” to the CEO’s office over the course of your career as any given child is to luck into being the next multi-platinum pop star. So, it’s a rather strange thing that we tsk-tsk children for indulging pie-in-the-sky fantasies past a certain age while we use nearly identical fantasies as the blueprint for modern industry. Kid wants to be Justin Bieber? Pff. Thirty-year-old wants to be Mark Zuckerburg? Keep working hard, kicking butt, and acing those performance reviews, and someday you’ll get there!

Pff. Read More


My Blog: If I Build It, Will They Come?

I’m writing a quick post tonight in response to a question I received today.  I actually intended to address this later, but I have a number of posts about what Michael O Church calls CS666 in various stages of readiness, and I’m trying to juggle not offering rabble-rousing cynicism without solutions, avoiding a stream-of-consciousness brain dump of material for my book, and having interesting material to post.  My opinions on the flaws of modern corporate structure will have to wait, and I don’t have my Visual Studio setup with me, so there’s no Chess TDD to be had tonight, either.

The question(s) I’m answering, paraphrased: “there seems to be little point to blogging if no one is reading, so how do you get readers?”

On Low Readership and Blogging Nihilism


Read More


Chess TDD 30: Starting To Be Idiomatic With SpecFlow

This episode went so poorly, I thought briefly about scrapping it and starting from scratch… but that would not be true to the premise I established at the outset where I’d do this unedited, flubs and all.  Having finished with the AsciiBoardBuilder, it was time to start putting Darren Cauthon’s ideas into play.  You can read up on that here.  I sized up what he had done and, in spite of knowing very little about SpecFlow, decided that I only needed certain parts of it for my purposes.  This turned out to be a mistake as something that I thought he had just added for illustrative/cosmetic purposes was decidedly non-cosmetic, and it took me a lot of floundering to figure that out.  Now, that’s not uncommon for me, per se — I’m a “figure it out by breaking it” sort of person, but it’s not exactly the stuff of scintillating videos.

Here’s what I accomplish in this clip:

  • Got the first idiomatic SpecFlow test written in the new feature.  Barely.  And ugly.

Here are some lessons to take away:

  • When using someone else’s example as a template for learning something you don’t yet know, don’t jump the gun and start tweaking and changing things before you get the example working.  Do as I say, not as I do.
  • No matter how long you’ve been doing this, you’ll still make off by one errors and get array bounds arithmetic wrong when it’s complicated.  Improve the odds in your favor by using TDD or, by some other mechanism that you come up with, if applicable.
  • When you find yourself writing a good bit of logic in test code (meaning, you’re writing a lot of code that you aren’t test-driving), ask yourself whether you could move the logic to production or find some other way to tease it out with TDD.  You can see by my floundering here that you become decidedly less productive when you’re writing a lot of code and just hoping for the best.
  • Using NCrunch, it’s pretty easy to run quick experiments to help with my debugging.  One such example was to start hard-coding the row/column indices to see for which ones exceptions were actually generated.
  • Similarly, putting a temporary precondition assert at the top of a test method to check your assumptions can also be a big help.  This is what started me down the path of realizing my mistake with the table’s header.  I finally sanity-checked my assumption that the table had 8 rows to find that it really only had 7.


Please Direct all Inquiries to My Agent

I got an email from a recruiter not too long ago.  I suppose that’s not a surprise, given how I’ve made my living, but what might surprise you is that I usually respond to recruiters, and politely at that.  They’re human beings, trying to earn a living in a way that I don’t envy.  These days, my relatively stock reply is to thank them for reaching out, tell them that I’m pretty happy and thus pretty picky, and to offer to chat anyway, if they just want to network.  As a developer with some community presence, a serial freelancer, a consultant, and general entrepreneur, it never hurts to talk for a few minutes and make a connection.  This recruiter persisted, and said that, even if it wasn’t a current fit, something might make sense later.  Sure, why not?

Come Hear about this Depressing Opportunity!

When she called, we exchanged pleasantries and she asked what I’d been doing lately in a professional capacity.  I explained that the last 2 years had seen me as the CIO of a company, running an IT department, and then going off on my own to do freelance development, consulting, coaching, and a cadre of other activities.  At this point, she began to explain what life was like for line level devs at her company and asking what tech stack I preferred.  I sighed inwardly and answered that I’d been engaged in coaching/mentoring activities in Java and .NET recently, but that I didn’t care too much about language or framework specifics.  She then asked about my career goals, and I scratched my head and explained, honestly, that I was looking to generate enough passive income to work on passion projects.  She became a little skeptical and asked if I had recent development experience, clearly now concerned that whatever it was that I’d been doing might not qualify me to crank out reams of line-o-business code or whatever fate she had in mind for me.

The conversation had become deeply tiring to me at this point, and I steered it to a close relatively quickly by telling her I had no interest in line-level development positions unless they were freelance, B2B, part time sorts of engagements that weren’t very long in duration (and not bothering to mention that I’d probably sub-contract something like that since I don’t have an abundance of time).  She assured me that all of the positions she was hiring for were W2, full time positions but I should give her a call if I changed my mind and felt like being an architect or something, and that was that.

I hung up the phone, sort of depressed.  Honestly, I wished I’d never taken the call more profoundly than if I’d interviewed for some plum gig and been rejected.  This just felt so… pointless.  I couldn’t really put my finger on why, and indeed, it took my subconscious some time to kick into useful mode and deposit it coherently into my active brain.DevOpportunityCost

Read More

Acknowledgements | Contact | About | Social Media