Tuesday, January 19, 2010

Announcing Availability of tgext.menu, v0.2

Long story cut short: I've not been moving on Bit Vizier as fast as I wanted for a number of reasons. One of them is the pain that is managing the navigation bar from a development perspective. If I want to move things around, I have to update my controllers and my navigation bar template. If I need to rename something, I have to do the same. If I want to add a feature, I have to do the same. The navigation bar, the side bar, and any other menus are all easily determined from the code. Why do I have to maintain a separate template?

With tgext.menu, I don't have to do so anymore. Instead of having a separate template, I simply have to provide a list of the menu entries, and the rest just happens. It makes dealing with things much easier.

tgext.menu is available on the Python Package Index (for use with easy_install), and also on bitbucket.org (to get the source code).

I'll apologize now for the shortness of this post. I'm still recovering from ear surgery, so mildly unavailable, but didn't want to hold this back any longer.

Wednesday, January 13, 2010

Choose The Right Data Structure

This one is actually almost embarrassing to post. I've been working on an extension for TurboGears called tgext.menu. I'll not get into long explanations of why, or what I hope to accomplish with it (I'll leave that for when the first release happens, hopefully early next week).

I will say this, though: If you don't choose the right data structure, right off the bat, you are condemning yourself to a hellish experience coding.

In my case, I had a list that looked like this:

  • ExitApp
  • Foo Spot
  • Foo Spot || Bar
  • Foo Spot || Baz
  • Foo Spot || Foo
  • Foo Spot || Sub || Bar
  • Foo Spot || Sub || Baz
  • Foo Spot || Sub || Foo
  • Sub || Sub 1
  • Sub || Sub 1 || Nested 1
  • TestHome
I wanted that to become a nested unordered list in HTML, looking like this:
  • ExitApp
  • Foo Spot


    • Bar
    • Baz
    • Foo
    • Sub


      • Bar
      • Baz
      • Foo




  • Sub


    • Sub 1


      • Nested 1




  • TestHome
Looks really simple, doesn't it? All you have to do is loop over the list, split each item on the || symbols, generate openings, put your entries, and generate closings. Except you have to compare the current base of the tree with the next base of the tree and the previous base of the tree.

I can't count the number of methods I tried, and every one of them had a small, subtle, error that threw off all the output. Sometimes elements would not be closed properly. Sometimes they would not be opened properly. I tried iterating, I tried recursion. All of them failed with errors that I could not find a generic way to correct.

Saying this was frustrating is a major understatement. Last night, I finally changed my data structure that represented the output: Instead of a list, I went with a tree. Using a tree, I was able to write up (in less than a dozen lines) a simple recursive loop that wrote out the entire tree, with appropriate whitespace, CSS class tags, the work.

In one hour, I solved problems that had been plaguing me for two weeks.

Lesson learned: If I'm spending a lot of time trying to solve a specific problem, and my algorithms are always producing errors, I need to look at the underlying data structures. I'll probably save myself a lot of time that way.

Wednesday, January 6, 2010

Are You So Arrogant ...

I was insulted last night. Now, there's nothing new about that, nor even anything particularly blog worthy. After all, we all get insulted in some fashion or another on a regular basis. We shrug it off, and we move on. This time, though, I've heard this particular insult too often. I want to address this, in particular: I was called arrogant.

Why? Because I answered a question.

The person who called me arrogant had asked about a particular piece of a program I've written, wondering what would happen if the user did a specific action. I replied that them doing so would be irrelevant, since it could do no harm. The reply came back, and amounted to "Are you sure?"

Suddenly, I wasn't sure. I went back to the code, and re-read it. I checked the actual behavior while running. I verified the contents of the database. Now, I was sure again: It simply didn't matter if the user did this action. It produced an off-by-one sum error for something which already has a much larger margin of error (counting cards that got sent and receieved from around the world). Being off by one in that situation causes no concern whatsoever.

Despite this, I then checked the database to see who was doing it, and found a whopping four people out of fifty three had done it. I spelled all of this out for the original questioner. Since the original questioner is not a technical person, I made sure to use terms that would make sense to her.

And then she asked the question that started with the title of this post: "Are you so arrogant ... " (yes, I've left the rest out, as I'm trying very hard not to make this an attack against her, and quoting her excessively would do just that).

I'm arrogant because I answered her question in terms that I knew she would understand.

After that, she mentioned that, in her experience, computer people (programmers, techs, administrators, etc) come across as if dealing with idiot children when dealing with non-computer people. So, instead of just being arrogant, I'm arrogant and condescending.

This is where the great disconnect occurs, and is the main point of this post: As a developer, I have to know things about the computer that many people do not. Doing web development, I have to know HTML, CSS, and JavaScript. If I'm doing anything with dynamic data, I also have to know whatever programming language I'm using on the server, and some database dialect so I can store, retrieve, and manipulate that data. All of that is the bare minimum required to do that work.

In order to do it well, I need to know some bits about the underlying operating system, the web server software being used, basics about HTTP (and possibly https), and the quirks of the various browsers in use around the world (IE6/7/8, Firefox, Opera, Chrome). Possibly more importantly, I have to have the knowledge that I can make no assumptions about anything. I can't count the number of times I've said "That's not possible to happen!" only to find out later that not only was it possible, it happened due to a bug in my code, and that bug came from an assumption.

In other words, I have to have a huge amount of specific, detailed, technical knowledge rolling around in my head just to do the basics of my job well. When I get somebody who is a self-proclaimed non-technical person asking me for answers that require at least some of that knowledge be handed out, I have to mentally change gears and use terms that I know will work to explain that knowledge. Of course I sound condescending, simply because I try very hard to make no assumptions.

The part that I find most interesting to me, in all of this, is one thing that my experience has taught me: The more understanding people have of their own systems, the less likely they are to call me arrogant when I explain an answer to their question.

I care a great deal about making sure I'm understood. There are times when my doing so comes across as rude, arrogant, or condescending. I do not set out to do so, but there are times when I cannot think of a way to avoid it. I actually don't like doing so. To have the insult lobbed in my direction on top of that is more than I can accept. I had to say something.

My final thought on all of this comes from her final remark: "Not everybody is a computer genius." That's correct, not everybody is. Not even me. If you want to find out about a few of them, allow me to give you some names to look up: Alan Turing, Steve Wozniak, Linus Torvalds, Alan Cox, Theo de Raadt, Brian Kernighan, Dennis Ritchie, Larry Wall, and Guido von Rossum. I am not, and never will be, in their league.