Thoughts
It's Time to USE The Web : Mozilla Labs Releases Ubiquity
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.
- 0 comments
- read comments
- post comment
- permalink
aintjustsoul.net: A portable record player for the Internet
I'm very pleased to announce a website I just launched:
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.
- 3 comments
- read comments
- post comment
- permalink
Chicago's Google App Engine Hack-A-Thon Recap
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.
- 0 comments
- read comments
- post comment
- permalink
Fixture Goes 1.0 (Testing With Data In Python)
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
Highlights of This Release
- SQLAlchemy 0.4 now finally works as a nice fixture backend (0.5 beta support is shaky, but mostly there).
- Even more documentation! The new docs have been completely reorganized thanks to the venerable Sphinx. Of special note is a new tutorial that shows how to use fixture to test a Pylons + SQLAlchemy application.
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.
- 0 comments
- read comments
- post comment
- permalink
An In-Process, Headless Web Browser for Python?
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:
- document
- window
- navigator
- layer
- and all the form 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.
- 3 comments
- read comments
- post comment
- permalink
After the release of Google App Engine, the Rubyists ...
... 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.
- 0 comments
- read comments
- post comment
- permalink
Making Erlang indentation-sensitive
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!
- 3 comments
- read comments
- post comment
- permalink
The Python Make tool
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:
- SCONS
- A software construction tool
- zc.buildout
- System for managing development buildouts
... and more recently:
- Vellum
- Vellum is Zed Shaw's project to create a nice build tool for Python, or really for anything you need to automate in a consistent fashion.
- Paver
- Paver is a Python-based build/distribution/deployment scripting tool along the lines of Make or Rake
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.
- 8 comments
- read comments
- post comment
- permalink
Testing Google App Engine sites
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.
- 4 comments
- read comments
- post comment
- permalink
PyPi (Cheeseshop) on Google App Engine
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...
- urlfetch can't get big packages
- fetching SQLAlchemy triggered the ResponseTooLarge error but its package was barely over 1MB. We might be able to create a download proxy to work around this.
- May not be fully compatible with easy_install yet
- Can't run scripts on App Engine
- Not too big a deal, you have to think of web pages as scripts and use a separate crontab to make timed requests. There are security issues with this, but for mirroring pypi it's not a problem
- Note that I haven't actually mirrored all of PyPi, I'm still testing it out.
- It's not very pretty yet (see below)
- The prototype works, now it needs some tests :)
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.
- 6 comments
- read comments
- post comment
- permalink
Unicode In Python, Completely Demystified (slides available)
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!
- 5 comments
- read comments
- post comment
- permalink
Data mining in Python and beyond?
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?
- 11 comments
- read comments
- post comment
- permalink
The Monty Hall Problem (win a goat or a car)
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.
- 10 comments
- read comments
- post comment
- permalink
Building Flash/ActionScript sites entirely in code and using FireBug for debugging
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.
- 2 comments
- read comments
- post comment
- permalink
Software is written by hand
...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.
- 0 comments
- read comments
- post comment
- permalink
Converting ReStructuredText to Wiki syntax
- 0 comments
- read comments
- post comment
- permalink
Leapfrog Online is looking for some Django developers (Chicago area)
- 0 comments
- read comments
- post comment
- permalink
Datejs - A JavaScript Date Library
- 1 comment
- read comments
- post comment
- permalink
WSGI Intercept Has A New Home
- 0 comments
- read comments
- post comment
- permalink
importing modules from setup.py (chicken vs. egg!)
- 2 comments
- read comments
- post comment
- permalink
How To Get Started Writing Open Social Applications
- 1 comment
- read comments
- post comment
- permalink
Pycon in Chicago, Excited Yet?
- 2 comments
- read comments
- post comment
- permalink
GTAC Highlights Part 1 - Selenium is Alive and Well, Model Based Testing Is Smart, And...
- 9 comments
- read comments
- post comment
- permalink
Python on TextMate demo (Chicago area)
- 2 comments
- read comments
- post comment
- permalink
Hacking python frames
- 0 comments
- read comments
- post comment
- permalink
fileinput : nice module for file processing
- 0 comments
- read comments
- post comment
- permalink
context_tools, bridging the gap between test methods and test classes?
- 0 comments
- read comments
- post comment
- permalink
Going to the GTAC (Google Test Automation Conference)
- 2 comments
- read comments
- post comment
- permalink
What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
- 9 comments
- read comments
- post comment
- permalink
What I Thought I Knew About Unicode in Python Amounted To Nothing
- 6 comments
- read comments
- post comment
- permalink
undefined reference to `__stack_chk_fail' (compiling subversion 1.4.3 on Ubuntu)
- 1 comment
- read comments
- post comment
- permalink
documentation for fixture module
- 0 comments
- read comments
- post comment
- permalink
Humans are here to stay!
- 0 comments
- read comments
- post comment
- permalink
multiple inheritance woes
- 11 comments
- read comments
- post comment
- permalink
testing just got easier (a few nose plugins)
- 0 comments
- read comments
- post comment
- permalink
unicode and unicorns
- 0 comments
- read comments
- post comment
- permalink
Live doctest in TextMate (IPython + Twisted?)
- 3 comments
- read comments
- post comment
- permalink
PyCon: A Star Schema in pure python code? Is this guy INSANE?
- 0 comments
- read comments
- post comment
- permalink
You vs. The Real World: Writing Tests With Fixtures (Sunday at Pycon!)
- 0 comments
- read comments
- post comment
- permalink
Why People Don't Use Hand Dryers
- 1 comment
- read comments
- post comment
- permalink
Industry of the Ordinary
- 0 comments
- read comments
- post comment
- permalink
2 stupid things I coded this week
- 7 comments
- read comments
- post comment
- permalink
Coffee! ... and python
- 2 comments
- read comments
- post comment
- permalink
Housecall from the pydoctor (finally, a doc generator that works!)
- 2 comments
- read comments
- post comment
- permalink
Generating python with python
- 0 comments
- read comments
- post comment
- permalink
Python gets true closures in 3000 - do I care?
- 2 comments
- read comments
- post comment
- permalink
New Chicago City Sticker
- 0 comments
- read comments
- post comment
- permalink
You vs. The Real World: Testing With Fixtures (Coming Soon)
- 0 comments
- read comments
- post comment
- permalink
Creating a subversion checkout/ dev target for easy_install
- 0 comments
- read comments
- post comment
- permalink
Blogging, Blogosphere, or something
- 1 comment
- read comments
- post comment
- permalink
