PyObjC notes

I've been hacking around with PyObjC, the Python-ObjC/Cocoa bridge recently, and it's quickly becoming my favorite way to write Cocoa apps. It's really natural to mix Python idioms with Cocoa objects.

The latest version of PyObjC is 2.0, it's installed by default on OS X 10.5, and XCode now includes templates for starting a PyObjC project. There's even code autocomplete in XCode for PyObjC and IB integration, so aside from some smart-indenting issues, writing PyObjC in XCode is almost as natural as writing in ObjC.

I thought I'd post a few nice shortcuts and tips here.

You can use tuples for NSRect/Range/Point, for instance, this -

r = NSInsetRect(((0, 0) ,
                 (100, 100)),
                10, 10)

creates this NSRect -

NSRect origin=
       size=>

Passing python arrays as NSArray instances (and dictionaries as NSDictionaries) works great, but sometimes you need to pass a C array. The Python 'array' module handles that nicely:

import array
g = NSGradient.alloc().
   initWithColors_locations_colorSpace_(
    [NSColor.whiteColor(),
     NSColor.blackColor()],

    array.array('f', [0.0, 1.0]),
    NSColorSpace.deviceRGBColorSpace())

ObjC selectors are just python strings in PyObjC.

defNC.addObserver_selector_name_object_(self,
  'windowDidResize:',
  NSWindowDidResizeNotification,
  self)
# or
self.performSelectorOnMainThread_withObject_waitUntilDone_('doIt:', None, False)
# or
if o.respondsToSelector_("fun:"): return o.fun_(a)

Finally, something that comes in handy when working with KVC, the '_' method now defined on NSObjects in PyObjC:

o = 
print o._.myKey
o._.myKey = 44
# is equivalent to:
print o.valueForKey_('myKey')
o.setValue_forKey_(44, 'myKey')

That last example is straight from the NEWS page, where lots of other useful info can be found.

What is Site Reliability Engineering at Google

I've been looking around for some more detailed information about the "Site Reliability Engineering" positions at Google. Apparently the role is a real mix of very large-scale system administration, planning and automation.

I've collected some links to public info about the job.

The Google channel has a promotional video from one engineer about the role - he tells a quick story about being on call to monitor and address problems with Google talk.

A set of slides from a talk by James Youngman at the UK Unix & Open Systems User's Group gives a good description of the general task, and dives deeper into two specific examples - powering down failed disks, and protecting data with checksums, exploring how straightforward ideas can explode at scale. (These slides also have potentially the best proprietary-information disclaimer I've ever seen: "This has been written entirely in ASCII. No EBCDIC or animal fat.")

Here is another set of slides with a quick overview, from a 'lightning talk'.

A sampling of what Google SRE engineers put in their public resumes about their job includes quite a span - from troubleshooting mission critical services to writing automation software (in Python).

And finally, an interesting post from 2006 about the theory behind Google's hiring strategy, summarized as "only hire candidates who are above the mean of your current employees".

Twitter Stats in SVG using gnuplot

Damon Cortesi just shared a handy script for grabbing your tweets and compiling some stats about when you post to twitter and who you reply to.

His script generates a list of numbers and included a Numbers template to paste them into. Since I don't have Numbers, I've modified his script to write a file that can be read by gnuplot, and wrote a basic gnuplot script to output an SVG file version of the stats.

While I was at it, I changed it so it no longer counts "@someone" separately from "@someone:".

Both scripts are right here - gnuplot_twitterstats.tgz

It uses gnuplot 4.2, which you can get on OS X with macports using port install gnuplot +no_x11'. (Or it's a pretty easy build on its own, see the gnuplot download page )

Here are my stats: Sorry, it looks like your browser doesn't support SVG. You're really not missing much. Click here for a full-screen version.

TaskPaper adds just enough to stick

My favorite apps, the ones that slip easily into everyday use and stick there, just start with plain text and add some extra sauce. VoodooPad is a great example, and Hog Bay Software's new app TaskPaper is, too.

I've used both kgtd and iGTD, and played around with a few others. I came closest to sticking with a system using kgtd, but switched to iGTD because manually syncing kgtd got old.

All the extra stuff in iGTD was appealing, but I left tasks in the inbox for weeks, and never reviewed much of my vast forest of projects. I eventually fell back into tending short lists in Stickies, with titles like "NOW:" and "BY TUESDAY!:".

When I moved those Stickies lists into TaskPaper, all I had to do was copy and paste - it uses the same format I do when I get lazy, and that has to be a good sign. I haven't found a reason to jot a note somewhere else yet.

Moving tasks from iGTD was more sobering. Half those "next actions" had been done for weeks, and the other half were clearly scheduled for next Neversday. As Merlin Mann pointed out, switching apps is a good excuse for a real review.

TaskPaper adds automatic formatting, tabs, search, and a bit of hyperlinking to plain text. Tasks are lines that start with a dash, and can be tagged by starting any word with an at-sign. Clicking a tag starts a search for that tag. I use them in a couple of ways - as contexts, and for scheduling. They can really be anything that makes sense as a visible search keyword.

I have been keeping a few tabs open - one to edit tasks, and a couple others with live searches to look at what's on my plate. When I want to schedule something, I'll tag it as @now or @tomorrow - I have those two as open tabs, and as I work I keep the @now tab open. Other tabs come and go to look at contexts, like @email or @errand.

I like that the tags can be part of the sentence, so I don't have to tab through a bunch of controls to set tags - I just write something like '@email Bob @home'... easy.

I also set up an inbox project (by typing "Inbox:", naturally) to collect notes quickly, and that's worked pretty well so far.

As with any 1.0, there's some room for improvement. It's not very scriptable, but it is plain text, so it could be worked around. Quicksilver integration was important with both kGTD and iGTD, and I'm not sure yet if I'll really miss that here. It can clean up tasks marked as done into an "Archive" project, but doesn't yet note when they were finished, if that kind of thing matters to you. Finally, I'm not sure what the best way to sync with other devices would be, but there is a web interface in development - maybe that would be a good iPhone option.

TaskPaper is a solid, clear, and nicely minimalist app. Over the week I've been using it, it has made keeping to-dos in one place too easy to avoid, and added just enough functionality to sort through them without being distracting.

Note: When I downloaded the 1.0 release, I found a conflict with TextExtras and wrote a bug report. In reply, Jesse sent me a complimentary license. Nice guy. I was going to write about it anyway, but I thought I should mention that I got it for free, as a surprise.

The editing pass

Anything worth writing is worth re-writing. This applies to code as well as prose.

I give paper sections and important emails a while to sit after I write them, and they always benefit from another look with fresh eyes. I think that doing this with code is worth thinking about.

Once you get a piece of code to the point where you believe it works - it's passing its tests - go back over it and edit it. That is, go back and edit it for clarity, flow, and style. Just as if it were an essay.

This is particularly important for tests. If a test fails, it should tell a clear story that explains exactly what failed, and what it was expecting.

Things to consider editing out are vague variable or function names, and non-idiomatic shortcuts. Control flow can get tangled when working out a solution. Make it obvious. One-liners often don't tell the full story. When you come back to a piece of code, you know the chase. It's the first loose thread of a bug, a failed test, or an occurrence of a symbol you need to refactor. What you need is the story around it, and solid code will fill that in.

You can learn this by sharing your code or by waiting a while and reading it over again. It's easier said than done - I don't always do it, but I do know: an editing pass can do you good.

Something to think about: would a professional code editor help or hurt in the long run?

That Windows feeling

I started this post more than a year ago. Not much has changed, and it's time to just let it out.

Uninvited dialogs popping to the front or stealing keyboard focus in OS X have been giving me that Windows feeling lately. It was part of the old Mac OS's comfortable "I'm in control" feeling, and was always immediately noticeable using Windows - popups and splash screens everywhere.

It's particularly bad with multiple monitors, when you may not notice that a dialog opened on the other monitor and is stealing all your keypresses, making the app you thought you were using seem unresponsive and rudely interrupting your work.

Here are just a few that I notice all the time:

  • Apple Backup: Every damn time it runs a backup I get an annoying alert, sometimes two if the media isn't ready when it wants to run. This is the one single situation that I can remember Retrospect's UI being better.

  • Apple Mail: If a message is sent but the SMTP server can't be contacted, the message pops back up with a sheet to pick a new server to be used until you change locations - a feature I endure daily to cope with my home ISP insisting I use their SMTP server. This window pops to the front and steals key focus, so if you're typing in another mail message, you lose letters.

  • Safari with GMail: sometimes GMail just pops to the front of the stack. I don't ever want a web page deciding that it needs to be in the front - what is going wrong here? (note, now that I use my WebMail app, this doesn't happen to me anymore…)

  • Safari also pops the download window up when it starts a download - good idea right? Not if it took a while to start the download and I'm now editing something in a totally unrelated browser window...

  • Growl: Growl could be a solution to some of these problems, but it adds its own annoyance. Just waving your pointer over a notification - or even having it sitting in the spot the notification appears at - steals key focus from the current app. I use a variety of sticky notifications that I have to click on, and so this happens to me all the time.

  • FileMerge: if it takes a while to open a merge and I've moved away, it still pops the window to the front and takes key.

  • iTunes: changes to the music store status (like it finally loading a page), cause background windows to pop up in front of other iTunes windows. This doesn't happen in browsers, why here?

  • iTunes: A more debatable example is if your iPod battery is completely drained, it will charge for a while before bringing iTunes to the front at a random time when it's ready to sync. This is only if you've already requested iTunes to be shown when you plug in your iPod, so maybe it's not their fault it annoys me.

  • Keychain security - because I have sensitive passwords on my laptop, my keychains lock when it sleeps, and time out. So I see a lot of the keychain password dialog, which steals key focus - even when it's invoked from an app in the background. Backup makes this happen regularly. The dialog is small enough that I often don't notice it on the other monitor.

If this annoys you too, share your examples in the comments.

Skim 0.7

The amazing Christiaan Hofman has released another nice update to Skim, the great PDF reader that is quite literally my dream reader app.

As usual, there are detailed and complete release notes, and I'd like to call attention to my favorite new feature, because I use it all the time, and actually wrote part of it:

Skim can now download PDFs from remote URLs, which can be provided on the clipboard, dropped on the Skim icon, or through Services.

I use this all the time to drag a PDF URL from a browser to the Skim dock icon - Skim downloads the file and displays it in one step. Very handy.

Processing Email

I watched Merlin Mann's Google Tech Talk about processing email yesterday, and even though I'd followed his posts on Inbox Zero when they came out, it's good to get a reminder, and Merlin's an entertaining speaker - I recommend you watch it.

He talks about strategies for keeping an empty inbox based on processing email as it comes in, and deciding what to do with each message as you read it so nothing just sits there reminding you of vague, unspecified amounts of work you need to deal with sometime.

You may have to accept on faith that an empty inbox is a worthwhile goal. Some people disagree, but I think it's safe to say that for most people, moving the things you get as email into more appropriate places like notes apps, calendars or to-do lists is a great way to get in control of your work. Process it, then get to work. I've been doing this for a while, and it's a good feeling to know you don't have any surprises laying forgotten in old mail.

One point from Merlin's talk that I'd like to comment on is that email is just a medium, and it's worth thinking about whether it's really the best medium for what you're trying to do. This has been in my mind lately as I've been working on a project with a series of parallel email-based heavily technical conversations, sometimes with three or four people replying every couple of minutes. I struggle with the feeling that email is just not the best way to do this, but it seems like the only way to include everyone.

Merlin made the point that sometimes email dysfunction is just a symptom of an organizational communications problem, and no amount of email system adjustment can solve it. I agree - if you're really just tracking bugs, use a bug tracker. If you're coordinating things in real time, use IMs or IRC. If you're collaborating on a document, use something like Google Docs. Please stop overloading email.

NSLocalizedString can set errno

This is a short one, but it might help someone with debugging someday.

A while back, we had some code that was checking errno, then using the NSLocalizedString macro to get a localized error message, but it checked errno again later. Only the app isn't localized yet. There's no Localizable.strings file, so when NSBundle -localizedStringForKey gets called, even though it fails gracefully, it still ends up setting errno to "ENOENT", or "file not found".

So the lesson is - in case you're seeing weird behavior where errno is changing after you check it, make sure you're not using any system calls that might set it.

Free advice about a pro email client

If you're thinking of writing a commercially successful pro email client for Mac OS X, here's some advice along the lines of what I wrote yesterday:

Make sure you've tried a lot of email clients. Try everything you can get your hands on. Really use each one - figure out what makes it different, and what makes it powerful. Make sure you've tried text-only clients like mutt and pine. Lots of your target audience refuses to give those up - figure out why. Don't just try free alternatives - peek in on big-business. Fire up Parallels and try Outlook and Notes in Windows (there may be others that are even better examples). Read up on the Chandler project.

Make sure the email is always available in an open data format. If this isn't obvious, you should probably stay home. Keep a backup copy of email in something Apple Mail can read - like Unix mbox files. You can use a database for tags and whatever, but there had better be mbox files around, because your target audience won't move into an app they can't move out of.

Don't start out by cloning Apple Mail. If your first screenshot looks almost like Mail but does less or isn't as pretty, it's bad news. Mail is a big program with lots of time and effort behind it. If you try to match its feature list first before you make your client unique, you're toast.

Pick a specific customer, and get to know their email problem. Why not clone Apple Mail? Because you're not writing for the same customer, are you? Make sure you know who your customer is, and what they actually need. People who want a pro app probably already have a system for to-do lists & notes, so your client doesn't need to match those features. Likewise, email pros can still use Mail to send slideshows to Mom…

As an example, since you're probably a programmer, think about how a programmer's email client would be different from the standard. Maybe it does syntax highlighting. Maybe you can apply patches people send you with one click. Maybe you can create bugzilla issues from an email with one click. Or collaborate on a support email with the SubEthaEngine. Nobody but programmers will want to use that client, but that's fine - there are lots of programmers. Now what about music and video editors? Graphic designers? See where I'm going?