Today: (we start today doing the examples at the end of lecture-7 which we did not get to). Start movie example, grid, grid testing.

Today example movie.zip

One Function at a Time - Debugging

Grid Utility Code

Grid Functions

Grid Example Code

grid = Grid(3, 2)
grid.width # returns 3
grid.set(2, 0, 'a')
grid.set(2, 1, 'b')

alt: grid, width 3 height 2, 'a' upper right, 'b' lower right

set_edges()

Start out without the Doctests.

Implement set_edges() (in movie.py)

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

Is that code right? 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

A "literal" in code is when you can type a value directly in the code, like 6 or 'Hello'

There is a syntax to write a Grid literal 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']]

Note: Doctests are super picky - if we had an extra space after the last ], the test will fail.


Random Numbers - Random Module

"Anyone who attempts to generate random numbers by deterministic means is, of course, living in a state of sin." John von Neumann

A computer program is "deterministic" - each time you run the lines with the same input, they do exactly the same thing. Creating random numbers is a challenge, so we settle for "pseudo-random" which are random looking, but generated by an algorithm that selects a random-like, aka "pseudo-random", series of numbers.

Try the "Python Console" tab at the lower-left of your PyCharm window to get an interpreter. It may have a prompt like "In[2]:", but it's just the same old >>> interpreter.

>>> 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 10% of the time to a random char from 'doofus'

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

Next up: scroll_left()

Function to move every grid square one to the left + tests for that function.