Wednesday, April 22, 2009

Timing is everything

Python Patterns - An Optimization Anecdote
The above link is to an article by Guido van Rossum on the Python website.   Needless to say, anything Guido says on the topic of Python is worth looking at (he is the author of the Python programming language). 

I thought of this particular article while reading a post, trying to decide how to check if an object is a sequence.  While all the contributors to the discussion are helpful, none actually checks the performance of the proposed solutions.  This is typical of the posts you see on various forums. 

Guido's article highlights how straightforward it is to do basic testing most of the time.  Here is a quick summary of performance of the proposed solutions in the above link:

import time

# Guido's timing function
def timing(f, n, a):
    print f.__name__,
    r = range(n)
    t1 = time.clock()
    for i in r:
        f(a); f(a); f(a); f(a); f(a); f(a); f(a); f(a); f(a); f(a)
    t2 = time.clock()
    print round(t2-t1, 3)

if __name__ == "__main__":
    #For Example
    # some functions to check if an object is a sequence
    def isit(obj):
        try:
            it = iter(obj)
            return True
        except TypeError:
            return False

    isit2 = lambda obj: isinstance(obj,basestring) or    \ getattr(obj,'__iter__',False)

    def isit3(obj):
        return (isinstance(obj,basestring) or getattr(obj,'__iter__',False))

    #...then:
    '''
    >>> timing(isit3, 100000, [])
    isit3 0.99
    >>> timing(isit2, 100000, [])
    0.99

    >>> timing(isit, 100000, [])
    isit 0.53
    '''





Tuesday, April 21, 2009

Choosing a Python GUI api

I narrowed the choice to Tkinter and wxPython fairly quickly--based on Tkinter being the de facto alternative and wxPython being the most discussed alternative on a basic Google search of "Python GUI".

Also wxPython has the largest widget collection, including a spreadsheet and since what I'm doing will involve a spreadsheet-like interface I decided that further investigation had quickly diminishing returns.

PyQt looks very powerful, and drives the incredibly impressive Orange application--but failed the "can I install and use it without much brain damage?" test, as did pyGTK  (also known as the "can an idiot install it?" test--me being the idiot--if something requires more than one or steps to install, it generally fails this test).   I would not be surprised to need revisit pyQt and pyGTK for larger scale projects.

The following, very helpful discussion walks through a very simple app in Tkinter and wxPython side-by-side.  Good for understanding the basic differences of the two packages and for understand the basics of GUI programming.

Building a basic GUI application in Python with Tkinter and wxWidgets

NB:  One fact that might help clear confusion as you surf GUI related posts-- wxWidgets == wxWindows.   The name of the underlying C++ library was changed to wxWidgets at some point (no doubt copyright/trademark related).

I'm also starting to look at wxGlade, a GUI builder wrapper for wxPython.

NB, re Editors:  I am using Eclipse with Pydev, with good results. 


Friday, April 17, 2009

Autumn ORM

I've been playing with Autumn, a Object Relational Mapper by Jared Kuolt.  First, I can recommend it, highly.  It took me less time to get it up and running and start doing useful things with it than to get through the first sections of the documentation for any of the other ORMs for Python out there.

Second, an interesting thought reading some of the comments on old posts when Jared first announced Autumn.   Several comments saw no reason to release a new package, feeling more or less strongly, that the open source way is to jump on to one of the existing projects.   This to me is very wrong-headed.

Part of the power of open source is from the willingness to throw out something because you don't have a tremendous revenue or sunk cost number associated with -- and to start over again using what you learned from the first effort.



Python: Static Methods versus Class Methods

The best discussion I've seen regarding the differences between static methods and class methods in Python is an old post at Miya's blog.    I like the way Miya approaches it.  Rather than going into the technical discussion found in the Python docs, he asks why would one use static methods, if it seems that class methods can do everything static methods can but not vice versa.

The key to understanding the difference between the two is in the comments.  A commentor points out
"classmethod give[s] you access to the class's attributes. static method does not so..."

Modifying the commentors example slightly:
>>> class MyClass(object):

        myattribute = 'spam'

        @classmethod
        def eggs(cls):
            return cls.myattribute

        @staticmethod
        def static_eggs():
            self.myattribute   # Will this work??
       
>>> MyClass.eggs()            
# O.K. for class method
'spam'
>>> MyClass.static_eggs()    
# ...not so much for static method
Traceback (most recent call last):
  File "<pyshell#33>", line 1, in <module>
    MyClass.static_eggs()
  File "<pyshell#31>", line 8, in static_eggs
    self.myattribute
NameError: global name 'self' is not defined

To recap:
  • Both static and class methods can be called from the class without an instance:
>>>MyClass.static_method_that_says_hi()
"HI"
>>>MyClass.class_method_that_says_hi()
"HI"
>>>x = MyClass()
>>>x.static_method_that_says_hi()
"HI"
  • Both can be inherited by sub-classes and maintain their identity (i.e., both are actually static).
  • Class methods give you access to a class attributes and static methods do not.

So, why use one instead of the other?  Why not just use class methods since they're more powerful?

For me the principle is to use the simplest structure that handle's problem.   Class methods can do more, and therefore using them should signal that you're class does fairly complicated stuff.  Having a bias to using static methods means that you've thought about parsimony in your design. 

I'll come up some examples of each and be back.