Handling Parameters and Return Values

A function is a named block of code that performs one well-defined task. Functions are the primary unit of reuse in Python: they let you name a behavior once and invoke it from anywhere in the program. Good programs are, to a large extent, a set of well-chosen functions glued together.

You define a function with def name(parameters): and optionally annotate each parameter and the return type with type hints (def total(values: list[int]) -> int:). Parameters are the named inputs; arguments are the values passed in at call time. Python supports positional arguments, keyword arguments, default values (def greet(name, greeting='Hello')), variable positional (*args), and variable keyword (**kwargs) parameter forms. Combining these thoughtfully lets a single function serve many call styles.

A return statement ends the function and sends a value back to the caller. Without an explicit return, the function returns None. A function can return any Python object, including tuples for multiple values, lists, dictionaries, other functions, or even classes. Returning None vs. returning a value is a design choice: pure computations should return; procedures that mutate the outside world may legitimately return nothing.

Well-designed functions share a handful of habits: one clear responsibility, predictable inputs and outputs, explicit validation of preconditions (raising ValueError or TypeError on bad input), and a short docstring that says what the function does rather than how. When a function grows past about twenty-five lines or starts mixing responsibilities, split it into smaller functions that call each other — the work in Handling Parameters and Return Values almost always reads better after that refactor.

Key syntax pieces that define and call functions for Handling Parameters and Return Values. Skim the table before reading the code example, and click any name to open the official documentation.

ToolPurpose
def
keyword
Declares a named function with parameters and body.
return
keyword
Sends a value back to the caller and ends the function.
*args
parameter form
Accepts any number of positional arguments as a tuple.
**kwargs
parameter form
Accepts any number of keyword arguments as a dictionary.
default values
syntax
def f(x=0) makes a parameter optional.
type hints
syntax
name: str -> int documents expected types for readers and tools.
lambda
keyword
Creates a tiny anonymous function in an expression.

Handling Parameters and Return Values Code example

Build typed reusable functions for Handling Parameters and Return Values.

# Lesson: Handling Parameters and Return Values
# Goal: define a focused function with type hints, call it with several inputs,
# and show how the return value is consumed afterwards by another piece of code.
from dataclasses import dataclass


@dataclass
class Student:
    name: str
    scores: list[float]


def summarize_handling_parameters_and_return_values(name: str, scores: list[float]) -> str:
    '''Return a single line describing a student's average and best score.'''
    if not scores:
        return f"{name}: no scores"
    avg = sum(scores) / len(scores)
    top = max(scores)
    return f"{name} -> avg={avg:.1f}, top={top:.1f}"


# --- main script ---------------------------------------------------------
students = [
    Student("Ada", [91.2, 88.0, 95.5]),
    Student("Lin", [78.0, 81.5]),
]

print(summarize_handling_parameters_and_return_values("Ada", [91.2, 88.0, 95.5]))
print(summarize_handling_parameters_and_return_values("Lin", [78.0, 81.5]))

# follow-up use: loop through the data class list and reuse the function
for student in students:
    line = summarize_handling_parameters_and_return_values(student.name, student.scores)
    print("report:", line)

Walk through each part before moving to the next lesson:

1) The example defines one clear unit of logic.
2) Inputs are explicit, so behavior is reproducible.
3) Output lines are designed for quick validation.
4) The self-test section confirms expected behavior.

Try both examples below to strengthen understanding.

# Example A: keyword arguments
def build_label_handling_parameters_and_return_values(name: str, level: str = "beginner") -> str:
    return f"{name} ({level})"
print(build_label_handling_parameters_and_return_values("Handling Parameters and Return Values learner"))

# Example B: multiple return values
def min_max_handling_parameters_and_return_values(values: list[int]) -> tuple[int, int]:
    return min(values), max(values)
print(min_max_handling_parameters_and_return_values([37, 2, 9, 8]))

Run these assertions after the example. If nothing prints, tests passed.

result = summarize_handling_parameters_and_return_values("A", [10.0, 20.0])
assert "avg=15.0" in result
assert summarize_handling_parameters_and_return_values("A", []) == "A: no scores"

Your exact values can vary slightly (especially dates/times), but the structure should match.

Ada -> avg=91.6, top=95.5
Lin -> avg=79.8, top=81.5