Python Functions Tutorial Beginners
You have been writing Python code that runs from top to bottom — one instruction after another. That works for small scripts, but as your programs grow, you will start repeating the same blocks of code over and over. That is a problem. Functions are the solution.
A function is a named, reusable block of code that you define once and can call as many times as you need from anywhere in your program. Functions make your code shorter, cleaner, easier to read, and much easier to fix when something goes wrong. Every serious Python program is built around functions.
Table of Contents
- What Is a Function?
- Defining and Calling Functions
- Parameters and Arguments
- The return Statement
- Default Arguments
- Keyword Arguments
- *args and **kwargs
- Variable Scope — Local vs Global
- Docstrings — Documenting Your Functions
- Practical Examples
- Frequently Asked Questions
- Conclusion
1. What Is a Function?
Think of a function like a recipe. You write the recipe once — the list of ingredients and steps — and then whenever you want to make that dish, you just say its name. You do not rewrite the entire recipe every time.
In Python, the same idea applies. You write the code once inside a function, give it a name, and then call that name whenever you need that code to run.
Python already comes with many built-in functions that you have already been using:
print("Hello") # print() is a built-in function
len("Python") # len() is a built-in function
int("42") # int() is a built-in function
input("Enter: ") # input() is a built-in function
Now you are going to learn how to create your own.
2. Defining and Calling Functions
You define a function using the def keyword, followed by the function name, parentheses, and a colon. The code inside the function must be indented.
def function_name():
# code goes here
Defining a function does not run it. To actually run the code inside, you have to call the function by writing its name followed by parentheses.
# Defining the function
def greet():
print("Hello! Welcome to Verxio.")
print("Let's learn Python together.")
# Calling the function
greet()
Output:
Hello! Welcome to Verxio. Let's learn Python together.
You can call the same function as many times as you want:
greet() greet() greet()
All three lines produce the same output. You only wrote the code once.
3. Parameters and Arguments
A function that always does the exact same thing has limited usefulness. Parameters let you pass information into a function so it can work with different data each time it is called.
A parameter is the variable name listed inside the parentheses when you define the function. An argument is the actual value you pass in when you call the function.
# name is a parameter
def greet(name):
print(f"Hello, {name}! Welcome to Verxio.")
# "Alice" and "Bob" are arguments
greet("Alice")
greet("Bob")
greet("Hacker")
Output:
Hello, Alice! Welcome to Verxio. Hello, Bob! Welcome to Verxio. Hello, Hacker! Welcome to Verxio.
Functions can take multiple parameters, separated by commas:
def describe_tool(name, category, is_free):
print(f"Tool: {name}")
print(f"Category: {category}")
print(f"Free: {is_free}")
print("---")
describe_tool("Nmap", "Network Scanner", True)
describe_tool("Burp Suite", "Web Security", False)
Output:
Tool: Nmap Category: Network Scanner Free: True --- Tool: Burp Suite Category: Web Security Free: False ---
4. The return Statement
So far our functions just print things. But often you want a function to calculate something and give the result back so you can use it elsewhere in your program. That is what return does.
def add(a, b):
return a + b
result = add(10, 5)
print(result) # 15
print(add(100, 200)) # 300
The function calculates the sum and hands it back. You can store it in a variable, print it, or use it in another calculation.
def calculate_area(width, height):
area = width * height
return area
room1 = calculate_area(5, 4)
room2 = calculate_area(8, 3)
total = room1 + room2
print(f"Room 1 area: {room1} m²")
print(f"Room 2 area: {room2} m²")
print(f"Total area: {total} m²")
Output:
Room 1 area: 20 m² Room 2 area: 24 m² Total area: 44 m²
Important: Once Python hits a return statement, it immediately exits the function. Any code written after return inside the same function will never run.
def check_password(password):
if len(password) < 8:
return "Too short"
if password == "password":
return "Too obvious"
return "Password looks okay"
print(check_password("abc")) # Too short
print(check_password("password")) # Too obvious
print(check_password("Verx10$ecure")) # Password looks okay
5. Default Arguments
You can give a parameter a default value. If the caller does not provide that argument, the default is used automatically. If they do provide it, the default is overridden.
def greet(name, language="English"):
if language == "English":
print(f"Hello, {name}!")
elif language == "Swahili":
print(f"Habari, {name}!")
elif language == "French":
print(f"Bonjour, {name}!")
greet("Alice") # Uses default - English
greet("Kamau", "Swahili") # Overrides default
greet("Pierre", "French") # Overrides default
Output:
Hello, Alice! Habari, Kamau! Bonjour, Pierre!
Rule: Parameters with default values must always come after parameters without defaults in the function definition.
# Correct
def connect(host, port=80):
print(f"Connecting to {host}:{port}")
# This would cause an error - default before non-default
# def connect(port=80, host): # SyntaxError
6. Keyword Arguments
Normally, arguments are matched to parameters by their position — the first argument goes to the first parameter, the second to the second, and so on. But you can also pass arguments by name, which makes your code clearer and lets you pass them in any order.
def create_user(username, email, role):
print(f"Username: {username}")
print(f"Email: {email}")
print(f"Role: {role}")
# Positional - order matters
create_user("thecrazyhacker", "admin@verxio.site", "admin")
# Keyword - order does not matter
create_user(role="editor", username="blogwriter", email="writer@verxio.site")
7. *args and **kwargs
Sometimes you do not know in advance how many arguments someone will pass to your function. Python gives you two special syntaxes to handle this.
*args — accept any number of positional arguments
The asterisk before the parameter name tells Python to collect all extra positional arguments into a tuple.
def add_all(*numbers):
total = 0
for num in numbers:
total += num
return total
print(add_all(1, 2)) # 3
print(add_all(10, 20, 30)) # 60
print(add_all(5, 5, 5, 5, 5)) # 25
**kwargs — accept any number of keyword arguments
Double asterisk collects all extra keyword arguments into a dictionary.
def display_info(**details):
for key, value in details.items():
print(f"{key}: {value}")
display_info(name="Verxio", type="Blog", topic="Cybersecurity", year=2026)
Output:
name: Verxio type: Blog topic: Cybersecurity year: 2026
8. Variable Scope — Local vs Global
Scope refers to where in your code a variable is accessible. This is one of the most confusing topics for beginners so read this carefully.
A variable created inside a function is a local variable. It only exists while that function is running and cannot be accessed from outside.
def my_function():
message = "I am local"
print(message)
my_function()
# print(message) # This would cause a NameError - message doesn't exist out here
A variable created outside all functions is a global variable. It can be read from inside functions but cannot be modified without the global keyword.
site_name = "Verxio" # global variable
def show_site():
print(f"Welcome to {site_name}") # reading global - this works fine
show_site()
count = 0 # global
def increment():
global count # declare we want to modify the global
count += 1
increment()
increment()
increment()
print(count) # 3
Best practice: Avoid modifying global variables from inside functions. It makes your code harder to understand and debug. Instead, pass values in as parameters and return the result.
9. Docstrings — Documenting Your Functions
A docstring is a string written at the very beginning of a function that explains what the function does. It is not required but it is excellent practice, especially as your functions grow more complex.
def calculate_bmi(weight_kg, height_m):
"""
Calculate Body Mass Index (BMI).
Parameters:
weight_kg (float): Weight in kilograms
height_m (float): Height in metres
Returns:
float: The calculated BMI value
"""
bmi = weight_kg / (height_m ** 2)
return round(bmi, 2)
print(calculate_bmi(70, 1.75)) # 22.86
You can access a function's docstring at any time using help():
help(calculate_bmi)
10. Practical Examples
Password Strength Checker
def check_password_strength(password):
"""Check how strong a password is and return a rating."""
score = 0
feedback = []
if len(password) >= 8:
score += 1
else:
feedback.append("Use at least 8 characters")
if any(char.isupper() for char in password):
score += 1
else:
feedback.append("Add at least one uppercase letter")
if any(char.isdigit() for char in password):
score += 1
else:
feedback.append("Add at least one number")
if any(char in "!@#$%^&*" for char in password):
score += 1
else:
feedback.append("Add a special character (!@#$%^&*)")
if score == 4:
rating = "Strong"
elif score == 3:
rating = "Medium"
else:
rating = "Weak"
return rating, feedback
rating, tips = check_password_strength("Verx10$!")
print(f"Password strength: {rating}")
for tip in tips:
print(f" - {tip}")
Simple Caesar Cipher
def caesar_encrypt(text, shift):
"""Encrypt text using Caesar cipher."""
result = ""
for char in text:
if char.isalpha():
base = ord('A') if char.isupper() else ord('a')
encrypted = chr((ord(char) - base + shift) % 26 + base)
result += encrypted
else:
result += char
return result
def caesar_decrypt(text, shift):
"""Decrypt Caesar cipher by reversing the shift."""
return caesar_encrypt(text, -shift)
message = "Hello Verxio"
encrypted = caesar_encrypt(message, 3)
decrypted = caesar_decrypt(encrypted, 3)
print(f"Original: {message}")
print(f"Encrypted: {encrypted}")
print(f"Decrypted: {decrypted}")
11. Frequently Asked Questions
Do I always need to use return in a function?
No. If a function does not have a return statement, it automatically returns None. Functions that just print output or perform an action do not need to return anything. Use return when you need the result of the function for further use in your program.
Can a function call another function?
Absolutely, and this is very common. Breaking complex tasks into smaller functions that call each other is a core principle of good programming. A function can call any other function that has been defined before it is called.
What is the difference between print() and return?
print() displays output to the screen — that is all it does. return sends a value back to wherever the function was called from, so the rest of your program can use it. A function that only prints cannot have its result stored in a variable or used in a calculation.
Can a function return multiple values?
Yes. Python lets you return multiple values separated by commas, and they come back as a tuple. Example: return width, height. You can unpack them like this: w, h = get_dimensions().
Conclusion
Functions are one of the most important concepts in all of programming. They let you write code once, reuse it everywhere, keep your programs organised, and fix problems in one place instead of hunting through dozens of repeated code blocks.
Make sure you practice: write a few of your own functions from scratch, experiment with parameters and return values, and try building the password checker and cipher examples above.
In the next part of the Python series, we cover Data Structures — lists, tuples, dictionaries, and sets. These are how Python stores and organises collections of information, and they are used in virtually every Python program ever written.



