Skip to content
beginner

Writing Reusable Python Code: DRY Principles for Beginners

Copy-paste feels fast. It is also how small scripts turn into maintenance traps.

Published 2026-09-05Updated 2026-09-127 min read
Vibrant heart-shaped pattern in swirling orange and teal marbling art form.
Vibrant heart-shaped pattern in swirling orange and teal marbling art form. Photo by Turgay Koca on Pexels.

Copy-paste feels fast. It is also how small scripts turn into maintenance traps.

Here is a version of a problem I see constantly in beginner code. Imagine you are building a tiny order-report script. Three different places need to format a price the same way:

# order_report.py

item_one = {"name": "notebook", "price_cents": 450}
item_two = {"name": "pen", "price_cents": 125}
item_three = {"name": "desk lamp", "price_cents": 2499}

print(f"{item_one['name']}: ${item_one['price_cents'] / 100:.2f}")
print(f"{item_two['name']}: ${item_two['price_cents'] / 100:.2f}")
print(f"{item_three['name']}: ${item_three['price_cents'] / 100:.2f}")
notebook: $4.50
pen: $1.25
desk lamp: $24.99

That works. Now suppose your business changes: prices should show with a currency symbol like €4.50. You now have to find every copy of that formatting logic and edit it. Miss one, and your report silently mixes currencies. That is not a style problem. That is a maintenance bill you just signed.

Why Copy-Pasted Code Costs You Later

Beginners copy code because it works the first time. The cost arrives on the second edit, when you have to remember every place that logic lives.

Code is read and changed far more often than it is first written. Every duplicated block means that when a requirement changes, you must find all the copies, edit all of them, and trust that you did not miss one. Missing a copy creates a silent bug: no error message, just wrong output.

This problem is common enough that software developers gave it a name: DRY, which stands for Don't Repeat Yourself. The idea is simple: capture one piece of behavior in exactly one place, then reuse it everywhere that behavior is needed.

Knowledge check

Check your understanding

Answer this question before you continue.

Why does duplicated formatting logic make a later requirement change more error-prone?
Single Choice

Focus: Identify how DRY reduces maintenance work when shared behavior changes.

What DRY Actually Means (and What It Doesn't)

DRY does not mean you must never write two similar lines. It means you should not have multiple copies of the same job scattered through your code.

Here is the distinction that matters. Two loops that both print values are not automatically duplicates:

# One job: print scores
for score in scores:
    print(score)

# Different job: print names
for name in names:
    print(name)

Those loops look alike, but they do different work. DRY is a judgment about intent and change, not a word-count rule. If you would need to edit two places to make one logical change, that is duplication. If the two blocks would change for different reasons, they are not duplicates.

Knowledge check

Check your understanding

Answer this question before you continue.

Which situation best matches the article's definition of duplication?
Misconception Check

Focus: Distinguish duplication by shared intent and change from merely similar-looking code.

The First Reuse Tool: Functions

You already know how to define and call a function. Now let's put that skill to work.

The duplicated price formatting from our opening example is a perfect candidate. Wrap it in a function:

def format_price(item):
    return f"{item['name']}: ${item['price_cents'] / 100:.2f}"

item_one = {"name": "notebook", "price_cents": 450}
item_two = {"name": "pen", "price_cents": 125}
item_three = {"name": "desk lamp", "price_cents": 2499}

print(format_price(item_one))
print(format_price(item_two))
print(format_price(item_three))
notebook: $4.50
pen: $1.25
desk lamp: $24.99

Same output, but the structure changed. The formatting logic now lives in exactly one place. When the currency changes, you edit one function, and every call site updates automatically.

This is the core payoff of writing reusable Python code: you change the logic once, and the fix propagates everywhere the function is used. No hunting through the file for copies. No risk of missing one.

Tip: A good beginner instinct is to ask, "If this behavior changes, how many places do I have to edit?" If the answer is more than one, consider extracting a function.

Knowledge check

Check your understanding

Answer this question before you continue.

What does this code print?
Output Prediction

Focus: Predict the output produced by calling a reusable formatting function with an item dictionary.

def format_price(item):
    return f"{item['name']}: ${item['price_cents'] / 100:.2f}"

item = {"name": "pen", "price_cents": 125}
print(format_price(item))

When a Function Isn't Enough: Modules

A three-level hierarchy showing repeated formatting logic in several places, one format_price function reused by multiple calls in a single script, and a formatting.py module imported by report_one.py and report_two.py.
Functions centralize behavior within a file; modules make that behavior reusable across files.

Functions reuse code within one script. But what happens when you need that same helper in a second script?

You could copy the function into the new file. That recreates the exact problem you just solved. The better move is to put the function in a module.

A module is just a .py file that holds code you want to reuse. If you save format_price in a file called formatting.py, any other script in the same folder can import and use it:

# formatting.py

def format_price(item):
    return f"{item['name']}: ${item['price_cents'] / 100:.2f}"
# report_one.py
from formatting import format_price

item = {"name": "notebook", "price_cents": 450}
print(format_price(item))
# report_two.py
from formatting import format_price

item = {"name": "desk lamp", "price_cents": 2499}
print(format_price(item))

Save all three files in the same folder. Then run report_one.py or report_two.py from that folder, and the import will find formatting.py.

The distinction is clean: functions organize behavior inside a file; modules organize functions across files. When you catch yourself needing the same function in a second script, that is the signal to move it into a module.

Knowledge check

Check your understanding

Answer this question before you continue.

You need to use the same helper in two Python scripts. According to the article, what is the better next step?
Single Choice

Focus: Choose between a function and a module based on whether reuse stays within one file or crosses files.

A Real-World Habit: Spotting Duplication as You Write

DRY is not a rule you recall after the damage is done. It is a habit you practice while typing.

Here is the trigger I teach beginners: if you are about to paste the same block a second time, pause. Ask yourself whether this is the same job as the block you are copying from. If yes, extract a function first, then call it in both places.

What about the first time you write a block? My rule is simple: wait for the second use. Abstracting too early is the beginner's opposite mistake. You do not need a function for logic that appears once and may never appear again. When the pattern shows up twice, you have real evidence that reuse will pay off.

This habit matters most in the work beginners actually do: automation scripts, data cleanup, small reporting tools. Those projects are full of repeated formatting, validation, and file-handling logic. Each repetition is an invitation to write reusable Python code instead of another copy.

Common Beginner Mistake: Fixing One Copy and Missing the Rest

The classic symptom of duplication failure is subtle. You fix a bug in one copy of the logic, but another copy still holds the old behavior. The program runs without errors. The output is just wrong in one spot.

# First copy — fixed to use two decimal places
price_display = f"${item_one['price_cents'] / 100:.2f}"

# Second copy — still uses the old format
price_display = f"${item_two['price_cents'] / 100}"

# Third copy — also still old
price_display = f"${item_three['price_cents'] / 100}"

Run that with the same item values from earlier, and you get:

$4.50
$1.25
$24.99

Wait. Two of those look right. The second and third lines happen to produce clean numbers because 125 / 100 and 2499 / 100 do not expose the missing decimal formatting. But try price_cents = 1255 in the second copy, and you will see $12.55 instead of $12.55 — no, check that again: 1255 / 100 gives 12.55, which looks fine too. The real trap appears with a value like 1250, which prints as 12.5 instead of 12.50.

The point is not the floating-point details. The point is that the inconsistency is nearly invisible until a specific value exposes it. No error message. No warning. Just wrong output on the day a customer order hits the unlucky number.

This is not a personal failure. It is the predictable cost of duplication, which is exactly why DRY exists. When you catch yourself editing one of several copies, treat that moment as your signal: extract the function now, before the copies drift further apart.

Your Next Step

Pick a small script you have already written. Find one block that appears more than once — a formatting expression, a validation check, a cleanup step. Refactor it into a function. Run the script and confirm the output did not change.

That last part matters. The goal of refactoring is not new behavior. It is the same behavior, organized so the next change is cheaper.

Once you feel comfortable reusing functions across scripts, the natural next step is learning how to build and import your own modules. That is where python code reuse moves from a single file to an entire project.

Knowledge check

Final check

Finish the article by checking the ideas you just learned.

What does the article recommend when a block of logic has been written only once?
Question 1 of 2Misconception Check

Focus: Apply the article's timing rule for extracting a function when repeated code first appears.

What is the goal of the refactoring exercise described at the end of the article?
Question 2 of 2Single Choice

Focus: Explain the intended result of refactoring duplicated code into a reusable function.

References

  1. An Overview of Packaging for Python — Python Packaging User Guidepackaging.python.org
  2. Defining Your Own Python Functionrealpython.com
7sources checked
7source domains
5searches run

Research updated Sep 5, 2026

Practical resource

Want a more structured Python path?

Use the Python Starter Pack to turn scattered tutorials into a focused practice path.

View the bundle
Coming soon

Python Starter Pack

A compact LearnPyFast PDF pack covering what Python is, installation, your first program, running Python code, and Python versions.

$9
PDF BundleTopic PackPythonBeginner
  • 5 curated chapters
  • Enhanced PDF edition with bundle-only learning guidance
  • Offline-friendly format for focused review
  • Source article links for future online updates

Coming soon

Free Python bundle

Get the LearnPyFast Python Starter Bundle

A focused collection of beginner-friendly Python resources to help you move from setup to building practical projects.

You’ll receive the bundle by email. You can unsubscribe anytime.

No spam. You can unsubscribe anytime. See our Privacy policy.

Related sites

Continue beyond Python

Explore related Worldmonger sites when you want to move from Python basics into JavaScript or LLM application building.

JavaScript tutorialstutorial

LearnJSFast

Beginner-friendly JavaScript tutorials for practical web development and self-taught developers.

JavaScriptFrontendWeb development
Visit LearnJSFast
LLM tutorialstutorial

LearnLLMFast

Practical LLM tutorials for builders who want to understand prompting, workflows, agents, and AI applications.

LLMAIBuilders
Visit LearnLLMFast

Keep learning

Related tutorials

Continue with nearby Python topics and beginner-friendly explanations.

A breathtaking sunrise over a vast mountainous landscape with clear skies.
beginner
6 min read

Defining Functions in Python

A function turns a block of code into a named tool you can call by name. Write the steps once, give them a name, and reuse them across your program instead…

Read tutorial
Explore summer relaxation with a teal swimsuit covered in sand on a sunny beach.
beginner
7 min read

Importing Modules in Python

An import statement is not a magic incantation. It is a name-resolution request: you tell the running Python program, "find this module and make its names…

Read tutorial