Hello, my name is Joshua Inkenbrandt and I live in Kansas City, Missouri with my wife and two kids. I'm a Mac guy. I'm a Python guy.

My goal is to make cool stuff that's fun and easy to use.

Only showing Posts with tag python X

June 24, 2010

Tornado Tip

I actually discovered this nice little feature when I was up working late one night. When you pass a dictionary into self.write(), it will automatically be JSON encoded and will set the Content-Type header for you.

import tornado.web
import tornado.escape

# Long version
class HelloWorldHandler(tornado.web.RequestHandler):
    def get(self):
        response = dict(error=False, message="Hello World")
        self.set_header('Content-Type', 'text/javascript')
        self.write(tornado.escape.json_encode(response))

# Short version
class HelloWorldHandler(tornado.web.RequestHandler):
    def get(self):
        response = dict(error=False, message="Hello World")
        self.write(response)

April 12, 2010

Tornado's Templates

Tornado is awesome — its documentation at this point isn't. So here's my little contribution to make a great web framework a little easier to develop in.

First things first, Tornado's templates aren't sandboxed like Django's. Meaning it converts your templates into Python code and then executes them with a given context. And there's a benefit in rendering templates as evaluated Python code. Speed. Aside from being fast, I've personally found Tornado's templating syntax to be much easier to write in than Django's, though they are very similar.

But there's also a downside. Templates in Tornado make it possible to do almost anything, including accessing your database, deleting your files, terminating your webserver's instance, etc. These things can actually can be done in Django if you use a custom filter or tag, but straight out of the box, Django protects you from your templates. So a redundant and some-what-obvious word of warning: use discretion when writing your templates in Tornado.

Basic Output

1 Hello, {{ current_user.name }}

Basic Logic

 1 {% if not current_user %}
 2     You're not logged in!
 3 {% elif current_user and curent_user.is_admin %}
 4     Good day, sir!
 5 {% else %}
 6     Howdy!
 7 {% end %}
 8 
 9 {% for link in links %}
10     <a href="{{ link.href }}">{{ link.title }}</a>
11 {% end %}
12 
13 {% set i = 10 %}
14 {% while i %}
15     Item {{ i }}
16     {% set i -= 1 %}
17 {% end %}
18 
19 {% try %}
20     {{ undeclared_var }}
21 {% except NameError, e %}
22     {{ e }}
23 {% end %}

Inheritance

 1 <!-- base.html Template -->
 2 <body>
 3     <div id="main">
 4     {% block main %}
 5         You'll see me if the 'main' block isn't overridden
 6     {% end %}
 7 </body>
 8 
 9 <!-- home.html Template -->
10 {% extends "base.html" %}
11 {% block main %}
12     Now you see me!
13 {% end %}

Comments

1 {% comment "I'm a comment" %}

Includes

1 {% include "other_template.html" %}

Imports

1 {% import os %}
2 {% import sys %}

Setting Variables

1 {% set DEBUG = True %}
2 {% set BASEPATH = os.getcwd() %}

Applying a function to a block

1 {% apply escape %}
2 <h1>Hello World</h1>
3 {% end %}
4 output:  <h1>Hello World</h1>
5 
6 {% apply base64.b64encode %}
7 Base64 Encode Me!
8 {% end %}
9 output: CkJhc2U2NCBFbmNvZGUgTWUhCg==

Caveats

Because the templates are executed as Python code, they follow the same explicit rules as Python. For instance, if you try to access a variable that doesn't exist in scope {{ myvar }} , you'll get a NameError. If you're used to using Django or Jinja, this might throw you off. Also note that every closing block tag is always just {% end %} .

There's a lot more you can do with templates when they're integrated with Tornado's tornado.web.RequestHandler. I would recommend, if you haven't already, giving Tornado a try. It's a perfect combination of simplicity and power.

March 22, 2010

Life Expressed in Language

All code in Python.


class Death(exception):
    pass

# Simple function that sums it all up

def work(life):
    if life == 0:
        raise Death()
    else:
        work(life-1)
work(100)


# Let's try a more Object oriented approach

class Person:

    def __init__(self, name):
        self.name = name
        self.life = 100
        self.debt = 0
        self.goals = []
        self.accomplished_goals = []
        self.spouse = None
        self.children = []
        self.assets = []
        self.location = None

    def get_life(self):
        return self._life

    def set_life(self, life):
        if life == 0:
            raise Death()
        else:
            self._life = life
    
    life = property(get_life, set_life)

    def marry(self, person):
        if self.spouse:
            self.divorce()
        self.spouse = person
        self.life -= 1

    def divorce(self):
        if not self.spouse:
            return
        self.spouse = None
        self.life -= 1
   
    def purchase(self, item, with_cash=False):
        self.assets.append(item)
        if not with_cash:
            self.debt += 1
            self.life -= 1

    def sell(self, item):
        if item in self.assets:
            self.assets.remove(item)

    def set_goal(self, goal):
        self.goals.append(goal)

    def accomplish_goal(self, goal):
        self.goal.remove(goal)
        self.accomplished_goals.append(goal)

    def watch_tv(self, is_educational=False):
        self.life -= 1
        if not is_educational:
            self.goals.pop()

    def play_video_games(self):
        self.life -= 1
        self.goals.pop()

    def make_a_baby(self, name):
        baby = Person(name)
        self.children.append(baby)
        self.life -= 1

    def work(self):
        self.life -= 1

    def retire(self):
        import time
        while 1:
            self.life -= 1
            time.sleep()

me = Person('Joshua')
me.set_goal('Find a wife')
me.marry(Person('Jodi'))
me.accomplish_goal('Find a wife')
me.watch_tv(is_educational=True)
me.play_video_games()
me.play_video_games()
me.make_a_baby(Person('Judah'))
me.set_goal('Get a better paying job')
me.accomplish_goal('Get a better paying job')
me.watch_tv()
me.buy('Scion xB')
me.buy('MacBook Pro')
me.make_a_baby(new Person('Jacob'))
me.work()