Functions

Beginner-Friendly Teaching Edition — Python

What You Will Learn

  • How to define and call your own functions.
  • How parameters and return values work.
  • How functions can receive multiple, default, keyword and arbitrary arguments.
  • How Python generates random numbers and how the random module can simulate a die.
  • How tuples can be used to return more than one value.
  • How to use the Python Standard Library and the math module.
  • How methods, scope and imports work.
  • How Python passes object references to functions.
  • How recursion and functional-style programming work.
  • How variance and standard deviation measure data spread.

Chapter Structure

4.1 Introduction4.2 Defining Functions4.3 Multiple Parameters4.4 Random Numbers4.5 Game of Chance4.6 Standard Library4.7 math Module4.8 Tab Completion4.9 Default Parameters4.10 Keyword Arguments4.11 *args4.12 Methods4.13 Scope4.14 import4.15 Argument Passing4.16 Recursion4.17 Functional Style4.18 Dispersion4.19 Wrap-Up

4.1 Introduction

Functions are one of the most important ideas in programming. A function is a named block of code that performs a specific task. Instead of writing the same code again and again, we put it inside a function and call it whenever we need it.

Big idea: A function helps us reuse code, organize a program, make code easier to test and make complicated programs easier to understand.

This chapter also connects functions with random-number generation, the Python Standard Library, methods, scope, imports, argument passing, recursion, functional-style programming and measures of dispersion. The source chapter specifically uses random numbers to simulate a six-sided die and builds toward the dice game craps.

4.2 Defining Functions

You have already used built-in functions such as print(), input(), len(), sum(), min() and max(). Now we create our own.

Basic Function Syntax

def function_name(parameter):
    # function body
    return result
  • def tells Python that we are defining a function.
  • function_name is the name we choose.
  • A parameter is an input received by the function.
  • return sends a result back to the caller.
def square(number):
    """Calculate the square of number."""
    return number ** 2

print(square(7))
print(square(2.5))
49 6.25
Remember: Defining a function does not mean it runs immediately. The function runs when you call it.

Function Call Flow

Call functionPass argumentFunction executesreturn valueCaller receives result

4.3 Functions with Multiple Parameters

A function can receive more than one input.

def rectangle_area(length, width):
    return length * width

area = rectangle_area(10, 5)
print(area)
50

The first argument goes to length and the second goes to width.

Common mistake: The number and order of positional arguments matter. If a function expects two parameters, calling it with the wrong number of arguments causes an error.

4.4 Random-Number Generation

Python's Standard Library contains the random module. It provides functions for generating pseudo-random values. In this chapter, random numbers are used to simulate rolling a six-sided die.

import random

for roll in range(5):
    print(random.randrange(1, 7))

randrange(1, 7) can produce 1 through 6; the ending value 7 is excluded.

Reproducible Random Numbers

Sometimes we want random-looking values but also want the same sequence every time while testing. A random-number generator can be seeded for reproducibility.

import random

random.seed(10)
print(random.randrange(1, 7))
Remember: Seeding is useful when you want repeatable results during testing or demonstrations.

4.5 Case Study: A Game of Chance

The chapter combines custom functions and random-number generation to simulate the dice game craps. It also introduces tuples and uses a tuple to return more than one value from a function.

Returning More Than One Value

A function can return multiple values together. Python can pack those values into a tuple.

def roll_dice():
    import random
    die1 = random.randrange(1, 7)
    die2 = random.randrange(1, 7)
    return die1, die2

first, second = roll_dice()
print(first, second)
Think of a tuple like a small package: the function can put several values into one returned package, and the caller can unpack them into separate variables.

Craps — Core Idea

The important programming lesson is not memorizing a casino game. The lesson is how several functions, random values, conditions and returned values can work together to model a real process.

Roll two diceAdd the valuesCheck game rulesWin / lose / roll again

4.6 Python Standard Library

Python comes with a large collection of reusable modules called the Python Standard Library. Using these capabilities saves you from reinventing the wheel. The chapter imports and uses modules such as random, math and statistics.

import math
print(math.sqrt(81))
9.0
Remember: Before writing a utility yourself, check whether Python's Standard Library already provides it.

4.7 math Module Functions

The math module provides mathematical functions and constants.

Function / ConstantMeaningExample
math.sqrt(x)Square rootmath.sqrt(25) → 5.0
math.pow(x, y)x raised to ymath.pow(2, 3) → 8.0
math.piπUseful for circles
math.eEuler's numberMathematical constant
import math

radius = 5
area = math.pi * radius ** 2
print(area)

4.8 Using IPython Tab Completion for Discovery

IPython provides tab completion, which helps you discover available names and members while coding. Instead of remembering everything, you can type part of a name and use tab completion to explore what is available.

Learning habit: Use tools such as tab completion and documentation to discover capabilities rather than trying to memorize the entire Standard Library.

4.9 Default Parameter Values

A parameter can have a default value. If the caller does not provide that argument, Python uses the default.

def describe_pet(name, animal="dog"):
    return f"{name} is a {animal}"

print(describe_pet("Buddy"))
print(describe_pet("Milo", "cat"))
Buddy is a dog Milo is a cat

Here "dog" is the default value for animal.

Key idea: Default parameters make a function flexible while still keeping a convenient simple call.

4.10 Keyword Arguments

With positional arguments, Python matches values according to position. With keyword arguments, you explicitly name the parameter.

def rectangle_area(length, width):
    return length * width

print(rectangle_area(width=4, length=10))
40

Keyword arguments can make calls clearer, especially when a function has many parameters. The chapter notes that they also let arguments be supplied without depending entirely on their positions.

Remember: In a keyword argument, the parameter name is written before =: width=4.

4.11 Arbitrary Argument Lists

Sometimes a function needs to accept any number of arguments. Python supports this with *args.

def average(*args):
    return sum(args) / len(args)

print(average(5, 10))
print(average(5, 10, 15))
print(average(5, 10, 15, 20))
7.5 10.0 12.5

The * tells Python to pack the extra positional arguments into a tuple named args. The name args is conventional, but another identifier can be used. If *args is combined with other parameters, it must be the rightmost parameter.

Unpacking with *

grades = [88, 75, 96, 55, 83]

print(average(*grades))
83.4

The *grades expression unpacks the list so its individual elements are passed as separate arguments.

Watch out: Calling average() with no arguments makes len(args) zero, so the division causes ZeroDivisionError.

4.12 Methods: Functions That Belong to Objects

A method is a function that belongs to an object. You have already seen this idea with string methods.

name = "python"

print(name.upper())
print(name.title())
PYTHON Python
Function vs method:
Function → called by its name, such as len(name).
Method → called through an object, such as name.upper().

4.13 Scope Rules

Scope tells us where an identifier can be used. A variable created inside a function normally has local scope.

x = 10

def show_value():
    x = 20
    print("Inside:", x)

show_value()
print("Outside:", x)
Inside: 20 Outside: 10

The two x names refer to different bindings in different scopes.

Remember: A local variable is created for use within its function. A variable outside the function is not automatically replaced just because the function uses the same name.

4.14 import: A Deeper Look

There are several ways to import capabilities from a module.

Import the Module

import math
print(math.sqrt(36))

Import a Specific Identifier

from math import sqrt
print(sqrt(36))

Use an Alias

import statistics as stats

grades = [85, 93, 45, 87, 93]
print(stats.mean(grades))
80.6

The chapter recommends the module-name approach or an alias because it helps reduce accidental name conflicts.

Why avoid careless wildcard imports? With from math import *, names from the module can overwrite names already used in your program. The chapter demonstrates this with the name e.

4.15 Passing Arguments to Functions: A Deeper Look

Python arguments are passed using references to objects. The source describes this as pass-by-reference and also notes the term pass-by-object-reference. When a function call supplies an argument, Python copies the reference to the object, not the object itself.

Why Mutable Objects Matter

def add_item(items):
    items.append("Python")

books = ["Java"]
add_item(books)

print(books)
['Java', 'Python']

The function receives a reference to the same list object, so mutating the list is visible to the caller.

Important distinction: Passing a reference does not mean every assignment inside a function changes the caller's variable. What matters is whether the function mutates the shared object or simply rebinds its local parameter.

4.16 Recursion

A recursive function is a function that calls itself, either directly or indirectly through another function.

Example: Factorial

def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))
120

The function needs a base case so that the recursive calls eventually stop.

factorial(5)
5 × factorial(4)
→ 5 × 4 × factorial(3)
→ 5 × 4 × 3 × factorial(2)
→ 5 × 4 × 3 × 2 × factorial(1)
→ 120
Common mistake: A recursive function without a correct stopping condition can continue calling itself until Python raises a recursion-related error.

4.17 Functional-Style Programming

Python supports functional-style programming. This approach often treats functions as values that can be passed to other functions and emphasizes processing data through operations.

Lambda Functions

A lambda is a small anonymous function.

square = lambda x: x ** 2
print(square(5))
25

filter()

filter() selects elements for which a condition is true.

numbers = [1, 2, 3, 4, 5]
odds = list(filter(lambda x: x % 2 != 0, numbers))
print(odds)
[1, 3, 5]

map()

map() applies a function to each selected element.

numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x ** 2, numbers))
print(squares)
[1, 4, 9, 16, 25]

filter + map

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]

result = list(map(
    lambda x: x ** 2,
    filter(lambda x: x % 2 != 0, numbers)
))

print(result)
[1, 9, 25, 49, 81]

The chapter later connects these ideas to functional-style sequence processing and MapReduce.

Simple memory trick:
filter → "Which items should stay?"
map → "What should I do to each item?"

4.18 Intro to Data Science: Measures of Dispersion

Earlier, mean, median and mode described the center of data. Measures of dispersion describe how spread out the values are. The chapter introduces variance and standard deviation.

Example Data

values = [1, 3, 4, 2, 6, 5, 3, 4, 5, 2]

The mean is 3.5. To calculate population variance manually, subtract the mean from each value, square the differences and calculate their mean. For this data, the population variance is 2.25.

Using statistics

import statistics

values = [1, 3, 4, 2, 6, 5, 3, 4, 5, 2]

print(statistics.pvariance(values))
print(statistics.pstdev(values))
2.25 1.5

The chapter also shows that math.sqrt(statistics.pvariance(values)) gives 1.5.

MeasureSimple meaning
VarianceMeasures how far values spread from the mean, using squared differences.
Standard deviationSquare root of variance; it is expressed in the same units as the original data.
Small valueValues tend to be closer to the mean.
Large valueValues tend to be more spread out.

The chapter distinguishes population functions pvariance() and pstdev() from sample functions variance() and stdev().

Why standard deviation is often easier to interpret: variance has squared units, while taking the square root returns the result to the original units.

4.19 Wrap-Up

This chapter builds the foundation for writing reusable Python programs with functions. It combines custom functions with random-number generation, introduces tuples for returning multiple values, and demonstrates how the Standard Library helps programmers reuse existing capabilities.

Quick Concept Map

FunctionParametersreturnRandomTupleModulesDefault argsKeyword args*argsMethodsScopeimportReferencesRecursionLambdafilter/mapVarianceStd Dev

Common Beginner Mistakes

  1. Forgetting the colon after a function header.
  2. Incorrect indentation inside a function.
  3. Defining a function but forgetting to call it.
  4. Forgetting return when a value is needed by the caller.
  5. Passing the wrong number of arguments.
  6. Confusing positional arguments with keyword arguments.
  7. Calling a *args function with no values and then dividing by zero.
  8. Using wildcard imports and accidentally replacing an existing name.
  9. Forgetting a base case in recursion.
  10. Confusing mutation of a shared object with rebinding a local variable.

Remember These Points

  • def creates a function; a function call executes it.
  • Parameters receive input; return sends a result back.
  • Default parameters provide fallback values.
  • Keyword arguments identify parameters by name.
  • *args packs arbitrary positional arguments into a tuple.
  • *iterable unpacks an iterable into separate arguments.
  • A method is a function associated with an object.
  • Scope controls where names can be accessed.
  • Python passes references to objects as function arguments.
  • Recursion needs a stopping/base case.
  • filter selects; map transforms.
  • Variance and standard deviation describe data spread.

Revision Questions

  1. What is a function and why do programmers use functions?
  2. What is the difference between a parameter and an argument?
  3. What does the return statement do?
  4. How can a function return more than one value?
  5. Why is random.seed() useful?
  6. What is a default parameter value?
  7. What is a keyword argument?
  8. What does *args do?
  9. What is a method?
  10. What does scope mean?
  11. How does import ... as ... work?
  12. What does it mean that Python passes object references to functions?
  13. What is recursion?
  14. What is the difference between filter() and map()?
  15. What do variance and standard deviation tell us?

Practice Programs

  1. Write a function that returns the cube of a number.
  2. Write a function that accepts length and width and returns rectangle area.
  3. Write a function with a default parameter.
  4. Write an average(*args) function that safely handles zero arguments.
  5. Create a function that rolls two dice and returns both values.
  6. Use random to simulate 20 die rolls and count the results.
  7. Write a recursive factorial function.
  8. Use filter() to select even numbers and map() to square them.
  9. Calculate population variance and standard deviation using statistics.

Teaching note: This HTML is a beginner-friendly transformative explanation based on the chapter's concepts and structure. It is designed for learning and revision rather than reproducing the book's original text.