Python

Python Functions

A function is a reusable block of code designed to perform a specific task.

Instead of writing the same code repeatedly, we can place it inside a function and call that function whenever we need it.

For example, without a function:

print("Welcome to SkillMantra")
print("Welcome to SkillMantra")
print("Welcome to SkillMantra")

With a function:

def welcome():
    print("Welcome to SkillMantra")

welcome()
welcome()
welcome()

Functions make programs:

  • Reusable
  • Easier to understand
  • Easier to maintain
  • Easier to test
  • More organized
  • Less repetitive

1. Creating a Function

We use the def keyword to create a function.

Syntax

def function_name():
    # code to execute

Example:

def welcome():
    print("Welcome to Python Bootcamp")

The function is created, but its code does not run until we call it.

2. Calling a Function

To execute a function, write its name followed by parentheses.

def welcome():
    print("Welcome to Python Bootcamp")

welcome()

Output:

Welcome to Python Bootcamp

We can call the same function multiple times:

welcome()
welcome()
welcome()

3. Why Use Functions?

Imagine a website where we need to calculate the total price in 20 different places.

Instead of writing:

total = price + tax

20 times, we can create:

def calculate_total(price, tax):
    return price + tax

Then:

print(calculate_total(1000, 100))
print(calculate_total(2500, 250))
print(calculate_total(5000, 500))

The same logic can be reused anywhere.

4. Function with a Parameter

A parameter is a variable defined inside the function declaration.

def welcome(name):
    print("Welcome", name)

Here, name is a parameter.

We can provide a value when calling the function:

welcome("Raj")

Output:

Welcome Raj

Another call:

welcome("John")

Output:

Welcome John

5. Parameter vs Argument

These two terms are related but different.

Parameter

A parameter is the variable defined when creating the function.

def welcome(name):
    print(name)

name is the parameter.

Argument

An argument is the actual value passed when calling the function.

welcome("Raj")

"Raj" is the argument.

Think of it like this:

Parameter → placeholder
Argument  → actual value

6. Multiple Parameters

A function can accept multiple parameters.

def student_info(name, age, course):
    print("Name:", name)
    print("Age:", age)
    print("Course:", course)

student_info("Raj", 25, "Python")

Output:

Name: Raj
Age: 25
Course: Python

7. Positional Arguments

Arguments are normally assigned according to their position.

def student_info(name, age):
    print(name)
    print(age)

student_info("Raj", 25)

Here:

"Raj" → name
25     → age

The order matters.

student_info(25, "Raj")

would assign:

25   → name
Raj  → age

which is probably not what we intended.

8. Keyword Arguments

We can explicitly specify which parameter receives which value.

def student_info(name, age, course):
    print(name, age, course)

student_info(
    name="Raj",
    age=25,
    course="Python"
)

The advantage is that the order no longer matters.

student_info(
    course="Python",
    name="Raj",
    age=25
)

This is also valid.

9. Default Arguments

We can provide a default value for a parameter.

def welcome(name="Student"):
    print("Welcome", name)

If we provide a value:

welcome("Raj")

Output:

Welcome Raj

If we don't:

welcome()

Output:

Welcome Student

The default value is used when no argument is supplied.

10. Multiple Default Parameters

def student_info(name, course="Python", city="Kathmandu"):
    print("Name:", name)
    print("Course:", course)
    print("City:", city)

We can call:

student_info("Raj")

Output:

Name: Raj
Course: Python
City: Kathmandu

Or override the defaults:

student_info("John", "Django", "Pokhara")

11. Important Rule for Default Parameters

A parameter without a default value generally comes before parameters with default values.

Correct:

def student(name, age, course="Python"):
    print(name, age, course)

Avoid:

def student(name="Raj", age, course):
    print(name, age, course)

This causes a syntax error because a required parameter cannot follow a default parameter.

12. Return Value

A function can send a result back to the place where it was called.

We use return.

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

result = add(10, 20)

print(result)

Output:

30

13. print() vs return

This is one of the most important concepts in functions.

Using print()

def add(a, b):
    print(a + b)

result = add(10, 20)

print(result)

Output:

30
None

The function displayed the result but did not send it back.

Using return

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

result = add(10, 20)

print(result)

Output:

30

return allows us to use the result later.

14. Using a Returned Value

def calculate_total(price, tax):
    return price + tax

total = calculate_total(1000, 100)

discount = 50

final_price = total - discount

print(final_price)

Output:

1050

This is why returning values is important in real applications.

15. Returning Multiple Values

Python allows a function to return multiple values.

def calculate(a, b):
    addition = a + b
    subtraction = a - b
    multiplication = a * b

    return addition, subtraction, multiplication

We can receive them separately:

add, subtract, multiply = calculate(10, 5)

print(add)
print(subtract)
print(multiply)

Output:

15
5
50

Python internally returns these values as a tuple.

16. Returning a List

A function can return a list.

def get_courses():
    return ["Python", "Django", "MERN", "Data Science"]

courses = get_courses()

print(courses)

Output:

['Python', 'Django', 'MERN', 'Data Science']

17. Returning a Dictionary

def get_student():
    return {
        "name": "Raj",
        "age": 25,
        "course": "Python"
    }

student = get_student()

print(student)

18. Function Without return

If a function does not explicitly return a value, Python returns None.

def welcome():
    print("Welcome to SkillMantra")

result = welcome()

print(result)

Output:

Welcome to SkillMantra
None

19. Early return

return immediately exits the function.

def check_age(age):

    if age < 18:
        return "Not eligible"

    return "Eligible"

print(check_age(15))
print(check_age(25))

Output:

Not eligible
Eligible

20. Function with Conditions

Functions can contain normal Python logic.

def check_result(marks):

    if marks >= 40:
        return "Pass"

    return "Fail"

print(check_result(75))
print(check_result(35))

Output:

Pass
Fail

21. Function with a Loop

A function can also contain loops.

def print_numbers(start, end):

    for number in range(start, end + 1):
        print(number)

print_numbers(1, 5)

Output:

1
2
3
4
5

22. *args

Sometimes we don't know how many positional arguments a function will receive.

*args allows us to accept multiple positional arguments.

def add_numbers(*numbers):

    total = 0

    for number in numbers:
        total += number

    return total

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

Output:

30
60
150

Inside the function, numbers behaves like a tuple.

23. Understanding *args

def show_items(*items):
    print(items)

show_items("Python", "Django", "MERN")

Output:

('Python', 'Django', 'MERN')

So:

*args → multiple positional arguments → tuple

The name args is a convention. We could technically use another name:

def show_items(*courses):
    print(courses)

24. Practical *args Example

Calculate the average of any number of values.

def average(*numbers):

    total = sum(numbers)

    return total / len(numbers)

print(average(10, 20, 30))
print(average(80, 75, 90, 85))

25. **kwargs

**kwargs allows a function to accept multiple keyword arguments.

def student_info(**details):
    print(details)

student_info(
    name="Raj",
    age=25,
    course="Python"
)

Output:

{'name': 'Raj', 'age': 25, 'course': 'Python'}

Inside the function, details behaves like a dictionary.

So:

**kwargs → multiple keyword arguments → dictionary

26. Looping Through **kwargs

def student_info(**details):

    for key, value in details.items():
        print(key, ":", value)

student_info(
    name="Raj",
    age=25,
    course="Python",
    city="Kathmandu"
)

Output:

name : Raj
age : 25
course : Python
city : Kathmandu

27. *args and **kwargs Together

A function can accept both.

def example(*args, **kwargs):

    print("Arguments:", args)
    print("Keyword Arguments:", kwargs)

example(
    10,
    20,
    30,
    name="Raj",
    course="Python"
)

Output:

Arguments: (10, 20, 30)
Keyword Arguments: {'name': 'Raj', 'course': 'Python'}

28. Function Parameter Order

When using different types of parameters, the general order is:

def function(required, default="value", *args, **kwargs):
    pass

Example:

def student(name, course="Python", *skills, **details):

    print(name)
    print(course)
    print(skills)
    print(details)

Call:

student(
    "Raj",
    "Django",
    "HTML",
    "CSS",
    "JavaScript",
    city="Kathmandu",
    age=25
)

29. Unpacking *

* can also be used when calling a function.

Suppose:

def add(a, b, c):
    return a + b + c

We have:

numbers = [10, 20, 30]

We can unpack the list:

print(add(*numbers))

Output:

60

Python treats it like:

add(10, 20, 30)

30. Unpacking **

** can unpack a dictionary into keyword arguments.

def student(name, age, course):
    print(name, age, course)

details = {
    "name": "Raj",
    "age": 25,
    "course": "Python"
}

student(**details)

This is equivalent to:

student(
    name="Raj",
    age=25,
    course="Python"
)

31. Scope

Scope determines where a variable can be accessed.

Python commonly has:

  • Local scope
  • Global scope

32. Local Variable

A variable created inside a function normally belongs to that function.

def test():
    message = "Hello"
    print(message)

test()

message is a local variable.

Trying to access it outside:

print(message)

will cause an error because message exists only inside the function.

33. Global Variable

A variable created outside a function can normally be accessed inside the function.

name = "Raj"

def welcome():
    print(name)

welcome()

Output:

Raj

name is a global variable.

34. Local and Global with Same Name

Consider:

name = "Raj"

def welcome():
    name = "John"
    print(name)

welcome()

print(name)

Output:

John
Raj

The function's local name does not change the global name.

35. The global Keyword

If we really need to modify a global variable inside a function, we can use global.

count = 10

def update_count():
    global count
    count = 20

update_count()

print(count)

Output:

20

However, excessive use of global variables can make programs harder to maintain. In most cases, returning values from functions is cleaner.

36. Function Documentation

We can describe what a function does using a docstring.

def calculate_area(length, width):
    """
    Calculate the area of a rectangle.
    """

    return length * width

The text inside the triple quotes is a docstring.

We can access it:

print(calculate_area.__doc__)

37. Type Hints

Python allows us to describe the expected types of parameters and return values.

def add(a: int, b: int) -> int:
    return a + b

print(add(10, 20))

Here:

a: int → expected integer
b: int → expected integer
-> int → expected return type

Type hints improve readability and tooling, but Python does not automatically enforce them at runtime.

38. Reusable Calculation Function

Instead of writing:

price = 1000 tax = 100 print(price + tax)

we can create:

def calculate_total(price, tax):
    return price + tax

Then:

print(calculate_total(1000, 100))
print(calculate_total(2500, 250))
print(calculate_total(5000, 500))

This is the real purpose of functions: write logic once and reuse it.

39. Practical Example : Grade Calculator

def calculate_grade(marks):

    if marks >= 80:
        return "A+"
    elif marks >= 70:
        return "A"
    elif marks >= 60:
        return "B+"
    elif marks >= 50:
        return "B"
    elif marks >= 40:
        return "C"
    else:
        return "Fail"


print(calculate_grade(85))
print(calculate_grade(72))
print(calculate_grade(35))

40. Practical Example : Student Information

def student_info(name, age, course="Python"):

    return {
        "name": name,
        "age": age,
        "course": course
    }


student = student_info(
    "Raj",
    25,
    "Django"
)

print(student)

Output:

{'name': 'Raj', 'age': 25, 'course': 'Django'}

41. Practical Example : Shopping Cart

def calculate_cart_total(*prices):

    total = 0

    for price in prices:
        total += price

    return total


total = calculate_cart_total(
    1500,
    800,
    2500
)

print("Total:", total)

Output:

Total: 4800

42. Practical Example : Discount

def calculate_discount(price, discount=10):

    discount_amount = price * discount / 100

    final_price = price - discount_amount

    return final_price


print(calculate_discount(1000))
print(calculate_discount(1000, 20))

Output:

900.0
800.0

43. Practical Example : Login Function

def login(username, password):

    correct_username = "admin"
    correct_password = "python123"

    if username == correct_username and password == correct_password:
        return True

    return False


if login("admin", "python123"):
    print("Login successful")
else:
    print("Invalid username or password")

Functions like this allow authentication logic to be reused elsewhere in an application.

44. Practical Example : Search Function

def search_course(courses, target):

    for course in courses:

        if course.lower() == target.lower():
            return True

    return False


courses = [
    "Python",
    "Django",
    "MERN",
    "Data Science"
]

if search_course(courses, "django"):
    print("Course found")
else:
    print("Course not found")

45. Functions Calling Other Functions

Functions can work together.

def calculate_total(price, tax):
    return price + tax


def calculate_discount(total, discount):
    return total - (total * discount / 100)


total = calculate_total(1000, 100)

final_price = calculate_discount(total, 10)

print(final_price)

This approach allows a large program to be divided into smaller pieces.

46. Function Design Principle

A good function should generally have one clear responsibility.

Instead of:

def process_student():
    # create student
    # calculate marks
    # save database
    # send email
    # generate certificate
    # print report

it is usually better to divide the work:

def create_student():
    pass


def calculate_marks():
    pass


def save_student():
    pass


def send_email():
    pass


def generate_certificate():
    pass

Small functions are easier to test and reuse.

47. Function Naming

Use descriptive names.

Good:

def calculate_total():
    pass


def get_student():
    pass


def search_course():
    pass


def validate_email():
    pass

Avoid unclear names:

def x():
    pass


def abc():
    pass

A function name should tell us what the function does.

48. Copy Code

Below is the complete copy-ready code for the Python Functions lesson.

# ========================================== # Python Functions # ==========================================


# ------------------------------------------ # 1. Basic function # ------------------------------------------

def welcome():
    print("Welcome to Python Bootcamp")


welcome()


# ------------------------------------------ # 2. Function with parameter # ------------------------------------------

def welcome_user(name):
    print("Welcome", name)


welcome_user("Raj")
welcome_user("John")


# ------------------------------------------ # 3. Multiple parameters # ------------------------------------------

def student_info(name, age, course):

    print("Name:", name)
    print("Age:", age)
    print("Course:", course)


student_info("Raj", 25, "Python")


# ------------------------------------------ # 4. Positional arguments # ------------------------------------------

def introduce(name, age):

    print("My name is", name)
    print("My age is", age)


introduce("Raj", 25)


# ------------------------------------------ # 5. Keyword arguments # ------------------------------------------

introduce(
    age=25,
    name="Raj"
)


# ------------------------------------------ # 6. Default arguments # ------------------------------------------

def welcome_student(name="Student"):
    print("Welcome", name)


welcome_student()
welcome_student("Raj")


# ------------------------------------------ # 7. Multiple default arguments # ------------------------------------------

def student(name, course="Python", city="Kathmandu"):

    print("Name:", name)
    print("Course:", course)
    print("City:", city)


student("Raj")
student("John", "Django", "Pokhara")


# ------------------------------------------ # 8. Return value # ------------------------------------------

def add(a, b):

    return a + b


result = add(10, 20)

print(result)


# ------------------------------------------ # 9. Multiple return values # ------------------------------------------

def calculate(a, b):

    addition = a + b
    subtraction = a - b
    multiplication = a * b

    return addition, subtraction, multiplication


add_result, subtract_result, multiply_result = calculate(10, 5)

print(add_result)
print(subtract_result)
print(multiply_result)


# ------------------------------------------ # 10. Return a list # ------------------------------------------

def get_courses():

    return [
        "Python",
        "Django",
        "MERN",
        "Data Science"
    ]


courses = get_courses()

print(courses)


# ------------------------------------------ # 11. Return a dictionary # ------------------------------------------

def get_student():

    return {
        "name": "Raj",
        "age": 25,
        "course": "Python"
    }


student = get_student()

print(student)


# ------------------------------------------ # 12. Early return # ------------------------------------------

def check_age(age):

    if age < 18:
        return "Not eligible"

    return "Eligible"


print(check_age(15))
print(check_age(25))


# ------------------------------------------ # 13. Function with condition # ------------------------------------------

def check_result(marks):

    if marks >= 40:
        return "Pass"

    return "Fail"


print(check_result(75))
print(check_result(35))


# ------------------------------------------ # 14. Function with loop # ------------------------------------------

def print_numbers(start, end):

    for number in range(start, end + 1):
        print(number)


print_numbers(1, 5)


# ------------------------------------------ # 15. *args # ------------------------------------------

def add_numbers(*numbers):

    total = 0

    for number in numbers:
        total += number

    return total


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


# ------------------------------------------ # 16. Average using *args # ------------------------------------------

def average(*numbers):

    return sum(numbers) / len(numbers)


print(average(10, 20, 30))
print(average(80, 75, 90, 85))


# ------------------------------------------ # 17. **kwargs # ------------------------------------------

def show_student(**details):

    print(details)


show_student(
    name="Raj",
    age=25,
    course="Python"
)


# ------------------------------------------ # 18. Loop through **kwargs # ------------------------------------------

def student_details(**details):

    for key, value in details.items():
        print(key, ":", value)


student_details(
    name="Raj",
    age=25,
    course="Python",
    city="Kathmandu"
)


# ------------------------------------------ # 19. *args and **kwargs together # ------------------------------------------

def example(*args, **kwargs):

    print("Arguments:", args)
    print("Keyword Arguments:", kwargs)


example(
    10,
    20,
    30,
    name="Raj",
    course="Python"
)


# ------------------------------------------ # 20. Unpacking list using * # ------------------------------------------

def add_three(a, b, c):

    return a + b + c


numbers = [10, 20, 30]

print(add_three(*numbers))


# ------------------------------------------ # 21. Unpacking dictionary using ** # ------------------------------------------

def display_student(name, age, course):

    print(name)
    print(age)
    print(course)


details = {
    "name": "Raj",
    "age": 25,
    "course": "Python"
}

display_student(**details)


# ------------------------------------------ # 22. Local scope # ------------------------------------------

def local_example():

    message = "Hello from function"

    print(message)


local_example()


# ------------------------------------------ # 23. Global scope # ------------------------------------------

name = "Raj"


def global_example():

    print(name)


global_example()


# ------------------------------------------ # 24. Local and global variable # ------------------------------------------

name = "Raj"


def test_scope():

    name = "John"

    print("Inside:", name)


test_scope()

print("Outside:", name)


# ------------------------------------------ # 25. global keyword # ------------------------------------------

count = 10


def update_count():

    global count

    count = 20


update_count()

print(count)


# ------------------------------------------ # 26. Function documentation # ------------------------------------------

def calculate_area(length, width):
    """
    Calculate the area of a rectangle.
    """

    return length * width


print(calculate_area(10, 5))

print(calculate_area.__doc__)


# ------------------------------------------ # 27. Type hints # ------------------------------------------

def add_values(a: int, b: int) -> int:

    return a + b


print(add_values(10, 20))


# ------------------------------------------ # 28. Calculate total # ------------------------------------------

def calculate_total(price, tax):

    return price + tax


print(calculate_total(1000, 100))
print(calculate_total(2500, 250))


# ------------------------------------------ # 29. Grade calculator # ------------------------------------------

def calculate_grade(marks):

    if marks >= 80:
        return "A+"

    elif marks >= 70:
        return "A"

    elif marks >= 60:
        return "B+"

    elif marks >= 50:
        return "B"

    elif marks >= 40:
        return "C"

    else:
        return "Fail"


print(calculate_grade(85))
print(calculate_grade(72))
print(calculate_grade(35))


# ------------------------------------------ # 30. Student information # ------------------------------------------

def create_student(name, age, course="Python"):

    return {
        "name": name,
        "age": age,
        "course": course
    }


student = create_student(
    "Raj",
    25,
    "Django"
)

print(student)


# ------------------------------------------ # 31. Shopping cart # ------------------------------------------

def calculate_cart_total(*prices):

    total = 0

    for price in prices:
        total += price

    return total


total = calculate_cart_total(
    1500,
    800,
    2500
)

print("Total:", total)


# ------------------------------------------ # 32. Discount calculator # ------------------------------------------

def calculate_discount(price, discount=10):

    discount_amount = price * discount / 100

    final_price = price - discount_amount

    return final_price


print(calculate_discount(1000))
print(calculate_discount(1000, 20))


# ------------------------------------------ # 33. Login function # ------------------------------------------

def login(username, password):

    correct_username = "admin"
    correct_password = "python123"

    if username == correct_username and password == correct_password:
        return True

    return False


if login("admin", "python123"):
    print("Login successful")
else:
    print("Invalid username or password")


# ------------------------------------------ # 34. Search course # ------------------------------------------

def search_course(courses, target):

    for course in courses:

        if course.lower() == target.lower():
            return True

    return False


courses = [
    "Python",
    "Django",
    "MERN",
    "Data Science"
]


if search_course(courses, "django"):
    print("Course found")
else:
    print("Course not found")


# ------------------------------------------ # 35. Function calling another function # ------------------------------------------

def calculate_total(price, tax):

    return price + tax


def calculate_discount(total, discount):

    return total - (total * discount / 100)


total = calculate_total(1000, 100)

final_price = calculate_discount(total, 10)

print(final_price)

49. Practice Exercises

Exercise 1 : Basic Function

Create:

def welcome():

The function should print:

Welcome to SkillMantra Python Bootcamp

Exercise 2 : Greeting Function

Create a function that accepts a name.

Input:
Raj

Output:
Hello Raj

Exercise 3 : Calculator

Create separate functions:

add()
subtract()
multiply()
divide()

Test each function with different numbers.

Exercise 4 : Even Number

Create:

def is_even(number):

The function should return True if the number is even and False otherwise.

Exercise 5 : Maximum Number

Create:

def find_max(a, b, c):

Find the largest number without using max().

Exercise 6 : Student Grade

Create:

def calculate_grade(marks):

Return:

80+ → A+
70+ → A
60+ → B+
50+ → B
40+ → C
Below 40 → Fail

Exercise 7 : *args

Create:

def calculate_sum(*numbers):

It should accept any number of numbers and return their total.

Example:

calculate_sum(10, 20, 30, 40)

Expected:

100

Exercise 8 : **kwargs

Create:

def display_profile(**details):

Call it with:

display_profile(
    name="Raj",
    age=25,
    course="Python",
    city="Kathmandu"
)

Display each key and value.

Exercise 9 : Shopping Cart

Create:

def calculate_total(*prices):

Then create:

def apply_discount(total, discount=10):

Use both functions to calculate the final shopping price.

Exercise 10 : Student Management

Create functions for:

add_student()
find_student()
delete_student()
display_students()
calculate_average()
find_top_student()

Use a dictionary to store student information.

This exercise introduces students to the idea of breaking a larger program into small reusable functions.

Interactive Sandbox
Python