Course outline · 0% complete

0/32 lessons0%

Course overview →

Project: Word Counter

lesson 10-2 · ~13 min · 31/32

The tool

Given a line of text, report three things:

  1. how many words it has,
  2. how many different words it has,
  3. which word appears most often.

The ingredients, all yours already: split() and set() from lesson 7-3, the dict counting pattern from lesson 7-1, and a find-the-max scan like lesson 6-3. One new touch: lowercase the text first with .lower() (lesson 2-2) so The and the count as the same word.

the words list the cat and the ... 8 items, repeats kept set() 5 unique no counts get pattern the: 3 and: 2 cat: 1 ... max the A set answers how many DIFFERENT words. A dict also answers how many times each one appeared.
The two containers the word counter needs. The words list holds all eight items with repeats intact, and converting it to a set collapses them to five unique words but keeps no tallies. The dict built with the get pattern keeps a count per word instead, mapping the to three and and to two, and a find-the-max scan over those pairs picks out the most frequent word.

Part 1: the two totals

One chained expression prepares the text, and the two counts fall out of it directly.

text = input()
words = text.lower().split()
print("words:", len(words))
print("unique:", len(set(words)))

Input

the cat and the dog and the bird

Output

words: 8
unique: 5

The chain text.lower().split() does two jobs in order, normalizing the case and then cutting on whitespace, and it leaves words holding a list of eight strings. Counting that list gives the total, and wrapping the same list in set collapses the repeats to give the distinct count of five, since the appears three times and and twice.

Building words once and reusing it matters here. Calling split again for the second line would work but would repeat the parsing, and keeping the list around is what lets the next part of the project count frequencies without re-reading anything.

Lowercasing before counting matters so that "The" and "the" are treated as the same word.

String comparison is exact, which means the two spellings would become two separate dict keys and two separate set members. A sentence beginning with a capitalized The would then report one more unique word than a human would count, and its frequency tally would be split across two entries.

Normalizing with lower() from lesson 2-2 removes that distinction before any counting happens. The general principle applies well beyond word counts: whenever text is used as a key, normalize it first, which is the same reasoning behind the email comparison in lesson 2-2.

Part 2: the most common word

Two loops finish the tool, one to build the frequency dict and one to scan it for the winner.

text = input()
words = text.lower().split()
counts = {}
for w in words:
    counts[w] = counts.get(w, 0) + 1
best = None
best_count = 0
for w, c in counts.items():
    if c > best_count:
        best = w
        best_count = c
print(f"{best} appears {best_count} times")

Input

the cat and the dog and the bird

Output

the appears 3 times

The first loop is the get pattern from lesson 7-1, reading each word's current count with 0 as the fallback and storing one more. The second is the find-the-max scan from lesson 6-3, unpacking each pair with the items() form from lesson 7-2 and keeping both the best word and its count in step.

Two accumulators are needed rather than one, because the answer is a word while the comparison is on a number. Updating them together inside the same if is what keeps them consistent, and the strict > means the first word to reach the highest count wins any tie.

Run against the line up down up down up, the tool reports 5 total words and 2 unique words.

split cuts on the spaces and yields five pieces. The set of those pieces contains only up and down, since repeats are stored once, so its size is 2.

This is the word-frequency version of the len(nums) against len(set(nums)) comparison from lesson 7-3. The gap between the two numbers is a quick measure of repetition, and here it is large because a five-word line draws on a vocabulary of only two.