This isn't how it was supposed to end.
Art work
I put a lot of effort into my job, and at some level, it's a creative outlet. Still, I sometimes want to put my into little side projects.
I've got a bit of nostalgia for cursor-position-based programs, software like xeyes, Jewel Thief, and Neko the Cat.
Anyway, Alex was in town last week (securing an apartment before moving out), and I was chatting about it with him. Last night, I had a few free hours and just coded it up. I made the first part, but I need more help.
First, click through:

Might not work in IE. I'll fix it later.
I want to make a bigger art project out of this, so I'd like to get more people on Flickr to take eye-tracking photos of themselves and combine them into one big cool page. I put up a page with the instructions. Anything is fine — snapping the photos with your phone is plenty fine.
Thanks for your help.
I've got a bit of nostalgia for cursor-position-based programs, software like xeyes, Jewel Thief, and Neko the Cat.
Anyway, Alex was in town last week (securing an apartment before moving out), and I was chatting about it with him. Last night, I had a few free hours and just coded it up. I made the first part, but I need more help.
First, click through:

Might not work in IE. I'll fix it later.
I want to make a bigger art project out of this, so I'd like to get more people on Flickr to take eye-tracking photos of themselves and combine them into one big cool page. I put up a page with the instructions. Anything is fine — snapping the photos with your phone is plenty fine.
Thanks for your help.
JavaScript on Rhino on Java on App Engine
I've got a limited amount of free time, and there's a lot of stuff in this world to play around with. When I'm trying to put together little demos and things, I tend to use Python on the server side -- it's a succinct, loosely type language with a lot of time and typing-saving features. Also, it's an interpreted language; App Engine's development server automatically catches change you make to a file, so my development cycle is just type-save-reload (leaving little time for swordplay).
Some of those language features' advantages start not to be advantages when your app gets more complex, however. When writing a large application, features like type checking, interface definition, and member access permissions become essential. While they introduce a lot of verbosity, they do make the problem of writing a large, complex, and (hopefully) fast app easier.
It's little surprise, then, that the second runtime the App Engine team released is Java (sadly, not Fortran).
For certain tasks, I'll even admit I like Java. It has its time and place. But what gets me excited about the App Engine announcement is that there are a lot of scripting language implementations that are written for Java. Two that should get web folks excited are JRuby and, for JavaScript, Rhino.
I'm excited about the latter. Rhino on App Engine means that I can quickly script apps in probably my most productive language, JavaScript. So I took some time yesterday mashing up the embedded Rhino examples with App Engine's "Hello World!" example.
The two classes, hopefully in a working state, are here, sans all the import statements:
Basically, I'm just exposing to the JavaScript environment an object, in the global scope, named "request" with one method: "write". Obviously, as a more robust framework, you could expose more of the underlying App Engine APIs, or even make the Java objects available for scripting.
Anyway, in this way, you can start writing your server side logic in JavaScript. So in this example,
Cool stuff. This is really the first I've ever worked with Rhino, but I hope to spend some more of my free cycles on this and come up with a more general system for working server-side in JavaScript on App Engine. There's a lot of potential here.
Some of those language features' advantages start not to be advantages when your app gets more complex, however. When writing a large application, features like type checking, interface definition, and member access permissions become essential. While they introduce a lot of verbosity, they do make the problem of writing a large, complex, and (hopefully) fast app easier.
It's little surprise, then, that the second runtime the App Engine team released is Java (sadly, not Fortran).
For certain tasks, I'll even admit I like Java. It has its time and place. But what gets me excited about the App Engine announcement is that there are a lot of scripting language implementations that are written for Java. Two that should get web folks excited are JRuby and, for JavaScript, Rhino.
I'm excited about the latter. Rhino on App Engine means that I can quickly script apps in probably my most productive language, JavaScript. So I took some time yesterday mashing up the embedded Rhino examples with App Engine's "Hello World!" example.
The two classes, hopefully in a working state, are here, sans all the import statements:
public class Response extends ScriptableObject {
public Response() {
out = new StringWriter();
}
@Override
public String getClassName() { return "Response"; }
public void jsFunction_write(String str) {
out.write(str);
}
public StringWriter out;
}
public class RhinoServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException {
res.setContentType("text/plain");
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
ScriptableObject.defineClass(scope, Response.class);
Scriptable response = cx.newObject(scope, "Response");
ScriptableObject.putProperty(scope, "response", response);
FileReader reader = new FileReader("hellorhino.js");
Object result = cx.evaluateReader(scope, reader, path, 1, null);
Response javaResponse = (Response) cx.jsToJava(
response, Response.class);
res.getWriter().write(javaResponse.out.toString());
} catch (Exception ex) {
res.setStatus(500);
res.getWriter().println(ex.toString());
} finally {
Context.exit();
}
}
}
Basically, I'm just exposing to the JavaScript environment an object, in the global scope, named "request" with one method: "write". Obviously, as a more robust framework, you could expose more of the underlying App Engine APIs, or even make the Java objects available for scripting.
Anyway, in this way, you can start writing your server side logic in JavaScript. So in this example,
hellorhino.js is just:
var words = ['Hello', 'World!'];
response.write(words.join(' '));Cool stuff. This is really the first I've ever worked with Rhino, but I hope to spend some more of my free cycles on this and come up with a more general system for working server-side in JavaScript on App Engine. There's a lot of potential here.
JSON Proxy
Brett works on Google App Engine. As such, he persistently badgers me to build App Engine apps. This dates back to long before App Engine existed externally.
I've made a few, the simplest of which actually got popular.
Anyway, I recently put up another one: JSON Proxy
Cross-domain JSONP (or "JSON with callbacks") has long been an interest of mine. It's interesting that many sites are offering JSON as an output type for their web APIs. Flickr, Twitter, and GData APIs all do.
Having such APIs is great -- it allows client-side code to pull data as JavaScript object literals across domains, skirting the same origin policy of XMLHttpRequest (just make sure you never serve private user data with this method). For example, on this page, I'm using a URL formed with the Twitter API to fill the Tweets section in the sidebar (a callback called
Unfortunately, there no recourse if some web service lacks JSON as an output type. Some sort of proxy is required. The Google AJAX Feed API allows fetching of RSS and Atom feeds, which is very useful (the XML-to-JSON transformation is better defined in this case).
So, I wrote a proxy for an even more general case: any XML, and accepts a callback parameter, which allows you to fetch any GET-accessible XML resource as a JSON object. The App Engine app fetches the XML content, transforms it to JSON, and sends it out, wrapped in a callback if requested.

This allows some cool stuff. I came up with the example of all-client-side Amazon search through their Amazon Web Services API.
Anyway, I've written a better and more technical writeup, and have posted the source.
I would love it if somebody would come up with a really innovative application of the proxy.
Enjoy!
I've made a few, the simplest of which actually got popular.
Anyway, I recently put up another one: JSON Proxy
Cross-domain JSONP (or "JSON with callbacks") has long been an interest of mine. It's interesting that many sites are offering JSON as an output type for their web APIs. Flickr, Twitter, and GData APIs all do.
Having such APIs is great -- it allows client-side code to pull data as JavaScript object literals across domains, skirting the same origin policy of XMLHttpRequest (just make sure you never serve private user data with this method). For example, on this page, I'm using a URL formed with the Twitter API to fill the Tweets section in the sidebar (a callback called
twitterCallback is called with a JSON object of my tweets).Unfortunately, there no recourse if some web service lacks JSON as an output type. Some sort of proxy is required. The Google AJAX Feed API allows fetching of RSS and Atom feeds, which is very useful (the XML-to-JSON transformation is better defined in this case).
So, I wrote a proxy for an even more general case: any XML, and accepts a callback parameter, which allows you to fetch any GET-accessible XML resource as a JSON object. The App Engine app fetches the XML content, transforms it to JSON, and sends it out, wrapped in a callback if requested.

This allows some cool stuff. I came up with the example of all-client-side Amazon search through their Amazon Web Services API.
Anyway, I've written a better and more technical writeup, and have posted the source.
I would love it if somebody would come up with a really innovative application of the proxy.
Enjoy!
Debugging JavaScript on Android
I've been messing around with the Android emulator, particularly with its browser. Debugging just JavaScript wasn't well covered in the documentation, and I spent a little while getting it set up. I wanted to publish it here so it shows up in others' web searches -- I'll look into adding some of this to the official docs at work.
Anyway, to get you started: You can use either an actual Android device or an emulator. Install the Android SDK.
Then, you can use the Android Debug Bridge to connect to your device or emulator.
The key thing to note is that browser debug output will be tagged with
You can do some sniffing around by looking at the

Turns out it there's a console object with a subset of the methods from Firebug's console, though they just take a single string for the argument (not multiple arguments). The method names all produce debug output at the "D" level. So, this code:
Now you know.
Anyway, to get you started: You can use either an actual Android device or an emulator. Install the Android SDK.
Then, you can use the Android Debug Bridge to connect to your device or emulator.
The key thing to note is that browser debug output will be tagged with
WebCore. So, if you're only interested in browser debug output, start adb filtering debug output for everything but those tags. The command line is:adb logcat WebCore:V *:SWhich means "show all debug output tagged with WebCore, and silence everything else" (see their documentation for more information).
You can do some sniffing around by looking at the
window object in the browser:var terms = [];You'll notice a bunch of goodies in there (and a few interesting ones I'll investigate later). But, particularly, you'll notice a reference to
for (key in window) {
terms.push(key + ': ' + window[key] );
}
terms.sort();
for (var i = 0; i < terms.length; i++) {
document.write('<p>' + terms[i] + '</p>');
}
window.console. Loop over that and you'll see:
Turns out it there's a console object with a subset of the methods from Firebug's console, though they just take a single string for the argument (not multiple arguments). The method names all produce debug output at the "D" level. So, this code:
console.error('1');
console.info('2');
console.log('3');
console.warn('4');Produces this output:D/WebCore ( 165): Console: 1 line: 0 source: http://...In addition, any JavaScript errors will also show up in the output. Good stuff.
D/WebCore ( 165): Console: 2 line: 0 source: http://...
D/WebCore ( 165): Console: 3 line: 0 source: http://...
D/WebCore ( 165): Console: 4 line: 0 source: http://...
Now you know.
A new day
The day before my birthday, Dave and I ran to catch a bus from Madison to Chicago. We were off to Union Station to catch a train to New York, where we were going to couch surf for a week over spring break. It was 2004. Crossing into Illinois, the ground was covered with patches of snow, and the street corners with political signs. It was days before the Democratic Senate primary. I remember the simple blue signs that read "Obama" in white serif, probably the first time I'd heard the name. He went on to easily defeat Alan Keyes (who I remember talking to in the lounge of my dorm previously).
It's now just a few months short of five years later. I'm on my couch in San Francisco (where I never expected to live), watching Obama take the oath of office to become the President of the United States.
Life is unpredictable. And that's awesome.
It's now just a few months short of five years later. I'm on my couch in San Francisco (where I never expected to live), watching Obama take the oath of office to become the President of the United States.
Life is unpredictable. And that's awesome.
Fractal Snowflake Holiday Cards
Ever since I got out of college, I've sent out holiday cards. Originally, I'd just buy a nice set of cards, sign them, and send them out. Last year, however, my inner Martha Stewart caught hold. I wanted something clever that stood out amongst the generic store-bought cards, so I drew my own.
They were well received, so I'd like to make an annual tradition of self-made cards. And in keeping with that tradition, I made the second annual holiday card.
I had been mulling a couple of clever ideas over the last year, most of them involving photography around San Francisco. Unfortunately, San Francisco weather was cold and rainy the last few weeks before traveling home, so I put together a quick plan B -- a card with a picture not taken or drawn by me, but by the computer.
With the Koch snowflake as inspiration, I wrote a quick script that would draw a fractal snowflake. I wanted something small and elegant that made a complex and detailed drawing.

Of course, the source was printed on the inside.
They were well received, so I'd like to make an annual tradition of self-made cards. And in keeping with that tradition, I made the second annual holiday card.
I had been mulling a couple of clever ideas over the last year, most of them involving photography around San Francisco. Unfortunately, San Francisco weather was cold and rainy the last few weeks before traveling home, so I put together a quick plan B -- a card with a picture not taken or drawn by me, but by the computer.
With the Koch snowflake as inspiration, I wrote a quick script that would draw a fractal snowflake. I wanted something small and elegant that made a complex and detailed drawing.
#/usr/bin/python2.5Which made this snowflake, which I put on the cover of the card (with the invocation call,
import turtle
turtle.delay(0)
turtle.tracer(False)
def draw_line(len, rec=0, stay=False, turn=0):
pos, heading = turtle.position(), turtle.heading()
turtle.right(turn)
if (rec is 0):
turtle.forward(len)
else:
rec = rec - 1
step = len / 2
draw_line(step, rec, True)
draw_line(step * .75, rec, turn=60)
draw_line(step * .75, rec, turn=-60)
draw_line(step, rec , True)
if not stay:
turtle.goto(pos)
turtle.setheading(heading)
def draw_flake(rec):
turtle.setheading(90)
for turn in xrange(6):
draw_line(400, rec)
turtle.right(60)
turtle.done()
draw_flake(6)):
Of course, the source was printed on the inside.