Monthly Archives: January 2009

Don’t try this at home, we’re professionals

So I just received the feedback for my last exercises for the Data Structures course. Three mistakes total: I transformed an O(n) algorithm to an O(n2) one (although I spotted that one myself – after I had already submitted my answers, d’oh!) and my lazy-delete linked list was doubly borked: two successive deleted items confused my Purge routine altogether, and the search would stop on a deleted item.

Ouch.

OK, so I admit, I didn’t really pay attention to the search thing at all, and I’m taking some credit for figuring the O(n2) thing out myself, but damn, not checking for two successive deleted items in the key part of the algorithm I was actually working on. Sloppy!

Fortunately, at work I tend to interleave writing tests with implementing my algorithms, but I have to admit that I’m not sure if I would have thought to check for this case when doing TDD, either.

Sobering thoughts. One should never ever fall to the trap of thinking that a problem is so trivial it doesn’t merit a thorough checking. Because programming is hard:

  • If your code deals with arbitrary human text, it’s probably broken. (Have you taken the Turkey test recently?)
  • If your code deals with floating point numbers, it’s probably broken.
  • If your code deals with concurrency (whether that means database transactions, threading, whatever), it’s probably broken.
  • If your code deals with dates, times and time zones, it’s probably broken. (Time zones in particular are hideous.)
  • If your code has a user interface with anything other than a fixed size and a fixed set of labels (no i18n), it’s probably broken.

Let me add one to the list: if your code implements an algorithm you that you can’t verify for correctness at a glance, it’s probably broken. Especially if I wrote it.

Friday miscellany

Synchronicity strikes again. A couple of days after I write about what I think is the responsible way to refactor, Raganwald’s del.icio.us link feed coughs up a post titled “Refactoring yourself out of business” from a blog by a chap named Eric Ries. Choice quotes:

They asked for my advice, and we went through a number of recommendations […] I thought we were having a successful conversation. Towards the end, I asked when they’d be able to make these changes, so that we could meet again and have data to look at together. I was told they weren’t sure, because all of their engineers were currently busy refactoring. You see, the code is a giant mess, has bugs, isn’t expandable, and is generally hard to modify without introducing collateral damage. In other words, it is dreaded legacy code. The engineering team […] is taking several weeks to bring it up to modern standards, including unit tests, getting started with continuous integration, and a new MVC architecture. Doesn’t that sound good?

I asked, "how much money does the company have left?" And it was this answer that really floored me. They only have enough money to last another three months.

I have no doubt that the changes the team is currently working on are good, technically sound, and will deliver the benefits they’ve claimed. Still, I think it is a very bad idea to take a large chunk of time (weeks or months) to focus exclusively on refactoring. The fact that this time is probably a third of the remaining life of the company (these projects inevitably slip) only makes this case more exaggerated.

[…]

We’re always going to have to live with legacy code. And yet it’s always dangerous to engage in large refactoring projects. In my experience, the way to resolve this tension is to follow these Rules for Refactoring:

  • Insist on incremental improvements.
  • Only pay for benefits to customers.
  • Only make durable changes (under test coverage).
  • Share what you learn.

I can’t help but notice the bulleted list looks a lot like what I was suggesting. .-)

Now, I’ve butchered the quote from Eric’s entry (sorry!) to save some space, so if my previous rant resonated with you, go read the original text – it’s far more comprehensive, and well-written.

Next up, TechCrunch has a story on why googlers quit. All is not well in the land of milk and honey. My, one might even conclude that it’s silly to expect a single employer to be the be-all, end-all workplace for every top notch techie. Really I’m just enjoying some schadenfreude, given that I suck too much to ever pass the Google hiring bar. ,-)

Back on the topic of refactoring, I’ve had an analogy in mind for a while now, between programming and cooking. Obviously, the cooking itself is the programming, but if you’ve prepared anything remotely interesting, you know the dirty dishes, cartons, plastic wrappings and ingredients you no longer need quickly accumulate into a big mess that makes the actual cooking hard. Kind of like legacy code. So continuously cleaning up after yourself is kind of like continuously refactoring while you add features.

I’m not saying that analogy really helps me when I’m programming – I already have a certain mindset for it. However, what I don’t like is cleaning up, and thinking about chores as tiny little refactorings in my home helps a bit.

How geeky is that? .-)

PuTTY, Vista and the annoying security warning

I’ve been living for months now with the annoying security warning generated when you open an executable you just downloaded, such as PuTTY.exe. From time to time I’d try to uncheck the “Always ask” checkbox only to have it return on the next run, and periodically I’d search for the anwer.

Turns out there are two ways of getting rid of the warning. First is to use the installer version of PuTTY. But I had done that already. And true enough, it didn’t used to happen until I downloaded PuTTYtray, which didn’t come in the installer.

The only way to fix things is to open the file properties window while it’s in the original download location and unblock the executable. How very annoying.

Fortunately, all my browsers store the downloaded files in the same, default location, which is C:\Users\myusername\Downloads. So I moved the file there, and ta-da, the unblock button appeared in the properties window.

 

This is one of those times I really have to say a feature of Vista sucks, big-time. I mean, security-wise it’s a good thing that verifications like this are done, but UI-wise it’s insane to hide the option if the file is moved and not tell about it in any way, shape or form.

Obviously the information about the original location of the file is stored somewhere, otherwise the button couldn’t have appeared when I moved it there. Hence the UI should at the very least tell me what is wrong, and where I need to move the file to fix things. Something like this, perhaps:

UI concept: the file properties dialog with information about the problem

The wording and placement of the message could and should be improved, but the key things are: something is not right – there is something about this file you need to know. This is why it’s happening – you shouldn’t have to guess at what’s wrong. And most importantly, this is what you can do about it. Armed with that information, I can make the informed decision on what, if anything, I should do about it.

I’m sure Raymond Chen can give me a dozen reasons why this is technically impossible, or a bad idea security-wise. Still, if the UI is going to refuse to obey me, it should let me know why and let me know how I can fix it. This is making my computer so secure I can’t use it properly either.

Software that doesn’t pull its weight

A moment ago, I decided I’d play around with ASP.NET MVC for a while, mostly just to try out the Spark view engine and see if it actually is as elegant as it looks. I fired up Visual Studio, and then remembered that I should probably install the new Release Candidate of ASP.NET MVC too.

I downloaded the installer, ran it, and got this:

An older version has already been installed. I could remove it for you, but instead I'll just throw an error in your face!

First of all, having an earlier version installed is an error? Are you saying I shouldn’t have tried the beta?

Second, just what exactly is preventing you from offering a button that says something to the effect of “replace with this version”, runs the uninstaller quietly and then installs? Why bother making a big deal out of this?

Third, if that’s too much work, could you at least please offer me a quick way to access the uninstaller? Instead, now I have to open up Explorer, groan in exasperation, dig up control panel, go to Add/Remove Programs and remove it myself, then close the error and re-run the installer.

And the feature isn’t even called Add/Remove Programs in the Vista default control panel view:

It says "Uninstall a program", not Add/Remove Programs

Of course, since this product is targeted at developers, the people encountering this error will probably have the good sense to locate “Uninstall a program”. But if this is a general installer feature, which I think it is, I can imagine a less computer literate user might not dare to disobey the message like that.

I’m sure it’s easier to fail and let the user deal with it. But damn it bugs me. I haven’t even begun to evaluate the actual product, and already it has given me a bad impression. Good thing I’m still inclined to like the framework itself.

 

Now that I think about the error a bit more, I’m pretty sure I’ve actually done the same deed – packaged an IE extension in an installer that would throw precisely the same error if it was already installed, which meant upgrading required an uninstall. Damn! Now I’m angry at myself too.

Time for improvement

Today I had a long discussion – more of a one-sided rant, really – where I tried to convince two other programmers that quality stems from the programmer, and almost every programmer has it in their power to change things for the better.

Suppose you are given the task, of say, implementing a Frobnitzer for the next minor version of Blooperator. You open your editor and dive in to gain understanding on how to best implement the feature. Then you get that sinking feeling. The existing code was intended for a Flubbergleep instead. It was written by someone who left the company ages ago. It’s poorly documented. Worst of all, it looks like a mess. You sigh, and wish for the 307th time that the customer would agree to The Big Refactoring.

But nobody ever pays for refactoring only. And why should they?

Clean code is a nice thing to have, but from the customer’s standpoint, that’s not what provides the value. The customer just wants their Frobnitzer. While the existing code is ugly, with lots of tight coupling, obscure variable names and near-indecipherable methods, it works as expected.

You are a programmer. Your job is to solve problems for the business, even if they don’t acknowledge them.

Poor quality code is a problem. So solve it.

It doesn’t really require The Big Refactoring, even though it would be the easy way to do it. When you work out what that complex algorithm with lots of one-letter variable names is actually doing, clarify the variable names. When you’re forced to change a method that consists of 200 lines of arrowhead code, flatten it. If you can extract a method to clarify the meaning of the code, do it. There are automated tools that can do it and verify that they don’t make any semantic changes to your code. Use them — make any and every simplifying or clarifying change you judge safe enough to do while still shipping on schedule.

If you can, write tests for it. So you’ve got a 100kLOC project with zero tests, and seeing the first one throw a red bar is a bit disheartening. Grit your teeth, make it pass, then go for another one. In a week you’ll have a couple of dozen. In a month or so, you’ll probably surpass a hundred. And the next maintainer will thank you.

Most likely that maintainer will be you.

If it feels like you can’t write tests for it, I’ve got a book you need to read. Get used to the idea of working with legacy code. You’ll be doing that most of the time anyway.

Complaining endlessly about how you’re never explicitly given the time and resources to get things right is a cop-out. Making things better bit by bit is rarely easy, rarely rewarding and almost never appreciated by the customer. But it’s the right thing to do.

So quit complaining, and go do your job.

Beating procrastination

I’m a terrible procrastinator. I put off all sorts of things all the time, because I’m tired, I don’t feel like it or I just don’t have the time. However, I seem to always have enough time and energy for the things I do like, so I’ve come to suspect that maybe I’m trying to fool myself.

Procrastination is a weird thing. You delay the bigger reward of having accomplished your task in favor of the small-to-the-point-of-nonexistent reward of… not doing it. It wouldn’t make any sense at all, if we weren’t hard-wired to prefer the immediate reward over the long-term reward.

It’s also something that accumulates quickly. You should make dinner but you can’t because first you’d have to wash the dishes which would require you to empty the cupboard where the dry dishes from the last round are, and so on, and so forth. It applies to everything. First you procrastinate, and before you know it, you’re shaving yaks.

The only cure is to break the loop: find the determination to do one of those accumulated things. That may lead to a feedback loop that goes the other way: you feel accomplished, energized and ready to tackle the next task, too.

I find that lists are useful in getting things done. Writing down the first two or three things, the things I actually have to do, and then continuing the list with the things I don’t want to do is a great tactic. Once I cross off the first items from the list, I often end up having enough momentum to tackle at least one, sometimes all of the tasks I had been avoiding.

Unfortunately, all it takes is a little slip-up, and then you’re down that road again: I’m too busy to write a list etc…

The periods when it does work, for me, seem to happen at times when I’m breaking other bad habits too. For instance, in the last few days I’ve cooked proper meals several times, washed the dishes as soon as there’s space for them, and even exercised on the Wii Fit. Which is something, by the way, of which I will NOT provide pictures.

Today I’ve managed to clear my list for the most part, and I’d still have time to exercise my programming muscles for a bit. I just don’t really feel like doing it. However, there’s one last episode of Blackpool left for me to watch…

OGG files and Windows Media Player 11

Ever since I bought my ThinkPad, I’ve been primarily using Vista. And although my initial judgment was “disappointed”, I’ve grown fond of the new interface, and rarely find things that really bug me. I even like the Media Player 11 interface, enough to prefer it for playing music and videos.

However, it doesn’t like to work with formats it doesn’t know, and the list of those formats is long. I’m particularly interested in FLAC and OGG, because most of the music I’ve manually ripped from CD is in those formats.

I tried to get things working previously, by installing a filter that was able to play the files, but that alone isn’t enough. If you like the WMP11 interface, you’re likely to want the files to show up there too. This is how it’s done:

First, get a codec pack that will play OGGs. The Combined Community Codec Pack seems to be a fairly popular alternative. Next, get a plugin that will provide metadata support: WMP Tag Support Extender. I had it figured this far, and still had no result. Until I found a Windows Media Player 11 Guide that had the key information piece: even without the tag support, when the proper codecs are installed, WMP recognizes the OGG and FLAC files as playable media. However, it does not know that they’re music files, so it indexes them as “other media” instead. And once the files have been indexed, they won’t be re-added when you scan the music folder with the tag support plugin enabled. The trick is, then, to delete the “other media” and re-add it, after which it gets properly recognized as music.

This “other media” view is almost hidden – it took me longer than usual to locate it. It lurks under the note icon in the top left corner:

 mediaplayer_views

Although there is an alternative way to access it: select “other” in the Library menu.

Having removed the offending entries from the index, WMP now correctly figured out that my OGG files were in fact music. Success! Now I can again enjoy my collection of Sentenced and Kamelot.

New things

Well, it’s been a while since I last took a chance and tried to change the way I use my computer. I’m fairly set in my ways, even though I realize that some of the ways I do things are fairly ineffective. I also feel I’ve sort of fallen behind the curve with regards to making good use of services on the web and whatnot, so I thought I’d try a couple of new things.

First, I’m trying Chrome as my default browser for… well, either until it annoys me and I go back to Firefox, or if it doesn’t, then possibly indefinitely. At first I disliked the idea of a browser without an ad blocker. And then I remembered Privoxy, which seems to pretty much cover what I used to have AdBlock for.

Second, after having read a lot of good things about Windows Live Writer, I’m going to use it to type these entries. In fact, I’m doing it right now, and my first impression is very positive. Apart from the installer that wanted first to install everything and the kitchen sink and then to sign me up for all sorts of things, this is the way software should work. Non-intrusive, helpful, not arrogant.

Third, I took ASP.NET MVC for a quick tour. I didn’t actually write an application yet, I just took a peek at the default app skeleton and futzed around a bit, because a guy on IRC said he found it hard to work with. Positive things: having gotten used to MonoRail in an earlier project, most things felt natural. I was quickly able to add an action to the default controller and modify its behavior. Less positive: the default configuration provides no obvious way of switching to another view engine (or, possibly, it did and I missed it), and I hate the default, which is WebForms. Still, I think it will be a fun framework to dabble with.

It’s funny, but I feel like I really need a project to play with now, while just yesterday completing the exercises for my Data Structures course felt like too much work. Speaking of which, I should take it upon myself to go through the list of essential things from the last couple of weeks and feed them to Anki. The spaced learning system seems interesting, and this would be a perfect time to try it.

Recovery-wise, the inflammation in the eye socket has clearly gone down, it feels more comfortable, and I feel like doing some physical exercise. In fact, I did a 30-minute workout on Wii Fit for the first time in almost six months. It felt good. I suppose I should take it easy for a couple of days still. But I’m definitely going to the sauna today. And have a couple of beers.

On that note, cheers. I’ll try to keep to a more intense posting schedule in the future.

It’s all fun and games until someone loses an eye

Last time I posted I wrote about my eye. The one that had so many things wrong with it that finally the only thing left to do was to cut it out.

I guess most people will never have to make a call like that.

The alternatives were to not do anything, to try and kill the nerves from the eye, or to eviscerate it.

When I discussed the issue with my doc, I coolly summarized the points for and against all the alternatives, and told him that by my count, the only way to get a sure result is to cut the thing out.

Last Wednesday morning I checked in to the clinic. My wife was there with me, until around the time I was supposed to change into the hospital clothes.

The vaguely meat-colored loosely hanging shirt and pants seemed like a final insult: not only did you get struck with shit that you shouldn’t have to deal with in at least thirty years, but you won’t even get to wear underpants.

A nurse collected all sorts of tidbits about my health, the doctor who performed the anesthesia shuffled back and forth between me and a bunch of other patients. And then I was left alone for an hour, with nothing to do but “lie back and rest.”

Lie back and rest. That almost got a chuckle out of me. Throughout the last two months the pain was never worse than it was when I lay down. I guess I’ll take a pass on that, doc.

Finally, around 10:30, the nurse told me we’d be going to the OR. I got up, and she asked me if I could walk. I held back the first thing that came to my mind, which was to ask if she was perhaps daft. I’m half blind and in pain. I’m not a fucking cripple.

One floor down, and through a twisty corridor. Halfway across there was an intersection of hallways that was covered with plastic sheets, something or other was being renovated on the same floor. A door to the left from me opened, and two guys in construction worker suits and helmets walked in, trailing us for the next leg of the hallway. “This sure looks promising,” I thought. I imagined them walking behind me all the way to the OR.

My thoughts got interrupted when we took a sudden turn, opened a pair of doors to an OR with a team waiting. The nurse asked if they were Doc So-and-so’s. They nodded to affirm, and then proceeded to tell me how I should be on the operating table.

My pulse was a bit up, I kept my breathing in check, and inside I was as terrified as I had ever been. The nurses helped me lie down. A young female nurse shielded my good eye from the light when I managed to communicate that the pain got real bad when lying down, and the light made things worse. She told me her hand smells like ethanol, in an apologetic tone. I was grateful. I almost asked her to hold my hand. By that time I had the IV drip in my left hand. Semi-jokingly I told them I had considered writing “NOT THIS ONE” on my left eyelid. Suddenly it didn’t feel that funny any more.

A slight tingly feeling in the left hand. Anesthetics. Someone put a gas mask on my face, explained that it was oxygen. I breathed in, and spaced out.

Consciousness seeped back in. I heard someone talking to me, asking if I was awake. I coughed a response, and realized my throat was sore. I figured that was because of the breathing apparatuses. I tried to open my eye, and when it didn’t quite work out, I eased my hands close enough to pry the lids open with my fingers. Then, satisfied that I could still see, I let the eye close and sighed. “Oh goody, you took the right one.”

The fog of the anesthesia began clearing rather quickly. Another nurse told me she’d have to “grope” me for a while to remove the electrodes from my chest. “If only I could see you properly,” I quipped. She told me she was 45, had short hair, and generally indicated that I’d be disappointed.

The nurses got the bed rolling. Someone noted that the bed doesn’t move all that well with weight on it. I asked them if they were calling me fat, much to their horror. And my amusement.

Back at the room I started from. The anesthesia doc brought me water, made me drink through a straw. Next up, a mini-carton of juice, and again with the straw. I asked if coffee was an option, and while that was being arranged, I propped myself up. Drank the rest of the juice, and made a note of the fact that I really didn’t want to lie down.

Doc came back with the coffee. I drank it, eyed my surroundings. Took my laptop bag on the bed with me. Asked if I could have some salmiakki candy since I brought my own. Permission was duly granted. I munched down like nobody’s business.

Cue the nurses that would transport me to the ward where I’d sleep for the night. They wheeled me out to the corridor. I asked if I could smoke. Yes, I could. Could they get my jacket? And um, my lighter. From my pants pocket? I got the pants too. And onwards to the elevator.

On the seventh, top floor of the hospital, we got out of the elevator, and I got assigned a room. At first, they took me to the door of a children’s room, and looked around in confusion. Asked the nurses of that ward a couple of questions, and finally pushed my bed into an adult room with another patient in it.

I felt cheerful. The pain was gone, and apart from the itching, there was very little discomfort. I asked if I could plug in my laptop, then wired things up, and began IMing status updates every which way.

Later in the evening, Sari came to see me. Brought me a cup of latte from my favorite coffee shop. We talked a bit. After a while she got up and left for home. I was supposed to play Peggle. It took me hours before I got to that.

I got acquainted with my roommate during the evening. I got the impression he was suffering from a burnout. When the night nurse came with our painkillers, he told the nurse that the whole deal scared him. The nurse didn’t understand — the operation’s done. What’s there to worry about? You’re OK, and if you take care of the eye, everything will be fine.

Right. Your body is built so that it’s possible for your retina to disconnect from the back of your eye, the doctors are fixing it up with a small bubble of gas, you need to maintain an upright position for the next few weeks… but don’t worry! Your eye may suddenly explode into a bright fireworks of pain with no advance warning, and anchor you to your home for weeks on end. But since it’s operated already, don’t worry!

During the night, I kept talking to the roommate. He told me a bit about himself. He clearly needed someone to talk to. I think I may have talked too much for him to get to say what he was going to — or maybe not. After a while, the night-nurse walked past our door, heard us talk and came to chastise us for not sleeping. I wanted to snap. Neither of us felt like sleeping. We weren’t bothering anyone. If it was going to mean that I’d be tired in the morning, I should think it’s my fucking call to make. But I kept my mouth shut, and went to sleep. Tried to, anyway.

Next morning I had barely eaten my breakfast when the nurses came to wheel me back down to the ward where I’d get my final instructions and be released. I packed my stuff, shook the hand of my roommate whose name I never asked, wished him well and went off.

Down in the first floor things were a bit hectic. I got out of the meat-suit and back to my own underwear, comfy jeans and shirt. And then I had to wait. And wait some more. A doctor came to tell me I’d have to take a pain killer — we’d clean the would now, and it would be uncomfortable. I got a tablet that dissolved in the water. Another doctor stayed there to stir the tablet for me. The nurses and doctors zipped back and forth, never staying in one place for long. I felt impatient.

After a while, I’d downed the glass, and the doctor finally prepared for the cleaning. Every two minutes somebody would interrupt, the doctor would apologize, and I felt like screaming. Get on with it already, I want this shit OVER with. They unwrapped the bandages around my head and began tearing off the tape that held the swab of cloth to my face. And finally, it was time to remove the cloth that had been between the eyelids for the last twelve hours. Can you imagine a piece of cloth stuck to your eye? Almost, but not quite dried up, so you can tear it off, and it doesn’t exactly hurt… but it’s the most intensely uncomfortable feelings you can imagine.

The cleaning process turned out to be simple: take a 20ml syringe, fill it with saline or tap water, and slowly let it flush behind the eyelids.

The doc let droplets of saline fall to my eye socket, and suddenly the reality of my situation struck me. What had just been done to me. What sort of call I had been forced to make. And what I would have to do for who knows how long to keep from getting an infection. I sobbed a bit. I managed to make it look like it was the discomfort. They placed another swab on top of the eye, taped it to my cheek and forehead, and gave me a stack of paper with instructions, schedules, recipes and whatnot. I nodded numbly at regular intervals to keep things going. Someone kept interrupting, and my release kept being delayed.

Finally, they called me a cab. I was about to light a cigarette, and I felt like I was in the breaking point. The cab arrived sooner than I expected, so I put the cigarette back in the box, got in the cab and told him the address of the pharmacy near our home. Sitting in the cab somehow pushed the emotions back. I didn’t want to share them with the driver.

The cab driver drove close to the pharmacy. The meter said 29.80. And then he continued right past the door. Maybe because he wanted an even 30 on the bill. Who knows.

I bought the antibiotics and pain killers, and went home. When Sari came from work, we argued a bit — I was sensitive to everything. And then I broke down completely. For a while, I couldn’t do anything except cry. And while I cried, I kept fearing it would be bad for the wound. My eyelids were swollen, my hair was greasy, and moving my eyes hurt. Everything felt like shit.

It’s surprising, how quickly you heal, really. In every sense of the word. The next day I was still very emotional. I cried even more. And then something happened in the evening — the swelling went down a bit. The pain eased off a bit. And for the next two days, things looked a bit less terrible every hour.

Can you imagine looking at your swollen eyelids, thinking about how nothing in life is fair? And two days later, opening the eyelids, revealing something that looks not quite like a horror movie prop, but close. And being happy about it?

I can.

Today is the first day in well over two months that I could enjoy a cold beer. It suddenly struck me that there’s no reason I couldn’t have one. I don’t need the pain killers any longer. And even though the risk of infection will keep me from some places for a while still, even though it will be a month before I get the prosthesis, it looks like I’ve got my world back.

I’m taking a peek from my cave, and it looks like sunshine. It’s beautiful. And it no longer hurts my eyes.