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

Download movie.zip

Testing Thought For Today

Grid Utility Code

Grid Functions

set_edges()

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.

Grid Literals

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

alt: [['a', None, 'a'], ['b', None, 'b']]

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.

Grid Literal Construction

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']])

Recall: Write Test for set_edges()

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']]

Random Module

>>> 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'

random_right() Function

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

scroll_left(grid)

Scroll Ideas

Before:

NNd
NNN

After:

NdN
NNN

scroll_left() v1 with bugs

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

Add Doctest

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]]

Here is the Doctest added in. Use this to get this algorithm perfect.

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]]
    """

Work on scroll_left()

scroll_left() Solution

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

Testing Big Picture

Demo: Sand Program