Fundamentals

Python Functions Explained Through Practical Projects

Functions give a reusable name to a task. A good function has a clear input, one responsibility and a predictable return value. This makes automation easier to test.

Step by step

  1. Name functions with verbs describing their work.
  2. Pass values as parameters rather than relying on global variables.
  3. Return results so other code can reuse them.
  4. Test normal, boundary and invalid inputs.

Run this example

Use Python 3. Copy the code into a file or interactive Python environment.

def subtotal(prices):
    return round(sum(prices), 2)

print(subtotal([4.5, 2.25, 3]))
print(subtotal([]))

Expected output

9.75
0

Common issue

Avoid mutable default arguments such as `def f(items=[])`; use `None` and create a list inside instead.

Try it yourself

Write a `with_tax(subtotal, rate)` function and test a zero tax rate.

A function is a reusable contract

Parameters are names for inputs; arguments are the values supplied by the caller. return gives a value back to the caller, while print displays a message. A function without an explicit return value returns None. Keep calculations separate from file or network operations so you can test them in isolation.

Calculate a basket total

This function validates every price and returns a number. The caller decides how to display it. The assertions check both a normal basket and the empty case.

def basket_total(prices):
    if any(price < 0 for price in prices):
        raise ValueError("prices cannot be negative")
    return sum(prices)

assert basket_total([4, 6, 2]) == 12
assert basket_total([]) == 0
print(f"Total: {basket_total([4, 6, 2])}")

Expected output

Total: 12

Make dependencies visible

Pass the data a function needs instead of relying on changing global variables. Avoid a mutable list as a default argument: defaults are evaluated once and can retain state between calls. Use None and create the list inside the function when needed.

Exercise

Add a discount parameter and reject discounts larger than the total or smaller than zero. A basket of 12 with a discount of 2 should return 10. Write tests for no discount, an empty basket, and an invalid discount.

Troubleshooting

A TypeError about missing arguments means the call does not match the signature. If you receive None unexpectedly, inspect every path through the function for a return statement. Keep validation errors specific enough to explain the fix.

Keep learning

Read the relevant documentation · Free foundational resources

Related guides: How to Automate Excel Tasks With Python and 7 Common Python Beginner Mistakes and How to Fix Them.

Interested in applying these skills to a product? Explore the optional Python to Profit course. It focuses on product and business building, not replacing foundational Python study.