Tuesday, March 25, 2008

It's MY problem

I've been working on a prototype for a startup for a little while, now, and in the process, I think I've discovered why some people would never want to be a business owner. This may seem stupidly obvious at first, but it doesn't really hit you until things start flying at you: there is no problem that is not YOUR problem.

In a large company you have a fair degree of specialization. I've always been a software developer, so I write code. Project Managers take care of vendor interaction, Graphic Artists draw pictures and icons, Web Designers build page mockups and design the User Interface, System Administrators keep the boxes humming, DBA's watch over data integrity, and managers keep everyone out of each other's way. Past a certain point, you have to do things this way because there is simply too much to do and too much to know in each category for it to be handled by anything less than a full-time specialized employee.

One result of this (not a necessarily negative one) is the evolution of the "Not my problem" mindset. As a software developer, it's not my problem if the production database has crashed. Somebody else is around who will take care of that, so I don't need to think about what's going on out there and can concentrate on writing good code. I'm like the anesthesiologist in a hospital, my job is to do one thing really well because there are other people who will handle the patients needs that don't relate to being unconscious. There's nothing wrong with this, in fact it's necessary because it permits each member of the team to become extremely proficient at their precise technical skill, but when it comes to bootstrapping a startup your whole world changes.

Startup founders are more like field medics: they've got to be just good enough at everything to keep the patient alive (all while under serious pressure). There are no surgeons or pharmacists in combat with the infantry, so medics never get to say "This isn't my problem". You fix it or you fail.

This has been a bit like my experience in the last little while. Anything that comes up: Problems with the server configuration, UI quirks, graphics and visual design needs, uncooperative platform vendors, none of this can I pass on to a specialist to handle because there IS no one else. Whatever it is, it's MY problem, and I've got to either figure it out or fail. That can be a lot of pressure, and there are many people who would ever wish to go through an experience like that, but in a way I find it invigorating. I'm no superstar with any of those topics mentioned above, but I can now say conclusively that I know SOMETHING about each of them and that I have a good foundation for learning more. There is no greater supplier of competency than necessity.

Monday, March 24, 2008

SMS Gateway Review

UPDATE[04/10/2008]: The problem I experienced with Clickatell has since been resolved.

The new startup I'm working on depends on the sending and receiving of text messages. So naturally, when I got to the point in my development where I wanted to code up the SMS section of the app, I did a quick google search to see how other Ruby coders had accomplished this in the past. I felt pretty fortunate when I came upon a Ruby Gem already built to work with the SMS gateway service www.clickatell.com. Excited at the prospect of an easy touchdown, I installed the gem, got an account with clickatell, and my app was sending text messages within an hour. Great! Next step, I needed to be able to RECEIVE messages, so I started digging through clickatells "products" section trying to figure out how to accomplish that feat. It turns out it's pretty easy, just follow these steps:

1. Fill out clickatell's "application for two-way messaging".
2. Read the confirmation email they send you, asking you to pay 175 Euros through their website.
3. Go to the website, try to figure out where to make your payment for two-way messaging.
4. Go back to your email account, reread your confirmation email, realize how stupid the process is going to be.
5. Return to clickatell.com, buy enough text message credits to equal 175 Euros, then send an email to their support department asking them to reallocate the money into creating a two-way messaging account.
6. Wait for them to email you confirming the creation of your account.
7. Three days later, begin to suspect that you are not going to get that account after all. Check your credit card bill.
8. Send an email to support@clickatell.com asking for a status update.
9. Wait long enough to realize your not going to get a reply.
10. 4 days after sending the email, get a reply indicating that it can take weeks, or even months to set up a two way account.
11. write back asking how this is possible, since both the website and the confirmation email they sent you indicate 48 hours as the necessary time frame.
12. Get no reply. Ever.
13. realize that you just can't wait that long to have your website working, send multiple emails to clickatell requesting the closure of your account and a refund.
14. rework your code to work with the SMS gateway service ipipi.com instead.
15. watch in awe as ipipi.com has your two-way messaging set up in 3 business days.
16. watch in awe as you still have no reply from clickatell.
17. file a complaint with the better business bureau.

My advice to you is to skip directly to step 14.

Tuesday, March 18, 2008

The Flick (Old code is Bad code?)

Don't let the title fool you. Old code is not by defination bad code. I don't subscribe to complete rewrites very often. What I've noticed is that my initial impression of a piece of code I need to work in goes down exponentially as the time since I last looked at it increases. Maybe this is unique to me and no one else has this kind of experience, but when I revisit an application I haven't worked on in a while, I am inevitably overcome with revulsion.

"Good Lord, who wrote this crap??.....Oh man, I wrote this crap!"

Maybe, some of you are saying, This is a result of you writing bad code. Ok, I'll concede that as a possibility, maybe even a probability, but my question is then "why doesn't it feel like bad code at the time?". After considering the possible contributers to this phenomenon, I have a theory.

"The Flick"


The Flick -- A term used by air traffic controllers to describe a mental model representing the current and future positions of air traffic in a section of airspace. Controllers visualize the paths of multiple aircraft in terms of position, altitude, trajectory and speed. Controllers also refer to this as "having the picture." But the picture moves -- like a movie -- hence the term “the flick.” (borrowed from this really neat blogger.)


My younger brother, Oliver, has always had a strong interest in flying. He's looking to get his pilot license, and has bought every flight simulator every made. One unique purchase, that is within the same industry but a little off to the left, was a simulator that was used to train Air Traffic Controllers, a group of people whom I am fascinated with. For those of you who don't know the lore surrounding these guys, it's basically one of the most high stress jobs in the world. You have a large screen mapping the locations of all the planes under your control, and you must issue instructions to prevent collisions while maintaining a reasonable schedule. In a busy area of sky, this can get very complicated very quickly. In order to keep everything straight, the controllers have to have held in their head at all times a model of the airspace they are responsible for, and spontaneously feed into that model any new information. Naturally, this is a precarious balance, and it's possible to get distracted or overwhelmed and lose that picture, kind of like freezing in a game of tetris: you have to put the next block somewhere but it's moving too fast and you've lost the overall structure (dramatic oversimplification).

Anyway, I think that when you're working in an application every day for many hours, you develop a certain situational awareness about where everything is: you have the flick. You know how everything works together, and the flow of control makes sense to you. After a few months of NOT working in that code (or perhaps approaching a code base you have never worked in before) you have no such model in your mind: you've lost the flick. Things seem to be in the wrong place, you can't understand why the internal algorithms are so convoluted, and you get a general feeling of unpleasentness about the code. Some people describe this as "Code Rot", but that applies more accurately to code that has been maintained by someone who doesn't understand it. If the code hasn't changed, it hasn't rotted. You just aren't seeing it the way you did when you left it last.

So that begs the question, if the code looks this troublesome to you when you don't know anything about it, is it really any good? Tough question, but I'm going to lean towards "no". Ok, that's self-incriminating, I know, but it's also pretty much true. I know that one of my weaknesses as a developer is writing code in a way that works but that isn't necessarily transparent (easily processed by others). Many people who share this problem with me are of the opinion that their code is simply too advanced for anyone else to understand easily. Bull-hockey. Great developers produce code that is both elegant and understandable, not merely functional. Anybody can build a house, but it takes careful planning and forethought to construct a building that will stand for many years and that has all the components exposed correctly to make maintenance as easy as possible. That is what we should strive for, a codebase that doesn't make you gag when you first sit down to it again. During development, it's important to find a way to escape "the Flick" and to be able to consider what you're building from the point of view of an innocent bystander. How will you best structure this masterpiece so that other's can derive benefit not only from the product, but from the source when they dig into it?

Just a thought. Happy Easter, everyone!

Wednesday, March 12, 2008

Language Learning

I decided this week that I want to learn how to speak Russian. My father's an immigrant from the country, and every time somebody finds that out about me they say something like "Cool! Do you speak Russian?" (or worse, "Cool! Каково ваше любимое кино?" *Expectant stare*). I feel I've been doing something of an injustice to my heritage, so I bought the "Rosetta Stone" language learning program and I've commited myself to the goal of at least be able to stumble through a simple conversation.

Now that I've been at it a few days, I'm doing OK. I can point at things and say their name, their color, maybe how many there are if the number is low. It's actually kind of fun. What's struck me in the process is how some of my attempts to learn things quickly have hurt my progress, and how I've seen this happen when going between programming languages as well.

Had I been following the software program to the letter, I would just be learning by immersion in the language and not concern myself with trying to obtain other information outside of it's carefully constructed progression. That way I'd learn by example what proper word order is, how word endings modulate with context, and so on, without picking up any bad habits I'll have to un-learn later. Since I'm a little impatient, I quickly wanted to figure out some simple phrases that I'd consider useful. You know, "how are you?", "where is the bus station?", "I need a doctor!", etc. My approach to that was to simply take each word in the phrase and one at a time run it through the English-to-Russian dictionary, thus constructing the phrases I needed. Of course, the immediately apparent problem is that I have given no thought to grammar or syntax. I just know that in English I would phrase it this way, so now I'm basically saying English phrases in broken Russian. Hardly a good direction if I ever want to be able to hold useful conversations.

So what do you get when you have a developer who's worked in PL/SQL or PL/1 for a long time, and they start writing in C# or Java? They'll pick up a book, and learn enough of the syntax to basically write a program line for line the way they would in the old language, and still get it to compile. Does it work? Well, yes, in the same way that somebody who was learning English could say to you "Me name is be Frank" and you would know what they mean. It works, but it's not correct.

When going between spoken languages there are new rules for grammar that must be observed in order to make the best use of the language. Likewise, when learning another computer language that is of a different paradigm than those you are used to, there are new ideas and new ways of thinking that should be studied in order to maximize the usefulness of the language. If you're using C# and aren't taking advantage of delegates, generics, or even just objects, than you're probably fighting a lot harder than you have to.

Thursday, March 6, 2008

ActiveRecord Gotcha

I thought I'd throw out some information regarding ActiveRecord for those who are new to the Ruby on Rails framework. This is just a little thing that took me a few minutes to figure it out, but I could see where a newbie would get frustrated and give up on figuring out what's wrong. The issue is referring to attributes from within an ActiveRecord object. Assume you have a "person.rb" model, and that the table has columns "first_name", "middle_initial", and "last_name". Give this structure, you might want to create a method like the following:

class Person < ActiveRecord::base

def full_name

first_name + " " + middle_initial + " " + last_name

end

end

This way you could get that person's full name in one method call. When you run your tests, though, you'll be told that 'nil' can't be converted to a string, and you will wonder where nil is coming from. You'll check the column names, and find them correct, and then check you fixture data, and find that your fixture has all the data populated. You'll put in debug statements that look like this:

ethan = people(:ethan)
puts ethan.first_name
puts ethan.middle_initial
puts ethan.last_name

and you will see that the data is there, you just can't seem to access it from WITHIN the Person object; and then you might start to cry. Fear not, the problem is not some hidden bug, you just have to know how Ruby works. When it sees [first_name + " " + middle_initial + " " + last_name], it assumes that you've just created three local variables, and they are all initialized to nil. You can pick up the "Pick Axe" book if you want to understand this further, but the short fix is to restructure your method to look like this:

class Person < ActiveRecord::base

def full_name
read_attribute(:first_name) + " " +
read_attribute(:middle_initial) + " " +
read_attribute(:last_name)
end

end


or, for those interested in brevity:


class Person < ActiveRecord::base

def full_name
self[:first_name] + " " +
self[:middle_initial] + " " +
self[:last_name]
end

end


Happy coding!

EDIT:

It could be pointed out here that my Java/C# background has led me to concatenate strings with variables using the '+' operator. In Ruby, it would probably be considered better stylistically to use the #{} construct within the string where a variable is necessary. Thus, the above code would become this:

class Person < ActiveRecord::base

def full_name
"#{self[:first_name]} #{self[:middle_initial]} #{self[:last_name]}"
end

end

Tuesday, March 4, 2008

The Bug Hunter

You've just spent the last hour hacking on an application you haven't touched for a couple months. Nervously, you fire it up hoping that your skill in refactoring has saved you from having to spend the next few hours playing with break-points. Loading...loading...loading...executing...BOOM!!! A massive error message springs up on your console:


ERROR:
Expected flux-capacitor to be synced with solar radiation;
please re-calibrate your floogletron before invoking any
method that starts with the letter 'Q'.


oh crap. What now? You have never seen this error before, nor any like it, and the stack trace is all third party code. Looks like you're on a bug hunt.

I've been thinking lately that debugging may be a skill that does not necessarily exist in tandem with pure development ability. I have seen otherwise good developers absolutely thrash for hours when they come to a problem they're unfamiliar with. They basically take a wild guess at what "probably" caused the explosion, and then tweak that segment of code until they get really ticked off and decide that the problem is unsolvable. If they're resilient, they MIGHT pick another area of the code to start tweaking by throwing a dart at a printout of the source.

Obviously I'm exaggerating a bit, but nevertheless I've come to the conclusion that a lot of developers approach debugging the way a child would approach cracking a safe:

8-12-43 ? no
27-26-25 ? no
1-9-2 ? no
12-34-5? no
.........

It's obvious to you or me that you aren't going to get anywhere that way. Oh sure, there's a CHANCE that you could correctly guess the combination within the first few minutes by picking random numbers, but the chances of it are so remote that it's almost not worth trying. This is about how useful it is to see an unfamiliar error message and to start tweaking away at random pieces of code hoping that something you change will fix the problem; your chances of succeeding are low, and the process will probably end in frustration. Unfortunately, I've seen that approach taken far too often.

For a second, consider the way a safe COULD be cracked. If you already know how the internals of a safe work, you could devise a strategy for getting inside. If you don't know, you're going to have to find out. That's step one; you have to at least have an IDEA of how the offending code is supposed to work. If it was written by another developer at your company, or if it's a third party library, you may have to do a little research, but a little research up front sure beats hours of thrashing.

To give a brief idea of how a safe works (not to encourage any criminal activity), there are as many wheels in a combination lock as there are numbers in the combination. All the wheels have a notch in them that must line up with a shaft (called a "fence") in the lock in order for it to open. I'm going to simplify this greatly for the sake of brevity: basically each time you switch direction one more wheel stays in place, and if you put in the right combination all the wheels will end up with their notches lined up and the fence will drop into the aligned notches, allowing the lock to open (that's the cliff-notes version, anyway). Given all that information, we now know our problem space. So what's the easiest way to open the safe?

KNOW THE COMBINATION!!!

OK, so maybe this seems like a painfully stupid answer, but it's the truth. The most common method used by safe crackers to get into a safe is to somehow know the combination. This could be accomplished by finding where the safe-owner wrote it down, or by trying the industry standard combinations that most safes ship with (the owners are usually supposed to get the combination changed upon purchasing the safe), but one way or another they just get ahold of the combination.

The computer software equivalent of this technique is to compare the offending code to a code example. Many errors are just due to some syntactical error, especially in the case of libraries backed by XML configuration files or the like. Google is your friend in this case, as somebody has probably done something similar to what you're trying to do, and you can run a quick comparison to see if anything you've written is flat out wrong. This can easily save you hours, especially if you are relatively unfamiliar with the library you're working with.

But assume that you can't find the combination (read as: according to the code examples, you've done everything right). In that case we're just going to have to crack the safe. Now in movies, you've probably seen somebody crouched next to a safe with a stethoscope, and within seconds they've determined the combination and are on the run with the goods. As is usually the case, real life just ain't like that. There is a way to use a good ear to crack a safe, but it takes patience and is a little less glamorous. Basically (again, not encouraging criminals), the safe cracker uses his ear as he is slowly spinning the dial to determine when the notch in the "drive cam" (which is the main wheel attached directly to the dial that manipulates the actual combination wheels) arrives under the fence. The result will be a small click, which let's the cracker know he's found it. Next he turns the wheel all the way around to the opposite side of the dial in order to disengage all the combination wheels from manipulation. Once that's done, he can begin turning to the right again, and every "click" he hears from then on out is another wheel being engaged inside the lock. By counting these clicks, the safe cracker knows how many numbers are in the combination. THEN comes the tedious part. In short, the cracker starts from various positions (usually intervals of three around the dial) and turns slowly, listening for the tell-tale sounds of the contact area clicking by the fence, and records these results in order to show (on a graph) the correct numbers within the combination. The only remaining trick is that he doesn't know in what order they come, so in a three-number combination lock he must try each of the 6 possible combinations until the lock opens (obviously the more numbers in the combination, the longer this part takes).

Now, what was the point of that long explanation? Well, it certainly wasn't that I wanted to turn you into a criminal mastermind, because that sure won't be enough to get you going. The key point is that a safe-cracker doesn't just fiddle with the thing until he gets it right; he systematically reduces his problem space one piece at a time. Find out how many numbers are in the combination, then find out what numbers they are, then determine the order. It can take a little time, but he will find the answer in the end.

Likewise, the best debuggers I know have a mostly systematic approach to unearthing the problem behind a tricky bug. Variations on the pattern exits, but usually the problem can be reduced to reverting the application to a point at which it worked, and then incrementally adding one piece of code at a time (testing after each iteration) until it breaks; presto, the cause is known! It's not fixed yet, obviously, but you've narrowed your problem to the exact line that is screwing your application, and 90% of the time that you are now less than an hour away from fixing it. Is it trial and error? Yes, but it isn't random, and it can mean the difference between days and hours spent on a problem.

Monday, March 3, 2008

Education: is it worth it?

Every night after work, I don't go home immediately to have dinner with my wife (which is a shame, because she's a great cook). Instead I drive the opposite direction and spend the next few hours listening to lectures about polymorphism, computational complexity, data structures, and all the other academic topics that fall within the realm of computer science. That's right, I go to night school.

It's really not that bad in and of itself, most nights are at least interesting. But I have to wonder if there's really a point to what I'm doing. I spend most of my evenings there, a good chunk of my paycheck, and plenty of weekend time on homework; the idea is that once I've done this for a few years and have a piece of paper to hang on the wall, I will somehow be better off because of it. Well, I'm not sure that's the case. Computer science students generally graduate with their bachelors degree, and then they start looking for a job doing software development....which is exactly what I've been doing as my career in order to pay for my computer science degree.

That begs the question, is the degree necessary? Conventional wisdom would say "Of course!! Without a degree, you will starve on the streets of the slums and contract cancer at a horribly young age and spend your last few breaths of life on this earth bemoaning the fact that you didn't pursue higher education!!" I would contend otherwise. I think that an education is a critical requirement, for sure, but that you don't have to go to an institution in order to obtain one. This may not be the case for some fields that are more "Political" in nature; you probably need a degree in order to become a foreign diplomat. But in software development, a field where craftsmanship is one of the more critical components, your best education probably comes from an experienced craftsman. That COULD be a professor at a college, or it could be the founder of a tech startup that you start out working for. Put another way, if you were going to commission a work from a sculptor, would you hire the man who had a fine arts degree from Venice with a concentration in physical art, or the man who could show you several sculptures he'd made in the past. To me, that's a no-brainer.

Now, some of you will have spotted the problem with the above comparison: what if the man with the degree ALSO has done several sculptures in the past of comparable quality? Of course, you would then take the man with the degree. Here is what I think is the unfortunate reality, and the reason I'm still pursuing that bachelor's degree for myself: It's a check mark on every HR department's filtering checklist. If you have 500 resumes, and can only interview 30 people, an easy way to cut out half the contenders is to throw away those with no degree on their resume. That's a shame, but it's a pragmatic choice and I can appreciate it.

That being said, I would advise people who are considering an education in computer science to consider carefully what they want it for, and weigh it against the ever-rising cost of getting a degree. My experience is that 5 years into the job, a degree that came with $90,000 in student loans isn't necessarily that much more helpful than a degree that you paid a total of $10,000 for and worked towards mostly at night and on weekends. In fact, consider the following comparison: software developer with 4 year degree at stellar institution vs. software developer with 4 years of solid work experience and a reasonably priced degree to boot. Who would you hire?