Farm Development

Thoughts on Python

back to all thoughts

It's Time to USE The Web : Mozilla Labs Releases Ubiquity

posted in JavaScript, Python, The Future by kumar on Wednesday Aug 27th, 2008 at 10:26a.m.

Mozilla Labs releases the Ubiquity add-on for Firefox. In a nutshell: With search, users type what they want to find. With Ubiquity, they type what they want to do.

Big congrats to Aza and everyone else who worked on this! As innovative as Humanized was, building something similar into Firefox is genius. Personally I am excited by the prospect of developing work flows on the Ubiquity platform. There are so many common work flows that need simplification.

Developers: If you want to cut to the chase, Ajaxian shows how easy it is to create custom commands. And of course, the details are in the Authoring Tutorial.

aintjustsoul.net: A portable record player for the Internet

posted in JavaScript, Music, Projects, Python by kumar on Monday Aug 18th, 2008 at 11:00a.m.

I'm very pleased to announce a website I just launched:

http://aintjustsoul.net/

I'm calling it "a portable record player for the Internet" because I'm a record collector myself and listening to as much music as possible has been the best way to expand my collection. Yep, I'm one of those guys who goes to record conventions and brings a portable record player.

There are a few places to find used vinyl online — since 161,783 records are for sale on eBay right now, I'd say the Internet is a good venue. The problem is that you can't always listen to a record before you buy it and it's impossible to find great music by name alone when there is so much to choose from. I'm hoping to change all that with this site.

As you can see, it's still in very experimental stages and leaves a lot to be desired. eBay is the only marketplace supported so far but I plan to integrate Music Stack next. If anyone knows of another marketplace, please let me know. Also, if you have a friend who buys records then please send on the link (I'm interested to hear feedback from record buyers).

It took me about 6 months to get the data in order (doing all this in my spare time) so it is very exciting to be able to release an actual site now. The data pipeline is home-grown ETL and uses the eBay API + the super speedy and tolerant lxml.html (contrib by Ian Bicking), the excellent SQLAlchemy, and other tools. As I take the data pipeline to the next level I really hope to start using the very cool SnapLogic ETL framework for Python.

On the UI side this has been my first chance to really dive into Dojo. I like Dojo because it takes semantic HTML seriously, namespacing seriously, unit testing seriously, and object oriented JS seriously. It's a bit monolithic and I still haven't figured out how to build a custom minified version but so far I like it. Also, I really wish the Dojo API reference was more comprehensive. On the backend UI side, I'm using Pylons since I like how well it integrates with 3rd party Python libs. I don't like some of the magic it inherited from Rails but that is pretty easy to work around. Oh, I almost forgot to mention SoundManager 2, the ultimate javascript/flash mp3 player.

Chicago's Google App Engine Hack-A-Thon Recap

posted in Chicago, Google App Engine, Projects, Python by kumar on Thursday Jul 31st, 2008 at 10:45p.m.

Today was Chicago's Google App Engine Hack-A-Thon and I managed to get some good work done. Well, I had planned to make packages more ephemeral on the PyPi mirror since it quickly hit the 500MB limit as is. But instead I decided to add Datastore support to the fixture module so that loading sample data is easier when testing an App Engine site. It was very easy to do so I spent most of the time writing some documentation with a complete example for how to go about testing an App Engine site with fixture, WebTest, nose, and NoseGAE.

Here it is: Using Fixture To Test A Google App Engine Site.

Big Thanks to Marzia Niccolai and Mano Marks for trekking out to the Windy City and to all the folks at the Chicago Google office who helped make it happen. As for the hackers, I think we were a shy bunch; there wasn't much show and tell afterwards. I know Ian Bicking got damn close to making a Datastore version of enough builtin file I/O methods for Moin Moin to run on the App Engine. Maybe you'll hear about that soon. Someone did demo a cool iPhone app (literally passed his phone around). It analyzes geo location to provide users with a local message board. I didn't catch the name or a URL — can you drop a comment if you have the info?. UPDATE: The name is Puppyo. Oh yeah, and Harper Reed was hacking on http://excla.im/, an App Engine site that is complimented by a jabber bot allowing you to simply send an IM to post to twitter.

Fixture Goes 1.0 (Testing With Data In Python)

posted in Projects, Python, Testing by kumar on Friday Jul 18th, 2008 at 10:51a.m.

I've just pushed 1.0 — the I Heart Data release — of fixture, a Python module for loading and referencing test data. It is used heavily at my work in two test suites: one for the functional tests of an ETL framework and another for a Pylons + Elixir (SQLAlchemy) + Ext JS web application.

easy_install -U fixture

or download from PyPi

Highlights of This Release

Many thanks to those who submitted issues and patches, especially Manuel AristarĂ¡n, sokann, Brian Lee Hawthorne, and Jeffrey Cousens.

What's next? The fixture command that generates DataSet classes from a real database needs some attention. It doesn't work with SQLAlchemy 0.5 yet and could work better with SQLAlchemy based data models in general. Aside from that, fixture seems to have stabilized for my apps at work so I'll be waiting to hear from the community about what other areas to improve on.

An In-Process, Headless Web Browser for Python?

posted in JavaScript, Python by kumar on Thursday Jun 12th, 2008 at 11:46a.m.

Yesterday, Atul Varma announced he had resurrected python-spidermonkey, John J. Lee's project to run JavaScript in Python. Woo! Spider Monkey is the JavaScript runtime that Mozilla (i.e. Firefox) uses internally. However, it's just an engine and doesn't deal with the DOM or anything about the typical web browser environment JavaScript files usually run in. Roughly, that environment defines the following JavaScript objects:

I've always been interested in python-spidermonkey for the prospect of fully testing JavaScript-dependent web applications in Python alone. This is no small feat and there are many caveats. The first caveat is that if the Application Under Test is running in something too far off from its native runtime then the value of your tests rapidly decreases. In other words, the best way to test a JavaScript-heavy web app is to use Selenium or Windmill to automate and introspect the app in its native runtime: the web browser. I believe Java has Rhino but since it's implemented in Java my guess is its behavior is pretty far off from that of Firefox. We all know and love the quirks of web browsers; this is what makes web development so fun :(

A lightweight version of Firefox — its JavaScript engine, its DOM, etc — could possibly make web testing a lot more efficient. By lightweight I mean no GUI, no visual rendering (although removing this may greatly hinder JavaScript, not sure). Why? At the company I'm at we build and test web applications. Our largest suite of Selenium tests that automate a real web browser takes about 2 hours to run and that's expensive. We are looking into a Selenium Grid solution but if there's a way to simply cut out all the browser overhead that we don't need, this would be a huge score.

And, oh yeah, I haven't even talked about how tests for web apps need to run in Internet Explorer if they are to be worth anything. However, we make some apps for internal company use and thus can mandate the use of Firefox. To solve the cross-browser problem one approach could be to implement all this logic as a driver that can be hooked into the Selenium interface we use, which is all in Python code thanks to Selenium Remote Control. This the exact approach that Webdriver for Java takes &mdash you can simply tell it to use a faster in-process web browser and it will run JavaScript but only via Rhino, which goes back to the non-native runtime problem. In fact, WebDriver will soon be an actual driver for Selenium.

Hmm ... thinking out loud ... maybe the solution is to just run XULRunner as a headless firefox, the way SMILE web scraper does. Maybe I'll try that.

Besides web testing, one cool thing about python-spidermonkey is it may allow for unit testing of JavaScript libs in Python. This means you could create an import hook that loaded *.js files into Python and do all your testing in Python, reaping the benefits of tools like nose. Or, maybe more realistically, automate the testing of custom Firefox extensions implemented in JavaScript.

Have you ever ran unit tests in JavaScript? It's clunky because you need to run them in a browser. That's how JSUnit works anyway, which is otherwise a passable testing environment. To automate such tests you have to use something like Selenium to run your test suite in a real web browser.

After the release of Google App Engine, the Rubyists ...

posted in Google App Engine, Python, Ruby by kumar on Monday May 5th, 2008 at 3:07p.m.

... learn Python? No. They try compiling Ruby to Python bytecode, naturally. One has to admire their pride, I guess. The funny part is this might actually work. As the article points out, Ruby's opcode structure was inspired by Python's (I had no idea it was so similar, but this makes sense). And a while back Fuzzyman performed what looks to me a successful experiment in implementing Ruby-style anonymous blocks in Python bytecode, which is probably the only Ruby logic that Python doesn't do. Although I'm probably forgetting something as I don't use Ruby much.

Making Erlang indentation-sensitive

posted in Erlang, Python, The Future by kumar on Monday Apr 28th, 2008 at 5:56p.m.

Ulf Wiger has been experimenting with making Erlang indentation-senstive. He followed up with a Part 2 after comments.

For most people who start working in the Erlang language, the most annoying new concept is all the various line-terminators you have to know. Damien Katz sums this up nicely. All these explicit terminators might make other people's code easier to read but writing code should be easy too (they are equally important). Mue says just get over it but as a Python user I agree that Erlang would be way better off if it was indentation-based so this was an interesting experiment.

As for Python, I'm still shocked to hear people say "Python would be nice ... if it wasn't for that whitespace thing." Who is perpetuating this? I have no idea. The next time you hear someone say this, pass along Python: Myths about Indentation!

The Python Make tool

posted in Python by kumar on Tuesday Apr 22nd, 2008 at 10:54a.m.

A while back there was a lot of talk about needing a Make tool for Python, one like Ruby Rake. There are a few packages now:

... and more recently:

Personally, I liked Ian Bicking's suggestion to just use distutils but apparently his examples came off convoluted. I think this is because distutils is somewhat convoluted (to be fair, it was created a long time ago in software years).

At the time of that article I took Ian's advice and tried to do Make-like work in distutils commands. It was a pain. Mostly, I kept forgetting how everything needed to be set up. Since distutils silently ignores errors it doesn't tell you what's wrong, your command just doesn't work. But I still think the core concept is a good one. You probably already have a setup.py file anyway, so why not add some commands to it?

disthelper

So ... I made a helper to reduce the pain of creating setup.py commands: disthelper

It's the simplest possible approach: it just automates the creation of standard setup.py commands. You need setuptools and Paste to run disthelper but you don't need anything beyond the stdlib distutils module to run your custom command. I think more pain can be abstracted out of creating distutils commands. First off, I've been experimenting with an optparse-based wrapper around distutils.core.Command. This isn't ready for release but so far I am convinced it is possible to make a nicer Command class that's fully backwards compatible with distutils.core.Command. This could be taken even further and grow a decorator interface or something simpler that didn't require a class (for simple commands). If anyone wants to help dream up an interface, I've laid down the ground work to make this distutils-compatible and am willing to help implement it (my time permitting, of course). As an aside, I think such a wrapper would make a nice addition to the stdlib as long as backwards-compatibility is maintained.

Somewhat related is the buildutils project. Buildutils defines many custom tasks you typically want to perform on your project. At some point I may also make disthelper a repository for typical commands but right now I'd like to focus on making it a facilitator of creating setup.py commands.

Testing Google App Engine sites

posted in Google App Engine, Python, Testing by kumar on Thursday Apr 17th, 2008 at 3:07p.m.

The Google App Engine SDK sets up a fairly restrictive Python environment on your local machine to simulate their runtime restrictions. Roughly this consists of no access to sockets and thus barely working httplib, urllib, etc (replaced by urlfetch.fetch()), inability to use Python C modules, and no access to the file system. The SDK lets you run your app very easily using the dev_appserver.py script but I thought, how the heck would I test my app without the dev server?

It turns out this was ridiculously easy. You just run about 10 lines of code at the start of your test suite. Of course, it might change with an SDK upgrade but here's what worked in my tests/__init__.py in today's SDK (besides sys.path munging):

import os
from google.appengine.tools import dev_appserver
from google.appengine.tools.dev_appserver_main import *
option_dict = DEFAULT_ARGS.copy()
option_dict[ARG_CLEAR_DATASTORE] = True

def setup():
    ## path to app:
    root_path = os.path.join(os.path.dirname(__file__), '..')
    logging.basicConfig(
        level=option_dict[ARG_LOG_LEVEL],
        format='%(levelname)-8s %(asctime)s %(filename)s] %(message)s')
    config, matcher = dev_appserver.LoadAppConfig(root_path, {})
    ## commented out stuff that checked for SDK updates
    dev_appserver.SetupStubs(config.application, **option_dict)

The setup() is called by nose at the beginning of all tests but if you weren't using nose you could put it at the module level or anywhere else to be called once.

The really cool thing is running tests like this will automatically add indexes for your queries (just like the SDK dev server will) so if you had good code coverage your app would be ready to go live.

Next, you can test your URLs with something like WebTest like so:

from YOURAPP import application
from webtest import TestApp
def test_index():
    app = TestApp(application)
    response = app.get('/')

...where application is any WSGI app, like one defined in the Hello World tutorial:

from google.appengine.ext import webapp
class MainPage(webapp.RequestHandler):
  def get(self):
    self.response.out.write('Hello, webapp World!')

application = webapp.WSGIApplication(
                [('/', MainPage)], debug=True)

I haven't tried this for Django, but I'm pretty sure it would work as advertised, making your application object this:

application = django.core.handlers.wsgi.WSGIHandler()

And there you have it. The two modules used here aren't in the SDK but that's fine because you don't need to upload them to App Engine anyway. You can run easy_install nose WebTest and be ready to test. You were planning on testing your App Engine site, weren't you? :)

If you want to poke around in the test suite I made for pypi.appspot.com, the code is all in the Pypione project, specifically, the tests directory.

UPDATE

I have since realize the above method does not actually simulate all restrictions, it just inserts some stub modules. Specifically, it doesn't simulate restricting imports of a lot of builtin modules, nor does it remove file() and open().

Jason Pellerin is working on a nose plugin, noseGAE (mentioned below in comments), that aims to get all this simulation accurate. It is coming along nicely.

PyPi (Cheeseshop) on Google App Engine

posted in Google App Engine, Projects, Python, The Future by kumar on Tuesday Apr 15th, 2008 at 9:55a.m.

Like many of you, I've had my jaw on the floor since the release of Google App Engine. Although there are skeptics out there, a careful read of their terms will show you that it's for real — Google has released GOOGLE to the world and it's not for scary marketing purposes. In fact, I've been growing tired of paranoid Google haters; I'm hoping this will shut them up for a while.

Why is App Engine such a breakthrough? The concept of a hosted web application is nothing new but it has never been done this well. Mundane server maintenance? Gone. Infinite scalability? Check. 100% uptime? Let's face it, if Google went offline you'd probably be down in a nuclear bunker playing Parcheesi.

So ... how should we leverage this tool for the greater good of the community? I can't count the ways without getting dizzy. How about let's start with a mirror of PyPi, the Python Package Index?

PyPi on the App Engine

I barely spent two days on it, but here it is: http://pypi.appspot.com/. Test it out, play with it, try to break it.

As Python grows, especially due to App Engine, PyPi needs to scale too. Zope has put together a PyPi mirror but that's the only other one I know of (actually, I can't even find the link to it right now). Coincidentally, PyPi even went offline for a few min while I was writing this blog post.

Issues...

You Can Help

I'm not dedicated to this project, I just thought it sounded like a good idea and would be a fun way to experiment with the App Engine. If anyone is interested in working on it just let me know --kumar.mcmillan@gmail.com. If there is enough interest I'll put it on Google Code. Possibly the most exciting feature of App Engine is the Datastore API (aka BigTable) and Ben Bangert agrees. It's a little hard for me to wrap my head around it but so far the Expando class—besides being the coolest name for a class—seems to work great for storing package data. If EGG-INO grows a new parameter, it just gets tacked on to the row dynamically.

This has also been a great way to dig up bugs, some of which have already been fixed.

Unicode In Python, Completely Demystified (slides available)

posted in Chicago, Pycon 2008, Python by kumar on Saturday Mar 15th, 2008 at 2:06p.m.

Big thanks to everyone who attended my talk at PyCon today, Unicode In Python, Completely Demystified. It was an ambitious title; I highly doubt I "demystified" everything, but I was happy with how it went. There were a ton of great questions — even some I couldn't answer, of course. If you have any other questions feel free to comment here and I'll try my best to answer.

For those who couldn't make the talk or those who just want to refer back to the talk and / or source code, I've posted the slides here: http://farmdev.com/talks/unicode/. The audio / video should be available soon so I'll re-post a message when that's available.

Also, for reference, here is the primer:

This talks aims to make every single last person in the audience understand exactly how to write Unicode-aware applications in Python 2. If necessary, we will move to a Birds of Feather gathering, to the bar, to your hotel room, I'll start hanging around your cube at work -- whatever it takes -- until you completely "get it." But it's really simple so bring an open mind, a notepad, and get ready to create bullet proof Python software that can read and write text in Arabic, Russian, Chinese, Klingon, et cetera. As a citizen of the Python community you have the responsibility of creating Unicode-aware applications!

Data mining in Python and beyond?

posted in Data Mining, Python by kumar on Wednesday Mar 12th, 2008 at 4:49p.m.

Dear Lazy Web,

I am a software engineer who hasn't done any college level math (gasp!). Recently, I've been having a lot of fun transforming data into more meaningful data. This, I believe, is more commonly known as data mining and I'd like to learn more about it.

Specifically, I've been looking at Internet search data where keywords are buried in some kind of template like {foo}::{bar}::{keywords}, placeholders replaced with actual content; there are many different, disparate template formats and no template ID to go by. So, I spent some quality time with my favorite programming language, Python, and identified as many patterns as I could in a sampling of 5 million candidate strings. After much tweakage, my pattern recognition became 94.54% accurate. This rate was more than good enough to the users of the data so I basked in sweet triumph and called it a day :)

In another project I used frequency analysis and deduction to turn eBay auction titles into more meaningful identifiers of items up for sale. This worked fairly well because my dataset was large and all the auctions were for a specific kind of item.

My question to you is where can I find out more about this kind of fun stuff? Can you recommend a good book on data mining? Any good blogs to read? Should I take some math classes before I get too deep into this? If so, which ones?

The Monty Hall Problem (win a goat or a car)

posted in Python, Whatever by kumar on Wednesday Feb 13th, 2008 at 9:51a.m.

There is a puzzle used in game shows known as The Monty Hall Problem. It's been around for a while but over lunch yesterday someone explained it to me for the first time and 3 out of 4 of us argued convincingly the same answer. And it was wrong. Here's the problem:

Suppose you're on a game show, and you're given the choice of three doors: Behind one door is a car; behind the others, goats. You pick a door, say No. 1, and the host, who knows what's behind the doors, opens another door, say No. 3, which has a goat. He then says to you, "Do you want to pick door No. 2?" Is it to your advantage to switch your choice?

The most logical answer to me was no it doesn't matter if you switch or not because you never knew what was behind the first door you chose anyway. It seemed to me that the problem was no different than having two choices, a goat or a car and randomly choosing one. But this is all wrong!

Since I'm not good at math I could only loosely follow the explanations for why I was wrong. So, naturally, I wrote some code to see it in action (bear with me, I spent all of 5 minutes on it):

import random
from decimal import Decimal
choices = ['goat','goat','car']
tries = 99000
switch_correct, stay_correct = 0, 0
for num in range(tries):
    doors = [c for c in choices]
    random.shuffle(doors)
    first = doors.pop(random.randint(0,len(doors)-1))
    for i,val in enumerate(doors):
        if val == 'goat':
            doors.pop(i)
    switched = doors[0]
    if switched == 'car':
        switch_correct += 1
    elif first == 'car':
        stay_correct += 1
print "stay: you win %s%% of the time" % (Decimal(stay_correct) / Decimal(tries) * 100)
print "switch: you win %s%% of the time" % (Decimal(switch_correct) / Decimal(tries) * 100)

I found the result astonishing:

stay: you win 33.5% of the time
switch: you win 66.5% of the time

The wikipedia link above explains why this is but it is still incredible to me, like a magic trick.

Building Flash/ActionScript sites entirely in code and using FireBug for debugging

posted in ActionScript, Flash, JavaScript, Python, Testing by kumar on Monday Jan 28th, 2008 at 1:09p.m.

Way back in the olden days I used to dabble in Flash for building dynamic websites. This was incredibly painful, as I recall, because I couldn't stand the Flash IDE. It was clunky and hard to navigate, there weren't enough key commands, and the code editor was a sad version of notepad at best. And why use Flash anyway? JavaScript will do most of what you need for a dynamic site nowadays and I believe things like Google AdSense read the DOM for content filtering, which would render a Flash site useless. For me, the answer was audio playback. I wanted to play some audio on a site and for this Flash seems like the only option.

Digging deep into my vault of web dabblery I remembered getting so fed up with the Flash IDE that I wrote an entire site in ActionScript alone. I was quite proud of this as it was an early foray into programming and made me realize how much I enjoyed writing software in code. By some stroke of luck, this ActionScript-only site written circa 2002 is still online! OK, the intro was made with some timeline animation (someone else did that) but everything else is pure code, I swear.

(UPDATE: Me an my big mouth: A few months after I wrote this article the site changed, it's not longer the 2002 version :( But it looks and behaves similar so they might have reused some of my code.)

So there I was, planning out my soon-to-blow-your-mind Flash audio player, yet without Creative Suite 3, the latest Flash IDE. In fact, I didn't want it — $699.00, ouch! Not to mention: the pain of installing another massive, bloated application on my hard drive. A little Googling around later, I discovered Motion-Twin ActionScript 2 Compiler, or mtasc for short, written in OCaml. This was exactly what I was hoping for, an open source command line tool for compiling ActionScript code into SWF (Flash) movies without the need for any clunky IDE. And it works very nicely.

Unfortanately, ActionScript seems to have no error handling whatsoever (or I haven't figured out how to handle errors yet) so doing stupid stuff like calling a method that doesn't exist will not stop program execution as it should. Great. So I quickly became familiar with hooks that mtasc provides to the trace() command. Calling trace() writes to the Flash IDE's debug log. But since you aren't in a Flash IDE when testing a freshly compiled swf, mtasc allows you to define your own implementation of trace. Cool! So naturally, I created my own trace that writes to the FireBug log. FireBug, of course, is the ultimate webapp-debugging tool.

Here it is first added to the example app (from the mtasc tutorial):

class Tuto {

    static var app : Tuto;

    function Tuto() {
        // creates a 'tf' TextField size 800x600 at pos 0,0
        _root.createTextField("tf",0,0,0,800,600);
        // write some text into it
        _root.tf.text = "Hello world !";
        
        trace("debugging with trace rocks!");
    }

    // entry point
    static function main(mc) {
        // note that this seems to help mtasc find the trace method
        var f = new FireTrace();
        app = new Tuto();
    }
}

...saved to Tuto.as. And here is my trace implementation, saved to FireTrace.as:

class FireTrace {
    static function trace(msg, class_, file, line) {
        getURL('javascript:console.debug("[' + file + ':' + line + ' ' + class_ + '] ' + msg + '")');
    }
}

I compiled it like so:

mtasc -swf Tuto.swf -trace FireTrace.trace -main -header 800:600:20 Tuto.as

And used a simple HTML page to run it:

<html>
<head>
<script type="text/javascript">

if (!window.console || !console.firebug)
{
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

    window.console = {};
    for (var i = 0; i < names.length; ++i)
        window.console[names[i]] = function() {}
}

</script>
</head>
<body>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" name="TopPlayer" id="TopPlayer"
     codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0"
     width="800" height="600">
 <param name="movie" value="Tuto.swf"> 
 <param name="quality" value="high">
 <param name="loop" value="false">
 <param name="play" value="true">
 <!--<param name="bgcolor" value="#ffffff">-->
 <param name="swliveconnect" value="true">

 <embed src="Tuto.swf" quality="high" width="800" height="600"
 	type="application/x-shockwave-flash" name="TopPlayer" id="TopPlayer"
 	pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash"
 	swliveconnect="true">
 </embed>
</object>
</body>
</html>

...and here is what it prints to my FireBug console:

[Tuto.as:11 Tuto::Tuto] debugging with trace rocks!

Notice that I had to add this line of code to the Tuto class:

var f = new FireTrace();

I don't know if this is a bug in mtasc but without it the custom trace seems like it never gets loaded. Also notice that I used the FireBug Lite JavaScript snippet for gracefully degrading console methods when FireBug isn't running.

After my romantic reunion with writing ActionScript, what has changed? The first thing I've noticed is that ActionScript 3 now looks exactly Java but I have no idea why. Luckily, it remains compatible with ActionScript 2 so you can leave out all the type declarations and everything still seems to work. Thus, it is pretty much a clone of JavaScript with some extra craziness you probably don't need. I'm still trying to figure out a better way to handle errors; putting debug statements everywhere is pretty lame. If anyone has a suggestion let me know. At the least, I would like to get an error in the log when I stupidly try to call a non-existant method.

Now that I have a prototype, the next step is to write automated tests, of course! This will be a lot of fun as I love watching tests pass. At first glance, the AsUnit (ActionScript Unit Test Runner) seems like it will be useful. I have no doubt that GUI testing Flash is no easier than it is in other languages, and thus not so easy to automate ... but one always needs unit tests.

UPDATE

Ah, looks like there is an even better way to call JavaScript by way of the ExternalInterface class:

ExternalInterface.call("console.log", variable1, variable2, variableN);

I haven't tried it but this article suggests to limit your calls to String, Number, Array, Object, and Boolean datatypes.

Software is written by hand

posted in JavaScript, Python, Ruby, The Future, Whatever by kumar on Friday Dec 21st, 2007 at 3:36p.m.

...that's right, it's not molded or prefabbed, it's not made on a production line or in a lab. Are we insane??! Here is a hilarious probe into the darker side of this art we call programming.

Converting ReStructuredText to Wiki syntax

posted in Python by kumar on Friday Dec 21st, 2007 at 12:45p.m.

Leapfrog Online is looking for some Django developers (Chicago area)

posted in Chicago, Django, JavaScript, Python, Testing by kumar on Thursday Dec 13th, 2007 at 4:45p.m.

WSGI Intercept Has A New Home

posted in Projects, Python, Testing by kumar on Monday Dec 3rd, 2007 at 9:46a.m.

importing modules from setup.py (chicken vs. egg!)

posted in Python by kumar on Tuesday Nov 20th, 2007 at 2:02p.m.

How To Get Started Writing Open Social Applications

posted in JavaScript, Presentations, Python, The Future by kumar on Sunday Nov 18th, 2007 at 11:58a.m.

Pycon in Chicago, Excited Yet?

posted in Chicago, Pycon 2008, Python by kumar on Wednesday Nov 14th, 2007 at 1:09p.m.

GTAC Highlights Part 1 - Selenium is Alive and Well, Model Based Testing Is Smart, And...

posted in GTAC, Java, Python, Ruby, Testing, The Future by kumar on Saturday Aug 25th, 2007 at 5:34p.m.

Python on TextMate demo (Chicago area)

posted in Presentations, Python, TextMate by kumar on Wednesday Aug 8th, 2007 at 1:03p.m.

Hacking python frames

posted in Python by kumar on Wednesday Jul 18th, 2007 at 5:10p.m.

fileinput : nice module for file processing

posted in Python by kumar on Tuesday Jul 3rd, 2007 at 10:12a.m.

context_tools, bridging the gap between test methods and test classes?

posted in Python, Testing by kumar on Tuesday Jun 26th, 2007 at 10:31a.m.

Going to the GTAC (Google Test Automation Conference)

posted in Python, Testing by kumar on Thursday Jun 21st, 2007 at 11:19a.m.

What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?

posted in Python by kumar on Wednesday Jun 20th, 2007 at 2:04p.m.

What I Thought I Knew About Unicode in Python Amounted To Nothing

posted in Python by kumar on Thursday Jun 14th, 2007 at 4:23p.m.

documentation for fixture module

posted in Projects, Python, Testing by kumar on Tuesday Apr 17th, 2007 at 1:31p.m.

multiple inheritance woes

posted in Python by kumar on Thursday Mar 29th, 2007 at 10:09a.m.

testing just got easier (a few nose plugins)

posted in Python, Testing by kumar on Thursday Mar 22nd, 2007 at 5:25p.m.

unicode and unicorns

posted in Python by kumar on Monday Mar 12th, 2007 at 2:32p.m.

Live doctest in TextMate (IPython + Twisted?)

posted in Python, TextMate by kumar on Thursday Mar 1st, 2007 at 2:31p.m.

PyCon: A Star Schema in pure python code? Is this guy INSANE?

posted in Pycon 2007, Python by kumar on Saturday Feb 24th, 2007 at 10:17p.m.

You vs. The Real World: Writing Tests With Fixtures (Sunday at Pycon!)

posted in Python, Testing by kumar on Monday Feb 19th, 2007 at 1:42p.m.

Why People Don't Use Hand Dryers

posted in Python, The Future by kumar on Wednesday Feb 14th, 2007 at 10:32a.m.

2 stupid things I coded this week

posted in Python by kumar on Friday Feb 9th, 2007 at 10:12a.m.

Coffee! ... and python

posted in Chicago, Python by kumar on Wednesday Jan 31st, 2007 at 1:20p.m.

Housecall from the pydoctor (finally, a doc generator that works!)

posted in Python by kumar on Wednesday Jan 24th, 2007 at 5:10p.m.

Generating python with python

posted in Python by kumar on Wednesday Jan 17th, 2007 at 11:45p.m.

Python gets true closures in 3000 - do I care?

posted in Python by kumar on Saturday Dec 2nd, 2006 at 7:23p.m.

You vs. The Real World: Testing With Fixtures (Coming Soon)

posted in Python, Testing by kumar on Thursday Nov 30th, 2006 at 11:34a.m.

Creating a subversion checkout/ dev target for easy_install

posted in Python by kumar on Wednesday Nov 29th, 2006 at 4:58p.m.

Recent Projects

  • fixture

    Python module for loading and referencing test data.

  • pypione

    A mirror of PyPi running on Google App Engine

  • Wikir

    converts reStructuredText documents to various Wiki formats.