๐ง Functions Part II
Advanced function concepts and real-world applications
๐บ๏ธ What You'll Learn
๐ Same topic in the course notebook
Session_7 Functions Part II has *args, **kwargs, lambda, map, filterโsame ideas. Run the notebook cells.
๐ฆ *args - Variable Positional Arguments
๐ Accept Any Number of Arguments
*args allows a function to accept any number of positional arguments. The asterisk (*) packs all extra arguments into a tuple!
๐ *args = A Gift Box for Extra Arguments
def add(*args):
โ
โโโ All arguments get packed into a tuple!
add(1, 2) โ args = (1, 2)
add(1, 2, 3) โ args = (1, 2, 3)
add(1, 2, 3, 4, 5) โ args = (1, 2, 3, 4, 5)
One function, unlimited arguments! ๐
# *args from Session 7
def add_all(*args):
"""Add any number of numbers together"""
print("Received args:", args)
print("Type:", type(args))
return sum(args)
# Call with different numbers of arguments
print("Sum of 1, 2:", add_all(1, 2))
print()
print("Sum of 1, 2, 3, 4, 5:", add_all(1, 2, 3, 4, 5))
print()
print("Sum of 10, 20, 30, 40, 50, 60:", add_all(10, 20, 30, 40, 50, 60))
Received args: (1, 2) Type: <class 'tuple'> Sum of 1, 2: 3 Received args: (1, 2, 3, 4, 5) Type: <class 'tuple'> Sum of 1, 2, 3, 4, 5: 15 Received args: (10, 20, 30, 40, 50, 60) Type: <class 'tuple'> Sum of 10, 20, 30, 40, 50, 60: 210
๐ Combining Regular Parameters with *args
# Regular parameter + *args from Session 7
def greet_all(greeting, *names):
"""Greet multiple people with same greeting"""
for name in names:
print(f"{greeting}, {name}!")
greet_all("Hello", "Alice", "Bob", "Charlie")
print()
greet_all("Good morning", "Team")
Hello, Alice! Hello, Bob! Hello, Charlie! Good morning, Team!
You can use any name after the asterisk: *numbers, *items, *values. The * is what matters!
๐ท๏ธ **kwargs - Variable Keyword Arguments
๐ Accept Named Arguments
**kwargs allows a function to accept any number of keyword arguments. The double asterisk (**) packs them into a dictionary!
๐ **kwargs = A Dictionary of Named Arguments
def func(**kwargs):
โ
โโโ All keyword arguments become a dictionary!
func(name="Alice", age=25)
โ kwargs = {"name": "Alice", "age": 25}
func(a=1, b=2, c=3, d=4)
โ kwargs = {"a": 1, "b": 2, "c": 3, "d": 4}
# **kwargs from Session 7
def print_info(**kwargs):
"""Print any information passed as keyword arguments"""
print("Received kwargs:", kwargs)
print("Type:", type(kwargs))
print()
for key, value in kwargs.items():
print(f" {key}: {value}")
# Call with different keyword arguments
print_info(name="Alice", age=25, city="NYC")
print()
print_info(product="Laptop", price=999, brand="Dell", stock=50)
Received kwargs: {'name': 'Alice', 'age': 25, 'city': 'NYC'}
Type: <class 'dict'>
name: Alice
age: 25
city: NYC
Received kwargs: {'product': 'Laptop', 'price': 999, 'brand': 'Dell', 'stock': 50}
Type: <class 'dict'>
product: Laptop
price: 999
brand: Dell
stock: 50
๐ Combining *args and **kwargs
# Combining all argument types from Session 7
def super_function(required, *args, **kwargs):
"""Demonstrates all argument types"""
print("Required:", required)
print("Args (extra positional):", args)
print("Kwargs (extra keyword):", kwargs)
super_function("Hello", 1, 2, 3, name="Alice", age=25)
# Practical example: flexible print function
def custom_print(*messages, sep=" | ", prefix=""):
"""Print messages with custom separator and prefix"""
output = sep.join(str(m) for m in messages)
print(f"{prefix}{output}")
print("\\nCustom print examples:")
custom_print("Hello", "World", "Python")
custom_print(1, 2, 3, sep=" โ ")
custom_print("Error occurred", prefix="โ ๏ธ ")
Required: Hello
Args (extra positional): (1, 2, 3)
Kwargs (extra keyword): {'name': 'Alice', 'age': 25}
Custom print examples:
Hello | World | Python
1 โ 2 โ 3
โ ๏ธ Error occurred
Arguments must be in this order:
- Regular positional arguments
- *args
- Keyword arguments with defaults
- **kwargs
โก Lambda Functions
๐ฏ Anonymous Functions
Lambda functions are small, one-line anonymous functions. They're perfect for simple operations that don't need a full function definition!
๐ Regular Function vs Lambda
REGULAR FUNCTION (3 lines) LAMBDA (1 line)
โโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
def square(x): square = lambda x: x**2
return x**2
def add(a, b): add = lambda a, b: a + b
return a + b
Same result, less code! โก
# Lambda functions from Session 7/9
# Basic lambda
square = lambda x: x ** 2
print("Square of 5:", square(5))
# Lambda with multiple parameters
add = lambda a, b: a + b
print("3 + 4 =", add(3, 4))
multiply = lambda x, y: x * y
print("6 ร 7 =", multiply(6, 7))
# Lambda with conditional
is_even = lambda x: "Even" if x % 2 == 0 else "Odd"
print("10 is:", is_even(10))
print("7 is:", is_even(7))
# Lambda with no parameters
greet = lambda: "Hello, World!"
print(greet())
Square of 5: 25 3 + 4 = 7 6 ร 7 = 42 10 is: Even 7 is: Odd Hello, World!
๐บ๏ธ The map() Function
๐ Apply Function to Every Item
map() applies a function to every item in a sequence and returns the results!
๐บ๏ธ How map() Works
map(function, sequence)
numbers = [1, 2, 3, 4, 5]
1 2 3 4 5
โ โ โ โ โ
โผ โผ โผ โผ โผ
โโโโโโโโโโโโโโโโโโโโโ
โ square function โ
โโโโโโโโโโโโโโโโโโโโโ
โ โ โ โ โ
โผ โผ โผ โผ โผ
1 4 9 16 25
# map() examples from Session 7/9
# Square all numbers
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print("Squared:", squared)
# Convert to uppercase
names = ["alice", "bob", "charlie"]
upper_names = list(map(str.upper, names))
print("Uppercase:", upper_names)
# Convert strings to integers
str_numbers = ["1", "2", "3", "4", "5"]
int_numbers = list(map(int, str_numbers))
print("As integers:", int_numbers)
# Using a defined function
def add_ten(x):
return x + 10
result = list(map(add_ten, numbers))
print("Add 10:", result)
# map with multiple sequences
list1 = [1, 2, 3]
list2 = [10, 20, 30]
sums = list(map(lambda x, y: x + y, list1, list2))
print("Pairwise sums:", sums)
Squared: [1, 4, 9, 16, 25] Uppercase: ['ALICE', 'BOB', 'CHARLIE'] As integers: [1, 2, 3, 4, 5] Add 10: [11, 12, 13, 14, 15] Pairwise sums: [11, 22, 33]
๐ The filter() Function
๐ฏ Keep Only Matching Items
filter() keeps only items that pass a test (return True)!
๐ How filter() Works
filter(function, sequence)
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Filter: is_even (x % 2 == 0)
1โ 2โ
3โ 4โ
5โ 6โ
7โ 8โ
9โ 10โ
Result: [2, 4, 6, 8, 10]
# filter() examples from Session 7/9
# Filter even numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print("Even numbers:", evens)
# Filter odd numbers
odds = list(filter(lambda x: x % 2 != 0, numbers))
print("Odd numbers:", odds)
# Filter numbers greater than 5
greater_than_5 = list(filter(lambda x: x > 5, numbers))
print("Greater than 5:", greater_than_5)
# Filter non-empty strings
words = ["hello", "", "world", "", "python", ""]
non_empty = list(filter(None, words)) # None filters falsy values
print("Non-empty:", non_empty)
# Filter with a defined function
def is_positive(x):
return x > 0
mixed = [-5, 3, -2, 8, -1, 4, 0]
positives = list(filter(is_positive, mixed))
print("Positive numbers:", positives)
Even numbers: [2, 4, 6, 8, 10] Odd numbers: [1, 3, 5, 7, 9] Greater than 5: [6, 7, 8, 9, 10] Non-empty: ['hello', 'world', 'python'] Positive numbers: [3, 8, 4]
๐ The reduce() Function
๐ Combine All Items into One
reduce() takes a list and combines all items into a single value! You need to import it from functools.
๐ How reduce() Works
reduce(function, [1, 2, 3, 4, 5])
Step 1: 1 + 2 = 3
Step 2: 3 + 3 = 6
Step 3: 6 + 4 = 10
Step 4: 10 + 5 = 15 โ Final result!
Keeps applying function until one value remains.
# reduce() examples from Session 7/9
from functools import reduce
# Sum all numbers
numbers = [1, 2, 3, 4, 5]
total = reduce(lambda a, b: a + b, numbers)
print("Sum:", total)
# Multiply all numbers
product = reduce(lambda a, b: a * b, numbers)
print("Product:", product)
# Find maximum
maximum = reduce(lambda a, b: a if a > b else b, numbers)
print("Maximum:", maximum)
# Concatenate strings
words = ["Python", " is", " awesome", "!"]
sentence = reduce(lambda a, b: a + b, words)
print("Sentence:", sentence)
Sum: 15 Product: 120 Maximum: 5 Sentence: Python is awesome!
๐งฎ Practical Project: Calculator
๐ฉ Building a Calculator
Let's combine everything we've learned to build a functional calculator!
# Calculator from Session 7
def add(a, b):
"""Add two numbers"""
return a + b
def subtract(a, b):
"""Subtract b from a"""
return a - b
def multiply(a, b):
"""Multiply two numbers"""
return a * b
def divide(a, b):
"""Divide a by b"""
if b == 0:
return "Error: Division by zero!"
return a / b
def calculator(operation, a, b):
"""Perform calculation based on operation"""
operations = {
"+": add,
"-": subtract,
"*": multiply,
"/": divide
}
if operation in operations:
return operations[operation](a, b)
else:
return "Invalid operation!"
# Test the calculator
print("10 + 5 =", calculator("+", 10, 5))
print("10 - 5 =", calculator("-", 10, 5))
print("10 * 5 =", calculator("*", 10, 5))
print("10 / 5 =", calculator("/", 10, 5))
print("10 / 0 =", calculator("/", 10, 0))
10 + 5 = 15 10 - 5 = 5 10 * 5 = 50 10 / 5 = 2.0 10 / 0 = Error: Division by zero!
๐ Quick Reference
| Concept | Syntax | Example |
|---|---|---|
*args |
def f(*args): | Packs extra positional args into tuple |
**kwargs |
def f(**kwargs): | Packs extra keyword args into dict |
| Lambda | lambda x: x*2 | Anonymous one-line function |
map() |
map(func, list) | Apply function to each item |
filter() |
filter(func, list) | Keep items that return True |
reduce() |
reduce(func, list) | Combine all items into one |
๐ซ Common Mistakes (map, filter, comprehensions)
- map() returns an iterator in Python 3 โ You need
list(map(...))to see a list; otherwise you consume it once and it's empty. - Filter condition logic โ
filter(f, x)keeps items wheref(item)is True; double-check what your function returns. - Comprehension with side effects โ Use comprehensions for building a new list/set/dict; for side effects (e.g. printing) a normal loop is clearer.
๐ญ Short reflection
In one sentence: when would you use map() or a list comprehension instead of a manual for-loop?
โ CORE (Must know)
- List comprehensions:
[x*2 for x in list]; filter withif. map(func, iterable),filter(func, iterable);reduce()to combine.- Functions as first-class objects; pass functions as arguments.
๐ NON-CORE (Good to know)
- Lambda; functools; generator expressions.
Complete code from course notebook: Functions_in_python (1).ipynb
Every line of code from the course notebook (verbatim).
# --- Code cell 1 ---
# Functions in python
# --- Code cell 2 ---
# what is function?
A function is a block of code that performs a specific task.
it is reusable and helps to organize the code efficiently
1@ code reusability--write once and use multiple times
2@ modularity--Divide the code into smaller and manageable parts
3@ Reduces Redundancy--aviod writing the same code repatibilty
4@ Improved Readability--makes programs easier to understand
# --- Code cell 3 ---
Types of functions
1@ Built-in functions
2@ User-defined functions
3@ lambda(annoymous) functions
# --- Code cell 4 ---
#for any word when you add a parenthis is a function
# --- Code cell 5 ---
print("to print")
# --- Code cell 6 ---
# Built-in-functions
print()
max()
min()
sum()
len()
# --- Code cell 7 ---
flow=input("enter a name")
print(flow)
# --- Code cell 8 ---
import builtins
print(dir(builtins))
# --- Code cell 9 ---
list1=[23,34,56,78,89]
avg=sum(list1)/len(list1)
avg
# --- Code cell 10 ---
import statistics
list1=[23,34,56,78,89]
s=statistics.mean(list1)
s
# --- Code cell 11 ---
max(list1)
# --- Code cell 12 ---
min(list1)
# --- Code cell 13 ---
#user-defined function is created by the user to perform a specific task.
# --- Code cell 14 ---
# syntax
def hello(): # defining a function
# function block of code
hello() # calling function
# --- Code cell 15 ---
# simple function without parameters
def greet():
print("hello welcome to fuctions in python")
# --- Code cell 16 ---
greet()
# --- Code cell 17 ---
greet1()
# --- Code cell 18 ---
# syntax
def hello(parameters): # defining a function
# function block of code
hello(arguments) # calling function
# --- Code cell 19 ---
greet("vishal")
# --- Code cell 20 ---
greet("aravind")
# --- Code cell 21 ---
Function arguments in python
1@ positional arguments
2@ default arguments/keyword arguments
3@ arbitary Keyword arguments
4@ arbitary non keyword arguments
# --- Code cell 22 ---
# positional argument
def greet(name):
print(f"hello {name}")
# --- Code cell 23 ---
greet(3567)
# --- Code cell 24 ---
greet("azar")
# --- Code cell 25 ---
greet("rahul","aravind")
# --- Code cell 26 ---
# positional argument
def intro(name,age):
print(f"hello my name is {name} , and my age is {age}")
# --- Code cell 27 ---
intro(65,"banu",67)
# --- Code cell 28 ---
intro("banu")
# --- Code cell 29 ---
# default arguments/keyword arguments
def greet(name="rahul"):
print(f"hello,{name}!")
# --- Code cell 30 ---
greet() # no argument are passed
# --- Code cell 31 ---
greet("alice") # positional argument is passed
# --- Code cell 32 ---
# positional arguments
def student(marks,name,age=21):
print(f"name:{name} with age:{age} and marks:{marks}")
# --- Code cell 33 ---
student(33,"tarun",55)
# --- Code cell 34 ---
student("rahul",23) # Positional arguments
# --- Code cell 35 ---
student(90,"rahul",34) # wrong order of arguments
# --- Code cell 36 ---
student(marks=90,name="taarun",age=23) # keyword arguments without order
# --- Code cell 37 ---
student(44,name="aravind") # positional and keyword arguments
# --- Code cell 38 ---
student(name="aravind",44) # positional and keyword arguments
# --- Code cell 39 ---
student(marks=90,"rahul",23) # positional and keyword arguments
# --- Code cell 40 ---
# positional arguments
def student(marks,name,age=21):
print(f"name:{name} with age:{age} and marks:{marks}")
# --- Code cell 41 ---
student(name="rahul",marks=90) # positional and keyword arguments
# --- Code cell 42 ---
a=9
print(a)
# --- Code cell 43 ---
# keyword arguments
def employee(name,salary,department="IT"):
print(f"name:{name} with salary:{salary} and department:{department}")
# --- Code cell 44 ---
employee("rahul",23000,"HR")
# --- Code cell 45 ---
#In Python, return is used inside a function to send a value back to the caller and end the function immediately.
# --- Code cell 46 ---
def add(a,b):
return a+b
result=add(3,4) # store the returned value
print(result)
# --- Code cell 47 ---
# function with return
def jack(a,b):
add=a+b
sub=a-b
return(sub)
return(add)
jack(5,4)
# --- Code cell 48 ---
# function with return
def jack(a,b):
add=a+b
sub=a-b
return (sub,add)
result=jack(5,4)
print(result)
# --- Code cell 49 ---
# function with return
def jack(a,b):
add=a+b
sub=a-b
return(sub) # you cannot use a loop inside the function with mul return values
return(add)
jack(5,4)
# --- Code cell 50 ---
def introduce(name="Sandip", age=0, marks=0):
print(f"My name is {name}! and I am {age} years old. My marks are {marks}.")
introduce(marks = 100, age=30)
# --- Code cell 51 ---
def jack(a,b):
sub = a - b
sum = a + b
return(sub, sum)
jack(3,3)
# --- Code cell 53 ---
# simple calculator
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
return "Error: Cannot divide by zero!"
return a / b
# Real-time execution
print("---- Calculator ----")
a = float(input("Enter first number: "))
b = float(input("Enter second number: "))
choice = input("Choose operation (+, -, *, /): ")
if choice == '+':
print("Result:", add(a, b))
elif choice == '-':
print("Result:", subtract(a, b))
elif choice == '*':
print("Result:", multiply(a, b))
elif choice == '/':
print("Result:", divide(a, b))
else:
print("Invalid choice!")
# --- Code cell 55 ---
balance = 1000 # global function
def deposit(amount):
global balance
balance += amount
return balance
def withdraw(amount):
global balance
if amount > balance:
return "Insufficient balance!"
balance -= amount
return balance
print("---- ATM ----")
while True:
print("\n1. Deposit\n2. Withdraw\n3. Check Balance\n4. Exit")
choice = input("Enter choice: ")
if choice == '1':
amt = float(input("Enter amount to deposit: "))
print("New Balance:", deposit(amt))
elif choice == '2':
amt = float(input("Enter amount to withdraw: "))
print("New Balance:", withdraw(amt))
elif choice == '3':
print("Balance:", balance)
elif choice == '4':
print("Thank you! Visit again.")
break
else:
print("Invalid choice!")
# --- Code cell 56 ---
# arbitary arguments
1@ *args(non-keyword arbitary arguments)
2@ **kwargs(keyword arbitary arguments)
are called as arbitary arguments/special arguments that allows functions
to accept a variable number of arguments.
# --- Code cell 57 ---
# *args---accepts any number of positional arguments
# it allows to pass multiple arguments into a function
# These arguments are packed into a tuple inside the function
# --- Code cell 58 ---
# using *args
def add_numbers(*david):
return sum(david) # args is a tuple
# --- Code cell 59 ---
add_numbers(2,3,4,5,6,5,4,3)
# --- Code cell 60 ---
result=[3,4,5,6,7,8,9]
total = add_numbers(*result)
print(total)
# --- Code cell 61 ---
#iterating over *args
def print_names(*names):
for name in names:
print(f"Hello,{name}!")
# --- Code cell 62 ---
print_names("rahul","Tarun","sachin","Dinesh","ritesh")
# --- Code cell 63 ---
# Mixing regular arguments with *args
def greet(Title,name="aravind Reddy",*names):
for name in names:
print(f"{Title}{name}")
# --- Code cell 64 ---
greet("Dr.","Rahul","Tarun","sachin","Dinesh")
# --- Code cell 65 ---
dicti={"name":"rahul","age":23,"marks":90}
# --- Code cell 66 ---
dicti.values()
# --- Code cell 67 ---
#**kwargs---allows passing multiple keyword arguments to a function.
# These arguments are stored in a dictionary inside the function
# --- Code cell 69 ---
# using **kwargs
def print_details(**kwargs):
for key,value in kwargs.items():
print(f"{key}:>>>>>{value}")
# --- Code cell 70 ---
print_details(name="rahul",age=23,marks=90,grade="A",loaction="bangalore",class1="first",batch="nov")
# --- Code cell 71 ---
# mixing regular arguments with **kwargs
def display_students(name="alice",**details):
print(f"student:{name}")
for key,value in details.items():
print(f"{key}:{value}")
# --- Code cell 72 ---
display_students(age=23,grade="A",city="bangalore")
# --- Code cell 74 ---
def place_order(item, quantity=1, *toppings, **customer):
# Base prices
menu = {
"pizza": 200,
"burger": 120,
"pasta": 180
}
# Topping prices
topping_prices = {
"cheese": 30,
"olives": 20,
"mushrooms": 25
}
item = item.lower()
if item not in menu:
print("Item not available!")
return
print("\n--- ORDER SUMMARY ---")
print(f"Item: {item.title()}")
print(f"Quantity: {quantity}")
# Step 1: Base price
base_price = menu[item]
print(f"Base Price (each): โน{base_price}")
# Step 2: Topping cost calculation (clear breakdown)
topping_cost = 0
if toppings:
print("\nToppings Added:")
for t in toppings:
cost = topping_prices.get(t.lower(), 0)
print(f" {t} : โน{cost}")
topping_cost += cost
else:
print("\nNo toppings added.")
print(f"\nTotal Topping Cost (per item): โน{topping_cost}")
# Step 3: Final calculation
print("\n--- BILL CALCULATION ---")
print(f"Base Price : โน{base_price}")
print(f"Toppings : โน{topping_cost}")
per_item_total = base_price + topping_cost
print(f"Total per item : โน{per_item_total}")
final_bill = per_item_total * quantity
print(f"Quantity ({quantity}) ร โน{per_item_total} = โน{final_bill}")
# Customer info (**kwargs)
if customer:
print("\n--- CUSTOMER DETAILS ---")
for key, value in customer.items():
print(f"{key.capitalize()}: {value}")
print("\nFinal Amount to Pay: โน", final_bill)
print("--------------------------\n")
# --- Code cell 75 ---
#Basic Order
place_order("Pizza")
# --- Code cell 76 ---
#With toppings
place_order("Burger", 2, "Cheese", "Olives")
# --- Code cell 77 ---
# Full order with customer info
place_order(
"Pasta", 1, "olives","Mushrooms",
name="Alice",
address="123 Main Street",
phone="9876543210"
)
# --- Code cell 78 ---
# lambda function---anonymous function(one-line function)
#syntax---lambda arguments:expression
# only one expression is allowed
# --- Code cell 79 ---
add_all=lambda x,y,z,d:x-y+z+d
add_all(3,5,4,4)
# --- Code cell 80 ---
square=lambda x:x**2
square(23)
# --- Code cell 81 ---
square(23,45,88)
# --- Code cell 82 ---
numbers=[3,4,6,6,7]
square_map=tuple(map(lambda x:x**2,numbers))
print(square_map)