Contact
Evil Genius SocietyHomeLearnForumLeaderboardSocialsMessages
← Back to module

Lesson 10 of 10

Instead of one program, you'll build a library — a set of focused functions that each do one job well. This is how real code is organised.

Every function here follows the same discipline: take arguments, return a value, print nothing, carry a docstring.

Word count

def word_count(text):
    """Return the number of words in text."""
    return len(text.split())

print(word_count("the quick brown fox"))
print(word_count(""))

.split() with no arguments splits on any whitespace and drops empty pieces, so it handles double spaces and an empty string correctly.

Palindrome checker

A palindrome reads the same backwards — ignoring case, spaces, and punctuation.

def is_palindrome(text):
    """Return True if text reads the same backwards.

    Ignores case, spaces, and punctuation.
    """
    cleaned = "".join([c.lower() for c in text if c.isalnum()])
    return cleaned == cleaned[::-1]

print(is_palindrome("Racecar"))
print(is_palindrome("A man, a plan, a canal: Panama"))
print(is_palindrome("hello"))

Two things worth unpacking. c.isalnum() keeps only letters and digits, and the comprehension lowercases as it filters. cleaned[::-1] is a slice with a step of -1 — it reverses the string.

Character frequency

def char_frequency(text):
    """Return a dict mapping each character to how often it appears."""
    counts = {}
    for char in text:
        counts[char] = counts.get(char, 0) + 1
    return counts

print(char_frequency("banana"))

That's the counting pattern from lesson 3.6, wrapped in a function so you never write it again.

Truncate

def truncate(text, length=20, suffix="..."):
    """Shorten text to length characters, adding suffix if it was cut."""
    if len(text) <= length:
        return text
    return text[:length - len(suffix)] + suffix

print(truncate("short"))
print(truncate("a much longer piece of text here"))

Default parameters from lesson 4.3 make the common case a one-argument call.

Title case

def title_case(text, minor_words=None):
    """Capitalise each word, except small words that aren't first."""
    if minor_words is None:
        minor_words = {"a", "an", "the", "of", "in", "and"}

    words = text.lower().split()
    result = []
    for i, word in enumerate(words):
        if i > 0 and word in minor_words:
            result.append(word)
        else:
            result.append(word.capitalize())
    return " ".join(result)

print(title_case("the lord of the rings"))

Note minor_words=None rather than a set literal — the mutable default trap from lesson 4.3. enumerate() gives you the index and the item together, which is how we know whether a word is first.

The whole library

def word_count(text):
    """Return the number of words in text."""
    return len(text.split())

def is_palindrome(text):
    """Return True if text reads the same backwards, ignoring case and punctuation."""
    cleaned = "".join([c.lower() for c in text if c.isalnum()])
    return cleaned == cleaned[::-1]

def char_frequency(text):
    """Return a dict mapping each character to how often it appears."""
    counts = {}
    for char in text:
        counts[char] = counts.get(char, 0) + 1
    return counts

def truncate(text, length=20, suffix="..."):
    """Shorten text to length characters, adding suffix if it was cut."""
    if len(text) <= length:
        return text
    return text[:length - len(suffix)] + suffix

def longest_word(text):
    """Return the longest word in text, or an empty string if there are none."""
    words = text.split()
    if not words:
        return ""
    return max(words, key=len)

max(words, key=len) uses the same key idea as sorted() from lesson 4.7.

Try it yourself

Take it further

  • reverse_words(text) — reverse the word order, not the characters.
  • remove_duplicates(text) — drop repeated words, keeping the first of each.
  • vowel_count(text) — count vowels using the pattern from lesson 2.8.
  • Give every function a docstring, then run help(your_function) on each.

Module 4 complete

You can now write functions with parameters, defaults, and return values; control what's visible where; pass functions as arguments; use recursion when data is nested; and document all of it.

Most importantly, you've stopped writing one long script and started building small reusable pieces — the shift that makes larger programs possible.

Next up: Module 5 — Object-Oriented Programming, where data and the functions that work on it get bundled together into classes.

Questions about this lesson

Log in to ask a question.