Grabbing for good enough

by Rob Galanakis on 15/12/2014

Uncle Bob, who I consider my favorite programming writer, had a post a few weeks ago titled “Thorns around the Gold“. In it he describes how writing tests for your core functionality first can be harmful. Instead, Uncle Bob prefers to probe for “thorns” around the “gold” first.

I shy away from any tests that are close to the core functionality until I have completely surrounded the problem with passing tests that describe everything but the core functionality. Then, and only then, do I go get The Gold.

I haven’t been doing TDD for nearly as long as Uncle Bob but I was shocked to read this. I’ve always learned and taught that you should create positive tests first, and only need as many negative tests as you feel are warranted. While you may not grab the gold immediately, you at least step towards the gold. How many thorns you expose is a judgement call. In Python, most people don’t even bother validating for None inputs, and instead just let things raise (or not). Of course, this depends on your users. For libraries limited to one internal application, I wouldn’t “probe many hedges.” For open source libraries, I validate pretty aggressively.

Of particular interest was this:

I often find that if all the ancillary behaviors are in place before I approach the core functionality, then the core functionality is much easier to implement.

I always thought you should only program what you need and no more. It seems very strange to assume the ancillary behaviors will be needed. It seems like a violation of YAGNI.

I have been trying to reconcile Uncle Bob’s advice here, and the TDD best practices I’ve learned and developed. But I cannot. Either I’ve been receiving and giving years of bad advice, or Uncle Bob has made a rare mistake.

No Comments

Qt Designer is harmful, exhibit A

by Rob Galanakis on 11/12/2014

Last week, iker j. de los mozos posted a Qt tutorial on his blog. The post was retweeted a number of times, so I figure people liked it.

The post exemplifies what is wrong with the Qt Designer, and also how a little more investment in learning can pay dividends for your career.

I know it’s unfair to give people code reviews on things they just put out for free, but I consider it even worse to allow people to continue to use the Qt Designer with a clear conscience. I thank Ike for his post, and for syndicating his feed on Planet Tech Art, and hope that no one takes my writeup below personally. It’s not an attack on a person, it’s trying to point out there there is a much better way to do things.

There are 117 lines of Python code in Ike’s tool for locking and unlocking transformation attributes. This sounds like a small amount, but is for an experienced Pythonista it indicates huge waste. For comparison, the entire ZMQ-based request/reply client and server I built for Practical Maya Programming with Python is the same size or smaller (depending on the version). If we take a closer look at his code (see link above), we can see a ton of copy and pasted functionality. This is technically a separate concern from the use of the Designer, but in my experience the two go hand-in-hand. The duplication inherent in GUI tools carries over to the way you program.

Let’s look at some refactored code where we build the GUI in code (warning, I haven’t tried this code since I don’t have Maya on this machine):

from functools import partial
from PySide import QtGui
import pymel.core as pmc
import qthelpers

OPTIONS = [
    dict(label='Position', btn='POS', attr='translate'),
    dict(label='Rotation', btn='ROT', attr='rotate'),
    dict(label='Scale', btn='SCALE', attr='scale')
]

def setLock(obj, attr, value):
    obj.setAttr(attr, lock=value, keyable=not value)

def isAttrLocked(obj, attr):
    return obj.getAttr(attr, q=True, lock=True)

def toggleRowCallback(attr):
    obj = pmc.ls()[0]
    value = isAttrLocked(obj, attr + 'X')
    for axis in 'XYZ':
        setLock(obj, attr + axis, value)

def toggleCellCallback(attr, state):
    obj = pmc.ls()[0]
    setLock(obj, attr, state)

def makeRow(options):
    return qthelpers.row(
        [QtGui.QLabel(options['label'])] +
        map(lambda axis: qhelpers.checkbox(onCheck=partial(toggleCellCallback, options['attr'] + axis)), 'XYZ') +
        qhelpers.button(label='lock ' + options['btn'], onClick=partial(toggleRowCallback, options['attr']))
    )

def main():
    window = qthelpers.table(map(makeRow, OPTIONS), title='lockAndHide UI', base=QtGui.QMainWindow)
    window.show()

Why is this code better? Well, for starters, it’s less than a third of the size (37 lines) and there’s less duplication. These are very good things. When we want to change behavior- such as auto-updating the checkboxes when our selection changes- we can put it in one place, not nine or more.

So the code is better, but what other benefits are there to not using the Designer?
– We pull common primitives, like a “row” (QWidget with HBoxLayout) and “table” into a qthelpers module, so we can use this across all GUIs. This saves huge amounts of boilerplate over the long run, especially since we can customize what parameters we pass to it (like onClick being a callback).
– The GUI is clear from the code because the UI is built declaratively. I do not even need to load the UI into the Designer or run the code to understand it. I can just read the bottom few lines of the file and know what this looks like.
– You learn new things. We use functools.partial for currying, instead of explicit callbacks. This is more complicated to someone that only knows simple tools, but becomes an indispensable tool as you get more advanced. We are not programming in Turtle Graphics. We are using the wonderful language of Python. We should take advantage of that.

Again, I thank Ike for his blog post, and hope I haven’t upset anyone. Ike’s code is pretty consistent with the type of code I’ve seen from Technical Artists. It’s time to do better. Start by ditching the Designer and focusing on clean code.

4 Comments

The QA Department Mindset

by Rob Galanakis on 8/12/2014

From this post by Rands, titled “The QA Mindset”:

At the current gig, there’s no QA department. […]

My concern is that the absence of QA is the absence of a champion for aspects of software development that everyone agrees are important, but often no one is willing to own. Unit tests, automation, test plans, bug tracking, and quality metrics. The results of which give QA a unique perspective. Traditionally, they are known as the folks who break things, who find bugs, but QA’s role is far more important. It’s not that QA can discover what is wrong, they intimately understand what is right and they unfailingly strive to push the product in that direction.

I believe these are humans you want in the building.

At my current job, we don’t have a QA department either. And like Rands, I wasn’t comfortable at first. I’ve worked on teams without QA, but an entire company without a QA Department? I’ve certainly had questions about the use of a QA department, but does that mean they are a bad idea?

Yes, and this line in Rands’ defense is why:

Unit tests, automation, test plans, bug tracking, and quality metrics. The results of which give QA a unique perspective.

I am a staunch believer of “building quality in.” Every bug that slips out is a failure of your development process. The way to higher quality is not to find, or fix, more bugs. It’s to avoid them in the first place.

If you rely on QA to champion unit testing, automation, bug tracking, and quality metrics, your development process is lacking its most important tools and measures to improving quality. Quality can’t be imposed by QA, it must grow out of enabled and engaged development teams.

I have a saying: “Don’t hire to fix a problem.” If you have a quality problem, hiring a QA department isn’t going to fix it. You instead hide the systematic problems that cause quality issues in the first place.

This is not to say “the QA mindset” isn’t valuable. It is. One of my best hires was Bjorgvin Reynisson, who was a Test Engineer at Nokia and I hired as a QA Engineer at CCP. He was embedded with the graphics engine team and he helped them develop extensive automated correctness and performance testing systems. He worked with them to recognized holes in their process and test coverage. He helped with tracking issues and increasing quality. This is the “QA Mindset” I treasure, and this type of person is invaluable to development teams. Bjorgvin unlocked a latent “culture of quality” in the team he was a part of.

I contrast this “QA Mindset” with the “QA Department Mindset“. The QA Department Mindset has two damning characteristics. First, it is innately adversarial, as Rands notes.

Yes, there is often professional conflict between the teams. Yes, I often had to gather conflicting parties together and explain[…]

Second, it is by definition a separate department, which creates obstacles to better integrating engineering and QA.

Bjorgvin should be spending time with his teammates and the rest of the developers figuring out how to improve the entire development process. He should not be spending time with other QA personnel focused on QA functions. When I was Technical Director for EVE Online, I made sure there were minimal discussions gated by job title. Talk of a trade went on in Communities of Practice, which were open to all. Sometimes this didn’t happen, and those times were mistakes.

Like Rands says:

Yes, we actually have the same goal: rigorously confirming whether or not the product is great.

If that’s the case, QA should not be broken out into a separate department. QA should be working side by side, reporting into the same people, measured by the same success metrics, contributing to the holistic success of an entire product.

I love the QA Mindset. It’s tragic that having a QA Mindset gets confused with having a QA Department.

2 Comments

Long live Slack, down with egotistical email

by Rob Galanakis on 17/11/2014

We use Slack for team communication at Cozy. I struggled with the transition. When I reflected on my struggles, it made me better understand what a destructive format email is for workplace communication.

A quick disclaimer. This is only about work communication and not personal communication. I love email. I think email will be around for a long time and I will lament if and when it goes away. I just don’t think we should be using email for work.

Oration is the highest form of feeding an ego. You craft your message carefully. You research, write, and rehearse. Finally, you take the stage. You command everyone’s attention. And once you’re done, an important topic has been thoroughly addressed and everyone can go on with their lives, better off after hearing what you said.

Email is oratory without the speaking* (or skill). My problems with email stem from when it is used for one-way communication. I suspect that most emails I’ve ever received from anyone in management have been one-way. Generally these emails are meant to, first and foremost, communicate the sender/manager’s self-importance. Often the email contains a nugget of actual information which should be hosted elsewhere. Sometimes the email is an announcement no one understands. And as a rule, you can’t rely on people reading the email you send anyway.

When you craft a long email, like an orator crafts a speech, it is an ego boost. Each one is a masterpiece. You are proud of your fine writing. When you craft a long chat message, on the other hand, you look like a dramatic asshole. It puts in stark perspective how awful the written format is for important or high-bandwidth communication. I’ve never seen someone post a 300-word message to chat. How many 300-word emails do you have in your inbox?

Removing email also levels the playing field for communication. You don’t need to be a manager or orator. Everything you write has a visibility you can’t change. You choose your audience based on topic. Is there a question about a product’s design? Well, it goes into the product or design channel, whether you are Executive Emperor or QA Associate II. Also, no one really wants to read your dramatic flair so please keep it short and to the point.

I used to get frustrated when I’d write an excellent email, send it out, and within a few minutes someone would reply with a message like “Yeah, just to build on what Rob said, it’d be a good idea to do X.” You idiot! You are an Ice Cream Truck driving through the State of the Union. But of course, the problem was mine, playing a manipulative game, focusing too much on this amazing message I’d created. Sometimes these emails would be about the manipulative games people were playing and how we weren’t focused on the employees and customers and things that were actually important.

Email in the workplace is a systematic problem. We take it for granted. We use it constantly. We don’t question it. But email has a cost. It feeds into the already inflated ego of managers. It encourages one-way communication. It is wonderful for grandstanding. We spend a lot of time crafting museum-quality correspondence no one wants to read. And in the end, there are better ways to accomplish what we use it for.


* One of the greatest “speeches” of all time, Pro Milone by Cicero, was written, not spoken. We know great orators by their writing, not their speaking.

No Comments

First, do no harm

by Rob Galanakis on 13/11/2014

From a wonderful post by Matt Williams about the type of business he is looking for:

A Business Manifesto
We are uncovering better ways of running a business and helping others do it.
Through this work we have come to value:
People and interactions over profits and prestige
Quality service over quantity of service
Customer relationships over contract negotiation
Flexibility over following a plan
That is, while there is value in the items on the right, we value the items on the left more.

In a nutshell I want to work for a company which values people — both inside and out of the company. I want to work where people strive to do things right.

When I go home, I want to be able to look in the face of my daughter and not have to make excuses for the work that I do and the effect it has on others.

Sums things up nicely (and definitely what we aspire to at Cozy, by the way we’re hiring).

It is a reason I left the video games industry. I wanted to use my skills to do something I felt was more constructive.

But more than that, I was amazed and frustrated with how the industry was run (almost as bad as films). Mass layoffs even on successful projects. Over-managed projects that go on for 4, 5, 6 years and are cancelled. Creating an exploitative product in order to milk a customer base. Huge budgets, huge marketing, appeals to lowest common denominators (often sexual). There are good companies but the business models are so insane that you can be around for 10 years and fold tomorrow.

2 Comments

Behavioral testing is the bee’s knees

by Rob Galanakis on 10/11/2014

I have been doing Test Driven Development (TDD) with xUnit-based frameworks (like unittest and NUnit) for a number of years now, and started with RSpec in Ruby and Jasmine in JavaScript a few months ago. RSpec and Jasmine are behavioral testing frameworks that facilitate Behavioral Driven Development (BDD). BDD is really no different from “normal” TDD except for the frameworks used. BDD frameworks facilitate a different way of designing tests.

Behavioral testing is awesome and makes xUnit-style testing seem barbaric and uncivilized in comparison. I didn’t see the big deal for a long time. My xUnit style tests served me just fine. But now I’m hooked.

If you are a TDD person (or do any unit testing), I encourage you to try out BDD. You should get the hang of it quickly. It can take a little while to learn BDD idioms, but once you start doing things like custom matchers, it’s absolutely amazing.

In future posts I’ll try to discuss more of the differences between TDD and BDD, but for now I just provide a hearty endorsement of BDD and frameworks like RSpec and Jasmine.

3 Comments

If you hear “perception is reality” you’re probably being screwed

by Rob Galanakis on 27/10/2014

I was once told in a performance review that “perception is reality.” I was infuriated, and the words stuck in my mind as the most toxic thing a manager could say to an employee. I have avoided writing about it, but the “This American Life” episode about Carmen Segarra’s recordings at the Fed has inspired me to change my mind. Here’s the relevant section, emphasis mine:

Jake Bernstein: Carmen says this wasn’t an isolated incident. In December– not even two months into her job– a business line specialist came to Carmen and told her that her minutes from a key meeting with Goldman executives were wrong, that people didn’t say some of the things Carmen noted in the minutes. The business line specialists wanted her to change them. Carmen didn’t.

That same day, Carmen was called into the office of a guy named Mike Silva. Silva had worked at the Fed for almost 20 years. He was now the senior Fed official stationed inside Goldman. What Mike Silva said to Carmen made her very uncomfortable. She scribbled notes as he talked to her.

Carmen Segarra: I mean, even looking at my own meeting minutes, I see that the handwriting is like nervous handwriting. It’s like you can tell. He started off by talking about he wanted to give me some mentoring feedback. And then he started talking about the importance of credibility. And he said, you know, credibility at the Fed is about subtleties and about perceptions as opposed to reality.

Well shit, if that doesn’t sound familiar. Here I was, doing work that was by all measures extremely successful, yet pulled into a feedback meeting to be told “perception is reality.”

Let me tell you what “perception is reality” means, and why you should plan on leaving your job the moment you hear it:

The arbitrary opinions of your manager’s manager defines your situation. And they don’t like what you’re doing.

Your manager may be well-meaning (mine was, as was Mike Silva), but at the point you get this “perception is reality” bullshit, you can be sure there’s nothing that they are going to do to help you. Someone above them has taken notice, your manager has probably heard hours of complaints, and you can either shut up or get out. Perception isn’t reality everywhere; it is only the mantra in sick organizations totally removed from reality.

1 Comment

Technical debt takes many forms

by Rob Galanakis on 23/10/2014

Most people are familiar with “technical debt” in terms of code or architectural problems that slow down development. There are other forms of technical debt, though, that can be overlooked.

Dead Code: There are endless “dead code as debt” scenarios. You have a “live” function that is only used from dead code, hiding the fact that this function is also dead (this situation is cancerous). Every time you grep, you have to wade through code that is dead. Every time someone stumbles across the dead code, they need to figure out if it’s dead or alive. There’s no reason for any of this (especially not “keep it around as reference”). Dead code is a debt, but it’s also easy to pay back. Remove your dead code.

Unused Repos or Branches: Every time a new person starts, they will ponder what code is dead and what is alive. This pondering includes code, issues, and documentation. It is sloppy and unnecessary. Put unused repositories in cold storage. Delete stale branches.

Large Backlog: The larger the backlog, the worse the experience of using it. It’s harder to find, reclassify, and prioritize. Some developers will not even bother. A backlog is not a place for everyone to list anything they think should ever be done. Close stale and low-priority tickets. Close “symptom” tickets that you know won’t be addressed until a system is rewritten. Close everything except 3 months of work (and manage further out work on your roadmap, which should not be in your backlog).

Dirty Wikis/Documentation: Why out of date documentation is harmful should be pretty self-explanatory. Don’t let it get that way (or just delete the documentation). Make documentation someone’s responsibility, or make it part of the “definition of done.”

Every organization has these things. By recognizing them as debt, and thus detrimental to development, it can perhaps simplify any argument about what to do.

3 Comments

PracticalMayaPython: RuntimeError: Internal C++ object (PySide.QtGui.QStatusBar) already deleted.

by Rob Galanakis on 19/10/2014

TLDR: If you get that error for the code on page 163, see the fix at https://github.com/rgalanakis/practicalmayapython/pull/2/files

In August, reader Ric Williams noted:

I’m running Maya 2015 with Windows 7 64-bit. On page 163 when we open the GUI using a Shelf button, the GUI status bar does not work, (it works when called from outside Maya). This RuntimeError appears: RuntimeError: Internal C++ object (PySide.QtGui.QStatusBar) already deleted.

I no longer have Maya installed so I couldn’t debug it, but reader ragingViking (sorry, don’t know your real name!) contributed a fix to the book’s GitHub repository. You can see the fix here: https://github.com/rgalanakis/practicalmayapython/pull/2/files
And you can see the issue which has more explanation here: https://github.com/rgalanakis/practicalmayapython/issues/1

Thanks again to Ric and ragingViking. I did my best to test the code with various versions of Maya but definitely missed some things (especially those which required manual testing). If you find any other problems, please don’t hesitate to send me an email!

No Comments

High performance, poor morale, and the Niko-niko calendar

by Rob Galanakis on 2/10/2014

I was introduced to Niko-niko calendars by Max Webster at Niko Niko. Basically, they are a way of tracking a team’s mood over time. At the end of the day, team members put in a smile/frown/whatever face indicating their mood. You can see when people were happy or sad and coordinate that with other events (what tasks they were working on, what happened at work, etc.).

Initially, I thought this was a pretty useless metric. What good leader or manager wouldn’t always know this information? I can tell if things are going well because I speak to the team regularly as I make changes. But it can be useful to track mood for when things get lost in the cracks or regress. It’s also useful as an outside-facing metric, to show people how their decisions impact the team. The more I thought about it, the more I wished I had known about Niko-niko calendars earlier!

I would only consider Niko-niko effective on an already well-performing and generally happy team. It is a pretty high-level metric, so if people are unhappy for many reasons, I doubt you’ll get much useful data. So, with that, how about some scenarios that I would have used a Niko-niko calendar for, had I known about them?

  • Process tweaks like shortening sprints or requiring more code reviews. People are resistant at first but usually accept it. Is this because they get happier over time? Or because they do not feel empowered to change things back?
  • Changing the branching/integration strategy. At previous jobs we seemed to have a new one every six months. At my current job there are fans and detractors of git flow. Does morale go down or stay the same when integrations happen more often? Is this better or worse depending on the branching/integration strategy?
  • How much do people actually hate planning days, and what can we do to improve them?
  • How painful are releases? People should be happiest, not unhappy, before and after a release!
  • Does a team hate what it’s doing? How much does dumping work on a team impact morale? Do they not believe in the product or are expectations out of whack? What can be done to help the team “own” the project rather than resent it?
  • How does changing team composition cause morale to be affected?

I’m sure there are more, but I thought the idea of using a Niko-niko chart could be interesting. I won’t have a chance to try one out for a while, but will post a followup after I do.


I wrote this draft a couple months ago and finished it recently. Since then I’ve seen a few other apps in a similar space, such as Know Your Company and Know My Team, that focus on tracking morale. I think it’s a good trend. And it’s a reminder that what may appear as a management fad can often have deep, established roots.

No Comments