liveBook · Manning

Don't repeat yourself principle

As explained in A Pythonic Adventure: From Python basics to a working web app

The DRY principle is the software-development practice of avoiding duplicated knowledge or implementation by defining it once and reusing it.

Don’t Repeat Yourself, often shortened to DRY, means noticing code that performs the same job again and again and giving that job one reusable definition. Repetition may work at first, but a changed menu format, a new menu category, or a bug would otherwise require the same repair in every copied section. DRY makes one place responsible for the shared work. section 2.0

Start with a small detective question: which parts stay the same, and which parts change? In a coffee-shop chooser, each menu needs a heading, a numbered loop through choices, and an input prompt. The list being displayed, its title, and its prompt are the changing parts. Put the shared steps in a function, then pass the changing values as arguments. section 3.0

One menu function, three choices

A menu function accepts choices, title, and prompt. It prints the title and numbered items, asks for input, converts that input into a list position, and returns the selected item. Calling it once for drinks, once for flavors, and once for toppings replaces three nearly identical code blocks while allowing each call to use different data and wording. section 3.0

Use DRY as a practical routine:

  • Spot code that repeats the same sequence of operations. section 3.0
  • Separate the repeated steps from the values that vary between uses. section 3.0
  • Create a function for the shared steps and supply the varying values as arguments. section 3.0
  • Call the function for each needed list instead of copying the original block again. section 3.0
Listing 3.1 The full menu program with a function
def menu(choices, title="Erik's Menu", prompt="Choose your item: "):
    print(title)
    print(len(title) * "-")
    i = 1
    for c in choices:
        print(i, c)
        i = i + 1
    choice = input(prompt)
    answer = choices[int(choice) - 1]
 
    return answer
 
 
drinks = ["chocolate", "coffee", "decaf"]
flavors = ["caramel", "vanilla", "peppermint", "raspberry", "plain"]
toppings = ["chocolate", "cinnamon", "caramel"]
 
drink = menu(drinks)
flavor = menu(flavors, "Erik's flavors", "Choose your flavor: ")
topping = menu(toppings, "Erik's toppings", "Choose your topping: ")
 
print("Here is your order: ")
print("Main product: ", drink)
print("Flavor: ", flavor)
print("Topping: ", topping)
print("Thanks for your order!")

Compare the single menu definition with its three calls: shared display-and-selection work stays in the function, while each call supplies its own list and labels. section 3.0

A function does not have to make every call identical. The same function can do the same overall work with different arguments, and default arguments can provide ordinary title and prompt values when a call does not need custom ones. That is the useful trick behind DRY: reuse the process while keeping the input specific. section 3.0

How A Pythonic Adventure: From Python basics to a working web app covers it

How deep it goes
Works through identifying repeated and varying parts, then implements a Python function with arguments, a return value, and defaults.
Examples
Uses drinks, flavors, and toppings menus that collect selections for a coffee-shop order.
What it assumes
Builds on lists, loops, print(), input(), indexing, and integer conversion while introducing user-defined functions.
What you can do after
Build it from scratch by refactoring repeated Python menu code into a parameterized function.
How it connects
Connects functions, arguments, return values, lists, loops, input, and default arguments.

Also explained in

Compare how 10 books explain don't repeat yourself principle →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of A Pythonic Adventure: From Python basics to a working web app. The section links point to the parts of the book it draws on.