David Ziegler's personal blog of computing, math, and other heroic achievements.


09 Apr 2009

How much contractors bill per hour

I thought this was a pretty interesting poll on Hacker News asking how much people billed per hour, so I decided to make a histogram. It uses a Dapper feed so the results should be updated either hourly or in real time. You’ll need to have javascript enabled to view the poll. If it doesn’t appear after a few seconds, try refreshing.

The bottom axis is how much a person charges per hour, the left axis is the frequency.

To be fair, this poll doesn’t specify what type of consulting work you do, but being Hacker News, it probably has something to do with computers.

Comments (View)

04 Apr 2009

Another CleverCSS Patch

Found another bug in CleverCSS. This one prevented you from subtracting values (ie 960px - 200px). Again, I don’t see this being fixed in the official release anytime soon, so you can download the most recent patched version here:

http://code.google.com/p/django-css/downloads/list

At this rate, maybe I’ll just release my own fork.

Update: Forked! http://github.com/dziegler/clevercss/tree/master

Comments (View)

03 Apr 2009

It is a FACT that I never sleep

energy drinks

more energy drinks

Sleep is the cousin of death, as they say.

Comments (View)

03 Apr 2009

CleverCSS Patch

So after raving about how great CleverCSS is, I discovered a small bug that will cause it to fail with django-css. Basically, if you run CleverCSS from the command line like so:

$ clevercss static/base.ccss

it will output a file called ccss.css in the directory you ran clevercss.py from, instead of creating a file called static/base.css. Fortunately, this was literally a one character fix.

I submitted the patch but it doesn’t look like the official version will be patched anytime soon, since the package hasn’t been changed since 2007. Until then you can download the recent patched version here: http://code.google.com/p/django-css/downloads/list

Update: My forked version of CleverCSS is now here: http://github.com/dziegler/clevercss/tree/master with various bug fixes. It will also install a clevercss executible in your path.

Comments (View)

02 Apr 2009

CSS compilers rock

I actually wrote django-css because I was looking through the slides from the Reddit keynote at PyCon, and got really excited when I saw what their CSS compiler could do (page 29). Variables, functions, and nested styles in CSS? Could it be? Was I dreaming?

Then after about 5 minutes of searching the internet I realized that this was nothing new, and that there were already tons of CSS compilers out there that I had just never heard of. Now that I’m using a CSS compiler, I have no idea why more people don’t know about them or use them, because they are totally awesome. The three biggest reasons to use a CSS compiler in my opinion are:

  1. Variables - Good programmers don’t like to hardcode. In many cases you can avoid this in CSS by using good inheritence, but sometimes it’s unavoidable. With variables, changing your color scheme means updating one variable instead of 13 attributes.
  2. Math - This goes hand in hand with variables. Say your left column is 100px, your right column is 500px, and your wrapper div is 600px. Well, maybe you decide to change it to 960px. Wouldn’t it be awesome if the width of your columns adjusted automatically? The answer is yes.
  3. Nested Styles - This is probably the most important. CSS is flat, which means complex sites end up with CSS that is a pain to go through. I’d much rather stare at this beautiful, pythonic, whitespace using code:
    ul#comments, ol#comments:
      margin: 0
      padding: 0
    
      li:
        padding: 0.4em
        margin: 0.8em 0 0.8em
    
        h3:
          font-size: 1.2em
        p:
          padding: 0.3em
        p.meta:
          text-align: right
          color: #ddd
    

    than this ugly mess:
    ul#comments,
    ol#comments {
      margin: 0;
      padding: 0;
    }
    
    ul#comments li,
    ol#comments li {
      padding: 0.4em;
      margin: 0.8em 0 0.8em;
    }
    
    ul#comments li h3,
    ol#comments li h3 {
      font-size: 1.2em;
    }
    
    ul#comments li p,
    ol#comments li p {
      padding: 0.3em;
    }
    
    ul#comments li p.meta,
    ol#comments li p.meta {
      text-align: right;
      color: #dddddd;
    }
    

If you find the idea of CSS compilers to be intimidating, HSS is a good place to start. It has nested styles and variables, but no math. It also keeps CSS’s bracket {} notation and doesn’t rely on whitespace, unlike Sass and CleverCSS.

If you want a little more power though, head over to Sass or CleverCSS. Sass is in Ruby and CleverCSS is in python. The only major difference between the two is that Sass requires your indents to be 2 spaces, and CleverCSS doesn’t care. This is a big enough difference to cause me to prefer CleverCSS, because everything else I program uses 4 spaces for indentation. However, they both have variables, can do basic math, have nested styles, and utilize whitespace rather than brackets and semicolons. For django-css, it doesn’t really matter which one you use because they can both be called from the command line.

Honestly, I can’t really think of a reason not to use a CSS compiler other than you’re too lazy to port your existing CSS over to a slightly different format. If you’re using Django, you can keep your existing CSS in one file and write your new CSS using CleverCSS or HSS in a different file. Django-css will recognize your existing CSS files and merge/compress all of your CSS together anyway, so it doesn’t really matter how many separate CSS files you have.

EDIT (4/19/09) - I’ve found a couple bugs in CleverCSS, and it doesn’t look like the official version is being maintained, so I’m hosting a patched version here: http://code.google.com/p/django-css/downloads/list

Update: My forked version of CleverCSS is now here: http://github.com/dziegler/clevercss/tree/master with various bug fixes. It will also install a clevercss executible in your path.

Comments (View)

31 Mar 2009

Django-css

I just uploaded django-css over at google code. It’s a fork of django-compress that adds the ability to easily use CSS compilers with your Django projects. CSS compilers extend CSS syntax to include more powerful features such as variables and nested blocks.

CSS files are re-compiled only when they are changed, so you can still serve them as static content.

django-css also automates the compression, combination, and versioning of your CSS and Javascript files. See django-compress for more information on CSS/JS compression.

django-css can currently be used with any CSS compiler that can be called from the command line, such as HSS and Sass.

Comments (View)

24 Mar 2009

Reverse Geocoding with Geopy

Geopy is an awesome geocoding toolbox for Python, that is now even more awesome.

I actually added the reverse geocoding feature a while ago, but didn’t get around to writing up how to use or install it until now. Right now it’s in a separate but stable development branch.

Installation and usage instructions are here: http://code.google.com/p/geopy/wiki/ReverseGeocoding

Comments (View)

20 Mar 2009

Deploying a pinax project with mod_wsgi

I recently deployed a Django web app built on Pinax. I had heard a lot of good things about mod_wsgi as opposed to mod_python, so I wanted to give it a shot. This was my first time using mod_wsgi and when I tried following the steps in the Pinax documentation, all I got was server 500 errors. What should have probably only been a 10 minute procedure turned into an hour of cursing and fist shaking, and it seems like I’m not the only one who had problems getting WSGI to play nice with Pinax. To spare you the same fate I thought I would write up the correct way to deploy a Pinax project with mod_wsgi.

NOTE: The official documentation and files may have been changed after originally writing this. I’m currently using Pinax 0.5.1 with Django 1.0.2. This project was deployed on a Webfaction shared host (highly recommended for hosting Django projects!) but I don’t think it really matters what host you use.

Short version

If you already know how to use mod_wsgi, the short version of why following the steps in the Pinax documentation doesn’t work is that it sets up your sys.path incorrectly. Pinax uses a lot of external apps and libraries which need to be included.

If you’re brand new to mod_wsgi though, read on.

Set up

I’ll run through deploying the complete_project that comes with the default installation of Pinax 0.5.1. I’ll assume that pinax lives in PATH/pinax/, and that you already have your database set up and installed. To get this to work with your project, just change the following instances of PATH to the absolute path Pinax sits on, and change complete_project to the name of your project.

Settings.py

Add the following to your Settings.py file

from os.path import abspath, join, dirname

PINAX_ROOT = abspath(join(dirname(__file__), "../../"))
PROJECT_ROOT = abspath(dirname(__file__))

This assumes that you’re using the default directory structure that comes with Pinax 0.5.1. If you’re using something different, just change PINAX_ROOT to PATH/pinax/ and PROJECT_ROOT to the absolute path of your project.

wsgi_handler.py

You will need a script to create a WSGI-handler for your project, which we’ll call wsgi_handler.py. It’s recommended for security reasons that you keep your WSGI script in a directory separate from your website, and not in the DocumentRoot for your Apache installation. Create a directory called ‘wgsi’ at PATH/wgsi/ and place wsgi_handler.py in it, so you have something like this:

PATH/wsgi/wsgi_handler.py

If you use a revision control sysem like SVN and want to keep wsgi_handler.py in SVN, just create a symbolic link in PATH/wsgi/ that links to wherever you want to keep wsgi_handler.py.

In wsgi_handler.py put

import sys
from os.path import abspath, dirname, join
from os import environ
from site import addsitedir

# redirect sys.stdout to sys.stderr for libraries that use
# print statements for optional import exceptions.
sys.stdout = sys.stderr

sys.path.insert(0, abspath(join(dirname(__file__), "../pinax/projects")))

from django.conf import settings
environ['DJANGO_SETTINGS_MODULE'] = 'complete_project.settings'

path = addsitedir(join(settings.PINAX_ROOT, "libs/external_libs"), set())
if path:
sys.path = list(path) + sys.path
sys.path.insert(0, join(settings.PINAX_ROOT, "apps/external_apps"))
sys.path.insert(0, join(settings.PINAX_ROOT, "apps/local_apps"))
sys.path.insert(0, join(settings.PROJECT_ROOT, "apps"))
sys.path.insert(0, settings.PROJECT_ROOT)

from django.core.handlers.wsgi import WSGIHandler
application = WSGIHandler()

http.conf

Edit your Apache http.conf to make sure mod_wsgi and mod_authz_host are loaded:

LoadModule wsgi_module modules/mod_wsgi.so
LoadModule authz_host_module modules/mod_authz_host.so

The actual path to the modules may be different on your system, so make sure those are correct. Then add the following code:

WSGIScriptAlias / PATH/wsgi/wsgi_handler.py
WSGIDaemonProcess complete_project processes=1 threads=10
WSGIProcessGroup complete_project

<Directory PATH/wsgi>
Order allow,deny
Allow from all
</Directory>

Edit the WSGIDaemonProcess line to control the amount of system resources you want mod_wsgi to use. For small to medium load websites, I’ve heard that 1 process with 10 threads should be ok.

(psstt, don’t forget to configure apache to serve your static files and not Django!)

And that’s it! Restart apache and hopefully your Pinax project is up and running. Drop me a note in the comments or shoot me an email at david.ziegler {at} gmail.com if I’m wrong or missed something.

More info and tutorials on mod_wsgi, Django, and Pinax:

http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide

http://www.technobabble.dk/2008/aug/25/django-mod-wsgi-perfect-match/

http://www.20seven.org/journal/2008/09/pinax-setup-and-deploy.html

Comments (View)

18 Mar 2009

What a bad Soy Sauce, eating Helen’s cha siu baau…

Comments (View)

Page 4 of 4