Function Basics

1. 🧰 Functions

    1.1 What is a Function?
    1. Imagine a website for checking exam results. You enter your Symbol Number or Roll Number. The website checks the exam records. Then it shows your result and grade as output. A Python function works in a similar way. Here: - Symbol Number ➜ Input - Checking records ➜ Logic - Result and grade ➜ Output Definition: A function is a named block of reusable code that performs a specific task. It can take input values, called parameters, process them using a set of statements, and optionally return an output value. Functions help us: ✅ Avoid repeating code ✅ Break big problems into smaller parts ✅ Make code easier to read ✅ Make code easier to maintain ✅ Reuse the same logic multiple times A function usually has: Input ➜ Parameters / Arguments Logic ➜ Code inside the function Output ➜ Return value Example: def greet(name):return f"Hello, {name}!"message = greet("Rabi") print(message) # ➜ Hello, Rabi!
    1.2 Why Use Functions?
    1. Without function: print("Hello, Ram!") print("Hello, Hari!") print("Hello, Sita!")With function: def greet(name):return f"Hello, {name}!"print(greet("Ram")) print(greet("Hari")) print(greet("Sita")) ✅ Function helps us write the logic once and reuse it many times.
    1.3 Function Syntax
    1. Syntax: def function_name(parameters):code inside functionreturn value Here: def ➜ Keyword used to define a function function_name ➜ Name of the function parameters ➜ Input variables return ➜ Sends result back from the function 📌 Function body must be indented. 📌 A function does not run until it is called.
    1.4 Defining and Calling a Function
    1. Defining a function means creating it. Calling a function means using it. Example: def say_hello():print("Hello!")say_hello()Output: Hello! Here: def say_hello(): creates the function. say_hello() calls the function.

2. 📥 Parameters and Arguments

    2.1 What are Parameters and Arguments?
    1. A parameter is the variable written inside the function definition. An argument is the actual value passed when calling the function. 📌 Parameters are used while defining a function. 📌 Arguments are used while calling a function. Example: def greet(name):return f"Hello, {name}!"print(greet("Ram")) Here: name ➜ Parameter "Ram" ➜ Argument
    2.2 Function with One Parameter
    1. Example: def square(num):return num ** 2result = square(5)print(result) # ➜ 25
    2.3 Function with Multiple Parameters
    1. Example: def add_numbers(num_1, num_2):return num_1 + num_2result = add_numbers(10, 5)print(result) # ➜ 15
    2.4 Positional Arguments
    1. In positional arguments, values are matched based on position. Example: def student_info(name, age):return f"{name} is {age} years old."print(student_info("Ram", 22)) # ➜ Ram is 22 years old. Here: "Ram" goes to name. 22 goes to age.
    2.5 Keyword Arguments
    1. In keyword arguments, values are passed using parameter names. Example: def student_info(name, age):return f"{name} is {age} years old."print(student_info(age=22, name="Ram")) # ➜ Ram is 22 years old. 📌 Keyword arguments make code clearer when there are many parameters. 📌 When mixing positional and keyword arguments, positional arguments should come first.

3. 📤 Return Value

    3.1 What is return?
    1. return is used to send a result back from a function. Example: def add_numbers(num_1, num_2):return num_1 + num_2result = add_numbers(10, 5) print(result) # ➜ 15 Here, the function returns 15.
    3.2 return vs print()
    1. print() displays output on the screen. return sends a value back so we can store or reuse it. Example using print(): def add_numbers(num_1, num_2):print(num_1 + num_2)add_numbers(10, 5)Output: 15 Example using return: def add_numbers(num_1, num_2):return num_1 + num_2result = add_numbers(10, 5) print(result) # ➜ 15 📌 Use return when the result is needed later. 📌 Use print() when you only want to display output.
    3.3 Function without return
    1. If a function does not return anything, Python automatically returns None. Example: def greet(name):print(f"Hello, {name}!")result = greet("Ram") print(result) # ➜ None 📌 The greeting is printed, but no value is returned.
    3.4 Returning Multiple Values
    1. A function can return multiple values. Example: def get_rectangle_area_perimeter(length, width):area = length * widthperimeter = 2 * (length + width)return area, perimeterarea, perimeter = get_rectangle_area_perimeter(5, 3)print(area) # ➜ 15 print(perimeter) # ➜ 16 📌 Multiple returned values are returned as a tuple and can be unpacked.
    3.5 Function Stops After return
    1. When return runs, the function stops. Example: def check_number(num):if num > 0:return "Positive"return "Zero or Negative"print(check_number(5)) # ➜ Positive 📌 Code after a return statement in the same path does not run.

4. 📝 Docstring

    4.1 What is a Docstring?
    1. A docstring is a short description written inside a function. It explains what the function does. Docstrings are written inside triple quotes """ """ immediately after the function definition. Example: def greet(name):"""Returns a greeting message."""return f"Hello, {name}!"print(greet("Ram")) # ➜ Hello, Ram!
    4.2 Why Use Docstrings?
    1. Docstrings help us explain: - What the function does - What input it needs - What output it returns They make code easier to understand and maintain.
    4.3 Accessing Docstring
    1. We can access a function's docstring using __doc__. Example: def greet(name):"""Returns a greeting message."""return f"Hello, {name}!"print(greet.__doc__) # ➜ Returns a greeting message.
    4.4 Multi-line Docstring
    1. Example: def calculate_area(radius):"""Calculates area of a circle.Parameter:radius: radius of the circleReturns:Area of the circle"""pi = 3.14area = pi * radius ** 2return areaprint(calculate_area(5)) # ➜ 78.5

5. 🌍 Variable Scope

    5.1 What is Variable Scope?
    1. Imagine two employees named "Ram" in different departments. One Ram works in Sales. Another Ram works in IT. When we say "Ram" inside the Sales department, it refers to the Ram from Sales. When we say "Ram" inside the IT department, it refers to the Ram from IT. But, the company name is the same for both departments. Everyone in the company can identify the company name. Local and global variables work in a similar way. A local variable exists only inside its own function, whereas a global variable can be accessed from anywhere in the program. Variable scope means where a variable can be accessed in a program. Main types of scope: - Local scope - Global scope - Nonlocal scope
    5.2 Local Variable
    1. A local variable is created inside a function. It can be used only inside that function. Example: def my_function():x = 5print(x)my_function()Output: 5 Here, x is a local variable.
    5.3 Global Variable
    1. A global variable is created outside a function. It can be read inside a function. Example: x = 10def my_function():print(x)my_function()print(x)Output: 10 10
    5.4 Local and Global Variable with Same Name
    1. Example: x = 10def my_function():x = 5print("Inside function, x =", x)my_function()print("Outside function, x =", x)Output: Inside function, x = 5 Outside function, x = 10 Here: x = 5 is local. x = 10 is global.
    5.5 NameError
    1. If Python cannot find a variable, it gives NameError. Example: def my_function():y = 20my_function()print(y) # ➜ NameError ⚠️ This line gives an error because y is local to the function. 📌 NameError means Python cannot find the variable name.
    5.6 global Keyword
    1. If we want to modify a global variable inside a function, we use global. Example: count = 0def increase_count():global countcount = count + 1increase_count() print(count) # ➜ 1 📌 Use global carefully because it changes variables outside the function.
    5.7 nonlocal Keyword
    1. nonlocal is used in nested functions. It allows the inner function to modify a variable from the outer function. Example: def outer_function():count = 0def inner_function():nonlocal countcount = count + 1inner_function()return countprint(outer_function()) # ➜ 1 📌 nonlocal is mainly used with nested functions.

6. ⚙️ Default Values

    6.1 What is Default Value?
    1. A default value makes a function argument optional. If the argument is not passed, the default value is used. Example: def greet(name="Python"):return f"Hello, {name}!"print(greet()) # ➜ Hello, Python! print(greet("Data Engineer")) # ➜ Hello, Data Engineer!
    6.2 Default Value Example
    1. Example: def calculate_discount(price, discount=10):final_price = price - (price * discount / 100)return final_priceprint(calculate_discount(1000)) # ➜ 900.0 print(calculate_discount(1000, 20)) # ➜ 800.0 Here: - If discount is not passed, 10 is used. - If discount is passed, the passed value is used.
    6.3 Mutable Default Value Problem
    1. We should avoid using mutable data like list or dictionary as default values. Wrong: def add_item(item, item_list=[]):item_list.append(item)return item_list This can create unexpected results because the same list is reused. print(add_item("apple")) # ➜ ["apple"] print(add_item("banana")) # ➜ ["apple", "banana"] 😕 Why did "apple" appear again? Because the same default list is reused between function calls. Better: def add_item(item, item_list=None):if item_list is None:item_list = []item_list.append(item)return item_list 📌 Use None as default when the default value should be a list or dictionary.

Practice QuestionsNot started

  1. 1. Function Basics

    Question 1 of 4

      1.1 Practice writing basic functions:
      1. Write a function get_simple_interest(principal, rate, time) to calculate and return simple interest. Formula: simple_interest = (principal * rate * time) / 100
      2. Write a function get_rectangle_area_perimeter(length, width) to calculate and return area and perimeter of a rectangle.
      3. Write a function is_palindrome(string) to check whether a string is palindrome or not. Return True if it is palindrome, otherwise return False.
      4. Write a function count_vowels(string) to return the number of vowels in a given string.
      5. Write a function get_square_root(num) to return the square root of a given number.
  2. 2. Return Values and Default Values

    Question 2 of 4

      2.1 Practice tasks with return values and default values:
      1. Write a function greet(name, course="Python") that returns: Hello, {name}, Welcome to {course} class. Call this function once by passing your name only, and another time by passing your name and "Data Science".
      2. Write a function get_product_remainder(num_1, num_2) that returns product and remainder of two numbers. If num_2 is 0, return "Cannot divide by zero" for the remainder.
      3. Write a function calculate_discount(price, discount=10) that returns final price after discount.
      4. Write a function get_circle_area(radius, pi=3.14) that returns area of a circle.
      5. Write a function add_item(item, item_list=None) that adds item to a list and returns the updated list.
  3. 3. Scope and Docstring

    Question 3 of 4

      3.1 Practice tasks on scope and docstrings:
      1. Create a global variable x = 10. Create a function that has local variable x = 5 and prints it. Print x outside the function and observe the result.
      2. Write a function with a docstring that explains what the function does. Print the docstring using __doc__.
      3. Write a function that tries to print a local variable outside the function and observe the NameError.
      4. Write a function that modifies a global counter using global keyword.
      5. Write a nested function example that uses nonlocal keyword.
  4. 4. Function Challenge

    Question 4 of 4

      4.1 You have numbers stored in a list: numbers = [1, -3, 0, 2, 0, 7, 10, 8, -1]
      1. Write a function get_data(l, r, x) that finds the sum of numbers from index l to index r, including both l and r.
      2. If 0 appears between index l and index r, use value x instead of 0 while calculating the sum. Example: l = 2, r = 6, x = 5. Items from index 2 to 6 are: 0, 2, 0, 7, 10. Normal sum with zeros = 19. Since there are two zeros, replace them with 5 and add 5 + 5. Final result = 19 + 5 + 5 = 29. Output: 29