Functions in Python
Reviewed & published by Brayan K
A function in Python is a named, reusable block of code that performs a specific task, optionally takes inputs (arguments) and returns a result, so you can run the same logic many times without repeating it.
Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Learn to organize, reuse, and simplify your code with Python functions.
What You'll Learn in This Lesson
- What a function is and why it's the #1 tool for code reuse
- How to define functions with def and call them
- How to pass data into functions using parameters
- How to get results back from functions with return
- Default parameters and keyword arguments
- How to return multiple values at once
1. What Are Functions?
A function is a reusable block of code that performs a specific task. Instead of writing the same code over and over, you write it once in a function and call it whenever you need it.
Why Use Functions?
- Reusability — Write once, use many times
- Organization — Break complex programs into smaller pieces
- Easier debugging — Fix bugs in one place, not everywhere
- Readability — Code is easier to understand
2. Defining a Function
Use the def keyword to create a function:
| Part | Meaning |
|---|---|
| def | Keyword that starts a function definition |
| function_name | The name you give your function (use snake_case) |
| () | Parentheses for parameters (empty if none) |
| : | Colon to start the function body |
| Indented code | The code that runs when you call the function |
# Define a simple function
def greet():
print("Hello, World!")
# Call the function
greet()
# You can call it multiple times
greet()
greet()
# ✅ Expected output:
# Hello, World!
# Hello, World!
# Hello, World!3. Parameters — Giving Functions Inputs
Parameters are variables listed inside the parentheses when defining a function. They allow you to pass information into the function.
# Function with one parameter
def greet(name):
print(f"Hello, {name}!")
# Call with different arguments
greet("Alice")
greet("Bob")
greet("Charlie")
# Function with multiple parameters
def introduce(name, age):
print(f"I'm {name} and I'm {age} years old.")
introduce("Alice", 25)
introduce("Bob", 30)
# ✅ Expected output:
# Hello, Alice!
# Hello, Bob!
# Hello, Charlie!
# I'm Alice and I'm 25 years old.
# I'm Bob and I'm 30 years old.4. Return Values — Getting Results Back
The return keyword sends a value back to the code that called the function. This lets you use the result!
def add(a, b):
print(a + b)
result = add(5, 3)
# Prints: 8
# result is None!def add(a, b):
return a + b
result = add(5, 3)
# result is 8
print(result * 2) # 16# Function that returns a value
def add(a, b):
return a + b
# Store the result
result = add(5, 3)
print(f"5 + 3 = {result}")
# Use the result in another calculation
doubled = result * 2
print(f"Doubled: {doubled}")
# Use directly in expressions
total = add(10, 20) + add(5, 5)
print(f"Total: {total}")
# ✅ Expected output:
# 5 + 3 = 8
# Doubled: 16
# Total: 40🎯 Your Turn: Write a Function That Returns
You have now seen def, parameters, and return in worked examples. Time to finish one yourself. Everything is written except four small pieces — replace each ___, run it, and check your output against the expected block at the bottom.
# 🎯 YOUR TURN — replace each ___ and run it.
___ area_of_rectangle(width, height): # 👉 the keyword that starts a function definition
"""Return the area of a rectangle."""
___ width * height # 👉 send the answer BACK to whoever called it
# Call it twice and keep both answers.
small = area_of_rectangle(3, 4)
big = area_of_rectangle(___, ___) # 👉 use a width of 10 and a height of 2.5
print("small:", small)
print("big :", big)
print("total:", small + big) # only works because the function RETURNS a number
# ✅ Expected output:
# small: 12
# big : 25.0
# total: 37.05. Default Parameter Values
You can give parameters default values. If no argument is passed, the default is used:
# Function with default parameter
def greet(name="Guest"):
print(f"Hello, {name}!")
greet() # Uses default
greet("Alice") # Uses provided value
# Multiple defaults
def create_user(name, role="user", active=True):
print(f"Created: {name} ({role}), Active: {active}")
create_user("Alice")
create_user("Bob", "admin")
create_user("Charlie", "mod", False)
# ✅ Expected output:
# Hello, Guest!
# Hello, Alice!
# Created: Alice (user), Active: True
# Created: Bob (admin), Active: True
# Created: Charlie (mod), Active: False6. Positional vs Keyword Arguments
When calling a function, you can pass arguments in two ways:
| Type | Example | Description |
|---|---|---|
| Positional | func("Alice", 25) | Arguments matched by position/order |
| Keyword | func(name="Alice", age=25) | Arguments matched by name (any order) |
def describe_pet(animal, name):
print(f"I have a {animal} named {name}.")
# Positional arguments (order matters)
describe_pet("dog", "Rex")
describe_pet("cat", "Whiskers")
# Keyword arguments (order doesn't matter)
describe_pet(name="Buddy", animal="hamster")
describe_pet(animal="fish", name="Nemo")
# Mixing: positional first, then keyword
describe_pet("bird", name="Tweety")
# ✅ Expected output:
# I have a dog named Rex.
# I have a cat named Whiskers.
# I have a hamster named Buddy.
# I have a fish named Nemo.
# I have a bird named Tweety.Worked Example: One Function, Every Idea So Far
Parameters, a default value, keyword arguments, a return value and a docstring all fit comfortably in one small function. Read every comment, then run it — this is the shape most real functions take.
def order_total(price, quantity, discount=0.0):
"""Work out what a customer pays. discount is a fraction: 0.1 means 10% off."""
subtotal = price * quantity # 4.50 x 2 = 9.0
saving = subtotal * discount # the money taken off
# round(value, 2) keeps it to pennies - floats otherwise drift, e.g. 8.100000000001
return round(subtotal - saving, 2) # hand the final figure back to the caller
# Two arguments given, so 'discount' falls back to its default of 0.0
plain = order_total(4.50, 2)
print("no discount :", plain) # 9.0
# A third argument is supplied, so it OVERRIDES the default
reduced = order_total(4.50, 2, 0.10)
print("10% off :", reduced) # 8.1
# Naming the arguments makes the call readable, and the order stops mattering
named = order_total(quantity=3, price=2.00, discount=0.25)
print("named args :", named) # 4.5 (3 x 2.00 = 6.00, minus a quarter)
# A returned value is an ordinary number - use it anywhere you like
print("all three :", round(plain + reduced + named, 2))
# The docstring is not a comment - Python stores it on the function itself,
# which is what help() and your editor's tooltips read.
print("help text :", order_total.__doc__)
# ✅ Expected output:
# no discount : 9.0
# 10% off : 8.1
# named args : 4.5
# all three : 21.6
# help text : Work out what a customer pays. discount is a fraction: 0.1 means 10% off.7. Returning Multiple Values
Python functions can return multiple values at once! They're returned as a tuple.
# Return multiple values
def calculate(a, b):
sum_val = a + b
diff = a - b
product = a * b
return sum_val, diff, product
# Unpack the results
s, d, p = calculate(10, 5)
print(f"Sum: {s}, Difference: {d}, Product: {p}")
# Or store as tuple
results = calculate(20, 3)
print(f"All results: {results}")
print(f"Just the sum: {results[0]}")
# ✅ Expected output:
# Sum: 15, Difference: 5, Product: 50
# All results: (23, 17, 60)
# Just the sum: 238. Variable Scope — Local vs Global
Scope determines where a variable can be accessed:
| Scope | Where Defined | Where Accessible |
|---|---|---|
| Local | Inside a function | Only inside that function |
| Global | Outside all functions | Everywhere in the file |
# Global variable
message = "Hello from outside!"
def my_function():
# Local variable
local_msg = "Hello from inside!"
print(local_msg) # Works - local variable
print(message) # Works - can read global
my_function()
print(message) # Works - global variable
# print(local_msg) # ERROR - local_msg doesn't exist here!
# ✅ Expected output:
# Hello from inside!
# Hello from outside!
# Hello from outside!9. Docstrings — Documenting Your Functions
A docstring is a special string that describes what your function does. Put it right after the def line:
def calculate_area(width, height):
"""
Calculate the area of a rectangle.
Parameters:
width: The width of the rectangle
height: The height of the rectangle
Returns:
The area (width * height)
"""
return width * height
# Access the docstring
print(calculate_area.__doc__)
# Use help() to see it
help(calculate_area)
# ✅ Expected output:
#
# Calculate the area of a rectangle.
#
# Parameters:
# width: The width of the rectangle
# height: The height of the rectangle
#
# Returns:
# The area (width * height)
#
# Help on function calculate_area in module __main__:
#
# calculate_area(width, height)
# Calculate the area of a rectangle.
#
# Parameters:
# width: The width of the rectangle
# height: The height of the rectangle
#
# Returns:
# The area (width * height)10. Common Mistakes to Avoid
| Mistake | Wrong | Correct |
|---|---|---|
| Forgetting parentheses | greet | greet() |
| Forgetting colon | def greet() | def greet(): |
| Missing indentation | def greet(): print("Hi") | def greet(): print("Hi") |
| Using print instead of return | print(a + b) | return a + b |
| Wrong argument count | add(5) | add(5, 3) |
11. Practical Examples
Example 1: Temperature Converter
def celsius_to_fahrenheit(celsius):
"""Convert Celsius to Fahrenheit."""
return (celsius * 9/5) + 32
def fahrenheit_to_celsius(fahrenheit):
"""Convert Fahrenheit to Celsius."""
return (fahrenheit - 32) * 5/9
# Test the functions
print(f"0°C = {celsius_to_fahrenheit(0)}°F")
print(f"100°C = {celsius_to_fahrenheit(100)}°F")
print(f"98.6°F = {fahrenheit_to_celsius(98.6):.1f}°C")
# ✅ Expected output:
# 0°C = 32.0°F
# 100°C = 212.0°F
# 98.6°F = 37.0°CExample 2: Grade Calculator
def calculate_grade(score):
"""Return letter grade based on score."""
if score >= 90:
return "A"
elif score >= 80:
return "B"
elif score >= 70:
return "C"
elif score >= 60:
return "D"
else:
return "F"
# Test with different scores
scores = [95, 82, 73, 65, 45]
for score in scores:
grade = calculate_grade(score)
print(f"Score: {score} → Grade: {grade}")
# ✅ Expected output:
# Score: 95 → Grade: A
# Score: 82 → Grade: B
# Score: 73 → Grade: C
# Score: 65 → Grade: D
# Score: 45 → Grade: FExample 3: Simple Calculator
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
return "Error: Cannot divide by zero"
return a / b
# Use the calculator functions
print(f"10 + 5 = {add(10, 5)}")
print(f"10 - 5 = {subtract(10, 5)}")
print(f"10 × 5 = {multiply(10, 5)}")
print(f"10 ÷ 5 = {divide(10, 5)}")
print(f"10 ÷ 0 = {divide(10, 0)}")
# ✅ Expected output:
# 10 + 5 = 15
# 10 - 5 = 5
# 10 × 5 = 50
# 10 ÷ 5 = 2.0
# 10 ÷ 0 = Error: Cannot divide by zero🎯 Mini-Challenge: A Tiny Grade Report
No code is pre-written this time — only the brief. You will need two functions: one that returns two values at once, and one that works out an average. Take it a step at a time, and use the expected output to check yourself.
# 🎯 MINI-CHALLENGE: a tiny grade report
#
# 1. Write describe_score(score, pass_mark=50) that RETURNS TWO things:
# the score itself, and the word "PASS" if score >= pass_mark else "FAIL"
# 2. Write average(scores) that returns the mean of a list of numbers,
# rounded to 1 decimal place
# 3. Use this data: scores = [72, 48, 91, 53]
# 4. Loop over scores. For each one, unpack the two returned values into
# two variables and print them as "72 -> PASS"
# 5. Finally print "average:" followed by average(scores)
#
# ✅ Expected output:
# 72 -> PASS
# 48 -> FAIL
# 91 -> PASS
# 53 -> PASS
# average: 66.0
# your code hereSummary: Quick Reference
| Concept | Syntax | Example |
|---|---|---|
| Define function | def name(): | def greet(): |
| With parameter | def name(param): | def greet(name): |
| Return value | return value | return a + b |
| Default param | param="default" | def greet(name="Guest"): |
| Keyword arg | param=value | greet(name="Alice") |
| Multiple returns | return a, b | x, y = func() |
| Docstring | """text""" | """Calculate area.""" |
Lesson done — you can now write reusable code like a pro!
Functions are the single most important concept in all of programming. You now know how to define them, pass data in, get results out, set defaults, and return multiple values.
Practice quiz
Which keyword is used to define a function in Python?
- func
- define
- def
- function
Answer: def. Functions are defined with the def keyword.
How do you call a function named greet that takes no arguments?
- greet()
- greet
- call greet
- def greet()
Answer: greet(). You call a function by writing its name followed by parentheses: greet().
What does a function return if it has no return statement?
- 0
- An empty string
- An error
- None
Answer: None. A function without a return statement returns None by default.
What is the difference between a parameter and an argument?
- They are the same thing
- A parameter is in the definition; an argument is the value passed in
- An argument is in the definition; a parameter is passed in
- Parameters are only for built-in functions
Answer: A parameter is in the definition; an argument is the value passed in. Parameters are the placeholders in the definition; arguments are the actual values supplied at call time.
For def greet(name='Guest'): what does greet() print?
- Hello, Guest!
- Hello, name!
- An error
- Hello, !
Answer: Hello, Guest!. With no argument the default value 'Guest' is used.
Where must default parameters appear in a function definition?
- First, before non-default ones
- Anywhere
- After non-default parameters
- Only alone
Answer: After non-default parameters. Default parameters must come after all non-default parameters.
What does 'return a + b, a - b' give back?
- Only a + b
- A tuple of both values
- A list
- An error
Answer: A tuple of both values. Comma-separated return values are packed into a tuple.
What is the main difference between print() and return?
- No difference
- return displays output
- print() is faster
- print() displays output (returns None); return sends a value back to use
Answer: print() displays output (returns None); return sends a value back to use. print() shows text but the function returns None; return hands a usable value back to the caller.
A variable defined inside a function is what kind of scope?
- Global
- Local
- Universal
- Static
Answer: Local. Variables defined inside a function are local and only accessible inside that function.
What is a docstring?
- A required return value
- A type of parameter
- A string describing what a function does, placed right after def
- A way to call a function
Answer: A string describing what a function does, placed right after def. A docstring is a string placed at the start of a function body to document it.
Continue this course
- Previous: Loops - For and While
- Next: Lists and Collections — Store and manipulate ordered sequences of data with Python lists
- Quick reference: Python cheat sheet › Functions
- From the blog: The Two Things That Actually Confused Me Learning Python (That No Course Explains)