Posts

Showing posts from July, 2012

Keeping tallies in Python

Python's collections module has some of the most consistently useful collection data structures you will need for everyday programming. Here's one I didn't know about: collections.Counter  (Python 2.7 only!) It is designed to keep "tallies" or count instances of something. The example will make it all clear: from collections import Counter cars = Counter() # I see one go past, it is red cars['red'] += 1 # And a green one cars['blue'] += 1 # etc This is pretty much like a defaultdict with an integer value, but it is convenient and neat, with some useful constructors. Don't you think?

Watching a file system directory with inotify and Linux

"Inotify is a Linux kernel subsystem that acts to extend filesystems to notice changes to the filesystem, and report those changes to applications." [Citation Needed] . You can use this service from Python using Twisted to watch a directory and its contents. Twisted is perfect for this as you likely want to be doing a number of other things at the same time, for example, making an HTTP request every time a change is noticed. The code is so monstrously simple, I will just paste it: from twisted.internet import inotify from twisted.python import filepath class FileSystemWatcher(object): def __init__(self, path_to_watch): self.path = path_to_watch def Start(self): notifier = inotify.INotify() notifier.startReading() notifier.watch(filepath.FilePath(self.path), callbacks=[self.OnChange]) def OnChange(self, watch, path, mask): print path, 'changed' # or do something else! if __name__ == '__main__': from tw...

Making two instances behave as the same instance in Python

The use-case is this: # Two instances of the same class x = A() y = A() x in {y: 1} # True So we want to be able to check an instance's presence inside a dict, set, or anything that hashes an instance for a key. You need two things: __hash__ method which returns an integer __eq__ method which tests equality against another instance and returns a boolean __hash__ method returns an integer which is used as the hash. I didn't want to invent a hash method, so instead I used the hash of a tuple, which seems a reasonable hashable type to use, but you could use an integer or string or anything. I wanted the tuple contents to be attributes of the instance, with the added side effect that the instance would pass the test: x is (1, 2) # True Here it is: def __hash__(self): return hash((self.name, self.age, self.location)) That is not enough though, if you implement __hash__ you must also implement __eq__, which is simple enough: def __eq__(self, other): return h...

Calling the Google Drive API and other Google APIs asynchronously with Twisted

You may know that the Google API Python Client is built on httplib2 . This is a reasonable general choice, but the tight coupling is unhelpful in situations where a different HTTP library, or an entirely different approach to network programming should be used. An example of this is Twisted . Aside: I won't be going on about how awesome Twisted is, but let's just take it for granted that it is so awesome that I could not write this application without it. Httplib2 is blocking, and that makes it incompatible with being run inside the Twisted reactor. Fortunately we are only the latest person to have this problem, and a solution exists: twisted.internet.threads.deferToThread api_call = drive.files().list() def on_list(resp):   for item in resp['items']:     print item['title'] d = deferToThread(api_call.execute) d.addCallback(on_list) A blocking call will be called in a thread and will callback on the returned deferred when it is done. I apprec...