Honey bees.

2008-05-21

There’s been a lot of talk about the demise of the honey bee, but we’re fortunate to have a swarming yard.

I wanted to give an old lens (Tamron 28-200 f/3.8-5.6) a try on the D40 and I was mostly happy with the results. It’s not an AF-S and as such doesn’t auto-focus so it took some getting used to manually focusing — bees are not forgiving.

I’m trying to decide between Lightroom and Aperture so this photo received more post-processing time than any other I’ve taken. As you can see I still have a lot of learning to do. I want to like Aperture, but I don’t — I do, however, like Lightroom 2 β. I’ll post when I decide.

Categories : photography

Bald Eagle weekend.

2008-05-19
Geotag Icon View on map.

We had the good fortune this weekend to see a number of birds of prey, including quite a few Bald Eagle sightings. There is something inspiring about seeing a Bald Eagle launch from its perch and soar over-head.

Categories : photography
Tags :

Seattle Conference on Scalability.

2008-05-16

I went to the conference last year and have been anxiously awaiting the speakers and session list for this year. It’s out and my RSVP has been confirmed.

It’s a fantastic one-day conference with very little of the fluff or this-is-how-you-do-’Hello World’ seen at some of the larger conferences. It’s worth attending if you can make it.

Categories : development

pysmug on Python2.6a3.

2008-05-16

I decided tonight was the night to try Python2.6a3 on my macbook pro with a goal of getting pysmug to run on it.

After downloading and doing the typical configure && make dance I saw this:

Failed to find the necessary bits to build these modules:
bsddb185          gdbm              linuxaudiodev
ossaudiodev       readline          spwd
sunaudiodev

Apparently setup.py won’t build the readline module with the stock readline library on my mac. I already installed libreadline from MacPorts so I applied the following patch:

diff -r c68686a4d0b2 setup.py
--- a/setup.py  Thu May 15 21:06:32 2008 -0700
+++ b/setup.py  Thu May 15 21:49:39 2008 -0700
@@ -298,6 +298,8 @@
         # Ensure that /usr/local is always used
         add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
         add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
+        add_dir_to_list(self.compiler.library_dirs, '/opt/local/lib')
+        add_dir_to_list(self.compiler.include_dirs, '/opt/local/include')
 
         # Add paths specified in the environment variables LDFLAGS and
         # CPPFLAGS for header and library files.

This worked. After installing the rest of the required pysmug dependencies (simplejson, nose, setuptools, pycurl) I was able to build pysmug. Running the tests resulted in the following error:

  File ".../nose-0.10.2-py2.6.egg/nose/suite.py", line 377, in makeSuite
self.context.setdefault(suite, []).append(context)
TypeError: unhashable type: 'ContextSuite'

It turns out this issue already has a patch. After applying it and re-[compiling,installing] I tried again. Success!

performance

Out of curiosity I tried two runs each of 2.5 and 2.6, interlaced.

$ python2.6 setup.py nosetests
Ran 9 tests in 10.654s
$ python2.5 setup.py nosetests
Ran 9 tests in 12.128s
$ python2.6 setup.py nosetests
Ran 9 tests in 11.413s
$ python2.5 setup.py nosetests
Ran 9 tests in 12.207s

In this extremely unscientific test it appears 2.6 has the edge. I wouldn’t read very much into this.

Categories : development
Tags :     

Python decorators.

2008-05-14

I finally found a non-trivial reason to implement a Python decorator. I make extensive use of Python keyword arguments in the pysmug API and map those spellings to SmugMug keyword arguments. The algorithm for converting a Python spelling to a SmugMug spelling is pretty straight forward and easily wrapped up in a function. Originally, the first line of every function required formatting the keywords into SmugMug-style spellings by calling self._prepare_keywords(**kwargs). It occurred to me this is a perfect use case for decorators so I converted the code from a class method to a function, moved the call up a line, prefixed a @ and voilà, a far more explicit communication about how this method handles keyword arguments — love it.

In version 0.4 of pysmug I refactored my code from this:

def _login(self, handler, **kwargs):
  kwargs = self._prepare_keywords(**kwargs)
  method = kwargs.get("method", None)
  ...

to this:

@smugmug_keywords
def _login(self, handler, **kwargs):
  method = kwargs.get("method", None)
  ...

by using this function (the function mg was originally the _prepare_keywords function):

def smugmug_keywords(fn):
  """Prepare the keywords for sending to SmugMug.
 
  The following operations are performed::
    1. If the key is "method", continue.
    2. If the key starts with an upper case letter, continue.
    3. If the key is in {methods.apikeys}, replace the key.
    4. If the key ends with {id}, upper case the first letter
       and {ID} and replace the key.
    5. Else, upper case the first letter only and replace the
       key.
 
  @param fn: the decorated function
  """
  def mg(*args, **kwargs):
    items = kwargs.items()
    for k, v, in items:
      if k == "method":
        continue
      if k[0].isupper():
        continue
      lk = k.lower()
      if lk in apikeys:
        key, func = apikeys[lk]
        del kwargs[k]
        kwargs[key] = func(v) if func else v
      else:
        del kwargs[k]
        if lk.endswith("id"):
          kwargs[lk[:-2].title() + "ID"] = v
        else:
          kwargs[lk.title()] = v
    return fn(*args, **kwargs)
  return mg

This function is an argument for Erlang-style pattern matching.

Categories : development
Tags :