Wednesday, April 30, 2008

Good Frameworks: Priceless

I think I sometimes under-appreciate all the things that an environment like the App Engine does on my behalf. Like many other people, I am quite focused on "commercial" application development and tend to forget all the hobbyists out there and what opportunities this system opens up. So I thought, I'd give a small example that deals a bit more with that aspect.

Suppose one has a personal web page and would like to display a nice little quote that changes on a regular basis. There are a few web sites out there that are wrapping the "fortune command", so all we would need is a little program that
  • connects to the site and downloads a "fortune"
  • scrapes the html and extracts the fortune text
  • embeds the result in our page
The following Java code (using NanoHTTPD as a web server) accomplishes that goal:


import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;

class Fortune extends NanoHTTPD {

private static URL FORTUNE_URL;
{
try {
FORTUNE_URL = new URL("http://www.coe.neu.edu/cgi-bin/fortune");
} catch (MalformedURLException e) {
e.printStackTrace();
System.exit(1);
}
}

Fortune() throws IOException {
super(80);
}

@Override
public NanoHTTPD.Response serve(
String uri, String method, Properties header, Properties parms ) {

// Connect to fortune website
StringBuilder sb = new StringBuilder();
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(FORTUNE_URL.openStream()));
for(String s = in.readLine(); s != null; s = in.readLine()) {
sb.append(s);
sb.append("\n");
}
}
catch (MalformedURLException e) {}
catch (IOException e) {}
finally {
if (in != null) {
try {
in.close();
} catch(Exception e){}
}
}

// Extract the Fortune
String fortune = "No fortune today :-(";
Pattern p = Pattern.compile(".*<pre>(.*)</pre>.*", Pattern.DOTALL);
Matcher m = p.matcher(sb.toString());
if (m.matches()) {
fortune = m.group(1);
}

// Build the response
String html =
"Your fortune:<pre>" +
fortune +
"</pre>";
return new NanoHTTPD.Response("200 OK", "text/html", html);
}

public static void main(String[] args) {
try {
System.out.println("Press ENTER to stop");
NanoHTTPD nh = new Fortune();
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
}


Does this code its job? Sure! Is it ideal? Certainly not!
  • Exceptions are not logged in a proper way. If there is a bug in production, it will be very hard to analyse.
  • For the little functionality we have, the code feels a little bloated.
  • The Web Server used is not necessarily built for scale. We have no idea how it will behave it it gets hit by many users. We could use a different web server (apache, jetty...), but that would require additional libraries and setup effort.
  • We will have to find a hosting provider that will let us run this application.
Now let's do the same service app engine style:


APP.YAML:
=========
application: fortune
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
script: fortune.py


FORTUNE.PY:
===========
from google.appengine.api import urlfetch
import re

def GetFortune(maxtries=3):
"""Connects to an online fortune site and extracts a fortune to display."""
fortune = None
for i in range(maxtries):
result = None
try:
result = urlfetch.Fetch('http://www.coe.neu.edu/cgi-bin/fortune')
except:
result = None
if result and result.content:
match = re.compile('.*<pre>(.*)</pre>.*', re.DOTALL).match(
str(result.content))
if match:
fortune = match.group(1)
break
if not fortune:
fortune = 'No fortune today :-('
return fortune

print 'Content-Type: text/html'
print ''
print '<html><body>Your fortune:<p/><pre>%s</pre></body></html>'\
% GetFortune()


So, how does this implementation compare to the previous one?
  • If something goes wrong in production, we will be able to see it in the application dashboard. The Dashboard even collects logs and statistics on what kind of requests fail most often for us.
  • Very little overhead; easy to read code.
  • Serving the pages is done by the App Engine for us. If many people hit the app, the serving environment will automatically assign more resources and help us scale.
  • We will not have to find a hosting provider that will let us run the application for us. Even better: for such a small scale app, hosting will probably be within the free quota!
Now, before anyone thinks about starting a flame war: this is not Python versus Java. I am sure that if App Engine would be supporting that other language, the resulting code would get considerably shorter! What it does show however is how a stack that is well designed can make it so much easier for people out there to put something together quickly and make it available. Just give it a try when writing that signup page for your bike relay -- or any other small tool that would otherwise be too much work to make available.

Saturday, April 26, 2008

Unique data, part 2

As a follow-up from my post earlier today, here is an example how to store and transactionally update globally unique values. Using the KeyVal class, keeping an updated count of something (like posts to a forum) could look something like this:


KeyVal.Get('count', 0, lambda x: x+1)


Retrieving the value without updating it (but having a default value in case it does not exist) would be the same method call, just without the lambda function:


KeyVal.Get('count', 0)


Without further ado, here is the class:


class KeyVal(db.Expando):
"""A simple model that stores a value under a key."""
key_value = db.StringProperty(required=True) # for GQL queries later on

@staticmethod
def Get(key, default=None, mutator=None):
"""Gets a value from the database and returns it.
If a mutator-function is given, it will execute it and store the
new value.
"""
if not key:
raise 'Key must not be null'
data = KeyVal.get_by_key_name(key)
if not data:
data = KeyVal.get_or_insert(key, value=default, key_value=key)
if not mutator:
return getattr(data, 'value', default)
def modify():
data = KeyVal.get_by_key_name(key)
value = mutator(getattr(data, 'value', default))
data.value = value
data.put()
return value
return db.run_in_transaction(modify)

Saving user-specific data

There are a couple of discussion threads on the app engine forum on how to enforce a uniqueness constraint on certain data. One example was how to store user settings and to make sure that they only exist once for every user. I would like to suggest a way of doing so for this particular case. If there is a better one, please let me know.

Assume we have a set of data for a user of a particular category (think settings, statistics, history...). The best way I currently know of to store a unique model is to build a primary key from whatever makes the object unique. In case of a user and a category, this could look something like this:


key_name = '%s||%s' % (user.email(), category)


In case of a user however, there is a small problem: the email address could change! This is not something that happens very often, but it is not unheard of (especially if the application is not build for gmail accounts but google apps for your domain). Think of someone changing his or her last name after a marriage or divorce. While the user object itself would stay the same (and could be used for GQL queries), a primary key built from the email would no longer return the right object.

The code at the end of this post tries to account for this situation. It creates an expando-model that is able to load and modify instances regardless of email changes. It also provides two helper-methods, Load() and Modify() to easily access the data and create an instance if it does not exist. For example, maintaining a count of how often a user has requested a particular page could be as easy as:


def modify(x):
x.count = getattr(x, 'count', 0) + 1
updated_stats = UserData.Modify(modify, 'stats')


The lookup or creation of an object is a three step process (see the Load() method in the example):
  1. lookup the object by its "standard"-primary key as described above
  2. if the object cannot be found, make a gql-query with the user object (to accomodate for changes in the email address)
  3. if nothing was found, create a new user object under the standard primary key (using get_or_create to prevent last-minute conflicts)
Attached the sample implementation. Let me know if I forgot anything:



from google.appengine.api import users
from google.appengine.ext import db


"""Persistence of user-specific data."""


class UserData(db.Expando):
"""An Expando-Model that can store an arbitrary set of data entries
for a given user. The only two required parameters are the
user object and a categorization of the data being stored
(such as "settings"). This class uses the primary key to create
a uniqueness-constraint within a user and a category, so it is
required that one uses the Load or Modify methods defined in
this class to persist new models. Afterwards, the normal rules
(using put(), run_in_transaction() and so on apply)
"""
user = db.UserProperty(required=True)
category = db.StringProperty(required=True)

@staticmethod
def Load(category='None', user=None):
"""Gets user-data in a specific category (such as "settings")
from the database. If no user-specific data exists yet, a new
unique entry will be created.
"""

# If no user is given, get the user that is currently logged in.
# If nobody is logged in, return None
if not user:
user = users.GetCurrentUser()
if not user:
return None

# In most cases, we can just do a lookup by key
key_name = '%s||%s' % (user.email(), category)
data = UserData.get_by_key_name(key_name)
if data:
return data

# That didn't work -- let's do a gql query, just in case the user's
# email address changed but we can find it by object
data = UserData.gql('WHERE user=:1 AND category=:2',
user, category).get()
if data:
return data

# Ok, so there is nothing in the database yet. We assume that we can
# create a new entry, using the key from above. In theory, there is a
# slim chance of creating a duplicate object (if the user's email
# address changes the very second we create that entry and a
# parallel request creates a new entry with the same user), but that's
# a chance we are willing to take.
data = UserData.get_or_insert(key_name,
user=user, category=category)
return data


@staticmethod
def Modify(logic, category='None', user=None):
"""Looks up user data, makes changes to it in a transaction and then
returns the object. Logic should be a function taking the object as
a parameter.
"""

# Can we retrieve the object from the database>
data = UserData.Load(category, user)
if not data:
return None
key = data.key().name()
if not key:
raise 'Programming error: cannot lookup key'

# Now, switch to transaction mode
def modify():
data = UserData.get_by_key_name(key)
logic(data)
data.put()
return data
return db.run_in_transaction(modify)

Tuesday, April 22, 2008

The other ten percent?

Ninety percent of everything is crap
I started this blog about two weeks ago with a simple question: can the release of something like the Google App Engine really turn the kid next door into a millionaire and put all us hard working developers out of business? Since then, I have looked into many different areas, trying to find the perfect opportunity for a (legal) get-rich-quick scheme. So far, I have yet to hit the Jackpot ;-) I wonder if others are more successful?

It is amazing to witness some of the applications that people have been able to push out in such a short period of time. While Sturgeon's law certainly applies (seriously -- how many hello-world-apps can a single human click on?), the range of innovation goes all along the spectrum, from a little site called Fug This! to truly sensational mashups like Multitube. The first impressions from my end so far are:
  • The simpler the app, the more frequently it will be cloned. And cloned again. And again. Think of all the services out there somewhat inspired by tinyurl, such as GURL, Hex!o or even my own shortlinker.
  • Does the revolution devour its own children? What came first -- the chicken or the egg? Should I use Latrz as a notepad for URLs, or should I rather use Readbag instead?
  • Chatrooms are neither rocket science nor unique -- just look at YouTalk, another amazing chat implementation.
Having looked at the apps out there, I start to wonder whether anyone out there is building his or her app in anticipation of profit, though. Has anyone built a site yet that has the potential for commercial success? The best thing I've seen so far in that respect is MySocial 24x7. What have I missed? Is a few weeks after the App Engine's phenomenal launch simply not enough time? Please post your opinions, preferably with a link to a great App Engine App...

Monday, April 21, 2008

Free Webhosting, Google App Engine style

A week ago, I discussed ways of getting more usage out of the three applications one may create in the trial period. What if the opposite is true, however? What if one has a perfectly good application id left but no idea what to use it for? Well, why not running your static webpage from it? After all, it's free :-)

The smallest app ever

The following app.yaml is a complete App Engine application. Just drop your entire webpage into a subfolder called "static", and it will be served:
application: mysite
version: 1
runtime: python
api_version: 1

handlers:
- url: /(.*)
static_files: static/\1
upload: static/(.*)

What does it do? Well, the regular expression "/(.*)" stands for "every request coming in." The following line instructs the application to look for a static file with the same name in the "static" subfolder. Last but not least, we also tell the application to upload that entire folder as static content into the application.

In other words, for the simplest of all cases, we can turn our webpage into an App Engine application with just a little bit of configuration magic. But wait, there is more:

Leveraging Templates

A lot of App Engine users these days seem to be requesting PHP. There certainly are many good reasons for that, but I kindof wonder if some purposes PHP is used for cannot be easily handled with Django templates. If, for instance, you happen to use PHP simply as a way to not having to copy and paste the same header and footer each and every time, App Engine is the right tool for you.
Take a look at Training Wheels. This site is a simple extension of the app.yaml shown above that serves pages in a slightly more sophisticated manner:
  • requests that do not end with "django" or "djhtml" are served as static content
  • "django/djhtml"-requests are considered Django templates that should be executed
In other words, without having to write a single line of python, one can use the richness of Django templates to stub out common things like headers and footers and have them behave the same way in all web pages. For more details on how it's done, check out the downloads-section of the app.

Serving big files

Right now, there are limitations on the file size an App Engine application may serve. However, it might make sense to outsource certain bigger files to another place, such as Google Sites. The reason for that is simple: quota. Assume that you have a bigger download (like a giant pdf file) that gets accessed many times a day. Why should that have to come out of your quota? Simply create a "file bin" in sites, upload your files there and have them also hosted for free. See this example downloads section built on sites.

Conclusion

An application is a terrible thing to waste. So is free stuff ;-). So, if you are one of the lucky few with an app to spare, consider migrating your homepage. Not only might it save you a few bucks a year, you also can extend it over time with all kinds of dynamic content, based on Google App Engine.

Friday, April 18, 2008

AppEngine and Encryption

One of the more requested features of the AppEngine is SSL support. While I have no doubt that this will get resolved over time, I wonder if there aren't ways to make data secure even in the current version? At least in the Web 2.0 ages, I believe there might be.

Imagine we start building a new web app from scratch. Most static pieces of the application do not really require encryption (html, company logo, css...). Let us also assume that we are not afraid of Javascript and can exchange all sensitive information through XmlHttpRequests. What prevents us from encrypting that data before sending it out? All we need is for client and server to negotiate an encryption method.

Ingredients needed:
(I have not tested any of these components, so there might be better ones out there).

Imagine the server runs on AppEngine and that we uploaded a key of public/private keys with the app. What would prevent us from doing the following:
  • put the public key into one of the Javascript files that is downloaded as part of the application. This way, the Javascript client is able to encrypt data in a way only the server can read.
  • upon initialization, the Javascript client creates a random key for AES encryption. It encrypts that data using the public key and stores it in a cookie.
  • we create out own version of an XmlHttpRequest that encrypts all data before sending it out using AES
  • the server gets the encrypted data, extracts the key from the encrypted cookie, and uses it to decrypt the data
  • when the server needs to send any data in return, it uses the very key it got from the client to encrypt the response
I have not tried this, so have no idea what impact this would have on my quota (encyrption/decryption in pure python might be expensive). I also do not know how performant AES would be on the client side. I currently have no need for that kind of security in my apps, so it's not worth the effort finding out. Still, if anyone else happens to have played with it, let me know :-)

Tuesday, April 15, 2008

Multiplexing and Namespaces: Running multiple apps on one App Engine instance

An application is a terrible thing to waste. Since we are currently in the preview period of App Engine, I can only create three instances to host my code. When I recently looked at my Dashboard, I realized that my URL Shortlinker was hardly using up any of the quota. This happened for three reasons that I am sure apply to many other people out there, as well:
  • it was not particularly popular (low amount of shortcuts)
  • it was optimized for performance (as far as I knew how to do that)
  • it was a simple application that did not need much resources to begin with
Now, there are certainly some apps out there that have to worry about running out of quota, but I'd like to bet that for many others (like me), the opposite is true. So, if one has a couple of apps that do not use a lot of space, what is the best way to put them to work?

One possibility to utilize ones resources would be to run several applications on the same instance. You have a shortlinker, a guestbook, a site counter and a random fortune generator? Mix them all together, call them "site tools" and run them as one App Engine app. Unfortunately, the merge process can become a little complicated (what if the apps use Model classes or scripts with the same name but different content?), so this can be a little bit tougher to achieve. I am convinced one could do a little python-magic to have each individual app in a sub-directory of its own and let one root script dispatch the calls, but that's a little bit beyond my skills for now (more on this idea further down below).

A second trick would be to abuse the major versions. I could upload two different applications to the same application id, one with major version "1" and the other with major version "2". Both should be reachable in parallel, so as long as I keep the names of the data objects separate, I should be good to go.

Example:
The following is the code for a very simple Link scrubber:
import wsgiref.handlers

from google.appengine.ext import webapp

class MainPage(webapp.RequestHandler):
def get(self):
if self.request.get('url'):
self.redirect(self.request.get('url'))
return
self.response.out.write('Link scrubber')

def main():
application = webapp.WSGIApplication([('/.*', MainPage)], debug=True)
wsgiref.handlers.CGIHandler().run(application)

if __name__ == "__main__":
main()

You can try it out by going to http://2.2.aef.appspot.com/ -- which is the very same application (aef) that I am using to host my URL shortlinker. The shortlinker just happens to be version 1 of the program and the redirector (although a completely different program) is defined as version 2.

While this is certainly feasible, I do not necessarily recommend this approach. Major versions are there for a good reason, and a little short-term gain here might turn out to become a headache later if any of these apps becomes very popular. With every bugfix for the redirector I upload, the minor version is going to change. I cannot bind an external Google Apps domain to it. In other words, the limitations are rather severe.


The third options is something that can often be done with very little code changes and can open up an application to more users: while it is not that easy to run several applications on one instance, it is possible to run the same application multiple times by using the domain as a namespace.

One single App Engine application can be bound to an arbitrary amount of domains. Within the application, a simple call to os.environ['SERVER_NAME'] will reveal what namespace we are currently working in. If we are smart about partitioning our data space accordingly, we can run a single service that will seem unique to each of our users.

Let's take a concrete example: download the simple wiki example from code.google.com. It is actually a very nice wiki, but it does not have separate namespaces. Assumed we had three different products (shortcuts, redirector, webhosting) and wanted to build a wiki for each of them on appengine, our three app-ids would be gone. Or would they?

If you take a look at the main script, wiki.py, you will see that there are actually only two places where data is loaded from the database or written to the database:

def save(self):
...
entity['name'] = self.name
...
datastore.Put(entity)

def load(name):
...
query = datastore.Query('Page')
query['name ='] = name
entities = query.Get(1)


Let's ignore for now that the developer is using a slightly different API than models and GQL. What we see is that the code uses the "name" of a wiki-entry as a unique key for loading and storing data in the store. By simply putting our domain name into the code, we can create a distinct namespace for as many wikis as we like, provided that we bind them under different URLs:

import os
def GetDomain():
return os.environ['SERVER_NAME']

...

def save(self):
...
entity['name'] = GetDomain() + "|" +self.name # CHANGED
...
datastore.Put(entity)

def load(name):
...
query = datastore.Query('Page')
query['name ='] = GetDomain() + "|" + name # CHANGED
entities = query.Get(1)

With very little modifications, we now have an application that can be used by many people in parallel without the need to upload multiple instances. Our utilisation of that single instance simply went through the roof. This will also work if the code is slightly more complicated, as seen in this example. However, the higher the level of complexity for a particular app is, the higher the chance to mess up these kind of modifications.

Conclusion:

Even without any code modifications, it is possible to use one application id to run multiple applications in parallel. Using the domain as a namespace, it is also possible to partition a database to have the same app host distinct data for each user. Both are methods to increase utilization of one's app, but both are rather crude. I believe there is a better way, but I do not know the codebase well enough yet to be sure. Here is what makes me think there is:
  • the wiki in this example uses a simpler persistence api (datastore), and it looks like both GQL and the Model class are using that internally, too (just look into __init__.py in the google/appengine/ext/db-folder of your SDK). Depending on how the higher-level classes are using the lower-level datastore, one might be able to monkeypatch it to separate by domain or sub-application automatically. If that is true, there would be no namespace conflicts in the datastore for running separate apps on the same instance.
  • the SDK is written in python. At some point, there is an entry-level class that, depending on the content of the app.yaml, decides which of an application's scripts to execute. If that code could be generalized, one could have a set of applications, each in a subdirectory, with a simple top-level script that just makes the decision which subfolder's app.yaml to use.
Depending on how long the preview period of App Engine will take, it might be worth investigating this further. If anyone has looked into this already, please let me know.

Monday, April 14, 2008

Beginner's pain

What a hot summer weekend, just in the middle of April :-) While I was out on a little walk to along the Santa Clara streets, I thought about my next blog entry. Should I talk a little about the "making of" my current app? How I solved problems xyz for my specific use case? What I liked about the datastore and what caused me chagrin?

Truth be told, there are so many people writing about this stuff right now that this seems pretty much like a waste of bandwidth to me. So let me just point out a couple of interesting things I found:

Google Datastore and the shift from a RDBMS:
An excellent article on working around the differences from SQL and how to manage sessions.

Pagination snippets:
A thread on the App Engine forum about how to build pagination into your app. Quite similar to some techniques I used for the tables in my shortlinker.

Google AppEngine - A Second Look:
Great meta-article that distills a lot of different threads and topics in one post.
Less technical but a great summary on what's currently going on in both blogs and the forum

Appengine-Monkey:
An article that describes how this new opensource project tries to make the appengine feel more "standard python" and how that made it possible to get Pylons working.



Any great recent article I forgot? Post it as a comment and let me know...

Sunday, April 13, 2008

Getting Started

Note: My first app is out at aef.appspot.com :-) . It is a URL shortlinker that can be tied into any domain. This is not the app I mentioned in a previous post -- I still have no idea what would be the best thing to build. It will take a little while for this blog to catch up on the "making of", but I'll do my best to type fast...

The first step is always the hardest: getting started. In my case, this meant to set up everything I needed to develop my first app and eventually push it out:

Getting a domain


Good news: that was actually not halfway bad :-) I went to the signup page for Google Apps and chose the Standard Edition. Google has an option that lets me buy my domain name directly through them. This has a couple of great advantages: since the company can directly interface to their DNS partners, my domain came preconfigured, out of the box with working email. Sounds convenient? It gets even better: since I intend to leverage some of the applications that come with standard edition, I know that I won't have to bother with setting up too many A records or CNAMEs when it comes to mapping my web page. I know that Google will do it for me.

Creating some content


Rome was not built in a day, and creating an attractive website that makes people want to spend there as much time as possible is no easy feat. I am no web designer, and creating all that HTML code is a nuisance!
Turns out I am once again in luck: Google has three products that take the hurt out of html:
  • Google Sites is a service that lets me create sophisticated web WYSIWYG-style and serves them for me. I will use this for all my help pages and images; this way, serving static content does not come out of my application's quota. Sites also comes with a set of professionally-looking templates that take care of the overall layout for me.
  • Google Page Creator is a second tool with a similar purpose, just a little bit less sophisticated. It has one great advantage though: I can easily configure my Google Apps domain to serve my web root (www.appenginefan.com) from there.
  • Blogger, to create this very site. Setting up blogger was easy; except for getting my page served at blog.appenginefan.com (that required a few manual steps).
So, the first thing I did was putting a couple of pages together. Signing up for AdSenseGetting an account can take a little bit, so I tried to be proactive: I filled out the form as early as possible, so that I would have everything ready once my site would go live.

Installing the SDK

As mentioned in my previous post, there were a few tools I needed to install. Well, or so I thought. It turned out that, besides Jedit and the Google App Engine SDK, everything else was already on my Ubuntu machine. Installing the SDK was just a matter of unzipping it into a folder of my choice and dropping a couple of aliases into my bash-configuration (not really necessary, but who always wants to type python ~/google_appengine/dev_appserver.py my_app/ ? Certainly not me!)

Speaking of aliases -- my first application is a URL shortlinker that can be tied into any domain. My next post will talk a little bit more about getting it implemented and out into the cloud.

Thursday, April 10, 2008

The App Engine Bet

Get rich quickly, no money down?

Unless you have been living under a rock for the last couple of days, you will probably have heard about Google App Engine. Its launch sparked a lot of discussion: is it the greatest thing since sliced bread, or just another lame hosting platform? The first couple of days created a lot of controversy, like any great and revolutionary idea will.

One of the many comments sparked my interest. In this article referencing the HuddleChat situation, the author writes:

Like Campfire, any Web 2.0 app can be easily replicated by a developer(s) in his/her spare time.

Any app? Really? Another post on a different discussion thread takes it even further: to paraphrase, this person claimed that with all this free technology out there, a student with too much free time on his hands could simply go out, rip off established web applications, and thus render us hard working developers completely useless ;-)

That got me thinking -- how big of a threat would this platform really be? Obviously, there are very gifted youngsters out there. Heck, I recently witnessed an incredibly well done Google talk by a twelve year old. So, could this unknown poster really be on to something?


That's when I decided to do a little experiment: I wanted to build a hosted business from the ground up with little or no money at all. I will use whatever is available, as long as it is legal and ethically sound, but I will not spend any money on it, unless an average high-school kid could do the same thing. I will track all my expenses and all money I make from this site and publish it openly. I will accept advice from others on monetization and how to make the business work, but I will not use any resources an average kid would not have access to. Can I make this work and turn a nice profit? I guess we'll find out...

The game begins

Let me first start with a disclaimer: I am not a student any more. I work as a software engineer for Google. I have not been part of the core team that brought you App Engine, but I have worked with them and am familiar with the APIs. So, how can I do this experiment as realistically as possible? Let's talk about the rules.

Rule #1: The job comes first!

I love working at Google. I will do nothing to jeopardize my work or bring me into an ethically difficult situation. In particular, this means

  • I will not work on this experiment on the job. I will also not use company resources to get things done.
  • I will not use insider information to make this a better site or to make the programs on this site work better.
  • If my employer thinks an app created by me creates a conflict of interest, I will take it down. No questions asked. This is not a matter of censorship or oppression, it is simply being professional. Google is providing me with an environment in which I can grow personally and professionally; and I would be an ungrateful bastard to do anything that hurts the company goals!
How does this translate into "student/highschool kid" terms? Well, there is classes, homework, chores, SAT, extracurricular stuff, earning extra money at a fast food chain. Just because those guys do not work full time for money does not mean they have nothing to do but writing code.

Rule #2: No fancy equipment

Kids these days have a lot of stuff. The days of my good ole Atari 600 XL are definitely over for good. Why having to choose between a Wii and an Xbox if Junior can have both?
All ranting aside, defining what equipment to permit was actually a difficult task. Here is what I settled for:

  • An almost four year old Dell Laptop with a weak Celeron Processor, 768M of main memory and Linux Operating system
  • A monitor that can do roughly 1400x900 resolution
  • A second computer that has Internet Explorer on it (not used for development but for testing browser compatibility; in real life, the kid could always ask a friend)
  • A 35 Dollar hp printer from Wal-Mart
  • Internet connectivity (DSL, smallest tier)
It seemed fair to assume that someone who wanted to develop software for the Internet would have access to these kind of things, be it through school, parents or personal possession (many kids have even better, since it doesn't play the latest video games). Anything beyond that however would be a pure luxury that I do not want to take for granted.

Rule #3: Free Software rules!

I am not opposed to paying money for good software, but for this experiment, I am just a kid on pocket allowance. Software Piracy is not an option, so I will stick to things that I can either use online or on my little machine. My starting equipment is:

Wow -- come to think of it, there really is such a thing as a free lunch, isn't it?

Rule #4: My only equity is sweat equity

In the real world employees cost money. Good employees often cost even more money. Heck, I sure as hell couldn't afford myself ;-) Good thing we do not live in the real world here.
The great thing about being a college geek with a computer is that there is time. One's regular occupation (being a student or living at home with Mom and Dad) pays the bills, and there is no mortage to worry about or alimony payments. So, for the sake of this experiment, it is assumed that I can sink as much time into software development as I want. It does not cost me a single cent, so I do not need to account for it on this page. In return, I will not account for time spent as accrued equity; there is no such thing creative accounting. Which brings me to my final rule:

Rule #5: There is no such thing as virtual money

Unless I put the check into my bank account, I will not count any earnings I make. By the same reasoning, I will not count any expense until I actually spend the money. When I do spend the money however, it will immediately be reflected on my balance sheet. In other words, I am accounting on a cash basis.

My business plan? Don't be like the Underpants Gnomes!


The good thing about being in the "kid - from - next - door - builds - super - app - and - becomes - overnight - millionaire" business is that we are not going out for venture capital. So far, our investment has only been 10 bucks for the domain, which would roughly be the equivalent of mowing our neighbor's lawn once. We can be a little bit sloppy about the specifics of how to make money (hey -- if I believed that this would actually become profitable, I wouldn't need to do the experiment!). Then again -- do I really want to be like the gnomes from South Park and just expect the money to magically flow in? Shouldn't I at least have a basic plan?

Since this whole site heavily relies on Google technology, we might as well take a page out of their book: Focus on the user and all else will follow. In other words, we will focus on providing a site that a lot of users are going to be interested in and hope that we can monetize that well. So what does this mean in detail?
  1. First, we will build up a site. We will provide free applications and content that people will want to use.
  2. We will connect our site to AdSense and place advertisement at strategic places.
  3. We hope that within our quota enough people will click on the adds that we create a stream of income.
Why using ads? Well, first of all, I am lazy ;-) Second however, think about it: what young software builder without significant capital will have the time to walk around and sell paid subscriptions or services to people out there? Where does the marketing budget come from? Who pays the sales commissions? We might need to revisit this approach in the future, but for now it's the easiest way to get us started.

So, what's next?

Well, I guess I am going to spend the weekend setting up my site, putting an application together and bringing it live. Revisit this blog in a couple of days to see how it is going...