Learn How to Think with Karel the Robot. Chapter 9. Text Strings
Chapter 9
Text Strings
In this chapter you will learn:
- How to work with text strings and text string variables.
- How to assign text strings to variables.
- How to display them and compare with each other.
- How to concatenate them and multiply with integers.
- How to obtain the length of a text string.
- How to use the for loop to parse text strings one character at a time.
- How to extract individual characters from a text string using their indices.
- How to reverse and slice text strings.
- How to display quotes and check for substrings.
At the end we will solve some very interesting tasks:
- Counting occurrences of a substring in a text string.
- Finding where a substring is located in a text string.
- Searching for substrings and replacing them with others.
- Removing substrings from text strings.
- Swapping substrings in a text string,
- and even executing a text string as Karel code!
9.1. Raw text strings and text string variables
In the Karel language, working with text strings is similar to Python, although Karel does not
implement all Python’s functionality.
A text string is a sequence of characters enclosed in either single quotes, such as ’Hello World!’ or in double quotes, such as ~I am Karel~. It does not matter whether single or double quotes are used. A text string which contains no characters is called empty text string. The following screenshot shows a few examples:
9.2. Assigning, displaying, and comparing text strings
A text string can be assigned to a variable using the standard assignment operator =:
Both raw text strings and text string variables can be displayed using the print statement exactly as you would expect:
Output:
Text strings (in either raw form or as text string variables) can be compared using the same comparison operator == as numbers:
2if str1 == ’Karel’
3 print(~That’s him, Karel!~)
4else
5 print(~No, that’s not him.~)
Output:
9.3. Concatenating text strings
One can concatenate two or more text strings using the same + symbol which is used to add
numbers:
As you can see, it does not matter whether one concatenates raw text strings or text string variables. The output of this program is:
Notice that each of the text strings str1 and str2 had an empty space at the end. It is important
to account for empty spaces, they are not inserted automatically. Let’s see what happens when
we leave them out:
Output:
9.4. Multiplying text strings with integers
Any text string (in raw form or as a variable) can be multiplied with a (positive) integer, as
shown in the following example:
Output:
9.5. Length of a text string
Karel provides the Python function len to obtain the length of a text string. The following example shows various flavors of using it:
2txt1 = ’I am Karel’
3print(len(txt1))
4txt2 = ’Karel rocks!’
5n = len(txt2)
6print(n)
Output:
9.6. Parsing a text string with the for loop
Karel provides the Python for loop to parse text strings one character at a time. The keyword for is followed by a variable for the individual characters, the keyword in and the name of the text string to be parsed. For example, let’s parse the text string ’Karel’ and just display all the characters:
Output:
9.7. Reversing text strings
As another example, let’s use the for loop to reverse a text string!
Output:
9.8. Extracting individual characters by their indices
Characters in a text string are internally enumerated, starting with 0 (first character), 1 (second character), 2 (third character), etc. These numbers are called indices (the singular of the word is index). Appending the index in square brackets at the end of either a raw text string or a text string variable yields the desired character. For illustration, let’s extract all five individual characters from the text string ’Robot’ using their indices 0, 1, 2, 3 and 4:
2print(name[0])
3print(name[1])
4print(name[2])
5print(name[3])
6print(name[4])
Output:

Now let’s extract individual characters from a raw text string:
2print(’Karel the Robot’[11])
3print(’Karel the Robot’[12])
4print(’Karel the Robot’[13])
5print(’Karel the Robot’[14])
Output:
9.9. Using negative indices
When one needs to extract characters from the end of a text string, it is possible to use negative indices. The last character has index -1, the one before last has index -2, etc. Let’s illustrate this on a simple example:
2print(name[-5])
3print(name[-4])
4print(name[-3])
5print(name[-2])
6print(name[-1])
Output:

9.10. Slicing text strings
Slicing text strings is another useful functionality provided by Python. Sometimes one needs to extract not only one character, but an entire word or a substring. Actually, you already know how to do this: To extract a five-character word from the beginning of a text string name, one can type name[0] + name[1] + name[2] + name[3] + name[4]:
Output:
But, the same can be done more easily using slicing. A five-character slice from the beginning of a text string name is name[:5]:
Output:
A three-character slice starting with the second letter is name[1:4]:
Output:
A five-character slice from the end of the text string name is name[-5:]:
Output:
A three-character slice starting with the fifth letter from the end is name[-5:-2]:
Output:
9.11. Displaying quotes in text strings
Displaying quotes is a bit tricky, because these are the symbols which are used to define text strings. To illustrate the problem one can get into, let’s try to display the text She said: ~Hello, it is nice to meet you.~:
Output:
The reason why this did not work is that the interpreter found a complete and correct text string ~She said:~ in the print function. Then it expected either a closing parenthesis, or a comma, or perhaps one of the + or * operators. But instead, it found Hello which did not make any sense. Was this a misplaced variable? The interpreter had no choice other than to throw an error.
The way to prevent this confusion is to enclose the text string that contains double quotes in single quotes:
Output:
An analogous problem will arise when one tries to display a text string that contains single quotes by enclosing it in single quotes:
Output:
The problem can be fixed by enclosing the text string in double quotes:
Output:
9.12. Checking for substrings
Another Python feature provided in the Karel language is the ability to check if a text string
contains a given substring. This is done using the keyword in:
2if ~Karel~ in txt
3 print(~The text string contains the word ’Karel’.~)
4else
5 print(~The text string does not contain the word ’Karel’.~)
Output:
And of course this can be done using a variable as well:
2name = ~Karel~
3if name in txt
4 print(~The text string contains the word ’Karel’.~)
5else
6 print(~The text string does not contain the word ’Karel’.~)
Output:
9.13. Counting occurrences of substrings
Sometimes one needs to count how many times certain text string is present in another text
string. Python has a built-in functionality for this which is not present in Karel. So, let’s
implement it! Your task is to write a function count(sub, txt) to count the number of
occurrences of a substring sub in a text string txt. If the substring is not found, the function
should return zero. Try to solve this task by yourself before looking at the solution
below!
Solution: You already know from Section 9.10 (page 781) how to slice text strings. As the first
thing we will introduce a counting variable (named for example result), initialize it with zero,
and measure the length of both sub and txt. Let’s denote their lengths by l1 and l2,
respectively. The algorithm will be very simple. We will take the first [0:l1] slice of txt and
compare it with sub. If there is a match, we will increase result by one. Then we will do the
same for the [1:l1+1] slice of txt, for the [2:l1+2] slice of txt, etc. There are l2-l1+1 such
slices. At the end, we will return the value of result. Here is the corresponding Karel
code:
2def count(sub, txt)
3 result = 0
4 l1 = len(sub)
5 l2 = len(txt)
6 index = 0
7 repeat l2 - l1 + 1
8 slice = txt[index:index+l1]
9 if slice == sub
10 inc(result)
11 inc(index)
12 return result
13
14# Main program:
15text = ~The Karel programming language was named after Karel Čapek.~
16word = ~Karel~
17print(~The word ’~ + word + ~’ was found~, count(word, text), ~times.~)
Output:
9.14. Finding the positions of substrings
Sometimes one needs to locate the position of a text string in another text string. This means, if
the substring is present, to find the index of its first character in the longer text string. If the
substring is not present, the result should be -1. Again, this is a built-in functionality in Python
which is not provided in Karel. Therefore, let’s implement it! Your task is to write a function
find(sub, txt) to return the position of (the first occurrence of) a substring sub in a text
string txt. If the substring is not found, return -1. Try to solve this task by yourself before
looking at the solution below!
Solution: In Section 9.13 (page 815) we learned how to count the occurrences of a substring in a
text string. We will use it as the first thing to check if the substring sub is part of the text string
txt. If not, we will return -1. The rest will be similar to the function count from Section 9.13:
We will run a loop and compare the [0:l1], [1:l1+1], [2:l1+2] etc. slices of txt to sub. We
know at this point that the substring is there because if it was not there, we would have returned
-1 previously. So, once a match is found, we return the starting index of the slice. Here is the
corresponding program:
2# in a text string txt. If the substring is not found, return -1:
3def find(sub, txt)
4 # Check for the substring:
5 if not sub in txt
6 return -1
7 # Now we know the substring is there:
8 index = 0
9 l1 = len(sub)
10 l2 = len(txt)
11 repeat l2 - l1 + 1
12 slice = txt[index:index+l1]
13 if sub == slice
14 return index
15 inc(index)
16
17# Main program:
18text = ~The Karel programming language was named after Karel Čapek.~
19word = ~Karel~
20result = find(word, text)
21if result == -1
22 print(~The substring was not found.~)
23else
24 print(~The substring was found at position~, result)
Output:
9.15. Searching and replacing in text strings
Another functionality which is provided in Python but not in Karel is searching for substrings in
text strings and replacing them with other substrings. Therefore, let’s implement it! Your task is
to write a function replace(txt, sub1, sub2) which in the text string txt finds all
occurrences of the substring sub1, replaces them with the substring sub2, and returns the result
as a new text string. Try to solve the task on your own before looking at the solution
below!
Solution: We will begin with creating an empty text string for the result (named, for
example, result). This is where we will add parts of the text string txt which do not
contain sub1, and where we will add sub2 instead of sub1. At the beginning, we
will call find(sub1, txt) to find the position pos of the first occurrence of the
substring sub1 in txt. While the substring is there (pos is not -1), we will add to
result the part of txt which precedes sub1 (its [:pos] slice) and sub2. Then we
remove this part from txt by redefining txt by its slice txt[pos + len(sub1):].
This process is repeated while the substring sub1 is present in txt. At the end, we
add the remaining part of txt to result and return it. Here is the corresponding
code:
2def replace(txt, sub1, sub2)
3 result = ’’
4 pos = find(sub1, txt)
5 while pos != -1
6 result += txt[:pos] + sub2
7 txt = txt[pos + len(sub1):]
8 pos = find(sub1, txt)
9 return result + txt
10
11# Main program:
12text = ~The Carlos programming language was named after Carlos Čapek.~
13result = replace(text, ~Carlos~, ~Karel~)
14print(result)
Output:
9.16. Removing substrings
Your next task is to write a function remove(sub, txt) to remove all occurrences of a
substring sub from a text string txt. Try to solve this task by yourself before checking the
solution below!
Solution: This is a simple application of the function replace() from Section 9.15 (page 823). It
is sufficient to replace all occurrences of the substring sub with an empty text string
~~:
2def remove(sub, txt)
3 return replace(txt, sub, ~~)
4
5# Main program:
6text = ~The Karel the Robot programming language was named after Karel Čapek.~
7result = remove(~the Robot ~, text)
8print(result)
Output:
9.17. Swapping substrings
Your next task is to write a function swap(txt, sub1, sub2) to swap the substrings sub1
and sub2 in the text string txt. Try to come up with a solution on your own before looking at
our solution below!
Solution: This is another simple application of the function replace() from Section 9.15 (page 823). Let’s define a helper text string which for sure will not be present in the text string txt. For example, we can define help = ~__NCLAB_HELPER_STRING__~. Then, one can perform the following three steps:
- (1)
- Replace in txt all occurrences of the substring sub2 with help.
- (2)
- Replace in txt all occurrences of the substring sub1 with sub2.
- (3)
- Replace in txt all occurrences of the substring help with sub1.
Here is the corresponding program:
2def swap(txt, sub1, sub2)
3 help = ~__NCLAB_HELPER_STRING__~
4 txt = replace(txt, sub2, help)
5 txt = replace(txt, sub1, sub2)
6 txt = replace(txt, help, sub1)
7 return txt
8
9# Main program:
10text = ~The Čapek programming language was named after Čapek Karel.~
11result = swap(text, ~Karel~, ~Čapek~)
12print(result)
Output:
9.18. Executing text strings as code
Executing text strings as code is another built-in functionality in Python which is not present in Karel. So let’s implement it! This will be really neat – imagine sending a robot an SMS from your phone and watch him act on it! Hence, your task is to write a function eval(txt) to execute the text string txt as Karel code. There will be some limitations on how this text string may look like (these limitations help you because they make your programming simpler):
- All characters in the text string txt should be lowercase.
- The text string should not contain empty spaces at the ebginning or at the end.
- Individual commands should be separated with exactly one empty space ’ ’.
- The text string only should contain the five basic commands go, left, right, get and put.
An example of such a text string txt is ~go get left go put right go~.
Solution: This is a straightforward application of the if-elif-else statement. If the first two characters of the text string txt are ~go~, we will execute the command go, and remove this command and the following empty space from txt by redefining txt = txt[3:]. Otherwise, if the first four characters of txt are ~left~ then we execute the command left and remove this command and the following empty space from txt by redefining txt = txt[5:]. The same we do for the remaining commands right, get and put. The else branch should be used for the case when there is a problem with the text string txt and none of the five basic commands is recognized. All of this should be enclosed in a while loop which checks whether the text string txt is not empty.
Here is the corresponding program:
2# Only the basic commands go, left, right, get, put are accepted.
3# All commands must be lowercase, and separated with one empty space.
4# No empty spaces at the beginning or at the end!
5def eval(txt)
6 while txt != ~~
7 if txt[:2] == ~go~
8 go
9 txt = txt[3:]
10 elif txt[:4] == ~left~
11 left
12 txt = txt[5:]
13 elif txt[:5] == ~right~
14 right
15 txt = txt[6:]
16 elif txt[:3] == ~get~
17 get
18 txt = txt[4:]
19 elif txt[:3] == ~put~
20 put
21 txt = txt[4:]
22 else
23 print(~Unknown command, exiting.~)
24 return
25 print(~Finished!~)
26 return
27
28# Main program:
29txt = ~go get left go put right go~
30eval(txt)
We will test the program on a simple maze where Karel needs to make one step forward, collect a gold bugget, turn left, make another step forward, put the nugget in the bag, make a right turn, and make one more step to enter his home square. In other words, the text string will have the form ~go get left go put right go~:
After the program finishes, the nugget is in the bag and Karel is home:
Also, the following message is displayed at the end:
9.19. Your homework
The function eval(txt) from Section 9.18 (page 834) has a few technical limitations which are easy to remove:
- All characters in the text string txt should be lowercase.
- The text string should not contain empty spaces at the ebginning or at the end.
- Individual commands should be separated with exactly one empty space ’ ’.
Remove all of them in order to make the function more robust!
Then there is one more substantial limitation:
- The text string only should contain the five basic commands go, left, right, get and put.
Extend the function eval(txt) to allow simple repeat loops (not nested) whose body is enclosed in two empty spaces!
9.20. Review questions
Friendly reminder - for every question either none, one, or several answers may be correct.
QUESTION 9.1. Which of the following are valid text strings?
- A
- Hi, I am Karel!
- B
- ’Hi, I am Karel!’
- C
- ~Hi, I am Karel!~
- D
- (Hi, I am Karel!)
QUESTION 9.2. What is the correct way to assign the text string ~Karel~ to a text string variable name?
- A
- name := ~Karel~
- B
- name == ~Karel~
- C
- name = ~Karel~
- D
- ~Karel~ == name
QUESTION 9.3. What is the correct way to compare two text strings str1 and str2?
- A
- if str1 = str2
- B
- if str1 == str2
- C
- if str2 = str1
- D
- if str2 == str1
QUESTION 9.4. How can one display the contents of a text string variable txt?
- A
- print(~txt~)
- B
- print(’txt’)
- C
- print(txt)
- D
- print[txt]
QUESTION 9.5. How can one concatenate two text strings txt1 and txt2?
- A
- txt1, txt2
- B
- concat(txt1, txt2)
- C
- txt1 + txt2
- D
- txt1 * txt2
QUESTION 9.6. How can one define a new text string echo which contains 10 times the text string ~Help! ~?
- A
- echo = ~Help!~ * 10
- B
- echo = ~Help! ~ + 10
- C
- echo = ~Help! ~ * 10
- D
- echo = ~Help! Help! ~ * 5
QUESTION 9.7. What is the way to obtain the length of a text string text?
- A
- len(text)
- B
- length(text)
- C
- length text
- D
- text(length)
QUESTION 9.8. What is the correct way to parse a text string story one character at a time?
- A
- for c in story
- B
- for story in c
- C
- in story for c
- D
- repeat for c in story
QUESTION 9.10. What is the slice txt[3:6] of the text string ~Thermometer~?
- A
- ~rmo~
- B
- ~mom~
- C
- ~ome~
- D
- ~met~
QUESTION 9.11. What is the slice txt[-6:-3] of the text string ~Thermometer~?
- A
- ~rmo~
- B
- ~mom~
- C
- ~ome~
- D
- ~met~
QUESTION 9.12. Which of the following are valid text strings in Karel?
- A
- ’Hi, it’s me!’
- B
- ~Hi, it’s me!~
- C
- ~Hi, it~s me!~
- D
- ’Hi, it~s me”
QUESTION 9.13. How can one check if text string txt contains a substring sub?
- A
- if txt has sub
- B
- if sub in txt
- C
- if txt in sub
- D
- if contains(txt, sub)
QUESTION 9.14. How can one swap the contents of two text strings str1 and str2?
- A
- Execute str1 = str2 and then str2 = str1
- B
- Create a helper variable help. Execute help = str2, then str2 = str1 and then str2 = help
- C
- Create a helper variable help. Execute help = str1, then str2 = str1 and then str2 = help
- D
- Create a helper variable help. Execute help = str2, then str2 = str1 and then str1 = help
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