Python Notes: Chapter 8 - Functions
Chapter 8 - Functions
Advantages of Functions:
- Enable structured programming by dividing the program into separate functional modules.
- Reduce program complexity and improve readability.
- Enable code reuse through multiple calls after single definition.
- Enhance code quality by separating tasks into simpler, manageable units.
- Facilitate collaborative development.
- Implement special functionality.
Function Classification:
- Built-in functions
- Standard library functions
- Third-party library functions
- User-defined functions
Function Declaration:
def function_name([formal_parameters]):
function_body
- function_name must be a valid identifier
- formal_parameters are the function's parameters
- Functions can use return to return values. If a return statement is present, the function returns a value; otherwise, it returns None.
Function Calls:
Call format: function_name([actual_parameters])
- function_name must be an accessible function object in the current scope.
- The actual parameters must correspond one-to-one with the formal parameters declared in the function definition.
- Function calls are expressions.
Example:
import sys def display_symbols(n): print(("*" * n).center(50)) # Prints n asterisks centered in a width of 50 line_count = int(sys.argv[1]) # Number of triangle lines for i in range(1, 2 * line_count, 2): # Iterates through 1, 3, 5... display_symbols(i)
![]()
Higher-order Functions (Functions as Objects):
In Python, functions are objects, so function objects can be assigned to variables.
Example:
def calculate(func, numbers): return func(numbers) print(calculate(min, (1,2,5,9))) print(calculate(max, (1,2,9,5)))
Anonymous Functions with Lambda Expressions:
- Lambda provides a concise way to define functions inline.
- Lambda generates a function object (anonymous function).
Basic Lambda Format:
lambda arg1,arg2,...:
Example: f = lambda x, y: x + y
f(12,34)
Output: 46
Parameter Passing:
1. Formal Parameters vs Actual Parameters
- The parameters declared in a function are formal parameters (formal_params), while the values passed during function calls are actual parameters (actual_params).
- Actual parameters are passed in order to formal parameters. Parameter count mismatch results in an error.
- Formal parameters within the function body act as local variables and can be used anywhere in the function.
Immutable vs Mutable Object Passing:
- Immutable objects cannot be modified within the function scope.
- Mutable objects can be modified within the function scope.
Default Parameters:
You can assign default values to parameters during function declaration. If the function is called without corresponding arguments, the default values are used.
Post-class Practice
1. Factorial Calculation (Recursive and Non-recursive)
![]()![]()```
# Recursive implementation
def factorial(n):
if n == 1:
return 1
return n * factorial(n - 1)
n = int(input("Enter a number (n > 0): "))
result = factorial(n)
print(f"{n}! = {result}")
# Non-recursive implementation
def factorial(n):
product = 1
for i in range(1, n + 1):
product *= i
return product
n = int(input("Enter a number (n > 0): "))
result = factorial(n)
print(f"{n}! = {result}")
View CodeOutput:
- Fibonacci Sequence Generation
def fibonacci(n):
if n == 1:
return 1
if n == 0:
return 0
else:
return fibonacci(n - 1) + fibonacci(n - 2)
for i in range(20):
print(fibonacci(i))
- Function to Find Minimum Value
def find_min(*args):
minimum = args[0]
for num in args[1:]:
if num < minimum:
minimum = num
return minimum
print(find_min(8, 2))
print(find_min(16, 1, 7, 4, 15))
- Function to Find Max, Min and Count Elements
list1 = [9, 7, 8, 3, 2, 1, 55, 6]
list2 = ["apple", "pear", "melon", "kiwi"]
string1 = "TheQuickBrownFox"
def analyze_sequence(seq):
if isinstance(seq, list):
sorted_seq = sorted(seq)
max_val = max(sorted_seq)
min_val = min(sorted_seq)
count = len(sorted_seq)
else:
chars = list(seq)
sorted_chars = sorted(chars)
max_val = max(sorted_chars)
min_val = min(sorted_chars)
count = len(chars)
return max_val, min_val, count
print(f"For list1: Max={analyze_sequence(list1)[0]}, Min={analyze_sequence(list1)[1]}, Count={analyze_sequence(list1)[2]}")
print(f"For list2: Max={analyze_sequence(list2)[0]}, Min={analyze_sequence(list2)[1]}, Count={analyze_sequence(list2)[2]}")
print(f"For string1: Max={analyze_sequence(string1)[0]}, Min={analyze_sequence(string1)[1]}, Count={analyze_sequence(string1)[2]}")
Alternative Implementation:
def analyze(sequence):
print(f"Sequence: {sequence}\nMax: {max(sequence)}, Min: {min(sequence)}, Count: {len(sequence)}")
list_data = [9,7,8,3,2,1,55,6]
str_data = "TheQuickBrownFox"
analyze(list_data)
analyze(str_data)
Output:
Sequence: [9, 7, 8, 3, 2, 1, 55, 6]
Max: 55, Min: 1, Count: 8
Sequence: TheQuickBrownFox
Max: x, Min: B, Count: 16