BYU logo Computer Science

To start this guide, download this zip file.

Practice with conditions

These problems will give you a chance to practice using if statements with conditions that include and, or, and not. Use the event stream pattern, and think carefully about what conditions you need.

Download the zip file above and put it in your bit folder.

Freedom

For this problem, Bit starts in this world:

Bit in a world with some black squares on both sides

Can you move Bit to the first space open on both sides? This is how the world should look when it is done:

Bit has moved to a place where both the left and right are open

You can find some starter code in freedom.py:

from byubit import Bit


@Bit.worlds('freedom')
def go(bit):
    # Write code here
    pass


if __name__ == '__main__':
    go(Bit.new_bit)

Planning

When should Bit stop? What is the condition you would use? Express this in words, not Python code.

work with a friend to solve this problem

There are two ways to think of this:

  • Bit should move until the left is clear and the right is clear.
  • Bit should move if the left is not clear or the right is not clear.

Solution #1

Let’s start by looking at how the first solution would work — Bit should move until the left is clear and the right is clear.

You can write this with the following functions:

def found_freedom(bit):
    return bit.left_clear() and bit.right_clear()


@Bit.worlds('freedom')
def go(bit):
    while not found_freedom(bit):
        bit.move()

We have put the stopping condition the left is clear and the right is clear into a function called found_freedom() that returns True if those conditions are met.

Then in go() Bit keeps moving while not found_fredom(bit). In other words, Bit has to keep moving while the condition is not met.

Add this to your code and run it to see it working!

Solution #2

Let’s now write code so that we follow the second suggestion, Bit should move if the left is not clear or the right is not clear. You can write this with the following functions:

def keep_moving(bit):
    return not bit.left_clear() or not bit.right_clear()


@Bit.worlds('freedom')
def go(bit):
    while keep_moving(bit):
        bit.move()

Here, instead of a stopping condition we have keep moving condition. We write this in the function keep_moving() that returns True if either the left is not clear or the right is not clear.

Then in go() Bit keeps moving while keep_moving(bit). In other words, Bit keeps moving while the condition is met.

Add this to your code and run it to see it working!

Spiral

For this problem, Bit starts in this world:

Bit in a world with some black squares

Can you move Bit in the shape of a spiral? This is how the world should look when it is done:

Bit has moved in a spiral

You can find some starter code in spiral.py:

from byubit import Bit


@Bit.worlds('spiral')
def run(bit):
    pass


if __name__ == '__main__':
    run(Bit.new_bit)

Planning

This problem looks more complex, but it can be simple if you focus on conditions. When should Bit stop? When should it turn left?

work with a friend to solve this problem

An important thing to notice is that the spiral stops when Bit reaches a square where the front and the left are not clear.

  1. The stopping condition for Bit is if the front is not clear and the left is not clear.

  2. Bit should keep moving forward when it can, but turn left if the front is blocked.

Solution

Here is one way to write these conditions:

def end_of_spiral(bit):
    return not bit.front_clear() and not bit.left_clear()


@Bit.worlds('spiral')
def run(bit):
    bit.paint('blue')
    while not end_of_spiral(bit):
        if not bit.front_clear():
            bit.left()
        bit.move()
        bit.paint('blue')

We use the end_of_spiral() function to have the stopping condition. It stops if the front is not clear or the left is not clear.

We use the run() function to keep Bit moving and painting blue. We use while not end_of_spiral(bit) to keep Bit moving unless the stopping condition is met. Along the way, if the front is ever not clear, Bit turns left.

Notice that we also need an extra bit.paint('blue') to get the first square.

An alternate solution

It’s important to recognize that there are multiple solutions to many problems! For example, you could instead write conditions like this:

  1. Bit moves as long as the front is clear

  2. If the front is ever not clear, Bit turns left.

Notice that if both the front and left are not clear, Bit will turn left, and then the front will be blocked. We need to be sure Bit doesn’t turn left again! That makes this solution a little more tricky to write.

Here is one way to do it:

@Bit.worlds('spiral')
def run(bit):
    while bit.front_clear():
        bit.paint('blue')
        bit.move()
        if not bit.front_clear():
            bit.left()

    bit.paint('blue')

Notice a few things that are different from the first solution. Bit needs to paint first, then move. At this point, if the front is not clear, Bit turns left. This way Bit can keep moving forward as long as the front is clear. But if it turns left and the front is blocked, it will stop and not turn again. Finally, we have to be sure the last square is painted blue, since Bit paints before it moves.