Lesson 5.4
Loop over the characters
Part 5: Text, lists, stacks and queuesReading, about 5 min3 exercises in this lesson, in Python4 exercises in this lesson, in Java
Java answers can't run on Spine yet. You can still read Java, trace it, and put an answer's lines in order.
Visiting every character
By the end of this you will be able to write a loop that visits every character of a text value, to count the ones you care about or to build a new text value from them.
A text value of length 5 has the indexes 0, 1, 2, 3 and 4. A count-controlled loop can produce exactly those numbers. Put the two together and the loop reaches every character in turn.
One loop, every index
word = "panda"
for i in range(len(word)):
print(str(i) + " " + word[i])public static void main(String[] args) {
String word = "panda";
for (int i = 0; i < word.length(); i++) {
System.out.println(
i + " " + word.charAt(i));
}
}When it runs:
0 p 1 a 2 n 3 d 4 a
The loop starts at 0 and stops before the length, because the last index is one less than the length. In Python, range(len(word)) gives 0 up to, but not including, 5. In Java, the condition is i < word.length(), with < and not <=.
A common mistake: going one too far, with <= in Java or range(len(word) + 1) in Python. The loop then asks for the character at index 5, which is not there, and the program stops with an error on its last pass.
Counting the characters you care about
This is the counting pattern, with a test on one character inside the loop. Start a count at 0 before the loop, look at one character each time round, and add 1 when it is the kind you want.
text = "one small step"
count = 0
for i in range(len(text)):
if text[i] == " ":
count = count + 1
print(count)public static void main(String[] args) {
String text = "one small step";
int count = 0;
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == ' ') {
count = count + 1;
}
}
System.out.println(count);
}This prints 2.
In Python, text[i] is a text value of one character, so it is compared with the text value " ", in double quotes. In Java, charAt gives a char, so the space it is compared with is written in single quotes, ' '. Two char values are compared with ==. It is String values that need .equals. To change the case of one char, write Character.toLowerCase(ch). In Python, .lower() works on one character just as it does on a longer text value.
In Python, a loop can also hand you each character without an index. for ch in text: runs once for every character, with ch holding that character. Use it when you need each character but not where it is. In Java, keep using the loop over the indexes shown above: it works for every task in this lesson.
Building a new text value
A loop can build text as well as count. Start with an empty text value, and join on each character you want to keep.
text = "555-01-99"
digits = ""
for i in range(len(text)):
if text[i] != "-":
digits = digits + text[i]
print(digits)public static void main(String[] args) {
String text = "555-01-99";
String digits = "";
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) != '-') {
digits = digits + text.charAt(i);
}
}
System.out.println(digits);
}This prints 5550199. The empty text value "" does the job that 0 does for a count: it is the answer before any character has been looked at.
Now try it yourself on the questions below.
Exercise 5.4.1 · Trace itTrace: count in a word
Complete the trace table for this Python code. word[i] is the character at index i, counting from 0, and len(word) is the number of characters. [3]
Line 1: word = "noon"Line 2: first = word[0]Line 3: count = 0Line 4: for i in range(len(word)):Line 5, indented 1 level: if word[i] == first:Line 6, indented 2 levels: count = count + 1Line 7: print(count)
Fill in one row each time a line changes i or count, or prints something. The table already has the right number of rows. In each row, write only what that line changes; you can leave the other cells empty or copy their values down. Write values the way Python shows them: 3 and 3.0 are different, and text goes in quotes. In the output column, write exactly what appears on screen, with no quotes around it.
| Row | i | count | output |
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 | |||
| 8 |
Exercise 5.4.1 · Trace itTrace: count in a word (Java)
Complete the trace table for this Java code. word.charAt(i) is the character at index i, counting from 0, and word.length() is the number of characters. [3]
Line 1: String word = "noon";Line 2: char first = word.charAt(0);Line 3: int n = word.length();Line 4: int count = 0;Line 5: for (int i = 0; i < n; i++) {Line 6, indented 1 level: if (word.charAt(i) == first) {Line 7, indented 2 levels: count = count + 1;Line 8, indented 1 level: }Line 9: }Line 10: System.out.println(count);
Fill in one row each time a line changes i or count, or prints something. The table already has the right number of rows. In each row, write only what that line changes; you can leave the other cells empty or copy their values down. Write values the way Java shows them: 3 and 3.0 are different, and text goes in quotes. In the output column, write exactly what appears on screen, with no quotes around it.
| Row | i | count | output |
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 | |||
| 8 | |||
| 9 |
Exercise 5.4.25.4.2 · Write itCount a letter
Write a function that returns how many times a letter appears in a piece of text, ignoring upper and lower case.
letteris always one letter from A to Z, in either case. In Python it is a text value of one letter; in Java it is achar.- Upper and lower case count as the same letter, whichever way round:
Ain the text matches the lettera, andain the text matches the letterA. - The text contains only English letters, digits, spaces and punctuation, and can be empty. Digits, spaces and punctuation never match a letter.
Only the number your function returns is checked.
def count_letter(text: str, letter: str) -> int
Examples
Your function is tested on 9 cases: the 3 examples below, and 6 hidden ones that check the rules above.
- count_letter("Bob", "b") should return 2: a capital B in the text matches the letter b, and so does the b at the very end (rule 2)
- count_letter("Mississippi", "S") should return 4: an upper-case letter still matches lower-case text (rule 2)
- count_letter("", "x") should return 0: empty text (rule 3)
public static int countLetter(String text, char letter)
Running Java here comes later. You can put this answer's lines in order instead. You can still write your Java answer (it stays while this page is open) and compare it with our worked solution. Or try this exercise in Python.Checking whether Java answers can run here.
Examples
Your function is tested on 9 cases: the 3 examples below, and 6 hidden ones that check the rules above.
- countLetter("Bob", 'b') should return 2: a capital B in the text matches the letter b, and so does the b at the very end (rule 2)
- countLetter("Mississippi", 'S') should return 4: an upper-case letter still matches lower-case text (rule 2)
- countLetter("", 'x') should return 0: empty text (rule 3)
Exercise 5.4.35.4.3 · Write itCharacters at even indexes
Write a function that returns the characters at the even indexes of a text value, joined in the order they appear.
- Indexes start at 0, so the even indexes are 0, 2, 4 and so on.
textcontains only English letters, digits, spaces and punctuation.textcan be empty. Empty text gives empty text back.
Only the value your function returns is checked.
def every_second(text: str) -> str
Examples
Your function is tested on 9 cases: the 3 examples below, and 6 hidden ones that check the rules above.
- every_second("planet") should return "pae": indexes 0, 2 and 4 of six characters (rule 1)
- every_second("abc") should return "ac": an odd length: the last character is at index 2, which is even
- every_second("") should return "": empty text (rule 3)
public static String everySecond(String text)
Running Java here comes later. You can put this answer's lines in order instead. You can still write your Java answer (it stays while this page is open) and compare it with our worked solution. Or try this exercise in Python.Checking whether Java answers can run here.
Examples
Your function is tested on 9 cases: the 3 examples below, and 6 hidden ones that check the rules above.
- everySecond("planet") should return "pae": indexes 0, 2 and 4 of six characters (rule 1)
- everySecond("abc") should return "ac": an odd length: the last character is at index 2, which is even
- everySecond("") should return "": empty text (rule 3)
Exercise 5.4.4 · Trace itTrace: Java reverse
Complete the trace table for this Java code. word.charAt(i) is the character at index i, counting from 0. i-- takes 1 away from i, the opposite of i++, so this loop counts down. [3]
Line 1: String word = "cab";Line 2: String result = "";Line 3: for (int i = word.length() - 1; i >= 0; i--) {Line 4, indented 1 level: result = result + word.charAt(i);Line 5: }Line 6: System.out.println(result);
Fill in one row each time a line changes i or result, or prints something. The table already has the right number of rows. In each row, write only what that line changes; you can leave the other cells empty or copy their values down. Write values the way Java shows them: 3 and 3.0 are different, and text goes in quotes. In the output column, write exactly what appears on screen, with no quotes around it.
| Row | i | result | output |
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 | |||
| 8 | |||
| 9 |