LearningPython TutorialFunctions & Scope
CHAPTER 12 · REUSABLE CODE

Python Functions & Scope

Functions reusable blocks of code hote hain. Is chapter me def, parameters, return values, defaults, keyword arguments, *args, **kwargs, variable scope aur recursion basics ko practical examples ke saath samjhenge.

English + Hinglish65 min readOnline practice included

Why functions?

Function repeated logic ko ek reusable name deta hai. Isse duplication kam hota hai, code readable hota hai aur testing/debugging easier ho sakti hai.

first-function.pyPython
def greet():
    print("Hello from BrounStack!")

greet()
greet()
Hinglish Explanation

def function define karta hai. Function ke andar ka code tab run hota hai jab function ko call karte ho.

Try your first function →

Parameters and arguments

Parameter function definition me placeholder hota hai; argument function call ke time supplied value hoti hai.

parameters.pyPython
def greet(name):
    print(f"Hello, {name}!")

greet("Aman")
greet("Riya")

Multiple parameters

multiple.pyPython
def student_summary(name, course, score):
    print(f"{name} | {course} | {score}")

student_summary("Aman", "Python", 88)

Positional arguments order ke basis par parameters se match hote hain.

Return values

return function ke result ko caller ko wapas deta hai. print() sirf output display karta hai; return value ko further calculations me use kiya ja sakta hai.

return.pyPython
def add(a, b):
    return a + b

result = add(10, 20)
print(result)
print(add(5, 7) * 2)
Important: Function explicitly return na kare to Python normally None return karta hai.

Early return

early-return.pyPython
def classify_score(score):
    if score < 0 or score > 100:
        return "Invalid"
    if score >= 40:
        return "Pass"
    return "Needs Improvement"

print(classify_score(72))

Early return unnecessary deep nesting ko reduce kar sakta hai.

Default arguments

defaults.pyPython
def greet(name, message="Welcome"):
    return f"{message}, {name}!"

print(greet("Aman"))
print(greet("Riya", "Good morning"))

Required parameters ko generally default parameters se pehle rakhna hota hai.

Mutable default argument trap

List/dictionary jaisi mutable value ko direct default banana confusing shared state create kar sakta hai.

safe-default.pyPython
def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

print(add_item("HTML"))
print(add_item("Python"))

None sentinel beginner-friendly safe pattern hai.

Keyword arguments

keywords.pyPython
def profile(name, city, course):
    print(name, city, course)

profile(course="Python", name="Aman", city="Delhi")

Keyword arguments call ko self-documenting bana sakte hain aur order dependence reduce karte hain.

Positional and keyword rules

  • Normal positional arguments usually keyword arguments se pehle aate hain.
  • Same parameter ko positional aur keyword dono se value dene par error aata hai.
  • Missing required argument par TypeError aata hai.
  • Unexpected keyword argument par bhi TypeError aa sakta hai.

Variable positional arguments: *args

args.pyPython
def total(*numbers):
    return sum(numbers)

print(total(10, 20))
print(total(10, 20, 30, 40))

*args extra positional arguments ko tuple me collect karta hai. Name technically kuch bhi ho sakta hai, but args common convention hai.

Variable keyword arguments: **kwargs

kwargs.pyPython
def show_profile(**details):
    for key, value in details.items():
        print(f"{key}: {value}")

show_profile(name="Aman", course="Python", city="Delhi")

**kwargs extra keyword arguments ko dictionary me collect karta hai.

Unpacking values into function calls

call-unpacking.pyPython
def add(a, b, c):
    return a + b + c

values = [10, 20, 30]
print(add(*values))

profile = {"name": "Aman", "city": "Delhi"}

def intro(name, city):
    return f"{name} from {city}"

print(intro(**profile))

Returning multiple values

multiple-return.pyPython
def min_max(values):
    return min(values), max(values)

lowest, highest = min_max([12, 7, 25, 18])
print(lowest, highest)

Python yahan effectively tuple return kar raha hota hai, jise unpack kiya ja sakta hai.

Function docstrings

docstring.pyPython
def calculate_average(marks):
    """Return the average of a non-empty marks list."""
    return sum(marks) / len(marks)

print(calculate_average.__doc__)

Public/reusable functions ke purpose, parameters ya behavior ko document karna useful hota hai.

What is variable scope?

Scope decide karta hai ki variable code ke kis part me accessible hai. Function ke andar banaya gaya local variable normally function ke bahar directly available nahi hota.

scope.pyPython
course = "Python"  # global

def show_course():
    message = "Learning"  # local
    print(message, course)

show_course()
print(course)

LEGB rule — beginner view

Python name lookup ko commonly LEGB se explain kiya jata hai: Local → Enclosing → Global → Built-in.

legb.pyPython
name = "Global"

def outer():
    name = "Enclosing"

    def inner():
        name = "Local"
        print(name)

    inner()

outer()

Inner scope me same variable name outer/global name ko temporarily shadow kar sakta hai.

global keyword

global.pyPython
count = 0

def increment():
    global count
    count += 1

increment()
print(count)

global se global variable reassign kiya ja sakta hai, lekin heavy global mutable state code ko harder to reason about bana sakta hai. Return values often cleaner design hote hain.

nonlocal keyword

nonlocal.pyPython
def counter():
    count = 0

    def increment():
        nonlocal count
        count += 1
        return count

    return increment

next_count = counter()
print(next_count())
print(next_count())

nonlocal enclosing function scope ke variable ko reassign karne deta hai. Closures ka deeper use later advanced chapters me dekhenge.

Prefer clear inputs and outputs

Beginner code me functions ko explicit inputs dena aur result return karna usually hidden global state se cleaner hota hai.

clear-design.pyPython
def apply_discount(price, percent):
    discount = price * percent / 100
    return price - discount

print(apply_discount(2000, 10))

Recursion basics

Recursive function khud ko call karta hai. Har recursive solution me base case hona zaroori hai jo recursion ko stop kare.

recursion.pyPython
def countdown(number):
    if number == 0:
        print("Done")
        return

    print(number)
    countdown(number - 1)

countdown(3)
Use recursion carefully: Har problem ke liye recursion best choice nahi hoti. Python me deep recursion limit hit kar sakti hai; simple loops often clearer hote hain.

Practical function workflow

result-system.pyPython
def valid_mark(mark):
    return 0 <= mark <= 100


def average(marks):
    if not marks:
        return None
    return sum(marks) / len(marks)


def grade(value):
    if value >= 90:
        return "A"
    if value >= 75:
        return "B"
    if value >= 60:
        return "C"
    if value >= 40:
        return "Pass"
    return "Needs Improvement"

marks = [78, 92, 85, 66]
valid_marks = [mark for mark in marks if valid_mark(mark)]
result = average(valid_marks)

if result is not None:
    print(f"Average: {result:.2f}")
    print(f"Grade: {grade(result)}")

Run function example →

Common beginner mistakes

  • Function define karke call karna bhoolna.
  • print() ko return samajhna.
  • Required arguments miss karna ya wrong order me pass karna.
  • Mutable default argument use karke shared state create karna.
  • *args aur **kwargs ko unnecessarily use karna.
  • Local variable ko function ke bahar accessible assume karna.
  • Global variable ko function ke andar assign karte waqt scope rules ignore karna.
  • Built-in names jaise list, str, sum ko variable/function name bana dena.
  • Function me too many responsibilities rakhna.
  • Recursion me base case bhoolna.

Beginner best practices

  • Function name ko action/purpose clear karne wala rakho.
  • Function ko focused rakho: ek clear responsibility.
  • Inputs parameters se lo aur useful result return karo.
  • Repeated code ko function me extract karo, but tiny one-off code ko over-engineer mat karo.
  • Defaults simple aur safe rakho.
  • Global mutable state minimize karo.
  • Complex function ke liye docstring add karo.
  • Boundary cases test karo: empty list, zero, negative input, invalid range.

Chapter checklist

  • def se function bana aur call kar sakte ho?
  • Parameter vs argument ka difference clear hai?
  • return aur print() ka difference samajh aaya?
  • Default aur keyword arguments use kar sakte ho?
  • *args / **kwargs ka basic purpose clear hai?
  • Local/global/enclosing scope ka basic idea samajh aaya?
  • global aur nonlocal ko recognize kar sakte ho?
  • Recursion me base case kyun zaroori hai, samajh aaya?

Practice Task — Student Result Toolkit

BrounStack Playground me function-based result toolkit banao.

  1. read_mark() function banao jo numeric mark return kare.
  2. is_valid_mark(mark) function banao.
  3. calculate_average(marks) function banao.
  4. calculate_grade(average) function banao.
  5. print_report(name, marks) function banao.
  6. At least one function default argument use kare.
  7. At least one function keyword arguments ke saath call karo.
  8. One function multiple values return kare.
  9. Empty-list case handle karo.
  10. 0–100 validation handle karo.
  11. Global variables ke bina solution banane ki koshish karo.
  12. Function names meaningful rakho.
  13. One small docstring add karo.
  14. Final output readable f-strings me print karo.

Open practice starter →