DaedTech

Stories about Software

By

ChessTDD 21: False Starts and The Knight Problem

This wasn’t the most productive episode I’ve ever recorded, per se, in terms of functionality, but, hey, it’s always a learning experience to write code.  This was kind of table setting for a big, important piece of functionality: distinguishing captures from blocked moves because of friendly pieces.

Here’s what I accomplish in this clip:

  • Flesh out the non-happy path scenario for PathChecker (later renamed PathMaker)
  • Start implementing functionality for Knight on the board.

And, here are some lessons to take away:

  • If you write a test that you think should pass and it fails, it’s okay to pivot what you’re testing to gain understanding.  Improving your reasoning about the code is extremely important.
  • Thrashing can happen.  It occurred to me that GetSpacesAlongPath maybe shouldn’t return the destination piece in its collection, but that created problems for existing code.  I weighed the dependencies and what would need to change the functionality and decided clarifying the name was a better route.
  • It’s okay to write and leave tests to confirm your hypotheses.  The TDD discipline is to force yourself to change production code only in response to a failing unit test, but there’s nothing to say you can’t write green tests to confirm that the system is working as you expect.  I have no qualms about weaving this sort of thing into red-green-refactor provided that the test is one that is meaningful when left in place because it’s important to corroborate your reasoning about the code.
  • Don’t call it a day with a failing unit test.  If you’re not prepared to finish by making it green, back it out and add a todo list item.  You don’t want to start at red next time.

By

How to Get Your Company to Stop Killing Cats

We humans are creatures of routine, and there’s some kind of emergent property of groups of humans that makes us, collectively, creatures of rut. This is the reason that corporations tend to have a life trajectory sort of similar to stars, albeit on a much shorter timeline. At various paces, they form up and then reach sort of a moderate, burning equilibrium like our Sol. Eventually however, they bloat into massive giants which is generally the beginning of their death cycle, and, eventually, they collapse in on themselves, either going supernova or drifting off into oblivion as burned out husks. If you don’t believe me, check out the biggest employers of the 1950s, which included such household names as “US Steel” and “Standard Oil.” And, it’s probably a pretty safe bet that in 2050, people will say things like, “oh yeah, Microsoft, I heard of them once when playing Space-Trivial-Pursuit” or “wow, Apple was a major company? That Apple? The one that sells cheap, used hologram machines?”  (For what it’s worth, I believe GE and some other stalwarts were on that list as well, so the dying off is common, though not universal)

Yes, in the face of “adapt or die” large companies tend to opt for “die.” Though, “opt” may be a strong word in the sense of agency. It’s more “drift like a car idling toward a cliff a mile away, but inexplicably, no one is turning.” Now, before you get any ideas that I’m about to solve the problem of “how to stop bureaucratic mobs from making ill-advised decisions,” I’m not. I’m really just setting the stage for an observation at a slightly smaller scale.

I’ve worked for and with a number of companies, which has meant that I’ve not tended to be stationary enough to develop the kind of weird, insular thinking that creates the Dead Sea Effect (wow, that’s my third link-back to that article) or, more extremely, Lord of the Flies. I’m not the kids wearing war paint and chasing each other with spears, but rather the Deus Ex Machina marine at the end that walks into the weird company and says, in disbelief, “what are you guys doing?” It’s not exactly that I have some kind of gift for “thinking outside the box” but rather that I’m not burdened with hive mind assumptions. If anything, I’m kind of like a kid that blurts out socially unacceptable things because he doesn’t know any better: “geez, Uncle Jerry, you talk funny and smell like cough medicine.”

You can’t just not kill cats.

ScaredCat

What this series of context switches has led me to observe is that organizations make actual attempts to adapt, but at an extremely slow pace and desperately clinging to bad habits. This tends to create a repelling effect for a permanent resident, but a sad, knowing smile for a consultant or job hopper.  If you find yourself in this position, here’s a (slightly satirical) narrative that’s a pretty universal description of what happens when you start at (and eventually exit) a place that’s in need of some help.

You get a call from a shop or a person that says, “we need help writing software, can you come in and talk to us for an afternoon?” “Sure,” you say and you schedule some time to head over. When you get there, you notice (1) they have no computers and (2) it smells terrible. “Okay,” you say, hesitantly, “show me what you’re doing!” At this point, they lead you to a room with a state of the art, industrial grade furnace and they say, “well, this is where we round up stray cats and toss them in the furnace, but for some reason, it’s not resulting in software.” Hiding your horror and lying a little, you say, “yeah, I’ve seen this before — your big mistake here is that instead of killing cats, you want to write software. Just get a computer and a compiler and, you know, write the software.”

The next week you come in and the terrible smell is gone, replaced by a lot of yowling and thumping. You walk into the team room and discover a bunch of “software engineers” breathing heavily and running around trying to bludgeon cats with computers. “What are you doing,” you ask. “You’re not writing code or using the compiler — you’re still killing cats.” “Well,” the guy who called you in replies shamefacedly, “we definitely think you’re right about needing computers, and I know this isn’t exactly what you recommended, but you can’t just, like, not kill cats.” “Yes, you can just not kill cats,” you reply. “It’s easy. Just stop it. Here, right now. Hand me that computer, let’s plug it in, and start writing code.” Thinking you’ve made progress, you head out.

The next week, you return and there’s no thundering or yowling, and everyone is quietly sitting and coding. Your work here is done. You start putting together a retrospective and maintenance plans when all of a sudden, you hear the “woosh” of the old oven and get a whiff of something horrible. Exasperated, you march in and demand to know what’s going on. “Oh, that — every time we finish a feature, we throw a bunch of cats in the furnace so that we can start on the next feature.” Now at the end of your rope you restrain the urge to say, “I’m pretty sure you’re just Hannibal Lecter,” opting instead for, “I think we’ve made some good progress here so I’m going to move on now.”  “Oh, we hate to see you go when you’re doing so much good,” comes the slightly wounded reply, “but we understand.  Just head over to maintenance and give them your parking garage pass along with this cat — they’ll know what to do with it.  And yes, mister smarty pants, they do really need the cat.”

As you leave, someone grabs you in the hallway for a hushed exchange.  “Haha, leaving us already, I see,” they say in a really loud voice.  Then, in a strained whisper, “take me with you — these people are crazy.  They’re killing cats for God’s sake!”  What you’ve come to understand during your stay with the company is that, while at first glance it seems like everyone is on board with the madness, in reality, very few people think it makes sense.  It just has an inexplicable, critical mass of some kind with an event horizon from which the company simply cannot escape.

What’s the score here?  What’s next?

So once you leave the company, what happens next?  Assuming this exit is one of departing employee, the most likely outcome is that you move on and tell this story every now and then over beers, shuddering slightly as you do.  But, it might be that you leave and take the would-be escapees with you.  Maybe you start to consult for your now-former company or maybe you enter the market as a competitor of some kind.  No matter what you do, someone probably starts to compete with them and probably starts to win.  If the company does change, it’s unlikely to happen as a result of internal introspection and initiative and much more likely to happen in desperate response to crisis or else steered by some kind of external force like a consulting firm or a business partner.  Whatever the outcome, “we just worked really hard and righted the ship on our own” is probably not the vehicle.

If that company survives its own bizarre and twisted cat mangling process, it doesn’t survive it by taking incremental baby-steps from “cat murdering” to “writing software,” placating all involved at every step of the way that “nothing really needs to change that much.”  The success prerequisite, in fact, is that you need to change that much and more and in a hail of upheaval and organizational violence.  (People like to use the term “disruption” in this context, but I don’t think that goes far enough at  capturing the wailing, gnashing of teeth and stomping of feet that are required). In order to arrive at such a point of entrenched organizational failure, people have grown really comfortable doing really unproductive things for a really long time, which means that a lot of people need to get really uncomfortable really fast if things are going to improve.

I think the organizations that survive the “form->burn->bloat->die” star cycle are the ones that basically gather a consortium of hot burning small stars and make it look to the outside world that it’s a single, smoothly running star.  This is a bit of a strained metaphor, but what I mean is that organizations need to come up with ways to survive and even start to drive lurching, staggering upheaval that characterizes innovation.  They may seem calm to the outside world, but internally, they need malcontents and revolutionaries leaving the cat killing rooms and taking smart people with them.  It’s just that instead of leaving, they re-form and tackle the problem differently and better right up until the next group of revolutionaries comes along.  Oh, and somehow they need all of this upheaval to drive real added value and not just cause chaos.  Yeah, it’s not an easy problem.  If it were, corporations would have much better long term survival rates.

I don’t know the solution, but I do know that many established organizations are like drug addicts, hooked on a cocktail of continuity and mediocrity.  They know it isn’t good for them and that it’s even slowly killing them, and they seek interventions and hide their shame from those that try to help them, but it’s just so comfortable and so easy, and just a few more months like this, and look, man, this is just the way it is, so leave me alone about it, okay!?  If you’re working for or with a company struggling to change, understand this dynamic and game plan for drastic measures.  You’re going to need to come  up with a way to change the game, radically, and somehow not piss all involved parties off in the process.  If you want to stay, that is.  If not, there’s probably good money to be made in disrupting or competing with outfits that just want to keep burning those cats.

By

Help, My Boss Sucks!

I might be accused of link bait for a title like this, but I actually get a decent amount of questions that, when you distill them down to their bare essence, amount to this title. The questions are often packaged in narrative (possibly rant) form and almost invariably summed up with an apology for all of the detail. Please don’t apologize for that level of detail. It’s not that I enjoy hearing about your miseries, but I think that there’s definitely a shared catharsis that occurs when recounting or listening to tales of corporate stupidity with a narrator that’s powerless to stop it.

My Expert Beginner series and eventual E-Book resonated with a lot of people largely, I think, because of this dynamic. The experience of dealing with an entrenched incompetent is so common in our industry that thousands and thousands of people read these posts and, thought, “hey, yeah, I had to deal with a guy just like that!” And I’m small potatoes — the DailyWTF is an entire, vibrant site with tens of thousands of subscribers and a number of authors and editors dedicated to this kind of thing. If you want to go even bigger, think of Dilbert and his pointy haired boss or the Peter Principle.

Assuming, however, that commiseration with others isn’t enough to bring the joy back into your life (or at least to remove the angst from it), the question then follows, “what should I do?” It’s at this point that one might expect to stumble across some kind of insipid faux-answer on LinkedIn or something. It’d probably go something like this:

Top Ten Tips to Tame a Terrible Tyrant

  1. Take up meditation or yoga and learn to take deep breaths when your stress level is getting high so that you can react calmly even in the face of irrational behavior.
  2. Ask yourself if you’re not part of the problem too and do some serious introspection.
  3. You don’t have to like someone to respect them.
  4. Talk to human resources and ask for discretion.
  5. Have a heart to heart and explain your concerns, being courteous but firm.
  6. Enlist the help of a mentor or respected person in the group to make things more livable.
  7. Empathize with their motivations and learn why they do what they do so that you can avoid their triggers.
  8. Heap praise on the boss when he or she avoids behaviors you don’t like in favor of ones that you do.
  9. Seek out a project that puts you on loan to another group or, perhaps, minimizes the direct interaction with your boss.
  10. If all else fails and you’re at wits’ end, perhaps, maybe, possibly, you might want to consider some kind of change in, you know, jobs — but do a ton of research before you do anything and make lots of idea webs and charts and make really, really sure that this is what you want to do because it’s a huge decision.

Honestly, go out and google something like, “what to do about a bad boss” and this is the sort of platitudinous, enumerated non-answer to which you’ll be treated.  It’s manicured, politically correct, carefully considered, diplomatic, and a load of crap.

Let’s get real.

What To Do When Your Boss Sucks

  1. Form an exit strategy.  That’s it.  There is no 2.

AngryArch

Wait, Wat?

Yes, you read that correctly.

I don’t advocate that you take up yoga or work it out on the heavy bag or recite “calm blue ocean” or empathize or anything else.  If you find yourself miserable at work day after day because of a boss with whom you are fundamentally incompatible or if you find yourself googling “what to do about a bad boss” or if you find yourself writing to someone like me to ask for advice on what to do about your bad boss, you’re in a fundamentally awful position that’s probably shaving hours and days off of your life.

Whatever appeasement strategy upon which you may choose to embark is only going to mitigate that — it won’t alter it.  You need to take control of your destiny and that requires an executable, measurable, and tangible plan of action.

I’m not advising you to rage quit or do anything rash — that’s an awful plan (or perhaps a non-plan).  What I’m suggesting that you do is start laying out a sequence of events that removes this person from your life.

There are a lot of ways that this could happen.

Obviously, you could quit and work elsewhere, but you could also plan to stick it out until the boss retires in 18 months.  Perhaps you start taking classes at night so that you can transfer into a different group or maybe you find some team-lead type that acts as a buffer between you and Mr Spacely.

It could be that you do something as unusual as becoming a huge advocate for your boss to upper management so that he’ll get that promotion that will take him to another division or, at least, away from dealing with you directly.  Maybe you initiate controlled explosions inside of your own ears so that you never have to hear his terrible voice again and he can’t deal with you unless he learns sign language.

Go make yourself a brainstorming list — no idea short of criminal malfeasance too farfetched — and capture every imaginable path to your emancipation.  Once you’ve got that list in hand, start narrowing it down and firming it up until you have several strategies that you can work simultaneously, all timeboxed and with contingency plans.

You need to have measurable goals against which you can measure progress and you need to understand when to pivot.  A good plan would be something like:

“I’m going to get that certification that will make me a bit more cross functional and then I’ll start volunteering for work over in Bill’s group in my spare time.  Within 3 months of that, I’ll casually broach the subject of spending some time in that group and within 4 months, I’ll make it official.  While that’s going on, I’ll talk to HR within the next month about the idea of a potential transfer.  If after 4 months, none of that is going well, I’ll start interviewing for other positions.”

Now when you’re looking at your life, you’re not seeing an unending string of misery to be mitigated only with non-actionable platitudes like, “be more understanding” and “ask yourself if you aren’t partially responsible.”  Instead, you have a plan of action that you believe, if followed, will lead you to being happier.  Because here’s the thing — if you’re fundamentally incompatible with a boss then “who is responsible” is a non-starter and being more understanding isn’t really going to help.

There’s a Protestant Work Ethic, “Pain is Gain” underpinning to all of this that’s really not appropriate.  Is it an inappropriate sense of entitlement that must drive you to say, “I shouldn’t have to work somewhere that my boss makes me miserable?”  Many would argue yes, but I’m not one of them, and I think that’s silly.

If you’re overly picky or sensitive, you’ll wind up job hopping, getting stuck somewhere or, perhaps, have trouble finding work.  That’s how you pay the piper for being too picky or sensitive and, if those things start happening, maybe you should embark on a course of introspection.

But if you’re miserable under a boss, that’s real and there’s no way it’s entirely your fault.  It’s not your sole responsibility to figure out a way to prevent someone from making you miserable and you ought to view this as a no-fault problem to set about solving.  That’s where the plan comes in.

A boss is someone who should be removing impediments from your path to allow you to be as productive and awesome as possible.

That’s not feel-good BS — it’s the way to get the most value and productivity out of knowledge workers.  No boss that truly embraces this mandate should be making your life miserable, even if you are an over-sensitive, uber-picky prima donna.

If the boss is making you miserable on a daily basis then he’s an impediment and not an impediment remover.  Since you’re then responsible for removing your own impediments, there’s only one thing to be done with this boss: remove him from your life.

That’s All Well and Good…

I realize that this all probably sounds rash and maybe you think, “easy for you to say,” but it didn’t just happen to become easy for me to say.  I planned for it.

I’ve spent a lifetime optimizing for my own happiness and satisfaction with what I do and, when that temporarily wanes, due to a boss or anything else, I form a plan, follow it, and fix the problem.  And I do this by thinking in terms of diversification and dependency.

If you take a job at Acme Inc, settle in for a 10+ year stay, and let your resume gather dust, then you’re largely dependent on Acme Inc for your well being via income — you’re putting all of your eggs in that basket.  If Acme then burps out a bad manager and puts him above you in the org chart, you find yourself in the same position as a cable company customer: “yeah, we’re awful, but good luck doing anything else.”

If it seems daunting or hard to plan at this point, it’s because you’re pretty coupled to Acme.  You still can and should make a plan, by all means, but that’s why my advice might seem cavalier.

I have contingency plans all the time, and they range from W2 opportunities to 1099/B2B work to royalty streams to oddball, go-for-broke schemes like moving to the country to be a hermit and try my hand at writing novels.

Some of them are clearly more realistic or feasible than others, but they all exist and I’m in a constant state of assessing my happiness and weighing my options.

Don’t confuse this with fickleness or disloyalty in me and I’m not advocating those things in you.  If I could find something that made me consistently happy, work-wise, for the next 2 decades, I’d happily take the consistency and stability, and I cheerfully advise you to do the same.

But when life or companies throw crap situations at you don’t hesitate to start executing contingency plans to bring your happiness level back to where you want it.  Your happiness is something that you can’t count on anyone but you to monitor and it’s not just important to your quality of life — it’s important to your quality of output as a knowledge worker.  You and your reputation can’t afford for you not to be happy.

By

ChessTDD 20: Refactoring in Earnest

In this post, I set out to do some real refactoring of the Board class.  It bothered me enough to take a crack at it and, since this is a fun side project, there really aren’t any constraints.  Were I committed to delivering some business value here, I might need to take a look at my priorities and evaluate whether making things clearer here is worth the delay.  But, luckily in this case, I don’t need to make that call.  And, refactorings are always fun.

Here is what I accomplished in this clip:

  • Refactored a couple of methods out of Board and onto BoardCoordinate.
  • Refactored path checking logic into a PathChecker class.

Here are lessons to take away:

  • If you have functionality that’s purely static in some class (as in, not referring to instance variables in that class), think about where else it might go.  If that static method is principally interested in operating on properties or with methods of another type, you might have the “feature envy” code smell.  This was the case with my static methods that evaluated whether two BoardCoordinates were on the same horizontal or vertical path.  They compared properties on two different BoardCoordinates — so why not make this a member of BoardCoordinate?
  • This isn’t really something I’ve been emphasizing here, but early on I decided to do a quick local commit with Git.  Commit early and often.  I’ve never regretted too many commits unless I was using a terrible source control tool.
  • Defining  a class in the same space as another class is a tool that can help me with extract class refactorings.  This is one of the more volatile refactorings that you can do, so make sure you don’t try to do too much at one and that you get green regularly as you go.  Recreate the functionality faithfully first and then think about how to refactor.
  • If you can factor a method toward not referring to any instance state, then you’re well on the way to letting it be moved to a different class.  This is a good intermediate step to reason about — see how much instance state you can abstract out.
  • When you extract a class as part of a refactoring, it’s fine to leave the tests that cover both classes in place.  In fact, it’s a natural set of tests to leave.  Add tests for the newly created class only to address new complexities that arise from the newly exposed functionality needing to tighten up guard conditions and such.

By

Lessons from the College Days

I have two degrees (Bachelor’s and Master’s) in computer science, so it’s probably no surprise that I place a fairly high degree of value on the background that all of this course work provided. That being said, my experience was that you learn some pretty unfortunate ‘lessons’ in CS degree programs. To name some that I learned (and later had to unlearn):

  • Writing readable code is for weaklings.  Writing your entire loop logic inside the loop guard condition FTW!
  • You get partial credit for non-running (or even non-compiling) code if you add a lot of vacuous comments.
  • All programming projects can be wrapped up in a month or, in extreme cases, a semester.
  • Source control is an important thing, theoretically, but it doesn’t solve any actual problem you have.
  • There are no consequences to making an enormous mess of your code in the hour before your deadline as long as it hits the predefined benchmarks because you’ll never look at it again in your life.
  • Performance and accuracy of results are all that matter.
  • Staying up for 36 hours straight to wheeze across the finish line is how heroes get it done.
  • All you need to deliver is a bunch of source code files that compile.

First of all, I’d like to point out that these aren’t things that a professor sat me down and said at any point and, in fact, if shown this list, they’d probably say, “those things aren’t good lessons.” But these were the lessons I learned by virtue of the incentives to which I was exposed and how I was rewarded or penalized for my actions. There’s a lot of room for improvement, but I’ll come back to that later.

The common theme that drives this list of less-than-awesome lessons learned is that the academic environment and the theory that it tends to teach lend themselves to non-representative situations, contrived for the purpose of teaching a specific lesson, such as how to implement Alpha-Beta pruning or how state machines work. The best ways to drive these points of instruction home don’t correspond with workaday dev concerns like “write me a web service that triggers a database update and keep it relevant when I change my mind every month or so.”

But one lesson that I did take away that has served me very well is, “do what’s necessary to get a D instead of an F, save that off for reference, and once that’s secured, go for the C, save, etc.” In a lot of classes, we’d submit coding assignments that would run against some kind of benchmark, and it was something like, “if you satisfy 60 of the 100 conditions you get a D, 70 of 100 and you get a C, etc.” And I learned that you mitigated a lot of risk by making it your top priority not to fail or get a 0, and then improving from there. This way, if the time ran out, you’d be less like an action hero trying to defuse a bomb before the timer goes off and more like a fussy dog show entrant trying to put a few last minute touches on your dog that would improve its chances of being judged better than the other dogs, whatever that entails.

DogShow

This early lesson to which I was first exposed as an undergrad, around the time the Agile Manifesto was being written, was really the precursor to concepts like iterative development and thin-sliced, end-to-end goals for software. It taught me, through real, meaningful incentives, to make sure that I secured at least some value before chasing unicorns like an A+ off into the sunset. If there were 2 minutes left to submit the assignment, I wanted the backup plan to be an A- rather than a zero.

So what does any of this matter to you grizzled software veterans a decade or however long into your careers? Well, bear in mind that there’s always an A- (or B or C or whatever) out there when a bunch of work gets thrown your way. That web service you’re tasked with writing isn’t all or nothing. Not even a phone app that shows you the time is all or nothing (if push comes to shove, and app that tells you whether it’s AM or PM is better than nothing). Things can always be pared down and scope can always be adjusted, assuming you design towards modularity.

The overriding message of this post is that you should always, always, always look at the beginning for ways that you can secure yourself intermediate grades between 0 and A+ on the way to calling your software done; it’s the only reasonable way that you can manage expectations and adjust on the fly with a software project, apart from getting your customer to agree to indefinite delays. But, for a bit of fun, I’ll leave you with a series of ideas for how college CS curricula might better prepare students for actual development gigs. These might make you laugh to think about, but they’re actually things that could add some value:

  • One assignment in every programming class starts you off not from scratch or from professor-written template code, but from whatever pile of mess some students turned in last semester (teaches you what an unkindness it is to make a mess in code)
  • Every assignment requires students to update a single, shared text file whenever they’re testing against the benchmark and they get dinged if it gets out of sync (teaching about file contention and merge conflicts)
  • There are one or more assignments during the course of the curriculum that simply cannot be totally completed (teaches students to prioritize while working against unrealistic parameters)
  • There is some code that you carry over semester to semester and thus have to live with for years and/or there is a class where each assignment builds on the code of the last one but requires refactoring (teaches writing code with the idea of maintaining it)
  • Lock kids out of the computer lab between 1 and 6 AM.  (Teaches you that you’re going to work at places where juvenile heroics simply aren’t feasible for reasons ranging from the fact that this is a bad idea to the fact that the facility may be locked down at night)
  • All homework/project submissions are real-world deliverables along the lines of an actual phone app, web app or MSI installer (teaches that there’s more to delivering software than writing code)