Trevor Hunsaker

Salt Lake area Web developer

Pascal's Triangle in Python (with semi-decent printing)

Today, I ran across a Hacker News thread where someone mentioned that they often ask job applicants to whiteboard a function that would return a row of Pascal's Triangle. I couldn't resist, so and came up with this:

print "\n"
print "Printing Pascal's triangle."
num_rows = input("How many rows do you want: ")

def triangle(num_rows):
	width = 2*num_rows - 1
	prev_row = []
	triangle = []

	for row_num in range(num_rows):
		row_width = row_num + 1 # the number of items that will appear in this row
		if row_num == 0:
			row = [1]
		
		else:
			row = []
			for i in range(row_width):
				if i == 0 or i == row_width-1:
					# the '1's on either end of each row
					row.append(1)
				else:
					# Calculate the sum of the two numbers above this position
					row.append(prev_row[i-1] + prev_row[i])
		
		prev_row = row
		triangle.append(row)
	return triangle

# Actually generate the triangle		
triangle = triangle(num_rows)

# Now print it out nicely
# First, get the width of the last row in the triangle (printed as a string)
width = len(" ".join(["%s" % num for num in triangle[-1]]))

for line in triangle:
	print str.center(" ".join(["%s" % num for num in line]), width)

Obviously, I was less interested in returning the row as I was in building the triangle itself and printing it. Returning the actual row is left as an exercise to the reader.

Force SSL connection on a subdirectory using mod_rewrite

A while back I needed to force an SSL connection for only a subdirectory of a website.  Apache's mod_rewrite came to my rescue.

RewriteEngine On
RewriteCond %{HTTPS} off # the following rules only apply if the connection isn't already HTTPS

# Next line captures any bits after the directory we're interested in
# and stuff it into %1, which gets expanded back out in the rule at the end
RewriteCond %{REQUEST_URI} /dir-that-needs-ssl/(.*)
RewriteRule / https://www.example.com/dir-that-needs-ssl/%1 [R,L]

Understanding Python decorators

A while back, I was hanging out on some Python forum and someone posted a comment about not being able to wrap their head around decorators.  I spent some time on what I thought was a helpful comment, and that was that. Recently I figured it'd be worthwhile to expand that comment a bit.  So, here we go.

First, it helpes to understand that python variables are not boxes in which you store values, but rather name tags that you hang onto objects.  Please don't move on until you grok this, it's the central principle to decorators.

Second, in Python, functions are objects. Function names themselves are just name tags hung onto their respective function objects.

Finally, here's a simple definition of a decorator: It's just a function.  Seriously. Nothing magic about it all. It takes another function as an argument (the function being decorated). It returns yet another function object.

If that sounded like I just said, "Function function function function function," (which is how I felt when trying to wrap my head around decorators), here's a small python program that may help out:

def orig_function():
    print "Hello!"

def my_decorator(function_to_decorate):  # Decorator takes a function as an argument
    def third_func():   # Yes, it's totally legit to create nested function definitions. 
    			# It's a very common decorator idiom.
        print "Take Off, eh?"

    return third_func # return a function object.  Note: we don't have parens here.

If we'd run this code in the interactive interpreter, here's the output we'd get:

>>> orig_function()
Hello!
>>> # now, we're going to decorate orig_function with my_decorator
>>> orig_function = my_decorator(orig_function)
>>> orig_function()
"Take off, eh?"

That above syntax is what made decorators click for me. All we've done here is taken the orig_function nametag, and hung it onto the third_function object (remember, my_decorator returns third_func). So when we call orig_function() now, what we're really calling is third_func().

I used the above syntax ( a=decorator(b) ) until I was sure I understood how decorators worked before I switched to using the shorter @ syntax.

orig_function = my_decorator(orig_function)

is equivalent to

@my_decorator
def orig_function():
    print "Hello!"

which isn't as intuitive and is probably the main roadblock to understanding decorators right at first, but nicer to use once you've got the hang of things.

In this example, we didn't do anything in the my_decorator function with the argument that was passed in ( orig_function ), but we could have called it and returned something other than third_func, depending on what orig_function returned. Remember, a decorator is just a function, you can do anything inside a decorator you'd do in a vanilla Python function. It just needs to take a function as a parameter, and return another function.