Tools Don’t Make the Team

Today I was involved in a meeting with our team about switching from scrum to kanban. The details of the meeting aren't important, however one person's question stands out in my head.  One of our team members asked, "What's to stop the team from always picking up the 'fun' cards and leaving the crappy projects waiting?" My immediate response was, we'll just have a policy, always take cards form the top.  Problem solved. Right?

Wrong. You don't have to fix this problem because we have a good team. Good people know what to do and they get it done.  They don't need people telling them what to do or how to do it.  If you have a problem like the above where people selfishly only work on things that are fun and leave the crap work for others, then you have a problem. No tool is going to magically make people something they are not.

Scrum, Kaban or whatever methodology you choose are really just tools to help your team wrangle in the complexities of business outside of your team. Processes like these help point you in a direction. That's it. They are designed to bring order to the chaos that ensues from this: "We need x,y and z and we need them yesterday. Also, a,b and c would be nice too. No wait, foo is now the most important thing. If we don't have foo, then kittens will die!!1!" Business people don't understand the perils of task switching. They really don't care about best practices or testing. They care about output. (until that output breaks in front of clients, then they suddenly care...)

Since the people outside your little team are guaranteed to be certifiably insane, then we must provide them with constraints.

  • Scrum - "We've committed to {x} amount of work for the next {t} week(s). Put it on our backlog and we'll prioritize it for next sprint."
  • Kanban - "We can only have {n} things in progress. If we push this into our Todo queue, then we'll need to pull something off. What would you like to delay?"

That's it. The tools here just provide a consistent means to constrain work and set expectations for people outside our circle. If there is no buy in from those outside your group to being constrained, then no tool is going to fix that. If the people within your group suck and they do what they want, then you're doomed too.

With all of that said, a good team can benefit from better tools. But please remember, they are just there to facilitate your goals. Don't fall into the trap of valuing your methods over your work. All wrenches turn bolts, but an impact gun does it faster. The focus isn't how fast we can spin lug nuts, it's how fast we can get in and out of the pits and not have the wheels fly off mid race.

Dear Black Yukon

My wife and I had an interesting experience that I just need to share. We went to Lowe's to pick up some paint supplies. When we came back to our car, a lady across the parking lot flagged us down and told us that the vehicle beside us whacked our car really hard with her door. I looked it over and decided I could buff it out. My wife decided to leave them a little note just to let them know they were busted. It went something like this:

Dear Black Yukon:
A lady in the parking lot saw you hit our car with
your door. Please be more careful next time.
Sincerely,
Gray Xterra
{phone number}

She left it under their windshield wiper and we went on with our errands. While we were driving we had a little debate, will they own up to what they did and call us back? This question left me excited to get home. I knew they had found the note by now, so we should have a phone call waiting, right?

When we got home there was the missed call and the voicemail. He said something along the lines of, "I'm really sorry please give me a call back so that I can make this right." I was a little shocked. Obviously that was the right thing to do, but I really wasn't expecting it. I quickly ran out to the garage and buffed out the scratch to confirm that we were cool. I then called him back and let him know that everything was okay and thanked him for calling us. He apologized again and we hung up. My faith in humanity is restored.

I have to hand it to my wife, I never would have thought to leave a "you just got busted" note. Normally I see these things going one of three ways:

  1. Shrug it off and pretend like it never happened. The other person never knows they did anything wrong.
  2. Wait for person to come out and confront them.
  3. Kick in their door and then leave.

I would never do number three. For me to follow thorough with number two the damage would have to be significant. Number one is the typical route for me since I'm generally non-confrontational. My wife just introduced me to the 4th option, leave a shame-on-you note. :)

Knockout.js Money Observable

A few days ago I posted a solution to create a custom money binding for knockout.js. If you recall, I was a bit hesitant about the solution because I felt that it wasn't very semantic. Namely, DOM objects do not have a money property to bind to. I had a chat with Elijah Manor and he shared the same reservations. Comments on that post echoed the yucky feeling. Time for round 2.


See the full sample on jsFiddle

What I had missed was the writable dependentObservable introduced in knockout.js some time recently. With this new found power I can keep the appropriate text or value bindings and still have a clean view model. With the solution above, I don't have to jump through hoops to get a clean json representation of my view model. On top of that, my bindings are still simple enough to understand. There is less magic and I like it that way.

This feels a lot better than the first solution. I'm still not sold though. It feels like this type of concern should be pushed out of the view model. Possibly something like this? <input data-bind="value:Cash" data-convert="value:MoneyConverter" />

What do you think of the new bits? Is this a better or worse solution? Also, how can we improve this?

Knockout.js Custom Money Binding

EDIT: I think I've found a better solution. Click here to see the post on creating a money observable.

As I've been digging deeper into knockout.js, I had a need to simplify some things. I needed to have my view model hold float values but display it as a formatted money value. Time to write my own custom binding for knockout.

I'm a bit mixed about this. On one hand, it was dead simple to get the behavior I needed. On the other, the semantics don't match up. The built in bindings are things like text and value. That is, you are mating an object to the text or value property of a DOM element. DOM elements don't have a 'money' property, which makes this approach feel wrong.

There it is and I'm not confident that I'm using the tool appropriately. What do you think?

ASP.NET MVC3 JSON decimal binding woes

I just stumbled onto this bug the other day and I figured I would share. Given the following controller action and ajax call, what would you expect the value of deez to be in the BreakStuff action?

//Model to be bound.
public class Decimals {
   public decimal d1 { get; set; }
   public decimal d2 { get; set; }
   public decimal d3 { get; set; }
}
//Controller action to check the binding
public ActionResult BreakStuff(Decimals deez) {
   return new EmptyResult();
}
//Ajax call to controller action above
$.ajax({
   type: "POST",
   url: "/Home/BreakStuff",
   contentType:'application/json',
   data:JSON.stringify({d1:42.00,d2:3.14,d3:'17'})
});

A screenshot says a thousand words:

Model values before adding DecimalModelBinder

What happened to d1? The resulting JSON from JSON.stringify({d1:42.00,d2:3.14,d3:'17'}) ends up being {"d1":42,"d2":3.14,"d3":"17"} Cool right? Mostly, except that once this value gets server side, that 42.00 is now seen as an int (42) and the default model binder doesn't want to stuff that into my decimal type. Bummer. Not exactly what I was expecting.

Phil Haack to the rescue! After doing some searching I stumbled across this post which fixes binding to string values with comma separators. It solves the same problem I'm having, so I'll repost the bits here:

using System;
using System.Globalization;
using System.Web.Mvc;

public class DecimalModelBinder : IModelBinder {
    public object BindModel(ControllerContext controllerContext,
                                    ModelBindingContext bindingContext) {
        ValueProviderResult valueResult = bindingContext.ValueProvider
            .GetValue(bindingContext.ModelName);
        ModelState modelState = new ModelState { Value = valueResult };
        object actualValue = null;
        try {
            actualValue = Convert.ToDecimal(valueResult.AttemptedValue,
                CultureInfo.CurrentCulture);
        }
        catch (FormatException e) {
            modelState.Errors.Add(e);
        }

        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
    }
}

Then stick this into your Global.asax.cs Application_Start:

protected void Application_Start() {
    ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
    // Your other stuff goes here.
}

Once I did that and re-ran the code above, everything works as expected. See for yourself:

Model values after adding DecimalModelBinder

« Previous PageNext Page »