2
\$\begingroup\$

I've written a simple program in Python which does the following:

Input: an integer \$n\$

Output: a \$2^n x 2^n\$ matrix containing small \$L\$s which fill the entire matrix except one single square. Each L has its unique number, and consists of three squares.

It's a fairly simple program, and you can see clearly what it does by typing in a few different \$n\$s.

What I'd like to do: Keep the actual algorithm as it is now (the rec() function), but improve my C-like code to make full use of Python's features.

#!/usr/bin/env python import sys, math ur = [[1,0], [1,1]] ul = [[0,1], [1,1]] lr = [[1,1], [1,0]] ll = [[1,1], [0,1]] shapeCounter = 1 matrix = [] def printMatrix(): for row in matrix: for element in row: if(element >= 10): print("%d" % element), else: print(" %d" % element), print print def square(n): global matrix matrix = [[0]*(2**n) for x in xrange(2**n)] matrix[0][len(matrix) - 1] = -1 rec(0, 0, len(matrix) - 1, len(matrix) - 1) matrix[0][len(matrix) - 1] = 0 printMatrix() def writeRect(rect, x, y): global shapeCounter matrix[y][x] += rect[0][0] * shapeCounter matrix[y+1][x] += rect[1][0] * shapeCounter matrix[y][x+1] += rect[0][1] * shapeCounter matrix[y+1][x+1] += rect[1][1] * shapeCounter shapeCounter += 1 def rec(sx, sy, ex, ey): if(ex - sx < 1 or ey - sy < 1): return #print("(%d,%d) (%d,%d)" %(sx,sy,ex,ey)) if(matrix[sy][sx] != 0): rect = ul elif(matrix[ey][sx] != 0): rect = ll elif(matrix[sy][ex] != 0): rect = ur elif(matrix[ey][ex] != 0): rect = lr hx = sx + (ex - sx) / 2 hy = sy + (ey - sy) / 2 writeRect(rect, hx, hy) rec(sx, sy, hx, hy) rec(hx + 1, sy, ex, hy) rec(sx, hy + 1, hx, ey) rec(hx + 1, hy + 1, ex, ey) if __name__=='__main__': square(int(sys.argv[1])) 
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Get out of the habit of using global variables like that. You're just asking for trouble when you do. \$\endgroup\$ Commented Sep 23, 2012 at 19:19

1 Answer 1

3
\$\begingroup\$
#!/usr/bin/env python import sys, math ur = [[1,0], [1,1]] ul = [[0,1], [1,1]] lr = [[1,1], [1,0]] ll = [[1,1], [0,1]] 

Rather then creating four separate variables, I'd suggest making a list. I'd also suggest using the numpy library for its array type. It makes working with 2D arrays much nicer then using lists of lists.

shapeCounter = 1 matrix = [] 

Don't use global variables. Instead, pass matrix in as the parameter to the function.

def printMatrix(): for row in matrix: for element in row: if(element >= 10): 

Parens aren't needed here

 print("%d" % element), else: print(" %d" % element), print print 

Note that if you used numpy, that library would already be able to nicely print a matrix.

def square(n): global matrix 

This function should really create and return the matrix

 matrix = [[0]*(2**n) for x in xrange(2**n)] 

In numpy, this would be matrix = numpy.zeros( (2**n, 2**n) )

 matrix[0][len(matrix) - 1] = -1 rec(0, 0, len(matrix) - 1, len(matrix) - 1) matrix[0][len(matrix) - 1] = 0 printMatrix() 

Functions that do work on your variables shouldn't print them. Your main control function should do the printing.

def writeRect(rect, x, y): global shapeCounter 

This isn't a terrible use of a global, but I'd avoid it. I'd have an object this attribute was stored on.

 matrix[y][x] += rect[0][0] * shapeCounter matrix[y+1][x] += rect[1][0] * shapeCounter matrix[y][x+1] += rect[0][1] * shapeCounter matrix[y+1][x+1] += rect[1][1] * shapeCounter shapeCounter += 1 def rec(sx, sy, ex, ey): 

I wouldn't use abbreviations. Use start_x, end_y to make your code clearer.

 if(ex - sx < 1 or ey - sy < 1): return #print("(%d,%d) (%d,%d)" %(sx,sy,ex,ey)) if(matrix[sy][sx] != 0): rect = ul elif(matrix[ey][sx] != 0): rect = ll elif(matrix[sy][ex] != 0): rect = ur elif(matrix[ey][ex] != 0): rect = lr 

You don't need all those parens

 hx = sx + (ex - sx) / 2 hy = sy + (ey - sy) / 2 writeRect(rect, hx, hy) rec(sx, sy, hx, hy) rec(hx + 1, sy, ex, hy) rec(sx, hy + 1, hx, ey) rec(hx + 1, hy + 1, ex, ey) if __name__=='__main__': square(int(sys.argv[1])) 
\$\endgroup\$
4
  • \$\begingroup\$ In newer versions of python, print is deprecated as a keyword and requires brackets like any other function. \$\endgroup\$ Commented Sep 24, 2012 at 18:57
  • \$\begingroup\$ @Aleksandar, when I said the parens are unnecessary, I'm referring to the if statement, not print. \$\endgroup\$ Commented Sep 24, 2012 at 19:00
  • \$\begingroup\$ Your code view segment shows print, that's what led me to my conclusion. :) \$\endgroup\$ Commented Sep 24, 2012 at 19:02
  • \$\begingroup\$ You'll see that may comments are always after the code they are commenting on, not before. But I might still object to the usage here for being inconsistent. \$\endgroup\$ Commented Sep 24, 2012 at 19:04

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.