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:
When you finish, the world should look like this:
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:
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
:
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:
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:
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:
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:
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:
and should end like this:
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:
At the end, it should look like this:
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:
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:
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?
- “make a decision” sounds like it will need an
- Go until…
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
Task | Description | Points |
---|---|---|
Run to the lake! | Your solution works | 1 |
To infinity… | Your solution works | 2 |
Roofing the house | Your solution works | 1 |
Not too far! | Your solution works | 2 |
Invert | Your solution works | 1 |
Invert…carefully | Your solution works | 1 |
Bit the Wanderer | Your solution works | 2 |