0% found this document useful (0 votes)
9 views17 pages

Python Functions and Modules Guide

This document covers Python programming concepts related to functions and modules, including user-defined functions, argument types, default arguments, variable-length arguments, and lambda functions. It also explains recursion, generator functions, and the concept of namespaces and scope rules in Python. The document provides examples for each concept to illustrate their usage.

Uploaded by

sandhiyababu1511
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)
9 views17 pages

Python Functions and Modules Guide

This document covers Python programming concepts related to functions and modules, including user-defined functions, argument types, default arguments, variable-length arguments, and lambda functions. It also explains recursion, generator functions, and the concept of namespaces and scope rules in Python. The document provides examples for each concept to illustrate their usage.

Uploaded by

sandhiyababu1511
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

PMDS508L - Python Programming

Module – 5 – Functions and Modules

Prepared by: Dr. Nandhini S, SAS

User-defined Functions
1. Functions allow us to organize code into reusable blocks.
2. They improve readability, reusability, and maintainability.

Defining a Function:

def function_name(arguements):
statements
return value
There are 4 types of arguments:

• Positional arguments → matched by position.


• Keyword arguments → matched by name.
• Default arguments → if not passed, default is used
• Variable-length arguments (*wrd, **wrds)

Positional and Keyword arguments:

# Program 1

def student(name, age):


print(f"Name: {name}, Age: {age}")
student("Alice", 21)
student(age=22, name="Bob")

# Program 2

def student_info(name, age, grade):


print(f"Name: {name}, Age: {age}, Grade: {grade}")

# Using keyword arguments

student_info(name="Alice", age=15, grade="10th")


student_info(grade="11th", age=16, name="Bob")

# change of order does not throw error

student_info("Charlie", grade="9th", age=14) # using both positional & Keyword

# can mix both but positional must be the first

student_info(grade="9th","Charlie", age=14) # Error

Points to ponder:

Positional arguments – considers the order.


Keyword arguments – dependent on parameter names.
Mixing - allowed, but positional must come first.

Default arguments:

# Program 1

def greet(name, msg="Good Morning"):


print(f"Hello {name}, {msg}")
greet("Alice")
greet("Bob", "How are you?")

# Program 2
def generate_report(name, marks, grade="Not Applicable", attendance=100,
scholarship=False, remarks=None):

print(f" ------ Student Report for {name} --------")


print(f"Marks: {marks}")
print(f"Grade: {grade}")
print(f"Attendance: {attendance}%")
print(f"Scholarship: {'Yes' if scholarship else 'No'}")
print(f"Remarks: {remarks if remarks else 'No remarks'}")
print("-" * 40)

# 1. Only mandatory arguments (defaults will be used)


generate_report("Alice", {"Math": 95, "Science": 89})

# 2. Overriding some defaults with keyword arguments


generate_report("Bob", {"Math": 70, "English": 75}, grade="B", attendance=92)

# 3. Passing everything
generate_report("Charlie", {"Math": 60, "History": 55}, grade="C", attendance=80,
scholarship=True, remarks="Needs improvement")

# 4. Mixing positional + keyword


generate_report("David", {"Science": 99}, scholarship=True)

Variable-length arguments:

# Program 1

def add_all(*args):
return sum(args)
print(add_all(1,2,3,4))

# Program 2

def add_all(*args): # passing arguments in a tuple


print("Arguments received:", args)
return sum(args)

print(add_all(1, 2)) # can pass any number of arguments as tuple


print(add_all(10, 20, 30, 40, 50))
print(add_all())

# Program 3

def demo(**wars): # ** passing arguments in a dictionary


print(wars)

demo(name="Alice", age=20)

# Program 4
def generate_report(name, marks, **margs):

print("=" * 40)
print(f"Report for {name}")
print("-" * 40)

# Display marks

total = sum([Link]())
avg = total / len(marks)
for subject, score in [Link](): # gives both keys and values
print(f"{subject:<10} : {score}")
print("-" * 40)
print(f"Total : {total}")
print(f"Average : {avg:.2f}")

# Display extra details passed using margs


if margs:
print("-" * 40)
print("Additional Details:")
for key, value in [Link]():
print(f"{[Link]():<12} : {value}") # <- left align the tex , > - right align, ^ - center align

print("=" * 40)
print()
# Calling the function

generate_report("Alice", {"Math": 95, "Science": 89}, grade="A", attendance=98)

generate_report("Bob", {"Math": 70, "English": 75}, grade="B", scholarship="Yes", remarks="Needs improvement")

generate_report("Charlie", {"History": 65, "Geography": 72}, address="123 Main St", phone="9876543210")

Namespaces and Scope Rules


A namespace is a system that maps names to objects to ensure all identifiers are unique within that context. Python
uses several types of namespaces:

✓ Built-in: Contains functions like len(), abs(), etc.


✓ Global: Defined at the top-level of a script/module.
✓ Local: Inside a function or method.
✓ Enclosing: For nested functions.
✓ A namespace is the environment that stores the mapping from the name → object.
✓ The order of resolution is known as the LEGB rule:
Local → Enclosed → Global → Built-in.
Example:

x = "This is an example for global"


def outer():
x = "This is an example for enclosed"
def inner():
x = "This is an example for local"
print(x) # 'local'
inner()
print(x) # 'enclosed'
outer()
print(x) # 'global'

Lambda Function
A lambda function is a small, anonymous function defined with the lambda keyword. It can take any number of
arguments but has only one expression. They are useful for short, throwaway functions.

Syntax: lambda arguments: expression

Example:1
square = lambda x: x * x
print("Square of 5:", square(5))

# def square(x): # equivalent to the above statement


# return x * x

Example:2

maximum = lambda a, b: a if a > b else b


print("Maximum of 10 and 7:", maximum(10, 7))

# def maximum(a, b):


# if a > b:
# return a
# else:
# return b
# print("Maximum of 1 and 7:", maximum(1, 7))
Example:3

numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x*x, numbers))
evens = list(filter(lambda x: x % 2 == 0, numbers)) # returns the
values for which the function is TRUE
print(squared) # [1, 4, 9, 16, 25]
print(evens) # [2, 4]

Recursive Functions
✓ A recursive function is a function that calls itself. Each recursive call reduces the problem into smaller
subproblems. A base case is essential to stop recursion, otherwise infinite recursion occurs.

Example:1

def factorial(n):
if n == 0:
return 1 # base case
else:
return n * factorial(n-1)

print(factorial(5)) # 120

Example:2

def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)

print("Fibonacci of 6:", fibonacci(6))


Example:3
def reverse(s):
if s == "":
return s # base case: empty string
return reverse(s[1:]) + s[0]
reverse('hello')

Generator Functions
✓ Generator functions allow iteration over data without storing it all in memory.
✓ They use the 'yield' keyword to return one value at a time, pausing the function’s state until the next call.

yield vs return
• return → exits the function completely and gives a value.
• yield → pauses the function, gives a value, and remembers where it left off.
• This makes the function a generator instead of a normal function.
Example:1

def count_up_to(n):
count = 1
while count <= n:
yield count # pauses the function and send n to for loop
print(count)
count += 1

for number in count_up_to(5):


print(f"number is : {number}")
Example:2

def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b

print(list(fibonacci(10)))

==================== END ====================

You might also like