Course 3.2Lesson 5 of 5
In this project we fix a small text library that has four hidden bugs. The library has four functions that count the words of a text, give the average length of a word, find the most common word with the first in the alphabet for a tie, and test for a palindrome. A table of thirteen tests finds the bugs: splitting on a single space gives empty words, the average divides by zero for an empty text, a greater-or-equal in the tie rule lets the wrong word win, and the palindrome test does not ignore capitals and punctuation. We run the tests, read the failures, explain each bug in a sentence, fix one thing at a time, run all the tests again, and extend the library with tests of our own.
Try the code and the simulations beside the lesson.
After this lesson you can
A friend wrote a small library of four text functions, and says "it works". You do not believe it, and you have a table of thirteen tests. The functions:
word_count(text): the number of words.average_word_length(text): the average length of a word. For no words, 0.0.most_common_word(text): the most common word. When two words tie, the one that comes first in the alphabet. For no words, None.is_palindrome(text): does the text read the same both ways, ignoring capitals, spaces and punctuation?The tests are written from the rules above, not from the code.
| Failing test | The answer | Expected |
|---|---|---|
word_count | 3 | 2 |
word_count empty | 1 | 0 |
word_count spaces | 4 | 2 |
average empty | ZeroDivisionError | 0.0 |
most_common tie | b | a |
palindrome capital | False | True |
palindrome sentence | False | True |
Group the failures by function. Three come from word_count, and two from is_palindrome. It is likely that each function has one bug that shows in more than one test. This is a useful habit: read all the failures first, then group them, before you fix anything.
For each bug, use the loop: reproduce, locate, explain, fix one thing, test again.
Bug 1: word_count.
word_count("the cat"), with two spaces, gives 3.text.split(" ") cuts at every single space. Two spaces make an empty word between them. An empty text gives [""], one empty word, so the count would be 1, not 0. A space at the start or the end adds an empty word too.split(" ") makes empty words, so the count is too big."text.split() with no argument drops all the white space.Bug 2: average_word_length.
average_word_length("") raises a ZeroDivisionError.len(words) is 0, and the sum is divided by 0.if not words: return 0.0 first. (This is the empty edge case.)Bug 3: most_common_word.
most_common_word("b a a b") gives b, and the rule says a.counts[word] >= counts[best]: with greater or equal, a later word with the same count replaces the earlier one. So the last of the tie wins.>= lets a later word replace an equal one, but the first in the alphabet should stay.">, strictly more. (A wrong condition at an edge, from the table of the usual suspects.)Bug 4: is_palindrome.
is_palindrome("Level") gives False.L is not equal to the small l, and the spaces and commas of a sentence are in the way.Set the words to 0: the empty text gives one empty piece with split(" "), the very bug in word_count("").
Pick one or two, and do them without looking at a solution.
"don't", capital letters in most_common_word.longest_word(text), with a rule for a tie. Write the tests first, then the function.is_palindrome against a trusted answer: for any text t, is_palindrome(t + reverse_of(t)) must be True.unittest. Rewrite the table as a test class with assertEqual and assertRaises.word_count(text + " " + text) must be twice word_count(text). Is it?Start with two quick questions. Each New numbers gives you a fresh one, so you can practise as long as you like.
Then the labs and the problems:
Try each one on your own first. If you are stuck, open a hint. Then check with Show the answer.
word_count("") not give 0?> instead of >= change in most_common_word?Every lesson is open to read. Enrolling also lets you:
Log in to join the discussion.
Loading…
This lesson is free to read. Enroll free to keep your place and take the tests.