Learn How to Think with Karel the Robot. Chapter 4. Conditions
Chapter 4
Conditions
In this chapter you will learn:
- What are conditions and why they are used in computer programming.
- Why does Karel need conditions.
- How to use the if statement and the else branch
- How to detect obstacles, collectible objects, and containers.
- New function print and a new command pass.
- About the sensors north, empty and home.
- How to use the full if-elif-else statement.
- How to combine two or more conditions using the keywords not, and, and or.
4.1. What are conditions?
Sometimes we need our program to contain parts which are not executed always, but only in certain situations (conditionally). Imagine, for example, that our program asks the user to enter a credit card number. Users are known to make mistakes. So, when the credit card number is received, the program needs to execute a condition, checking whether the number has 16 digits. If so, then the program can proceed to other tests (is the credit card number valid?) But if not, then the program needs to ask the user to correct his/her input. Conditions are present in every programming language, not only to check user data but for many other types of tests as well.
4.2. Why does Karel need them?
Karel needs conditions to check his sensors. You will learn more about them soon. With the help of his sensors, he can:
- Detect collectible objects and containers on the ground beneath him,
- detect and avoid obstacles in front of him,
- find out which way is North (and from there, any other direction),
- check his GPS coordinates and know where he is in the maze,
- check whether he is at his home square,
- check whether his bag is empty,
- pass through unknown mazes, etc.
4.3. Karel’s wall sensor and the if statement
Karel’s mazes can feature many different types of walls:
The robot has a sensor named wall which helps him detect a wall in front of him. Here "in front
of him" means that the wall is right in front of him - he would crash into it if he made one more
step forward.
Now imagine that Karel is in a new environment that he does not know. He wants to make one step forward. Keep in mind that he does not have eyes, so he cannot see what you see. So, he cannot know if there is a wall in front of him or not:
He knows that he can’t just execute
because if there was a wall in front of him, he would blindly crash into it. So, instead, he uses the
keyword if to check his sensor wall before making the step:
And this was a very good decision indeed, because otherwise he would have crashed! The outcome of Program 4.1 is:
Notice that the keyword left was indented in Program 4.1 - that’s because it forms the body of
the condition.
4.4. What happens if there is no wall?
Now let’s see what happens when the condition is not satisfied:
When Program 4.1 is executed, the condition is not satisfied. Therefore the conditional code - in this case just one command left on line 2 - is skipped. Hence, Karel just executes the command go on line 3 and makes one step forward:
4.5. Other types of obstacles
Besides walls, one can find in Karel’s mazes various other obstacles:
Karel has a dedicated sensor to detect each one. The names of the sensors exactly correspond to
the names of the obstacles. For example, the fire sensor helps him detect fire, the
water sensor helps him detect water, etc. All obstacle sensors work analogously to the
wall sensor, so the robot can detect fire only when the fire is right in front of him,
etc.
All of the thin ones are walls. Some of the thick ones are walls as well, but mainly these are other objects such as fire, water, plant, scorpion, tools, skull, etc.
4.6. Combining loops and conditions
As you have seen in Section 3.10 (page 193), loops can contain other loops. Then we talk about nested loops. In this section we want to show you that loops can also contain conditions. To illustrate it, let’s have Karel play the Game of Arrows. How is this game played?
Karel knows that his home is exactly 33 steps away. Dangerous carnivorous plants are located randomly in the maze. He only knows that when he encounters one, he must turn left - so in fact, each plant serves as a left arrow.
Here is a program which solves this puzzle:
The point of this example was to show you that when a loop contains a condition, then the body of the condition must be indented twice. We are talking about the command left on line 4. You already have seen the accumulation of indents in nested loops in Section 3.10 (page 193). Of course, conditions can contain loops, and conditions can also contain other conditions. And all these can be nested. We will see more examples later.
4.7. Collectible objects
In addition to obstacles, one can find various collectible objects in Karel’s mazes:
Detecting collectible objects works differently from obstacles - Karel must stand above a collectible object (in the same square) to be able to detect it. He has a dedicated sensor for each collectible object, and the name of the sensor exactly corresponds to the name of the object. For example, he can use the sensor beeper to detect beepers on the ground, the sensor spider to detect spiders, etc.
4.8. Collecting bananas
For illustration, let’s look at the following maze where several bananas lie at random positions between Karel and his home square. The home square is 12 steps ahead. The robot’s task is to collect them all:
The robot has a sensor banana which helps him detect bananas on the ground. Here is a
program that solves this task:
Notice that the condition is part of the body of a repeat loop - therefore, the command get on line 3 is indented twice.
4.9. Containers
The third type of objects one can find in Karel’s mazes are containers. Containers are useful when one wants Karel to place collectible objects at a designated place in the maze which he does not know in advance.
When installing a container into the maze, one can define its capacity (number of
objects the container can store) as well as the type of objects which can be stored in
it.
The process of building mazes and creating games will be explained in detail in Appendices A.2 and A.3.
4.10. Collecting coconuts
You already saw Karel collect bananas, now let’s enlist his help collecting coconuts! There are four coconuts placed randomly between the robot and his home square. The home square is 12 steps away. Also, there is a box somewhere between the last coconut and the home square. The blue number 4 located close to the box indicates that the box can store up to four bananas. Karel’s task is to collect all the coconuts and put them into the box:
The program to solve this task is shown below. Notice that it contains a loop which contains a
condition which contains another loop. Hence, the command put on line 6 is indented three
times:
4.11. The else branch
So far we have used the if statement to just skip some code when the condition was not
satisfied. But sometimes one needs to also execute alternative code. This is exactly what the
else branch does!
Imagine that Karel wants to move by one square to the East. If there is a wall in front of him, he needs to go around it. If not, he can just make one step forward:
Here is the corresponding code:
Since the condition on line 1 was satisfied, lines 2-7 were executed and line 9 was skipped. This is Karel’s position after the program ends:
Now let’s see what the program will do when there is no wall:
Since there is no wall in front of the robot, the condition on line 1 is not satisfied. Therefore lines 2-7 are skipped, line 9 is executed, and Karel just makes one step forward:
4.12. Hurdle race
Today Karel participates in a hurdle race! He must get to his home square, jumping over (i.e., going around) several randomly placed walls. His home square is 12 steps ahead:
The solution program is based on Program 4.5:
4.13. Function print
As you already know, Karel shares significant functionality with Python. One such function
is the function print which Karel can use to display text messages. For example,
typing
will generate the following text output:
Notice:
4.14. Sensor north
Karel has a sensor north to detect whether he is facing North (top of your screen).
Let’s try this! We will execute the code below with Karel facing various directions on the
compass:
Here are the outcomes:
4.15. Command pass
Another command which is the same in Karel and in Python is the command pass.
This command is often used as a placeholder for a future code. Or to really do nothing, as we will show in the next section.
4.16. Finding North
Imagine that Karel is facing a random direction - he does not know whether he faces
North, South, East or West. This program will make sure that the robot turns to face
North:
But why does the program begin with repeat3 when there are four major directions on the compass? Well, if the robot already faces North, then he does not have to turn at all. If he faces East, then he must turn left once to face North. If he faces South, then he must turn left two times. And when he faces West, he must turn left three times. So he never needs to turn four times!
Imagine that Karel faces North, and step through the above program in your mind: The condition on line 2 is always satisfied, so the program executes pass three times. The left command is skipped every time.
Now let’s say that the robot faces East. Then the condition is not satisfied in the first cycle, and therefore Karel turns left. But then he faces North, so in the remaining two cycles the condition is satisfied, and so the program executes pass in the second and third cycles of the loop.
Analogously, when the robot faces South, then the condition is not satisfied in the first cycle, and Karel turns left. Then he faces East. So, the condition is not satisfied in the second cycle either, and he turns left again. Then he faces North, so in the third cycle the condition is satisfied and the robot does not turn anymore.
When Karel faces West, then the condition will never be satisfied. In the first cycle he turns left to face South, in the second cycle he turns left to face East, and finally in the third cycle he turns left to face North.
As a conclusion - no matter what direction he faces initially, Karel will always face North after the program finishes. Below is a graphical breakdown of the analysis. Let’s begin with the case when Karel initially faces North. The four images in the row show where he is facing initially and then after the first, second, and third cycle of the loop:
4.17. Keyword not
Karel has a keyword not which can be used to reverse the outcome of conditions. For example,
ifnotwall is satisfied when ifwall isn’t, and vice versa.
The behavior of the keyword not can be summarized in the following table:
condition | not condition |
Satisfied | Not satisfied |
Not satisfied | Satisfied |
Let’s look again at Program 4.9:
Using the keyword not, it can be simplified to:
Isn’t this neat? But hold on, in Chapter 5 we will show you how this program can be simplified further to only two lines!
4.18. Sensor empty
Karel has a sensor empty to check whether his bag is empty. When in doubt whether the robot is
carrying any objects, checking this sensor prior to executing the put command will prevent the
program from crashing:
The empty sensor is useful in many other situations as well - for example, when the robot needs to remove all objects from his bag:
To be clear - the robot cannot know the number of objects in his bag. He does not have a
sensor that would count the objects or anything like that. Here is the corresponding
code:
Here is the outcome of the program (there were seven nuggets in the bag):
The empty sensor also can be used to have Karel collect only the first of several objects:
When Karel’s bag is initially empty, the following program will do it:
When the program finishes, Karel brings home one water bottle only:
4.19. Keyword and
As you could see, Program 4.13 had two nested conditions: ifbottle inside of ifempty. As a
result, the command get on line 4 was only executed when both these conditions were
satisfied. But Karel has a keyword and which can do the same in a much simpler
way!
The single condition ifemptyandbottle is identical to the two nested conditions. So,
Program 4.13 can be simplified:
This table summarizes how the keyword and works:
condition1 | condition2 | condition1 and condition2 |
Satisfied | Satisfied | Satisfied |
Satisfied | Not satisfied | Not satisfied |
Not satisfied | Satisfied | Not satisfied |
Not satisfied | Not satisfied | Not satisfied |
4.20. Bounty
Let’s show one more example which uses the keyword and. This time Karel is in a mine, and he found an unknown number of gold nuggets. Now he needs to put them on mining carts (one nugget per cart). The number and positions of the carts are unknown too:
If he knew that he has enough nuggets to put one on each cart, then he could use the following program:
But he does not know that, and the program will fail if there aren’t enough nuggets in Karel’s
bag. Namely, at some point the robot will attempt to put a nugget on a cart when his bag is
empty. The solution to this problem is very simple though - all he needs to do is also check that
his bag is not empty before placing a nugget:
Notice that the expression notempty is enclosed in parentheses.
It turns out that Karel had four nuggets in his bag, so when the program finishes, only four carts are loaded:
4.21. Keyword or
Today Karel needs to collect nuggets and gems which are placed randomly between him and his home square.
This could be done with the following program:
However, as you can see, there are two conditions with the same body which are checked
separately, one after another. In a situation like this, the code can be simplified using the
keyword or:
Importantly - Karel needs to collect nuggets and gems, but typing ifnuggetandgem on line 2
would be a mistake. Namely, Karel would be checking for squares which contain both a nugget
and a gem. Such a condition would never be satisfied, so Karel would not collect anything. With
the current line 2, using the keyword or, the condition will be satisfied when Karel detects any
of the two objects - a nugget or a gem.
The following table summarizes how the keyword or works (for two conditions). It can be used to combine three, four, or even more conditions as well.
condition1 | condition2 | condition1 or condition2 |
Satisfied | Satisfied | Satisfied |
Satisfied | Not satisfied | Satisfied |
Not satisfied | Satisfied | Satisfied |
Not satisfied | Not satisfied | Not satisfied |
4.22. Danger
This time Karel has a difficult task to find his home square in a wall of fire, water, and acid! The position of his home, as well as the positions of the fire, water, and acid are unknown:
The following program will solve the task:
2 if fire or water or acid
3 # Move one square to the right:
4 right
5 go
6 left
7 else
8 # You are in front of the home square - do nothing:
9 pass
10# Make one final step home:
11go
In Chapter 5 we will show you how this program can be simplified using a different type of loop.
4.23. Sensor home
Karel has a sensor home to check whether he is in his home square. For illustration, let’s write a simple program for the robot to walk straight ahead until he reaches his home square, and to stay there. He does not know how far ahead the home square is:
Karel knows that the width of the maze is 15 steps, so he uses a repeat loop with 15
cycles:
In Chapter 5 we will show you a different type of loop which will make this task easier to solve.
4.24. The full if-elif-else statement
The Karel language provides the full Python-style if-elif-else statement which is useful when one has more than two options to choose from. The keyword elif is an abbreviation of "else if", which makes its meaning self-explanatory. The general form of the if-elif-else statement is
In place of the ellipsis (the three dots) can be one of more additional elif branches.
Today, Karel needs to sort the treasures he collected in the mines. Located randomly between him and his home square lie on the ground light bulbs, gold nuggets, and gems. He needs to collect the bulbs, move the nuggets one square up, and the gems one square down:
The solution program looks as follows:
2 go
3 if nugget # move nuggets one square up
4 get
5 left
6 go
7 put
8 right
9 right
10 go
11 left
12 elif gem # move gems one square down
13 get
14 right
15 go
16 put
17 left
18 left
19 go
20 right
21 else # it’s a bulb
22 get
23go
When the program finishes, Karel is at his home square, and the treasures are sorted!
4.25. More is coming!
In this chapter we have only shown you the basic use of Karel’s sensors and the if, if-else and if-elif-else statements. There is much more that can be done with them. In the following chapters we will introduce the Boolean values True and False, as well as Boolean expressions, variables and functions. You will learn that Karel’s sensors are in fact Boolean functions. So, keep reading!
4.26. Review questions
Friendly reminder - for every question either none, one, or several answers may be correct.
QUESTION 4.1. Why are conditions used in computer programming?
- A
- To repeat commands or sequences of commands.
- B
- To check user data.
- C
- To make runtime decisions.
- D
- To correct syntax errors.
QUESTION 4.2. Why does Karel need conditions?
- A
- To detect and avoid obstacles.
- B
- To execute commands.
- C
- To find out which way is North.
- D
- To check whether his bag is empty.
QUESTION 4.3. When is the body of a condition executed?
- A
- Always.
- B
- When the condition is satisfied.
- C
- When the condition is not satisfied.
- D
- Never.
QUESTION 4.4. When can Karel detect an obstacle?
- A
- When it is one step ahead.
- B
- When it is less than two steps ahead.
- C
- When it is is an adjacent grid square.
- D
- When it is right in front of the robot.
QUESTION 4.5. When can Karel detect a collectible object?
- A
- When it is right in front of the robot.
- B
- When it is in an adjacent grid square.
- C
- When it is beneath the robot.
- D
- When it is above the robot.
QUESTION 4.9. What is the else branch used for?
- A
- For code to be executed when the condition is not satisfied.
- B
- For code to be executed after the body of the condition.
- C
- For code to be executed before the body of the condition.
- D
- For code to be never executed.
QUESTION 4.10. What is the correct way to display Helloworld! in Karel?
- A
- print(Hello world!)
- B
- print(~Hello world!~)
- C
- print Hello world!
- D
- print[~Hello world!~]
QUESTION 4.11. When is the condition ifnorth satisfied?
- A
- When the robot faces North.
- B
- When the robot does not face North.
- C
- When the robot is in the top (North) row of the maze.
- D
- When the robot is in the bottom row of the maze, facing North.
QUESTION 4.12. What does the command pass do?
- A
- It bypasses a condition.
- B
- It bypasses a loop.
- C
- It does nothing.
- D
- It bypasses the else branch.
QUESTION 4.13. Karel is facing South. What direction will he face when the following program finishes?
- A
- North
- B
- South
- C
- West
- D
- East
QUESTION 4.14. When is the condition ifempty satisfied?
- A
- When all collectible objects in the maze have been collected.
- B
- When Karel’s bag is empty.
- C
- When all containers in the maze are empty.
- D
- When at least one container in the maze is empty.
QUESTION 4.15. What line of code is equivalent to the following nested conditions?
- A
- if north and (not wall)
- B
- if north or (not wall)
- C
- if north (and not) wall
- D
- if north (or not) wall
QUESTION 4.16. Condition1 and Condition2 is satisfied when:
- A
- Condition1 is satified, Condition2 is satisfied.
- B
- Condition1 is not satified, Condition2 is satisfied.
- C
- Condition1 is satified, Condition2 is not satisfied.
- D
- Condition1 is not satified, Condition2 is not satisfied.
QUESTION 4.17. Condition1 or Condition2 is satisfied when:
- A
- Condition1 is satified, Condition2 is satisfied.
- B
- Condition1 is not satified, Condition2 is satisfied.
- C
- Condition1 is satified, Condition2 is not satisfied.
- D
- Condition1 is not satified, Condition2 is not satisfied.
QUESTION 4.18. Karel stands above a nugget (there is no gem beneath him). Which of the following conditions will be satisfied?
- A
- if gem and nugget
- B
- if gem or nugget
- C
- if gem and (not nugget)
- D
- if (not gem) or (not nugget)
QUESTION 4.19. Karel stands above a beeper and faces a wall. Which of the following conditions will be satisfied?
- A
- if beeper and wall
- B
- if beeper and (not wall)
- C
- if (not beeper) or wall
- D
- if beeper or (not wall)
QUESTION 4.20. Karel stands above a spider, away from walls, looks West, and his bag is empty. What will the following code print?
2 print(~I am looking West!~)
3elif wall
4 print(~I don’t see any walls!~)
5elif not empty
6 print(~My bag is empty!~)
7else
8 print(~There is a spider!~)
- A
- I am looking West!
- B
- I don’t see any walls!
- C
- My bag is empty!
- D
- There is a spider!
Table of Contents
- About
- 1. Introduction
- 2. Basic Commands
- 3. Counting Loop
- 4. Conditions
- 5. Conditional Loop
- 6. Custom Commands
- 7. Variables
- 8. Functions
- 9. Text Strings
- 10. Testing Your Programs
- 11. Boolean Values, Variables, Expressions, and Functions
- 12. Randomness and Probability
- 13. Lists
- 14. Recursion
- 15. Advanced Applications
- Appendix A. Karel App in NCLab
- Appendix B. Self-Paced Karel Course in NCLab