Saturday, November 29, 2008

Syntax Highlighting In Blogger


I have pulled various tricks in the past to get syntax highlighting in my code samples. In the past I only had highlighting for ruby code. I think I finally have a good solution and it works for any C style language.

Luka Marinko's blog has simple instructions to get this to work. Thanks Luka! Now here is some nonsense code to show what kind of highlighting you get with Java, Python, and Ruby. All the useless imports and requires are just so we can see those kinds of statements getting highlighted.
JAVA

import java.io.*;

class HelloWorld{
public static void main(String[] args) {
hello();
}

public static void hello(){
System.out.println("hello world");
}

}

RUBY

require 'rubygems'
class HelloWorld
def initialize
puts "hello world"
end
end

HelloWorld.new

PYTHON

import sys
class HelloWorld:
def __init__(self):
print "hello world"

HelloWorld()

Unit Test Your Google App Engine Models


I've been working on a project using Google App Engine (GAE) called "les Freres Jacques" That manipulates images of people's face onto the cover of this old french LP. Look for it to be out in a couple months. Anyway, My favorite way to start any project is by doing TDD. Unfortunately I'm new to python and GAE simultaneously so I had to do plenty of research to figure out how to unit test a GAE app. Most importantly for me was the ability to test my models that are based on google's datastore api. What follows is some information to get you started writing unit tests against a GAE model. First, a list of the tools you need to install.
  • Nose is a tool for running your python unit tests.
  • NoseGAE is a plugin for nose that bootstraps the GAE environment.
The easiest way to install these is with python's easy_install, which as far as I can tell is similar to ruby's 'gem' program and perl's 'cpan' program... though I don't know if it resolves dependencies automatically. Anyway, on OSX easy_install is installed by default so you can simply type
sudo easy_install nose
sudo easy_install nosegae
Now let's create a test to exercize a simple GAE model object. Here is a file called test_simple_model.py
import unittest
from google.appengine.api.users import User
from test_example.simple_model import SimpleModel

class TestSimpleModel(unittest.TestCase):
def test_creation(self):
user = User(email = "test@foo.com")
model = SimpleModel(goo_user = user)
model.put()
fetched_model = SimpleModel.all().filter('goo_user =', user).fetch(1)[0]
self.assertEquals(fetched_model.goo_user, user)
The nose tool we installed earlier gives us a program called nosetests to run. When you call it it looks through your project and runs all your tests. We should call it now with the google app engine switch.
nosetests --with-gae
Wheee!! It is a lovely failing test.

======================================================================
ERROR: Failure: ImportError (No module named simple_model)
----------------------------------------------------------------------
Traceback (most recent call last):
...
from test_example.simple_model import SimpleModel
ImportError: No module named simple_model

----------------------------------------------------------------------
Ran 1 test in 0.002s

FAILED (errors=1)
Good. Now we need to write some code to get our test passing. Here is what I wrote in a file called simple_model.py.
from google.appengine.ext import db
class SimpleModel(db.Model):
goo_user = db.UserProperty()
Now when I run
nosetests --with-gae
I get the lovely
.
----------------------------------------------------------------------
Ran 1 test in 0.008s

OK
and I am happy because I see how I can do TDD with GAE! Here is a list of references I used to figure this stuff out. Hope you find them useful. You can find the full source of this example here.
Update: 11/30/08
The datastore persists between tests which isn't usually what I want to happen. I submitted an issue on the nose-gae issue tracker. In the meantime here is a workaround to make sure the datastore is flushed between runs. Add this method to your test class and call it in your setUp method.

from google.appengine.api import apiproxy_stub_map
from google.appengine.api import datastore_file_stub

def clear_datastore(self):
# Use a fresh stub datastore.
apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()
stub = datastore_file_stub.DatastoreFileStub('appid', '/dev/null', '/dev/null')
apiproxy_stub_map.apiproxy.RegisterStub('datastore_v3', stub)
Update: 1/29/09
Reading Dom's well researched and documented post on testing App Engine applications. I thought I better spruce up my own post by adding a citation. The code from the clear_datastore method above comes from this message posted on the google app engine google groups mailing list.
Update: 5/17/09
There is currently an issue with nosegae. See defect 18. There are patches that fix the issue posted there. I downloaded the source code, removed the subversion directories, patched the code and ran
easy_install .
in the root directory of the code. That fixed the issue for me.
Update: 5/17/09
As of GAE SDK 1.2.1 the appid of your datastore stub must match your appID. Make sure your call to DatastoreFileStub uses your actual app id.

Tuesday, November 25, 2008

Deep Clean Your Subversion Working Copy


awk and xargs. Deep cleaning action for those hard to reach places. Sometimes you just want your subversion working copy to be clean. If you have files with changes you can just revert things, but what about files that aren't under version control? Those are harder to clean up, especially if they are spread all over the place. Here is what I do when I want my working copy to be identical to the repo:
svn st | awk '{print $2}' | xargs rm -rf
That will remove all files that are out of sync with the repository. Then simply update to restore things you deleted and get up to date.
svn up

Access Google App Engine Development Server Remotely


By default Google AppEngine's (GAE) development webserver doesn't accept remote requests. If you'd like to make your devel GAE application available remotely you can use a simple proxy to forward requests. I chose to use pen proxy because it is sooooo simple. To install pen on ubuntu do
sudo apt-get install pen
to do it on OSX with macports do
sudo port install pen
Once it is installed startup your GAE application. Then start up pen like this:
pen 8079 localhost:8080
Now pen will forward requests from port 8079 to your app running at 8080.

Monday, November 24, 2008

A Software Journeyman


For the past year or two I have been hearing the words 'software' and 'craftsmanship' used together more and more frequently. Uncle Bob has been talking about it for most of a decade (click the craftsman link). So today when I heard about Corey Haines' pair programming tour I decided these two things must be connected. Corey is traveling through Ohio, Michigan, Illinois and Indiana. Every place he stops he is going to meet different software craftsmen and pair with them. He is a true Journeyman software craftsman. Wikipedia has this to say about Journeymen craftsmen.
In parts of Europe, as in later medieval Germany, spending time as a journeyman (Geselle), moving from one town to another to gain experience of different workshops, was an important part of the training of an aspirant master. Carpenters in Germany have retained the tradition of traveling journeymen until today, although only a small minority still practice it.
Very cool! If you want a chance to hear from aspirant master craftsman, Corey Haines, he will be talking about his travels as a Journeyman programmer and his chain of command gem at the December meeting of the Chicago Ruby User Group. Details are here.

Friday, November 21, 2008

ChiPy Meeting at ThoughtWorks

The December Chicago Python User Group will be hosted at ThoughtWorks! This will be the best meeting of any kind, ever. Be there! Meeting and RSVP details to follow. Oh, and if the flyer doesn't make sense to you, I usually help out with the Chirb meetings at our office and I couldn't help doing a sort of mashup with a reference to _why's foxes. See! Ruby and Python can co-exist at ThoughtWorks. Hope you like the flyer. I made it with inkscape.

Fine Print:
My loving imitation of _why's foxes appear courtesy of the CC license of the original work.
Creative Commons License
Therefore this work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.

Saturday, November 15, 2008

Update Bash History in Realtime


I have long been annoyed by the behavior of Bash's history file. If you use multiple terminals all history is lost except that of the last terminal closed. The correct behavior should be to save all history from all terminals! An easy way to make that happen is just to save commands to the history file in realtime. Thanks to the Linux Commando I know how to make this happen. Here is the secret:
shopt -s histappend
PROMPT_COMMAND="history -a;$PROMPT_COMMAND"
Put those lines in your bash_profile or bashrc. The first line tells bash to append to the history instead of completely overwriting. The second line calls history -a every time the prompt is shown, which essentially appends the last command to the history file. So simple. I wish I had known this years ago!