In Python, user-defined functions are custom functions created by the programmer to perform specific tasks. These functions allow you to encapsulate a block of code into a reusable, named unit. User-defined functions are defined using the def
keyword and can accept input parameters, execute a sequence of statements, and optionally return a value.
[1] Simplified User-Defined Function
The Python function below multiply_by_two
multiplies an input by two.
- Function Header: The function header line defines the function and its parameters. In this case, the function is named
multiply_by_two
, and it takes a single parameter,input_value
. The colon:
indicates the beginning of the function’s body. - Docstring: It provides a brief description of what the function does. It serves as documentation to help developers understand the purpose of the function.
- Function Body: The function body is the part of the function that contains the actual code. In this function, it’s a single line of code:
result = input_value * 2
. This line calculates the result by multiplying theinput_value
by 2 and assigns it to the variableresult
. - Return Statement: The
return
keyword is used to specify what the function should output. In this case, it returns the value stored in theresult
variable, which is the result of the multiplication. - Function Call: The last line,
multiply_by_two(5)
, is a function call. It invokes themultiply_by_two
function with the argument5
. This means it’s passing the value 5 as theinput_value
parameter. The function then returns the result of multiplying 5 by 2, which is 10.
########################################################
# USER-DEFINED FUNCTION
########################################################
def multiply_by_two(input_value): # <- Function Header
"""Takes an input value and multiplies it by two.""" # <- Docstring
result = input_value * 2 # <- Function Body
return result
multiply_by_two(5)
----------------- OUTPUT -----------------------
10
------------------------------------------------
[2] User-Defined Function with Multiple Parameters
User-defined functions with multiple parameters are custom functions that can accept more than one input value. These functions allow us to perform operations that depend on multiple pieces of data or information.
The Python function below multiply_numbers
takes two numbers (num1
and num2
) as input and returns their result.
########################################################
# MULTIPLE PARAMETERS
########################################################
def multiply_numbers(num1, num2):
""" Multiplies two numbers and returns the result """
result = num1 * num2
return result
multiply_numbers(2,5)
----------------- OUTPUT -----------------------
10
------------------------------------------------
[3] User-Defined Function with For Loop
The Python code below creates a Python function numbers_below_limit
that generates a list of numbers below a specified limit using a for loop. It takes one parameter limit
, which indicates the upper limit for generating the number.
Inside the function, an empty list named result
is created to store the generated numbers. A for loop is used to iterate through a range of numbers from 0 to limit-1
. This loop creates a sequence of numbers, starting from 0 and ending at a limit-1
. Inside the loop, each number is appended to the result
list using the append
method. After the loop, the result
list, which contains all the numbers below the specified limit, is returned as the output of the function.
########################################################
# USER-DEFINED FUNCTION WITH LOOP
########################################################
def numbers_below_limit(limit):
""" Generate a list of all numbers below a specified limit using a for loop """
result = []
for number in range(limit):
result.append(number)
return result
numbers_below_limit(10)
----------------- OUTPUT -----------------------
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
------------------------------------------------
[4] Scope in Functions
In programming, “scope” refers to the context or region in a program where a particular variable is valid and can be used. It defines where in your code a variable can be accessed or modified. There are two common types of scopes in most programming languages, including Python:
- Local Scope: Variables defined within a function are typically considered local to that function. They are only accessible from within that specific function and are not visible or usable outside of it.
- Global Scope: Variables defined at the top level of a program or module are considered global variables. They can be accessed and modified from anywhere in the program, including within functions.
The example below illustrates local and global scopes:
########################################################
# SCOPE
########################################################
x = 10 # Global variable
def my_function():
y = 5 # Local variable
print("Inside the function: x =", x, "y =", y)
my_function()
----------------- OUTPUT -----------------------
Inside the function: x = 10 y = 5
------------------------------------------------
In this example, global_variable
is in the global scope and can be accessed from anywhere in the code. local_variable
is in the local scope of the my_function
and is only accessible within that function.
[5] Nested Function
A nested function is a function defined inside another function. In programming, it’s a way to encapsulate functionality and create a more organized and modular code structure.
The code below defines a Python function called calculate_sum_and_square
, which calculates two related values and returns them as a pair.
########################################################
# NESTED FUNCTION
########################################################
def calculate_sum_and_square(x, y):
def calculate_sum(a, b):
return a + b
def calculate_square(c):
return c ** 2
total = calculate_sum(x, y)
squared_total = calculate_square(total)
return total, squared_total
result1, result2 = calculate_sum_and_square(3, 5)
print("The sum is:", result1)
----------------- OUTPUT -----------------------
The sum is: 8
------------------------------------------------
print("The square of the sum is:", result2)
----------------- OUTPUT -----------------------
The square of the sum is: 64
------------------------------------------------
[6] Default Arguments
Default arguments are parameters in a function that have predefined values. When you define a function with default arguments, you can call the function without providing a value for those parameters. Instead, the function uses the default values specified in the function definition.
Here’s an example:
########################################################
# DEFAULT
########################################################
def greet(name, greeting="Hello"):
print(greeting, name)
greet("Alice")
----------------- OUTPUT -----------------------
Hello Alice
------------------------------------------------
greet("Bob", "Hi")
----------------- OUTPUT -----------------------
Hi Bob
------------------------------------------------
In this example, the greet
function has a default value for the greeting
parameter. If you don’t provide a greeting when calling the function, it defaults to “Hello.”
[7] Flexible Arguments
Flexible arguments in Python are a way to pass an arbitrary number of arguments to a function. They are often used when we want a function to be able to handle an unknown or variable number of arguments. When we use *args
in a function definition, it allows us to pass an arbitrary number of positional arguments. These arguments are collected into a tuple, which can be iterated over or used in the function as needed.
In this example, *args
allows the function to accept any number of arguments, and it calculates the sum of these numbers.
########################################################
# FLEXIBLE ARGUMENTS
########################################################
def sum_numbers(*args):
total = 0
for num in args:
total += num
return total
result = sum_numbers(2, 4, 6, 8)
print(result)
----------------- OUTPUT -----------------------
20
------------------------------------------------
[8] Flexible Keyword Arguments
When we use **kwargs
in a function definition, it allows us to pass an arbitrary number of keyword arguments. These keywords arguments are collected into dictionary where the keys are the arguments names, and the values are the argument values.
In this example, **kwargs
allows the function to accept any number of keyword arguments and prints them.
########################################################
# FLEXIBLE KEYWORDS ARGUMENTS
########################################################
def display_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
display_info(name="Alice", age=30)
----------------- OUTPUT -----------------------
name: Alice
age: 30
------------------------------------------------
[9] Lambda Functions
A lambda function is a small, anonymous function that can be defined using the lambda
keyword. Lambda functions are commonly used in situations where a small simple function is needed for a short duration, such as in functional programming constructs like map()
, filter()
and reduce()
.
Here is an example of a lambda function that calculates the result of raising a given number x
to the power of another number y
.
########################################################
# LAMBDA FUNCTIONS
########################################################
# Create lambda function
raise_to_power = lambda x, y: x**y
raise_to_power(2,3)
----------------- OUTPUT -----------------------
8
------------------------------------------------
n the provided example, the lambda function raise_to_power
takes two arguments, x
and y
, and returns the result of raising x
to the power of y
. When we call raise_to_power(2, 3)
, it returns 2^3, which is 8.
[10] Error Handling
Error Handling in Python involves the process of managing and responding to expectations or errors that may occur during the execution of a program. Exception handling is critical for writing robust and reliable code. It allows us to handle unexpected situations, prevent our program from crashing, and provide meaningful error messages to users.
The following code defines a Python function named sqrt
. This function is intended to calculate the square root of a given number x
. If an exception occurs, the function will print the following message: x must be an int or float
.
########################################################
# ERROR HANDLING
########################################################
def sqrt(x):
""" Returns the square root of a number """
try:
return x ** 0.5
except:
print("x must be an int or float")
sqrt(4)
----------------- OUTPUT -----------------------
2.0
------------------------------------------------
sqrt('four')
----------------- OUTPUT -----------------------
x must be an int or float
------------------------------------------------
We can also use a TypeError
. This occurs when an operation receives an argument of the correct data type but with an inappropriate value.
The Python function sqrt
is intended to calculate the square root of a non-negative number. It includes input validation to ensure that the input is non-negative, and if a negative number is provided, it raises a ValueError
.
########################################################
# ERROR HANDLING
########################################################
def sqrt(x):
""" Returns the square root of a number """
if x < 0:
raise ValueError('x most be non-negative')
try:
return x ** 0.5
except TypeError:
print('x must be an int or float')
sqrt(4)
----------------- OUTPUT -----------------------
2.0
------------------------------------------------
sqrt(-4)
----------------- OUTPUT -----------------------
ValueError: x most be non-negative
------------------------------------------------
Conclusion
The blog post provides an overview of various aspects of user-defined functions and error handling in Python, including user-defined functions with multiple parameters, functions with loops, scopes, nested functions, default arguments, flexible arguments, lambda functions, and error handling.