BYU logo Computer Science

Lab 2 — Loops and Control With Bit

To begin, use PyCharm to create a project called lab-2. You should do all your work there.

Next, download lab-2-files.zip. This is a zip file, so you will need to extract its contents. You should put the files inside of a folder called lab-2 in your CS 110 folder. These files contain worlds. A world is a file that contains a description of what Bit sees.

You should have a folder called lab-2/worlds/, and then a bunch of files in there.

You are going to write your code in the lab-2/ folder.

Run to the Lake!

Bit: “How do I get to the lake?”

Helpful passerby: “Take a left a the stop sign.”

For this problem, make Bit do the following:

  • go straight until it reaches a red square
  • turn left
  • go straight until it reaches a blue square
  • paint all squares green, except those that are red or blue.

Use the file go-to-lake-start.txt as the starting world for Bit. You can load this file with:

bit = Bit.load("worlds/go-to-lake-start.txt")

When you start, the world looks like this:

lake start

When you finish, the world should look like this:

lake finish

Create a file called lake.py and write your code there. You should by loading the world:

from byubit import Bit
bit = Bit.load("worlds/go-to-lake-start.txt")

Once you are done, you can use this command to check your solution:

bit.compare(Bit.load("worlds/go-to-lake-finish.txt"))

There are many ways to solve this.

Try a solution with

while ...:
    bit.paint("green")
    bit.move()

and another solution with

while ...:
    bit.move()
    bit.paint("green")

Does one solution require more code than the other?

Which solution do you like more? Why?

To Infinity…

Bit is trying to paint a square. It should look like this:

blue square

But something isn’t working right! Run the code in square.py. What happens?

Please fix it.

Roofing the House

Help Bit build a roof for his house.

The roof should be red. It can extend 3 squares beyond a truss. If there is another truss under the third square, the roof can continue to extend.

Write your code in a file called roofing.py. Here is a starting world, in roofing-start.txt:

roofing start

The trusses are shown in black.

Remember, you can load this with:

from byubit import Bit
bit = Bit.load("worlds/roofing-start.txt")

Now implement your solution, which should look like this when you are done:

roofing finish

You can compare your solution with:

bit.compare(Bit.load("worlds/roofing-finish.txt"))

Observation

For a loop to continue iterating, the condition of the loop does not need to be true the whole time the body of the loop is running. It only needs to be true when the condition is evaluated.

For example, consider the following while loop:

while bit.get_color() == "blue":
    bit.move()
    bit.move()

If Bit starts on a "blue" square, then Bit will move twice: once from the first "blue" square to the second square, and once from the second square to the third. If the third square is "blue", then the loop will repeat, but the second square could be any color!

🧐 It is important to remember that the condition of a while loop is only checked at the beginning of the loop body. Then the body of the loop is executed. Finally, the whole process repeats until the loop condition is false.

Not too far!

Look where you are going

Bit code cannot just do a move() any old time. If Bit moves into a black area, the move is blocked and the program returns an error. To prevent this, each a move needs to be preceded by a front_clear() check.

Double Move

The goal of this problem is to paint every other square red in a row (the first square clear, the second square red). You ignore the first square. Here is an example of a 9x3 world:

double red start

Write your code in a file called double-red.py. You can create this world with:

from byubit import Bit
bit = Bit.new_world(9, 3)

At the finish, the world should look like this:

double red finish

You can compare your solution with:

bit.compare(Bit.load("worlds/double-red-finish.txt"))

Does your same code work for a 10x3 world?

from byubit import Bit
bit = Bit.new_world(10,3)

It should draw this:

double red2 finish

You can compare your solution with:

bit.compare(Bit.load("worlds/double-red2-finish.txt"))

#Tip

An interesting part of this problem is that Bit needs to move twice — once for the blank square and once for the red one. The first move is covered by the front_clear() check, but the second move is not.

We can solve this with an if statement. Add an if statement before the second move, and make the second move conditional on the if statement.

The while condition protects the first move, and if the front is still clear, Bit can make the second move.

Be sure your code works on both scenarios.

Invert

Change every empty sqaure to blue and every blue sqaure to empty.

Note, you can erase a color using bit.erase()

Write your code in a file called invert.py. Start the world with the file called invert-start.txt. Follow our previous examples in this lab to load this world.

The world starts like this:

invert start

and should end like this:

invert start

You can compare with:

bit.compare(Bit.load("worlds/invert-finish.txt"))

Invert…Carefully

For this problem, the rules are:

  • change blue squares to empty
  • change empty squares to blue
  • leave everything else alone

Write your code in a file called invert2.py. The starting world is in the file invert2-start.txt and looks like this:

invert2 start

At the end, it should look like this:

invert2 finish

You can compare your solution with:

bit.compare(Bit.load("worlds/invert2-finish.txt"))

if, elif, and else

if and else work when you have two outcomes to pick from:

“Is my condition true? Yes: do if-block. No: do else-block.”

What if you have more than two outcomes? For example, consider the case below where we are trying to move Bit to a space that is clear.

if bit.front_clear():
    bit.move()

elif bit.left_clear():
    bit.left()
    bit.move()

elif bit.right_clear():
    bit.right()
    bit.move()

else:
    pass  # Bit is trapped, so nothing to do

We use elif to mean “else if”, mashing “else” and “if” together.

It’s also important to note that Python doesn’t like empty blocks for if or while. In this case, you can use pass if you have a block that doesn’t need any code.

Checking for an empty square

What color is an empty square? It’s None. So you can check for this with:

if bit.get_color() is None:

Bit the Wanderer

For this problem, the starting world is in wander-start.txt and looks like this:

wander start

The rules for bit are:

  • paint the starting block green
  • move Bit forward when you can
  • paint new blocks blue
  • if Bit is blocked in front, turn in the direction that is clear
  • if Bit is blocked in every direction, stop
  • paint the ending block red

The finished world should look like:

wander finish

You can compare your result with:

bit.compare(Bit.load("worlds/wander-finish.txt"))

You’ll need a few new bricks in your bag for this.

Multiple conditions

When you want to test for whether two or more conditions are all true, use and:

while bit.front_clear() and bit.left_clear() and bit.right_clear():
    ...

If you want to test whether any of a set of conditions are true, use or:

while bit.front_clear() or bit.left_clear() or bit.right_clear():
    ...

Nested loops

You will also want to use nested loops.

  • The outer loop is controlled by condition A
  • The inner loop is controlled by condition B
while <condition A>:
    # May need code here?
    while <condition B>:
        # Will definitely need code here

❗️Remember, indentation matters!

The inner loop will have more indentation than the outer loop.

Strategy:

  • What is the condition of the outer loop?
    • How do we know our solution is complete?
  • What are the two pieces of the outer loop body?
    • Go until…
      • “go until” sounds like it will need a loop.
      • What is the condition of this loop?
    • Then make a decision…
      • “make a decision” sounds like it will need an if.
      • What is the condition to test?

Lessons

What we want you to get from this lab:

  • You feel confident writing while loops and choosing the expression for the while loop

  • You feel confident writing if statements and choosing the conditions for the if statements

  • You know when to use a while loop and when to use an if statement

  • You can think carefully about what is needed before you write your code

  • You can figure out what went wrong when something unexpected happens

  • Hopefully you had fun!

Points

TaskDescriptionPoints
Run to the lake!Your solution works1
To infinity…Your solution works2
Roofing the houseYour solution works1
Not too far!Your solution works2
InvertYour solution works1
Invert…carefullyYour solution works1
Bit the WandererYour solution works2