Lesson 8 - Python Functions

In this lesson, we’ll explore Python functions. These are powerful tools that help us automate tasks, make our code easier to understand, and avoid repeating ourselves. We’ll begin with built-in functions like sum() and len() and then move on to creating our own custom functions.

Think of functions like a vending machine. You insert something (an input), the machine processes it, and you get a result (an output). Python functions work the same way:

  • They take in input (we call this a parameter)
  • They do something with that input (process it)
  • Then they give back a result (we call this the return value)

Let’s look at an example using a built-in function.


Example: Using len() to get the length of a list

list_1 = [21, 0, 72, 2, 5]
print(len(list_1))

Output:

5

Here’s what happens:

  1. We give the list list_1 to the len() function.
  2. The function counts the elements in the list.
  3. It returns 5, the number of items.

We can even mimic how len() might work behind the scenes using a for loop and a counter:

list_1 = [21, 0, 72, 2, 5]

length = 0
for item in list_1:
    length += 1

print(length)

Output:

5

We’ve just built a simple version of len() ourselves! In the next section, we’ll try the same for sum() — stay tuned.


Understanding Built-in Functions with an Example

In the previous section, we saw how the len() function counts the number of items in a list. Now let’s take another commonly used built-in function: sum().

What does sum() do?

It adds up all the numbers in a list and gives us the total. But instead of using it directly, let’s try writing the logic ourselves first to understand what’s happening under the hood.


Task: Manually compute the sum of a list

We’ll use a for loop to go through the list and add up each number. Here’s the list we’re working with:

a_list = [4444, 8897, 6340, 9896, 4835, 4324, 10, 6445,
          661, 1246, 1000, 7429, 1376, 8121, 647, 1280,
          3993, 4881, 9500, 6701, 1199, 6251, 4432, 37]

Let’s write a small piece of code that adds all these numbers manually:

sum_manual = 0
for list_element in a_list:
    sum_manual += list_element

print(sum_manual)
print(sum(a_list))

Output:

112464
112464

Notice something interesting here?

  • sum_manual is the result of our manual addition.
  • sum(a_list) is Python’s built-in way to do the same thing instantly.

Both return the same result — which confirms that our loop logic works just like sum().


So what have we learned here?

  • Built-in functions like sum() are simply pre-written tools that handle repetitive tasks.
  • When you understand how they work, you can write similar logic yourself — or even build your own versions when needed.

In the next section, we’ll build a frequency table using this idea — a repetitive task that’s perfect for turning into a function later.


Why We Use Functions

Imagine this — you’re analyzing a dataset and need to do the same thing again and again. For example, let’s say you want to count how many times each value appears in a list — a task we call building a frequency table.

You could write a for loop each time… or you could use a function and make your life much easier.

Let’s look at this small list of app content ratings:

ratings = ['4+', '4+', '4+', '9+', '12+', '12+', '17+', '17+']

Now we want to count how many times each rating appears in the list.


Task: Build a Frequency Table with a Dictionary

Here’s how we can do that with a for loop and a dictionary:

content_ratings = {}

for rating in ratings:
    if rating in content_ratings:
        content_ratings[rating] += 1
    else:
        content_ratings[rating] = 1

print(content_ratings)

Output:

{'4+': 3, '9+': 1, '12+': 2, '17+': 2}

Why this matters

This is a perfect example of a repetitive task:

  • You might want to generate similar tables for different columns or datasets.
  • Writing the same code over and over is inefficient.
  • It’s easy to make mistakes when you copy-paste and tweak things manually.

This is exactly where functions come in handy.

In the next section, we’ll write our own function to handle tasks like this.


Creating Your First Function

So far, we’ve seen how useful built-in functions like sum() and len() can be. But what if Python doesn’t have a built-in function for what you need?

No worries — Python lets you create your own functions.

Let’s start simple.


A Function to Square a Number

Say you want to calculate the square of a number — that is, multiply the number by itself. Instead of writing the formula over and over again, you can define a function:

def square(a_number):
    squared_number = a_number * a_number
    return squared_number

Let’s break this down:

  • def tells Python we’re defining a function.
  • square is the function’s name.
  • a_number is the input — we call it a parameter.
  • Inside the function, we multiply a_number * a_number.
  • Then we return the result.

Let’s try using the function:

squared_6 = square(a_number=6)
squared_4 = square(a_number=4)
squared_9 = square(a_number=9)

print(squared_6)
print(squared_4)
print(squared_9)

Output:

36
16
81

Practice Time

Let’s practice by computing a few more squares.

def square(a_number):
    squared_number = a_number * a_number
    return squared_number

squared_10 = square(a_number=10)
squared_16 = square(a_number=16)

Now you’ve just written your first custom function!


Great! Let’s move on.


Understanding the Structure of a Function

Let’s revisit the function you just created — square(a_number) — and take a closer look at how it’s built. Understanding the anatomy of a function will make it much easier to write your own later.

Here’s the full function again:

def square(a_number):
    squared_number = a_number * a_number
    return squared_number

Key parts of a function:

PartWhat it does
defKeyword that tells Python you’re defining a function
squareThe name of the function (you choose this!)
a_numberThe input your function accepts — this is called a parameter
Function bodyThe indented lines of code that do the actual work
returnSends back the final result so you can use it outside the function

When you write this line:

squared_6 = square(a_number=6)

Python will:

  1. Take in the number 6 (that’s the argument).
  2. Multiply it by itself (6 * 6).
  3. Return 36 and store it in the variable squared_6.

Here’s a quick visual to help you understand what happens during a function call:

Input: 6 → square function → Output: 36

Let’s Write Another One

Let’s say we often need to add 10 to different numbers. We can create a function to do that for us:

def add_10(number):
    result = number + 10
    return result

Now you can use it just like the built-in functions:

add_30 = add_10(number=30)
add_90 = add_10(number=90)

This saves time, reduces errors, and makes your code easier to read.


Parameters vs. Arguments

Let’s clear up a common confusion: parameters and arguments are not the same — although many people mix them up.

Let’s look at this simple function again:

def square(a_number):
    return a_number * a_number

What is a parameter?

The variable name you define inside the parentheses when creating a function — like a_number in def square(a_number) — is called a parameter. It’s like a placeholder for the input value.

What is an argument?

The actual value you pass into the function when calling it — like 6 in square(6) — is the argument.

Quick Example:

def square(a_number):     # a_number is the parameter
    return a_number ** 2

print(square(6))          # 6 is the argument

Do I always need to name the argument?

No. In most cases, especially with short functions, you can just call the function like this:

square(6)

But you can also be more explicit by naming the argument:

square(a_number=6)

Both ways are correct. The second way makes your code easier to read in some situations, especially when there are multiple parameters.


Let’s Try It with Multiple Parameters

Suppose we want to format dates. Here’s a simple function to do that:

def date(year, month, day):
    return month + " " + str(day) + ", " + str(year)

We pass three arguments into the function, and it puts them together in a readable format:

print(date(2006, "July", 15))      # July 15, 2006
print(date(2004, "February", 4))   # February 4, 2004
print(date(1949, "June", 9))       # June 9, 1949

If you reverse the order or forget one argument, it won’t work as expected — so always check your order and number of inputs!



The Return Statement

Let’s revisit one of the most important parts of writing your own function: the return statement.

The return statement tells Python what the result of your function should be — it’s what gets sent back when the function is called.

Here’s the square() function again:

def square(a_number):
    squared_number = a_number * a_number
    return squared_number

When we call square(6), the function returns the value 36.

print(square(6))

Skipping the Extra Step

Sometimes, instead of creating a separate variable like squared_number, you can directly return the result of the expression:

def square(a_number):
    return a_number * a_number

Both versions work the same. The second one is a bit cleaner and often preferred — as long as it stays readable.


When NOT to Skip the Step

If the calculation is complex, skipping steps can make your code hard to read:

# Not recommended — this is hard to read!
def confusing(x):
    return ((x**2 + x)**x * 2**2.71828) / (x**x)**5

In those cases, it’s better to break the problem into smaller parts using intermediate variables.


Your Turn: Practice

Let’s practice creating a simple function using the shorter version.

Task

  1. Write a function named square() that returns the square of a number, using the short version (no intermediate variable).

  2. Use the function to find:

    • The square of 6, store it in squared_6
    • The square of 11, store it in squared_11
# Your code here

def square(a_number):
    return a_number * a_number

squared_6 = square(6)
squared_11 = square(11)

print(squared_6)
print(squared_11)

Review

In this lesson, you learned how Python functions can simplify and speed up your workflow — especially when tasks start to repeat. Here’s a quick recap of what we’ve covered:


Key Concepts

  • Functions help us organize and reuse code. A function:

    1. Takes input (called a parameter)
    2. Does something with that input (processing)
    3. Returns a result (called output)
  • Built-in functions like sum(), len(), min(), and max() already exist in Python and are ready to use.

  • We can also create our own functions using the def keyword. This is helpful when we want to automate repetitive tasks or package logic into reusable blocks.


Function Structure

Every function has three main parts:

  1. Header: This starts with def, followed by the function’s name and its parameters in parentheses.
  2. Body: This contains the logic and is indented.
  3. Return Statement: This sends back the output to the place where the function was called.

Example:

def square(number):         # Header
    return number * number  # Body with return

Parameters and Arguments

  • A parameter is the name you use in the function definition: def square(number)
  • An argument is the actual value you pass when calling the function: square(6)

Why This Matters

Functions:

  • Make your code easier to read, test, and reuse
  • Reduce duplication — write once, use many times
  • Help break big problems into smaller, manageable pieces

As your projects grow, writing and using functions will become second nature. It’s one of the biggest steps forward in learning to think like a programmer.