Functions¶

In [1]:
from byubit import Bit

@Bit.run_from_empty(5, 3)
def go(bit):
    while bit.front_clear():
        bit.move()
        bit.paint('green')

go_green.py¶

NOTES

Look at the go_green.py file and learn about how we can define our own functions.

  • A function parameter serves as another name for whatever is passed to the function.
  • In go, we use bit to refer to Bit
  • In go_green we could use cosmo or jousting_dogs to refer to whatever was passed to it
    • Try to come up with names that help you remember what the variable actually represents
  • The names a function uses are called its scope

NOTES

  • Draw out the scope of go and the scope of go_green
  • Show how bit points to something on the heap (a bit world)
  • Show how when go_green is called, cosmo now points to that same thing on the heap
  • Show how using the name bit in go_green is different than bit in go
  • Discuss good naming. bit is good, cosmo not so much, thing even worse, color worse still.

Try running the code:

  • without paretheses: go_green
  • without the parameter: go_green()

What happens?

NOTES

Didn't invoke the function: missing parentheses

NOTES

Missing positional argument. The name the error gives you is the name of the parameter in the function you tried to call.

How can we figure out where the problem was? For example, was it the first or second call to go_green?

In coming weeks, we'll talk about other tools that make this easier in complex programs.

For now, you can use bit.snapshot to put breadcrumbs in the program to figure out where the problem is happening.

When naming a function:

  • Use underscore _ (next to the zero key + shift) to break up compound names
    • go_green instead of gogreen or goGreen
  • use lower-case characters
    • go instead of Go or GO
    • Casing matters: go is different from Go!
In [7]:
from byubit import Bit


def go_green(bit):
    """
    Bit moves in the direction it is already facing
      and goes until it is blocked in front
    Bit paints each square green, 
      except for the starting square
    """
    while bit.front_clear():
        bit.move()
        bit.paint('green')

        
@Bit.run_from_empty(4, 3)
def go(bit):
    go_green(bit)
    bit.left()
    go_green(bit)
  • docstrings allow us to document our functions
  • If the first line of a function is a string, it is used as the docstring
  • The triple quotes """ allow us to include multiple lines in the same string.
Functions give you the ability to create and name new ideas.

The concept of creating and naming new ideas is called abstraction

Programming is all about the art of abstraction

Blue Ocean 👨🏿‍🎨¶

blue_ocean.py¶

Fill the world with blue.

Bit gives us move, paint, etc.

What new verbs would make this job even easier?

NOTES

We've done problems like this before (nested while, etc.), but this is the first time we are using functions to define the pieces. The emphasis of this exercise is on the decomposition and abstraction of the parts, and then putting those parts together.

Several strategies to consider:

  • Row-by-row, zig-zag
  • Row-by-row, down-and-back
  • Column-by-column
  • Spiral

Which seems easiest? Why?

  • Computers (and humans!) don't do well will uncertainty. We like strategies with 0% uncertainty.
  • When we loop through a block of code, we want to know exactly where Bit will be before and after each iteration.
  • When we call a function, we want to know exactly where Bit will be before and after the function call.

NOTES

  • implement go using fill_row_with_blue(bit) (even though it isn't defined yet)
  • Then define and implement fill_row_with_blue

  • What are the boundary conditions of fill_row_with_blue?

    • Where does bit start?
    • Where does bit end?
    • Notice how the prep (turn up) and the down-and-back make the problem easier

Remember¶

  • Choose strategies that minimize uncertainty
  • Pick concise but accurate and helpful names for your functions
  • Document the purpose and boundary conditions of the function
    • What does the function accomplish?
    • Where does Bit start? What direction is he facing?
    • Where does Bit end? What direction is he facing?

Hurdles 👩🏼‍🎨¶

  • What pattern or strategy best fits this problem?
  • What verbs would make this problem easy to solve?

NOTES

The event stream pattern works well: the event is running into a jumpable wall (left clear). The event loop runs until Bit cannot jump anymore.

  • You can also use "up" and "drop" as events with and if/else as opposed to a single "jump hurdle" event
    • But this is a bit tricky: the order of conditions is critical

The mosaic pattern could work: move to the base of the first hurdle, then jump hurdles (which includes advancing to the next) until left is not clear.

  • Approach this using the event-stream pattern, instead of the mosaic pattern used by Stanford

    • Note that the world is slightly different that Stanford's and would require a little setup first (move to base)
  • Note that "up" and "over" are similar, vs "down"

Key Ideas¶

  • functions, def
    • arguments (a.k.a. parameters)
  • abstraction
    • the art of abstraction: learning how to create ideas that are easy to understand and fit together well
  • boundary conditions: fitting the pieces together
  • mosaic pattern: fitting repeated pieces together
  • event-stream pattern: moving towards a goal while performing tasks on cue