Python Functions
Functions are one of the most fundamental building blocks in Python programming. They allow you to organize your code into reusable blocks, making your programs more modular, readable, and maintainable. Understanding functions is crucial for working with PyTorch, as much of PyTorch's functionality is implemented through functions.
What are Functions?
A function is a block of organized, reusable code that performs a specific task. Functions provide better modularity and a high degree of code reusing. In Python, functions are first-class citizens, meaning you can pass them around as arguments, return them from other functions, and assign them to variables.
Defining a Function in Python
The syntax for defining a function in Python is as follows:
def function_name(parameters):
"""Docstring explaining what the function does"""
# Function body
# Your code here
return value # Optional return statement
Let's break this down:
def
is the keyword that tells Python you're defining a functionfunction_name
is the identifier you use to call the functionparameters
are input values you can pass to the function (optional)- The function body is indented and contains the code to be executed
return
is used to specify the output of the function (optional)
Simple Function Examples
Function with No Parameters or Return Value
def say_hello():
print("Hello, World!")
# Calling the function
say_hello() # Output: Hello, World!
Function with Parameters
def greet(name):
print(f"Hello, {name}!")
# Calling the function with an argument
greet("Alice") # Output: Hello, Alice!
Function with Return Value
def add_numbers(a, b):
return a + b
# Calling the function and storing the result
result = add_numbers(5, 3)
print(result) # Output: 8
Function Parameters
Python provides different ways to specify parameters:
Default Parameters
You can assign default values to parameters, which are used when the function is called without those arguments:
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("Bob") # Output: Hello, Bob!
greet("Alice", "Hi") # Output: Hi, Alice!
Variable-Length Arguments
Sometimes you want to pass a variable number of arguments to a function:
*args (Non-Keyword Arguments)
def sum_all(*numbers):
total = 0
for num in numbers:
total += num
return total
print(sum_all(1, 2, 3, 4)) # Output: 10
print(sum_all(5, 10)) # Output: 15
**kwargs (Keyword Arguments)
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="John", age=25, city="New York")
# Output:
# name: John
# age: 25
# city: New York
Function Documentation
It's good practice to include docstrings that explain what your function does:
def calculate_area(length, width):
"""
Calculate the area of a rectangle.
Args:
length (float): The length of the rectangle
width (float): The width of the rectangle
Returns:
float: The area of the rectangle
"""
return length * width
# Using the function
area = calculate_area(5.0, 3.0)
print(area) # Output: 15.0
Anonymous Functions (Lambda)
Python allows for the creation of small anonymous functions using the lambda
keyword:
# Regular function
def square(x):
return x * x
# Equivalent lambda function
square_lambda = lambda x: x * x
print(square(5)) # Output: 25
print(square_lambda(5)) # Output: 25
Lambda functions are particularly useful when you need a simple function for a short period, often as an argument to higher-order functions like map()
, filter()
, and sorted()
.
numbers = [1, 5, 3, 9, 7]
# Using lambda with map() to square all numbers
squared = list(map(lambda x: x * x, numbers))
print(squared) # Output: [1, 25, 9, 81, 49]
# Using lambda with filter() to get only odd numbers
odd_numbers = list(filter(lambda x: x % 2 != 0, numbers))
print(odd_numbers) # Output: [1, 5, 3, 9, 7]
Function Scope
Variables defined inside a function are only accessible within that function, unless they're explicitly returned:
def my_function():
local_var = "I'm local"
print(local_var) # Works fine
my_function() # Output: I'm local
# print(local_var) # This would raise a NameError
However, functions can access variables from outer scopes:
outer_var = "I'm from outside"
def my_function():
print(outer_var) # Accessing the outer variable
my_function() # Output: I'm from outside
Practical Examples for PyTorch
Let's look at how functions are commonly used when working with PyTorch:
Data Preprocessing Function
def preprocess_image(image_path, size=(224, 224)):
"""
Load and preprocess an image for a neural network.
Args:
image_path (str): Path to the image
size (tuple): Target size for resizing
Returns:
Processed image ready for the model
"""
# In a real PyTorch application, you'd use:
# from PIL import Image
# import torchvision.transforms as transforms
print(f"Loading image from {image_path}")
print(f"Resizing to {size}")
print("Applying normalization")
# Simulated processing steps
result = f"Processed image of size {size}"
return result
# Using the function
processed_img = preprocess_image("cat.jpg")
print(processed_img) # Output: Processed image of size (224, 224)
Model Evaluation Function
def evaluate_model(model, test_data, device="cpu"):
"""
Evaluate a PyTorch model on test data.
Args:
model: The PyTorch model to evaluate
test_data: The test dataset
device: The device to run evaluation on ("cpu" or "cuda")
Returns:
dict: Dictionary containing evaluation metrics
"""
print(f"Evaluating model on {device}")
print(f"Test data size: {len(test_data)} samples")
# In a real application, you'd have actual evaluation code
# Simulated metrics
metrics = {
"accuracy": 0.92,
"precision": 0.94,
"recall": 0.89
}
return metrics
# Using the function
results = evaluate_model("my_model", [1, 2, 3, 4, 5], "cuda")
print(f"Accuracy: {results['accuracy']}") # Output: Accuracy: 0.92
Summary
Functions are essential components in Python programming that:
- Help organize and structure your code
- Make code reusable and maintainable
- Allow you to abstract away implementation details
- Can take input parameters and return output values
- Support various parameter passing mechanisms
When working with PyTorch, you'll use functions to:
- Preprocess data
- Define model architectures
- Implement training and evaluation loops
- Create custom loss functions
- And much more
Understanding how to effectively create and use functions will significantly improve your efficiency when working with PyTorch and Python in general.
Exercises
- Create a function that converts temperatures between Celsius and Fahrenheit.
- Write a function that takes a list of numbers and returns both the minimum and maximum values.
- Create a function that simulates a simple PyTorch training loop (pseudo-code is fine).
- Write a lambda function to sort a list of tuples based on their second element.
- Create a function with default parameters to simulate data augmentation for PyTorch.
Additional Resources
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)