I'm trying to get better at Python and would like a critique.
Accept a 2D grid containing 1's and 0's (1 being mine locations) and print a solved sum grid (the way the final grid would show upon completion of a minesweeper game with all the neighbor sums).
Beyond that, what might be horribly wrong with the code below? I am interested in finding a recommended balance between readability and what the cool kids call idiomatic. For example, List comprehension in some places was deliberately omitted in favor of making something that I thought was easier on the eyes.
The top-level functions are called via:
if __name__ == '__main__': locMap = [[1,0,0,0],[0,0,1,0],[0,1,0,1]] # Sample input print "Location map = " printMineField(locMap,locMap) newMap = getSummedMap(locMap) print "Summed map = " printMineField(locMap,newMap)
The output is:
''' Location map = * 0 0 0 0 0 * 0 0 * 0 * Summed map = * 2 1 1 2 3 * 2 1 * 3 * '''
The actual functions are:
def generatePaddedGrid(grid): """ Input: 2D list. Output: 2D list Purpose: Returns a 0-padded boundary around a grid. Useful to perform easier 2D traversal + operations of the inner grid without painful boundary checking """ # Get Dimensions of grid nRows = len(grid) nCols = len(grid) # Create a grid with +2 row/col padding (on all sides) paddedGrid = [[0 for x in range(0,nCols + 2)] for x in range(0,nRows + 2)] # Insert 'centered' locMap into the Padded Grid for xIter in range(0,nRows): for yIter in range(0,nCols): paddedGrid[xIter+1][yIter+1] = grid[xIter][yIter] return paddedGrid def getSummedMap(locMap): """ Input: 2D list Output: 2D list Purpose: Takes in a 2D array (locMap) and returns a same-sized array with each cell now containing the sum of all the neighbors including diagonals (max of 8 neigbor cells) """ # Insert + Center this grid into a padded grid to prevent access errors paddedGrid = generatePaddedGrid(locMap) nRows = len(locMap) #Actual rows to be iterated nCols = len(locMap) #Actual cols to be iterated. # Create a target/output grid of the actual size to write the sums into sumGrid = [[0 for x in range(0,nCols)] for y in range(0,nRows)] for xIter in range(1,nRows+1): for yIter in range(1,nCols+1): Sum = 0 # Top + Bottom + Left + right Sum += paddedGrid[xIter-1][yIter] +\ paddedGrid[xIter+1][yIter] +\ paddedGrid[xIter][yIter+1] +\ paddedGrid[xIter][yIter-1] # Then 4 diagonals Sum += paddedGrid[xIter-1][yIter-1] +\ paddedGrid[xIter+1][yIter-1] +\ paddedGrid[xIter+1][yIter+1] +\ paddedGrid[xIter-1][yIter+1] sumGrid[xIter-1][yIter-1] = Sum return sumGrid def printMineField(locMap, SumMap): """ Input: 2 x 2D Arrays Output: No return, just print an overlayed Sum-map over a given Loc-map but leave the mine-locations as '*' (instead of the neighbor-sums) """ numActualRows = len(locMap) #Actual rows to be iterated numActualCols = len(locMap) #Actual cols to be iterated. for xIter in range(0,numActualRows): for yIter in range(0,numActualCols): if locMap[xIter][yIter] == 1: print '*', else: print str(SumMap[xIter][yIter]), print '\n'