April 22, 2008

Ryan (and wxWidgets) on The Web

Filed under: General Information — Ryan Wilcox @ 12:37 pm

So I need to update my website a bit. After a bit o reorganization and backend rework. But, in the spirit of Useful Information Now, I’m going to make it easy for people to see my reputation online. For right now it’s just wxWidgets links, because I’m out of time (and I do have a decent sized presence in the wx community), but I’ll add more links to categories eventually.

wxWidgets Community:

April 14, 2008

Textmate and high level ASCII characters

Filed under: Uncategorized — Ryan Wilcox @ 7:32 pm

Here’s a fun gotcha when creating commands for TextMate: if your command’s output is set to Create New Document on output, then that output must be either free of high level (extended) ASCII characters, or UTF-8.

If your output doesn’t conform to this rule, the new document populated by TextMate will be blank. Nada, nothing, just blank.

Try this test:

  1. Create a file in TextMate with an extended character in it (umlauts are good, or say option-y). And something afterwards, to prove my point that nothing else comes through.
  2. Save, and set the file encoding to UTF8
  3. Create a new command: set its Input to None, Output to Create New Document, and Command(s) to cat path/to/your/saved/file
  4. Run command
  5. Notice your output: just like you expected
  6. Now Save your document as another encoding. Say MacRoman. (Make sure to replace your old file: we want the command to open this file now!)
  7. Run the command
  8. Notice there’s no output

This might not seem like a big deal, but remember that any Unix command you run could return high ASCII text. Grepping through a source tree of MacRoman files, let’s say.

In cases where those extended characters can be discarded, there’s a great tool from University of California at San Diego: a Perl script called fix. Fix replaces extended ASCII characters (and other craziness) to spaces. (I like to put scripts like this in a bin folder in my home directory.)

So, if extended ASCII characters don’t matter to you, use fix like this:
cat path/to/your/saved/file | perl ~/bin/fix.pl -

If you really do care about those characters, and you can assume the source encoding, you can use iconv.
cat path/to/your/saved/file | iconv -f 'macroman' -t 'utf-8'

After all that, it should be noted that the Output: Show as HTML setting can accept extended ASCII characters. But if your output isn’t HTML…

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!)

February 24, 2008

appscript’s get syntax (advanced concepts)

Filed under: Uncategorized — Ryan Wilcox @ 12:22 am

So if you read my previous article on appscript’s get syntax, you might now be wondering how to do more advanced things with getters. For example, in the Finder with Applescript you can say:

tell app "Finder" to get selection

if you want the alias (and not a reference to the finder item you’re dealing with):

tell app "Finder" to get selection as alias

So how do you do this in appscript? Read on…

(more…)

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.

November 20, 2007

PyObjC (2.0) + FSEvents

Filed under: Uncategorized — Ryan Wilcox @ 11:59 am

For the adventurous: there’s a sample on how to integrate PyObjC with FSEvents at /Developer/Examples/Python/PyObjC/FSEvents/watcher.py

Neato.

October 31, 2007

appscript’s get syntax

Filed under: General Information — Ryan Wilcox @ 11:26 am

I use appscript - a Python module letting me talk to scriptable applications on the Mac - everywhere I can. It means I can write less in the verbose, cranky, sometimes read-only AppleScript.

Appscript is nice, but in earlier versions seemed very… verbose. Where AppleScript did all kinds of magic behind the scenes, appscript made you do a lot of that stuff yourself.

Today I was working on getting an object’s reference’s value from appscript. In Applescript this is easy:


tell app "Microsoft Word" to get selection's selection start

(Maybe Word isn’t the best example of this, but it’s what I’m working in now…)

In appscript I’ve always struggled with how to get and set values in appscript. Not today, since I’ve discovered there are three ways of doing it (shown here from the Python Interpreter, one of the great tools for appscript: piece together things line by line interactively!)


>>> msw = app("Microsoft Word")
>>> msw.selection.selection_start.get()
48
>>> msw.selection.selection_start()
48
>>> msw.get( msw.selection.selection_start )
48

The first get() call is the one I’ve been using since early in appscript’s development. Entire reference (the subject), than the verb. It’s very OOP smelling, OBJECT then VERB. You see this everywhere, including Python.

The second get() call is one I didn’t know about until I read the appscript manual just today: once you have a reference, call it like a function and you’ll get its value. That’s a great shortcut, and feels somewhat OOP too.

The third get() call is one I just discovered, and probably the most familiar to AppleScript programmers. Much of Applescript works on VERB then OBJECT, because it could be considered not a class based object oriented programming language. So here we are: GET the selection object’s selection start).

It’ll be a toss-up for me whither I’ll use the second or the third form of the “get idiom”, but I’ve always found the first to be too literal, personally. I’m glad there are other forms.

Oh, and PS: appscript has had addressing by creator code, bundle identifier, path, as well as name and eppc URL since very early in its development. Thanks for catching up, Applescript. <nudge />

October 17, 2007

Betas and Testing

Filed under: General Information — Ryan Wilcox @ 1:45 pm

Steven Frank: Betas and Testing

Lots of truth in the article, from both ends (running a beta cycle, being in QA, and also giving some advice to people in a beta testing program. My advice for the latter group would be: test, let people know that you’re testing, even if you haven’t found any problems in the areas you’ve explored. Basically, let the people running the beta cycle that you’ve gone fishing in this part of the application and haven’t caught anything.)

But I have to point this out:

I’ve researched automated testing with products like Eggplant, with mixed results. I’m a big advocate of unit testing, but in practice, it always seems to get back-burnered, and is not easy enough to do with predominantly GUI-driven applications.

You can have all the unit tests in the world, but if the logic connecting your view component to everything else doesn’t work, the program doesn’t work. I know this point all too well. So testing (internal QA and beta testing) are very useful.

The beta testing being a check on internal QA: making sure the internal QA does its job well, and also going above internal QA, trying oddball stuff that internal QA wouldn’t think of. When you work with a product day in and day out it’s easy to test and use the app only the way that makes sense to you - or to the development group - but people may use the app differently in the real world. People will zig when you are expecting them to zag. Which is also why you need beta testers, even if you have automated tests.

August 21, 2007

Google CTemplate Integration (Check!)

Filed under: Distribute — Ryan Wilcox @ 5:39 pm

Today I tried out Google CTemplate, as I said I would. In addition to what I liked about the template language, it has tools to check your templates and generate C constants for the template elements (aka: the things to replace in the template). Meaning (if you use those constants) you can change the name of things in your template and your C++ code will complain, catching the errors at compile time instead of runtime.

I’ve integrated these tools into the build script so we have this safety from the get go.

I also have very comprehensive instructions for building the project, between gathering up all the tools to build on my functional machine, and fighting through all the build/linker errors I’ve been faced with.

So today my research app builds again. It’s a good day (and about time).

Next Page »