Functions
Goal: Understand how to define, call, and debug functions in Python,
including parameters, return values, and scope.
1. What Are Functions?
Functions are reusable blocks of code that perform specific tasks. They
help:
Avoid repetitive code.
Organize logic into modular units.
Simplify debugging.
Syntax:
def function_name(parameters):
# Code to execute
return value
Example:
def greet(name):
print(f"Hello, {name}!")
greet("Alice") # Output: Hello, Alice!
2. Defining Functions
1. Function Name: Follows variable naming rules (letters,
underscores, no numbers/symbols).
2. Parameters: Variables listed in parentheses (inputs to the
function).
3. Body: Indented code block.
4. Return Statement: Exits the function and sends back a value
(optional).
Example with Return:
def add(a, b):
return a + b
result = add(3, 5)
print(result) # Output: 8
Key Notes:
If no return is specified, the function returns None.
Functions can return multiple values (as a tuple):
def min_max(numbers):
return min(numbers), max(numbers)
values = [4, 2, 9]
smallest, largest = min_max(values)
3. Parameters vs. Arguments
Parameters: Variables defined in the function’s declaration.
Arguments: Actual values passed to the function when calling it.
Example:
def multiply(x, y): # x and y are parameters
return x * y
multiply(2, 4) # 2 and 4 are arguments
Types of Parameters:
1. Positional: Matched by order.
2. Keyword: Explicitly named arguments.
3. Default: Assigned a default value.
4. Arbitrary: *args (tuple) and **kwargs (dict).
Example with Default Values:
def power(base, exponent=2):
return base ** exponent
print(power(3)) # Output: 9 (uses default exponent=2)
print(power(3, 3)) # Output: 27
4. Scope: Local vs. Global Variables
Local Variables: Defined inside a function. Not accessible outside.
Global Variables: Defined outside functions. Accessible
everywhere.
Example:
global_var = 10
def my_function():
local_var = 5
print(global_var + local_var) # Output: 15
my_function()
print(local_var) # NameError: 'local_var' is not defined
Modifying Global Variables:
Use the global keyword:
count = 0
def increment():
global count
count += 1
increment()
print(count) # Output: 1
5. Common Function Errors
1. Missing Return Value:
def calculate_area(radius):
area = 3.14 * radius ** 2
print(calculate_area(5)) # Output: None (no return statement)
2. Incorrect Indentation:
def wrong():
print("Hello") # IndentationError
3. Mixing Data Types:
def add(a: int, b: int) -> int:
return a + b
add("3", 5) # TypeError: Can't add str and int
4. Unused Parameters:
def greet(name):
print("Hello!") # 'name' is defined but never used
6. Lambda Functions
Anonymous, single-expression functions.
Syntax: lambda arguments: expression
Example:
square = lambda x: x ** 2
print(square(4)) # Output: 16
Use Cases:
Short operations (e.g., sorting with key=lambda).
Temporary functions.
7. Recursion
A function that calls itself.
Example (Factorial):
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n - 1)
print(factorial(5)) # Output: 120
Key Notes:
Requires a base case to avoid infinite recursion.
Can be memory-intensive for large inputs.
8. Docstrings
Documentation strings explaining a function’s purpose.
Example:
def divide(a, b):
"""Divides two numbers and returns the result.
Args:
a (float): Numerator
b (float): Denominator
Returns:
float: Result of division, or None if b is 0.
"""
if b == 0:
return None
return a / b
Accessing Docstrings:
print(divide.__doc__)
9. Real-World Applications
1. Data Processing:
def clean_data(data):
# Remove duplicates, handle missing values
return cleaned_data
2. Input Validation:
def validate_age(age):
return age >= 18
3. Modularizing Code:
def send_email(recipient, message):
# Connect to server, send email
print("Email sent!")
10. Key Takeaways
1. Use def to define functions and return to exit with a value.
2. Parameters can have default values (e.g., def func(a=0)).
3. Variables inside functions are local unless declared global.
4. Avoid infinite recursion with a base case.