Monday, January 28, 2013

Project Purgatory

I went to Startup Weekend this weekend, to which I will dedicate a full post... but one thing that's on my mind before then is how a number of my past projects are stuck in this terrible, almost-dead, zombie like state of code-rot and limbs falling off and hiding in a cave where no one can see them.

Project purgatory

Let's define Project Purgatory as when you had a really great app/prototype/demo of something, but servers died or APIs you depended on deprecated features you used, and you have little to zero evidence left of the awesomeness that once was.

What to do? 

Crap, I don't know. Write blog posts lamenting it for starters. List which projects got stuck in hell and which have escaped and look for trends? The options I'm considering are:
  1. Let go
  2. Vow to dedicate chunks of time to freeing certain projects from purgatory 
  3. Try really hard to not accidentally condemn projects to hell


My robust and vital projects 

Sketch-a-bit survived. It's definitely had it's share of excitement (Tom's servers are full and Adam must rescue everything while Kathleen is at Startup Weekend!) but the app lives on and still generates lots of cool sketches.

The pattern of other surviving apps includes stand-alone apps that live on in the android market or are hosted on flash game websites or are just simple websites hosted on my own website.


Projects trapped in hell (turns out they're all tied to Facebook)


Weird Sorta-Like-Poking Thing <-- at least I have that URL as a trophy

Actually, I don't care about this one. For a little while in 2007-8, the world had the ability to snorgle each other with kittens in a pile of more kittens instead of just "poking" them, and it's okay that that's not possible anymore. It doesn't work because FB requires things to come from a secure HTTPS server and I didn't do that. And/or you need signing/verification certificates that cost money.


Picard pretending to actually work. I'm confused. This is an example of the kind of HELL it's in where I'm not even sure how broken it is and it looks ever so temptingly alive.

Ah, there we go with Picard. Stuck in an infinite authentication loop for some reason.

Actually, after writing this therapeutic post, it turns out that Picard is the one that I'm really bothered about. We made this sweet flashcard learning game and put it INSIDE of facebook and now it's basically trapped inside of an impossible-to-fix no-scrolling iframe nightmare.

I value being able to log into things with Facebook or Twitter and I think I want to learn how to do that better, while developing things that technically live outside the realm of Facebook.


What would you do? 

It's been valuable to collect and save little artifacts along the way. At least I've got some screenshots on flickr. 

Since it's really hard for me to Stop Caring about some of these projects, I think I'm going to schedule some evening time into my calendar in the coming weeks that says "spend 2 hours trying to improve the situation."

Got any other suggestions for getting out/staying out of project purgatory?

Sunday, January 20, 2013

Drilling holes in glass wine bottles

My lab (the Center for Game Science at UW) is hosting the department TGIF next week. It's going be extremely elaborate and over the top and fancy-shmancy and amazing. A lot of people are  contributing via cooking or playing live classical music during the event. I'm in charge of decorating, and decided to bring a dash of danger and power tools into the equation.

So, as of half an hour ago, Adam and I finished drilling holes in wine bottles. Because it is utterly important to me that the lights get crammed in the side, not the top of the bottle.

wine bottles with holes drilled in them
Wine bottles with holes that seem large enough to shove lights through...

I haven't put lights in them yet (partially because the lights I'm planning to use are still attached to the outside of the house...) but they should end up looking like this:

End result, maybe? From this blog:
bright wine
HERE is the real final result! 6 illuminated bottles in various shades of green and clear!
glass drill bit package glass and tile drill bit
Drill bit.

Other people have succeeded at this on the internet (drilling a hole through a bottle with a drill bit like this and not dying), and now so have we.

Some of the highlights:
  • Some kind of coating flaked off the drill bit and then it seemed to work slightly better.
  • We had a spray bottle of water that we would use to spritz away glass powder (and turn it into glass mud) and also to cool the drill bit, although we did this outside in 40 degree weather so it didn't get too hot. 
  • Adam pointed out that in the hardware store, I was doing a "self-comforting" behavior of petting my hands with my other hands. Which makes sense because I was quite nervous about this whole drilling experiment until the first bottle was finally done and reasonable. Also I wanted a hole saw and the local hardware store didn't have those for glass.
  • We had a fancy bottle of Chianti with a basket, but the glass was kind of thin and we cracked it. 
  • It took about 10 minutes per bottle.
  • We used the 1/2 inch drill bit to make holes wider than 1/2 inch.
  • It worked the best when I held the bottle and the spritzer water bottle and Adam held the drill with both hands. 
RIP, chianti...
The chianti bottle didn't make it.

Tuesday, January 15, 2013

Research into faces

Grad school! This is a post about grad school... Kind of/mostly.

My research interests have recently led me to attempt a project combining computer vision facial analysis technology* and the intuition, generosity, and curiosity of the crowd. The "crowd" here is the crowd implicit in "crowdsourcing". Lots more ideas opinions on that, and why I want crowdsourcing to be way more than it is right now, but that's not what this post is about. This post is about faces!

*Briefly! Computer vision is only mediocre at faces. Computers can detect front-facing faces in a lot of images, and sort of detect smiles and a few other emotions when the conditions are just right, but there is soooo much more that could be done, just by having better training data, for starters.

face tracker!
Face tracker from Jason Saragih, now maintained by Kyle McDonald

Faces are this weird thing that almost all humans seem to have. Right out in front where other humans can see it. I have one. It's alright, now that I'm not in the middle of puberty. Honestly, aside from that I have one of my very own, and I like to use this little website called "Facebook" to look at other people's photos of their faces, I didn't get what was so compelling about faces.

Until recently...! This is what transpired:

0) Computers and things. 

The first part of this was that I got someone to explain to me how other people do research with computers and faces, and then I built a vision system that actually kind of worked. That was the meme impression quiz I blogged about a little while ago. Nothing like a computer doing what you want it to do based on your freshly minted skills to get you thinking you can bend it to your will even more later.

1) I read a book by Paul Ekman, Emotion in the Human Face

Do I recommend you read it? Maybe, or you can just have me vaguely tell you what I liked about it. So, this book was published in 1972 (according to Wikipedia, this was right around the time Human Subject Research Legislation/Institutional Review Board was cropping up) and it starts off like this (major paraphrasing): "When I approached this field of face psychology research, I was a little pessimistic because it seemed like there were no consistent results to be had; the face was just a big, confusing jumble of fleshy bits." ... "But then I started doing my own experiments, and wouldn'tchyaknow, my results were just fine and dandy! Turns out, there's plenty of good work to be done in this space, but everyone before was just messing it all up. Here, let me write a book pointing out how everyone got a big fat F on the scientific method, but if we take everyone's experiments together and correlate results and squint our eyes a bit, we can kind of get something reasonable."

Oh, also, the experiments (pre-IRB) were like, "What faces do people make when they're about to be shocked, or when they're harassed and stressed out by an interviewer and subsequently soothed, or when they witness (or perhaps partake in?) decapitating a live rat?" Or, "What faces do babies make when they're vertically displaced [dropped] a little bit?" (It seemed like all two babies were kind of peeved, no matter the stimulus.)

I've learned some actual things, like the difference between facial behaviors (what's the face is doing physically) and emotions (which may or may not be shown on the face). And the difference between judgment studies and component studies. And how in the past, people were mainly trying to verify that the face does contain information about emotion, and then determine how general/universal that information is.

Obviously, 40 years have passed since the book was written, so now my task is to find out what the heck people have been doing since then, and what's neat about it, and how I can improve it further.  I mean, aside from getting so famous from researching micro-expressions that they make TV shows about you.

2)  I started watching a TV drama about Paul Ekman.

Lie to Me. It's so much fun! It's a prime time drama show that was on from 2009-2011 that has kind of the same medical mystery spin as House, but it's based on that face psychologist I was just reading about! I like when the characters spew out familiar textbook information to each other for the viewers' benefit, like, "DID YOU KNOW?! You can tell a fake smile from a real smile by looking at the crinkles around the eyes!" Thanks for the tip, sidekick scientist lady!

They should really make more TV shows about scientists. Not documentaries, but gripping, compelling dramas. Like the PhD Movie. Aaanndd... nope, can't think of any more examples.

In conclusion, faces are pretty neat, and the more I learn, the more interesting they become. I'll leave you with what a strange photo of myself underground in a cave in Slovenia.

kathleen in a cave making a bad face
This is one of the least flattering photos I have on the internet.

Friday, January 11, 2013

blogger layout

The sexy dynamic (slow) layout was getting on my nerves. So we're back to blue flowers.

Monday, January 7, 2013

Make Computer Go

We can start off my telling our fine audience that Adam is typing this while Kathleen does the dishes. It might be a little bit unfair, gender-wise, but Adam did all the cooking.

Additionally, the goal of this blog post is to expose my pattern of what I use under the hood of a lot of my research projectS. What is that, you ask?

I like to make web pages that trigger crazy computations behind the scenes. The gist: how do you make a web page trigger math in the form of some C++ code behind the scenes.

So, I don't know what you're writing, and not seeing it is pretty weird. I don't intend to write stream of consciousness blog post, so this may be pretty silly.

Step 1: Make a web server out of pythons using Twisted (this is step 1?). Try it out and hit up http://localhost:8080/random

Why Twisted? Four years ago, Adam heard that @progrium was using Twisted for cool stuff, and now Kathleen uses it for basically everything. If you, dear reader, have a suggestion of something better, I/we would like to hear it (we don't get to talk to web people often!).

Oh, a kitty! (+Mpeg & Jpeg The Cats).

Step 2: You need the thing that does the computation. For me, in my research, this means a new photo gets processed and added to a 3D model, or it a face gets detected in the photo and its features are extracted and it is added to a predictive model. This is the sort of thing I don't want to write in some scripting language (e.g. PHP), I want to use my mathy libraries far away from my web serving logic. I want to be able to launch these jobs on our cluster and not deal with web requests in the same process.

For the purposes of this post (and me making a template for using later), the mathy task is computing a random number and returning it (OpenCV comes later). So, let's look at the code here (again):

Step 3: I have my web server (the python script) running. It listens for normal HTTP requests, but, because we're in Twisted, we can also listen for requests on other wild sockets. Because I know how to do socket programming in C++ (and bash, yo, /dev/tcp), we're gunna go with it. The actual step of step 3 is making this happen: have the C++ dial up the web server.

Our mathy worker is going to function like a client; it'll initiate a connection to the main server. Once connected, the server will know that it can shunt requests for work down to the worker through the connection it made.

The challenge here is speaking sockets in both languages (Python/C++).

Some of the fun trickiness that I discovered, and that Adam help sort out, involved Deferreds in Twisted (event callback thingies, to be precise). Earlier, I had the worker talking to the server, but this was totally separated from the web page serving logic.

In the WorkerManager (a piece in Python), I create a "job" (instance of Deferred) and put it into a queue. When a response comes in from the worker over the socket, I dequeue the oldest job and post a callback on it. This might be different than what you normally think of as an (air quotes) job queue. It's actually just a Python list of things that I enqueued that happened to use a variable name called "job".

If you look at the main server, the way that we use this WorkerManager thing is with "inlineCallbacks". If you haven't seen it before, inlineCallbacks ... Well, without it, writing a lot of chained callback logic in Twisted quickly leads to spaghetti code (Adam notes: node.js folks know what this is like). With inlineCallbacks, the flow of a single function gets logically paused at any "yield" point, waiting to be resumed when a callback is made. This really makes my page serving logic easy to read and write.

If you were writing Twisted without IC, you'd have all these deferreds floating around, getting triggered, getting handled in various way, and this is the crap that I deal with in ActionScript (oh, sick burn), so it's really easy for things to happen out of order. If you want to force things to happen in order, and wait for the event before them to finish, you can use IC to write code in the order you expect it to run with these "yield" statements.

The way I put this all together is... First, I make a Resource (part of Twisted's web framework) to handle requests to certain pages. In the logic for the render method, I use this sort of trick

def render_GET(self, request):
    def _process():
        numbar = yield workerManager.doWork("random")
    return server.NOT_DONE_YET

(I feel weird about putting the decorator on the render method itself, so I apply it to a little internal helper function.)

Some of the logic I want to launch finishes quickly (fast enough that I might want to keep the HTTP connection open until the end), but some other logic is best simply launched and checked via polling other pages. In the case of the little random number generator, we have the page rendering method effectively block until the worker has finished its measly task.

If it didn't matter that I got a response from the worker right away, I wouldn't have used the callback trick in the Resource at all. This is a totally new concept: there are different length of concepts that I want my worker to do. Some of those are fast (say, under a second), and others are minutes to hours. The only thing I want to do with most web requests is to start a job. So maybe the random number example is misleading.

(I'm doing some dishes right now, with pink gloves.)

First, I think this post needs some more pictures, or else nobody is going to read it.

Two, to wrap up, if you ever trigger complicated computation from your web request handlers... rather, if you have previously solved this problem in another way, tell me about it. Tell me how this works for you.

I have a little bit of the Impostor Syndrome where I don't know if I'm doing this Right. So... I'm just going to do it my way until I hear of something better.


(And, with that, Kathleen has cleaned all the dishes except the cast-iron pan.)

dishes and dictation

bloggin' and typin'