The Daily Parker

Politics, Weather, Photography, and the Dog

To Git or not to Git...

I'm torn.

Or I'm a dinosaur. Or I'm a Perceiver. Or I'm a senior software development manager who's sick of changing technologies.

My current drama is between continuing to use Mercurial on one hand, and switching to Git on the other. Both are distributed version control systems, so both enable a load of flexibility in single- or multi-developer workflows. I know that sounds like jargon, so let me explain.

No, there is too much; let me sum up: If you don't have to share every little change you make to a software project, everyone is better off.

The cold war between these two products has created two problems that appear to have nothing to do with each other:

  • We have multiple software projects that we have to continue to support in production while we build entirely new hunks of them (which will take months); and
  • All of the cool tools for integration and deployment work with Git, while not all of them work with Mercurial.

I suppose I shouldn't be surprised. I chose Betamax and Laserdisc as well. I have a real weakness for the best technical solution, even while the popular solution takes the lead. (Both Betamax and LaserDisc had superior audio and slightly better video than the products that defeated them. At least I held off choosing between HD DVD and Blu-Ray until one of them was cold and dead in the ground.)

I digress.

I'm annoyed that Git is moving so far ahead of Mercurial that it's becoming an argument to use Mercurial. I assert this is an argument to popularity, not to logic. But I also get really tired of swimming upstream, and if Microsoft, Bitbucket, and a bunch of other companies are pushing a technology, who am I to blow against the wind?

A conclusion, to the extent possible, will follow shortly.

Another bit of sanity brought to you by unit testing

I just saved myself hours of pain by creating a unit test around a simple method that turned out to have a subtle bug.

The method in question calculates the price difference between two subscriptions for a product. If you're using the product, and you use more of it, the cost goes up. Every day, the application looks to make sure you're only using your allotted amount. If you go over, you get automatically bumped to the next subscription level and charged the difference, pro-rated by how much of the subscription term is left.

Here's the basic code:

var delta = subscription.IsAnnual ? 
   newTier.AnnualPrice - currentTier.AnnualPrice : 
   newTier.MonthlyPrice - currentTier.MonthlyPrice;

All well and good, except MonthlyPrice, for reasons known only to the previous developer, is nullable. So in order to prevent an ugly error message, I made sure it could never be null using the ?? operator:

var delta = subscription.IsAnnual ? 
   newTier.AnnualPrice - currentTier.AnnualPrice : 
   newTier.MonthlyPrice ?? 0m - currentTier.MonthlyPrice ?? 0m;

Do you see the problem? I didn't. But I learned today that - takes precedence over ??. So here's the correction:

var delta = subscription.IsAnnual ? 
   newTier.AnnualPrice - currentTier.AnnualPrice : 
   (newTier.MonthlyPrice ?? 0m) - (currentTier.MonthlyPrice ?? 0m);

I discovered that when the unit test I wrote kept insisting that 6 - 6 = 6. This is because without the parentheses where I put them, the compiler thinks I meant this:

newTier.MonthlyPrice ?? ((0m - currentTier.MonthlyPrice) ?? 0m)

In English, the compiler thought my first attempt meant, "Take the new monthly price, except if it's null, in which case take zero minus the old monthly price, unless that's null too, in which case take zero." What I meant, and what my correction means, is, "Take the new monthly price, or zero if it's null, and subtract the old monthly price (or zero if that's null)."

I'm glad I use NUnit.

Bing Maps on Windows 8 #fail

I have an HTC Windows 8X phone. I work for a Microsoft Partner, so this seemed like a good idea at the time. After nearly a year, I can report that I am tired of this phone and want to go back to Android.

The one thing my phone does well is manage two Microsoft Exchange accounts. And it does Skydrive all right too. Those are Microsoft products, so Windows should handle them.

I find the touch-screen waaay too sensitive. It can't determine what letter I want more than half the time, and its auto-correct suggestions hardly ever make sense.

Bing, however, sucks ass, compared with Google. And there's no way to change the hyper-sensitive search button on the phone, which fires up Bing every time my thumb goes near the search icon. Sometimes when I'm trying to take a photo, or do something else that involves the phone not switching applications.

Bing Maps is even worse. I won't spend too much time on a rant when I could just show you.

Let me preface this by saying Seoul's WiFi situation is amazing. I have free WiFi nearly everywhere I go. Which is how I was able to run the following comparison.

Exhibit A, where the Bing Maps application thought I was this afternoon:

(Click for full-size image.)

Exhibit B, where Google Maps thought I was at the same moment:

Google wins.

Note that the Bing Maps application on my phone failed to produce a usable map; Bing Maps itself has the data. Here's what the Bing Maps website shows inside a browser window:

Attention, Microsoft: Having a nicely detailed map on my laptop does not help me when I'm in the middle of Gangnam. That's really exactly the moment that I want a good map.

Oh, and to add insult, Google Maps doesn't really work that well on the IE11 mobile browser. As in, it won't search unless you really make sure you touch exactly the right pixel on the screen.

My next phone? I'm going back to Android.

Things I found while listening to a conference call

Tomorrow afternoon is the Day of the Doctor already, and then in a little more than four days I'm off to faraway lands. Meanwhile, I'm watching a performance test that we'll repeat on Monday after we release a software upgrade.

So while riveted to this Live Meeting session, I am pointedly not reading these articles:

Perhaps more to the point, I'm not finishing up the release that will obviate the very performance test I'm watching right now. That is another story.

The first head rolls

The person most directly responsible for the HealthCare.gov debacle is "retiring:"

The chief information officer at the Centers for Medicare and Medicaid Services, whose office supervised creation of the troubled federal website for health insurance, is retiring, the Obama administration said Wednesday.

The official, Tony Trenkle, will step down on Nov. 15 “to take a position in the private sector,” said an email message circulated among agency employees.

As the agency’s top information officer, Mr. Trenkle supervised the spending of $2 billion a year on information technology products and services, including development of HealthCare.gov, the website for the new health insurance marketplace.

Sibelius, though. Why's she still around?

The usability of HealthCare.gov

Jakob Nielsen's company has written a detailed analysis of how the Federal Health Exchange screwed up usability:

The HealthCare.gov team has suffered what most web professionals fear most: launching a broken web application. This is particularly harrowing given the visibility of the website in question. The serious technical and data issues have been covered extensively in the media, so we won’t rehash those. Instead, in this article we focus on how to improve the account setup process. This is a user experience issue, but fixing it will also alleviate the site's capacity problems.

Account Set-up Usability is Mission Critical

Account setup is users’ first taste of a service. A suboptimal account setup can spawn 3 problems:

  • Increased service cost: When people can’t self-service online and you have no competitors, they call you. Call-center interaction is more expensive than web self-service. In 2008, Forrester estimated call-center calls to cost $5.50 per call versus 10 cents for a user who self-services online.
  • Increased cognitive strain: The instructions for creating usernames and password in this flow (which we address further along in this article) require a great deal of concentration, and if users don’t understand the instructions, they will need to keep creating usernames and passwords until they are accepted.
  • Halo Effect: Account setup is the first in a series of web-based interactions that users will need to conduct on HealthCare.gov. A poor experience with this first step will impact how people feel not only about subsequent interactions with the site, but how they feel about the service in general and the Affordable Care Act as a whole.

The discussion around our office hinges on two things other than usability: first, give us $2 million (of the $400 million they actually spent) and we'll build a much better site. Second, the biggest problems come from the insurance companies on the back end. Users don't care about that; they just want to get health insurance. As Krugman says, though, there really wasn't a way to get the insurance companies out of the equation, and that, more than anything, is the foundation of all these other problems.

jQuery: Party like it's 1989

Programming languages have come a long way since I banged out my first BASIC "Hello, World" in 1977. We have great compilers, wonderful editors, and strong typing.

In the past few years, jQuery and JSON, both based on JavaScript, have become ubiquitous. I use them all the time now.

jQuery and JSON are weakly-typed and late-bound. The practical effect of these characteristics is that you can introduce subtle, maddening bugs merely by changing the letter case of a single variable (e.g., from "ID" to "Id").

I've just spent three hours of a perfectly decent Sunday trying to find exactly that problem in some client code. And I want to punch someone.

Two things from this:

1. Use conventions consistently. I'm going to go through all the code we have and make sure that ID is always ID, not Id or id.

2. When debugging JSON, search backwards. I'll have more to say about that later, but my day would have involved much more walking Parker had I gone from the error symptom backwards to the code rather than trying to step through the code into the error.

OK, walkies now.

healthcare.gov is bad, but the Times should know better

I am agog at a bald impossibility in the New York Times' article today about the ACA exchange:

According to one specialist, the Web site contains about 500 million lines of software code. By comparison, a large bank’s computer system is typically about one-fifth that size.

There were three reporters in the byline, they have the entire Times infrastructure at their disposal, and still they have an unattributed "expert" opinion that the healthcare.gov codebase is 33 times larger than Linux. 500 MLOC? Why not just say "500 gazillion?" It's a total Dr. Evil moment.

Put in other terms: it's like someone describing a large construction project—a 20-story office building, say—as having 500 million rivets in it. A moment's thought would tell you that the mass of 500 million rivets would approach the steel output of South Korea for last month.

The second sentence is nonsense also. "A large bank's computer system?" Large banks have thousands of computer systems; which one did you mean? Back to my example: it's like comparing the 500-million-rivet office building to "a large bank's headquarters."

I wouldn't be so out of my head about this if it weren't the Times. But if they can't get this right, what hope does any non-technical person have of understanding the problem?

One last thing. We, the people of the United States, paid for this software. HHS needs to disclose the source code of this monster. Maybe if they open-sourced the thing, they could fix it faster.

Small world

The Chicago technology scene is tight. I just had a meeting with a guy I worked with from 2003-2004. Back then, we were both consultants on a project with a local financial services company. Today he's CTO of the company that bought it—so, really, the same company. Apparently, they're still using software I wrote back then, too.

I love when these things happen.

This guy was also witness to my biggest-ever screw-up. (By "biggest" I mean "costliest.") I won't go into details, except to say that whenever I write a SQL delete statement today, I do this first:

-- DELETE
SELECT *
FROM MissionCriticalDataWorthMillionsOfDollars
WHERE ID = 12345

That way, I get to see exactly what rows will be deleted before committing to the delete. Also, even if I accidentally hit <F5> before verifying the WHERE clause, all it will do is select more rows than I expect.

You can fill in the rest of the story on your own.

Unbelievably stupid Windows thing

Fortunately, I'm in an airport with lots of power outlets. Because my laptop just warned me that it was down to its last few milliamps, even though ordinarily the 90 W/h battery I lug around can last about 8 hours. What happened? Windows Search decided that consuming 50% of my CPU (i.e., two entire cores) was a good idea while running on battery.

So since I have an hour before boarding, and since I'm now plugged in (which means I don't have any worries about driving my portable HDD), here is a lovely picture of Montréal from earlier today: