Today; style 1.0, top-down decomp digital images, RGB, pixels, "foreach" loop, expressions

Fn Call Recap Diagram

Here's a diagram showing the function-call sequence we played with in lecture-3, e.g. the stripes example. The run starts in the caller and goes over to run the lines in the called function. When the called function is finished, the run resumes where it left off in the caller.

function call run goes from caller, to called, back to caller

Bonus fact: the variables, such a "x" above, are separate and independent for each function, so x in caller is a completely separate variable from x in foo.

Pep Talk

Week-1 and week-2 have the maximum number of things to learn of the whole quarter. It's all a little weird looking, but you can pick it up. Do some reps. Later weeks we will slow down.

stripe_world() - Issue With Odd Rows

Detail I glossed over last time, see Case-7. > Stripes

What if there are an odd number of rows available in the loop? Solution: add if-logic for the second move within the loop. See this on

def stripe_world(filename):
    bit = Bit(filename)  # provided line, load bit from filename
    # vvv
    fill_row_color(bit, 'blue')
    while bit.front_clear():
        bit.move()
        fill_row_color(bit, 'green')
        if bit.front_clear():   # Need this if
            bit.move()
            fill_row_color(bit, 'blue')

Coding Style 1.0 - Tactics

xx link to py-style1.html

CS106A doe not just teach coding. It has always taught how to write clean code with good style. Your section leader will talk with you about the correctness of code, but also pointers for good style.

All the code we show you will follow PEP8, so just picking up the style tactic that way is the easiest.

Python Style1 doc - We'll scan through this


Decomposition Strategy - Divide and Conquer

e.g. stripe_world() function solves the whole thing, calling the stripe_row_color() function to do one row.

Big Picture - Browser Example

Aside: Delegation and Knowing Things

Top-Down Decomposition Steps


Hurdles Decomposition Example

> Hurdles

bit runs series of hurdles

   while not bit.left_clear():
       bit.move()

Hurdles Outline

solve_hurdles()

def solve_hurdles(filename):
    """
    Solve the sequence of hurdles.
    Start facing north at the first hurdle.
    Finish facing north at the end.
    (provided)
    """
    bit = Bit(filename)
    while False and bit.front_clear():  # remove False to run
        solve_1_hurdle(bit)

solve_1_hurdle()

solve_1_hurde() Helpers + Triple Quote

Here is the solve_1_hurdle() code - write this one first, just image that that the helpers exist. Think about pre/post for each.

At the top of the function is a description of what the function does within triple-quote marks - we'll start writing these from now on. The description is just a summary of the pre/post in words.

Q: When calling a helper function, do you think about its internal details? No! Just call it, and know the post condition will get done. Not knowing is power!

def solve_1_hurdle(bit):
    """
    Solve one hurdle, painting all squares green.
    Start facing north at the hurdle's west edge.
    End facing north at the start of the next hurdle.
    """
    go_wall_right(bit)
    bit.right()
    bit.move()
    go_wall_right(bit)
    bit.right()
    go_until_blocked(bit)
    bit.left()
    go_until_blocked(bit)
    bit.left()

Two More Helpers

Now write two more helpers, keeping the pre/post in mind. Earlier claimed that pre/post help to mesh the various functions together, and that's crucial here.

def go_wall_right(bit):
    """
    Move bit forward so long as there
    is a wall to the right. Paint
    all squares green. Leave bit with the
    original facing.
    """
    bit.paint('green')
    while not bit.right_clear():
        bit.move()
        bit.paint('green')


def go_until_blocked(bit):
    """
    Move bit forward until blocked.
    Painting all squares green.
    Leave bit with the original facing.
    """
    bit.paint('green')
    while bit.front_clear():
        bit.move()
        bit.paint('green')

Run vs. Helper Tests

When all the code is written, remove the False from the solve_hurdles() and give it a Run. Previously we had separate testing for each helper which is ideal, and we will do that again in the future. In this case, we just run the whole thing and see if it works without the benefit of helper tests.

This sort of decomposition appears on HW1b - triple and checkerboard - decompose out helper functions as above to solve the whole thing.


Digital Images

RGB Color Scheme

Image = Pixels, Coordinates, RGB

    # Load image into Python "image" variable
    image = SimpleImage('flowers.jpg')
image made of pixels in x,y grid

Best Loop Form: for

for x in collection:
    # use x in here
    x.do_something()

Image1 Code Examples

> Image1 Functions

Image For-Loop - red_channel()

pixel var points to each pixel in turn
def red_channel(filename):
    """
    Creates an image for the given filename.
    Changes the image as follows:
    For every pixel, set green and blue values to 0
    yielding the red channel.
    Return the changed image.
    """
    image = SimpleImage(filename)
    for pixel in image:
        pixel.green = 0
        pixel.blue = 0
    return image

Update Variable: x = x + 1

x = 6
x = x + 1
# what is x now?

image1-b. Make Image Darker

for pixel in image:
    pixel.red = pixel.red // 2
    pixel.green = pixel.green // 2
    pixel.blue = pixel.blue // 2