how to use conscious purpose without wrecking everything

is the title of the truly fantastic talk John Gall gave at Tom Gilb's annual Gilbfest a few weeks ago. You can read the whole thing here. Here's a small selection of the many snippets that spoke to me:
Maximizing efficiency is the error of having a single goal, what William Blake once called “Newton’s sleep.”
Always the more beautiful answer who asks the more difficult question [e.e.cummings]
Evolution always means Co-evolution. The horse eats the grass, the grass grows stronger roots, the horse grows stronger jaws.
What is involved is not simply survival of the fittest, but survival of the fitting-in-est.
The amount of feedback that is built into living organisms differs by many orders of magnitude from the amount that we build into manmade systems.
Flexibility means the willingness to act in response to the feedback message by actually changing how the system works.
There are many Potemkin Villages in operation today, hiding and distracting us from awareness of what’s really going on.
Ignoring feedback merely means that the system will eventually experience a massive unpleasant surprise rather than a small unpleasant surprise.
As Bradford Keeney pointed out, stability is not homeostasis, it’s homeodynamics.
Once you get above that first level, the level of material things and forces, you are dealing with abstractions. In place of physical forces, you have communication—messages, signals. And in place of material things, you have relationships—which are abstractions.
Once we get above the level of physical objects and forces, we are dealing with patterns of interaction, that is, with abstractions.
Abstractions — that is, ideas — don’t die. They can’t be killed. They can’t be exterminated. They just keep coming back, over and over and over. This problem can never be solved if one continues to believe that the so-called "real" world of physical objects and forces is all there is. The Chinese have a word for this. They call it "being stuck in the ten thousand things."
In order to become birds, dinosaurs had to give up being dinosaurs.
If I design a system with no regard for the universe that surrounds it, I will have scanty knowledge of what can impact it.


barbel fishing


My latest Barbel fishing trip was to the River Wye on the Middle Hill Court beat. I caught this 10lb 1oz beauty (that's 4.5kg in old money). My first double!

Winnie-the-Pooh

is an excellent book by A.A.Milne (isbn 978-1405223980). As usual I'm going to quote from a few pages:
Here is Edward Bear, coming downstairs now, bump, bump, bump, on the back of his head, behind Christopher Robin. It is, as far as he knows, the only way of coming downstairs, but sometimes he feels that there really is another way, if only he could stop bumping for a moment and think of it.
He was getting rather tired by this time, so that is why he sang a Complaining Song.
"What do you want a balloon for?" you said.
Winnie-the-Pooh looked round to see that nobody was listening, put his paw to his mouth, and said in a deep whisper: "Honey!"
"But you don't get honey with balloons!"
"I do," said Pooh.
"I have just been thinking, and I have come to a very important decision. These are the wrong sort of bees."
"I mean," said Rabbit, "that having got so far, it seems a pity to waste it."
Christopher Robin nodded
"Then there's only one thing to be done," he said. "We shall have to wait for you to get thin again."
"How long does getting thin take?" asked Pooh anxiously.
"About a week, I should think."
He sat down and thought, in the most thoughtful way he could think. Then he fitted his paw into one of the Tracks … and then he scratched his nose twice, and stood up.
"Yes," said Winnie-the-Pooh.
"I see now," said Winnie-the-Pooh.
"I have been Foolish and Deluded," said he, "and I am a Bear of No Brain at All."
"You're the Best Bear in All the World," said Christopher Robin soothingly.
"Am I?" said Pooh hopefully. And then he brightened up suddenly.
"Anyhow," he said, "it is nearly Luncheon Time."
So he went home for it.
Pooh felt that he ought to say something helpful about it, but didn't quite know what. So he decided to do something helpful instead.
But Owl went on and on, using longer and longer words, until at last he came back to where he started...
"You don't often see them," said Christopher Robin.
"Not now," said Piglet.
"Not at this time of year," said Pooh.
Owl was explaining that in a case of Sudden and Temporary Immersion the Important Thing was to keep the Head Above Water.
Owl hasn't exactly got Brain, but he Knows Things.
It wasn't what Christopher Robin expected, and the more he looked at it, the more he thought what a Brave and Clever Bear Pooh was.

Tragically I was an only twin

subtitled The Complete Peter Cook is an excellent book by (isbn 0-09-944325-2). As usual I'm going to quote from a few pages:

Builders of Xanadu (Saturday Live, Channel 4, 1986)
...
John Bird: Got the job then?
Peter Cook: Yes, got the job.
John Bird: Big one?
Peter Cook: Well, fairly big. He's got very grandiose in his old age, Kubla has.
John Bird: Well what does he want? An extension?
Peter Cook: No, no. More than that. He wants a pleasure dome.
John Bird: Nice. What sort of pleasure dome did he have in mind?
Peter Cook: Well, he was a bit vague about it. He rambled on a bit. The only adjective I got from him was 'stately'. In fact, that's what he decreed.
John Bird: Oh, he's decreeing things now then, is he?
Peter Cook: Certainly. No pissing about with planning permission for Kubla. If he wants a stately pleasure dome, wallop! He decrees it.
John Bird: Yes, well why not?
Peter Cook: Why not, at his age?
John Bird: Did you bung him an estimate, then?
Peter Cook: No, it's a bit tricky, you see.
John Bird: What's the problem? A pleasure dome's straightforward enough. I don't know about this 'stately' though. What's this 'stately'? That's new to me. What's that? Plants? Hammocks? Not structural, is it?
Peter Cook: No, it's not structural, 'stately'. It's more of an ambience sort of area.
John Bird: Well then, we'll just budget for a regular pleasure dome, and see if we can pick up some stately trimmings down the market.
...
Peter Cook: ... Part of his decree, vis-à-vis the stately pleasure dome, is he has this bloody sacred river Alph running through the structure.
John Bird: A sacred river?
Peter Cook: Running right through the structure. He specified that.
John Bird: We'll need a plumber then. I can have Ronnie bodge up a river for you and we can bung up a sign saying 'Sacred River of Alph'. Something along those lines.
Peter Cook: Yes, but we've still got a problem with his specifications.
John Bird: What's that, then?
Peter Cook: These caverns he wants.
...
Peter Cook: ... with these caverns, you see, he's specified, here, on the docket there, 'measureless to man'.
John Bird: Measureless? He wants caverns you can't measure?
Peter Cook: Yes.
...

Dancing with elves

subtitled Parenting as a Perfoming Art, is an excellent book by John Gall (isbn 978-0-9618251-4-0). As usual I'm going to quote from a few pages:
No one can avoid influencing others. The only question is whether we are going to do it knowingly or unknowingly. Our position is that knowledge is better than ignorance.
Command-and-control tries to get 100% compliance - an impossible goal. In the name of discipline, it teaches rigidity.
The mother bird repeats the sequence over and over, with endless patience, until the children learn. You never see a mother bird attack her offspring; you never see her punish her baby for failure to learn the lesson. When the adult animal teaches their offspring, it is done by one method and that is by modelling over and over the desired behaviour.
Talking about your own experiences causes others to access their own similar experiences. I wish I could get across to you how powerful this effect is and how silently it operates.
Words have this incredible power to call up experience.
What a momentous thing you are doing when you speak words to your child or to your spouse or to any other person. You have the power to create their experience, you have the power to shape it, to make it beautiful. You can give them the experience of competence, of comfort, of success.
Somewhere between the first week of life and age forty or fifty, something rather serious happens. We stop using our feedback. We're carefully taught to pay attention to the program inside our head, instead of what's happening in the real world.
When you speak to someone, they split into two pieces. This happens all the time, to everybody. There's a part that wants to go along with what you say, and then there's a part that wants to defend their individuality, they're not going along. There's the part that agrees, and a part that disagrees, simultaneously.
It obviously doesn't make sense to demand impulse control from a little person that doesn't have it.
If you see "stubbornness" then you're naturally going to expect certain things. You're going to act in certain ways, you're going to get an interaction started that assumes this.
What does it mean when you say a person is "just lazy?" or "just stubborn?". It really means that you have tried out some of your repertoire of behavioural interventions in order to elicit a desired piece of behaviour from the other person and you have failed, because your repertoire was too limited.

The Tao of Pooh

is an excellent book by Benjamin Hoff (isbn 1-4052-0426-5). As usual I'm going to quote from a few pages:
Cottleston, Cottleston, Cottleston Pie,
A fly can't bird, but a bird can fly.
Ask me a riddle and I reply:
Cottleston, Cottleston, Cottleston Pie.
It is useless to you only because you want to make it into something else and do not use it in its proper way.
One disease, long life; no disease, short life.
Unlike other forms of life, though, people are easily led away from what's right for them, because people have Brain, and Brain can be fooled. Inner Nature, when relied on, cannot be fooled. But many people do not look at it or listen to it, and consequently do not understand themselves very much. Having little understanding of themselves, they have little respect for themselves, and are therefore easily influenced by others.
For a long time they looked at the river beneath them, saying nothing, and the river said nothing too, for it felt very quiet and peaceful on this summer afternoon. [A.A.Milne]
I think therefore I am Confused.
All work and no play makes Backson a dull boy.
"But you should be something Important," I said.
"I am," said Pooh.
"Oh? Doing what?"
"Listening," he said.
the Bisy Backson Society, which practically worships youthful energy, appearance, and attitudes.
It's really fun to go somewhere where they are no timesaving devices because, when you do, you find that you have lots of time.
We are determined to be starved before we are hungry. [Henry David Thoreau]
From caring comes courage [Tao Te Ching]
...too many who think too much and care too little.


Experiential Learning 2: Invention

is an excellent book by Jerry Weinberg. There's no isbn - you can buy it from Leanpub. As usual I'm going to quote from a few pages:
At intervals, keep adding members from the observer corps to each team and observe how each team handles the additional members.
They were… concentrating with their eyes closed (that is, sleeping).
Everything that happens in an exercise is an experience; and every experience provides an opportunity for learning.
Let the students design a slide show of their learnings, and present it to you.
If you were to run this exercise again, with observers chosen before the exercise started, what would you instruct the observers to keep track of? How would you process those data once the exercise was finished?
If you can’t find a regular pattern of some time for self-observation, your leadership development program is in serious trouble.
Have each participant make a "sandwich board" on a large sheet of paper saying:
1) what I'm seeking in teammates
2) what I have to offer my teammates
When standing aside at some distance, we can often see what we couldn’t see up close - that the whole structure is about to collapse, and that additional work will just be wasted work.

the book of tea

is an excellent book by Kakuzo Okakura (isbn 0-486-200070-1). As usual I'm going to quote from a few pages:
One of the cardinal concepts of Oriental thought, from even before the time of Confucius, has been the belief that alternating, diametrically opposed forces govern the universe, like day and night.
Those who cannot feel the littleness of great things in themselves are apt to overlook the greatness of little things in others.
The art of life lies in a constant readjustment to our surroundings.
We must know the whole play in order to properly act our parts; the conception of totality must never be lost in that of the individual.
Truth can be reached only through the comprehension of opposites.
It is much to be regretted that so much of the apparent enthusiasm for art in the present day has no foundation in real feeling.
We classify too much and enjoy too little.

sliming and refactoring and deliberate duplication



Suppose I'm doing the Print-Diamond kata in Ruby:
Given a letter print a diamond starting with 'A' 
with the supplied letter at the widest point. 
For example: print-diamond 'E' prints
    A
   B B
  C   C
 D     D
E       E
 D     D
  C   C
   B B
    A
I start with a test
def test_diamond_A
  assert_equal ['A'], diamond('A')
end
which I pass using
def diamond(widest)
  ['A']
end
I add another test
def test_diamond_B
  assert_equal [' A',
                'B B',
                ' A'], diamond('B')
end
which I pass using
def diamond(widest)
  if widest == 'A'
    return ['A']
  end
  if widest == 'B'
    return [' A',
            'B B',
            ' A']
  end
end
I add one more test
def test_diamond_C
  assert_equal ['  A',
                ' B B',
                'C   C',
                ' B B',
                '  A'], diamond('C')
end
which I pass using
def diamond(widest)
  if widest == 'A'
    return ['A']
  end
  if widest == 'B'
    return [' A',
            'B B',
            ' A']
  end
  if widest == 'C'
    return ['  A',
            ' B B',
            'C   C',
            ' B B',
            '  A']
  end
end
The tests have already proved valuable:
  • I've decided I don't want to actually test printing
  • I've chosen the result format - an array of strings
  • I've chosen not to embed newlines at the end of the strings
  • I've something to refactor against
However, there is no point in carrying on sliming. As the tests get more specific, the code should get more generic. I have three specific tests, but the code is equally specific. I need to generalize the code.

While coding the array of strings for the 'C' case I found myself copying the result for 'B' and modifying that. Specifically, I had to:
  • duplicate the 'B B' string
  • add a space at the start of the ' A' and 'B B' strings
  • add a new middle string 'C C'
This gave me the idea to try a recursive implementation. My first step was to refactor the code to this:
def diamond(widest)
  d = inner_diamond(widest)
  mid = d.length / 2
  d[0..mid-1] + d[mid+1..-1]
end

def inner_diamond(widest)
  if widest == 'A'
    return ['A',
            'A']
  end
  if widest == 'B'
    return [' A',
            'B B',
            'B B',
            ' A']
  end
  if widest == 'C'
    return ['  A',
            ' B B',
            'C   C',
            'C   C',
            ' B B',
            '  A']
  end
end
This looks a promising step towards a recursive solution - to make the implementation of 'C' contain the implementation of 'B' and then add strings only for 'C'. So, remembering what I had to do when copying and modifying, I refactored to this:
def inner_diamond(widest)
  if widest == 'A'
    return ['A',
            'A']
  end
  if widest == 'B'
    return [' A',
            'B B',
            'B B',
            ' A']
  end
  if widest == 'C'
    b = inner_diamond('B')
    upper,lower = split(b.map{ |s| ' ' + s })
    c = widest + '   ' + widest
    return upper + [c,c] + lower
  end
end

def split(array)
  mid = array.length / 2
  [ array[0..mid-1], array[mid..-1] ]
end
From here I verified the recursive solution works for 'B' as well:
def inner_diamond(widest)
  if widest == 'A'
    return ['A',
            'A']
  end
  if widest == 'B'
    a = inner_diamond('A')
    upper,lower = split(a.map{ |s| ' ' + s })
    b = widest + ' ' + widest
    return upper + [b,b] + lower
  end
  if widest == 'C'
    b = inner_diamond('B')
    upper,lower = split(b.map{ |s| ' ' + s })
    c = widest + '   ' + widest
    return upper + [c,c] + lower
  end
end
Now I worked on generalizing the use of the hard-coded argument to inner_diamond() and the hard-coded number of spaces:
def inner_diamond(widest)
  if widest == 'A'
    return ['A','A']
  end
  if widest == 'B'
    a = inner_diamond(previous(widest))
    upper,lower = split(a.map{ |s| ' ' + s })
    n = (widest.ord - 'A'.ord) * 2 - 1
    b = widest + (' ' * n) + widest
    return upper + [b,b] + lower
  end
  if widest == 'C'
    b = inner_diamond(previous(widest))
    upper,lower = split(b.map{ |s| ' ' + s })
    n = (widest.ord - 'A'.ord) * 2 - 1
    c = widest + (' ' * n) + widest
    return upper + [c,c] + lower
  end
end

def previous(letter)
  (letter.ord - 1).chr
end
Now I collapsed the duplicated specific code to its more generic form:
def inner_diamond(widest)
  if widest == 'A'
    return ['A','A']
  else
    a = inner_diamond(previous(widest))
    upper,lower = split(a.map{ |s| ' ' + s })
    n = (widest.ord - 'A'.ord) * 2 - 1
    b = widest + (' ' * n) + widest
    return upper + [b,b] + lower
  end
end
Finally some renaming:
def inner_diamond(widest)
  if widest == 'A'
    return ['A','A']
  else
    inner = inner_diamond(previous(widest))
    upper,lower = split(inner.map{ |s| ' ' + s })
    n = (widest.ord - 'A'.ord) * 2 - 1
    middle = widest + (' ' * n) + widest
    return upper + [middle,middle] + lower
  end
end
To summarise:
  • When sliming I try to think ahead and choose tests which allow me to unslime the slime.
  • If I have slimed 3 times, my next step should be to unslime rather than adding a 4th gob of slime.
  • My first unsliming step is often deliberate duplication, done in a way that allows me to collapse the duplication.


Experiential Learning 1: Beginning

is an excellent book by Jerry Weinberg. There's no isbn - you can buy it from Leanpub. As usual I'm going to quote from a few pages:
This is a very simple exercise, but it will get people talking about process improvement.
If there is no provocation, there is no learning. ... We must first put our students into a provocative environment. We must encourage them to experiment - to play with the materials in that environment.
In many traditional courses, the only significant observation made is pass/fail on the test.
By the mathematical properties of averaging, almost all teams will perform "better" than almost all individuals - simply because they are more average. … All we are measuring is how much closer an average answer is likely to be to another average answer which is essentially a tautology.
People are more ready to accept your facts than your opinions, so be very careful to separate observation (news) from interpretation and significance.
Be patient with silence. Usually a long silence comes just before a breakthrough idea.
Different people on each team learned different things from the same trial of the same exercise. This is characteristic of well designed and well led experiential exercises.
Leaders are not in complete control of what participants are going to learn. Are you going to be able to live with that?
The strongest way to achieve safety in experiential exercises is by making clear that every exercise is optional. If someone doesn't want to participate, they are always free to step aside without explaining their reasons, and without any attempts to persuade or cajole. If someone wishes to opt out, then the learning leader should invite them to take an observer role, but they may opt out of that, too.
You can't just pop experiential exercises at people regardless of the context, so pay special attention to the very first exercise you do with a group.
There must be a bazillion ways to form teams, but we've tried only half of them.

The principles of product development flow

is an excellent book by Donald Reinersten (isbn 978-1-935401-00-1). As usual I'm going to quote from a few pages:
Operating a product development process near full utilisation is an economic disaster.
When we emphasise flow, we focus on queues rather than timelines.
Almost any specialist can become a queue.
We grow queues much faster than we can shrink them.
When queues are large, it is very hard to create urgency.
Queues amplify variability. Moving from 75 to 95% utilisation increases variability by 25 times.
Sequential phase-gate processes have inherently large batch transfers.
Large batches encourage even larger batches.
Reducing batch size is usually the single most effective way to reduce queues.
Companies inevitably feel they can computerise this whiteboard, however, they almost always create a more elegant but less useful system.
The speed of feedback is at least two orders of magnitude more important to product developers than manufacturers.
The human effect of fast feedback loops are regenerative. Fast feedback gives people a sense of control; they use it, see results, and this further reinforces their sense of control.
Homeostasis is the tendency of a system to maintain its current state.
In product development, our problem is virtually never motionless engineers. It is almost always motionless work products.
Opportunities get smaller with time, and obstacles get larger.
The scarcest resource is always time.
To align behaviours reward people for the work of others.
It has been said that one barbarian could defeat one Roman soldier in combat, but that 1,000 Roman soldiers could always defeat 1,000 barbarians.
The Marines, and all other elite organisations, maintain continuity in their organisational units.


Olve's uncle

Yesterday, whilst stuck in a traffic jam, my great friend Olve Maudal told me a wonderful story about his uncle. Olve's uncle lived in the country. He didn't much care for the city. He felt the city folk were always in a rush. Often too busy to remember basic courtesy. One day he had to go into the city so he got into his old Volvo and set off. In the middle of the city the old Volvo stalled. He tried restarting it several times with no luck. Then the driver behind him starting tooting his horn. Olve's uncle calmly opened his door, got out his car, and walked towards the tooting driver. Olve's uncle explained to the driver that his old Volvo wouldn't start, and, offering him the car key, asked him if he knew how to get it started. The driver immediately, and in a friendly manner, said yes and took the key. As the tooting driver started walking towards the old Volvo, Olve's uncle said, "I'll wait here and toot your horn for you".

practising

Last week I attended a two day course on the banks of the River Tay learning to speycast using a 15 foot double handed rod. I learned it quickly and effectively, for three reasons:
  • First, I was taught by a great tutor, Gary Scott. Not only is Gary a world champion spey caster he is also a really great teacher and a thoroughly nice bloke to boot.
  • Second, I had almost no previous experience of fly-fishing for trout. This was very helpful as I had no bad habits to unlearn. In contrast, some of the other anglers who attended Gary's course were experienced trout fly-fishers. Gary would correct some particular movement and for a few casts they would do the new movement - but then Gary would move along to help the next angler and soon they dropped back into muscle-memory-mode and had lost the new movement.
  • Third, when I started Gary made sure I did not have a hook tied to the end of the line. This would have been plain dangerous before I had at least some control. Having a small piece of wool instead of the hook meant I was not thinking about catching a salmon; I was thinking only about improving my casting technique. In contrast the other anglers on the course started with a hook and their efforts to improve their casting were inevitably watered down by their desire to catch a salmon.


red-green starts with red

Suppose I've written a test and got it passing...
@Test
public void yahtzee_full_house_scores_25() {
  assertEquals(25, 
    new YahtzeeScorer(4,4,3,4,3).fullHouse());
}
After refactoring I write my next test...
@Test
public void yahtzee_not_full_house_scores_0() {
  assertEquals(0, 
    new YahtzeeScorer(4,4,4,4,4).fullHouse());
}
And this passes first time. That is, it passes without failing first. One of the reasons for failing first is to be sure the test is actually running. For example, suppose I'd forgetten to write @Test and didn't notice that the JUnit output wasn't showing one more test passing. Ooops. A question I've been asked on several occasions is whether, in this situation, you should change the code or the tests to force an initial red. For example, my first version of the yahtzee_not_full_house_scores_0 could have been this, (where I've deliberately used 42 instead of 0 simply because 42 is a good example of a number that is not 0):
@Test
public void yahtzee_not_full_house_scores_0() {
  assertEquals(42, 
    new YahtzeeScorer(4,4,4,4,4).fullHouse());
}
I see it fail, and then change the 42 to 0 and see it pass. This works, and I have done this. Perhaps you have too. If so, do you agree that it doesn't feel right? I've learned that when something doesn't feel right my subconscious is trying to tell me something. I've learned that when I've got two choices it's often a good idea to look for a third. And there is a third way. I could instead start with this:
@Test
public void yahtzee_not_full_house_scores_0() {
  fail("RED-FIRST");
}
And when I've seen it fail, I delete the fail() and write the actual code I want to write:
@Test
public void yahtzee_not_full_house_scores_0() {
  assertEquals(0, 
    new YahtzeeScorer(4,4,4,4,4).fullHouse());
}
Or, as an alternative, I could start with this:
@Test
public void yahtzee_not_full_house_scores_0() {
  fail("RED-FIRST");
  assertEquals(0, 
    new YahtzeeScorer(4,4,4,4,4).fullHouse());
}
and when I've seen it fail I simply delete the fail() line.

Either way I get the mechanics of seeing the fail out of the way and then I write the code as a separate thing. By un-asking the question I avoid having to decide what to temporarily fiddle with - the code or the tests. I get to write the code I actually want to write. All the time.

yahtzee cyber-dojo refactoring




Several people have asked for refactoring sessions in cyber-dojo. The idea is that instead of starting from the minimal start code and working towards a solution, you start from finished (but poor) solution and work on refactoring instead. So here are four deliberately poor solutions to Yahtzee in Java, C#, C++, and Python just itching to be refactored!
These buttons create Individual Practices:
These buttons create Group Practices:

when it shocked us

A while ago I set myself a goal of reading all four volumes of Jerry Weinberg's Quality Software Management twice. I'm 7/8 through and this morning some of volume 4, Anticipating Change, really spoke to me.

Figure 10-9 extends the simple view of a feedback controller, to show that the environment of each level contains both the levels above and below.
In a feedback control system, the roles of system and controller are symmetrical. It's only our perception that determines which is controller and which is controllee, which is high and which is low.
In all the cases I have examined, the error correction mechanism seems to start at the lowest possible level and slowly works its way higher. [Donald Norman. Psychology of Everyday Things].
Norman is talking about correcting errors in handling everyday things, like being unable to insert the car key, trying again, trying the key upside down, trying another key, wiggling the handle, trying another door, and finally realizing that it's the wrong car. But the same way of progressing through levels is commonly found in correcting organizational faults.
Maturity tends to mean reliability.
In terms of the Feedback Control Model, every one of the more than a hundred failures I've studied closely can be attributed to poor management.
Software is invisible only when we have not developed the correct engineering measurements. A hundred years ago electricity was considered invisible. We only knew of its existence when it shocked us.
Software often lacks sufficient stability to make meaningful measurements.


the cat in the hat

I've blogged before about how Patrick and I often watch The Princess Bride. Patrick has Asperger's syndrome and loves to watch the same film many times. Many many times. It would be easy for me to not watch a repeat-showing with Patrick on the grounds I'd find it boring. I think that not that many years ago that's exactly what I would have done. But something Jerry Weinberg wrote (in Quality Software Management volume 1 Systems Thinking, page 111) struck a chord with me. He said:

It's not the event that counts, it's your reaction to the event.

So now I challenge myself to watch the film with Patrick (for the umpteenth time) and change the way I react so I don't find it boring. For example, I can specifically look for scenes or lines that I can relate to software development. I've found there will always be some. Here are some from The Cat in The Hat:

For refactoring and continuous-improvement (the song at the end after they've tidied up the mess they made)

I've got to admit it's getting better.

For attitude (after they make the cupcakes which taste disgusting)

They're horrible. Who want's some?

For gratitude (again at the end)

This day has been amazing. Thank you.

For pair-programming! (when they're in the car)

Two people can't drive at the same time.

For testing! (when they're in the car again)

I think there's something wrong with your brakes. When was the last time you had them checked?

For quick and dirty (which is really slow-and-dirty)

There's no way to explain this to mom.

For QWAN, Quality Without A Name, when they're riding the Mrs KWAN roller-coaster:

Please keep your hands and feet in the KWAN at all times.

It's amazing how what you see changes when you change how you look.

big cyber-dojo in Beijing


Mike Long (@meekrosoft) ran a Cyber-Dojo for 32 people in Beijing yesterday. Way to go Mike :-)

cyber-dojo in the cloud

http://cyber-dojo.com is now properly hosted in the Amazon cloud :-) I'll leave the old server, 81.31.112.23 (in my house, under the stairs, with the flaky internet connection - I live in a rural area) up for a few days, but will be gone soon.

A few people have been asking if they could donate something towards running Cyber-Dojo. Now that I'm paying for the hosting that seems a sensible idea, so I've added a donate button. Thanks.

Emil's cyber-dojo




I ran a Mastering Agile Practice tutorial with Kevlin Henney at the recent Scandinavian Developer Conference in Sweden. Emil Jönsson attended and liked Cyber-Dojo so much he ran one at his company afterwards. He says:

Just wanted to let you now that the Cyber-Dojo session I organised at work last week went really well. We did the leap year kata in Java and we were eight in total, so we ended up working in four pairs. It was fun to hear all the interesting discussions taking place and it was perfect how we could jump between the different solutions of the pairs afterwards when talking about the code. The feedback after the dojo was all positive and my colleagues liked the Cyber-Dojo way of practicing.

I hope this will become a reoccurring event. Thanks for the excellent work creating the Cyber-Dojo.

It's my pleasure Emil.


ACCU conference charity bookstall



A big thank you to the excellent people attending the ACCU 2012 conference who raised £645.77 plus a €10 note plus a very small silver coin of unknown origin! This will be split equally between Paws with a Cause and The Autism Trust.

building a rails 3 turnkey cyber-dojo server




NOTE: The cyber-dojo github repo now uses ruby(2.1.3), Rails(4) and docker(1+).
I don't think these instructions will work anymore.
Instead see setting up your own cyber-dojo docker server

I've been working on building a cyber-dojo VirtualBox Turnkey image that uses rails 3 and ruby 1.9.3 on top of the Turnkey Rails app. I figured the steps involved might be useful for someone so here they are. You can also download them as a shell file here .

First I removed the existing ruby
# cd ~
# apt-get purge ruby-enterprise
Then install libyaml
# cd ~
# wget http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
# tar xzf yaml-0.1.4.tar.gz
# cd yaml-0.1.4
# ./configure
# make
# make install
Then install the version of Ruby I want (this takes quite a while)
# cd ~
# wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p125.tar.gz
# tar xzf ruby-1.9.3-p125.tar.gz
# cd ruby-1.9.3-p125
# ./configure --disable-install-doc
# make
# make install
Then pull the rails3 Cyber-Dojo source (hit return when it asks for a password). I got some utf-ascii conversion warnings which don't seem to matter. When asked if I wanted to overwrite an executable I responded [y]es. This too takes quite a while.
# cd /var/www
# git clone https://JonJagger@github.com/JonJagger/cyberdojo
# chown -R www-data cyberdojo
# chgrp -R www-data cyberdojo
# cd cyberdojo
# gem update --system
# gem update --no-rdoc
# gem install bundle --no-ri --no-rdoc
# bundle install
Then setup apache
# cd /etc/apache2/sites-enabled
# sed s/railsapp/cyberdojo/ <railsapp >cyberdojo
# rm railsapp
# cd /etc/apache2/sites-available
# sed s/railsapp/cyberdojo/ <railsapp >cyberdojo
# rm railsapp
# cd /etc/apache2/conf
# sed s/railsapp/cyberdojo/ <railsapp.conf >cyberdojo.conf
# rm railsapp.conf
Then setup passenger (it takes quite a while), and edit /etc/apache2/conf.d/passenger as directed by the output
# cd ~
# apt-get update
# apt-get install libcurl4-openssl-dev
# cd /var/www/cyberdojo
# gem install passenger --no-ri --no-rdoc
# passenger-install-apache2-module
Then
# cd /var/www/cyberdojo
# service apache2 restart
And viola, cyber-dojo was up. Saving to a .ova file creates a 418MB file. This will give you C and C++ (gcc 4.4.5), Perl (5.10.1), Python (2.6.6), Ruby (1.9.3). If you want to upgrade any of these or use any of the other languages you'll need to install their compilers and unit test frameworks.

cyber-dojo Skillsmatter podcast

I had the pleasure of running a Cyber-Dojo at Skillsmatter's 2 day Progressive Java tutorial last week. The session was video'd and is available here.

requiem for C head cam

At the ACCU 2012 conference Uncle Bob gave his excellent keynote Requiem for C. Skillsmatter video'd the whole keynote and it will be available soon. As an experiment Uncle Bob gamely agreed to wear a Go Pro 2 head camera whilst giving the keynote! So here, possibly for the first time ever, are a few rough clips of what it's like to give a keynote.





The evolution of useful things


is an excellent book by Henry Petroski (isbn 0-679-74039-2). As usual I'm going to quote from a few pages:
Can any single theory explain the shape of a Western saw, which cuts on the push stroke, as readily as an Eastern one, which cuts on the pull?
A French book of advice to students recognised the implicit threat involved in using a weapon at the table, and instructed its readers to place the sharp edge of their knife facing towards themselves… Such actions, coupled with the growing widespread use of forks, gave the table knife its now familiar blunt-tipped blade.
Round chopsticks would tend to twist in the fingers and roll off the table, and so squaring one end eliminated two annoyances in what is certainly a brilliant design.
The stories associated with knives, forks, and spoons also illustrate well how interrelated are technology and culture generally.
Luxury, rather than necessity, is the mother of invention.
The very properties of the material that make it possible to be shaped into a useful object also limit its use.
Engineering is invention institutionalised, and engineers engaged in design are inventors who are daily looking for ways to overcome the limitations of what already works.
It is not the form follows function but, rather, that the form of one thing follows from the failure of another thing to function as we would like.
When sewn into a garment, a piece of thread can be thought of as a continuous and flexible ghost of a needle.
It is 3M's policy (and that of other enlightened companies) to allow its engineers to spend a certain percentage of their work time on projects of their own choosing, a practice known as "bootlegging".

Consilience


is an excellent book by Edward O. Wilson (isbn 0-349-11112-X). As usual I'm going to quote from a few pages:
The first step to wisdom, as the Chinese say, is getting things by their right names.
The cost of scientific advance is the humbling recognition that reality was not constructed to be easily grasped by the human mind.
Analysis and synthesis, he [Goethe] liked to say, should be alternated as naturally as breathing in and breathing out.
Nothing in science - nothing in life, for that matter - makes sense without theory.
Complexity is what interests scientists in the end, not simplicity.
Consilience among the biological sciences is based on a thorough understanding of scale in time and space.
Complexity theory can be defined as the search for algorithms used in nature that display common features across many levels of organisation.
In a system containing perfect internal order, such as a crystal, there can be no further change.
The brain is a machine assembled not to understand itself, but to survive.
The biologist S. J. Singer has drily expressed the matter thus: I link, therefore I am.
No example of bias-free mental development has yet been discovered.

Curry velocity

Some people's introduction to curry begins with them ordering the hottest dish on the menu. They discover the dish is beyond their curry-capacity and they can't finish it. Amazingly, they often repeat this behaviour. Lots of curry goes to waste. Dishes are frequently only half-eaten. Curry velocity remains at zero.

Other people's introduction to curry begins with them trying something nearer the cooler end of the Scoville scale. They find the dish is below their curry-capacity. They finish it! No curry is wasted. Their curry velocity is above zero. The next time they may decide to try something a little hotter. But they are in control of the curry, rather than the curry being in control of them.

Being wrong

is an excellent book by Kathryn Schulz (isbn 978-0-06-117604-3). As usual I'm going to quote from a few pages:
One extremely good way to become wedded to a theory you just idly expressed is to have it contradicted... from noncommittal to evangelical in a matter of milliseconds.
We take our own certainty as an indicator of accuracy.
The instant an implicit assumption is violated, it turns into an explicit one.
When we ask people to look for something specific they develop a startling inability to see things in general.
The genius of statistics was that it did not ignore errors, it quantified them. [Laplace]
In ancient Indo-European, the ancestral language of nearly half of today's global population, the word 'er' meant "to move", "to set in motion", or simply "to go."
It is all too common for caterpillars to become butterflies and then maintain that in their youth they had been little butterflies.
the stakes of our mistakes.
Realizing that we are wrong about a belief almost always involves acquiring a replacement belief at the same time.
"fallor ergo sum" (I err, therefore I am) [St Augustine]
When other people reject our beliefs, we think they lack good information. When we reject their beliefs, we think we possess good judgement.
As with so many systems, the strengths of inductive reasoning are also its weaknesses. For every way that induction serves us admirably, it also creates a series of predictable biases in the way we think...
When a framework serves us well... we call it brilliant, and call it inductive reasoning. When it serves us poorly, we call it idiotic, and call it confirmation bias.
Being wrong can be funny; other people being wrong can be very very funny.
Without some kind of belief system in place, we wouldn't even know what kinds of questions to ask, let alone how to make sense of the answers.

Adapt - why success always starts with failure

is an excellent book by Tim Harford (isbn 978-0-349-12151-2). As usual I'm going to quote from a few pages:
Cross the river by feeling for stones [Deng Xiaoping]
Accepting trial and error means accepting error.
Darwin, a meticulous observer...
The art of success is to fail productively.
Complexity is a problem only in tightly coupled systems.
Make sure you know when you've failed, or you will never learn.
What Palchinsky realised was that most real-world problems are more complex than we think. They have a human dimension, a local dimension, and are likely to change as circumstances change. His method for dealing with this could be summarised as three 'Palchinsky principles'
  • seek out new ideas and try new things
  • when trying something new, do it on a scale where failure is survivable
  • seek out feedback and learn from your mistakes as you go along
If we are to take the 'variation' part of 'variation and selection' seriously, uniformly high standards are not only impossible but undesirable.
When John Nagl served in Baghdad in 2003, he found that while his young inexperienced soldiers had the authority to kill, he - a major with a doctorate and a decade of experience - didn't have the authority to print his own propaganda pamphlets to counteract the clever PR campaign that the local insurgents were running.
Speciation - the divergence of one species into two separate populations - rarely happens without some form of physical separation.
Tight coupling means the unintended consequences proliferate so quickly that it is impossible to adapt to the failure or to try something different.
The first thing Timpson does when it buys another business is to rip out the electronic point-of-sale machines (there are always EPOS machines) and replace them with old fashioned cash registers. 'EPOS lets people at head office run the business', explains John Timpson. 'I don't want them to run the business.'

John Timpson describes one instance where he couldn't buy half-price happy hour drinks at a hotel bar, because midway through giving his order, the hour ended and the bar's computerised sales system refused to allow the half-price offer to be applied.

Timpson's company training manual describes the twenty easiest ways to defraud the company, making it clear that the company understands the risks it is running and trusts its employees anyway - and many people respond to being trusted by becoming more trustworthy.
A central point of the corporation, as a legal structure, is that it is supposed to be a safe space in which to fail. Limited liability companies were developed to encourage people to experiment, to innovate, to adapt - safe in the knowledge that if their venture collapsed, it would merely be the abstract legal entity that was ruined, not them personally.
Fail better. [Samuel Beckett]

The conquest of happiness

is an excellent book by Bertrand Russell (isbn 0415378478). As usual I'm going to quote from a few pages:
It will be found that a quiet life is characteristic of great men, and that their pleasures have not been of the sort that would look exciting to the outward eye. No great achievement is possible without persistent work.
Worry is a form of fear, and all forms of fear produce fatigue.

Every kind of fear grows worse by not being looked at.
More and more it becomes possible to choose our companions on account of congeniality rather than on account of mere propinquity.
Like the heroes of Valhalla who spent every day hunting a certain wild boar, which they killed every evening but which miraculously came to life again in the morning…
Fundamental happiness depends more than anything else upon what may be called a friendly interest in persons and things.

To like many people spontaneously and without effort is perhaps the greatest of all sources of personal happiness.

The secret of happiness is this: let your interests be as wide as possible, and let your reactions to the things and persons that interest you be as far as possible friendly rather than hostile.
The more things a man is interested in, the more opportunities of happiness he has.
Events only become experiences through the interest that we take in them.
In the best kind of affection a man hopes for a new happiness rather than for escape from an old unhappiness.
Work, therefore, is desirable, first and foremost, as a preventive of boredom, for the boredom that a man feels when he is doing necessary though uninteresting work is as nothing in comparison with the boredom that he feels when he has nothing to do with his days.
Two chief elements make work interesting: first, the exercise of skill, and second, construction.

All skilled work can be pleasurable, provided the skill required is either variable or capable of indefinite improvement.
We may distinguish construction from destruction by the following criterion. In construction the initial stage of affairs is comparatively haphazard, while the final state of affairs embodies a purpose; in destruction the reverse is the case: the initial state of affairs embodies a purpose, while the final state of affairs is haphazard.
Destruction is of course necessary very often as a preliminary to subsequent construction; in that case it is part of a whole which is constructive.
Few things are so likely to cure the habit of hatred as the opportunity to do constructive work of an important kind.
I should seek to make young people vividly aware of the past, vividly realising that the future of man will in all likelihood be immeasurably longer than his past, profoundly conscious of the minuteness of the planet upon which we live and of the fact that life on this planet is only a temporary incident; and at the same time with these facts which tend to emphasise the insignificance of the individual I should present quite another set of facts designed to impress upon the mind of the young the greatness of which the individual is capable, and the knowledge that throughout all the depths of stellar space nothing of equal value is known to us.
Happiness must be, for most men and women, an achievement rather than a gift of the gods, and in this achievement effort, both inward and outward, must play a great part.
The only man totally indifferent to power is the man totally indifferent to his fellow-men.
It is better to do nothing than to do harm. Half the useful work in the world consists of combating the harmful work.

smell-driven development

After much research by our scientists I can finally report a major advance in software methodology - smell driven development.

Our scientists have perfected a set of software metrics which accurately monitor the health of your software. These metrics are gathered in real time by our patented custom SmellWare servers. Each SmellWare server (prices to be announced shortly) is connected via USB to three glass vials and a sophisticated spray-atomizer.
  • When the metrics read by the SmellWare server indicate your software is in a poor state, the atomizer will spray scent from the first glass vial.
  • When the metrics indicate a further deterioration, the atomizer will spray scent from the second glass vial.
  • When the metrics indicate a really disgusting codebase, the atomizer will spray scent from the third glass vial.
By choosing smells with an increasing tendency to get on the developers' olfactory nerves you can "visualize" the state of your codebase in a way that cannot be ignored!

The genius of this approach is that smell, being the oldest sense, has had the longest to evolve. The olfactory sense is, at the same time, both the most primitive sense and the most sophisticated. Even in humans about 1 in 50 genes is devoted to smell-related protein receptors!

Our odour scientists have studied the four aspects of threshold and tolerance; odour concentration, odour intensity, odour quality, and hedonic tone, and after extensive field testing the first (cheese based) vials are ready.
  • Vial 1 (Yellow) is based on Pong-Leveque (Normandy) and is ranked "distinct, strong, and unpleasant" on the Odour Awareness scale.
  • Vial 2 (Amber) is based on Epoisses de Pieds (Southern Italy) and is ranked "very strong, liable to cause rashes and sore eyes". (Epoisses de Pieds is banned from public transport in Italy).
  • Vial 3 (Red) is based on Peixe-Podre et Meia (Northern Portugal) and is ranked "intolerable, liable to cause vomiting, diahorrea, and heart attacks". (Peixe-Podre et Meia is based on Blue-vein Smegma which had a 97% mortality rate before the EU made its manufacture a federal offense punishable by 25 years imprisonment.)
Believe us when we tell you that once your developers have experienced Peixe-Podre et Meia (Red) they will never again sit idly by while your codebase is merely in Epoisses de Pieds (Amber) state!

Ivan Marks - the people's champion

is an excellent book from Media Press (isbn 978-0-9567015-9-6). As usual I'm going to quote from a few pages:
Young anglers were encouraged and taught the basic skills by more experienced anglers. The club would fish matches where novice anglers were paired off with the top men. For two hours the older angler sat patiently with his pupil explaining the correct tactics to use.
There are, of course, times of the year when the facility to make maggots sink at a reduced rate of fall is a great advantage, especially in still water.
A 4lb chub will eat a half-pint of casters.
His [Benny Ashurst] maxim was always to keep the fish feeding for as long as you can.
Tanked fish have been fed yellow maggots and given an electric shock every time the made a move to eat one. The same fish were fed white maggots and allowed to take what they liked without interference. Later, when those same fish were fed mixed yellow and whites they wouldn't look at the yellows - and can you blame them? That experiment proves that fish can learn.
The real secret with loose-feeding is regularity.
You must not panic and fool yourself into believing that the more stuff you throw in, the more fish will come out.
I told the Italian team manager that I might have taken the individual honours had I been able to stay catching bleak of around that weight. "No Ivan," said the Italian, "it isn't possible!" He explained that my 1oz bleak was a fat and none too healthy fish, and he was right. It looked spawn-bound. In fact he said it had a worm infection. And he explained that fish in that condition are not fit fish. They don't move to the bait fast enough - even if there are enough of them - to allow true speed fishing. Which helps explain just how deeply the Italians have delved into this type of fishing.
A barbless hook punctures the bait, but fills the hole it makes.
Roach and bream don't grab your bait with their teeth. They simply inhale water into their mouths and this sucking process puts the bait where you want it to go.
The biggest risk of breaking a line comes from shock impact. Sudden shock is to be avoided at all costs.

Fun and learning at Ericsson

I had the pleasure of teaching a TDD C++ course at Ericsson's Jorvas centre in Helsinki this week. As usual I made heavy use of cyber-dojo. Above is a screen shot of the dashboard of one of the practice katas. My evals were 5.8 for the course as a whole and 5.9 for teaching skills (out of 6). Some of the comments were:
  • Very clear.
  • You really got us understanding TDD.
  • Transformation of the mindset became clearly visible during the course.
  • Thanks!
  • Best course I've taken at Ericsson, thank you.
  • The cyberdojo is an excellent environment.
  • Very good hands on training.
  • cyber-dojo extremely nice.
  • It was fun!
  • You really need to try to do TDD in practice to see how beneficial and fun it is.
  • You made it visible in practice.
  • Fun fun fun.

Nicer HTML radio buttons

One of my pet peeves is plain html radio buttons. If I have a set of 5 radio buttons with 5 text labels of differing lengths then I want to be able to click anywhere on the shaded area and not just the text labels.

This is quite easy to achieve. Simply put each <input> into a <div>...
<div class="radio">
  <input type="radio" ... value="Red"/>
    <label>Red</label>
</div>
<div class="radio">
  <input type="radio" ... value="Amber"/>
    <label>Amber</label>
</div>
<div class="radio">
  <input type="radio" ... value="Green"/>
    <label>Green</label>
</div>
...and use a bit of jQuery
var $j = jQuery.noConflict();
$j(document).ready(function() {
  $j('div.Radio').each(function(n,node) {
    $j(node).click(function() {
      $j(this).children(':first').attr('checked', true);
    });
  });
});
Using a <div> changes the layout - so you might want to put each <div> into a table layout.

You can add some CSS to highlight the clickable whitespace...
  .Radio { background-color: Moccasin; }
  .Radio::after { content: "\00a0"; }
If you want to remove the bullet simply add the following
$j(document).ready(function() {
  $j('input[type=radio]').hide();
};
If you want to see an example of this, just try CyberDojo

Complexity and postmodernism - understanding complex systems

is an excellent book by Paul Cilliers (isbn 0-415-15287-9). As usual I'm going to quote from a few pages:
Complex systems operate under conditions far from equilibrium. There has to be a constant flow of energy to maintain the organisation of the system and to ensure its survival.
If resources were limitless, i.e., if growth could take place unrestricted, no meaningful structure would evolve. Boundaries, limits and constraints are preconditions for structure.
The theory of self-organised criticality tells us the following. A self-organising system will try to balance itself and a critical point between rigid order and chaos.
The classic definition of stability states that in a stable system small causes produce small effects.
The classical definition of instability, at least as used by Poincaré, is probabilistic. Unstable events are defined as events that have no observable cause.
The system of language transcends the choices of any individual user, and therefore has stability.
In the last analysis, the two facts are interdependent: the sign is exposed to alteration because it perpetuates itself.
When dealing with complex phenomena, no single method will yield the whole truth.

Bare bones ruby unit testing

This morning I spent a happy hour exploring a little of ruby's Test::Unit::TestCase. I started with this:
require 'test/unit'

class MyTest < Test::Unit::TestCase

  def test_one_plus_one_equals_two
    assert_equal 2, 1+1.1
  end

end
I wanted to see how little I needed to write my own, super-minimal implementation of Test::Unit::TestCase...
require 'test/unit'

class MyTest < MyTestCase

  def test_one_plus_one_equals_two
    assert_equal 2, 1+1.1
  end

end
After 204 traffic lights in cyber-dojo I ended up with this...
require 'assertion_failed_error'

class MyTestCase

  def self.test_names
    public_instance_methods.select{|name| name =~ /^test_/}
  end
  
  def assert_equal( expected, actual )
    message = 
      "#{expected.inspect} expected but was\n" +
      "#{actual.inspect}\n"
    assert_block(message) { expected == actual }
  end

  def assert_block( message )
    if (! yield)
      raise AssertionFailedError.new(message.to_s)
    end
  end

end

at_exit do
  ::ObjectSpace.each_object(Class) do |klass|
    if (klass < MyTestCase)
      klass.test_names.each do |method_name| 
        begin
          klass.new.send method_name
        rescue AssertionFailedError => error
          print "#{klass.name}:#{method_name}:\n" +
                "#{error.message}"
        end
      end
    end
  end
end
class AssertionFailedError < RuntimeError; end
which allowed me write...
require 'my_test_case'

class MyTest < MyTestCase

  def test_one_plus_one_equals_two
    assert_equal 2, 1+1.1
  end

end
and finally, I added this...
class MyTestCase
  ...
  def self.test( name, &block )
    define_method("test_#{name}".to_sym, &block)
  end
  ...
end
which allowed me to rewrite the test as...
require 'my_test_case'

class MyTest < MyTestCase

  test "1+1 == 2" do
    assert_equal 2, 1+1.1
  end

end
Fun :-)

The Vizzini school of bad management

  • Am I going mad or did the word "think" escape your lips?
  • Hurry up
  • Inconceivable
  • Faster!
  • You know what a hurry we're in
  • I'm waiting!
  • Catch up with us quickly
  • I do not accept excuses
  • Did I make it clear that your job is on the line?
  • There will be no one to hear you scream
  • Stop doing that. We can relax, it's almost over