Tuesday, September 22, 2009

Twitter Weekly Updates for 2009-09-22


  • do the analysts saying TO had "no impact" not know football? u think fred jackson wouldve torn it up if we didnt need to double-cover TO? #

  • Latest Facebook blog post (http://bit.ly/VB1qa) says theyre now cash flow positive. If thats true, its incredible (they burnt $500m last yr) #

  • Aw, that's a sick tattoo! http://bit.ly/eDblr #

  • man tests out bulletproof glass by having his wife hold it in front of her face and shooting it: http://bit.ly/9iTlh #

  • Goten of Japan 5/5 on #Yelp: The food here is delicious. I've been here five times, and I've loved it every one of t... http://bit.ly/d9Wp9 #

  • "went to church this morning. worst mistake of the day." - some guy yelling in central square #

  • you can see why NE picks up vet players. fred taylor knows exactly how to set his blockers up. #

  • Celebrity Pizza & Dairy Bar 3/5 on #Yelp: My roommates and I walk here from our house once every couple weeks.

    The ... http://bit.ly/uMEAo #

  • Antonio's 4/5 on #Yelp: Antonio's makes the most unique and delicious pizza I've ever had. My favorites are the buff... http://bit.ly/10Wh8e #

  • i love when i wish a feature existed in an app, then find that it actually does. just happened with "bookmarks" on @yelp #

  • Me: let's diagram it out tomorrow. we should get a whiteboard.
    Alex: ya
    Alex: and tattoos. #


Powered by Twitter Tools

Monday, September 21, 2009

Tough as Nails

I set a goal for myself at the beginning of last week: stop biting my nails.

Nail Biting

It's been a lifelong habit. Personally, I don't think there's anything wrong with it. In fact, once I do end up successfully stopping, I may start again. I just want to see if I can do it.

So far, it's been a lot harder than I expected. I sometimes catch myself halfway through biting a nail (of course, I have to finish at that point, lest I leave half a nail hanging off). For the first few days, I wasn't even sure if I'd be able to do it.

Now, my nails are longer than they've been since I was a little kid. Once they get to the point where a normal person would cut them with a nail clipper, I'll consider myself victorious.

Saturday, September 12, 2009

Installing MySQL on Snow Leopard

Early on at Cisco, I realized that it's really beneficial to write down (step by step) what I've done when I install something new. It forces me to think about what I'm doing, it provides me with a guide in case I mess up and have to start over, and other people can benefit from it later.

With that in mind, I've decided to document my installation of MySQL on Snow Leopard (OS X 10.6). Hopefully, someone will get some use out of it, but if not, at least I'll have documentation of what I did.

The PATH Variable



MySQL has a bunch of useful executables that aren't in PATH by default. I could symlink to them, but I think that's less maintainable than just appending to PATH.


  1. Open the Terminal

  2. Open up the .bash_profile file in your home directory. This is a bash script that runs every time you start the Terminal, so the PATH variable will be extended properly every time. If you have TextMate and its UNIX command line tools installed, do it like this:
    [code lang="bash"]mate ~/.bash_profile[/code]
    Otherwise, do it like this:
    [code lang="bash"]/Applications/TextEdit.app/Contents/MacOS/TextEdit ~/.bash_profile &[/code]
    If you use the second one, make sure to add the ampersand at the end.

  3. We want to add MySQL's bin folder to PATH. MySQL's going to be installed at /usr/local/mysql, so let's add /usr/local/mysql/bin to PATH. Add the following line to .bash_profile:
    [code lang="bash"]export PATH="/usr/local/mysql/bin:/usr/local/sbin:$PATH"[/code]
    This replaces PATH with two new locations and the old value of path (so essentially, appending the two new locations to the beginning of PATH). You'll notice that, in addition to /usr/local/mysql/bin (which I mentioned earlier), I also added /usr/local/sbin. OS X doesn't include this in PATH by default, but I think it should, so I added it. I have no defense for that position, but this is as much a guide for myself as it is a guide for other people, so I don't need to defend it :)

  4. Save the updated .bash_profile and close it.

  5. Quit and reopen Terminal so that .bash_profile will be rerun (you could also run it explicitly, but I prefer quitting and reopening).

  6. Run the following command:
    [code lang="bash"]echo $PATH[/code]
    You should see /usr/local/mysql/bin and /usr/local/sbin in there now.


Downloading + Installing


I might try compiling and installing from source at some point, but I don't see any reason to when there are official OS X binaries available. Worst case scenario, it messes with a bunch of my settings, and I'll uninstall and then do it from source.

  1. Go to http://dev.mysql.com/downloads/mysql/5.1.html#downloads

  2. Scroll down to the Mac OS X section (near the bottom). Download the version labeled "Mac OS X 10.5 (x86_64)". It's very important that you download the 64-bit version. The 32-bit one will give you preference pane problems (I call them PPPs whenever I talk about them, though this is the first time I ever have). Eventually, there'll probably be a Mac OS X 10.6 version, but for now, this works perfectly.

  3. Open the .dmg, then run mysql-x.x.xx-osx10.5-x86_64.pkg. Continue through all the screens without changing anything, until it finishes.

  4. Optional: install the preference pane by running MySQL.prefPane.

  5. Optional: make MySQL start up along with OS X by running MySQLStartupItem.pkg. I didn't do this (I often use my computer for things other than development, and I don't want to bog it down unnecessarily), so I can't provide any instruction or vouch for how well it works on Snow Leopard.


  6. You should now be able to start MySQL by going into the MySQL preference pane and clicking "Start MySQL Server". If it doesn't work, leave me a comment, and I'll try to help you.

Monday, August 10, 2009

My Mornings

Every morning, when my alarm clock goes off, a little demon wakes up before I do and tries as hard as he can to delay my day.

Sometimes, he sets my alarm clock back 30 minutes. Other times, when he wakes up way before me, he just turns the alarm clock off and I sleep for another three hours. He used to whisper in my ear (when I was in school) that I was way ahead in my classes and that I should take a break from them, or at least from my earliest one. Now, he looks for my work laptop so he can send an "out sick" email to my boss.

Yeah, he's a jerk, but I've got his number. I put my alarm clock at the other end of my room, and leave my work laptop out in the car. He still makes it to the "snooze" button from time to time, but I always wake up and stop him before he can do anything more dangerous.

Problem is, I have to stay awake to keep him at bay. I have a 45-minute drive to work, which is almost entirely straight highway driving. From time to time, I catch him reaching for the wheel, or moving towards one of the pedals. So far, nothing's come of it, but something in the back of my head (maybe him) tells me that it's only a matter of time.

Monday, May 18, 2009

Django Middleware vs. Context Processors

This may be old news to many people, but it's something I just recently learned (after doing it wrong for about nine months), so I figured someone else may be able to benefit from my mistakes.

For a long time, when I needed to access the currently logged-in user in one of my Django views, they would follow this pattern:

[code lang="python"]from django.template import RequestContext

# some other view code

def my_view (request, obj_id):
context = RequestContext(request)
obj = get_object_or_404(SomeModel, pk=int(obj_id))

# do some stuff, including:
some_function(context["user"])

return render_to_response("some_url_name", {"some_var": some_val},
context_instance=context)[/code]

Now, seasoned Django vets (why are you reading this post, by the way?) are probably laughing, but this seemed perfectly fine to me. Luckily, my ignorance was revealed to me while asking on IRC about a problem which, while didn't seem so at the time, was completely tied to my misuse of RequestContext.

To put it simply, context processors are made to be used in templates. The only time they should ever be instantiated is at the very end of a view, like so:

[code lang="python"]return render_to_response("some_url_name", {"some_var": some_val},
context_instance=RequestContext(request))[/code]

I was using them all over views, and even in a few of my decorators. What's wrong with this? The main thing is, certain mutation functions are sometimes performed when a RequestContext is instantiated (such as user.get_and_delete_messages(), which gets all of a user's messages from the database and then deletes them), and performing them multiple times before loading the template can cause unexpected results. In my example, I was instantiating a RequestContext in a bunch of decorators, which meant that by the time my template was loaded, all of the user's messages were deleted (and stored in an earlier instance of RequestContext), making it look to me as if my auth messages were being thrown out.

What's the solution? Middleware. Middleware allows the programmer to attach variables to the request object before it reaches the view. With this (and the provided django.contrib.auth.middleware.AuthenticationMiddleware), I can still achieve my original goal (accessing the logged-in user from a view), but now I can do it without creating a RequestContext and potentially running mutation functions multiple times:

[code lang="python"]from django.template import RequestContext

# some other view code

def my_view (request, obj_id):
obj = get_object_or_404(SomeModel, pk=int(obj_id))

# do some stuff, including:
some_function(request.user)

return render_to_response("some_url_name", {"some_var": some_val},
context_instance=RequestContext(request))[/code]

I've removed all the references to RequestContext from my decorators, and made sure to only instantiate it at the very end of views. Now, messages work perfectly. I've even written my own middleware (which you can learn how to do here) to load instances of a few of my own models into the request.

To reiterate, I'm aware that this is common knowledge for many people, but it took me 9 months of moderate Django use and embarrassment on IRC to discover it for myself. Hopefully, this will help someone else in a similar position.

Sunday, May 10, 2009

Are you a better programmer than you were two years ago?

Two years ago, I was working on a fairly complicated (for my level of experience) web app for posting news articles. Quite a few times, I ran into situations where I was about to create tight coupling between two somewhat unrelated parts of my app. Sometimes, I wouldn't even recognize this as a problem. Other times, I would, but not be able to think of an easy fix, so I'd continue on.

Today, I find myself fixing tightly-coupled situations almost instinctively. I use design patterns that I was barely aware of two years ago, and I do it without straying into "design pattern fever" territory. This isn't to say I'm an expert at software design; it still takes a lot of thought to actually think of the best fix, and I'm sure I still make plenty of mistakes. My point is, my growth as a programmer is very obvious to me in these situations.

How about you? If you've been programming for more than two years, you're probably a better programmer than you were two years ago, but can you tell? If so, how can you tell? Can you give any good examples of moments when you realized it?

Tuesday, May 5, 2009

Non-painful email on Django development servers

I've been actively learning and using Django since August 2008, and I've loved almost every bit of it. There are plenty of places to read all about the virtues of Django, so I'll leave that out for now.

One thing that's always bugged me about web development in general is the sending of emails. I do development on my local computer (with a badly set up Apache / MySQL / PHP / Python / whatever else stack), and I've never felt like dealing with the headache of setting up a mail server. This means, when I add something that's supposed to send an email (like an activation email after registration), I have to get very hacky to test and debug it (making sure the email text is being produced correctly, making sure it's being sent to and from the right people, etc.).

This was one of the few web development pains that I thought Django didn't solve. Whenever I'd test a bit of code that was supposed to send email, I'd get a "Connection refused" error page (meaning my computer has no mail server to send the email with). I would usually add in a bit of printf debugging to make sure the subject and body had the correct text, but beyond that, I'd usually wait to test the email portions until I uploaded to a server that could send email (usually the production server, unfortunately).

Yesterday, I bumped into a little section in the Django documentation that explains how to get around this. As usual, Python has all the solutions. First, set this code in your settings.py file:

[code lang="python"]EMAIL_HOST = 'localhost'
EMAIL_PORT = 1025 # replace this with some free port number on your machine[/code]

Then, assuming you're on a Unix system (I'm on a Mac), run the following on the command line to start a "dumb" Python mailserver:

[code lang="bash"]python -m smtpd -n -c DebuggingServer localhost:1025[/code]

Make sure to replace 1025 with whatever you filled in for EMAIL_PORT.

Now, try running the email-sending code in your Python application. Voila! No error pages (or at least, none related to email), and the full text of the email (headers and all) appears in whatever command line prompt you ran the dumb mailserver on. This allows you to the see senders, recipients, subject, and body of the email being sent out, all without getting hacky or sending to an email account you own.

Taking this a step further, I created a small bash script called "dumbmail" in /usr/local/bin that looks like the following:

[code lang="bash"]#!/usr/bin/env bash
if [ -z $1 ]
then port=1025
else port=$1
fi

echo "Starting dumb mail server on localhost:$port"
python -m smtpd -n -c DebuggingServer localhost:$port[/code]

Now, when I'm testing a Django application and I get to a section that is going to send an email, I just run "dumbmail" (or "dumbmail some_number" if I need to use a different port, for some reason I can't imagine), and I'm ready to go.

Hope this helps people. The documentation was always there - I just never noticed that part until yesterday.