Fixed-width Font in GMail…

I know there’s a setting in Labs to allow you to switch to a fixed-width font… but that requires me to go and do it. Here’s a tip from Leo Soto that helps render the message as fixed width if you run Firefox: http://blog.leosoto.com/2009/03/fixed-width-font-on-gmail-again.html

PyCon 2009

Just a reminder that PyCon 2009 is just around the corner: March 27-29 in Chicago. Last year’s PyCon was a blast, and I expect that it’ll be this year too (lots of good talks lined up).

Check out their website: http://us.pycon.org/2009/about/

And remember, this is a great way to get some very cost effective training. The tutorials are a great way to learn, and taught by some fantastic people. If you’re a guru, stick around for some sprints after the conference is finished!

I look forward to seeing you there!

Recently snapped…

Some days I wonder if I’m ever getting better at this photography stuff, and then I snap a picture like this:

Matthew

This was originally a color picture, but after looking at it, thought it would look better as a black-and-white or sepia. I used a preset from Wonderland Presets called Sepia Chic. I really like the effect. Kudos to my son, Matthew, who was a trooper in front of the camera!

BTW, recently got the D700 for the high ISO range, and I’m loving it. It feels much better in my hand than the D80. It’s an excellent camera and expect to be using it for a long time.

Mini-review of Lightroom 2…

I’ve been using Lightroom to manage my photos now for nearly a year. I’m by no means an expert, but here are some of the pros and cons that I’ve accumulated.

Pros

Awesome Image Adjustments

This is Adobe, after all. Lightroom’s image adjustments are top-notch. Easy to manipulate, they’re fast, and fairly intuitive. It’s got the typical auto-tone, and good auto-white balance. But also has a tone curve control (not unlike Photoshop’s) and a nice split-toning control. This was the primary reason that I chose the tool, since I’m still a newb and often screw things up (like getting the exposure right—which I’ve gotten much better at lately!).

Smart Collections

I like the fact that I can build collections from the tags. I’m still not using this feature as much as I should be, but I like having it when I want it.

Printing Options

The printing mode is very nice in that you have quite a bit of control over page layout and such. I’ve not used this nearly as much because I don’t have a photo printer, but when I have, it’s been easy to use.

Cons

Poor Performance

Making the image adjustments is fast, and you can tell they spent a lot of time on it. Unfortunately, it’s the only thing that feels fast. Switching modes takes a long time. Browsing doesn’t go nearly as fast as I’d hope (it takes quite some time for the images to show the thumbnails, despite the fact that I chewed up the extra disk space to render them). This has been really disappointing, and it has me thinking about switching to Aperture, to be frank about it.

No Support for Photoshop Plugins

So, when you name a tool “Adobe Photoshop Lightroom,” I have a few expectations. The one that’s foremost, is the ability to use Photoshop features in Lightroom, even if it means I have to own Photoshop to do it.

Unfortunately, that just isn’t the case. It’s got a decent workflow between the two tools: you can open up an image in Photoshop from Lightroom, and have the new image imported into Lightroom immediately. And you can run some Photoshop actions using a “droplet,” but you can only do that on export.

My hope early on was that Adobe would make it easy for companies that wrote Photoshop plugins to port them to Lightroom. As it stands right now: the only thing you can write plugins for are export actions and the web stuff. That’s it. Not very useful, IMHO.

The lack of built-in support for third party plugins for things like noise reduction, also has me thinking about switching to Aperture. At least the stuff that I currently want, is readily available as a plugin for Aperture.

I’m a bit disappointed about how I generally have to navigate my way through my photo collection in Lightroom. The only real way to do it is via the folder/collection tree in the left-hand pane. I’d rather be able to point-and-click within the main viewing area though. Once again, Aperture lets me do that.

Can’t Get My Raw Files Back From DNG

Yes, you can do this using an external tool, and Adobe does provide it. But I can’t do it directly from Lightroom, and that bugs me.

Where I Stand

I’m very much on the fence about this tool. I really like the ability to make localized corrections, and I really like Lightroom’s image adjustments. I’ve tried to wait out the issues of performance, and the lack of plugins. I’m going to wait a little longer, but I have a feeling I’ll be switching to Aperture. At the moment, it looks like my personal workflow would be better if I were using Aperture.

Corollary to my recent post…

Jeff Atwood has a wonderful way of saying these things:

Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.

See it for yourself at http://www.codinghorror.com/blog/archives/001137.html. Make sure to read the maintenance programming article too!

Code Readability

Code Nazi.” That’s the phrase that was used to describe me lately. It’s pretty much on target, and I’ll explain why that’s true.

I view source code as part of my trade craft. Perhaps it’s because I work in a service industry and my deliverable is source code, not just binaries. So I spend time thinking about whether it’s well organized, and whether or not someone else can read this enough to take it over? I don’t want to maintain a project for eternity. And I certainly don’t want my customers to feel like I’ve backed them into a corner where only I can maintain the codebase. That’s not good for anybody: me or my customer. Plus, I see it as a reflection of my team and myself, just like any other trade views their works of art. People also have an undeniable tendency hang on to their first impressions. A code base that is clean and readable leaves an entirely different impression than one that is disorganized and poorly formatted. I want the customer to walk away feeling like we paid attention to every detail.

Paying attention to the details is important. It’s all about the details.

Let’s reach back into history and look at how things used to be in books, since reading code shouldn’t really be all that different than reading code. It used to be that sentences were written like so:

thisisareallyhardstatementtoreadbecauseall
thewordsarecrammedtogether.

Interestingly, that looks like half the source code I read:

if(something!=somethingElse){
  MyType mytype=new MyType();
  takeSomeUnreasonableAction(mytype);
  if(mytype.fetchSomething().doSomething()){
    return false;
  }
  return true;
}

Typographers and graphic designers discovered a few things: whitespace and alignment matters. And not just a little bit. It’s the difference between readable and unbearable. It’s the difference between elegant and mediocre. Let’s look at the same example with a little whitespace sprinkled in:

if (something != somethingElse) {
  MyType mytype = new MyType();

  takeSomeUnreasonableAction(mytype);
  if (mytype.fetchSomething().doSomething()) {
    return false;
  }

  return true;
}

It’s not much white space that has been added into this code block, but look what happens. You can clearly see the conditional—it’s not a function call, which is what it looked like previously. The initialization of the variable is it’s own step, because it’s broken away from the use of it. Then we operate on it, and get some result back out of it—that’s another step. And, if all went well, it’s easy to see that we’d return true out of here.

There’s a flow, and it’s encouraged by the whitespace around it.

This short example doesn’t make much of a difference. Try reading a whole codebase in the previous format, and I guarantee you’ll pull your hair out at the end of the day. Believe it or not, it takes a little extra energy to parse the first block of code, and it quickly adds up over the course of the day. I’m speaking from experience: I’ve read a tremendous amount of code.

So, yeah, I’m a Code Nazi. You read several millions line of code and see where you stand. And just for kicks, head over to the Subversion codebase and see how readable it is. How does your own project standup? Does it say “this software is mediocre?”

Note: for the curious, no, having a great looking codebase doesn’t come first over solving the problem. I am engineer after all: function over form. But having a well-formatted codebase is a very, very close second.

To see some examples of early writing, look at http://en.wikipedia.org/wiki/History_of_western_typography, and in particular, at http://en.wikipedia.org/wiki/File:Trajan_inscription_duotone.jpg.

Review Board and Djblets…

I’ve been looking a lot lately at getting a tool together that allows developers to easily set their projects up and encourages a good workflow without being forced into a specific paradigm. For instance, I think it’s a good idea to review before commit, but some projects only have a couple devs, and that can be painful when the other is out on vacation.

If you haven’t seen Review Board, you should take a look. They’re well on their way to a 1.0 release, and I have to say: it’s come a long way since I first saw it. It’s looking really sharp. They cleaned up the UI considerably, and have started supporting multiple VCSs. They’re also heading down the path of providing post review support (review after commit) as well. I like a lot of what they have done. However, I’d like the option of doing it both ways on the same project (review before commit when we can, and review after commit when the other dev is out for a bit). So I’m really eager to see how things shape up after 1.0. I’m definitely excited about it.

There is an internal component that I find very interesting though: Djblets. It’s part of Review Board, although packaged separately. It scratches a few itches: helping to move your Django instance to under a specific url, some nice registration and authentication options, caching, and datagrids. The last one is the one I find most interesting. It helps you do sortable tables, and linking, all relatively pain free.

Chris Hammond has written up a few articles about how to use Djblets. Take a peek and see if it scratches your itch as well!

Focus chart…

Jeffrey Friedl has an entry on his blog about testing autofocus on DSLRs. I’ve looked for this kind of thing in the past (figured it would be handy for evaluating lenses). This has to be the best chart I’ve seen yet, and it’s free.

Stepping up my ssh game

In the past, I used ssh almost solely for remote administration of a couple of boxes, which were well within my physical control (in the server room at work, the one at my desk at home, etc.). However, I’ve started using my laptop more and a number of services/tools that I want to use (Gitorious, Bazaar, Git, Launchpad, etc.) build on top of ssh. So I figured it was finally time to up my game on that front.

I always knew I should protect my private key with a passphrase, but to be honest, I’ve never done it—until recently. Just googling on ssh, you get pages of material that completely gloss over adding a passphrase to your identity key and why it’s important. Dave Dribin at least mentions it in his article on ssh-agent and Leopard’s integration with it. The basic premise is that someone has gained access through your account: through your web browser, using a terrible password, leaving your laptop unattended at the coffee shop, or perhaps it was stolen. If someone has your private ssh key, and it isn’t protected by a passphrase, then you’re in for a world of hurt, especially if you’ve been talking to a bunch of boxes. Better yet, they know exactly which hosts to compromise first. They’re listed in ~/.ssh/known_hosts.

However, adding a passphrase isn’t all glorious either. Most folks would like to simply ssh into a box, and start working. No password involved (at that’s one of the beauties of public key authentication). Adding a passphrase to your key means that ssh will want to ask for your passphrase every time you connect to a box. That is, unless you use ssh-agent.

ssh-agent has been around for quite some time, and helps to relieve that burden of entering your password every time. On the Mac, you had to launch it yourself or set it up to launch when you log in. I don’t use ssh that much, so it’s annoying to have it around constantly, and—as Dave Dribin points out—there are concerns there too. Dave also point out, that Leopard changes how ssh-agent is integrated. It now fires up only when you need it, and you can incorporate your identity into KeyChain, making it much more convenient to work with identities protected with a passphrase. He also has a follow-on article about how to use the KeyChain in a more secure manner. If you don’t happen to be using Mac OS X, there are other graphical agents for Linux that can do similar things (gnome-keyring comes to mind).

So, I’ve finally got my new keys installed and my old ones removed. It didn’t take very long—about 10 minutes once I was happy with how the integration with Leopard would work.

Oh, BTW, there’s a nice little article by Paul Keck on how to set up ssh keys. Getting the keys generated is easy, the man page tells you how to do that pretty well, but he has a nice little section on “single-purpose keys.” It wasn’t until recently that I realized you could put command="/path/to/command args..." in front of the key in ~/.ssh/authorized_keys to run a specific command upon sshing into the box. It’s pretty nifty, and that’s exactly how Bazaar, Git, and a host of other tools utilize the ssh transport.

Neat stuff! ssh has to be one of the best tools ever. It’s flexibility is unmatched. So make sure you keep it secure. :-)

Eye-pod

Yesterday, my son did something very amusing. We were playing with the blocks, and assembled what you see below. While he was describing it, I happened to hear what he called it. So I asked him what it was—just to be sure—and he said: “It’s my iPod!”

Eye-pod

Python 3.0 is here!

This has been a long time in the making.

We should pause for a minute and think about what just happened. It’s not often that a language choses to break backwards compatibility for the sake of the language. I, for one, give the entire Python dev team and community a great deal of thanks for not only allowing it to happen, but for having the vision that if it didn’t then we’d be far worse off. Look at Java’s generics and how they were bolted on to the language. If Java had chosen to break some compatibility, where would the language be today? Yeah, maybe folks wouldn’t adopt it up front, but that’s okay. It always takes time to move across those boundaries, and it will happen.

Congratulations to the team and the community!

Grab it now! Port your code!

http://www.python.org/download/releases/3.0/

Looking at ANTLR

I was sitting down last week looking at (yet another) problem where I needed to parse some data and bust it up into a tree, so that I could walk it and generate some specialized output. Generally, my need for doing this has been smallish, very specialized, and I know exactly what I want, so cranking out the code by hand is pretty painless. In this case, however, I need to parse some C, which isn’t all the friendly to parse without a compiler front-end. Which then lead me to think about ANTLR.

I’ve run across ANTLR in the past, and started thinking… I was about to parse this stuff into a tree… if I had to name that tree… it would probably be an Abstract Syntax Tree! So I finally decided to invest some mindshare into it and get The Definitive ANTLR Reference: Building Domain-Specific Languages by Terence Parr. Mind you, this isn’t my first foray into compiler front-ends, grammars, and such—despite the fact that the only two comp-sci courses I’ve ever taken are Cryptography and Digital Signal Processing Algorithms. However, I’m finding the book to be an amazingly easy read, and bears a lot of relevance to the several times I’ve need to recode data from one format to another. Up front, Terence got you writing a small grammar, and seeing some output. He then showed you how to turn it into an Abstract Syntax Tree, and write another grammar to perform actions on that tree. I’ve flown through the book so far… 142 pages in roughly 4 hours worth of time. I expect to have it done by the week’s end, and hopefully be able to do something productive with it. I do have to applaud the author for this little nugget:

…I implore everyone to please stop using XML as a human interface!..

I couldn’t agree more. It seems like everywhere I turn around, yet another project or tool wants to shove an XML file in my damn face. I get XML, but I despise it as a human interface. It’s too constraining, too verbose, and requires far too much knowledge to actually get it right. And while it may be “easy” to parse (not easy because it’s simple, easy because tools already exist), it comes at a heavy cost for the user. Something quick and easy with only a few rules to follow, is a much better way to go.

Someone beat me to the punch…

So, I started sending emails out announcing my intention to start a group… and it turns out that a Python Users Group just started down in Greenbelt called BACON-PIG. Looks like some major Python players are involved in the group, and Greenbelt is not that far from where I’m at (maybe 30 minutes). So I’m going to give the group a whirl and see how things go! If you’re near the area, consider attending!

Starting a Python Users Group

So, I’ve always been jealous of ChiPy and BayPIGgies, and their endless stream of awesome Python talks. My first reaction was to move. :-) But that isn’t going to work out to well with my current work… so I opted for choice two: create a Python Users Group. I haven’t gotten us on the schedule at the library yet, but I’m prodding for interest from the community. So, if you’re in the Baltimore-Washington DC area, and are interested, drop me a line and let me know. I’d like to get a list of at least 10 names, and then schedule it in at Howard County Central Library. Check out their website for the exact location, but it’s in Columbia across the street from Columbia Mall. As soon as I get enough folks (and I should be close), I’ll reserve the room, and hopefully we can have our first meeting after the holidays!

Hope to hear from you!

The latest edition of Python Magazine

So a little ways back I subscribed to Python Magazine, because I wanted to support the language. I didn’t really expect to learn much after having spent 6 years working with the language nearly every day. I must say that the latest edition of the magazine is awesome! In one edition, you can learn how to parse binary strings using a grammar, how to use Metaclasses to create an ORM, the advantages and disadvantages of slots, and Bazaar workflows!

On another note, while I don’t feel quite ready to give a talk at PyCon, I’d really like to give one at PyWorks next year… which just happens to be sponsored by the same folks that make the magazine.

Keep up the good work guys!

Have an error-handling strategy…

Seems like more and more I’m finding applications that have little or no error handling strategy, which is a real shame. The job the application is performing is important to me: I want to use it to save myself the time and headache of doing something repetitive or mind-numbing. Unfortunately, while the application does its job well, it fails on less than perfect input. Now, I’ve been using computers since I could barely say “computer,” so I’m well-versed in telling my computer what it wants to know, in the format that it wants to know it. And I’ve become accustomed to looking at tracebacks and using other tools (strace, ltrace, gdb, etc.) to find what is breaking, and correct my input. However, that doesn’t work for your average user—even if your average user is a developer. The end result: the application ends up with a bad rap pretty quickly. This is especially true if you have a command line application, and you have a bunch of users who aren’t command line junkies.

Having an error handling strategy doesn’t have to be particularly complicated to make for a better user experience. In fact, it’s really pretty straight-forward. But you do need to think about having a strategy before you write your application. Why? Because you need to partition your errors into “this is a problem for the user to resolve” and “this is a problem for the developer to solve”. If you don’t have a strategy up front, then you won’t partition the two classes of problems, and you’ll have to go back and look at every single exception being generated to determine whether it’s a user-input problem, or a failure of the application. Best to figure this out up front.

First, create your own exception class. In my Python apps, I generally use:

class ScriptError(Exception):
    pass

Second, on anything that’s meant to tell the user that he made a mistake on one of his inputs (malformed paths, a full disk, invalid command line option, etc.), simply raise a ScriptError in response:

# ...
if not os.path.exists(path):
    raise ScriptError("Can't find path '%s'.  "
                       "Please re-run specifying the location of the config file." % (
                           path))
# ...

or something like,

# ...
try:
    foo(something)
except ArithmeticError, e:
    raise ScriptError(e)

Finally, catch that somewhere near the top-level, and output the error message:

if __name__ == '__main__':
    try:
        main()
    except ScriptError, e:
        import sys
        print >>sys.stderr, "ERROR: %s" % str(e)
        sys.exit(1)

That’s it. It’s that simple. And look what we have done:

  1. The user is now informed of the problem in a meaningful way.
  2. You didn’t print a 1000-line traceback that’s impossible to comprehend for errors that are theirs.
  3. The combination of which makes for a much better user experience.

You will still get tracebacks out of this strategy, and that’s not terrible. Tracebacks can aid in working with users to determine the root cause of why something broke. And the presence of one can indicate the presence of a bug, rather than the mixed message of either being a bug or a user input problem. Of course, if your application is generating many tracebacks, even with this strategy in place, you’ve got bigger problems. :-)

Is this strategy perfect? No, and it’s not meant to be. The right answer depends on the project, its user-base, and development time. However, it’s minimal, relatively painless, better than nothing, and gets you the 80% solution. So why not use it?

I’m off to work to fix some broken-ass error handling… wish the original developers had taken my approach to begin with.

Getting a little better…

Here are some of the better shots that I’ve taken over the last month or so. I’m proud of the picture of Andrew. He’s such a moving target. I managed to have the camera ready for the split second that he stopped.

Fun stuff!

Leaves coming out of a fence in our backyard.

Another silhouette of Matthew.

Quick shot of Andrew

The Photographer’s Eye

After reading Ted Leung’s book review of Michael Freeman’s The Photographer’s Eye, I decided to get a copy and read it myself.

A little history first. I’m a very budding photographer at this point. Thanks to David Hobby, I believe I understand how to manipulate the lighting, aperture, shutter speed, and ISO to get the exposure that I want, and the way I’d like it to look. But, I’m still struggling with composition, and some mechanics (trying to adjust settings while my subject is changing). Composition seems to be the biggest issue though… and imagine that’s the case for all new photogs. :-)

I’m not sure what my expectation was before reading the book, but it’s an excellent book. It’s not very long—at least not by my standards—only 187 pages. However, it’s very dense with information. The book touched all parts of photography: framing, color, composition on many different fronts, and process. Michael Freeman did a wonderful job of walking through many aspects of his pictures, sighting the thought process about the framing, the color choices, the choice of contrast, etc. The most valuable part was he also showed less than ideal pictures too. He put them there on the page for you to study and see the differences between good and “bad”—which is terribly useful for schmucks like myself who still don’t have a good sense of how to make a good picture.

For those of you living in Howard County taking some of the photography classes and is getting serious about the subject: save your money. The one on lighting was very, very introductory. In fact, the instructor called me “advanced.” You got to manipulate your camera, but the class was too short to really do much. Instead, head over to Strobist and read that. David Hobby does an awesome job of breaking it down for you. I recently took another on composition, and was rather disappointed by that one too. We spent a lot of time going over guidelines, and didn’t get a chance to try and compose a single shot. Moreover, the slides the instructor showed were all ideal. Not one shot was a comparison between how a different composure would change the dynamics of the picture. Instead, read The Photographer’s Eye. It’s not expensive, and does a much more in-depth job than the class. The down side: it takes time to read, and there is no instructor to ask questions. Despite that, it’s still better than the HoCo class. :-)

Threads are Evil!

Myself and others have been talking about the problem that is threads quite a bit lately, and how bad they are as a tool for concurrency. What I didn’t realize is that there is actually a paper on it! I ran across it while reading a FAQ on SQLite’s homepage.

There’s a great line in the paper:

To offer a third analogy, a folk definition of insanity is to do the same thing over and over again and to expect the results to be different. By this definition, we in fact require that programmers of multithreaded systems be insane. Were they sane, they could not understand their programs.

There have been a number of days where I felt like that was so true. In many situations, threading has felt like it added more problems than it solved. Unfortunately, when you have no other tools at your disposal, you have to make due with what you have.

Fortunately, the Actor model seems to be catching on, and folks are starting to take a more serious look at the concurrency issue. Personally, I think we need a new language to really cope with concurrency. But there have been some other tools popping up that might be useful in current languages. There is Kilim for Java and a corresponding Google TechTalk. And there’s Kamaelia for Python. I’m eager to see what’s in store for the future, but worry about maintaining the junk we have now. :-(

Article on Embedding Python…

I’ve been spending a lot of time lately on the Python Wiki trying to figure out if there is material, advice, basically anything that could help me start a Python Users Group. I happened to be running through an area trying to collect articles/useful information in a format suitable for conferences and user groups, when I ran across an article about embedding python. It’s actually a very good article, despite being 8 years out of date. And, to be honest it’s exactly how you would embed Python today, except you may want to use Py_InitializeEx() to keep Python from attaching signal handlers. I wish I knew of this article the first time I tried embedding Python. Might have saved me from reading a lot of source code.

Older | Newer