Cleaver Karel

Jed Rembold & Fred Agbo

January 17, 2025

Announcements

  • Problem Set 1 posted and it’s due on Monday Jan. 27th @ 10pm!
    • You’ll have basically all you need to solve it after today
  • Small section meeting is starting next week
    • watchout for an email from Prof. Jed on when your section meets
    • If you did not recieve Prof. Jed’s email by Tuesday, you must not have filled out the availability poll.
    • Come see me after class and we can see about getting you placed into one.
  • Polling today! Use this link
    • Reminder: use your first name and be consistent to be able to uniquely identify you!

Inception: Loops in Loops

  • Whenever a loop ends, you just return to the same indentation level as when that loop began

  • For loops inside other loops then, this means that the “inner-most” loop runs from start to finish for every step of the outer loop

    while front_is_clear():
        move()
        while not_facing_north():
            turn_left()
        turn_left()
    put_beeper()

Understanding Check

Karel starts as shown to the right with 20 beepers in its bag. After executing the commands below, how many beepers are left in the bag upon the conclusion of the program?

while left_is_clear():
    while front_is_clear():
        move()
        if no_beepers_present():
            put_beeper()
    turn_left()

  1. 12
  2. 13
  3. 15
  4. 19

Counting Loops

  • Sometimes we know the number of times we want to loop

    • It is not dependent on some condition like a while loop
  • In these circumstances, the iterative statement called a for loop is best used

  • Syntax looks like:

    for i in range(desired_count):
        # statements to be repeated
    • desired_count is an integer indicating the number of times you want the loop to repeat
    • The i is a name that we will later make more general, but for now you can always leave it as an i

An Example for you

  • Suppose we want Karel to create a 6x6 square outline of beepers in a room
  • Need to repeat making each side 4 times
  • Need to repeat placing a beeper and moving 6 times for each side
    • Placing 6 beepers requires moving only 5 times. So not everything can be in the loop

A Potential Solution

import karel

def main():
    """Draw a 4x4 square in the world."""
    position()
    draw_box()

def position():
    """Move to starting corner of box."""
    move()
    move()
    turn_left()
    move()
    move()
    turn_right()

def turn_right():
    """Turns Karel 90 deg to the right."""
    turn_left()
    turn_left()
    turn_left()

def draw_box():
    """Draws a box with 4 equal sides in a CCW direction."""
    for i in range(4):
        draw_6_line()
        turn_left()

def draw_6_line():
    """Draws a straight line of 6 beepers, if space."""
    for i in range(5):
        if no_beepers_present():
            put_beeper()
        if front_is_clear():
            move()
    if no_beepers_present(): # Last beeper to make 6
        put_beeper()

Summary So Far

  • Karel can only:
    • move()
    • turn_left()
    • pick_beeper()
    • put_beeper()
  • Can get info about surroundings using predicate functions
    • Eg. front_is_clear()
  • Group code into bundles

    def function_name():
        # Code to be grouped
  • Conditional statements
    • Run certain code blocks only if a condition is true

      if condition_test:
          # Code if answer yes
      else:
          # Code if answer no
  • Iterative statements
    • while loop: repeat code block as long as condition is true

      while condition_test:
          # Code to repeat
    • for loop: repeat set number of times

      for i in range(desired_count):
          # Code to repeat

Algorithms

  • The process of designing a solution strategy to a problem is called algorithmic design
  • An algorithm is just an approach or recipe for a method to solve a particular problem
    • Frequently language agnostic
  • Algorithms are not a new concept
    • Euclids algorithm to find greatest common denominators for instance
  • A large part of computer science is focused on the study or analysis of algorithms

Algorithm ⮕ Code

  • You need to have an algorithm in place before you can write the code to tell the computer what you want to do
    • Imagine an alien asking me how to bake a cake. I need to understand the steps to baking the cake before I can even worry about the translation or communication
  • Programming tools like conditional statements and loops will frequently play a role in your algorithm, but as general concepts
    • I can easily describe a loop to you without needing the exact syntax of Python
  • The implementation of the algorithm is the act of translating it into Python (or whatever language you are using)

An Amazing Algorithm

  • Consider a simple, loop-less, maze that we want to move through
    • Karel could start anywhere
    • The end of the maze is a beeper
  • A common algorithm to get through the maze is to essentially always follow or touch the wall to your right
    • How could we phrase this in language Karel would understand?
  • Let’s take a few minutes to work with a neighbor(s) to sketch out your code

An Amazing Algorithm

  • Practically speaking, this largely means to go forward unless a passage opens to your right, in which case you take that passage
  • In Karel, since the exit is a beeper, we might implement the above algorithm as:
while no_beepers_present():
    # if opening on right, we follow
    if right_is_clear():
        turn_right()
        move()
    else:
        # go forward if possible or turn
        if front_is_clear():
            move()
        else:
            turn_left()

Stepwise Refinement

  • The most successful way to solve a complex problem is to break it down into progressively simpler problems
  • Begin by breaking the whole problem into a few simpler parts
    • Some of these parts might then need further breaking down into even simpler parts
  • The process is commonly called stepwise refinement or decomposition

Excellent Decomposing

  • A good problem decomposition should mean:

    The proposed pieces should be easy to explain
    One indication that you have succeeded is if it is easy to give them simple names
    The steps are as general as possible
    Each piece of code you can reuse is one less piece of code you need to write! If your steps solve general tasks, they are much easier to reuse.
    The steps should make logical sense for the problem you are solving
    If you have a function that will work to solve a step but was designed (and named) with something else entirely in mind, adopt it for the currently needed situation

Enter the Winter

  • Suppose we want Karel to usher in the Fall/Winter by removing the “leaves” from the tops of all the trees

Understanding the Problem

  • What are we guaranteed by the problem?
  • How will we know when we are done?

Understanding the Problem

  • There are four trees in this problem
  • We need to find a tree at a time
  • We need to remove the leaves
    • there are four leaves per tree

Top-Level Decomposition

  • We could break this problem into two main subproblems:
    1. Find the next tree
    2. Strip the leaves off that tree

Top-Level Decomposition

  • We could break this problem into two main subproblems:
    1. Find the next tree
    2. Strip the leaves off that tree

Top-Level Decomposition

  • We could break this problem into two main subproblems:
    1. Find the next tree
    2. Strip the leaves off that tree

Top-Level Decomposition

  • We could break this problem into two main subproblems:
    1. Find the next tree
    2. Strip the leaves off that tree

Top-Level Decomposition

  • We could break this problem into two main subproblems:
    1. Find the next tree
    2. Strip the leaves off that tree

Top-Level Decomposition

  • We could break this problem into two main subproblems:
    1. Find the next tree
    2. Strip the leaves off that tree

Top-Level Decomposition

  • We could break this problem into two main subproblems:
    1. Find the next tree
    2. Strip the leaves off that tree

Top-Level Decomposition

  • We could break this problem into two main subproblems:
    1. Find the next tree
    2. Strip the leaves off that tree

Top-Level Decomposition

  • We could break this problem into two main subproblems:
    1. Find the next tree
    2. Strip the leaves off that tree

Remember Your Algorithms!

  • Algorithmic design: The process of designing a solution strategy to a problem
  • An algorithm is just an approach or recipe for a method to solve a particular problem
    • Frequently language agnostic
  • Can you design algorithm to address the Fall/Winter problem?

Algorithm ⮕ Code

  • for four iterations
    • find a tree
    • then remove leaves
  • while the front is clear
    • keep moving
  • move up the tree
  • remove each leaf
  • move down the tree

Algorithm ⮕ Code

import karel
def main():
    # Here is our general solution with higher level of decomposition
    for i in range(4):
        find_next_tree()
        remove_leaves()
def find_next_tree():
    # the codes to find next tree
    while front_is_clear():
        move()
def remove_leaves():# codes to remove leaves
    move_up()
    deleaf()
    move_down()

def move_up(): # to move karel up the tree
    turn_left()
    while right_is_blocked():
        move()

def deleaf(): # function to deleaf
    pick_beeper()
    for i in range(3):
        move()
        pick_beeper()
        turn_right()
    turn_left()

def move_down(): # to move karel downward
    while front_is_clear():
        move()
    turn_left()

Class Activity?

// reveal.js plugins