0%

Chapter 2 · practice

More Expressive Functions

Useful Defaults

A good default gives a a useful common choice. Consider a function that labels one question:

def question_label(number, prefix):
    return f"{prefix} {number}"

Every caller must then supply both values. That is useful when every choice matters:

question_label(3, "Question")

Sometimes one has an obvious common choice. Most labels can use the prefix "Question". A default value records that common choice in the function definition:

def question_label(number, prefix="Question"):
    return f"{prefix} {number}"

Now both calls are valid:

question_label(3)
question_label(3, "Challenge")

The first call uses "Question". The second call replaces the default with "Challenge".

Defaults express policy

A good default is not merely convenient. It communicates what the function normally does. Callers only mention the unusual choices, so the common case stays short.

Use a default when:

  • one choice is safe and unsurprising;

  • most callers should use that choice;

  • callers can still replace it when their situation differs.

Do not hide essential information behind a made-up default. A label function still needs the actual question number.

Required parameters must come before parameters with defaults:

def question_label(number, prefix="Question"):
    ...

Python rejects a definition that places a required parameter after prefix in this example.

What does this print?

def greet(name, punctuation="!"):
    return f"Hello, {name}{punctuation}"


print(greet("Ada"))
print(greet("Ada", "."))

Add one useful default

The editor contains a score formatter. Give label the default value "Score", then return the formatted text. The function should work both with and without an explicit label.

Task

Complete format_score.

  • score and total must remain required.

  • label must default to "Score".

  • Return text in the form Label: score/total.

Do not print inside the . The provided calls handle display.