Strings model character sequences and possess the type str, which offers a variety of functions. In this chapter, you will learn about this topic through various exercises.
4.1 Introduction
Strings consist of single characters and, like lists, are sequential data types (see section 5.1.1), which is why many actions can be performed analogously, such as slicing. Unlike other languages, Python does not have a data type for individual characters, so they are simply represented as strings of length 1.
4.1.1 Practically Relevant Functions
len(str) gets the length of the string. This is a general Python function for querying the length of sequential data types such as lists or tuples, etc., but also strings.
str[index] provides index-based access to individual letters.
str[start:end]/str[start:end:step] extracts the characters between the positions start and end - 1. As a special feature, a stepwidth can be specified. Interestingly, even the range specification can be omitted and with [::-1] only a negative step size can be used, resulting in a new string with the reverse letter order of the original string.
str[:end] extracts the characters between the beginning and the position end - 1.
str[start:] extracts the characters between the position start and the end of the string.
str.lower()/str.upper() creates a new string consisting of lowercase or uppercase letters. Numbers and punctuation marks are not converted.
str.strip() removes whitespace at the beginning and end of text and returns this as a new string. As a special feature, you can pass a character that will be removed instead of whitespace.
str.isalpha()/str.isdigit()/... checks if all characters of the string are alphanumeric, digits, etc.
str.startswith(other)/str.endswith(other) checks whether the string starts or ends with the given string.
str.find(other)/str.rfind(other) searches for the supplied string and returns the index of the first occurrence or -1 on nonexistence. The function rfind() searches from the end. As a special feature, it is possible to specify an index range in both cases.
str.index(other, start, end)/str.rindex(other, start, end) returns the index of the first or last occurrence of other. Unlike find(), an exception is thrown if the index is not present.
str.count(text) counts how many times text occurs in the string.
str.replace(old, new) creates a new string in which all occurrences of old are replaced by new.
str.split(delim) returns a list of substrings resulting from splitting the original string. The delimiter is no regular expression1. Without specifying a delimiter, a text is split with respect to whitespace.
str.join(list) does the opposite of split(). Specifically, the elements passed as a list are joined to the string as a delimiter.
str.capitalize()/str.title() converts the first character to uppercase. With title() additionally within a string, the beginning of each new word is converted to uppercase.
4.1.2 Example Conversions and Extractions
4.1.3 Equality
That the output of references str1 and str2 is the same may be surprising at first. Why is that? As an optimization, Python sometimes groups identical objects together.
However, this behavior is not guaranteed. At the latest, when actions are performed on the strings, like above the replace() references are no longer the same, but the content is in this case, of course, identical.
4.1.4 Slicing—Access to Individual Characters and Substrings
4.1.5 Converting a String into a List of Characters
4.1.6 Iteration
4.1.7 Formatted Output
4.1.8 Character Processing
4.1.9 Example: String Processing
4.2 Exercises
4.2.1 Exercise 1: Number Conversions (★★✩✩✩)
Based on a string, implement a validation for binary numbers and a conversion to it. Repeat both for hexadecimal numbers.
The conversion can be solved with int(value, radix) and base 2 for binary numbers and base 16 for hexadecimal numbers. Do not use these explicitly; implement them yourself.
Examples
Input | Method | Result |
---|---|---|
“10101” | is_binary_number( ) | True |
“111” | binary_to_decimal( ) | 7 |
“AB” | hex_to_decimal( ) | 171 |
Exercise 1a (★✩✩✩✩)
Write function is_binary_number(number) that checks that a given string consists only of the characters 0 and 1 (i. e., represents a binary number).
Exercise 1b (★★✩✩✩)
Write function binary_to_decimal(number) that converts a (valid) binary number represented as a string to the corresponding decimal number.
Exercise 1c (★★✩✩✩)
Write the entire conversion again, but this time for hexadecimal numbers.
4.2.2 Exercise 2: Joiner (★✩✩✩✩)
Write function join (values, delimiter) that joins a list of strings with the given delimiter and returns it as one string. Implement this yourself without using any special Python functionality like join() provided by type str.
Example
Input | Separator | Result |
---|---|---|
[“hello”, “world”, “message”] | “ +++ ” | “hello +++ world +++ message” |
4.2.3 Exercise 3: Reverse String (★★✩✩✩)
Write function reverse(text) that reverses the letters in a string and returns it as a result. Implement this yourself; in other words, do not use any special Python functionality, such as [::-1].
Examples
Input | Result |
---|---|
“ABCD” | “DCBA” |
“OTTO” | “OTTO” |
“PETER” | “RETEP” |
4.2.4 Exercise 4: Palindrome (★★★✩✩)
Exercise 4a (★★✩✩✩)
Write function is_palindrome(text) that checks whether a given string is a palindrome regardless of case. A palindrome is a word that reads the same from the front and the back.
You can easily solve the verification with [::-1]. Explicitly do not use Python components; implement the functionality yourself.
Examples
Input | Result |
---|---|
“Otto” | True |
“ABCBX” | False |
“ABCXcba” | True |
Exercise 4b (★★★✩✩)
4.2.5 Exercise 5: No Duplicate Chars (★★★✩✩)
Determine if a given string contains duplicate letters. Uppercase and lowercase letters should not make any difference. Write function check_no_duplicate_chars(text) for this purpose.
Examples
Input | Result |
---|---|
“Otto” | False |
“Adrian” | False |
“Micha” | True |
“ABCDEFG” | True |
4.2.6 Exercise 6: Remove Duplicate Letters (★★★✩✩)
Write function remove_duplicates(text) that keeps each letter only once in a given text, thus deleting all subsequent duplicates regardless of case. However, the original order of the letters should be preserved.
Examples
Input | Result |
---|---|
“bananas” | “bans” |
“lalalamama” | “lam” |
“MICHAEL” | “MICHAEL” |
“AaBbcCdD” | “ABcd“ |
4.2.7 Exercise 7: Capitalize (★★✩✩✩)
Exercise 7a (★★✩✩✩)
Write function capitalize(text) that converts a given text into an English title format where each word starts with a capital letter. You must explicitly not use the built-in function title() of the type str.
Examples
Input | Result |
---|---|
“this is a very special title” | “This Is A Very Special Title” |
“effective java is great” | “Effective Java Is Great” |
Exercise 7b: Modification (★★✩✩✩)
Assume now that the input is a list of strings and that a list of strings should be returned, with the individual words and then starting with a capital letter.
Exercise 7c: Special treatment (★★✩✩✩)
In headings, it is common to encounter special treatment of words. For example, “is” and “a” are not capitalized. Implement this as function capitalize_special_2(words, ignorable_words), which gets the words excluded from the conversion as the second parameter.
Example
Input | Exceptions | Result |
---|---|---|
[“this”, “is”, “a”, “title”] | [“is”, “a”] | [“This”, “is”, “a”, “Title”] |
4.2.8 Exercise 8: Rotation (★★✩✩✩)
Consider two strings, str1 and str2, where the first string is supposed to be longer than the second. Figure out if the first one contains the other one. In doing so, the characters within the first string may also be rotated. Characters can be moved from the beginning or the end to the opposite position (even repeatedly). To do this, create function contains_rotation(str1, str2), which is case-insensitive during the check.
Examples
Input 1 | Input 2 | Result |
---|---|---|
“ABCD” | “ABC” | True |
“ABCDEF | “EFAB” | True (“ABCDEF” < x 2 ⇒ “CDEFAB” contains “EFAB”) |
“BCDE” | “EC” | False |
“Challenge” | “GECH” | True |
4.2.9 Exercise 9: Well Formed Braces (★★✩✩✩)
Write function check_braces(text) that checks whether the sequence of round braces passed as a string contains matching (properly nested) pairs of braces.
Examples
Input | Result | Comment |
---|---|---|
“(( ))” | True | |
“( )( )” | True | |
“(( )))((( ))” | False | Although it has the same amount of opening and closing braces, it is not properly nested |
“((( )” | False | No suitable bracing |
4.2.10 Exercise 10: Anagram (★★✩✩✩)
The term anagram is used to describe two strings that contain the same letters in the same frequency. Here, uppercase and lowercase should not make any difference. Write function is_anagram(str1, str2).
Examples
Input 1 | Input 2 | Result |
---|---|---|
“Otto” | “Toto” | True |
“Mary | “Army” | True |
“Ananas” | “Bananas” | False |
4.2.11 Exercise 11: Morse Code (★★✩✩✩)
Write function to_morse_code(text) that is capable of translating a given text into Morse code characters. They consist of sequences of one to four short and long tones per letter, symbolized by a dot (.) or a dash (-). It is desirable for easier distinguishability to place a space between each tone and three spaces between each sequence of letter tones. Otherwise, S (...) and EEE (...) would not be distinguishable from each other.
Letter | Morse code |
---|---|
E | . |
O | - - - |
S | . . . |
T | - |
W | . - - |
Examples
Input | Result |
---|---|
SOS | . . . - - - . . . |
TWEET | - . - - . . - |
WEST | . - - . . . . - |
Bonus Try to find out the corresponding Morse code for all letters of the alphabet so you can convert your name. You can find the necessary hints for this at https://en.wikipedia.org/wiki/Morse_code.
4.2.12 Exercise 12: Pattern Checker (★★★✩✩)
Write function matches_pattern(pattern, text) that examines a space-separated string (second parameter) against the structure of a pattern passed in the form of individual characters as the first parameter.
Examples
Input pattern | Input text | Result |
---|---|---|
“xyyx” | “tim mike tim” | True |
“xyyx” | “tim mike tom tim” | False |
“xyxx” | “tim mike tim” | False |
“xxxx” | “tim tim” | True |
4.2.13 Exercise 13: Tennis Score (★★★✩✩)
Write function tennis_score(score, player1_name, player2_name) that makes an announcement in a familiar style such as Fifteen Love, Deuce, or Advantage Player X, based on a textual score for two players, PL1 and PL2. The score is given in the format <PL1 points>:<PL2 points>.
A game is won (Game <PlayerX>) when a player reaches four or more points and is ahead by at least two points.
Points from zero to three are named Love, Fifteen, Thirty, and Forty.
In case of at least three points and a tie, this is called Deuce.
With at least three points and a one-point difference, this is called Advantage <PlayerX> for the one who has one more point.
Examples
Input | Score |
---|---|
“1:0”, “Micha”, “Tim” | “Fifteen Love” |
“2:2”, “Micha”, “Tim” | “Thirty Thirty” |
“2:3”, “Micha”, “Tim” | “Thirty Forty” |
“3:3”, “Micha”, “Tim” | “Deuce” |
“4:3”, “Micha”, “Tim” | “Advantage Micha” |
“4:4”, “Micha”, “Tim” | “Deuce” |
“5:4”, “Micha”, “Tim” | “Advantage Micha” |
“6:4”, “Micha”, “Tim” | “Game Micha” |
4.2.14 Exercise 14: Version Numbers (★★✩✩✩)
Write function compare_versions(version1, version2) that compares version numbers in the format MAJOR.MINOR.PATCH with each other. Thereby the specification of PATCH is optional. In particular, the return value should be represented in the form of the characters <, =, and >.
Examples
Version 1 | Version 2 | Result |
---|---|---|
1.11.17 | 2.3.5 | < |
2.1 | 2.1.3 | < |
2.3.5 | 2.4 | < |
3.1 | 2.4 | > |
3.3 | 3.2.9 | > |
7.2.71 | 7.2.71 | = |
4.2.15 Exercise 15: Conversion str_to_number (★★✩✩✩)
Convert a string into an integer. To do this, write function str_to_number(text) on your own.
The conversion can be easily achieved with int(value). Do not use this explicitly, but implement the entire conversion yourself.
Examples
Input | Result |
---|---|
“+123” | 123 |
“-123” | -123 |
“7271” | 7271 |
“ABC” | ValueError |
“0123” | 83 (for bonus task) |
“-0123” | -83 (for bonus task) |
“0128” | ValueError (for bonus task) |
Bonus Enable the parsing of octal numbers.
4.2.16 Exercise 16: Print Tower (★★★✩✩)
Write function print_tower(n) that represents a tower of n slices stacked on top of each other as ASCII graphics, symbolized by the character #. Also, draw a lower boundary line.
Example
4.2.17 Exercise 17: Filled Frame (★★✩✩✩)
Write function print_box(width, height, fillchar) that draws a rectangle of the specified size as an ASCII graphic and fills it with the passed-in fill character.
Examples
4.2.18 Exercise 18: Guessing Vowels (★★✩✩✩)
Input | Replacement | Result |
---|---|---|
“guide” | “?” | “g??d?” |
“lawnmower” | “-” | “l-wnm-w-r” |
“quiz” | “_” | “q z” |
“lawnmower” | “” | “lwnmwr” |
4.3 Solutions
4.3.1 Solution 1: Number Conversions (★★✩✩✩)
Based on a string, implement a validation for binary numbers and a conversion to it. Repeat both for hexadecimal numbers.
The conversion can be solved with int(value, radix) and base 2 for binary numbers and base 16 for hexadecimal numbers. Do not use these explicitly; implement them yourself.
Examples
Input | Method | Result |
---|---|---|
“10101” | is_binary_number( ) | True |
“111” | binary_to_decimal( ) | 7 |
“AB ” | hex_to_decimal( ) | 171 |
Solution 1a (★✩✩✩✩)
Write function is_binary_number(number) that checks that a given string consists only of the characters 0 and 1 (i. e., represents a binary number).
Solution 1b (★★✩✩✩)
Write function binary_to_decimal(number) that converts a (valid) binary number represented as a string to the corresponding decimal number.
Solution 1c (★★✩✩✩)
Write the entire conversion again, but this time for hexadecimal numbers.
Verification
4.3.2 Solution 2: Joiner (★✩✩✩✩)
Write function join(values, delimiter) that joins a list of strings with the given delimiter and returns it as one string. Implement this yourself without using any special Python functionality like join() provided by type str.
Example
Input | Separator | Result |
---|---|---|
[“hello”, “world”, “message”] | “ +++ ” | “hello +++ world +++ message” |
Verification
4.3.3 Solution 3: Reverse String (★★✩✩✩)
Write function reverse(text) that reverses the letters in a string and returns it as a result. Implement this yourself; in other words, without using any special Python functionality, such as [::-1].
Examples
Input | Result |
---|---|
“ABCD” | “DCBA” |
“OTTO” | “OTTO” |
“PETER | “RETEP” |
However, a small problem exists. The string concatenations with += are potentially expensive because strings are immutable in Python and thereby new string objects are created. Generally, each externally visible change creates a new string.
Optimized algorithm So how could it be more memory-efficient, for example, if very long strings are to be reversed extremely frequently?
The idea is to convert the string with list() into a list and work directly on it. In addition, you use two pointers, left and right, which initially point to the first and last character, respectively. Now you swap the individual letters, and the position pointers move inwards. Repeat the whole process as long as left < right is valid; if left >= right, the process is aborted.
Verification
4.3.4 Solution 4: Palindrome (★★★✩✩)
Solution 4a (★★✩✩✩)
Write function is_palindrome(text) that checks whether a given string is a palindrome regardless of case. A palindrome is a word that reads the same from the front and the back.
You can easily solve the verification with [::-1]. Explicitly do not use Python components; implement the functionality yourself.
Examples
Input | Result |
---|---|
“Otto” | True |
“ABCBX” | False |
“ABCXcba” | True |
Should it be case-sensitive?
ANSWER: No
Are spaces relevant?
ANSWER: First yes, later no, then to be ignored
An alternative way is always to shorten the string by the characters. Why is this logical solution not so good practically? The answer is obvious: This causes many temporary string objects to be created. Besides, a large number of copy actions would have to take place.
Solution 4b (★★★✩✩)
Please note that replace() unfortunately does not support regular expression to remove the special characters. Here this is the case for a space, exclamation mark, and period. Therefore, you simply call this three times appropriately.
Verification
This demonstrates that problem- and context-aware programming enables the creation of comprehensible and maintainable solutions. The properties of understandability, maintainability, and changeability are of high importance in practice since source code is usually modified far more frequently due to changing or new requirements than created completely from scratch.
4.3.5 Solution 5: No Duplicate Chars (★★★✩✩)
Determine if a given string contains duplicate letters. Uppercase and lowercase letters should not make any difference. Write function check_no_duplicate_chars(text) for this purpose.
Examples
Input | Result |
---|---|
“Otto” | False |
“Adrian” | False |
“Micha” | True |
“ABCDEFG” | True |
Verification
4.3.6 Solution 6: Remove Duplicate Letters (★★★✩✩)
Write function remove_duplicates(text) that keeps each letter only once in a given text, thus deleting all subsequent duplicates regardless of case. However, the original order of the letters should be preserved.
Examples
Input | Result |
---|---|
“bananas” | “bans” |
“lalalamama” | “lam” |
“MICHAEL” | “MICHAEL” |
“AaBbcCdD” | “ABcd” |
Verification
4.3.7 Solution 7: Capitalize (★★✩✩✩)
Exercise 7a (★★✩✩✩)
Write function capitalize(text) that converts a given text into an English title format where each word starts with a capital letter. You must explicitly not use the built-in function title() of the type str.
Examples
Input | Result |
---|---|
“this is a very special title” | “This Is A Very Special Title” |
“effective java is great” | “Effective Java Is Great” |
Exercise 7b: Modification (★★✩✩✩)
Assume now that the input is a list of strings and that a list of strings should be returned, with the individual words and then starting with a capital letter.
Exercise 7c: Special treatment (★★✩✩✩)
In headings, it is common to encounter special treatment of words. For example, “is” and “a” are not capitalized. Implement this as function capitalize_special_2(words, ignorable_words) that gets the words excluded from the conversion as the second parameter.
Example
Input | Exceptions | Result |
---|---|---|
[“this”, “is”, “a”, “title”] | [“is”, “a”] | [“This”, “is”, “a”, “Title”] |
Verification
4.3.8 Solution 8: Rotation (★★✩✩✩)
Consider two strings, str1 and str2, where the first string is supposed to be longer than the second. Figure out if the first one contains the other one. In doing so, the characters within the first string may also be rotated. Characters can be moved from the beginning or the end to the opposite position (even repeatedly). To do this, create function contains_rotation(str1, str2), which is case-insensitive during the check.
Examples
Input 1 | Input 2 | Result |
---|---|---|
“ABCD” | “ABC” | True |
“ABCDEF | “EFAB” | True (“ABCDEF” < x 2 ⇒ “CDEFAB” contains “EFAB”) |
“BCDE” | “EC” | False |
“Challenge” | “GECH” | True |
Is the direction of the rotation known ← / →?
ANSWER: No, arbitrary
Should the rotation check be case-sensitive?
ANSWER: No, treat as same
Idea 1: Brute Force As a first idea, you could try all combinations. You start without rotation. Then you rotate string str1 to the left and check if this rotated string is contained in str2. In the worst case, this procedure is repeated up to n times. This is extremely inefficient.
Idea 2: First check if rotation makes sense Another idea for solving this is to collect all characters in a Set per string in advance and then use issubset() to check if all needed letters are included. But even this is laborious and does not really reflect well the problem to be solved.
Verification
4.3.9 Solution 9: Well Formed Braces (★★✩✩✩)
Write function check_braces(text) to check whether the sequence of round braces passed as string contains matching (properly nested) pairs of braces.
Examples
Input | Result | Comment |
---|---|---|
“(( ))” | True | |
“( )( )” | True | |
“(( )))((( ))” | False | Although it has the same amount of opening and closing braces, it is not properly nested. |
“((( )” | False | No suitable bracing |
Verification
4.3.10 Solution 10: Anagram (★★✩✩✩)
The term “ anagram” is used to describe two strings that contain the same letters in the same frequency. Here, uppercase and lowercase should not make any difference. Write function is_anagram(str1, str2).
Examples
Input 1 | Input 2 | Result |
---|---|---|
“Otto” | “Toto” | True |
“Mary | “Army” | True |
“Ananas” | “Bananas” | False |
Verification
4.3.11 Solution 11: Morse Code (★★✩✩✩)
Write function to_morse_code(text) that is capable of translating a given text into Morse code characters. They consist of sequences of one to four short and long tones per letter, symbolized by a dot (.) or dash (-). It is desirable for easier distinguishability to place a space between each tone and three spaces between each sequence of letter tones. Otherwise, S (...) and EEE (...) would not be distinguishable from each other.
Letter | Morse code |
---|---|
E | . |
O | - - - |
S | . . . |
T | - |
W | . - - |
Examples
Input | Result |
---|---|
SOS | . . . - - - . . . |
TWEET | - . - - . . - |
WEST | . - - . . . . - |
Modern Python and match In many languages, case distinctions may be expressed using the if statement as well as the switch statement. The latter was missing in Python for a long time. With Python 3.10 comes match, an even more powerful variant for case discrimination with which we can now finally also realize the switch statement. Please consult section D.2 in Appendix D for more details.
Bonus
Experiment and research a little bit to find out the corresponding Morse code for all letters of the alphabet so you can convert your name. You can find the necessary hints for this at https://en.wikipedia.org/wiki/Morse_code.
Verification
4.3.12 Solution 12: Pattern Checker (★★★✩✩)
Write function matches_pattern(pattern, text) that examines a space-separated string (second parameter) against the structure of a pattern passed in the form of individual characters as the first parameter.
Examples
Input pattern | Input text | Result |
---|---|---|
“xyyx” | “tim mike tim” | True |
“xyyx” | “tim mike tom tim” | False |
“xyxx” | “tim mike tim” | False |
“xxxx” | “tim tim tim” | True |
- 1.
Is the pattern limited to the characters x and y?
- 2.
Is the pattern always only four characters long?
- 3.
Does the pattern ever contain spaces?
- 4.
Is the input always separated with exactly one space?
ANSWER: Yes
In the code, before the actual check, you still need to verify the special case of an empty input explicitly, since "".split(" ") results in a list of length 1.
Verification
4.3.13 Solution 13: Tennis Score (★★★✩✩)
Write function tennis_score(score, player1_name, player2_name) that makes an announcement in a familiar style such as Fifteen Love, Deuce, or Advantage Player X based on a textual score for two players, PL1 and PL2. The score is given in the format <PL1 points>:<PL2 points>.
A game is won (Game <PlayerX>) when a player reaches four or more points and is ahead by at least two points.
Points from zero to three are named Love, Fifteen, Thirty, and Forty.
In case of at least three points and a tie, this is called Deuce.
With at least three points and one point difference, this is called Advantage <PlayerX> for the one who has one more point.
Examples
Input | Score |
---|---|
“1:0”, “Micha”, “Tim” | “Fifteen Love” |
“2:2”, “Micha”, “Tim” | “Thirty Thirty” |
“2:3”, “Micha”, “Tim” | “Thirty Forty” |
“3:3”, “Micha”, “Tim” | “Deuce” |
“4:3”, “Micha”, “Tim” | “Advantage Micha” |
“4:4”, “Micha”, “Tim” | “Deuce” |
“5:4”, “Micha”, “Tim” | “Advantage Micha” |
“6:4”, “Micha”, “Tim” | “Game Micha” |
- 1.
First, a score in terms of two int values should be obtained from the textual representation.
- 2.
Afterwards, it is your task to generate the corresponding textual score names based on these values.
Verification
4.3.14 Solution 14: Version Numbers (★★✩✩✩)
Write function compare_versions(version1, version2) that permits you to compare version numbers in the format MAJOR.MINOR.PATCH with each other, thereby the specification of PATCH is optional. In particular, the return value should be represented in the form of the characters <, =, and >.
Examples
Version 1 | Version 2 | Result |
---|---|---|
1.11.17 | 2.3.5 | < |
2.1 | 2.1.3 | < |
2.3.5 | 2.4 | < |
3.1 | 2.4 | > |
3.3 | 3.2.9 | > |
7.2.71 | 7.2.71 | = |
Verification
The assignment did not specify a special case, namely the treatment of additional zeros in version numbers, such as for 3.1 and 3.1.0 or 3 and 3.0.0. You will find an extension that handles these special features in the accompanying sources.
4.3.15 Solution 15: Conversion str_to_number (★★✩✩✩)
Convert a string into an integer. To do this, write function str_to_number(text) on your own.
The conversion can be easily achieved with int(value). Do not use this explicitly, but implement the entire conversion yourself.
Examples
Input | Result |
---|---|
“+123” | 123 |
“-123” | -123 |
“7271” | 7271 |
“ABC” | ValueError |
“0123” | 83 (for bonus task) |
“-0123” | -83 (for bonus task) |
“0128” | ValueError (for bonus task) |
A variant would be to abort processing upon finding the first character that is not a digit, as implemented in Perl, for example. Then the number string “123ab4567” would become 123.
Verification
Bonus: Enable the Parsing of Octal Numbers
Verification
4.3.16 Solution 16: Print Tower (★★★✩✩)
Write function print_tower(n) that represents a tower of n slices stacked on top of each other as ASCII graphics, symbolized by the character #. Also, draw a lower boundary line.
Example
It is obvious how the problem can be broken down into increasingly smaller subproblems. Each function becomes thereby short for itself and usually also well testable (if no console outputs, but computations with return take place).
Verification
4.3.17 Solution 17: Filled Frame (★★✩✩✩)
Write function print_box(width, height, fillchar) that draws a rectangle of the specified size as an ASCII graphic and fills it with the passed-in fill character.
Examples
Verification
4.3.18 Solution 18: Guessing Vowels (★★✩✩✩)
Input | Replacement | Result |
---|---|---|
“guide” | “?” | “g??d?” |
“lawnmower” | “-” | “l-wnm-w-r” |
“quiz” | “_” | “q z” |
“lawnmower” | “” | “lwnmwr” |
Verification
4.4 Summary: What You Learned
Strings are an integral part of almost every program. You built up a sound understanding by solving simple tasks like palindrome checking and string reversing. Other tasks can be significantly simplified using suitable auxiliary data structures, such as sets or dictionaries. They help when checking for well-formed braces, converting a word into Morse code, and other tasks. I hope you feel that solving problems is becoming easier the more basic knowledge you have in different areas, especially data structures.
That’s why you will have a deeper look into this topic in the next chapter, which introduces lists, sets, and dictionaries in more depth.