March 21, 2008

Batching Requests to Amazon Web Services via pyaws

Filed under: ResearchAndDevelopment — Ryan Wilcox @ 4:49 pm

PyAWS (originally py-Amazon by Mark Pilgrim), is a neat, simple, Python API for getting requests from Amazon Web Services.

But it doesn’t let you do any batching: allowed by the Amazon Web Services API to reduce requests.

THe other day I wrote py_aws batch: which uses PyAWS as a springboard for batch requests. Which I think is really neat, so I’m sharing it with the community at large.

So here it is: pyaws_batch.py (Now Updated with right link!)

December 28, 2007

Turn any shell script into a double-clickable app!

Filed under: ResearchAndDevelopment — Ryan Wilcox @ 1:37 am

So, while this might be very obvious to other people, I found out an interesting thing about bundles today. In short, if you configure your Info.plist correctly, and have the right permissions for everything, it doesn’t matter what you put as you executable.

For example, I have a shell script I want to send someone, but they aren’t computer savvy, so I want it to be a double-clickable app. How do I do this? There are a few tools that help you here: Pashua can give your script a GUI, and can also encase it as a stand-alone app. (’Cept I don’t really need the GUI part, thank you). DropScript works, but only triggers the shell script when you drop a file onto the app (but I don’t want that either, in my situation).

Looking at Pashua’s stand-alone app, I had a thought, and here’s my method for making app an out of anything.

  1. Start with an empty app bundle.
    You can either build one yourself, or use the one that comes with Pashua’s Sample Stand-Alone app.
  2. Put your shell script into your bundle’s Contents/MacOS/ folder. Make it executable. (For the user and group) with chmod ug+x in Terminal.
  3. Modify Info.plist’s CFBundleName to be the name of your, well, app bundle. Also (and most importantly) modify CFBundleExecutable to be the name of your shell script from step #2.
  4. Double-click you app: your script should have run!

Sadly, if something goes wrong, the system won’t tell you anything. Not a thing. (It’ll just do a half-bounce of the app in the Dock. Or say that the app bundle is damaged.) So you just have to troubleshoot it on your own. Good Luck there.

This shell script of course assumes that all your script needs is right installed on the user’s system. Which might be right in controlled situations. But for (say) Python (or PyObjC) applications, you really should be building with py2app, which bundles up everything the script needs into the app, giving you a stand-alone solution that doesn’t even require that the user have Python (or have the right version of it).

December 10, 2007

Python, Properties and Future Class Changes

Filed under: ResearchAndDevelopment — Ryan Wilcox @ 12:26 pm

For a while now I’ve been thinking about class attributes in dynamically typed languages. I usually view these languages as “less than 50,000 line program languages”. For more lines than that I personally want the type safety and compile checks of a statically typed compiled language (like C++). Granted, a 50,000 line Python program would probably have as much functionality as a half million line C++ program, and with a full suite of unit tests the Python program may be just as reliable and resilient to change (if not more so) than a static compiler checking your work ala C++.

Anyway, because of this “small project” view, and increased experience, most of the time I don’t want to create boilerplate code in my dynamic language class… and accessor methods seem like just that. Ruby has a way around that with its attr_reader/attr_writter, but I do most of my scripting in Python.

But let me add that in languages that lack the ability to retain the same client interface while completely changing the behavior: direct data access to a function call in this case, I’d still write boilerplate getters/setters. Like when I’m writing Applescript modules…. So you could say that Ruby/Python does encapsulation one better: you can change from accessing data to calling a function without knowing it.

The other day I ran across blog post at codefork.com that talks about Python’s take on encapsulation. Python’s approach is very pragmatic: modify the members directly then when you need to - and only when you need to - use Python’s property keyword to make Python call a instance method instead of looking for a data member of that name.

Version 1 of your class could be:

class Person:
def __init__(self):
self.age = None
jeff = Person()
jeff.age = 5 # maturity

Version 2 could be:

class Person(object):
def __init__(self):
self._age = None
def get_age(self):
return self._age
def set_age(self, value):
self._age = value
def del_age(self):
del self._age
age = property(get_age, set_age, del_age)
jeff = Person()
jeff.age = 5

And the codefork article stops there. But there’s more…

Say we plan to deprecate something (the age property), but we want to give our callers time to adjust before we pull the rug out from under them. We take another Python feature to do this: decorators.

To keep this simple we’ll use the most simple decorator: there is a better version of this in the Decorator Library (jump to it)

Version 3:

import warnings
def deprecated(fObj):
warnings.warn("%s is depricated as of version 3. It will be removed completly for version 4" % (fObj.__name__), DeprecationWarning, stacklevel=3 )
return fObj
class Person(object):
def __init__(self):
self._age = None
@deprecated
def get_age(self):
return self._age
@deprecated
def set_age(self, value):
self._age = value
@deprecated
def del_age(self):
del self._age
age = property(get_age, set_age, del_age)
jeff = Person()
jeff.age = 5

warning.warn generates a warning which either could be ignored by the program, sent to standard out, or raise an exception - depending on a value you pass to Python.

The decorator is called automatically by Python before the actual function is called. Think of it like manually calling deprecated(); jeff.get_age() - although its more technically deprecated(jeff.get_age).

Normally decorators make one wonder “so why not just call the one function then the other function and avoid the extra language feature?” In cases like these, where changing client code isn’t an option, or if the function gets called automatically - an age = 5 will call set_age() - decorators make it easy to change stuff around without anybody else knowing.

So we’ve gone through the whole life of an attribute: creation/ “let’s get it working for now”; refinement/ “ok: this needs to happen differently, but lets not tear up everything to do it”; to death/ “ok, we have to remove this, there are better ways now… we need to announce that its going away so people avoid it… then we can pull life support”. We have a way to avoid the broilerplate of tradition encapsulation and also retaining complete control over the class’ destiny - which is what encapsulation is about: preventing internal changes from affecting callers.

June 15, 2007

Trippy (Cocoa Notifications in a Mostly Carbon App)

Filed under: ResearchAndDevelopment, VonTrapp — Ryan Wilcox @ 11:58 am

So I’m using a little bit of Cocoa in a client’s application. The fun thing is that this application is mostly Carbon/wxWidgets. This isn’t too terribly odd: people use Cocoa in Carbon applications all the time (anymore). The wxWidgets part is different than normal, but whatever.

The trippy thing comes when I needed to adapt when the system Appearance color changed (so Aqua to Graphite, for example). You can get that via [NSColor currentControlTint], but the old Appearance Manager Apple Event (kAppearanceEventClass/kAEAppearanceChanged) must fire too soon, because looking at the currentControlTint color then just gives me the old color.

Cocoa has a notification for this NSControlTintDidChangeNotification, and using this in a Cocoa app, then retrieving the control tint, got me the new tint.

So I had an idea: Register for the (Cocoa) notification (via NSNotificationCenter) in my Carbon/wxWidgets app (in a wrapper function). Whatdayaknow… my notification got to me! (Which I then turned into a wxWidgets event and sent along its way).

So now my (Carbon/wxWidgets) + Cocoa app has three ways of getting events: Carbon Events, wxWidgets Events, and the occasional Cocoa Notification. It’s the first time I’ve used that last one, and I think it’s pretty trippy (and really really cool).

February 5, 2007

Why QA testing is still important with unit tests

Filed under: ResearchAndDevelopment — Ryan Wilcox @ 11:00 pm

Here’s a parable for you.

One day a programmer was writing a script (in Python, if it matters). It was a complicated script, so like any good programmer, he factored the program so his calculation stuff could be done without requiring a GUI. Then he wrote unit tests, as he should.

The day came when the unit tests passed, and there was much rejoicing. The actual script was executed to do its job…. but wait, no output.

Great thoughts were thought, and code looked at. The unit tests pass… but it doesn’t work. Why??

The answer soon came - in factoring out calculation stuff (to allow easy testing), the programmer forgot to pass the values from the calculations on to the GUI!! Soon enough, all was fixed and the program worked.

The moral of the story: no matter how many unit tests you have testing your calculations and stuff on the backend, you still need someone (or some thing) going through and making sure the GUI works. Be this with your unit testing framework testing the views, automated testing, or acceptance testing, you need to make sure your information gets to your users.

November 1, 2006

Python Tip of the Day: Unit Tests and loading module to test

Filed under: ResearchAndDevelopment — Ryan Wilcox @ 5:10 pm

Unit Tests are very useful. Lately I find myself writing tests for even small scripts - a few hundred lines. Even in a few hundred line script there’s always that one function which does the main work on the most basic block, and you want to make sure it properly handles whatever kind of input is passed in. Doctests are great for this: having a method documented and tested without having to write any test infrastructure is great. (See also: my blog article on easy doctesting).

unittest: when doctest isn’t enough

Sometimes, for more complex things, you do need more infrastructure than doctest gives you. unittest is right there to help in that case. With more power often comes more pain, and unittest has the issue that with “standard” directory structures it’s hard to load the module you actually want to test.

Typically unittest based tests are kept in their own files, separate from the actual working code. Probably a good thing, it keeps the script file from becoming too large, and keeping the focus of purpose. So we keep tests in a separate file than the script it tests, and import said script to test the functions in it. Or: the test script imports the actual script, and tests methods from the actual script to make sure they work.

“Everybody” seems to like this directory structure for tests and code:

toplevelfolder/
	a.py
	b.py
	Tests/
		test_a.py
		test_b.py

I like this structure too - it keeps the tests away from the source, and I don’t get test files cluttering up my source directory. As much as I could let the file system sort these things I kinda like it.

So now we have a problem: test_a.py tests a.py, meaning that test_a has to import a. Hmm. Pythonistas are already familiar with this issue, but needs some explanation for Everybody Else. Then we can get onto the solutions.

The Background: The Problem of Importing ‘a’

Python searches for modules along a list of directories accessible via sys.path. So my answer to this question has always been to write a dozen lines of broiler-plate code in the test_ python files to:

  1. Get the parent directory of the script
  2. Get that directory’s parent directory
  3. Append that to sys.path
  4. Import module to test

Of course, every time you copy and paste code you risk subtle changes in the mix: did I copy it from an older place, or a more recent place, did I introduce something stupid, what if I need to update my methods? All these questions suck, so the best idea is to avoid duplicating as much broiler-plate code as possible.

The Solution in Python 2.5

Python 2.5 brings two solutions to the table. One of these solutions looks really promising, but doesn’t actually work. The other solution, which certainly isn’t the first one that jumps to mind when you’re looking at this problem, is the one that actually does work.

One Possible Solution: Relative Imports

Python 2.5, recently released, had a feature I was very excited about: Relative Imports (PEP 328), except it just gives an error.

In our test script we have:
from .. import a

When we try it out:


$ cd topleveldirectory/Tests/
$ python test_a.py
Traceback (most recent call last):
File "test_a.py", line 15, in
from .. import a
ValueError: Attempted relative import in non-package

Hmm. Funny, and it seems like it should work. ‘Cept apparently it doesn’t work like that in Python 2.5 (We’ll explain why later). Nuts, that would have solved my problem. On to the next solution.

The Actual Solution: Executing Modules As Scripts

As excited as I was about PEP 328’s relative imports and how it would make package management easier, I was equally as apathetic about PEP 338: Executing Modules As Scripts.

Reviewing this PEP finds the explanation of the error in our first approach:

Import Statements and the Main Module

The release of 2.5b1 showed a surprising (although obvious in retrospect) interaction between this PEP [338] and PEP 328 - explicit relative imports don’t work from a main module. This is due to the fact that relative imports rely on __name__ to determine the current module’s position in the package hierarchy. In a main module, the value of __name__ is always ‘__main__’, so explicit relative imports will always fail (as they only work for a module inside a package).

Apparently this issue will be revisited for Python 2.6:

The question of whether or not relative imports should be supported when a main module is executed with -m is something that will be revisited for Python 2.6.

Python 2.6 isn’t here yet, so we have to live in an imperfect world. But this Python 2.5 imperfect world is better than the world I lived in before, with dozens of lines of broiler-plate code laying around everywhere.

Setting up to use PEP 338

  1. Your test structure should look like:

    toplevelfolder/
    	a.py
    	b.py
    	Tests/
    		__init__.py
    		test_a.py
    		test_b.py
    

  2. In your test_a.py file, just import a and write your tests.
  3. $ cd toplevelfolder/
    $ python -m Tests.test_a.py
    

Yes! This works. Great. In a way it would be great to have something that gathers up all the tests for you. It also does its work very efficiently and with a minimal amount of typing. We also find a decent use case for PEP 338.

Another Solution (for shell scripts or earlier pythons)

In the process of writing this entry I remembered Python’s -c switch, which allows you to throw together small bits of Python together right on the command line and execute it. Silly me. We can use this method to run tests too. More typing, but hey it works, especially for installs that haven’t updated their Python to something modern (the version of Python that ships with Mac OS X 10.4 isn’t exactly modern. Hopefully 10.5 will ship with Python 2.5.)

Setup for this technique is just the same as the PEP 338 solution: import a in your test, cd toplevelfolder, and run Python. The command you feed to Python is really the only different thing here.

$ python -c "import unittest; import Tests; unittest.defaultTestLoader.loadTestsFromName('Tests.test_a.py')"

This has a distinct advantage to all the other methods: we can easily write a shell script to iterate over files in a folder and repeatedly call this pattern, executing all the tests in a folder. You know that shirt “Go away or I shall replace you with a very small shell script“? Well, guess what.


#!/bin/sh
for dir in $@; do
for files in `ls $dir/test_*.py`; do
dname=`dirname $files`
fname=`basename $files`
python -c "import unittest; import Tests; unittest.defaultTestLoader.loadTestsFromName('$dname.$fname')"
done
done

Save this as dotests.sh (say in your toplevelfolder. Or somewhere on your path, whatever) and now:

$ cd toplevelfolder/
$ sh dotests.sh Tests

All the test_*.py files in the Tests folder will be ran, and the world will be happy.

Conclusion

Seems like we have solutions! No More Broilerplate! Simple imports in our tests. Automation possibilities (consider it a reader’s exercise to port that shell script to use the PEP 338 method).

Now, go forth and test!

January 27, 2006

HowTo: Get Out The Icon Files In A Subversion Repo

Filed under: ResearchAndDevelopment — Ryan Wilcox @ 11:08 pm

I got bit by it: I loaded a Icon\r file into my subversion repository accidentally and blew it up (just like Andrew Pontious).

However, Andrew doesn’t actually tell you how to fix the problem, beyond some vague mutterings about svndumpfilter. I’m going to show you how.

(more…)

January 24, 2006

Universal, 10.3 and up Applescript Studio application

Filed under: ResearchAndDevelopment, Reanimate — Ryan Wilcox @ 11:43 pm

Introduction

Today I worked on making Helix Maintenance Manager, a universal binary. HMM is an AppleScript Studio application which needs to target Mac OS X 10.3 as well as Mac OS X 10.4. Since the steps to create an application under these exact situations seem to be helter-skelter, I’m combining them here, for a simple one, two, three checklist.

Something to note is that this app has a few Objective-C/Cocoa routines along with the AppleScript. Some of these steps might be irrelevant for ASK applications that have only AppleScript in them. On the other hand, I’m betting a great number of ASK applications include a few Objective-C/Cocoa routines anyway. I also started with an XCode “native” target, so if you are upgrading from say ProjectBuilder, you’ll need to Upgrade your Target to Native.

Targeting versions of Mac OS X earlier than 10.3.9 with your PPC builds is an easy thing, but you’ll need to use a different compiler (gcc 3.3 or lower) for your PPC builds, while using GCC 4 for your Intel builds. 10.3.9 is compatible with GCC 4.0, so if you’re only targeting that version, you can get away with the same compiler for both architectures. This article won’t touch on how to do that, but the Cross Development article from Apple’s Developer Website does mention this setting.

(more…)

November 23, 2005

MochiKit, DOM and Navigation Bars

Filed under: ResearchAndDevelopment — Ryan Wilcox @ 11:58 pm

In web design it is customary to include a navigation bar somewhere on your pages. Links on this navigation part point to other points on the site. This site, for example, provides Home, About Us, Products, Bugs, Wiki, and Blog.

It is nice to somehow highlight what section the user is currently on. You’ll see there is no “Blog” link in the title bar, it is a static (unclickable) text instead. This is how I show location - your visiting the Blog section of my site, so it’s different from the other links provided in the navbar

My first Content Management System was the static site generation of Userland Frontier, which did navbar generation extordinarily well (or so I thought at the time.) When I started designing wilcoxd.com I thought back and realized I wanted some sort of automated system to take care of navbar generation.

The Wilcox Development Solutions site was created by hand, just my friend BBEdit and a good CSS book. BBEdit has this feature where it can run included scripts, so I wrote a Python script to generate my navbar, given an XML file input

While this 200 line Python script works, it’s kind of annoying. First, it requires some special Python modules. Secondly, you need(ed?) to specify the full path to the script (assuming it lived outside the site’s tools folder, which this script did). This second requirement meant that every person who touched my site would need to change all of the paths to match their machine configuration. A find and replace all operation, but still annoying

The other day I got wondering if I could duplicate my statically-rendered-via-Python navigation bar with some clever Javascript… Read on for The Rest of the Story…

(more…)

October 18, 2005

Python Tip of the Day: Easy Doctest-ing

Filed under: ResearchAndDevelopment — Ryan Wilcox @ 10:05 pm

In Python you can add a description to any class or function. This description is called a docstring in the Python community.


def addOneToNumber(num):
"""this function adds one to the number parameter passed in.
If not a number will throw InputError"""

if isinstance(num, int) == True:
return num + 1
else:
raise InputError, "Must be a number"

Docstrings document what the function does, just as this docustring does here. Often with a description you want to include an example for future programmers, showing them how to call the function, or what they might expect what happens.

It is a great idea to put examples in your docstrings, but how can you be certain that the examples are up to date? Programmers really hate reading outdated sample code, is there a way to prevent this?

Python provides the doctest module which presents a solution to this problem: docstring will run statements in the docstring, and error if the output is different from what it expected. These docstrings are created by importing your script into a running Python interpreter, running your function, and pasting the command and the results into your docstring.

There’s an easy way to doctest your routines, read on to discover how…

(more…)

Next Page »