Recent Posts

Craig's avatar

How to Make Authentic Thai Food (Like a Jerk)

I think we can all agree that good restaurant Thai food is one of life's true gems. I think we can also all agree that it's not immediately obvious how to make it, and many recipes just don't quite bring home that explosive flavor we've come to know and love.

Today, we're going to squash that problem. My sister's boyfriend cooked at a Thai restaurant through high school and thus knows all the tricks. There are perks to befriending a member of the Illuminati!

Read More


Craig's avatar

Postgres GROUP BY with COUNT

As god is my witness, I will never again forget the syntax for this query. Coming from a decade of MySQL, I have proven myself incapable of remembering the Postgres version.

Read More


Craig's avatar

Introducing: DominionKingdoms.com

Over the past few months I've come to really enjoy the card game Dominion. It's well balanced, has outstanding replay value, and enjoys just the right blend of strategy and luck.

Read More


Craig's avatar

Real-time SQL output in Django

Sometimes when you're on a query-killing rampage to improve the performance of a page, you find yourself wondering exactly when various queries are triggered and executed. You know to add prefetch_related, selected_related, and all those goodies. Seeing every executed query isn't hard either.

Read More


Craig's avatar

Mocking things in Python (and specifically, in Django)

Correctly mocking external entities in your unit tests is a bit tricky syntactically, and I have to look up the exact incantations to type every single time they're needed. Thus, I'll make a quick sales pitch about mocking, quickly explain it to the best of my current understanding, and end with a sequence of tricks to be updated as I learn more. In essence, it's my own personal cheat sheet, stored in an accessible location I'm unlikely to misplace.

Read More


Craig's avatar

Dynamic, Complex Lookups in Django

Everyone knows about Django's Q objects and how to chain them together for complex lookups. The syntax is straight forward.

1
results = MyModel.objects.filter(Q(key1="value1") | Q(key2="value2"))

That generates this unexciting SQL:

1
2
3
SELECT *
FROM `my_table`
WHERE (`my_table`.`key1` = "value1" OR `my_table`.`key2` = "value2")

But what happens when you have an unknown amount of filters?

Read More


Craig's avatar

Nothing's Worse Than: Movie Trailers

The experience of sitting through a trailer and thinking, "Looks like I don't need to see that, now that every last plot twist was spoiled", or "New Comedy XYZ was pretty funny, but all the good parts were in the trailer," are too common.

As movies go, the only thing that approaches the awfulness of Jumper is having an otherwise good movie completely spoiled by a trailer that just wouldn't shut up.

Read More


Craig's avatar

How I Made the Django Admin Scale for Stik.com

At Stik.com, we're using Django to supply a RESTful interface to our database. Our support staff is also using its admin for simple ticket items. Fortunately for the business, but unfortunately for the Django admin, we have lots of tables with hundreds of millions of rows, and a few in the billions. We really didn't want to spend the time writing our own admin section for support staff, so the Django admin was a godsend... until we rolled it out to production and saw admin pages never respond ever. Read on to see what our problem was and how we fixed it.

The problem:

Large tables in InnoDB may not be able to even render their change_list view due to (possibly 2) expensive COUNT(*) queries. With tables of 100M+ records, this can take 15+ minutes to complete, even on fast servers.

Read More


Craig's avatar

The Survival Situation Manifesto

The following is a how-to guide for surviving terrible situations that I wrote with two roommates, Dan Lindeman and Ross Lepine, back in undergrad in 2008 after watching 30 Days of Night. Without further adieu:

Read More


Craig's avatar

Deploying this Blog (part 2)

Up and running with Django, MySQL, Apache2, and EC2

Before we get started, I'm assuming you've mastered or completed the first part of the tutorial, your site code itself is complete, your virtual environment is functional in local development, and you have your domain name pointed the IP of the EC2 instance we just made. If any of these assumptions are false then you are probably getting ahead of yourself.

Read More


Craig's avatar

Deploying this Blog (part 1)

Up and running with Django, MySQL, Apache2, and EC2 This is super fast and easy. Here we go:

Step 1: Literally the first step

Create and log into your http://aws.amazon.com account. Yadda yadda yadda.

Read More


Craig's avatar

Optimizing your Development

I've had the same debate at every company for which I've ever worked, and the setup is always the same. Legacy tools are in place that technically get the job done but the annoying, but newer programmers are calling for new methods and tools. Some of the older dogs and management don't want to change, citing the overhead and cost of switching gears -- while the voices of change insist that a smoother, faster, easier, and more stable iteration process awaits at the end of that overhead. On healthy teams this leads to a lot of passionate, respectful debate. On unhealthy teams it spawns gnashing of teeth, finger pointing, and name-calling.

Read More


Craig's avatar

Mountain Lion, MAMP, and Django 1.4

First, allow me to make a few assumptions:

  1. You're running Mac OS X 10.8.
  2. You have MAMP 2.x installed (and this is preventing MySQL-python from installing).
  3. You're going to run your Django site within a virtualenv (If you weren't planning on doing this, now's a great time to change your mind!).
  4. You're tired of PHP and you want to use Django, but because of other projects are unable to remove MAMP and start fresh.

Why it's failing:

MySQL-python won't compile because it needs the MySQL headers which are not in the expected location under a MAMP install. Luckily, this isn't hard to remedy.

Read More