Today: grid, grid testing, work on one function at a time

Download movie.zip

Implement set_edges()

def set_edges(grid): """ Set all the squares along the left edge (x=0) to 'a'. Do the same for the right edge. Return the changed grid. """ pass

Solution code:

def set_edges(grid): """ Set all the squares along the left edge (x=0) to 'a'. Do the same for the right edge. Return the changed grid. """ for y in range(grid.height): grid.set(0, y, 'a') grid.set(grid.width - 1, y, 'a') return grid

Q: How can we tell if that code works? With our image examples, at least you could look at the output, although that was not a perfect solution either. Really we want to be able to write test for a small case with visible data.

There's a syntax to write a grid out in Python code. It's a little funny looking, but it's fine for small grids. Suppose we have this 3 by 2 grid

Here is the nested-list "literal" representation of that grid:

[['a', None, 'a'], ['b', None, 'b']]

The grid is shown as a series of rows, row-0, row-1, .... Each row within square brackets. The special value `None`

is in the empty squares. So the first thing you see is the top row, Then the next row and so on.

The Grid code understands how to build a grid from a literal. This lets us throw together a grid in one line. This will be handy for testing!

grid = Grid.build([['a', None, 'a'], ['b', None, 'b']])

Here are the key 3 lines added to set_edges() that make the Doctest: (1) create a grid, (2) call fn, (3) write out the expected result of the function call

>>> grid = Grid.build([['b', 'b', 'b'], ['x', 'x', 'x']]) >>> set_edges(grid) [['a', 'b', 'a'], ['a', 'x', 'a']]

>>> import random # starter code has this already >>> random.randrange(10) 1 >>> random.randrange(10) 3 >>> random.randrange(10) 9 >>> random.randrange(10) 1 >>> random.randrange(10) 8 >>> random.choice('doofus') 'o' >>> random.choice('doofus') 'u' >>> random.choice('doofus') 'o' >>> random.choice('doofus') 'o' >>> random.choice('doofus') 's' >>> random.choice('doofus') 's' >>> random.choice('doofus') 'o' >>> random.choice('doofus') 's'

Provided to fill in letters at right

def random_right(grid): """ Set the right edge of the grid to some random letters from 'doofus'. (provided) """ for y in range(grid.height): if random.randrange(10) == 0: char = random.choice('doofus') grid.set(grid.width - 1, y, char) return grid

Before:

NNd NNN

After:

NdN NNN

def scroll_left(grid): """ Implement scroll_left as in lecture notes. """ for y in range(grid.height): for x in range(grid.width): val = grid.get(x, y) if x > 0 and val != None: # x,y is source to copy from val = grid.get(x, y) grid.set(x - 1, y, val) return grid

How about this input case:

[['a', 'b', 'c'], ['d', None, None]]

What should result look like for that input case? You should be able to write out the "after" case for an algorithm you are building.

After:

[['b', 'c', None], [None, None, None]]

def scroll_left(grid): """ Implement scroll_left as in lecture notes. >>> grid = Grid.build([['a', 'b', 'c'], ['d', None, None]]) >>> scroll_left(grid) [['b', 'c', None], [None, None, None]] """

def scroll_left(grid): """ Implement scroll_left as in lecture notes. >>> grid = Grid.build([['a', 'b', 'c'], ['d', None, None]]) >>> scroll_left(grid) [['b', 'c', None], [None, None, None]] """ for y in range(grid.height): for x in range(grid.width): val = grid.get(x, y) if x > 0 and val != None: # x,y is source to copy from val = grid.get(x, y) grid.set(x - 1, y, val) grid.set(x, y, None) return grid