Python

Functions And Functional Basics

Functions: Basics & Return Values

Without functions, repeated logic gets copy-pasted everywhere — a maintenance nightmare. Functions let you write logic once, name it, and reuse it.

JrCodex·5 min read

Jr Codex Python Notes

Level: Beginner–Intermediate Prerequisites: Module 1: Python Fundamentals Time to complete: ~25 minutes


Table of Contents

  1. Why Functions?
  2. Defining and Calling a Function
  3. Parameters vs Arguments
  4. The return Statement
  5. Returning Multiple Values
  6. Docstrings
  7. Functions as First-Class Objects
  8. Summary & Next Steps

1. Why Functions?

Without functions, repeated logic gets copy-pasted everywhere — a maintenance nightmare. Functions let you write logic once, name it, and reuse it.

# Without a function — repeated, error-prone
price1 = 100
tax1 = price1 * 0.08
total1 = price1 + tax1
 
price2 = 250
tax2 = price2 * 0.08
total2 = price2 + tax2
 
# With a function — write once, reuse everywhere
def calculate_total(price, tax_rate=0.08):
    tax = price * tax_rate
    return price + tax
 
total1 = calculate_total(100)
total2 = calculate_total(250)

2. Defining and Calling a Function

def greet(name):
    message = f"Hello, {name}!"
    return message
 
result = greet("Alice")     # "calling" the function
print(result)                 # Hello, Alice!
Anatomy of a Function
─────────────────────────────────────────
  def greet(name):        ← def keyword, function name, parameters
      message = f"..."     ← function body (indented)
      return message         ← what the function sends back
─────────────────────────────────────────

A function that has no return statement implicitly returns None:

def say_hello(name):
    print(f"Hello, {name}!")     # prints, but doesn't RETURN anything
 
result = say_hello("Bob")    # prints "Hello, Bob!"
print(result)                    # None

3. Parameters vs Arguments

The terms are related but distinct — worth knowing precisely:

def add(a, b):        # a, b are PARAMETERS — placeholders in the definition
    return a + b
 
add(3, 5)               # 3, 5 are ARGUMENTS — actual values passed in
TermMeaning
ParameterThe name in the function definition (a, b)
ArgumentThe actual value passed when calling the function (3, 5)

Positional vs Keyword Arguments

def describe_pet(name, animal_type):
    print(f"{name} is a {animal_type}")
 
describe_pet("Rex", "dog")                          # positional — order matters
describe_pet(animal_type="dog", name="Rex")          # keyword — order doesn't matter
describe_pet("Rex", animal_type="dog")                # mixed — positional must come first

4. The return Statement

return immediately exits the function, sending a value back to the caller. Any code after return in that branch never runs.

def check_age(age):
    if age < 0:
        return "Invalid age"   # exits here for negative ages
    if age < 18:
        return "Minor"
    return "Adult"
    print("This never runs")    # unreachable code
 
print(check_age(-5))    # "Invalid age"
print(check_age(15))     # "Minor"
print(check_age(25))      # "Adult"

A function can have multiple return statements — only one executes per call, whichever is reached first.


5. Returning Multiple Values

Python "returns multiple values" by packing them into a tuple (this connects directly to Module 1, Chapter 7 on tuple unpacking):

def get_min_max(numbers):
    return min(numbers), max(numbers)     # packs into a tuple: (min, max)
 
low, high = get_min_max([4, 1, 9, 3])     # unpacks the tuple
print(low, high)                             # 1 9
 
result = get_min_max([4, 1, 9, 3])
print(result)                                  # (1, 9) — it really is just a tuple
print(type(result))                             # <class 'tuple'>

6. Docstrings

A docstring is a string literal right after the def line, documenting what the function does. Tools (help systems, IDEs, doc generators) read this automatically.

def calculate_bmi(weight_kg, height_m):
    """
    Calculate Body Mass Index.
 
    Args:
        weight_kg (float): Weight in kilograms.
        height_m (float): Height in meters.
 
    Returns:
        float: The calculated BMI.
    """
    return weight_kg / (height_m ** 2)
 
print(calculate_bmi.__doc__)     # prints the docstring
help(calculate_bmi)                # shows a formatted help page

Not every function needs a full docstring — for small, obvious helpers, a one-liner (or nothing) is fine. Reserve detailed docstrings for public/reusable functions.


7. Functions as First-Class Objects

In Python, functions are values, just like ints or strings — you can assign them to variables, store them in lists, and pass them to other functions. This idea underpins Chapter 6 (lambdas) and Module 5 (decorators).

def square(x):
    return x * x
 
my_func = square          # assign the function itself (no parentheses = don't call it)
print(my_func(5))            # 25 — calling through the new name
 
operations = [square, abs, len]   # a list of functions!
for op in operations:
    print(op)                       # <function ...> — these are function objects

8. Summary & Next Steps

Key Takeaways

  • Functions package logic for reuse — defined with def, invoked by calling with ().
  • Parameters are placeholders in the definition; arguments are the actual values passed at call time.
  • return exits immediately and sends a value back; no return means the function returns None.
  • "Multiple return values" are really just one tuple, unpacked at the call site.
  • Functions are first-class objects — they can be assigned to variables and passed around like any other value.

Concept Check

  1. What does a function return if it has no return statement?
  2. What's the difference between a parameter and an argument?
  3. How does return a, b actually work under the hood?

Next Chapter

Chapter 2: Function Arguments


Jr Codex — 1-on-1 Personalized Coaching | Back to Module Index