Web.py on MacOSX

I’m loving web.py for developing tiny web apps. Here’s how to get it going on a Mac:


sudo port -v install python2.4 py-setuptools mysql5
#coz macports insists on adding a '5' suffix to all mysql5 tools.
sudo ln -s /opt/local/bin/mysql_config5 /opt/local/bin/mysql_config
sudo easy_install web.py cheetah markdown MySQL-python DBUtils

Not the twenty odd steps that’s on the web.py page (that even includes installing and configuring postgresql – bizarre!).

What I love about web.py is that this small bit of code:


#code.py
import web

urls = (
'/', 'index')

class index:
    def GET(self):
        print "Hello, world!"

if __name__ == "__main__": web.run(urls, globals())

… and running python code.py in a terminal gets you a working dev environment. Even camping doesn’t feel this tiny.

Edit: the performance numbers for this simple action are also very impressive:


time httperf --client=0/1 --server=localhost --port=8080 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=10000 --rate=500
httperf --client=0/1 --server=localhost --port=8080 --uri=/ --rate=500 --send-buffer=4096 --recv-buffer=16384 --num-conns=10000 --num-calls=1
Maximum connect burst length: 17

Total: connections 10000 requests 10000 replies 10000 test-duration 20.000 s

Connection rate: 500.0 conn/s (2.0 ms/conn, <=24 concurrent connections)
Connection time [ms]: min 0.1 avg 1.8 max 2987.4 median 0.5 stddev 42.2
Connection time [ms]: connect 0.7
Connection length [replies/conn]: 1.000

Request rate: 500.0 req/s (2.0 ms/req)
Request size [B]: 60.0

Reply rate [replies/s]: min 499.8 avg 500.0 max 500.0 stddev 0.1 (4 samples)
Reply time [ms]: response 1.0 transfer 0.0
Reply size [B]: header 108.0 content 14.0 footer 2.0 (total 124.0)
Reply status: 1xx=0 2xx=10000 3xx=0 4xx=0 5xx=0

CPU time [s]: user 3.75 system 9.17 (user 18.7% system 45.8% total 64.6%)
Net I/O: 88.9 KB/s (0.7*10^6 bps)

Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
httperf --client=0/1 --server=localhost --port=8080 --uri=/ --send-buffer=409  3.75s user 9.17s system 64% cpu 20.028 total

That’s 10K connections and more than 500req/s in a 20 sec timeframe. Really good.

SlideShare Twitter Mashup

So here’s a SlideShare/Twitter Mashup (command-line ruby code) that does these things:

  1. Gets buzzwords from Twitter. It does this by analyzing tweets and getting popular words (filtering out common ones) with the Twitter API.
  2. Gets the most popular buzz word and searches the SlideShare tag database with it (using the SlideShare API).
  3. Prints out the buzzword and the slideshows that’s associated with it.

The source code might not be a great example of filtering and getting popular words, but it’s a good demo of how simple the Twitter and SlideShare APIs are (REST yay) and how easy Hpricot makes parsing XML docs.

There’s a zip (with the source code, common_words.txt, twitter_words.txt) here: slideshare_twitter.zip. Enjoy. 🙂

Tail Recursion

Ponder this:

fact (0) ->
	1;
fact (N) ->
	N * fact (N - 1).

versus this:

fact(N) ->
	fact_helper(N, 1).
fact_helper(1, T) ->
	T;
fact_helper(N, T) ->
	fact_helper(N - 1, T * N).

The advantage of learning Erlang (albeit very slowly, with lots of interruptions) is that it directly introduces a lot of concepts I’ve been marginally aware of before. For instance, the second example implements factorial using tail recursion. The advantage is that a compiler doesn’t have to implement a call-stack when playing with arguments. See wikipedia entry.

Reg. the facebook code leak

Surprise, surprise! Facebook code sucks as much as anything else out there. For people who don’t get the sarcasm, it’s what gets stuffed onto the browser that matters in the end. Having said that, clean aesthetics and a professional layout, a pluggable architecture, and even a PhD. paper doesn’t mean your code is of the Field-Medal caliber. Capish? (Bonus: funny comments).

Adobe AIR: Calculator

If you’ve installed the AIR SDK (and it’s dead easy, just extract and copy it somewhere), you’ve got a lightweight cross-plaform VM to program apps in. Best of all, it works with HTML and Javascript.

In about an hour, I hitched up a calculator application. It’s very easy:

Calculator.xml:

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/air/application/1.0.M4"
	appId="in.vish.Calculator"
	version="1.0">
	<name>Calculator</name>
	<title>Calculator Installer</title>
	<description>Simple Calculator in HTML</description>
	<copyright></copyright>
	<rootContent systemChrome="standard" transparent="false" visible="true">
		Calculator.html
	</rootContent>
</application>

Calculator.html:

<!DOCTYPE html
     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
	<title>Calculator</title>
	<style>
		body, html { margin: 0; padding: 0; }
		body { background-color: black; color: #888; line-height: 1.5em;
			font-family: verdana, arial, sans-serif;
		}
		#wrap { margin: auto; width: 70%; }
		h1 { font-family: Tahoma, Arial, serif; font-size:2em; color: orange; }
		#sum_button { margin-top: 5px; }
	</style>
	<script>
		init = function() {
			runtime.trace("init function called");
		}
		calculate = function() {
			runtime.trace("calculate called!");
			value1 = document.getElementById('val1').value;
			value2 = document.getElementById('val2').value;
			sum_value = parseInt(value1) + parseInt(value2);
			if (isNaN(sum_value)) {
				document.getElementById('result').innerHTML = "You didn't enter valid numbers.";
			} else {
				document.getElementById('result').innerHTML = "The sum is " + sum_value + ".";
			}
		}
		resetForm = function() {
			runtime.trace("resetForm called!");
			document.getElementById('sum').reset();
		}
	</script>
</head>
<body onload="init()">
	<div id="wrap">
		<h1>Calculate a Sum!</h1>
		<form id="sum">
			<label for="val1">Value 1:
				<input type="text" name="val1" id="val1" size="4"/>
			</label>
			<label for="val2">Value 2:
				<input type="text" name="val2" id="val2" size="4"/>
			</label>
			<input type="button" value="Sum!" id="sum_button" onclick="calculate();">
			<input type="button" value="Reset" onclick="resetForm();">
			<p id="result"></p>
		</form>
	</div>
</body>
</html>

And voila, there you have it: a simple calculator:

There’s also a zip file with the code: calculator.zip and the AIR file for installation (to use that you need the AIR runtime)