Learn How to Think with Karel the Robot. Chapter 8. Functions

Chapter 8
Functions

In this chapter you will learn:

  • How to define and use functions which return values.
  • About functions which accept arguments.
  • About local and global scopes.
  • The difference between local and global variables.
  • That using global variables may lead to problems.
  • If functions can change the values of their arguments.

8.1. Defining and using functions

You already know how to define and use custom commands. A function is very similar to a command but in addition it uses the return statement to return a value. Functions also can accept arguments - this will be discussed in Section 8.6 (page 727). But for the time being let us stay with functions which do not need any arguments.

One of them is a simple function distance which will measure Karel’s distance to the nearest wall. The robot will simply walk to the wall, count his steps, and at the end return their number:


PIC

Figure 8.1: *

Karel measures the distance to the nearest wall.


Here is the corresponding program:

Program 8.1: Karel measures the distance to the nearest wall
1# Walk to the nearest wall, count steps, and return their number: 
2def distance 
3  d = 0 
4  while not wall 
5    go 
6    inc(d) 
7  return d 
8 
9# Call the function and display the result: 
10result = distance 
11print(~The distance was~, result, ~steps.~)
picture

On line 10, the value returned from the function was assigned to the variable result. Since the sole purpose of this variable was to provide the value to the print statement, it could be omitted. The function call could be placed into the print statement directly:

Program 8.2: Function call is placed directly into the print statement
1# Walk to the nearest wall, count steps, and return their number: 
2def distance 
3  d = 0 
4  while not wall 
5    go 
6    inc(d) 
7  return d 
8 
9# Call the function and display the result: 
10print(~The distance was~, distance, ~steps.~)

And here is the outcome of the program:


PIC


8.2. Builder

This time, Karel’s task is to measure the length of a straight wall. He stands just South of it, facing North.


PIC

Figure 8.2: *

Karel needs to measure the length of a wall.


First he must locate one end of the wall - say the left one:


PIC


This can be done using the following code:

1# Locate the left end of the wall: 
2while wall 
3  left 
4  go 
5  right 
6right 
7go 
8left

Then, he can create a new variable named length, and move along the wall until he reaches its other end:


PIC


After every step, he increases the value of length by one:

1# Measure the length: 
2length = 0 
3while wall 
4  right 
5  go 
6  left 
7  inc(length)

The above two code segments can be used to define a function measure which will be easily reusable to measure the length of any straight wall:

Program 8.3: Measure the length of any straight wall
1def measure 
2  # Locate the left end of the wall: 
3  while wall 
4    left 
5    go 
6    right 
7  right 
8  go 
9  left 
10  # Measure the length: 
11  length = 0 
12  while wall 
13    right 
14    go 
15    left 
16    inc(length) 
17  return length 
18 
19# Call the function and display the result: 
20print(~The length of the wall is:~, measure)

For the wall shown above, the program will display the following message:


PIC


8.3. Storekeeper

Today, Karel needs to count crates which form a rectangular pattern. Its dimensions are unknown. He stands just South of it, facing North. For example, the rectangle below has 4 rows and each row has 5 crates, so altogether there are 4 * 5 = 20 crates.


PIC

Figure 8.3: *

Karel is counting crates.


Karel will count the crates as follows:

(1)
Count the crates in the bottom row.
(2)
Store the result in a variable named t.
(3)
Create a new variable total and initialize it with 0.
(4)
Walk North along the crates, and for each row add t to total.

So, for the example above, Karel will calculate total = 5 + 5 + 5 + 5 = 20. In the program below, notice that to count the crates in the first row he uses exactly the same method that he used to measure the length of the wall in Section 8.2 (page 703):

Program 8.4: Count the crates!
1# Count crates in one row: 
2def measure 
3  # Locate left-most crate: 
4  while crate 
5    left 
6    go 
7    right 
8  right 
9  go 
10  left 
11  # Count crates: 
12  r = 0 
13  while crate 
14    right 
15    go 
16    left 
17    inc(r) 
18  go 
19  return r 
20 
21# Count crates in the rectangle: 
22def multiply 
23  # Count the crates in the first row: 
24  t = measure 
25  # Turn to face the crate: 
26  left 
27  # Initialize variable total with 0: 
28  total = 0 
29  # Walk north. For each row, add t to total: 
30  while crate 
31    inc(total, t) 
32    right 
33    go 
34    left 
35  return total 
36 
37# Main program: 
38print(~I counted~, multiply, ~crates!~)

And here is the corresponding output:


PIC


8.4. Local variables and local scope

The function distance from Section 8.1 (page 696),

1def distance 
2  d = 0 
3  while not wall 
4    go 
5    inc(d) 
6  return d

the function measure from Section 8.2 (page 703),

1def measure 
2  # Locate the left end of the wall: 
3  while wall 
4    left 
5    go 
6    right 
7  right 
8  go 
9  left 
10  # Measure the length: 
11  length = 0 
12  while wall 
13    right 
14    go 
15    left 
16    inc(length) 
17  return length

as well as the functions row and multiply from Section 8.3 (page 716) have one thing in common: They both introduce a variable which is only used in the function and not elsewhere in the program. Such a variable is called a local variable. The validity of a local variable is only within the body of the function or command where it was defined. picture

This is analogous to what you already know from Section 6.12 (page 622) - commands defined inside of other commands were local as well, and only valid within the command or function where they were defined.

Let’s see what happens if we try to use a local variable outside of its local scope:

1def distance 
2  d = 0 
3  while not wall 
4    go 
5    inc(d) 
6  return d 
7 
8print(~The distance was~, distance, ~steps.~) 
9print(~The last value of d was:~, d)

The program will crash with an error message:


PIC


8.5. Global variables and global scope

The main program is called global scope. A variable which is defined in the global scope is called global. picture

Global variables are sometimes used when they are needed in multiple commands or functions. However, their use should be kept to a minimum because they make the code prone to mistakes. For example, one may define a global variable in one program module, then forget about it, and define it again, but with a different value, in another module. Or, one can define in another module a command or function with the same name. Or one can inadvertently change the value of a global variable inside a function or command. These errors are then extremely difficult to find. picture

The following example is an example of bad programming. It uses a global variable to pass a value into a function. The function back will make Karel move back N steps:

1def back 
2  left 
3  left 
4  repeat N 
5    go 
6  right 
7  right

Then in the main program one could write

1N = 4 
2back

and Karel would move back 4 steps. Elsewhere one could write

1N = 7 
2back

and the robot would move back 7 steps. However, the global variable N "polluted" the main scope and made the program prone to mistakes. In the following section we will show you a much better way to define such a function back.

8.6. Functions that accept arguments

In Karel (same as in Python and other programming languages), a function can accept one or more arguments. When defining such a function, one introduces one or more parameters in paretheses following the function name, such as in defplace(p). The names of the parameters then can be used within the function’s body as local variables.

The following function place(p) will make Karel place p objects on the ground beneath him (it assumes that there are enough objects in the robot’s bag):

1def place(p) 
2  repeat p 
3    put

When one wants Karel to place two objects, one calls the function name with the number 2 in parentheses:

1place(2)

And when calling

1place(5)

the robot will place 5 objects. To give another example, let’s define a function back(n) to move Karel back n steps:

1def back(n) 
2  left 
3  left 
4  repeat n 
5    go 
6  right 
7  right

Then, to make Karel move back 4 steps, one calls:

1back(4)

And when one needs to move the robot 7 steps back, one types:

1back(7)

Functions can accept two or even more arguments. For example, the following function rectangle(a, b) will make Karel create a rectangle of gears with side lengths a and b:

Program 8.5: Create a rectangle of gears!
1# Create a rectangle of gears with dimensions a x b: 
2def rectangle(a, b) 
3  repeat 2 
4    repeat a-1 
5      put 
6      go 
7    left 
8    repeat b-1 
9      put 
10      go 
11    left 
12 
13# Create a 6 x 4 rectangle: 
14rectangle(6, 4)

Here is the outcome of the program:


PIC


8.7. Can a function change the values of its arguments?

This is an interesting question. Any function may attempt to modify the value of the arguments which are passed to it. For example, the following function double(d) executes the command d *= 2 in its body. Now the question is - when the function is called with an argument x as double(x), will the value of x be doubled when the function finishes?

1# Double the value of the argument and return it: 
2def double(d) 
3  d *= 2 
4  return d 
5 
6# Main program: 
7x = 2 
8print(~Value of x before function call:~, x) 
9xx = double(x) 
10print(~Value of x after function call: ~, x) 
11print(~Value of xx:~, xx)

The output of the program shows that the answer is "no". The function was not able to change the value of the argument x which was passed to it:


PIC


We can try the same with a text string variable, and we can actually pass it to the same function double(d) because the operation *= works for text strings:

1# Double the value of the argument and return it: 
2def double(d) 
3  d *= 2 
4  return d 
5 
6# Main program: 
7x = ~Karel~ 
8print(~Value of x before function call:~, x) 
9xx = double(x) 
10print(~Value of x after function call: ~, x) 
11print(~Value of xx:~, xx)

The output of the program shows that the answer is "no" again:


PIC


picture

8.8. Review questions

Friendly reminder - for every question either none, one, or several answers may be correct.

QUESTION 8.1. What is the difference between a command and a function?

A
Commands cannot use the return statement.
B
Commands do not return values.
C
Functions return values and can accept arguments.
D
There is no difference.

QUESTION 8.2. Check all correct statements!

A
A function which is defined must also be called.
B
When a function is defined, it is not automatically called.
C
A function can just be called, it does not have to be defined.
D
When a function is defined but not called, nothing happens.

QUESTION 8.3. Can a function call be placed directly into the print statement?

A
Yes
B
No

QUESTION 8.4. Check all true statements about local variables!

A
They are defined in the global scope, and valid everywhere in the main program.
B
They are defined in a command or function, and valid only within that command or function.
C
They are defined in the global scope, and valid only in some command or function.
D
They are defined in a command or function, and valid everywhere in the main program.

QUESTION 8.5. Check all true statements about global variables!

A
They are defined in a command or function, and valid everywhere in the main program.
B
They are defined in the global scope, and valid only in some command or function.
C
They are defined in a command or function, and valid only within that command or function.
D
They are defined in the global scope, and valid everywhere in the main program.

QUESTION 8.6. Which types of variables in Karel can have their values changed by functions?

A
Numerical variables.
B
Text string variables.
C
Boolean variables.
D
Complex variables.


Table of Contents

Created on September 27, 2018 in Karel.
Add Comment
0 Comment(s)

Your Comment

By posting your comment, you agree to the privacy policy and terms of service.