0% found this document useful (0 votes)
8 views25 pages

Python Functions

The document provides an overview of functions in Python, explaining their definition, key features, and syntax. It covers various aspects such as calling functions, passing parameters, return values, and different types of function arguments including positional, keyword, and default arguments. Additionally, it discusses the use of *args and **kwargs for variable-length arguments and the pass statement for placeholder functions.

Uploaded by

sexynehasecy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views25 pages

Python Functions

The document provides an overview of functions in Python, explaining their definition, key features, and syntax. It covers various aspects such as calling functions, passing parameters, return values, and different types of function arguments including positional, keyword, and default arguments. Additionally, it discusses the use of *args and **kwargs for variable-length arguments and the pass statement for placeholder functions.

Uploaded by

sexynehasecy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

PYTHON

Python Functions
Python

What is a Function in Python?


A function is a block of reusable code that performs a specific task. Functions help
organize code, improve modularity, and enable code reuse.

Key Features of Functions


A function runs only when it is called.
Functions allow passing parameters (input data).
They can return a value as an output.
Defined using the def keyword in Python.
Enhances code reusability and modularity.

Defining a Function in Python


A function in Python is defined using the def keyword, followed by:

1. A function name.
2. Parentheses () (to hold parameters, if any).
3. A colon (:) to start the function block.
4. An optional docstring (a brief description of the function).
5. An indented code block inside the function.
6. A return statement (optional) to send back a result(Output of the function).

Syntax of a Function

def function_name(parameters):
"""Optional docstring"""
# Function logic here
return value # Optional return statement

Example: Function Without Parameters and


Without Return Value

# Defining a simple function with function name welcome_message


def welcome_message(): #No parameters
"""This function prints a welcome message."""
print("Welcome to Intensity Coding")

# Calling the function


welcome_message()
#Expected Output: Welcome to Intensity Coding

Welcome to Intensity Coding

Example: Function with Parameters and Return


Value

#Example: Function to add two numbers with function name add_numbers

def add_numbers(a, b): #Here a and b are parameters


"""Returns the sum of two numbers"""
return a + b # Returning the sum

result = add_numbers(5, 10) # Calling the function


print("Sum:", result)
#Output: Sum: 15

Sum: 15

Calling a Function in Python


Once a function is defined, it can be called by using its name followed by parentheses
().

# Defining a function
def greet():
"""Prints a greeting message"""
print("Hello from Intensity Coding!")

# Calling the function


greet()
#Output: Hello from Intensity Coding!

Hello from Intensity Coding!

Example: Calling a Function with Arguments

# Function with parameters


def greet_user(name):
"""Greets the user with a personalized message"""
print(f"Hello, {name}! Welcome to Intensity Coding.")

# Calling function with an argument


greet_user("Alice")
# Output: Hello, Alice! Welcome to Intensity Coding.
Hello, Alice! Welcome to Intensity Coding.

Return Values in Python


Functions in Python can return values using the return statement. This allows us to
reuse the computed value elsewhere in the program.
It helps in reusing function output , improves code modularity and makes functions
more flexible.

Syntax of the return Statement

def fun():
statement_1
statement_2
statement_3
...
return [expression]

The return statement specifies the output that a function provides when it finishes
execution.

The return statement terminates the function’s execution and optionally sends a
value back to the caller.
A function does not have to include a return statement; in that case, it
automatically returns None.
If return is used without an expression, Python implicitly returns None.
The return statement must always appear inside the function body.

def square_number(x):
"""Calculates the square of the given number and returns the
result."""
return x ** 2

# Calling the function and printing the results


print(square_number(3)) # Output: 9
print(square_number(5)) # Output: 25
print(square_number(9)) # Output: 81

9
25
81

Returning Multiple Values from a Function


A function can return multiple values by separating them with commas in the return
statement.
Internally, Python packs these values into a tuple, allowing you to retrieve them
individually when the function is called.

Syntax

def function_name():
# statements
return value1, value2, value3

# Function that returns multiple values


def student_info():
name = "Alice"
age = 22
course = "Machine Learning"

# Returning multiple values as a tuple


return name, age, course

# Calling the function


info = student_info()
print("Returned Tuple:", info)

# Unpacking returned values


student_name, student_age, student_course = student_info()

print("Name:", student_name)
print("Age:", student_age)
print("Course:", student_course)

Returned Tuple: ('Alice', 22, 'Machine Learning')


Name: Alice
Age: 22
Course: Machine Learning

Explanation

When multiple values are returned, Python groups them into a tuple by default.
You can unpack this tuple into separate variables for easier access.
This feature makes it convenient to return several related pieces of data from a single
function.

The pass Statement


Python does not allow empty function definitions. If you need to define a function
without implementing it yet, you can use the pass statement.
It helps prevents syntax errors when defining an empty function and useful for creating
placeholders in large projects.

def future_function():
"""This function will be implemented later."""
pass # Placeholder to avoid errors

# Calling the function (does nothing)


future_function()

Pass by Reference vs Value in Python


Pass by Reference in Python
In Python, all parameters (arguments) are passed by reference. This means if a
function modifies a mutable object (like a list), the change will be reflected outside the
function as well.

# Example: Pass by Reference (Mutable Object)


# Function modifies the list by appending elements
def changeme(mylist):
"""Appends new elements to the list"""
[Link]([1, 2, 3, 4])
print("Values inside the function:", mylist)

# Creating a list
mylist = [10, 20, 30]

# Calling the function


changeme(mylist)

# Checking the list after function call


print("Values outside the function:", mylist)

# Output:
# Values inside the function: [10, 20, 30, [1, 2, 3, 4]]
# Values outside the function: [10, 20, 30, [1, 2, 3, 4]]

Values inside the function: [10, 20, 30, [1, 2, 3, 4]]


Values outside the function: [10, 20, 30, [1, 2, 3, 4]]

Example: Overwriting the Reference (Pass by Value


Behavior)
When a new object is assigned to a parameter inside the function, the original
reference is lost, and changes do not reflect outside.
# Function assigns a new list, breaking the reference
def changeme(mylist):
"""Assigns a new list inside the function"""
mylist = [1, 2, 3, 4] # Assigns a new reference
print("Values inside the function:", mylist)

# Creating a list
mylist = [10, 20, 30]

# Calling the function


changeme(mylist)

# Checking the list after function call


print("Values outside the function:", mylist)

# Output:
# Values inside the function: [1, 2, 3, 4]
# Values outside the function: [10, 20, 30]

Values inside the function: [1, 2, 3, 4]


Values outside the function: [10, 20, 30]

Function Arguments in Python


Functions can accept arguments (parameters), which are values passed during a
function call.

Parameters vs Arguments in Python


The terms parameters and arguments are often used interchangeably, but they have
distinct meanings:

Parameter: A variable listed inside the parentheses in the function definition.

Argument: The actual value passed to a function when calling it. It refers to the input
data on which a function operates to perform a specific action and produce an output
result.

# Function with parameter 'name'


def greet_user(name):
"""Greets the user with a personalized message"""
print(f"Hello, {name}! Welcome to Intensity Coding.")

# Calling function with an argument 'Alice'


greet_user("Alice")

# Output: Hello, Alice! Welcome to Intensity Coding.

Hello, Alice! Welcome to Intensity Coding.

Number of Arguments in Python Functions


By default, a function must be called with the correct number of arguments. If the
function expects two arguments, it must be called with exactly two.

# Example: Function with Multiple Arguments


# Function with two parameters
def my_function(fname, lname):
"""Prints full name"""
print(fname + " " + lname)

# Calling function with two arguments


my_function("Emil", "Refsnes")

# Output: Emil Refsnes

Emil Refsnes

# Example: Missing an Argument (Causes Error)


# Function expecting two parameters
def my_function(fname, lname):
"""Prints full name"""
print(fname + " " + lname)

# Uncommenting below will raise an error


# my_function("Emil") # TypeError: my_function() missing 1 required
positional argument: 'lname'

Required Arguments
A required argument must be passed when calling a function; otherwise, Python raises
an error.

# Function that prints a given string


def printme(string):
"""Prints the given string"""
print(string)

# Calling function with required argument


printme("Hello, Intensity Coding!")

# Output: Hello, Intensity Coding!

# Uncommenting the below line will cause an error


# printme() # TypeError: printme() missing 1 required argument

Hello, Intensity Coding!

Types of Function Arguments:


1. Positional Arguments
2. Keyword Arguments
3. Default Arguments
4. Variable-Length Arguments

Positional Arguments
Positional arguments are the most common and straightforward way to pass data into
a function. They are called positional because the position of each argument in the
function call determines which parameter it corresponds to.
When you call function, the arguments you provide are assigned to parameters based
on their position.

Rules for Using Positional Arguments

Order matters: The first argument corresponds to the first parameter, the second to the
second, and so on.
All required positional arguments must be provided: If any are missing, Python raises
a TypeError.
They cannot come after keyword arguments in a function call.

# Function definition
def greet(name, age):
print(f"Hello {name}, you are {age} years old.")

# Function call with positional arguments


greet("Alice", 25)
#Output: Hello Alice, you are 25 years old.

# If you change the order of arguments, the output will also change:
greet(25, "Alice")
#Output: Hello 25, you are Alice years old.

Hello Alice, you are 25 years old.


Hello 25, you are Alice years old.

Keyword Arguments
Python allows passing arguments using key-value pairs (key=value).
The order of arguments does not matter when using keyword arguments but the
number of arguments must match. Otherwise, we will get an error.
All the arguments after the first keyword argument must also be keyword arguments
too.

# Function to configure an AI model using keyword arguments


def configure_model(optimizer, loss_function, activation):
"""Prints AI model settings using keyword arguments"""
print("Model Configuration:")
print(f"Optimizer: {optimizer}")
print(f"Loss Function: {loss_function}")
print(f"Activation Function: {activation}")

# Calling function with keyword arguments in different orders


configure_model(optimizer="Adam", loss_function="MSE", activation="ReLU")
# Output:
# Model Configuration:
# Optimizer: Adam
# Loss Function: MSE
# Activation Function: ReLU

print("----------")

configure_model(loss_function="CrossEntropy", activation="Sigmoid",
optimizer="SGD")
# Output:
# Model Configuration:
# Optimizer: SGD
# Loss Function: CrossEntropy
# Activation Function: Sigmoid

Model Configuration:
Optimizer: Adam
Loss Function: MSE
Activation Function: ReLU
----------
Model Configuration:
Optimizer: SGD
Loss Function: CrossEntropy
Activation Function: Sigmoid

Note: Keyword arguments can only be used after all positional arguments.
def display_info(name, age):
print(f"Name: {name}, Age: {age}")

# Correct usage
display_info("Raj", 25) # Positional only
display_info("Meet", age=30) # Positional + Keyword

# Incorrect usage
# display_info(name="Charlie", 35) # Positional argument after
keyword argument not allowed

Name: Raj, Age: 25


Name: Meet, Age: 30

Default Parameter Value


A default parameter is used when an argument is not provided.

# Function with default training settings


def train_model(learning_rate=0.01, batch_size=32, epochs=10):
"""Prints training settings with default values"""
print(f"Training with learning_rate={learning_rate}, batch_size=
{batch_size}, epochs={epochs}")

# Calling function with custom values


train_model(0.001, 64, 20)
# Output: Training with learning_rate=0.001, batch_size=64, epochs=20

# Calling function without arguments (uses default values)


train_model()
# Output: Training with learning_rate=0.01, batch_size=32, epochs=10

Training with learning_rate=0.001, batch_size=64, epochs=20


Training with learning_rate=0.01, batch_size=32, epochs=10
Note: Default parameters must always come after non-default parameters.

# Correct: Non-default arguments come first


def greet(name, message="Hello"):
print(f"{message}, {name}!")

greet("Raj") # Output: Hello, Raj!


greet("Meet", "Hi") # Output: Hi, Meet!

# Incorrect: Default argument before non-default argument


# def greet(message="Hello", name): # This will raise a SyntaxError
# print(f"{message}, {name}!")

Hello, Raj!
Hi, Meet!

Variable-Length Arguments

Arbitrary Arguments (*args)

If you don’t know how many arguments will be passed into a function, use *args.
The function receives arguments as a tuple and can access them using indexing.
The *args argument exhausts positional arguments so you can only use keyword
arguments after it.

# Function to print multiple AI models


def list_models(*models):
"""Prints a list of AI models provided as arguments"""
print("Available AI Models:")
for model in models:
print(model)

# Calling function with multiple model names


list_models("Decision Tree", "Neural Network", "Random Forest")

# Output:
# Available AI Models:
# Decision Tree
# Neural Network
# Random Forest

Available AI Models:
Decision Tree
Neural Network
Random Forest

# Function with Required and Arbitrary Arguments


# Function to print a required dataset name and optional features
def dataset_info(dataset_name, *features):
"""Prints dataset name and additional feature details"""
print("Dataset Name:", dataset_name)
print("Features:")
for feature in features:
print(feature)

# Calling function with different numbers of features


dataset_info("Image Dataset")
# Output:
# Dataset Name: Image Dataset
# Features:

print("----------")

dataset_info("Image Dataset", "Grayscale", "Size: 28x28 pixels")


# Output:
# Dataset Name: Image Dataset
# Features:
# Grayscale
# Size: 28x28 pixels

Dataset Name: Image Dataset


Features:
----------
Dataset Name: Image Dataset
Features:
Grayscale
Size: 28x28 pixels

# Enforcing Keyword-Only Arguments After *args


# Function that accepts variable positional arguments and a keyword-only
argument

def log_data(*args, log_level="INFO"):


# Print all positional arguments
print("Data:", args)
# Print the log level
print("Log Level:", log_level)

# Valid usage: 'log_level' passed as a keyword argument


log_data(10, 20, 30, log_level="DEBUG")

# Invalid usage: passing 'log_level' as positional will raise an error


# log_data(10, 20, 30, "DEBUG") # TypeError

Data: (10, 20, 30)


Log Level: DEBUG

Arbitrary Keyword Arguments(**kwargs)

If you don’t know how many keyword arguments will be passed, use **kwargs.
The function receives arguments as a dictionary.
Always place the **kwargs parameter at the end of the parameter list, or you will get an
error.

# Function to print dataset details


def dataset_details(**info):
"""Prints dataset details dynamically"""
print("Dataset Details:")
for key, value in [Link]():
print(f"{key}: {value}")

# Calling function with dataset details


dataset_details(name="MNIST", samples=60000, image_size="28x28 pixels")

# Output:
# Dataset Details:
# name: MNIST
# samples: 60000
# image_size: 28x28 pixels

Dataset Details:
name: MNIST
samples: 60000
image_size: 28x28 pixels

Positional-Only and Keyword-Only Arguments


Python allows specifying whether function arguments must be passed positionally or
as keyword arguments.

Positional-Only Arguments
To enforce positional-only arguments, add / after them.

def multiply(x, /):


"""Multiplies a given number by 2. Requires a positional argument."""
print(x * 2)

# Correct usage (positional argument)


multiply(5) # Output: 10

# Incorrect usage (keyword argument, raises TypeError)


# multiply(x=5)

10
Keyword-Only Arguments
To enforce keyword-only arguments, add * before them.

def multiply(*, x):


"""Multiplies a given number by 2. Requires a keyword argument."""
print(x * 2)

# Correct usage (keyword argument)


multiply(x=5) # Output: 10

# Incorrect usage (positional argument, raises TypeError)


# multiply(5)

10

Combining Positional-Only and Keyword-Only


You can define functions that require both positional-only and keyword-only
arguments.

def compute(a, b, /, *, c, d):


"""Computes a calculation using mixed argument types."""
print((a + b) * (c - d))

# Correct usage
compute(5, 6, c=8, d=3) # Output: 55
# Incorrect usages (raises TypeError)
# compute(a=5, b=6, c=8, d=3)
# compute(5, 6, 8, 3)
# compute(c=8, d=3, 5, 6)

55
Recursion in Python
Recursion is when a function calls itself. It is commonly used in problems involving
mathematical calculations (factorial, Fibonacci series) and Tree and graph traversals.

Key Considerations When Using Recursion


Every recursive function must have a base case to avoid infinite recursion.
Recursive functions can consume a lot of memory if not handled correctly.

def recursive_sum(n):
"""
Recursively calculates the sum of all numbers from n to 0.
"""
if n > 0:
result = n + recursive_sum(n - 1) # Recursive call
print(f"Summing: {n}, Current Sum: {result}")
else:
result = 0 # Base case
return result

# Calling the recursive function


print("\nRecursion Example Results:")
recursive_sum(6)

#Output:
# Summing: 1, Current Sum: 1
# Summing: 2, Current Sum: 3
# Summing: 3, Current Sum: 6
# Summing: 4, Current Sum: 10
# Summing: 5, Current Sum: 15
# Summing: 6, Current Sum: 21
# 21

Recursion Example Results:


Summing: 1, Current Sum: 1
Summing: 2, Current Sum: 3
Summing: 3, Current Sum: 6
Summing: 4, Current Sum: 10
Summing: 5, Current Sum: 15
Summing: 6, Current Sum: 21

21

Python Closures and Nested Functions

Nested Functions in Python


In Python, you can define a function inside another function.
Such an inner function is called a nested function.
Nested functions become powerful when they retain access to variables from their
enclosing function even after the outer function has finished execution. This concept is
known as a closure.

#Basic Nested Function


def greet_user():
# Outer function variable
message = "Welcome to Intensity Coding!"

# Nested (inner) function


def display_message():
# Accessing variable from outer function
print(message)

# Calling the inner function


display_message()

# Execute the outer function


greet_user()

Welcome to Intensity Coding!


Explanation:

display_message() is defined inside greet_user().


The variable message is defined in the outer function but is accessible inside the inner
function.
This inner function is called a nested function.

Free Variables and Closures


When a nested function remembers variables from its outer function, even after the
outer function has finished running, Python forms a closure.
A closure is a function that captures variables from its enclosing scope so they remain
available for later use.

# Returning a Function (Closure)


def outer_function():
greeting = "Hello from Intensity Coding!"

# Inner function that uses outer variable


def inner_function():
print(greeting)

# Return the inner function instead of calling it


return inner_function

# Get the closure


closure_fn = outer_function()

# Call the returned function


closure_fn()

Hello from Intensity Coding!

Key Points:

The outer_function() completes execution but still, closure_fn() accesses the


variable greeting.
The variable greeting is called a free variable because it’s not defined in
inner_function() but is still available.
Python stores this reference in a cell object to preserve it for later use.

Inspecting Closures in Python


Python internally stores free variables in an object called a cell.
You can inspect this using the closure attribute.

def create_closure():
text = "Closure Example in Intensity Coding"

def inner():
print(text)

return inner

fn = create_closure()

# Inspect the closure cells


print(fn.__closure__)
print("Free variables:", fn.__code__.co_freevars)

(<cell at 0x7afa7f1a58a0: str object at 0x7afa7f160800>,)


Free variables: ('text',)

Explanation:

The closure attribute shows a tuple of cell objects storing the captured variables.
fn.__code__.co_freevars lists the names of these variables.

Memory Behavior of Closures


Closures keep references to variables, not copies.
Hence, both the outer and inner functions point to the same memory address.

def show_memory():
msg = "Hello Intensity Coding"
print("Outer variable memory address:", hex(id(msg)))

def inner():
print("Inner variable memory address:", hex(id(msg)))
print(msg)

return inner

fn = show_memory()
fn()

Outer variable memory address: 0x7afa7f1aea70


Inner variable memory address: 0x7afa7f1aea70
Hello Intensity Coding
Nonlocal Variables in Nested Functions
When working with nested functions, variables declared in the outer (enclosing)
function are neither local nor global.
To modify them inside an inner function, Python provides the nonlocal keyword.

# Example: Demonstrating nonlocal variable

def outer_function():
message = "Outer"

def inner_function():
nonlocal message # Refers to the variable in the outer function
message = "Modified by Inner Function"
print("Inside Inner:", message)

inner_function()
print("Inside Outer:", message)

outer_function()

# Output:
# Inside Inner: Modified by Inner Function
# Inside Outer: Modified by Inner Function

Inside Inner: Modified by Inner Function


Inside Outer: Modified by Inner Function

Explanation:

The nonlocal keyword allows the inner function to modify a variable in its enclosing
(outer) scope.

[Link]
Found this helpful ?

Follow on LinkedIn
Master AI/ML with Intensity Coding

@bhavdippatel2020

Like Comment Share Save

Each Article Includes Everything You Need

THEORY MADE SIMPLE PYTHON CODE


Complex ideas explained Hands-on coding for
in an easy way practice

VISUAL LEARNING MATH BEHIND AI/ML


Visual diagrams for Step-by-step explanation
clarity of core concepts

Explore more tutorials at Intensity Coding

[Link]

You might also like