Session 6

βš™οΈ Functions Part I

Creating reusable blocks of code

πŸ“š 8 Topics ⏱️ 45 min read 🎯 Essential Level

πŸ—ΊοΈ What You'll Learn

🎯 What are Functions?
✏️ Defining Functions
πŸ“₯ Parameters & Arguments
πŸ“€ Return Values
πŸ”§ Default Parameters
🏷️ Keyword Arguments

πŸ“˜ Same topic in the course notebook

Session_6 Functions Part I covers def, return, parameters, and scopeβ€”same as here. Practice in the notebook.

🏭

Functions = Mini Factories!

             INPUT                         OUTPUT
    (Raw Materials)      🏭              (Finished Product)
    
        πŸ₯š πŸ₯› 🧈    β†’   [CAKE_MAKER]  β†’    πŸŽ‚
                        FUNCTION
                        
    β€’ Give it ingredients (arguments)
    β€’ It does its job (function body)
    β€’ It gives back a result (return value)
    
    Write once, use many times! ♻️
          

A function is a reusable recipe - define it once, use it whenever you need!

❓ Why Use Functions?

6.1

🎯 Benefits of Functions

🚫 Without Functions (Bad)

# Calculate area of rectangle 1
length1 = 10
width1 = 5
area1 = length1 * width1
print("Area 1:", area1)

# Calculate area of rectangle 2 (copy-paste!)
length2 = 7
width2 = 3
area2 = length2 * width2
print("Area 2:", area2)

# Calculate area of rectangle 3 (more copy-paste!)
length3 = 15
width3 = 8
area3 = length3 * width3
print("Area 3:", area3)
          

βœ… With Functions (Good)

def calculate_area(length, width):
    return length * width

# Use it as many times as needed!
print("Area 1:", calculate_area(10, 5))
print("Area 2:", calculate_area(7, 3))
print("Area 3:", calculate_area(15, 8))
          
πŸ’‘ DRY Principle

Don't Repeat Yourself! Functions help you write code once and reuse it everywhere.

✏️ Defining Functions

6.2

πŸ“ Function Syntax

πŸ” Anatomy of a Function

    def function_name(parameter1, parameter2):
    β”‚   β”‚             β”‚
    β”‚   β”‚             └── Parameters (inputs)
    β”‚   β”‚
    β”‚   └── Function name (follows variable naming rules)
    β”‚
    └── 'def' keyword (defines a function)

        """Docstring: explains what the function does"""
            β”‚
            └── Optional but recommended!
        
        # Function body
        result = parameter1 + parameter2
            β”‚
            └── The code that runs when function is called
        
        return result
            β”‚
            └── What the function gives back
          
Python From Source
# Basic function from Session 6
def greet():
    """A simple greeting function"""
    print("Hello, World!")

# Call the function
greet()
greet()  # Can call it multiple times!
Output
Hello, World!
Hello, World!
⚠️ Don't Forget the Parentheses!

greet = the function object itself

greet() = calling/executing the function

πŸ“₯ Parameters & Arguments

6.3

🎁 Passing Data to Functions

Parameters are variables in the function definition. Arguments are the actual values you pass when calling the function.

🏷️ Parameters vs Arguments

    def greet(name):        ← 'name' is a PARAMETER
                              (placeholder/variable)
        print(f"Hello, {name}!")
    
    greet("Alice")          ← "Alice" is an ARGUMENT
                              (actual value passed)
          
Python From Source
# Function with parameters from Session 6
def greet(name):
    """Greet a person by name"""
    print(f"Hello, {name}! Nice to meet you.")

# Call with different arguments
greet("Alice")
greet("Bob")
greet("Charlie")

# Can pass variables too
my_name = "David"
greet(my_name)
Output
Hello, Alice! Nice to meet you.
Hello, Bob! Nice to meet you.
Hello, Charlie! Nice to meet you.
Hello, David! Nice to meet you.

πŸ“Š Multiple Parameters

Python From Source
# Multiple parameters from Session 6
def add_numbers(a, b):
    """Add two numbers and print the result"""
    result = a + b
    print(f"{a} + {b} = {result}")

add_numbers(5, 3)
add_numbers(10, 20)
add_numbers(-5, 5)

# More parameters
def introduce(name, age, city):
    """Introduce a person"""
    print(f"My name is {name}, I'm {age} years old, from {city}.")

introduce("Alice", 25, "New York")
introduce("Bob", 30, "London")
Output
5 + 3 = 8
10 + 20 = 30
-5 + 5 = 0
My name is Alice, I'm 25 years old, from New York.
My name is Bob, I'm 30 years old, from London.

πŸ“€ Return Values

6.4

🎁 Getting Results from Functions

The return statement sends a value back from the function. Without it, the function returns None.

πŸ”„ Print vs Return

    PRINT πŸ–¨οΈ                    RETURN πŸ“¦
    ─────────                    ──────────
    Shows on screen              Sends value back
    Can't use result             Can store/use result
    Returns None                 Returns specified value
    
    print("Hi")  β†’  Hi           return "Hi"  β†’  "Hi"
                   (to screen)                    (to code)
          
Python From Source
# Return values from Session 6
def add(a, b):
    """Add two numbers and return the result"""
    return a + b

def multiply(a, b):
    """Multiply two numbers"""
    return a * b

# Store the returned values
sum_result = add(5, 3)
product = multiply(4, 6)

print("Sum:", sum_result)
print("Product:", product)

# Use returned values directly
print("Direct use:", add(10, 20))

# Chain function calls
total = add(multiply(2, 3), multiply(4, 5))
print("Chained:", total)  # (2*3) + (4*5) = 6 + 20 = 26
Output
Sum: 8
Product: 24
Direct use: 30
Chained: 26

πŸ“¦ Returning Multiple Values

Python From Source
# Return multiple values from Session 6
def get_stats(numbers):
    """Calculate and return multiple statistics"""
    minimum = min(numbers)
    maximum = max(numbers)
    total = sum(numbers)
    average = total / len(numbers)
    return minimum, maximum, total, average  # Returns a tuple

# Call and unpack the results
data = [4, 8, 15, 16, 23, 42]
min_val, max_val, sum_val, avg_val = get_stats(data)

print(f"Min: {min_val}")
print(f"Max: {max_val}")
print(f"Sum: {sum_val}")
print(f"Average: {avg_val:.2f}")

# Or get as tuple
stats = get_stats(data)
print("\\nAs tuple:", stats)
Output
Min: 4
Max: 42
Sum: 108
Average: 18.00

As tuple: (4, 42, 108, 18.0)

πŸ”§ Default Parameters

6.5

πŸ“‹ Optional Arguments

Default parameters have a preset value that's used if no argument is provided. They make some arguments optional!

Python From Source
# Default parameters from Session 6
def greet(name, greeting="Hello"):
    """Greet with optional custom greeting"""
    print(f"{greeting}, {name}!")

# Using default greeting
greet("Alice")

# Providing custom greeting
greet("Bob", "Hi")
greet("Charlie", "Good morning")

# More examples
def power(base, exponent=2):
    """Calculate base raised to exponent (default: square)"""
    return base ** exponent

print("\\nPower examples:")
print("5 squared:", power(5))        # Uses default exponent=2
print("2 cubed:", power(2, 3))       # Custom exponent
print("10 to 4:", power(10, 4))     # Custom exponent
Output
Hello, Alice!
Hi, Bob!
Good morning, Charlie!

Power examples:
5 squared: 25
2 cubed: 8
10 to 4: 10000
⚠️ Important Rule

Default parameters must come AFTER non-default parameters!

βœ… def func(a, b=5)

❌ def func(a=5, b) - This is a syntax error!

🏷️ Keyword Arguments

6.6

πŸ“Œ Named Arguments

Keyword arguments let you specify which parameter gets which value by name. This makes your code clearer and more flexible!

Python From Source
# Keyword arguments from Session 6
def create_profile(name, age, city, occupation):
    """Create a user profile"""
    print(f"Name: {name}")
    print(f"Age: {age}")
    print(f"City: {city}")
    print(f"Occupation: {occupation}")
    print("---")

# Positional arguments (order matters!)
create_profile("Alice", 25, "NYC", "Engineer")

# Keyword arguments (order doesn't matter!)
create_profile(
    occupation="Designer",
    name="Bob",
    city="LA",
    age=30
)

# Mix of positional and keyword
create_profile("Charlie", 35, city="Chicago", occupation="Manager")
Output
Name: Alice
Age: 25
City: NYC
Occupation: Engineer
---
Name: Bob
Age: 30
City: LA
Occupation: Designer
---
Name: Charlie
Age: 35
City: Chicago
Occupation: Manager
---
πŸ’‘ When to Use Keyword Arguments
  • When a function has many parameters
  • When you want to skip some default parameters
  • When you want your code to be more readable

πŸ”­ Variable Scope

6.7

πŸ“ Local vs Global Variables

Scope determines where a variable can be accessed. Variables created inside a function are local to that function.

🏠 Think of Scope Like Rooms in a House

    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚          GLOBAL SCOPE 🌍              β”‚
    β”‚       (Living Room - Everyone)        β”‚
    β”‚                                       β”‚
    β”‚  global_var = "I'm everywhere!"       β”‚
    β”‚                                       β”‚
    β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                 β”‚
    β”‚   β”‚  FUNCTION SCOPE β”‚                 β”‚
    β”‚   β”‚  (Your Bedroom) β”‚                 β”‚
    β”‚   β”‚                 β”‚                 β”‚
    β”‚   β”‚  local_var = "My secret"          β”‚
    β”‚   β”‚  (Only you can see this)          β”‚
    β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                 β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          
Python From Source
# Variable scope from Session 6
global_var = "I'm global!"  # Global variable

def my_function():
    local_var = "I'm local!"  # Local variable
    print("Inside function:")
    print("  Global:", global_var)  # Can access global
    print("  Local:", local_var)    # Can access local

my_function()

print("\\nOutside function:")
print("  Global:", global_var)  # Can access global
# print("  Local:", local_var)  # ERROR! local_var doesn't exist here

# Variables with same name in different scopes
x = 10  # Global x

def test_scope():
    x = 20  # Local x (shadows global x)
    print("Inside function, x =", x)

test_scope()
print("Outside function, x =", x)  # Global x unchanged
Output
Inside function:
  Global: I'm global!
  Local: I'm local!

Outside function:
  Global: I'm global!
Inside function, x = 20
Outside function, x = 10

πŸ› οΈ Built-in Functions

6.8

πŸ“¦ Python's Ready-to-Use Functions

Python comes with many built-in functions that you've already been using!

Python From Source
# Common built-in functions from Session 6

# Type functions
print("type(42):", type(42))
print("int('100'):", int("100"))
print("str(42):", str(42))
print("float(5):", float(5))

# Math functions
numbers = [3, 1, 4, 1, 5, 9]
print("\\nmin:", min(numbers))
print("max:", max(numbers))
print("sum:", sum(numbers))
print("len:", len(numbers))
print("abs(-7):", abs(-7))
print("round(3.7):", round(3.7))
print("pow(2, 3):", pow(2, 3))

# Sequence functions
print("\\nrange(5):", list(range(5)))
print("sorted:", sorted(numbers))
print("reversed:", list(reversed(numbers)))

# Input/Output
# name = input("Enter name: ")  # Gets user input
print("Hello!")  # Outputs to console
Output
type(42): <class 'int'>
int('100'): 100
str(42): 42
float(5): 5.0

min: 1
max: 9
sum: 23
len: 6
abs(-7): 7
round(3.7): 4
pow(2, 3): 8

range(5): [0, 1, 2, 3, 4]
sorted: [1, 1, 3, 4, 5, 9]
reversed: [9, 5, 1, 4, 1, 3]
Hello!

πŸ“‹ Quick Reference

Concept Syntax Example
Define function def name(): def greet():
With parameters def name(a, b): def add(x, y):
Return value return value return x + y
Default parameter def f(a=5): def greet(name="World"):
Call function name(args) greet("Alice")
Keyword argument name=value greet(name="Bob")

🚫 Common Mistakes (Functions)

πŸ’­ Short reflection

In one sentence: why is it better to put repeated code inside a function instead of copying it in multiple places?

βœ… CORE (Must know)

πŸ“š NON-CORE (Good to know)

Complete code from course notebook: Functions_Part_I.ipynb

Every line of code from the course notebook (verbatim).

# --- Code cell 1 ---
# 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 2 ---
Types of functions
1@ Built-in functions
2@ User-defined functions
3@ lambda(annoymous) functions

# --- Code cell 3 ---
#for any word when you add a parenthis is a function

# --- Code cell 4 ---
print("to print")

# --- Code cell 5 ---
# Built-in-functions
print()
max()
min()
sum()
len()

# --- Code cell 6 ---
flow=input("enter a name")
print(flow)

# --- Code cell 7 ---
import builtins
print(dir(builtins))

# --- Code cell 8 ---
list1=[23,34,56,78,89]
avg=sum(list1)/len(list1)
avg

# --- Code cell 9 ---
import statistics
list1=[23,34,56,78,89]
s=statistics.mean(list1)
s

# --- Code cell 10 ---
max(list1)

# --- Code cell 11 ---
min(list1)

# --- Code cell 12 ---
#user-defined function is created by the user to perform a specific task.

# --- Code cell 13 ---
# syntax
def hello():  # defining a function
  # function block of code
hello()   # calling function

# --- Code cell 14 ---
# simple function without parameters
def greet():
  print("hello welcome to fuctions in python")

# --- Code cell 15 ---
greet()

# --- Code cell 16 ---
greet1()

# --- Code cell 17 ---
# syntax
def hello(parameters):  # defining a function
  # function block of code
hello(arguments)   # calling function

# --- Code cell 18 ---
greet("vishal")

# --- Code cell 19 ---
greet("aravind")

# --- Code cell 20 ---
Function arguments in python
1@ positional arguments
2@ default arguments/keyword arguments
3@ arbitary Keyword arguments
4@ arbitary non keyword arguments

# --- Code cell 21 ---
# positional argument
def greet(name):
  print(f"hello {name}")

# --- Code cell 22 ---
greet(3567)

# --- Code cell 23 ---
greet("azar")

# --- Code cell 24 ---
greet("rahul","aravind")

# --- Code cell 25 ---
# positional argument
def intro(name,age):
  print(f"hello my name is {name} , and  my age is {age}")

# --- Code cell 26 ---
intro(65,"banu",67)

# --- Code cell 27 ---
intro("banu")

# --- Code cell 28 ---
# default arguments/keyword arguments

def greet(name="rahul"):
  print(f"hello,{name}!")

# --- Code cell 29 ---
greet() # no argument are passed

# --- Code cell 30 ---
greet("alice") # positional argument is passed

# --- Code cell 31 ---
# positional arguments
def student(marks,name,age=21):
  print(f"name:{name} with age:{age} and marks:{marks}")

# --- Code cell 32 ---
student(33,"tarun",55)

# --- Code cell 33 ---
student("rahul",23) # Positional arguments

# --- Code cell 34 ---
student(90,"rahul",34) # wrong order of arguments

# --- Code cell 35 ---
student(marks=90,name="taarun",age=23) # keyword arguments without order

# --- Code cell 36 ---
student(44,name="aravind") # positional and keyword arguments

# --- Code cell 37 ---
student(name="aravind",44) # positional and keyword arguments

# --- Code cell 38 ---
student(marks=90,"rahul",23) # positional and keyword arguments

# --- Code cell 39 ---
# positional arguments
def student(marks,name,age=21):
  print(f"name:{name} with age:{age} and marks:{marks}")

# --- Code cell 40 ---
student(name="rahul",marks=90) # positional and keyword arguments