📎 Referral Code:
📊 Dashboard Sign In
Navigation
🗺️
Live Classes
🗺️
Courses
🎬
Assignments
💡
Q & A
💡
My Profile
💡
Recruiter Board
Job Support
🎯
Interview Board
AI Tools
🌐
Project Explanation Agent
🛟
Support Works
🏠 Dashboard June-08-2026:Morning 9:00AM - 10:00AM Python Function Design
📂 1. Python Basics To Advanced Level ⏱ 1.0h 📋 Video 4 of 21
📝 Class Notes
Class Documentation · Python Fundamentals

Python Functions

How to package reusable logic into a function, pass data in and out of it correctly, and where this exact skill shows up in every real pipeline you'll build.

01

What Is a Function, and Why Does It Matter?

You need to calculate GST (18% tax) on a product's price in FIVE different places in your code. Without a function, you'd copy-paste the same calculation five times — and if the tax rate ever changes, you'd have to hunt down and fix all five copies.

A Function is a reusable block of code that performs a specific task, which you can call by name as many times as you need — instead of rewriting the same logic over and over.

Why You're Learning This

Functions are the #1 tool for avoiding repeated code (a principle called "DRY — Don't Repeat Yourself"). Every real project you'll work on — data cleaning scripts, ETL pipelines, APIs — is organized almost entirely as a collection of small, focused functions. Writing good functions is one of the clearest signals of a developer who thinks beyond "just make it work."

Remember This
  • Function = reusable, named block of code you can call anytime
  • Fix logic in ONE place (the function), instead of many copy-pasted places
  • Memory trick: "Write once, use everywhere."
02

Defining and Calling a Function

You want a piece of code that greets a user by name — reusable for every single user who logs in, without rewriting the greeting logic each time.

Simple Answer: Use def to DEFINE (create) a function once. Then CALL it by name, as many times as you want, anywhere later in your code.

define_call.py
def greet_user(name):
    print(f"Welcome, {name}!")

# now call it as many times as you want:
greet_user("Sai")
greet_user("Priya")
Where You'll Use This in Your Career

Every ETL script you build will be broken into functions like extract_data(), clean_data(), load_data() — this exact define-then-call pattern is literally how real pipelines are structured, just at a bigger scale.

Remember This
  • def function_name(): defines a function — nothing runs yet, it just gets saved
  • function_name() actually RUNS (calls) it
  • Indentation matters — everything inside the function must be indented consistently
03

Parameters vs Arguments — A Common Fresher Mix-Up

An interviewer asks "what's the difference between a parameter and an argument?" and most freshers freeze — even though they've been using both correctly without realizing they're technically different words.

Simple Answer: A Parameter is the placeholder NAME listed when you DEFINE the function. An Argument is the ACTUAL VALUE you pass in when you CALL the function.

parameters_arguments.py
def calculate_total(price, quantity):   # price, quantity = PARAMETERS
    return price * quantity

calculate_total(100, 3)   # 100, 3 = ARGUMENTS
Where You'll Use This in Your Career

This is genuinely a common interview vocabulary check — not because it changes how you code, but because using the correct terms shows you can communicate precisely with other engineers, which matters more in team settings than people expect.

Remember This
  • Parameter = the placeholder name in the function's definition
  • Argument = the real value you actually send in when calling it
  • Memory trick: "Parameters are Promised, Arguments are Actual."
04

Default Parameter Values

Most orders in your store ship within India, but occasionally one ships internationally. Forcing every single function call to specify the country, even when it's almost always the same, is unnecessary repetition.

Simple Answer: You can give a parameter a DEFAULT value. If the caller doesn't provide that argument, Python automatically uses the default instead.

default_params.py
def ship_order(order_id, country="India"):
    print(f"Shipping order {order_id} to {country}")

ship_order(101)                  # uses default: "India"
ship_order(102, "USA")         # overrides the default
Where You'll Use This in Your Career

Default parameters make functions much easier to use — you'll see this constantly in real libraries, like PySpark's df.write.mode("overwrite")-style options, where most parameters already have sensible defaults so you only specify what's actually different from the norm.

Remember This
  • Default values go in the function definition: def f(x, y=10):
  • Parameters WITHOUT defaults must come BEFORE parameters WITH defaults
  • Reduces repetition when most calls use the same common value
05

*args — Accepting Any Number of Values

You want a function that adds up prices — sometimes 2 items, sometimes 5, sometimes 10. Writing separate functions for each possible number of items is clearly not practical.

Simple Answer: *args lets a function accept ANY number of extra positional values, automatically collected into a tuple inside the function.

args.py
def total_price(*prices):
    return sum(prices)

print(total_price(100, 200))          # 300
print(total_price(50, 75, 25, 10))  # 160
Where You'll Use This in Your Career

You'll see *args in real library code whenever a function needs to accept a flexible, unknown number of inputs — useful for writing your own reusable utility functions in data pipelines.

Remember This
  • *args = "accept any number of extra positional values"
  • Inside the function, args behaves like a tuple
  • The name "args" is just convention — the * is what actually matters
06

**kwargs — Accepting Any Number of Named Values

You're building a function to create a user profile, but different users provide different optional details — some give a phone number, some give a city, some give both. You don't want to force every possible field as a required parameter.

Simple Answer: **kwargs lets a function accept ANY number of extra NAMED (keyword) values, automatically collected into a dictionary inside the function.

kwargs.py
def create_profile(name, **details):
    print(f"Name: {name}")
    for key, value in details.items():
        print(f"{key}: {value}")

create_profile("Sai", city="Hyderabad", phone="9876543210")
# Name: Sai
# city: Hyderabad
# phone: 9876543210
Where You'll Use This in Your Career

This exact pattern shows up in almost every real Python library you'll use — Pandas, PySpark, and API frameworks all accept flexible optional settings via **kwargs, so understanding it helps you read and use documentation for tools you haven't seen before.

Remember This
  • **kwargs = "accept any number of extra named values"
  • Inside the function, kwargs behaves like a dictionary
  • *args = extra positional values, **kwargs = extra named values — don't mix them up
07

The return Statement — Sending a Value Back

A function calculates a discount, but just PRINTS the result instead of RETURNING it. You try to use that calculated value later in your code — and get None instead, because printing and returning are NOT the same thing.

Simple Answer: return sends a value BACK to wherever the function was called, so you can store it or use it further. Without a return, a function automatically gives back None, even if it printed something on screen.

return_statement.py
def calculate_discount(price):
    return price * 0.9   # 10% off, sent back to the caller

final_price = calculate_discount(1000)
print(final_price)   # 900.0 - usable, because it was RETURNED

def calculate_discount_wrong(price):
    print(price * 0.9)   # just displays it, doesn't return it

result = calculate_discount_wrong(1000)
print(result)    # None - the value is lost, only printed once
Where You'll Use This in Your Career

This print-vs-return confusion is one of the most common early bugs — a function LOOKS like it worked (you see output on screen), but the actual value is unusable in the rest of your program. Getting this right is essential the moment your functions need to work together, like in a multi-step ETL pipeline.

Remember This
  • print() → shows something on screen, for humans to read
  • return → sends a value BACK, for your CODE to actually use
  • No return statement → the function gives back None automatically
08

Variable Scope — Local vs Global

You create a variable INSIDE a function, then try to use it OUTSIDE the function — and Python says it doesn't exist. The variable was never "gone," it just never existed outside that function in the first place.

Simple Answer: A LOCAL variable only exists INSIDE the function where it was created — it disappears once the function finishes running. A GLOBAL variable is created outside any function, and can be READ (though not easily changed) from anywhere.

scope.py
tax_rate = 0.18   # global variable - exists everywhere

def calculate_tax(price):
    tax_amount = price * tax_rate   # tax_amount is LOCAL to this function
    return tax_amount

print(calculate_tax(1000))   # 180.0 - works fine
print(tax_amount)             # ERROR - tax_amount doesn't exist outside the function
Where You'll Use This in Your Career

Understanding scope prevents a whole category of confusing bugs — especially in larger scripts where you might accidentally expect a variable from one function to "leak" into another. This becomes even more important once you write functions that run independently, like PySpark UDFs.

Remember This
  • Local variable → created inside a function, only exists there, disappears after the function ends
  • Global variable → created outside any function, readable from anywhere
  • Keeping variables local (rather than global) generally makes code easier to understand and debug
09

Lambda Functions — Small, Throwaway Functions

You need a tiny function just to sort a list of products by price — used exactly ONCE, right there in the sorting line. Writing a full def function, giving it a name, just for this one-time use feels like overkill.

Simple Answer: A lambda is a small, anonymous (unnamed) function written in a single line — perfect for short, throwaway logic used once, often passed directly into another function.

lambda.py
products = [{"name": "Shoes", "price": 2000}, {"name": "Shirt", "price": 800}]

# regular function way
def get_price(item):
    return item["price"]
sorted_products = sorted(products, key=get_price)

# same result, using a lambda instead - shorter, used only once
sorted_products = sorted(products, key=lambda item: item["price"])
Where You'll Use This in Your Career

Lambdas show up constantly in Pandas (df['col'].apply(lambda x: x * 2)) and are used for quick sorting/filtering logic. That said, in PySpark, you'll typically prefer built-in functions over lambdas/UDFs for performance reasons — a concept you'll cover in more depth later.

Remember This
  • lambda arguments: expression — no def, no name, no return keyword needed
  • Best for short, one-time logic — not for anything complex or reused often
  • If you need multiple lines or reuse it elsewhere, use a regular def function instead
10

Quick Reference — All Function Concepts at a Glance

Use this table for a fast recall of every function concept covered today.

Concept Syntax What It Does Common Real-World Use
def def name(): Defines a reusable function Every function you'll ever write
Parameter def f(x): Placeholder name in the definition Describes what input the function expects
Argument f(5) Actual value passed when calling The real data sent into a function
Default Value def f(x=10): Fallback value if none is given Optional settings, common defaults
*args def f(*args): Accepts any number of positional values Flexible utility functions
**kwargs def f(**kwargs): Accepts any number of named values Optional settings in libraries
return return value Sends a value back to the caller Using a calculated result elsewhere
Local Variable created inside a function Only exists within that function Temporary calculations
Global Variable created outside any function Readable from anywhere Shared constants (like a tax rate)
lambda lambda x: x*2 Small, anonymous, one-line function Quick sort/filter keys, Pandas .apply()
11

Positional vs Default vs *args vs **kwargs — Feature Comparison

A fresher in an interview is asked: "how would you design a function that needs a required name, an optional country, and also needs to accept any number of extra product IDs and any number of extra settings?" This requires combining ALL FOUR parameter styles correctly in one function.

Feature Positional Default *args **kwargs
Syntax def f(x): def f(x=5): def f(*x): def f(**x):
Required? Yes No (has a fallback) No (can be zero values) No (can be zero values)
How Many Values? Exactly one per parameter Exactly one (or the default) Any number (unnamed) Any number (named)
Stored As (Inside Function) A single value A single value A tuple A dictionary
Typical Use Case Must-have inputs Optional settings with a common default Unknown count of similar values Unknown set of optional named settings
all_together.py
def place_order(customer_name, country="India", *product_ids, **extra_settings):
    print(f"Customer: {customer_name}, Country: {country}")
    print(f"Products: {product_ids}")
    print(f"Extra Settings: {extra_settings}")

place_order("Sai", "USA", 101, 102, 103, gift_wrap=True, express=True)
Why You're Learning This

Real, professional libraries (Pandas, PySpark, requests) combine all four of these styles in their functions constantly. Recognizing which style is being used just by reading a function signature is a genuine, practical skill for understanding documentation and other people's code quickly.

Remember This (mind map)
  • Always required, one value → Positional
  • Optional, usually the same value → Default
  • Unknown number of unnamed extra values → *args
  • Unknown number of named/optional extra settings → **kwargs
  • Order in a function definition: Positional → Default → *args → **kwargs
Big Picture Takeaway

A function packages reusable logic behind a name, so you write it once and call it anywhere. Parameters describe what goes in, return sends a result back out, and *args/**kwargs give you flexibility when the number of inputs isn't fixed. Scope keeps your variables organized and predictable, and lambdas give you a shortcut for tiny, one-off logic. Together, these concepts are how every real Python script — from a 10-line utility to a production ETL pipeline — is actually structured.

June-08-2026:Morning 9:00AM - 10:00AM
June-08-2026:Morning 9:00AM - 10:00AM
0% done
5
6. AWS Core
1 videos