Wednesday, April 30, 2008

Linux: Resetting GNOME Settings

My mother-in-law uses Linux, but she's far from the most savvy computer user in the world. It's tough when you start using Linux in your seventies ;) Anyway, somehow she occasionally deletes her GNOME panel. That's a problem because it prevents her from starting any applications. After much practice, I've narrowed down the list of steps that are the easiest to dictate over the phone:
  1. Restart the computer.
  2. Don't log in. Rather, hit Cntl-Alt-F1 in order to get to a text-based login screen.
  3. Now log in.
  4. Type "rm -rf .gnome* .gconf*".
  5. Now, hit Cntl-Alt-Delete.
  6. Let it reboot and then log in normally. Things should be fixed.
Note that this will wipe all of your GNOME settings. However, since it's easy to type, and she doesn't have any settings anyway, it's perfect. The reason I do this delicate dance of rebooting is to prevent gconfd from doing things behind my back.

Monday, April 28, 2008

User Experience: mint.com

mint.com ("free personal finance software, money management, budget planner and tools, online financial planning") is both amazingly intelligent and has an incredible user interface. All I can say is "Wow!"

Tuesday, April 22, 2008

UNIX: "join"

My buddy Pat Tufts showed me that Unix has a command called "join" that lets you do relational database style joins with text files. Let me show you how it works.

Let's suppose I have a bunch of purchase orders in a TSV (i.e. tab separated values) file called orders.tsv. The fields are order_id, item_id:
1 3
1 2
1 1
2 1
2 2
3 3
Next, I have all my items in another TSV file called items.tsv with fields item_id, item_name:
1 Hammer
2 Screw driver
3 Wrench
I want to print out the orders with item names instead of item ids.

The first thing I need to do to use join is pick the join field. Clearly, I'm going to join on the item_id field. The next thing is to make sure both files are sorted by item_id. This is a strange requirement if you're used to RDBMSs, but it makes sense if you think of how it's implemented. Clearly, items.tsv is already sorted by the item_id. However, I'll need to sort orders.tsv by item_id:
sort -k2n orders.tsv > orders-sorted.tsv
Hence, I sort orders.tsv by its second field, treating the values as numbers. I end up with:
1 1
2 1
1 2
2 2
1 3
3 3
Remember, the fields are order_id and item_id. Now, I can join the two files.
join -1 2 -2 1 -t '  ' -o 1.1,2.2 orders-sorted.tsv items.tsv | sort -k1n
I join the first file (orders-sorted.tsv) on its second field (item_id) with the second file (items.tsv) on its first field (item_id). My field delimiter is tab (to type a literal tab into a shell command, use cntl-v and then tab). I output the fields 1.1 (order_id) and 2.2 (item_name). Because the output comes out sorted by item_id instead of order_id, I need to sort it again by the first field (order_id). I end up with:
1 Hammer
1 Screw driver
1 Wrench
2 Hammer
2 Screw driver
3 Wrench
Hence, to fulfill order 1, I need a hammer, a screw driver, and a wrench.

Clearly, this isn't as easy and convenient as using a relational database. However, it's neat to see that it exists. My buddy Pat warned me though that dealing with all the required sorting and implicit field numbers can drive you crazy. Furthermore, it's really easy to end up with garbage.

Still, it's fun to see what's possible using plain text files and a shell. I've always heard that the "old timers" were able to implement relational databases using sed, awk, and sh, but it seems so much more plausible now that I've seen join in action.

Monday, April 14, 2008

UNIX: "cut" Can't Cut It

What I wanted to use was:
cut 3,4,1
However, I discovered the hard way that cut can't be used to reorder fields. It treats the above the same as if I had typed:
cut 1,3,4
Well, awk to the rescue!
awk -F '\t' '{ printf "%s\t%s\t%s\n", $3, $4, $1 }'

Wednesday, April 09, 2008

Web: Google Technologies Specialist

It'd be interesting to be a Google technologies specialist. Think of what you could get done if you were a true expert of Google Gears, Google Web Toolkit, and Google App Engine.

You could design apps that: worked offline, had really rich interfaces, scaled really well, and were easy to deploy.

On the flip side, why does the phrase "Microsoft Certified Engineer" keep coming to mind? ;)

Monday, April 07, 2008

Math Girl Makes Music

Math girl makes music

I'm speechless. Anything more would get me in trouble with my wife ;)

Python: Google App Engine

I just found out about Google App Engine. Does anyone else feel as overwhelmed as I do? This changes everything for us Python Web guys.

Thursday, April 03, 2008

Python: Werkzeug

I just finished the Werkzeug tutorial, and it looks pretty good.
Werkzeug started as simple collection of various utilities for WSGI applications and has become one of the most advanced WSGI utility modules. It includes a powerful debugger, full featured request and response objects, HTTP utilities to handle entity tags, cache control headers, HTTP dates, cookie handling, file uploads, a powerful URL routing system and a bunch of community contributed addon modules.

Werkzeug is unicode aware and doesn't enforce a specific template engine, database adapter or anything else. It doesn't even enforce a specific way of handling requests and leaves all that up to the developer.

Werkzeug is most useful for end user applications which should work on as many server environments as possible (such as blogs, wikis, bulletin boards, etc.).
Having coded applications in Aquarium, Django, Pylons, Ruby on Rails, Zope, Plone, etc., I've been fascinated by the idea of an anti-framework. A framework establishes the flow of the application and calls your code at certain points. That's the opposite of a library. A library lets you call its code whenever and however you want. Werkzeug is a collection of libraries.

There's a bunch of glue that's required to tie all the libraries together in order to build a Web application. Werkzeug gives you some code as an example, but basically, you're on your own. Hence, it's not for everyone, but it's great if you're someone like me who hates when things get in his way.

Anyway, it looks simple and clean. The tutorial was very good. Here are some other random comments:

The tutorial used Jinja which is a templating system based on Django templates. Personally, I don't like Django templates. (That's not an insult. Templating engines are a matter of taste.) Fortunately, there's absolutely nothing in Werkzeug tying you to any templating system or ORM. It doesn't even make it any easier to stick to Jinja.

Werkzeug has view functions like Django instead of controller classes with methods like Pylons. I personally prefer the Pylons approach since I can do a lot of stuff before and after the method call. On the other hand, I guess that just means I'd have to make better use of decorators. It's interesting because the tutorial itself said "A callable class has huge advantages over a function" when it was talking about the WSGI entry point. Of course, you're free to not use the built in URL dispatcher, in which case you could do whatever you want ;)

Like Pylons, parameters parsed from the URL path are passed in as arguments to the functions. Unlike Turbo Gears, form parameters are not passed in as function arguments. I don't personally like that approach anyway.

I love the way it's just a bunch of libraries and you have to write all the glue code. They show you examples for all the glue code. I can definitely see where I'd be less likely to get irritated by frustrating restrictions.

It supports the Pylons goal of having multiple instances of the same application in the same Python interpreter.

Rather than putting all your URL mappings in one place, they also show you how to declare your mappings on a per-view basis using function decorators.

They made it easy to write management scripts that operate outside a Web context, yet understand how to work with the app.

In the tutorial, they hard coded the dburi in the top-level module manage.py. Especially in the past, I use to get frustrated while using Pylons because I would need the dburi and it would be locked away in a .ini file. In order to support multiple instances of the same application in the same process, you need a procedure to get access to the correct .ini file, and in strange situations like management scripts, etc., it was hard to get access to this stuff. In Werkzeug, you're on your own to figure out how you want to manage your configuration data. That's fine with me--I've always disliked .ini files anyway ;)

It looks like you return redirects as instances. In a lot of systems like Pylons and Aquarium, when you do a redirect, it actually raises an exception to halt processing.

It does look like it's easy to create a hierarchy of views in a hierarchy of Python modules. That's good.

Well, I haven't written an application with it, but it looks nice ;)