Author: Pooja Kotwani

  • Python Exception Handling

    In Python programming, errors can be broadly classified into two types: Syntax Errors and Exceptions. Errors halt the program execution, while exceptions arise from unexpected events that disrupt the usual program flow but may still be handled to allow the program to continue.

    Common Types of Python Exceptions

    Python has several built-in exceptions for handling errors that may occur during code execution. Here are some frequent ones:

    • SyntaxError: Raised when there is a syntax issue, like a missing colon or an unmatched parenthesis.
    • TypeError: Occurs when an operation is applied to an inappropriate data type, such as adding an integer to a string.
    • NameError: Triggered when a variable or function name is not found.
      IndexError: Occurs when an index is out of range in a list or other sequence.
    • KeyError: Raised when a key is not found in a dictionary.
    • ValueError: Occurs when a function receives an argument with the right type but an inappropriate value.
    • AttributeError: Triggered when an attribute or method is not found on an object.
    • IOError: Raised for input/output errors, such as issues reading or writing a file.
    • ZeroDivisionError: Occurs when dividing a number by zero.
    • ImportError: Triggered when a module fails to import.
    Difference Between Syntax Errors and Exceptions

    Syntax Errors: Caused by improper syntax and will terminate the program.

    amount = 5000
    if amount > 1000
        print("Eligible to make a purchase")

    Output:

    SyntaxError: expected ':'

    Exceptions: These arise from runtime errors in syntactically correct code, which can change the program’s normal flow.

    value = 100
    result = value / 0
    print(result)

    Output:

    ZeroDivisionError: division by zero

    Handling Exceptions with try and except

    In Python, you use try and except blocks to catch and handle exceptions.

    Example:

    data = [1, 2, 3]
    try:
        print("Second element:", data[1])
        print("Fourth element:", data[3])
    except IndexError:
        print("An error occurred: Index out of range")

    Output:

    Second element: 2
    An error occurred: Index out of range

    Catching Specific Exceptions

    You can use multiple except clauses to handle different types of exceptions.

    def calculate(a):
        if a < 5:
            result = a / (a - 4)
        print("Result:", result)
    
    try:
        calculate(3)
        calculate(5)
    except ZeroDivisionError:
        print("Division by zero error occurred and handled")
    except NameError:
        print("NameError occurred and handled")

    Output:

    Division by zero error occurred and handled
    try with else Clause

    The else clause runs only if the try block does not raise any exceptions.

    name = 'Sam'
    age = 25
    print(f"Hello, My name is {name} and I'm {age} years old.")

    Output:

    -5.0
    Division resulted in zero denominator

    finally Clause in Python

    The finally block is always executed after try and except blocks, regardless of whether an exception occurs.

    num = int(input("Enter a value: "))
    add = num + 5
    print("The sum is %d" % add)

    Output:

    Cannot divide by zero
    Execution complete

    Raising Exceptions

    The raise statement allows you to force a specific exception. You can specify an error message when raising an exception.

    try:
        raise NameError("This is a custom NameError")
    except NameError:
        print("A NameError occurred")
        raise

    Output:

    A NameError occurred
    Traceback (most recent call last):
      ...
    NameError: This is a custom NameError
    Advantages of Exception Handling
    • Improves program reliability: Helps in avoiding program crashes from unexpected errors.
    • Simplifies error handling: Keeps error management separate from main logic, making the code more readable.
    • Produces cleaner code: Reduces complex conditional checks for error detection.
    • Eases debugging: Exception traceback indicates the error location, simplifying debugging.
    Disadvantages of Exception Handling
    • Performance overhead: Handling exceptions can be slower than using conditional checks.
    • Increases code complexity: Multiple exceptions can add complexity, especially with varied handling methods.
    • Potential security risks: Unhandled exceptions might reveal sensitive information or create vulnerabilities, so careful handling is essential.

    User-defined Exceptions in Python with Examples

    Custom exceptions in Python with practical examples is as follows.

    class CustomError(Exception):
        pass
    
    raise CustomError("Example of Custom Exceptions in Python")

    Output:

    CustomError: Example of Custom Exceptions in Python

    Python raises errors and exceptions when something goes wrong, potentially causing abrupt program termination. However, with try-except blocks, Python provides robust exception handling to prevent such interruptions. Common exceptions include IndexErrorImportErrorIOErrorZeroDivisionErrorTypeError, and FileNotFoundError.

    Creating User-Defined Exceptions in Python

    Custom exceptions should inherit from the Exception class, directly or indirectly. While it’s not required, custom exceptions often follow the naming convention of ending with “Error,” similar to Python’s standard exceptions.

    Example:

    # A Python program to create a user-defined exception
    # MyError class inherits from Exception
    
    class MyError(Exception):
        # Constructor to initialize the error value
        def __init__(self, value):
            self.value = value
    
        # __str__ method to return the error message
        def __str__(self):
            return repr(self.value)
    
    try:
        raise MyError(3 * 2)
    
    # Handling the exception
    except MyError as error:
        print('A new exception occurred:', error.value)

    Output:

    Customizing Exception Classes
    For more details about Exception class, try running:
    
    python
    Copy code
    Customizing Exception Classes

    For more details about Exception class, try running:

    help(Exception)

    Example 1: User-Defined Exception with Multiple Inheritance

    Below is an example with a base class Error inherited by user-defined classes to handle specific custom exceptions.

    # Defining a base class for exceptions
    class Error(Exception):
        """Base class for other exceptions"""
        pass
    
    class ZeroDivisionErrorCustom(Error):
        """Raised when the input value is zero"""
        pass
    
    try:
        num = int(input("Enter a number: "))
        if num == 0:
            raise ZeroDivisionErrorCustom
    except ZeroDivisionErrorCustom:
        print("Input value is zero, please try again!")

    Output:

    Enter a number: 0
    Input value is zero, please try again!

    Example 2: Deriving Errors from Superclass Exception

    When a module requires specific exception handling, a base class for those exceptions can be defined. Additional subclasses allow for distinct error conditions.

    # Define a base exception class
    class Error(Exception):
        pass
    
    class TransitionError(Error):
        # Raised when an invalid state transition occurs
        def __init__(self, prev, next, msg):
            self.prev = prev
            self.next = next
            self.msg = msg
    
    try:
        raise TransitionError(2, 6, "Transition Not Allowed")
    
    except TransitionError as error:
        print('Exception occurred:', error.msg)

    Output:

    Exception occurred: Transition Not Allowed
    Using Standard Exceptions as a Base Class

    The following example demonstrates using RuntimeError as a base class for custom exceptions, like NetworkError.

    # NetworkError is derived from RuntimeError
    class NetworkError(RuntimeError):
        def __init__(self, message):
            self.message = message
    
    try:
        raise NetworkError("Network connection lost")
    
    except NetworkError as e:
        print(e.message)

    Output:

    Network connection lost
    Advantages of Exception Handling
    • Reliability: Manages unexpected errors, ensuring program stability.
    • Simplified Error Management: Separates error-handling code from main logic.
    • Cleaner Code: Avoids nested conditionals by handling errors systematically.
    • Debugging Ease: Tracebacks help in pinpointing error locations quickly.
    Disadvantages of Exception Handling
    • Performance Overhead: Handling exceptions is slightly slower than conditional checks.
    • Complexity: Can increase code complexity, especially with multiple exception types.
    • Security Risks: Improperly managed exceptions may expose sensitive information, so they must be handled with caution.

    Built-in Exceptions in Python

    In Python, all instances must be derived from the BaseException class, and no two unrelated exception classes are considered equivalent, even if they share the same name. The Python interpreter or built-in functions can raise these exceptions.

    You can view built-in exceptions, functions, and attributes using the locals() function:

    >>> locals()['__builtins__']
    Base Classes

    The following exceptions serve primarily as base classes for other exceptions:

    1. BaseException: This is the base class for all built-in exceptions. It is not intended for direct inheritance by user-defined classes, which should inherit from Exception. This class uses str() to create a string representation of the exception based on its arguments. An empty string is returned if there are no arguments.

    Attributes:

    • args: A tuple of arguments passed to the exception constructor.
    • with_traceback(tb): Sets tb as the new traceback for the exception and returns the exception object.
    try:
        ...
    except SomeException:
        tb = sys.exc_info()[2]
        raise OtherException(...).with_traceback(tb)

    Exception: This is the base class for all non-system-exiting exceptions. User-defined exceptions should inherit from this class.

    2. ArithmeticError: Base class for exceptions related to arithmetic operations, such as:

    • OverflowError
    • ZeroDivisionError
    • FloatingPointError

    Example:

    try:
        a = 10 / 0
        print(a)
    except ArithmeticError:
        print("Arithmetic exception occurred.")

    Output:

    Arithmetic exception occurred.

    3. BufferError: Raised when an operation related to buffers cannot be completed.

    4. LookupError: Base class for exceptions raised when a key or index used on a mapping or sequence is invalid. Examples include:

    • KeyError
    • IndexError

    Example:

    try:
        a = [1, 2, 3]
        print(a[3])
    except LookupError:
        print("Index out of range.")

    Output:

    Index out of range.
    Concrete Exceptions

    Here are some of the more common exceptions:

    • AssertionError: Raised when an assert statement fails.
    class MyClass:
        pass
    
    obj = MyClass()
    print(obj.some_attribute)

    Output:

    AttributeError: 'MyClass' object has no attribute 'some_attribute'
    • EOFError: Raised when input() reaches the end of file condition.
    while True:
    data = input('Enter name: ')
    print('Hello', data)

    If an EOF is encountered, the interpreter will raise:

    EOFError: EOF when reading a line
    • FloatingPointError: Raised for floating-point operation failures when Python is configured to raise this error.
    • GeneratorExit: Raised when a generator or coroutine is closed.
    def generator():
        try:
            yield 1
        except GeneratorExit:
            print('Generator is exiting')
    
    g = generator()
    next(g)
    g.close()

    Output:

    ImportError: No module named 'non_existent_module'
    • IndexError: Raised for sequence indexes out of range.
    lst = [1, 2]
    print(lst[3])

    Output:

    IndexError: list index out of range
    • KeyError: Raised when a mapping (dictionary) key is not found
    dct = {'a': 1}
    print(dct['b'])

    Output:

    KeyError: 'b'
    • KeyboardInterrupt: Raised when the user interrupts execution (e.g., by pressing Ctrl+C).
    try:
        input("Press Ctrl+C to interrupt.")
    except KeyboardInterrupt:
        print("Execution interrupted by user.")
    • MemoryError: Raised when an operation runs out of memory.
    • NameError: Raised when a local or global name is not found.
    print(unknown_variable)

    Output:

    NameError: name 'unknown_variable' is not defined
    • NotImplementedError: Raised when an abstract method in a user-defined class is not implemented in derived classes.
    • OSError: Raised for operating system-related errors.
    • OverflowError: Raised for arithmetic operations that exceed limits.
    • RecursionError: Raised when the maximum recursion depth is exceeded.
    • ReferenceError: Raised when a weak reference proxy is used to access a referent that has been garbage-collected.
    • RuntimeError: Raised for errors that do not fall into any other category.
    • StopIteration: Raised to indicate the end of an iterator.
    • SyntaxError: Raised when a syntax error is encountered.
    eval('x === y')

    Output:

    SyntaxError: invalid syntax
    • SystemError: Raised for internal interpreter errors.
    • SystemExit: Raised by the sys.exit() function.
    • TypeError: Raised when an operation is applied to an object of inappropriate type.
    5 + 'a'

    Output:

    TypeError: unsupported operand type(s) for +: 'int' and 'str'
    • UnboundLocalError: A subclass of NameError, raised when a reference is made to a local variable that has not been assigned.
    • UnicodeError: Raised for Unicode-related encoding or decoding errors.
    • ValueError: Raised when a function receives an argument of correct type but invalid value.
    int('a')

    Output:

    ValueError: invalid literal for int() with base 10: 'a'
    • ZeroDivisionError: Raised when division or modulo by zero occurs.
    print(1 / 0)

    Output:

    ZeroDivisionError: division by zero

    In Python, errors can be classified as syntax errors and exceptions. Syntax errors occur due to incorrect syntax, stopping the program’s execution immediately. Exceptions, however, are raised by specific events during execution, changing the program’s normal flow.

    Some commonly encountered exceptions include:

    • IOError: Raised when a file operation (such as open) fails.
    • KeyboardInterrupt: Raised when the user interrupts program execution, typically by pressing Ctrl+C.
    • ValueError: Occurs when a function receives an argument of the right type but inappropriate value.
    • EOFError: Raised when the input() function hits an end-of-file condition.
    • ImportError: Raised when an import statement fails to find the specified module.

    Try-Except in Python

    The try and except statements help manage exceptions in Python. The try block contains the code that may throw an exception, and the except block handles the exception if it occurs.

    try:
        # Code to execute
    except:
        # Code to execute if an error occurs
    How try Works 

    1. Python executes the code within the try block first.
    2. If no exception is raised, the except block is skipped.
    3. If an exception occurs, Python jumps to the except block.
    4. If the exception is not handled, it will propagate to any outer try blocks, and, if unhandled, will stop execution.
    5. Multiple except blocks can be used to handle different exceptions.

    Example 1: Code runs without any exceptions, so only the try block executes.

    def divide(x, y):
        try:
            result = x // y
            print("The result is:", result)
        except ZeroDivisionError:
            print("Error: Division by zero is undefined.")
    
    divide(10, 2)

    Output:

    The result is: 5
    Catching Specific Exceptions with as

    You can also catch and display the specific type of error that occurs by using Exception as.

    def divide(x, y):
        try:
            result = x // y
            print("The result is:", result)
        except Exception as e:
            print("An error occurred:", e)
    
    divide(10, 'A')
    divide(10, 0)

    Output:

    An error occurred: unsupported operand type(s) for //: 'int' and 'str'
    An error occurred: integer division or modulo by zero
    Using else with tryexcept

    In Python, you can use an else clause with tryexcept blocks. The else block executes only if no exceptions are raised in the try block.

    try:
        # Code to execute
    except:
        # Code to execute if an error occurs
    else:
        # Code to execute if no exception occurs

    Example:

    def safe_divide(a, b):
        try:
            c = (a + b) // (a - b)
        except ZeroDivisionError:
            print("Error: Division by zero.")
        else:
            print("The result is:", c)
    
    safe_divide(5, 3)
    safe_divide(3, 3)

    Output:

    The result is: 4
    Error: Division by zero.
    finally Keyword in Python

    The finally block in Python is always executed after the try and except blocks, whether or not an exception occurs. It is often used for cleanup actions.

    try:
        # Code to execute
    except:
        # Code to execute if an error occurs
    else:
        # Code to execute if no exception occurs
    finally:
        # Code that always executes

    Example:

    try:
        k = 10 // 0  # Raises a ZeroDivisionError
        print(k)
    except ZeroDivisionError:
        print("Error: Cannot divide by zero.")
    finally:
        print("This block always executes.")

    Output:

    Error: Cannot divide by zero.
    This block always executes.
  • Python OOPs Concepts

    Object-Oriented Programming (OOP) is a fundamental concept in Python that enables developers to create modular, maintainable, and scalable applications. By mastering the core OOP principles—classes, objects, inheritance, encapsulation, polymorphism, and abstraction—programmers can fully leverage Python’s capabilities to design effective solutions for complex problems.

    What is Object-Oriented Programming in Python?

    In Python, Object-Oriented Programming (OOP) is a programming paradigm that uses objects and classes. This approach represents real-world entities through concepts like inheritance, polymorphism, encapsulation, and abstraction. The primary objective of OOP is to bind data and functions that operate on that data into a single unit, which restricts access to this data from other parts of the code.

    OOP Concepts in Python

    1. Class in Python
    2. Objects in Python
    3. Polymorphism in Python
    4. Encapsulation in Python
    5. Inheritance in Python
    6. Data Abstraction in Python

    Python Class

    A class is a blueprint from which objects are created. It groups related attributes and methods. For example, to manage a collection of dogs with attributes like breed and age, creating a class can help organize this information effectively.

    Key Points on Python Class:

    • Classes are created using the class keyword.
    • Attributes are variables within a class.
    • Attributes can be accessed using the dot (.) operator. For example: MyClass.my_attribute

    Syntax:

    class ClassName:
    # Statements
    pass

    Example:

    class Animal:
    pass

    Python Objects

    An object is an instance of a class and represents entities with a state and behavior. For example, an integer, string, or list in Python is an object.

    An object consists of:

    • State: Defined by its attributes.
    • Behavior: Defined by its methods.
    • Identity: Provides a unique identity for each object.

    To understand these, let’s revisit the Animal class:

    class Animal:
    def __init__(self, species, age):
        self.species = species
        self.age = age

    Here, species and age represent the state, while behaviors might include methods that describe the animal’s actions.

    Creating an Object

    lion = Animal("Lion", 5)
    The Python self

    In Python, every method must have self as the first parameter, which represents the instance of the class.

    The Python __init__ Method

    The __init__ method in Python is similar to constructors in other languages. It initializes an object’s attributes.

    Example with Class and Instance Attributes:

    class Car:
        # Class attribute
        category = "vehicle"
    
        def __init__(self, make):
            self.make = make
    
    # Object instantiation
    car1 = Car("Toyota")
    car2 = Car("Honda")
    
    # Accessing class attributes
    print(f"Car1 is a {car1.category}")
    print(f"Car2 is also a {car2.category}")
    
    # Accessing instance attributes
    print(f"Car1 make is {car1.make}")
    print(f"Car2 make is {car2.make}")

    Output:

    Car1 is a vehicle
    Car2 is also a vehicle
    Car1 make is Toyota
    Car2 make is Honda

    Python Inheritance

    Inheritance allows one class (child class) to inherit properties and methods from another (parent class). This promotes code reuse and a logical structure.

    Types of Inheritance in Python:

    1. Single Inheritance: One class inherits from a single parent class.
    2. Multilevel Inheritance: One class is derived from another, which is also derived from another class.
    3. Hierarchical Inheritance: Multiple classes inherit from one parent class.
    4, Multiple Inheritance: One class inherits from multiple classes.

    Example of Inheritance:

    # Parent class
    class Person:
        def __init__(self, name, idnumber):
            self.name = name
            self.idnumber = idnumber
    
        def display(self):
            print(self.name)
            print(self.idnumber)
    
    # Child class
    class Employee(Person):
        def __init__(self, name, idnumber, salary, position):
            super().__init__(name, idnumber)
            self.salary = salary
            self.position = position
    
        def show_details(self):
            print(f"Name: {self.name}")
            print(f"ID Number: {self.idnumber}")
            print(f"Position: {self.position}")
    
    emp1 = Employee("Alice", 101, 50000, "Manager")
    emp1.display()
    emp1.show_details()

    Output:

    Alice
    101
    Name: Alice
    ID Number: 101
    Position: Manager

    Python Polymorphism

    Polymorphism allows methods to operate on objects of various types. Here’s an example using different types of birds:

    class Bird:
        def description(self):
            print("This is a bird.")
    
    class Sparrow(Bird):
        def description(self):
            print("Sparrows can fly.")
    
    class Penguin(Bird):
        def description(self):
            print("Penguins cannot fly.")
    
    bird1 = Sparrow()
    bird2 = Penguin()
    
    bird1.description()
    bird2.description()

    Output:

    Sparrows can fly.
    Penguins cannot fly.

    Python Encapsulation

    Encapsulation wraps data and methods into a single unit, restricting access to certain components. For instance, private attributes can only be modified within their class.

    Example of Encapsulation:

    class BankAccount:
        def __init__(self):
            self.__balance = 1000  # Private attribute
    
        def deposit(self, amount):
            self.__balance += amount
    
        def get_balance(self):
            return self.__balance
    
    account = BankAccount()
    account.deposit(500)
    print("Balance:", account.get_balance())

    Output:

    Balance: 1500

    Data Abstraction

    Data abstraction hides implementation details from the user and provides only the essential features. This can be achieved using abstract classes or private attributes.

    Example of Data Abstraction

    class Rectangle:
        def __init__(self, length, width):
            self.__length = length  # Private attribute
            self.__width = width    # Private attribute
    
        def area(self):
            return self.__length * self.__width
    
        def perimeter(self):
            return 2 * (self.__length + self.__width)
    
    # Creating an object
    rect = Rectangle(5, 3)
    
    # Accessing methods
    print(f"Area: {rect.area()}")
    print(f"Perimeter: {rect.perimeter()}")
    
    # Uncommenting the following line will raise an AttributeError
    # print(rect.__length)

    Output:

    Area: 15
    Perimeter: 16

  • Python Functions

    Python Functions

    A function in Python is a block of code designed to perform a specific task. By grouping repetitive tasks into functions, you can reuse the same code for different inputs, improving both efficiency and maintainability.

    Benefits of Using Functions
    • Improves Code Readability: By abstracting complex tasks into named functions, the main code becomes cleaner and easier to read.
    • Increases Code Reusability: Once a function is written, it can be called multiple times without needing to rewrite the same code.

    Syntax for Python Functions

    def function_name(parameters):
    """Docstring (optional)"""
    # function body
    return value
    Types of Functions in Python

    There are two main types of functions in Python:

    1. Built-in Functions: These are pre-defined functions provided by Python (e.g., print(), len(), input()).
    2. User-defined Functions: Functions that you define yourself based on your needs.

    Creating and Calling a Function

    In Python, functions are created using the def keyword. After defining the function, it can be called by its name followed by parentheses.

    Example of a Simple Function:

    def greet():
        print("Hello, Welcome to Python!")
    
    greet()  # Function call

    Output:

    Hello, Welcome to Python!

    Example: Function to Add Two Numbers:

    def add(a: int, b: int) -> int:
        """Returns the sum of two numbers."""
        return a + b
    
    # Function call with arguments
    result = add(5, 10)
    print(f"Sum of 5 and 10 is {result}")

    Output:

    Sum of 5 and 10 is 15
    Python Function with Return

    Functions can return values using the return keyword. This allows you to send back the result of the function to the caller.

    Example:

    def square(num):
        return num * num
    
    print(square(4))  # Function call

    Output:

    16
    Types of Function Arguments

    Python supports different types of arguments that can be passed to functions:

    1. Default Arguments: Arguments that assume a default value if not provided in the function call.

    Example:

    def greet(name, greeting="Hello"):
        print(f"{greeting}, {name}!")
    
    greet("John")  # Uses default greeting
    greet("Alice", "Good Morning")  # Custom greeting

    Output:

    Hello, John!
    Good Morning, Alice!

    2. Keyword Arguments: Arguments where you explicitly define the name of the parameter.

    Example:

    def student_info(name, age):
        print(f"Name: {name}, Age: {age}")
    
    student_info(age=20, name="John")  # Using keyword arguments

    Output:

    Name: John, Age: 20

    3. Positional Arguments: Arguments are assigned based on their position in the function call.

    Example:

    def introduce(name, age):
        print(f"Hi, I am {name}, and I am {age} years old.")
    
    introduce("Alice", 25)  # Correct order
    introduce(25, "Alice")  # Incorrect order

    Output:

    Hi, I am Alice, and I am 25 years old.
    Hi, I am 25, and I am Alice years old.

    4. Arbitrary Arguments (*args and **kwargs):

    • *args: Used to pass a variable number of non-keyword arguments.
    • **kwargs: Used to pass a variable number of keyword arguments.

    Example with *args:

    def print_args(*args):
        for arg in args:
            print(arg)
    
    print_args("Hello", "Welcome", "to", "Python")

    Output:

    Hello
    Welcome
    to
    Python
    Docstrings

    Docstrings provide a description of the function’s purpose and are considered good practice. They are written within triple quotes right after the function definition.

    Example:

    def even_odd(num):
        """Checks if a number is even or odd."""
        if num % 2 == 0:
            print("Even")
        else:
            print("Odd")
    
    # Accessing docstring
    print(even_odd.__doc__)

    Output:

    Checks if a number is even or odd.
    Recursive Functions

    A recursive function is one that calls itself. It is useful for problems that can be broken down into smaller instances of the same problem.

    Example: Factorial Calculation:

    def factorial(n):
        if n == 0:
            return 1
        else:
            return n * factorial(n - 1)
    
    print(factorial(5))  # Output: 120

    Output:

    120
    Passing by Reference and Value

    In Python, when you pass an object to a function, you are passing a reference to the object, not a copy. So, changes made to the object inside the function will affect the original object.

    Example (Passing a List by Reference):

    def modify_list(lst):
        lst[0] = 100
    
    lst = [1, 2, 3]
    modify_list(lst)
    print(lst)  # List is modified

    Output:

    [100, 2, 3]

    Python def Keyword

    The def keyword in Python is used to define functions, which are reusable blocks of code designed to perform specific tasks. It is used before a function name, allowing the creation of a user-defined function. The def keyword is essential for structuring Python code logically by grouping related statements under a function name.

    Syntax of def in Python

    def function_name():
    # function statements
    Purpose of def Keyword

    In Python, def is not only for defining general functions but also for creating class methods and special member functions like __init__(). Using def helps with code reusability, letting developers encapsulate specific logic into functions instead of rewriting code repeatedly.

    Applications of def in Python

    Below are examples illustrating the various ways to use the def keyword in Python:

    Defining a Simple Function with No Arguments

    Example

    def greet():
        print("Hello, Python!")
    
    greet()

    Output:

    Hello, Python!
    Creating a Function for Subtraction

    This function, subtract, calculates the difference between two numbers.

    def subtract(x, y):
        return x - y
    
    result = subtract(15, 5)
    print("The difference is:", result)
    First Class functions in Python

    In programming, first-class objects are treated uniformly, allowing them to be stored in data structures, passed as arguments, and used in control structures. A language that treats functions as first-class objects supports first-class functions. Python, as an example, treats functions as first-class citizens.

    Properties of First-Class Functions
    • Functions are instances of the Object type.
    • Functions can be stored in variables.
    • Functions can be passed as parameters to other functions.
    • Functions can be returned from other functions.
    • Functions can be stored in data structures like lists or dictionaries.

    Examples:

    def greet(text):
        return text.lower()
    
    print(greet("HELLO"))
    
    whisper = greet
    
    print(whisper("HELLO"))
    Assign Function to a Variable in Python

    This article explains how to assign a function to a variable in Python. By assigning a function to a variable, we can call that function using the variable name multiple times, enhancing code reusability.

    Implementation

    To assign a function to a variable, simply use the function name without parentheses (). If parentheses are used, it will execute the function immediately, returning None if no return value is provided.

    Syntax:

    def func():
        # function body
    
    variable = func  # assigning function to variable
    variable()       # calling the function through variable

    Example:

    def greet():
        print("Welcome to Python!")
    
    # Assigning the function to a variable
    message = greet
    
    # Calling the function using the variable
    message()
    message()

    Output:

    Welcome to Python!
    Welcome to Python!

    Python User defined functions

    A function is a set of instructions designed to take inputs, perform specific calculations, and return an output. The purpose of a function is to consolidate tasks that are commonly or repeatedly performed so that we can call the function instead of duplicating code. Python provides built-in functions, such as print(), but we can also define our own functions, known as user-defined functions.

    Python User-defined Functions

    All functions that we write are categorized as user-defined functions. Below are the steps for creating user-defined functions in Python:

    • Use the def keyword to define a function.
    • An indented block of statements follows the function name and arguments, forming the function body.
    def function_name():
    # statements

    Example

    # Defining a function
    def show_message():
        print("This is a custom function.")
    
    # Calling the function
    show_message()

    Output:

    This is a custom function.
    Python Parameterized Function

    A function can accept arguments or parameters as inputs within the parentheses following the function name.

    Example:

    def check_even_odd(num):
        if num % 2 == 0:
            print("Even")
        else:
            print("Odd")
    
    # Calling the function
    check_even_odd(4)
    check_even_odd(7)

    Output:

    Even
    Odd
    Python Default Arguments

    A default argument has a value that is assigned if no argument is provided when the function is called.

    Example: Here, we call display_info() with a single argument.

    # Function with a default argument
    def display_info(name, age=25):
        print("Name:", name)
        print("Age:", age)
    
    # Calling the function
    display_info("Alice")

    Output:

    Name: Alice
    Age: 25
    Python Keyword Arguments

    Keyword arguments allow the caller to specify argument names with values, so the order of arguments does not need to be memorized.

    Example:

    def introduce(first_name, last_name):
        print(first_name, last_name)
    
    # Calling with keyword arguments
    introduce(first_name="John", last_name="Doe")
    introduce(last_name="Doe", first_name="John")

    Output:

    John Doe
    John Doe
    Python Variable-Length Arguments

    We can have variable numbers of arguments, both positional (*args) and keyworded (**kwargs).

    Example:

    def show_args(*args):
        for arg in args:
            print(arg)
    
    def show_kwargs(**kwargs):
        for key, value in kwargs.items():
            print(f"{key} == {value}")
    
    # Calling the functions
    print("Result of *args:")
    show_args("Hello", "This", "is", "Python")
    
    print("\nResult of **kwargs:")
    show_kwargs(name="John", age=30, country="USA")

    Output:

    Result of *args:
    Hello
    This
    is
    Python
    
    Result of **kwargs:
    name == John
    age == 30
    country == USA
    Pass by Reference or Pass by Value in Python

    In Python, every variable name is a reference. When a variable is passed to a function, a new reference to the object is created. We can use Python’s id() function to confirm this.

    Example:

    def show_id(value):
        print("Value inside function:", value, "id:", id(value))
    
    # Driver code
    num = 42
    print("Value outside function:", num, "id:", id(num))
    show_id(num)

    Output:

    Value outside function: 42 id: 139865623584656
    Value inside function: 42 id: 139865623584656
    Python Function with Return Value

    Sometimes a function needs to return a value to the caller, which can be achieved using the return statement.

    Example:

    def sum_values(a, b):
        return a + b
    
    def check_true(condition):
        return bool(condition)
    
    # Calling functions
    result = sum_values(5, 3)
    print("Result of sum function:", result)
    
    result = check_true(3 > 1)
    print("Result of check_true function:", result)

    Output:

    Result of sum function: 8
    Result of check_true function: True
    Defining a Python function at runtime

    In Python, we can create a function at runtime and execute it using FunctionType(). This approach involves importing the types module, using compile() with exec mode, and then defining the function at runtime with FunctionType().

    Example 1: Function to Print “Hello, Python!

    # Importing the module
    from types import FunctionType
    
    # Defining the function during runtime
    code_obj = compile('def hello_func(): return "Hello, Python!"', "<string>", "exec")
    runtime_func = FunctionType(code_obj.co_consts[0], globals(), "hello_func")
    
    # Calling the function
    print(runtime_func())

    Output:

    Hello, Python!

    Python Built in Functions

    Python is versatile in handling system scripting, software development, and web development (server-side). It can manage workflows, connect to databases, modify files, handle big data, and perform advanced mathematical tasks.

    The syntax in Python is straightforward and English-like, allowing developers to write concise code compared to other languages. Python’s interpreter system enables code execution immediately upon writing. Python also provides numerous built-in functions that make coding simpler.

    In this guide, you will discover Python’s built-in functions, exploring their purposes and applications. Here’s a rundown of some of the most commonly used built-in functions in Python:

    • abs(): Returns the absolute value of a number.
    abs(-5)
    # Output: 5
    • aiter(): Creates an asynchronous iterator from an asynchronous iterable.
    # Example: (used within an async function)
    async for item in aiter(async_iterable):
        print(item)
    • all(): Returns True if all elements in an iterable are True.
    all([True, True, False])
    # Output: False
    • any(): Returns True if any element in an iterable is True.
    any([False, True, False])
    # Output: True
    • anext(): Retrieves the next item from an asynchronous iterator.
    # Example: (used within an async function)
    await anext(async_iterator)
    • ascii(): Returns a string with only ASCII characters, escaping non-ASCII characters.
    ascii("éclair")
    # Output: "'\\xe9clair'"
    • bin(): Converts an integer to a binary string.
    bin(10)
    # Output: '0b1010'
    • bool(): Converts a value to a Boolean (True or False).
    bool(0)
    # Output: False
    • breakpoint(): Invokes a debugger at the call site.
    breakpoint()
    # (opens debugger)
    • bytearray(): Returns a mutable byte array from a sequence of bytes.
    bytearray([65, 66, 67])
    # Output: bytearray(b'ABC')
    • bytes(): Creates an immutable bytes object.
    bytes([65, 66, 67])
    # Output: b'ABC'
    • callable(): Checks if an object appears callable.
    callable(len)
    # Output: True
    • chr(): Returns a character for a given Unicode code.
    chr(97)
    # Output: 'a'
    • classmethod(): Converts a function to a class method.
    class MyClass:
        @classmethod
        def example(cls):
            return "This is a class method."
    
    MyClass.example()
    # Output: 'This is a class method.'
    • compile(): Compiles source code into a code object.
    code_obj = compile("x = 5", "<string>", "exec")
    exec(code_obj)
    # Output: (x is set to 5)
    • complex(): Creates a complex number.
    Enter a number: 100
    Type before conversion: <class 'str'>
    Type after conversion: <class 'int'>
    • delattr(): Deletes an attribute from an object.
    class MyClass:
        x = 10
    
    delattr(MyClass, 'x')
    • dict(): Creates a dictionary.
    dict(name="John", age=30)
    # Output: {'name': 'John', 'age': 30}
    • dir(): Returns a list of attributes and methods of an object.
    dir([])
    # Output: (list of list methods and attributes)
    • divmod(): Returns the quotient and remainder of division as a tuple.
    divmod(7, 3)
    # Output: (2, 1)
    • enumerate(): Adds a counter to an iterable, returning an enumerate object.
    list(enumerate(['a', 'b', 'c']))
    # Output: [(0, 'a'), (1, 'b'), (2, 'c')]
  • Loops in Python – For, While and Nested Loops

    Loops in Python

    In Python, loops are essential structures used to execute a block of code repeatedly. There are two main types of loops: the for loop and the while loop. Both loops serve similar functions but differ in their syntax and how they check conditions. This article explains how these loops work with examples.

    While Loop in Python

    while loop is used to repeatedly execute a block of code as long as a specified condition remains true. When the condition becomes false, the loop stops, and execution moves to the next line after the loop.

    Syntax:

    while condition:
    statement(s)

    Example:

    counter = 0
    while counter < 3:
        counter += 1
        print("Hello World")

    Output:

    Hello World
    Hello World
    Hello World

    Using the else Clause with a While Loop: You can attach an else statement to a while loop. This block will execute after the loop completes, unless the loop is exited prematurely with a break or an exception is raised.

    Example:

    counter = 0
    while counter < 3:
        counter += 1
        print("Hello World")
    else:
        print("Loop has finished")

    Output:

    Hello World
    Hello World
    Hello World
    Loop has finished

    Infinite While Loop: An infinite loop occurs when the condition always evaluates to true, resulting in continuous execution. Here’s an example:

    counter = 0
    while counter == 0:
        print("This will run forever!")

    Output:

    Amount: $150.75
    For Loop in Python

    The for loop in Python is used to iterate over a sequence such as a list, tuple, or string. It is ideal for traversing through elements in these data structures.

    Syntax:

    for element in sequence:
    statement(s)

    Example:

    n = 5
    for i in range(n):
        print(i)

    Output:

    0
    1
    2
    3
    4

    Iterating Over Different Data Structures: The for loop can also be used to iterate over various data structures, like lists, tuples, and strings.

    # List iteration
    fruits = ["apple", "banana", "cherry"]
    for fruit in fruits:
        print(fruit)
    
    # Tuple iteration
    colors = ("red", "green", "blue")
    for color in colors:
        print(color)
    
    # String iteration
    word = "Python"
    for letter in word:
        print(letter)
    
    # Dictionary iteration
    student_ages = {'Alice': 23, 'Bob': 25, 'Charlie': 22}
    for name, age in student_ages.items():
        print(f"{name}: {age}")

    Output:

    apple
    banana
    cherry
    
    red
    green
    blue
    
    P
    y
    t
    h
    o
    n
    
    Alice: 23
    Bob: 25
    Charlie: 22

    Using the Index in a For Loop: You can also iterate over the index of a sequence using range(len(sequence)). This allows access to each element’s index in the loop.

    fruits = ["apple", "banana", "cherry"]
    for index in range(len(fruits)):
        print(f"Index {index}: {fruits[index]}")

    Output:

    Index 0: apple
    Index 1: banana
    Index 2: cherry

    Using the else Clause with a For Loop: As with the while loop, the else block in a for loop executes when the loop completes normally (i.e., without interruption by break).

    Example:

    fruits = ["apple", "banana", "cherry"]
    for fruit in fruits:
        print(fruit)
    else:
        print("All fruits have been printed.")

    Output:

    apple
    banana
    cherry
    All fruits have been printed.
    Nested Loops in Python

    In Python, you can place one loop inside another, which is referred to as a nested loop. A for loop can be nested inside another for loop, and similarly, a while loop can be nested inside another while loop.

    Nested For Loop Syntax:

    for outer_var in sequence:
    for inner_var in sequence:
        statement(s)

    Nested While Loop Syntax:

    while condition:
    while condition:
        statement(s)
    statement(s)

    Example of a nested for loop creating a pattern:

    for i in range(1, 5):
    for j in range(i):
        print(i, end=' ')
    print()

    Output:

    1
    2 2
    3 3 3
    4 4 4 4

    Loop Control Statements

    Loop control statements modify the flow of execution within loops. Python has three primary control statements:

    1. continue: Skips the current iteration and moves to the next iteration.
    2. break: Exits the loop immediately.
    3. pass: Does nothing and moves to the next iteration.

    1. Using continue: This code skips the iteration when encountering a specific letter:

    for letter in "programming":
    if letter == "r":
        continue
    print(letter)

    Output:

    p
    o
    g
    a
    m
    m
    i
    n
    g

    Output:

    p

    Using pass: The pass statement is used when you want an empty loop body or placeholder for future code.

    for letter in "programming":
        pass
    print("Loop completed.")

    Output:

    Loop completed.

    Using breakThe break statement is used to exit a loop immediately when a specified condition is met. It terminates the loop’s execution and transfers control to the statement following the loop.

    Example with break:
    This code stops the loop when a specific letter is encountered.

    # Example of break
    for letter in "python":
        if letter == "h":
            break  # Exit the loop when the letter 'h' is encountered
        print("Current letter:", letter)

    Output:

    Current letter: p
    Current letter: y
    Current letter: t

    How the for Loop Works Internally

    Python’s for loop iterates over iterable objects such as lists, sets, and dictionaries. Here’s how it works:

    1. Python creates an iterator object from the iterable.
    2. It repeatedly fetches the next item from the iterator using the next() function until it raises a StopIteration exception.

    Example of manually iterating through a list using an iterator:

    fruits = ["apple", "orange", "kiwi"]
    iterator = iter(fruits)
    while True:
        try:
            fruit = next(iterator)
            print(fruit)
        except StopIteration:
            break

    Output:

    apple
    orange
    kiwi
  • Conditional Statements

    Conditional Statements

    Conditional statements control the flow of your Python code by executing different actions based on specified conditions. They’re fundamental for building decision-making in programs, making them crucial for writing logical and efficient Python code.

    Types of Conditional Statements in Python

    1. if Statement

    The if statement executes a block of code only if a specified condition is True. If the condition is False, the block will not execute.

    Syntax of the if statement:
    if condition:
    # Code to execute if condition is true

    Example:

    age = 18
    if age >= 18:
        print("You are eligible to vote.")

    Output:

    You are eligible to vote.
    2. if-else Statement

    The if-else statement expands on the if statement by adding an alternate block of code if the condition is False.

    Syntax of if-else:

    if condition:
        # Code if condition is true
    else:
        # Code if condition is false

    Example:

    score = 50
    if score >= 60:
        print("Passed")
    else:
        print("Failed")

    Output:

    Failed
    3. Nested if-else Statement

    A nested if-else is when an if-else block is placed inside another if-else block. This allows you to create more complex conditions.

    Example:

    number = 15
    if number > 10:
        if number < 20:
            print("Number is between 10 and 20")
        else:
            print("Number is 20 or more")
    else:
        print("Number is 10 or less")

    Output:

    Number is between 10 and 20
    4. if-elif-else Statement

    The if-elif-else ladder provides multiple conditions to check sequentially. Once a condition is found True, the corresponding block is executed, and the rest are bypassed.

    Example:

    day = "Wednesday"
    
    if day == "Monday":
        print("Start of the work week")
    elif day == "Wednesday":
        print("Midweek")
    elif day == "Friday":
        print("End of the work week")
    else:
        print("It's the weekend!")

    Output:

    Midweek
    5. Ternary Expression (Conditional Expression)

    The ternary expression allows you to write a conditional statement in a single line. It’s ideal for simple conditions that can be concisely expressed.

    Syntax:

    value_if_true if condition else value_if_false

    Example:

    x, y = 5, 10
    result = "x is greater" if x > y else "y is greater or equal"
    print(result)

    Output:

    y is greater or equal
  • Operators in Python

    Operators

    In Python, operators are symbols that perform specific computations or operations on variables and values, acting as essential tools in programming.

    • Operator: Special symbol used to perform operations, like +, -, *, /.
    • Operand: Value on which the operator acts.
    Types of Operators in Python
    • Arithmetic
    • Operators
    • Comparison
    • Operators
    • Logical Operators
    • Bitwise Operators
    • Assignment Operators
    • Identity and Membership Operators
    Arithmetic Operators in Python

    These operators help perform basic arithmetic tasks such as addition, subtraction, multiplication, and division.

    In Python 3.x, the division operator / returns a floating-point result, while // returns a floored integer result.

    OperatorDescriptionSyntax
    +Adds two valuesx + y
    Subtracts second value from the firstx - y
    *Multiplies two valuesx * y
    /Divides first value by the second (float)x / y
    //Divides first value by second (floor)x // y
    %Returns remainderx % y
    **Raises first value to power of secondx ** y

    Example: Performing Arithmetic Operations

    a = 12
    b = 5
    
    sum_val = a + b
    diff_val = a - b
    product_val = a * b
    quotient_val = a / b
    floor_div = a // b
    modulus_val = a % b
    power_val = a ** b
    
    print("Sum:", sum_val)
    print("Difference:", diff_val)
    print("Product:", product_val)
    print("Quotient (float):", quotient_val)
    print("Quotient (floor):", floor_div)
    print("Modulus:", modulus_val)
    print("Power:", power_val)

    Output:

    Sum: 17
    Difference: 7
    Product: 60
    Quotient (float): 2.4
    Quotient (floor): 2
    Modulus: 2
    Power: 248832
    Comparison Operators

    Comparison operators compare values and return True or False based on the condition.

    OperatorDescriptionSyntax
    >True if left value is greaterx > y
    <True if left value is smallerx < y
    ==True if values are equalx == y
    !=True if values are not equalx != y
    >=True if left value is greater or equalx >= y
    <=True if left value is smaller or equalx <= y

    Example: Using Comparison Operators

    x = 15
    y = 20
    
    print("Is x greater than y?", x > y)
    print("Is x less than y?", x < y)
    print("Is x equal to y?", x == y)
    print("Is x not equal to y?", x != y)
    print("Is x greater than or equal to y?", x >= y)
    print("Is x less than or equal to y?", x <= y)

    Output:

    Is x greater than y? False
    Is x less than y? True
    Is x equal to y? False
    Is x not equal to y? True
    Is x greater than or equal to y? False
    Is x less than or equal to y? True
    Logical Operators

    Logical operators combine conditional expressions.

    OperatorDescriptionSyntax
    andTrue if both conditions are truex and y
    orTrue if either condition is truex or y
    notTrue if condition is falsenot x

    Example: Logical Operations with Conditions

    a = True
    b = False
    
    print("a and b:", a and b)
    print("a or b:", a or b)
    print("not a:", not a)

    Output:

    a and b: False
    a or b: True
    not a: False
    Bitwise Operators

    These operators perform bit-by-bit operations.

    OperatorDescriptionSyntax
    &Bitwise ANDx & y
    |Bitwise OR`x
    ~Bitwise NOT~x
    ^Bitwise XORx ^ y
    >>Bitwise right shiftx >> y
    <<Bitwise left shiftx << y

    Example: Applying Bitwise Operations

    a = 5
    b = 3
    
    print("a & b:", a & b)
    print("a | b:", a | b)
    print("~a:", ~a)
    print("a ^ b:", a ^ b)
    print("a >> 1:", a >> 1)
    print("a << 1:", a << 1)

    Output:

    a & b: 1
    a | b: 7
    ~a: -6
    a ^ b: 6
    a >> 1: 2
    a << 1: 10
    Assignment Operators

    These operators assign values to variables, often combining an arithmetic operation.

    OperatorDescriptionSyntax
    =Simple assignmentx = y
    +=Add and assignx += y
    -=Subtract and assignx -= y
    *=Multiply and assignx *= y
    /=Divide and assign (float)x /= y
    //=Divide and assign (floor)x //= y
    %=Modulus and assignx %= y
    **=Exponent and assignx **= y
    &=Bitwise AND and assignx &= y
    |=Bitwise OR and assign`x
    ^=Bitwise XOR and assignx ^= y
    >>=Right shift and assignx >>= y
    <<=Left shift and assignx <<= y

    Example: Using Assignment Operators

    x = 10
    y = 3
    
    x += y
    print("After += :", x)
    
    x -= y
    print("After -= :", x)
    
    x *= y
    print("After *= :", x)
    
    x //= y
    print("After //= :", x)

    Output:

    After += : 13
    After -= : 10
    After *= : 30
    After //= : 10
    Identity Operators

    Identity operators check if two variables point to the same object in memory.

    OperatorDescription
    isTrue if both are identical
    is notTrue if they are not

    Example: Checking Object Identity

    a = 100
    b = 100
    c = a
    
    print("a is b:", a is b)
    print("a is c:", a is c)

    Output:

    a is b: True
    a is c: True
    Membership Operators

    Membership operators check if a value is in a sequence, like a list or a string.

    OperatorDescription
    inTrue if value is in sequence
    not inTrue if value is not in sequence

    Example: Checking Membership in a List

    fruits = ["apple", "banana", "cherry"]
    fruit = "banana"
    
    print("Is 'banana' in fruits?", fruit in fruits)
    print("Is 'orange' not in fruits?", "orange" not in fruits)

    Output:

    Is 'banana' in fruits? True
    Is 'orange' not in fruits? True

    Difference between / vs. // operator in Python

    In this article, we’ll explore the difference between the division operator / and the floor division operator // in Python.

    Standard Division in Python (/ Operator)

    The division operator / in Python performs classic division, yielding a floating-point result, even when dividing two integers. It calculates the precise value by including the decimal part.

    Example

    # Division operator
    result = 9 / 4
    print(result)

    Output:

    2.25
    Floor Division in Python (// Operator)

    The floor division operator //, on the other hand, performs division and rounds down to the nearest integer. This means that it removes the decimal part entirely, always resulting in an integer. Floor division can be helpful when you need integer results without rounding up, as it returns the largest whole number less than or equal to the result.

    Example:

    # Floor division operator
    result1 = 9 // 4
    print("Floor division result:", result1)

    Output:

    Floor division result: 2
    Summary of Differences Between / and // in Python

    Below is a comparison table highlighting the main differences between these two operators.

    FeatureDivision Operator (/)Floor Division Operator (//)
    Return TypeFloat (even if the operands are integers)Integer
    Fractional PartKeeps the fractional partDiscards the fractional part
    Examples7 / 3 = 2.3333...
    8 / 4 = 2.0
    6 / 2 = 3.0
    -9 / 4 = -2.25
    7 // 3 = 2
    8 // 4 = 2
    6 // 2 = 3
    -9 // 4 = -3

    Using these operators depends on the need for precision in your calculation: / is used when you need the exact decimal, while // is for cases where only the integer part is required.

    Python Star or Asterisk operator ( * )

    Uses of the Asterisk (*) in Python:

    1. Multiplication: The asterisk (*) can act as a multiplication operator when used between two numbers.

    # Using the asterisk for multiplication
    product = 8 * 6
    print(product)

    Output:

    48

    2. Exponentiation: Two asterisks (**) are used to raise a number to the power of another, representing exponentiation.

    x = 4
    y = 2
    
    # Using double asterisks for exponentiation
    power_result = x ** y
    print(power_result)

    Output:

    16

    3. List Multiplication: By placing an asterisk next to a list, we can repeat the elements in that list a specified number of times.

    # Multiplying a list
    words = ['hello'] * 4
    print(words)

    Output:

    ['hello', 'hello', 'hello', 'hello']

    4. Unpacking a List for Function Arguments: Using an asterisk in front of a list while passing it to a function allows us to unpack its elements as separate positional arguments.

    days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday']
    
    # Without unpacking
    print(' '.join(days))
    
    # Using asterisk to unpack
    print(*days)

    Output:

    Monday Tuesday Wednesday Thursday
    Monday Tuesday Wednesday Thursday

    5. Passing Multiple Positional Arguments with *argsThe asterisk allows a function to accept a variable number of positional arguments. Here, *args can be used to accept any number of arguments and handle them as a tuple.

    # Function using *args
    def add_numbers(*args):
        return sum(args)
    
    print(add_numbers(2, 8, 15, 5))

    Output:

    30

    6. Passing Multiple Keyword Arguments with **kwargsTwo asterisks (**) allow a function to accept a variable number of keyword arguments, making them accessible as a dictionary.

    # Function using **kwargs
    def describe_food(**kwargs):
        for item, description in kwargs.items():
            print(f"{description} is a {item}")
    
    describe_food(fruit='banana', vegetable='carrot', snack='chips')

    Output:

    banana is a fruit
    carrot is a vegetable
    chips is a snack

    7. Unpacking a Dictionary for Function Arguments Using **The double asterisk can also unpack a dictionary’s key-value pairs into function arguments, as shown here.

    # Function using **kwargs with dictionary unpacking
    def display_food_info(**kwargs):
        for item, description in kwargs.items():
            print(f"{description} is a {item}")
    
    food_info = {'fruit': 'apple', 'vegetable': 'spinach', 'grain': 'rice'}
    
    # Unpacking dictionary
    display_food_info(**food_info)

    Output

    apple is a fruit
    spinach is a vegetable
    rice is a grain

    Division Operators in Python

    Python provides two main types of division operators for handling division between numbers:

    1. Float Division (/)
    2. Integer (Floor) Division (//)

    Advantages of Division Operators in Python

    The division operators in Python are powerful and versatile tools in programming. Here are some advantages:

    • Fundamental Arithmetic: They’re essential for performing arithmetic calculations in programming.
    • Simplified Syntax: They offer a clear and concise way to represent division, avoiding more complex expressions.
    • Precision Control: With / for floating-point division and // for integer division, they provide control over the type of result.
    • Algorithmic Efficiency: They help in efficient computations, useful in mathematical modeling, machine learning, and data analysis.
    • Versatile Modeling: They can be applied to simulate complex systems and analyze phenomena with precision control.
    Types of Division Operators in Python

    1. Float Division (/): Using the / operator results in a float, even if both operands are integers.

    Example:

    # Float division examples
    print(8 / 2)
    print(15 / 3)
    print(-9 / 3)
    print(18.0 / 2)

    Output:

    4.0
    5.0
    -3.0
    9.0

    2. Integer (Floor) Division (//) : The // operator performs integer division, also known as floor division. If one of the operands is a float, the result will be a float. When applied to a negative number, it returns the closest integer less than or equal to the quotient.

    Example:

    # Integer (floor) division examples
    print(9 // 2)
    print(17 // 3)
    print(-7 // 3)

    Output:

    4
    5
    -3

    Division Operators in Python

    Division Operator on Boolean Values in Python

    Python does not support division for boolean values. Attempting to divide boolean values will result in a TypeError. However, you can overload the division operator for a custom class to define specific behavior.

    Example: Custom Division Operator Overload with Boolean Values

    In the following code, a custom class CustomBool is created. The division operator (/) is overloaded to perform a logical operation between two boolean values.

    class CustomBool:
        def __init__(self, value):
            self.value = bool(value)
    
        def __truediv__(self, other):
            # Logical AND operation between two boolean values
            return CustomBool(self.value and other.value)
    
    # Create instances
    a = CustomBool(True)
    b = CustomBool(False)
    result = a / b  # result.value will be False
    
    print(result.value)

    Output:

    False

    Modulo operator (%) in Python

    In Python, the % symbol represents the modulo operator, which calculates the remainder of a division operation. This is not to be confused with the “percent” symbol. When you see a % b, it means that a is divided by b, and the result is the remainder of this division.

    What is the Python Modulo Operator?

    The Python modulo operator, %, provides the remainder from the division of two numbers and is part of the arithmetic operations family alongside +-/***, and //. Unlike many programming languages, the modulo operator in Python works with both integers and floats.

    Syntax:

    result = a % b

    Example:

    # Example with integer operands
    num1 = 16
    num2 = 7
    
    result = num1 % num2
    print(num1, "mod", num2, "=", result, sep=" ")

    Output:

    16 mod 7 = 2
    Modulo Operator with Floating-Point Numbers and Negative Values

    The modulo operator can handle floating-point numbers, and when negative numbers are involved, the result takes on the sign of the divisor.

    # Example with floating-point operands and a negative divisor
    float_num1 = 22.5
    float_num2 = -8.0
    
    result = float_num1 % float_num2
    print(float_num1, "mod", float_num2, "=", result, sep=" ")

    Output:

    22.5 mod -8.0 = -5.5
    Practical Example Using the Modulo Operator

    Suppose we want to compute the remainder when dividing each number from 1 to n by a given divisor k. This example demonstrates how to calculate and display these remainders:

    # Define function to calculate remainders from 1 to n divided by k
    def calculate_remainders(n, k):
        for i in range(1, n + 1):
            remainder = i % k
            print(i, "mod", k, "=", remainder, sep=" ")
    
    # Calling the function
    n = 7
    k = 4
    calculate_remainders(n, k)

    Output:

    1 mod 4 = 1
    2 mod 4 = 2
    3 mod 4 = 3
    4 mod 4 = 0
    5 mod 4 = 1
    6 mod 4 = 2
    7 mod 4 = 3
    Handling ZeroDivisionError in Python

    If the divisor (right operand) is zero, Python raises a ZeroDivisionError since division by zero is undefined. The example below shows how to handle this exception gracefully.

    # Example with exception handling for division by zero
    num1 = 20
    num2 = 0
    
    try:
        print(num1, 'mod', num2, '=', num1 % num2, sep=" ")
    except ZeroDivisionError:
        print("Error: Division by zero is not allowed. Please use a non-zero divisor.")

    Output:

    Error: Division by zero is not allowed. Please use a non-zero divisor.
    Common Applications of the Modulo Operator in Python

    1. Idnentifying Even or Odd Numbers

    # Check if a number is even or odd
    num = 27
    if num % 2 == 0:
        print("Even")
    else:
        print("Odd")

    Output:

    Odd

    2. Cycling Through List Indices (e.g., Circular Buffer)

    # Cycling through indices with modulo
    indices = [0, 1, 2, 3]
    current_position = 6
    index = current_position % len(indices)
    print(indices[index])

    Output:

    2

    3. Checking Divisibility

    # Check if a number is divisible by another
    num = 45
    if num % 9 == 0:
        print("Divisible by 9")

    Output:

    Divisible by 9

    4. Time Calculations (e.g., Converting Minutes to Hours and Minutes)

    # Convert total minutes into hours and minutes
    total_minutes = 150
    hours = total_minutes // 60
    minutes = total_minutes % 60
    print(f"{hours} hours and {minutes} minutes")

    Output:

    2 hours and 30 minutes
    Modulo Operator and Negative Numbers

    When working with negative numbers, the result of a % b in Python has the same sign as b.

    # Modulo with positive and negative values
    result = 10 % -4
    print(result)  # Output: -2
    
    result = -10 % 4
    print(result)  # Output: 2

    Output:

    -2
    2
    Modulo with Floating-Point Numbers

    Python’s modulo operator also works with floats and returns a remainder that may also be a float.

    # Example with floating-point values
    result = 13.5 % 2.5
    print(result)

    Output:

    0.5

    Python OR Operator

    The OR operator in Python evaluates multiple boolean expressions and returns True if at least one expression is True. If all expressions evaluate to False, then it returns False.

    Example: OR Operator with Boolean Expressions

    # Example with Boolean expressions
    condition1 = 4 > 5
    condition2 = 4 < 5
    
    print('condition1:', condition1)
    print('condition2:', condition2)
    
    # OR operator
    result = condition1 or condition2
    print("OR operator result:", result)

    Output:

    condition1: False
    condition2: True
    OR operator result: True

    Example: Using Python OR Operator in an if Statement

    # OR operator in an if statement
    def check_number(n):
        if n % 4 == 0 or n % 6 == 0:
            print(f"{n} is a multiple of 4 or 6")
        else:
            print(f"{n} is not a multiple of 4 or 6")
    
    # Driver code
    check_number(12)
    check_number(5)
    check_number(24)

    Output:

    12 is a multiple of 4 or 6
    5 is not a multiple of 4 or 6
    24 is a multiple of 4 or 6
    Python OR Operator – Short-Circuiting

    The Python OR operator stops evaluating as soon as it encounters a True condition. This is known as short-circuiting, where it doesn’t check further expressions once a True is found.

    # Short circuiting with OR operator
    def return_true():
        print("Executing return_true()")
        return True
    
    def return_false():
        print("Executing return_false()")
        return False
    
    # Case 1: First operand is True
    case1 = return_true() or return_false()
    print("Result of Case 1:", case1)
    print()
    
    # Case 2: Both operands are True
    case2 = return_true() or return_true()
    print("Result of Case 2:", case2)
    print()
    
    # Case 3: Both operands are False
    case3 = return_false() or return_false()
    print("Result of Case 3:", case3)
    print()
    
    # Case 4: First operand is False, second is True
    case4 = return_false() or return_true()
    print("Result of Case 4:", case4)

    Output

    Executing return_true()
    Result of Case 1: True
    
    Executing return_true()
    Result of Case 2: True
    
    Executing return_false()
    Executing return_false()
    Result of Case 3: False
    
    Executing return_false()
    Executing return_true()
    Result of Case 4: True

    Walrus Operator in Python 3.8

    The Walrus Operator in Python

    The Walrus Operator (:=), introduced in Python 3.8, allows you to assign a value to a variable as part of an expression. This operator is particularly useful in cases where a value needs to be used repeatedly within the same expression, such as within loops or conditional statements, without having to calculate it multiple times.

    Basic Syntax and Usage

    The syntax for the Walrus Operator is variable := expression. This allows you to both evaluate and assign a value to variable within the context of an expression.

    Example: Using the Walrus Operator in a while Loop

    numbers = [10, 20, 30, 40, 50]
    
    while (n := len(numbers)) > 0:
        print(f"Remaining numbers: {numbers}, Length: {n}")
        numbers.pop()

    Output:

    Remaining numbers: [10, 20, 30, 40, 50], Length: 5
    Remaining numbers: [10, 20, 30, 40], Length: 4
    Remaining numbers: [10, 20, 30], Length: 3
    Remaining numbers: [10, 20], Length: 2
    Remaining numbers: [10], Length: 1

    Merging and Updating Dictionary Operators in Python

    Traditional Method: Using update()

    The update() method allows you to merge one dictionary into another. It modifies the first dictionary in-place by adding or updating keys from the second dictionary. However, it does not create a new dictionary, nor does it return any value.

    Example: Merging Dictionaries with update()

    # Define two dictionaries
    dict1 = {'x': 100, 'y': 200, 'z': 300}
    dict2 = {'y': 250, 'z': 350, 'w': 400}
    
    # Update dict1 with dict2 and return None
    result = dict1.update(dict2)
    print("Return value from update():", result)
    
    # dict1 is modified
    print("Updated dict1:", dict1)
    print("Unchanged dict2:", dict2)

    Output:

    Return value from update(): None
    Updated dict1: {'x': 100, 'y': 250, 'z': 350, 'w': 400}
    Unchanged dict2: {'y': 250, 'z': 350, 'w': 400}

    Using ** to Merge Dictionaries

    In Python, the ** operator can be used to unpack dictionaries, making it possible to merge multiple dictionaries in a single expression. This approach creates a new dictionary, leaving the original dictionaries unaltered.

    Example: Merging Dictionaries Using ** Unpacking

    # Define two dictionaries
    dict1 = {'p': 15, 'q': 25, 'r': 35}
    dict2 = {'s': 45, 'r': 55, 'q': 65}
    
    # Create a new dictionary by unpacking dict1 and dict2
    merged_dict = {**dict1, **dict2}
    
    print("Original dict1:", dict1)
    print("Original dict2:", dict2)
    print("Merged dictionary:", merged_dict)

    Output:

    Original dict1: {'p': 15, 'q': 25, 'r': 35}
    Original dict2: {'s': 45, 'r': 55, 'q': 65}
    Merged dictionary: {'p': 15, 'q': 65, 'r': 55, 's': 45}

    New Method in Python 3.9+: Using | and |= Operators

    Python 3.9 introduces the dictionary merge (|) and update (|=) operators. The merge operator (|) creates a new dictionary by combining the contents of the two dictionaries, while the update operator (|=) modifies the dictionary on the left in place by adding or updating keys from the dictionary on the right.

    Example: Merging with | and Updating with |=

    # Define two dictionaries
    dict1 = {'m': 5, 'n': 10, 'o': 15}
    dict2 = {'p': 20, 'o': 25, 'n': 30}
    
    # Merge using |
    merged_dict1 = dict1 | dict2
    print("Merging dict1 with dict2 (dict1 | dict2):")
    print(merged_dict1)
    
    merged_dict2 = dict2 | dict1
    print("\nMerging dict2 with dict1 (dict2 | dict1):")
    print(merged_dict2)
    
    # Update dict1 with dict2 using |=
    dict1 |= dict2
    print("\nUpdating dict1 with dict2 using |=:")
    print("Updated dict1:", dict1)
    print("Unchanged dict2:", dict2)

    Output:

    Merging dict1 with dict2 (dict1 | dict2):
    {'m': 5, 'n': 30, 'o': 25, 'p': 20}
    
    Merging dict2 with dict1 (dict2 | dict1):
    {'p': 20, 'o': 15, 'n': 10, 'm': 5}
    
    Updating dict1 with dict2 using |=:
    Updated dict1: {'m': 5, 'n': 30, 'o': 25, 'p': 20}
    Unchanged dict2: {'p': 20, 'o': 25, 'n': 30}

    Chaining comparison operators in Python

    In programming, checking multiple conditions is common. Instead of writing separate conditions with logical operators, Python allows you to combine comparisons into a single expression through chaining. This feature simplifies expressions like:

    if a < b and b < c:
    {...}

    In Python, you can simplify this with comparison chaining:

    if a < b < c:
    {...}

    Python supports chaining comparisons using operators like ><==>=<=!=isis notin, and not in.

    Comparison chaining in Python follows typical mathematical notation, making it intuitive. For example, x < y <= z is equivalent to x < y and y <= z, but with a key difference: each expression is evaluated only once. So, if x < y is false, y and z won’t be evaluated, improving performance.

    This chaining doesn’t imply comparisons between non-adjacent elements; for instance, a < b > c is valid and checks that a < b and b > c but does not relate a and c.

    Example of Comparison Operator Chaining

    # Demonstrating chaining of comparison operators
    x = 7
    print(1 < x < 15)          # Checks if x is between 1 and 15
    print(15 < x < 20)         # Checks if x is between 15 and 20
    print(x < 15 < x * 2 < 200) # Checks multiple conditions on x
    print(10 >= x <= 10)       # Checks if x is equal to or less than 10
    print(7 == x > 4)          # Checks if x is both 7 and greater than 4

    Output:

    True
    False
    True
    True
    True

    Importance of Parentheses in Logical Expressions

    When combining and and or with comparison chaining, parentheses are essential for clarifying precedence. Without them, expressions may not evaluate as expected, since and has higher precedence than or.

    p = 3
    q = 7
    r = 12
    
    # Example with no parentheses
    if p < q or q < r and r < p:
        print("This might not be printed as expected")
    
    # Using parentheses to clarify precedence
    if (p < q or q < r) and r < p:
        print("This will be printed as expected")

    Output:

    This might not be printed as expected

    Python Membership Operators

    Membership operators check if a value is present in a sequence (e.g., strings, lists, dictionaries).

    Membership Operators
    OperatorDescriptionSyntax
    inReturns True if the value exists in a sequence, else Falsevalue in sequence
    not inReturns True if the value does not exist in a sequence, else Falsevalue not in sequence
    Python in Operator

    The in operator tests whether a character, element, or substring exists within a sequence, returning True if it’s found, and False otherwise.

    Example :

    # Check if 'z' exists in a string (case-sensitive check)
    'z' in 'PythonProgramming'
    # Output: False
    Python is not Operator

    The is not operator returns True if variables refer to different memory locations.

    Example:

    # Variables
    num_a, num_b = 15, 15
    list_a = [1, 2]
    list_b = [1, 2]
    list_c = list_a
    
    # Testing identity
    print(num_a is not num_b)    # False
    print(list_a is not list_b)  # True
    print(list_a is not list_c)  # False

    Output:

    False
    True
    False
  • Python Data Types

    Python Data Types

    Python data types categorize data items, defining the kind of value they hold and determining applicable operations. Since Python treats everything as an object, its data types are classes, with variables as instances (objects) of these classes. Here are Python’s standard or built-in data types:

    • Numeric
    • Sequence
    • Boolean
    • Set
    • Dictionary
    • Binary Types (memoryview, bytearray, bytes)
    What Are Python Data Types?

    Python provides a function, type(), to determine the data type of any value. Below is an example that assigns various data types to the variable x and prints its type after each assignment.

    x = "Hello World"
    x = 50
    x = 60.5
    x = 3j
    x = ["apple", "banana", "cherry"]
    x = ("apple", "banana", "cherry")
    x = range(5)
    x = {"name": "John", "age": 30}
    x = {"apple", "banana", "cherry"}
    x = frozenset({"apple", "banana", "cherry"})
    x = True
    x = b"Hello"
    x = bytearray(5)
    x = memoryview(bytes(5))
    x = None
    1. Numeric Data Types in Python

    Numeric types represent values with numerical data: integers, floating-point numbers, and complex numbers.

    • Integers: Represented by the int class. Holds positive or negative whole numbers, with no limit on size.
    • Float: Represented by the float class. Real numbers with decimal points or scientific notation (e.g., 3.5 or 4.2e3).
    • Complex: Represented by the complex class, comprising a real and an imaginary part (e.g., 2 + 3j).

    Example

    a = 10
    print("Type of a:", type(a))
    
    b = 12.34
    print("Type of b:", type(b))
    
    c = 2 + 3j
    print("Type of c:", type(c))

    Output:

    Type of a:  <class 'int'>
    Type of b:  <class 'float'>
    Type of c:  <class 'complex'>
    2. Sequence Data Types

    Sequences are collections of values stored in an ordered way. Python has several sequence data types:

    • Strings
    • Lists
    • Tuples
    • String Data Type: Strings in Python represent text data, using Unicode characters. A string can be created using single, double, or triple quotes. Example:
    text1 = 'Welcome to Python'
    text2 = "It's a powerful language"
    text3 = '''Python supports
                multiline strings'''
    print(text1)
    print(text2)
    print(text3)

    Output:

    Welcome to Python
    It's a powerful language
    Python supports
                multiline strings

    Accessing String Elements: Strings can be indexed to access individual characters, with negative indexing for accessing elements from the end.

    str_example = "Python"
    print("First character:", str_example[0])
    print("Last character:", str_example[-1])

    Output:

    First character: P
    Last character: n
    • List Data Type : Lists are collections of items that can be of any data type, and they are mutable. Example:
    fruits = ["apple", "banana", "cherry"]
    print("First fruit:", fruits[0])
    print("Last fruit:", fruits[-1])

    Output:

    First fruit: apple
    Last fruit: cherry
    • Tuples in Python: A tuple is an immutable sequence data type in Python that can store a collection of items. Once a tuple is created, its elements cannot be changed, added, or removed. Tuples are defined using parentheses () and can hold elements of different data types. Example:
    mixed_tuple = (1, "hello", 3.14)
    print(mixed_tuple)  # Output: (1, 'hello', 3.14)

    Output:

    (1, 'hello', 3.14)
    3. Boolean Data Type in Python

    Boolean represents one of two values: True or False.

    Example:

    print(type(True))
    print(type(False))

    Output:

    <class 'bool'>
    <class 'bool'>
    4. Set Data Type in Python

    Sets are unordered collections of unique elements. They are mutable but cannot contain duplicate items.

    Example:

    my_set = set(["apple", "banana", "apple"])
    print(my_set)  # Output: {'apple', 'banana'}

    Output:

    Elements in the set: {'banana', 'apple', 'cherry'}
    Is 'apple' in set? True
    5. Dictionary Data Type in Python

    Dictionaries are unordered, mutable collections of key-value pairs. Each key is unique and maps to a value.

    Example:

    person = {
        "name": "Alice",
        "age": 25,
        "city": "New York"
    }
    print(person["name"])  # Output: Alice

    Output:

    Student Name: John
    Student Age: 20
    6. Binary Types in Python

    Python includes three binary types: bytesbytearray, and memoryview. These are used for low-level data manipulation and working with binary data.

    • Bytes: An immutable sequence of bytes.
    • Bytearray: A mutable sequence of bytes.
    • Memoryview: A memory view object that allows Python code to access the internal data of an object that supports the buffer protocol.

    Example:

    b = b"Hello"
    print("Bytes:", b)
    
    ba = bytearray(5)
    print("Bytearray:", ba)
    
    mv = memoryview(bytes(5))
    print("Memoryview:", mv)

    Output:

    Bytes: b'Hello'
    Bytearray: bytearray(b'\x00\x00\x00\x00\x00')
    Memoryview: <memory at 0x7f1e982f1f40>

    Practice examples

    Q1. Code to implement basic list operations

    # Define the list
    fruits = ["mango", "kiwi", "papaya"]
    print(fruits)
    
    # Append a new fruit
    fruits.append("pineapple")
    print(fruits)
    
    # Remove an item
    fruits.remove("kiwi")
    print(fruits)

    Output:

    ['mango', 'kiwi', 'papaya']
    ['mango', 'kiwi', 'papaya', 'pineapple']
    ['mango', 'papaya', 'pineapple']

    Q2. Code to implement basic tuple operation

    # Define the tuple
    coordinates = (7, 9)
    print(coordinates)
    
    # Access elements in the tuple
    print("X-coordinate:", coordinates[0])
    print("Y-coordinate:", coordinates[1])

    Output:

    (7, 9)
    X-coordinate: 7
    Y-coordinate: 9
  • Python Basic Input and Output

    Python Basic Input and Output

    Input and output operations are fundamental to Python programming, allowing programs to interact with users. The print() function displays information on the console, while the input() function captures user input.

    Displaying Output in Python

    The print() function in Python is the primary method to display output, including text, variables, and expressions.

    Example:

    print("Hello, World!")

    Output:

    Hello, World!
    Printing Variables

    You can print single or multiple variables, adding descriptive labels:

    name = "Alice"
    age = 30
    print("Name:", name, "Age:", age)

    Output:

    Name: Alice Age: 30
    Format Output Handling in Python

    Python offers several ways to format output, including the format() method, the sep and end parameters in print(), f-strings, and the % operator. Each method provides control over data display for enhanced readability.

    • Using format() method:
    amount = 150.75
    print("Amount: ${:.2f}".format(amount))

    Output:

    Amount: $150.75
    • Using sep and end parameters:
    # Using 'end' to connect lines
    print("Python", end='@')
    print("Programming")
    
    # Using 'sep' for separator
    print('G', 'F', 'G', sep='')
    
    # Date formatting example
    print('09', '12', '2023', sep='-')

    Output:

    Python@Programming
    GFG
    09-12-2023
    • Using f-string:
    name = 'Sam'
    age = 25
    print(f"Hello, My name is {name} and I'm {age} years old.")

    Output:

    Hello, My name is Sam and I'm 25 years old.
    • Using % operator for formatting:
    num = int(input("Enter a value: "))
    add = num + 5
    print("The sum is %d" % add)

    Output:

    Enter a value: 10
    The sum is 15
    Taking Multiple Inputs

    The split() method helps take multiple inputs in a single line, dividing the inputs into separate variables.

    # Taking two inputs at a time
    x, y = input("Enter two values: ").split()
    print("Number of apples:", x)
    print("Number of oranges:", y)

    Output:

    Enter two values: 3 5
    Number of apples: 3
    Number of oranges: 5
    Conditional Input Handling

    You can prompt users for input, convert it to a specific data type, and handle conditions based on that input.

    age = int(input("Enter your age: "))
    if age < 18:
        print("You are a minor.")
    elif age < 65:
        print("You are an adult.")
    else:
        print("You are a senior citizen.")

    Output:

    Enter your age: 22
    You are an adult.
    Converting Input Types

    By default, the input() function reads user input as a string. Convert it to other types like int or float if needed.

    • Example to take string input:
    color = input("What color is the sky?: ")
    print(color)
    • Example to take integer input:
    count = int(input("How many stars?: "))
    print(count)
    • Example to take floating-point input:
    price = float(input("Enter the price: "))
    print(price)
    Finding Data Type of a Variable

    To determine the data type of a variable, use type().

    Exanple:

    a = "Hello"
    b = 10
    c = 12.5
    d = ["apple", "banana"]
    print(type(a))  # str
    print(type(b))  # int
    print(type(c))  # float
    print(type(d))  # list

    Output:

    <class 'str'>
    <class 'int'>
    <class 'float'>
    <class 'list'>

    Taking input from console in Python

    In Python, the Console (also referred to as the Shell) is a command-line interpreter. It processes commands entered by the user, one at a time, and executes them. If the command is error-free, the console runs it and displays the result; otherwise, it returns an error message. The prompt in the Python Console appears as >>>, which indicates that it’s ready to accept a new command.

    To start coding in Python, understanding how to work with the console is crucial. You can enter a command and press Enter to execute it. After a command has run, >>> will reappear, indicating that the console is ready for the next command.

    Accepting Input from the Console

    Users can enter values in the Console, which can then be used within the program as needed. The built-in input() function is used to capture user input.

    # Capturing input
    user_input = input("Enter something: ")
    
    # Displaying output
    print("You entered:", user_input)

    You can convert this input to specific data types (integer, float, or string) by using typecasting.

    1. Converting Input to an Integer : When you need to capture integer input from the console, you can convert the input to an integer using int(). This example captures two inputs as integers and displays their sum.

    # Taking integer inputs
    number1 = int(input("Enter first number: "))
    number2 = int(input("Enter second number: "))
    
    # Printing the sum as an integer
    print("The sum is:", number1 + number2)

    2. Converting Input to a Float : To treat the input as a floating-point number, use the float() function to cast the input.

    # Taking float inputs
    decimal1 = float(input("Enter first decimal number: "))
    decimal2 = float(input("Enter second decimal number: "))
    
    # Printing the sum as a float
    print("The sum is:", decimal1 + decimal2)

    3. Converting Input to a String: All inputs can be converted to strings, regardless of their original type. The str() function is used for this purpose, though it’s also optional since input() captures input as a string by default.

    # Converting input to a string (optional)
    text = str(input("Enter some text: "))
    
    # Displaying the input as a string
    print("You entered:", text)
    
    # Or simply:
    text_default = input("Enter more text: ")
    print("You entered:", text_default)

    Python Output using print() function

    The print() Function in Python

    The print() function in Python displays messages on the screen or any other standard output device. Let’s dive into the syntax, optional parameters, and examples that showcase various ways to use print() in Python.

    Syntax of print()

    print(value(s), sep=' ', end='\n', file=file, flush=flush)

    Parameters

    1. value(s): Any number of values to print, which are converted to strings before display.
    2. sep: Optional. Defines a separator between multiple values. Default is a space (‘ ‘).
    3. end: Optional. Defines what to print at the end of the output. Default is a newline (‘\n’).
    4. file: Optional. Specifies a file-like object to write the output to. Default is sys.stdout.
    5. flush: Optional. A Boolean value indicating whether to forcibly flush the output. Default is False.

    By calling print() without arguments, you can execute it with empty parentheses to print a blank line.

    Example of Basic Usage

    first_name = "Sam"
    age = 40
    
    print("First Name:", first_name)
    print("Age:", age)

    Output:

    First Name: Sam
    Age: 40
    How print() Works in Python

    You can pass different data types like variables, strings, and numbers as arguments. print() converts each parameter to a string using str() and concatenates them with spaces.

    first_name = "Mona"
    age = 28
    
    print("Hello, I am", first_name, "and I am", age, "years old.")
    String Literals in print()
    • \n: Adds a new line.
    • "": Prints an empty line.
    print("DataScienceHub \n is a great resource for learning.")
    
    # Output:
    # DataScienceHub
    # is a great resource for learning.
    Using the end Parameter

    The end parameter lets you specify what appears after the output. By default, it’s set to \n, but you can customize it.

    print("Data Science is a growing field", end=" ** ")
    print("Stay curious!")
    
    # Output:
    # Data Science is a growing field ** Stay curious!
    Concatenating Strings in print()

    You can concatenate strings directly within print().

    print("Python is a powerful " + "programming language.")
    
    # Output:
    # Python is a powerful programming language.
    Output Formatting with str.format()

    Using str.format() lets you format the output.

    x, y = 5, 20
    print("The values of x and y are {} and {}, respectively.".format(x, y))
    
    # Output:
    # The values of x and y are 5 and 20, respectively.
    Combining print() with input()

    You can take input from the user and print it.

    number = input("Please enter a number: ")
    print("The number you entered is:", number)

    Output:

    Please enter a number: 50
    The number you entered is: 50
    Using flush in print()

    The flush argument forces Python to write each character immediately, useful in cases like a countdown timer.

    import time
    
    countdown = 5
    for i in reversed(range(countdown + 1)):
        if i > 0:
            print(i, end="...", flush=True)
            time.sleep(1)
        else:
            print("Go!")
    Using the sep Parameter

    The sep argument allows you to customize the separator for multiple values.

    day, month, year = 10, 10, 2024
    print(day, month, year, sep="/")
    
    # Output:
    # 10/10/2024
    File Argument in print()

    The file argument allows you to print to a file rather than the screen.

    import io
    
    # Create a virtual file
    buffer = io.StringIO()
    
    # Print to the buffer instead of standard output
    print("Hello, Pythonistas!", file=buffer)
    
    # Retrieve the contents of the buffer
    print(buffer.getvalue())

    Output:

    Hello, Pythonistas!

    In Python, presenting program output can take various forms: it can be printed in a readable format, written to a file, or customized based on user needs. Here’s an overview of Python’s formatting options:

    Output Formatting in Python

    Python offers several methods for string formatting:

    1. String Modulo Operator (%)
    2. format() Method
    3. Formatted String Literals (f-strings)

    Using the String Modulo Operator (%)

    The % operator can be used to format strings in a way similar to printf in C. Although Python doesn’t have a printf() function, the % operator is overloaded to allow printf-style formatting.

    Example:

    # Formatting integers and floats
    print("Books: %2d, Price: %5.2f" % (4, 32.75))
    print("Total items: %3d, Cost: %6.2f" % (120, 49.90))
    
    # Formatting octal and exponential values
    print("%4o" % (25))           # Octal
    print("%8.2E" % (457.12345))   # Exponential

    Output:

    Books:  4, Price: 32.75
    Total items: 120, Cost:  49.90
      31
     4.57E+02

    In %2d2 specifies the width (padded with spaces if shorter). %5.2f formats a float with width 5 and 2 decimal places.

    Using the format() Method

    Introduced in Python 2.6, the format() method offers flexibility in string formatting. {} placeholders mark where values should be inserted, with the option to specify formatting details.

    Example:

    print("I enjoy {} with '{}'.".format("coding", "Python"))
    print("{0} is the best {1}".format("Python", "language"))
    print("{1} is popular for {0}".format("programming", "Python"))

    Output:

    I enjoy coding with 'Python'.
    Python is the best language
    Python is popular for programming

    Combining Positional and Keyword Arguments:

    # Positional and keyword arguments
    print("Language: {0}, Version: {1}, {other}.".format("Python", "3.10", other="fun"))
    print("Python:{0:2d}, Version:{1:5.2f}".format(12, 3.1415))

    Output:

    Language: Python, Version: 3.10, fun.
    Python:12, Version:  3.14
    Using Dictionaries with format()

    You can also format strings with dictionary values by referencing keys within placeholders.

    Example:

    info = {'lang': 'Python', 'version': '3.10'}
    print("Language: {0[lang]}, Version: {0[version]}".format(info))

    Output:

    Language: Python, Version: 3.10
    Using Formatted String Literals (f-Strings)

    Introduced in Python 3.6, f-strings allow embedding expressions directly in string literals, denoted by an f prefix.

    Example:

    language = "Python"
    version = 3.10
    print(f"Language: {language}, Version: {version:.1f}")

    Output:

    Language: Python, Version: 3.1
    String Methods for Formatting

    Python provides methods like str.ljust()str.rjust(), and str.center() to align strings with padding.

    Example:

    text = "Python"
    
    print("Center aligned:", text.center(20, '*'))
    print("Left aligned:", text.ljust(20, '-'))
    print("Right aligned:", text.rjust(20, '-'))

    Output:

    Center aligned: *******Python*******
    Left aligned: Python--------------
    Right aligned: --------------Python
    Conversion Codes in Python Formatting

    Below is a table of some conversion specifiers:

    CodeMeaning
    dDecimal integer
    bBinary format
    oOctal format
    x/XHexadecimal format
    e/EExponential notation
    f/FFloating-point decimal
    sString
    %Percentage

    How to set an input time limit in Python?

    In this article, we will explain how to set an input time limit in Python. Python is an easy-to-learn programming language that is dynamically typed and garbage collected. Here, we will explore different methods to set an input time limit.

    Methods to Set an Input Time Limit in Python
    • Using the inputimeout module
    • Using the select module
    • Using the signal module
    • Using the threading module

    Method 1: Set an Input Time Limit using the inputimeout module

    The inputimeout module allows users to handle timed input across different platforms. To use this module, it must be installed first using the following command:

    pip install inputimeout

    Example:

    from inputimeout import inputimeout, TimeoutOccurred
    
    try:
        # Take timed input using the inputimeout() function
        response = inputimeout(prompt='What is your favorite color? ', timeout=5)
    
    except TimeoutOccurred:
        response = 'Time is up!'
    
    print(response)

    Method 2: Set an Input Time Limit using the select module

    The select module provides a way to monitor input/output on multiple file descriptors. It is part of the Python standard library and doesn’t require installation. This method helps handle input with a timeout in a cross-platform way.

    Example:

    import sys
    import select
    
    print("What is your favorite color?")
    print("You have 10 seconds to answer.")
    
    # Wait for input with a 10-second timeout
    ready, _, _ = select.select([sys.stdin], [], [], 10)
    
    if ready:
        print("Your favorite color is:", sys.stdin.readline().strip())
    else:
        print("Time's up!")

    Method 3: Set an Input Time Limit using the signal module

    The signal module in Python allows your program to handle asynchronous events such as timeouts. By setting an alarm signal, you can interrupt the input process after a specific time.

    Example:

    import signal
    
    def timeout_handler(signum, frame):
        print("\nTime's up!")
    
    # Set the timeout signal handler
    signal.signal(signal.SIGALRM, timeout_handler)
    
    def get_input():
        try:
            print("What is your favorite color?")
            print("You have 5 seconds to answer.")
            signal.alarm(5)  # Set a 5-second alarm
            response = input()
            signal.alarm(0)  # Cancel the alarm if input is received
            return response
        except Exception:
            return "No answer within time limit"
    
    answer = get_input()
    print("Your favorite color is:", answer)

    Method 4: Set an Input Time Limit using the threading module

    The threading module allows you to run multiple tasks simultaneously. By using a timer, you can create a time limit for input and interrupt it once the time has passed.

    Example:

    from threading import Timer
    
    def time_up():
        print("\nTime's up! You took too long to respond.")
    
    def ask_question():
        print("What is your favorite color?")
        timer = Timer(5, time_up)  # Set a 5-second timer
        timer.start()
    
        answer = input()
        timer.cancel()  # Cancel the timer if input is received on time
        return answer
    
    response = ask_question()
    print("Your favorite color is:", response)

    How to take integer input in Python?

    In this article, we’ll cover how to take integer input in Python. By default, Python’s input() function returns a string. To work with integers, we need to convert these inputs to integers using the int() function.

    Examples 1: Single Integer Input

    # Take input from the user
    value = input("Enter a number: ")
    
    # Display data type before conversion
    print("Type before conversion:", type(value))
    
    # Convert to integer
    value = int(value)
    
    # Display data type after conversion
    print("Type after conversion:", type(value))

    Output:

    Enter a number: 100
    Type before conversion: <class 'str'>
    Type after conversion: <class 'int'>

    Example 2: Taking String and Integer Inputs Separately

    # String input
    string_value = input("Enter a word: ")
    print("Type of string input:", type(string_value))
    
    # Integer input
    integer_value = int(input("Enter a number: "))
    print("Type of integer input:", type(integer_value))

    Output:

    Enter the size of the list: 3
    Enter list elements (space-separated): 8 16 24
    The list is: [8, 16, 24]

    Difference between input() and raw_input() functions in Python

    Input Functions in Python

    In Python, we can use two main functions to capture user input from the keyboard:

    1. input ( prompt )
    2. raw_input ( prompt )

    input() Function

    The input() function allows the program to pause and wait for the user to enter data. It’s built into Python and available in both Python 2.x and 3.x. However, there’s a key difference:

    • InPython 3.x, input() always returns the user input as a string.
    • In Python 2.x, input() returns data in the type entered by the user (e.g., numbers are returned as integers). Because of this, it’s often recommended to use raw_input() instead in Python 2.x for better consistency and security.

    Example in Python 3.x

    # Python 3 example with input() function
    
    name = input("Enter your name: ")
    print("Data type:", type(name))
    print("You entered:", name)
    
    # Taking a number and converting it to an integer
    number = input("Enter a number: ")
    print("Data type before conversion:", type(number))
    number = int(number)
    print("Data type after conversion:", type(number))
    print("You entered:", number)

    Output:

    Enter your name: Alice
    Data type: <class 'str'>
    You entered: Alice
    Enter a number: 42
    Data type before conversion: <class 'str'>
    Data type after conversion: <class 'int'>
    You entered: 42
    raw_input() Function

    In Python 2.x, raw_input() is used to take user input as a string, similar to the input() function in Python 3.x. It’s the recommended method for general input in Python 2.x due to security vulnerabilities with input().

    Example in Python 2.x with raw_input()

    # Python 2 example with raw_input() function
    
    name = raw_input("Enter your name: ")
    print("Data type:", type(name))
    print("You entered:", name)
    
    # Taking a number and converting it to integer
    number = raw_input("Enter a number: ")
    print("Data type before conversion:", type(number))
    number = int(number)
    print("Data type after conversion:", type(number))
    print("You entered:", number)
    Differences Between input() and raw_input() in Python 2.x
    input()raw_input()
    Takes user input and tries to evaluate it.Takes user input as a string.
    Syntax: input(prompt)Syntax: raw_input(prompt)
    May execute arbitrary code if not handled correctly.Safer, as input is taken only as a string.
    Converts input into respective data type.Returns the input as a string.
    Available in both Python 2.x and 3.x.Available only in Python 2.x.
  • Python Introduction

    What is Python?

    Python is a high-level, interpreted programming language known for its readability, simplicity, and versatility.

    One of Python’s key strengths is its extensive standard library, which provides tools suited to many tasks, from web development to data analysis, artificial intelligence, scientific computing, automation, and more. Python’s dynamic typing and automatic memory management simplify the coding process, allowing developers to write clear, logical code for both small and large-scale projects.

    History and Evolution of Python

    Python, conceived in the late 1980s by Guido van Rossum at the Centrum Wiskunde & Informatica (CWI) in the Netherlands, was inspired by the ABC language. Van Rossum aimed to create a language emphasizing readability and simplicity.

    Today, Python thrives with a vibrant community, regular updates, and strong industry presence. Its history reflects its adaptability, user-centric design, and collaborative development, ensuring it remains a powerful and accessible programming language.

    Importance of Python

    Python holds a significant position in the overall IT industry due to its versatility, simplicity, and wide range of applications. Here’s a detailed look at its importance:

    Versatility

    Python’s ability to serve multiple purposes across various domains makes it a highly versatile language. It is used in web development, data science, machine learning, artificial intelligence, automation, scientific computing, and more. This versatility ensures that Python is relevant across different sectors of IT.

    Simplicity and Readability

    Python’s clear and readable syntax makes it an excellent choice for beginners and experienced developers alike. The simplicity of the language reduces the learning curve, allowing new programmers to quickly become productive. This readability also facilitates collaboration among development teams and improves code maintainability.

    Extensive Libraries and Frameworks

    Python offers a vast ecosystem of libraries and frameworks that extend its capabilities.

    • Data Science and Machine Learning: Libraries like NumPy, pandas, Matplotlib, scikit-learn, TensorFlow, and PyTorch.
    • Web Development: Frameworks like Django and Flask.
    • Automation and Scripting: Libraries such as Selenium and PyAutoGUI.
    • Scientific Computing: Libraries like SciPy and SymPy. These resources save development time and effort by providing pre-built solutions for common tasks.
    Community Support

    Python has a large, active, and supportive community. This community contributes to the language’s development, maintains a wealth of resources, and provides assistance through forums, tutorials, and extensive documentation. This robust support network helps developers solve problems and keep up with best practices.

    Cross-Platform Compatibility

    Python is platform-independent, meaning it can run on various operating systems, including Windows, macOS, Linux, and Unix. This cross-platform compatibility ensures that Python applications can be developed and deployed across different environments without significant modifications.

    Integration Capabilities

    Python can easily integrate with other languages and technologies. It can serve as a glue language, connecting components written in C, C++, Java, or other languages. This integration capability makes Python an excellent choice for developing complex, multi-language systems.

    Productivity and Rapid Development

    Python’s concise syntax and extensive libraries enhance developer productivity by reducing the amount of code needed to implement functionalities. This enables rapid prototyping and faster development cycles, which is crucial in today’s fast-paced IT environment.

    Industry Adoption

    Python is widely adopted by major tech companies and organizations, including Google, Facebook, NASA, and CERN. Its use in real-world applications and large-scale systems underscores its reliability and effectiveness. The language’s adoption in academia also ensures a steady influx of skilled Python developers into the industry.

    Automation and Scripting

    Python is a popular choice for automating repetitive tasks and scripting. Its ease of use and powerful libraries enable the automation of a wide range of tasks, from simple file operations to complex workflows, thereby improving efficiency and productivity.

    Future-Proofing

    Python’s ongoing development and evolution ensure that it remains relevant in the face of emerging technologies. Its adaptability to new trends, such as machine learning and data science, positions Python as a future-proof language in the ever-evolving IT landscape. 

    Example:

    a = 10
    b = 3
    
    # Addition
    print(a + b)  # Output: 13
    
    # Subtraction
    print(a - b)  # Output: 7
    
    # Multiplication
    print(a * b)  # Output: 30
    
    # Division
    print(a / b)  # Output: 3.3333333333333335
    
    # Integer Division
    print(a // b)  # Output: 3
    
    # Modulus
    print(a % b)  # Output: 1
    
    # Exponentiation
    print(a ** b)  # Output: 1000
  • Python Tutorial Roadmap

    Python Introduction

    • What is Python?
    • Importance of Python
    • Basic Python Example

    Python Basic Input and Output

    • Python Basic Input and Output
    • Taking input from console in Python
    • Python Output using print() function
    • How to set an input time limit in Python?
    • How to take integer input in Python?
    • Difference between input() and raw_input() functions in Python

    Data Types

    • Python Data Types
    • Practice examples

    Operators

    • Operators
    • Difference between / vs. // operator in
    • Python
    • Python Star or Asterisk operator ( * )
    • Division Operators in Python
    • Division Operators in Python
    • Modulo operator (%) in Python
    • Python OR Operator
    • Walrus Operator in Python 3.8
    • Merging and Updating Dictionary Operators in
    • Python Chaining comparison operators in Python
    • Python Membership Operators

    Conditional Statements

    • Conditional Statements
    • Types of Conditional Statements in Python

    Loops in Python

    • Loops in Python
    • Loop Control Statements

    Python Functions

    • Python Functions
    • Python def Keyword
    • Python User defined functions
    • Python Built in Functions

    Python OOPs Concepts

    • Python Class
    • Python Objects
    • Python Inheritance
    • Python Polymorphism
    • Python Encapsulation

    Python Exception Handling

    • Handling Exceptions with try and except
    • Catching Specific Exceptions
    • finally Clause in Python
    • Raising Exceptions
    • User-defined Exceptions in Python with Examples
    • Built-in Exceptions in Python

    Python Modules

    • Importing a Module in Python
    • Importing Specific Attributes from a Module
    • Importing All Names with *
    • Locating Python Modules
    • Python Built-In Modules

    Python Packages

    • Python Packages
    • Python Packages for Web Frameworks
    • Python Packages for AI & Machine Learning
    • Data Visualization
    • Deep Learning
    • Natural Language
    • Processing
    • Generative AI
    • Computer Vision
    • Python Packages for GUI Applications
    • Python Packages for Web FrameworksPython
    • Packages for Game Development

    Python Collections Module

    • Python Collections Module
    • NamedTuple in Python
    • Deque in Python
    • ChainMap in Python
    • Python Counter
    • Objects elements()
    • OrderedDict in Python

    Python Interview Questions

    • Python Interview Questions