15.1 Functions I: Defining & Calling

Type Hints & Docstrings

Type hints clarify expected types for readers and tooling; docstrings explain purpose and usage.

from typing import Iterable, Tuple

def summarize(nums: Iterable[int]) -> Tuple[int, int, float]:
    “””Return (count, total, average) for a series of integers.

    Args:
        nums: Iterable of integers.
    Returns:
        A tuple (n, s, avg) where n is element count, s is sum, and avg is mean.
    “””
    n = 0
    s = 0
    for x in nums:
        n += 1
        s += x
    avg = s / n if n else 0.0
    return n, s, avg

  • Use Google- or NumPy-style docstrings for consistency across your project.
  • Type hints are optional at runtime but valuable for IDEs, linters, and documentation.

7. Naming, Purity & Side Effects

  • Use snake_case for function names (e.g., compute_total).
  • Write small, single-purpose functions; one clear responsibility.
  • Minimize side effects (mutating globals, printing) unless the function’s purpose is I/O.
  • Separate computation from I/O: have one function compute a result and another handle printing.

# Separate concerns: compute vs print

def percent(numerator: int, denominator: int) -> float:
    return (numerator / denominator) * 100

def report_percent(numerator: int, denominator: int) -> None:
    pct = percent(numerator, denominator)
    print(f”{pct:.2f}%”)

8. Common Calling Errors & Diagnostics

  • TypeError: wrong number of arguments (missing/extra).
  • TypeError: unexpected keyword argument (name mismatch).
  • NameError: calling a function before its definition in the same scope (when not yet executed).

# Example: unexpected keyword name

def add(a, b):
    return a + b

add(x=1, y=2)  # TypeError: add() got an unexpected keyword argument ‘x’

9. Practical Patterns

Patterns you will use frequently when defining/using functions:

  • Use defaults to model optional behavior (height=1).
  • Provide keyword names for readability at call sites.
  • Return tuples for grouped results and unpack at the call site.
  • Document preconditions/postconditions in the docstring when non-obvious.

# Example: simple parser returning multiple results

def parse_coordinates(text: str):
    “””Parse ‘x,y’ into two ints (x, y). Raises ValueError on bad input.”””
    x_str, y_str = text.split(‘,’)
    return int(x_str), int(y_str)

x, y = parse_coordinates(‘10,20’)

10. What Comes Next (Preview of Functions II)

  • Parameter kinds: positional-only (/), keyword-only (*), variadic *args and **kwargs.
  • Mutable default arguments pitfalls and safe patterns.
  • Closures, scope rules (LEGB), and decorators overview.
Scroll to Top
Tutorialsjet.com