Common Python Interview Questions and Answers for 2023 - IQCode

Introduction to Python Programming Language

Python is a popular programming language developed by Guido van Rossum, first released on February 20, 1991. It is a free and open-source language known for its clean and simple syntax, making it easy for developers to learn and understand. Python supports object-oriented programming and is used for general-purpose programming, machine learning, artificial intelligence, web development, and web scraping, among others.

As Python can accomplish multiple functionalities in fewer lines of code, its popularity is growing massively, leading to increased demand for Python developers in India and worldwide. This article will provide insights into commonly asked Python interview questions and answers that will help developers excel during interview sessions.

We've sorted questions into the following sections:

- Python Interview Questions for Freshers - Python Interview Questions for Experienced Developers - Python OOPS Interview Questions - Python Pandas Interview Questions - NumPy Interview Questions - Python Libraries Interview Questions - Python Programming Examples

To get started with Python, you can refer to the Python Cheat Sheet that covers basic to advanced concepts.

Python Interview Questions for Freshers:

1. What is Python, and what are its benefits?

Understanding Dynamically Typed Languages

In the world of programming, a dynamically typed language is one where variables are not bound to a specific data type during compilation time. Instead, the data type is determined at runtime based on the value assigned to the variable. This means that variables in dynamically typed languages can hold different data types at different points during program execution.

Examples of dynamically typed languages include Python, JavaScript, Ruby, and PHP. In contrast, statically typed languages like Java and C++ require variables to be explicitly declared with a specific data type during compilation.

While dynamically typed languages offer greater flexibility and simplicity in programming, they can also lead to errors that are caught only during runtime when certain values are incompatible with the expected data type. However, in general, dynamically typed languages are a popular choice for rapid prototyping, scripting, and web development.

Understanding Interpreted Languages

An interpreted language is a type of programming language where the code is executed line-by-line rather than compiled into machine code by a compiler. Instead, an interpreter reads and executes the code directly. Popular examples of interpreted languages include Python, JavaScript, and Ruby. Interpreted languages offer advantages such as portability and dynamic typing but may be slower than compiled languages due to the need to interpret the code at runtime.

What is PEP 8 and why is it important?

PEP 8 is a document that provides guidelines, best practices, and conventions for writing Python code. It covers topics such as code layout, naming conventions, comments, and code style.

Adhering to PEP 8 guidelines when writing code is important because it promotes consistency and readability in Python code. This makes it easier for other developers to understand and maintain the code, reducing the likelihood of errors or bugs. It also makes collaboration on projects more efficient and streamlined, as everyone follows the same style guide.

Following PEP 8 is considered a best practice when writing Python code and is widely supported by the Python community. Many tools and editors also have built-in support for enforcing PEP 8 guidelines, making it easier to ensure that code is written in a consistent and readable style.

Understanding Python's Scope

In Python, scope refers to the region in a program where a specific identifier is defined and can be accessed. There are two main types of scope in Python:

Global scope

When a variable is defined in the main body of a Python file or module, it has global scope. This means that the variable can be accessed by all functions or classes defined in that file or module.

Local scope

When a variable is defined inside a function or method, it has local scope. This means that the variable can only be accessed within that function or method.

It's important to understand scope in Python in order to properly manage and use variables in your code.

Lists and Tuples in Python

In Python, both lists and tuples are used to store a collection of items. The main difference between the two is that lists are mutable (can be modified) while tuples are immutable (cannot be modified).

A list is created using square brackets [] and items in the list are separated by commas. For example:

my_list = [1, 2, "apple", "banana"]

A tuple, on the other hand, is created using parentheses () and items in the tuple are also separated by commas. For example:

my_tuple = (1, 2, "apple", "banana")


Common Built-In Data Types in Python

Python has several built-in data types that are commonly used, including:

  • int

    (integer numbers)

  • float

    (floating point numbers)

  • bool

    (boolean values True and False)

  • str

    (strings of characters)

  • list

    (ordered sequence of elements)

  • tuple

    (ordered, immutable sequence of elements)

  • set

    (unordered collection of unique elements)

  • dict

    (unordered collection of key-value pairs)

These data types are fundamental to the language and are used extensively in Python programs.

Understanding the "pass" Keyword in Python

In Python, "pass" is a keyword that is used as a placeholder when a statement is required syntactically, but no code needs to be executed. It is typically used as a placeholder for functionality that needs to be implemented at a later time.

For instance, in empty classes and functions where you may want to fill in the details later, you can use the "pass" keyword to prevent syntax errors. Similarly, it can be used in conditional statements or loops where you want to skip over a block of code temporarily without causing an error.

Here's an example:


def my_function():
    pass

In the example above, we have defined a function "my_function" that does nothing. Without the "pass" keyword, this function would return a syntax error.

In essence, "pass" is a way to tell Python to do nothing and move on. It may seem like a useless keyword at first, but it is a powerful tool for structuring code and preventing errors.

Modules and Packages in Python

In Python, a module is a file containing Python definitions, statements, and functions. It allows you to reuse your code and organize your project into separate files. To use a module, you simply import it into your program using the `import` statement.

A package, on the other hand, is a way of organizing modules into subdirectories to make them easier to manage. A package contains an __init__.py file that tells Python that this directory should be considered as a Python package.

Both modules and packages are essential features of Python and enable the creation of complex and efficient software systems.

Understanding Global, Protected, and Private Attributes in Python

In Python, global variables are the ones that can be accessed from any part of the code. They are not restricted to the class or function in which they are defined. Protected attributes are defined with a single underscore (_) prefixing the name. This indicates that they should not be accessed by external code but can be accessed by subclasses. Private attributes are defined with a double underscore (__) prefixing the name, indicating that they can only be accessed by the class itself. However, it is still possible to access these attributes by using name mangling.

Understanding the Use of Self in Python

In Python, `self` is a reference variable that refers to the instance of a class. It is used to access the attributes and methods of a class in Python.

In other words, `self` is used to refer to the object that the method is being called upon. When a method is called, the `self` parameter is expected in the method definition, and it is used to access the attributes and methods of the class.

For example:


class Car:
    def __init__(self, make, model):
        self.make = make
        self.model = model

    def display_info(self):
        print(f"Make: {self.make}, Model: {self.model}")

my_car = Car("Ford", "Mustang")
my_car.display_info()  # Output: Make: Ford, Model: Mustang

In the above example, we created a `Car` class with the `__init__` method that sets the `make` and `model` attributes of the class. We then defined a `display_info` method that uses the `self` parameter to access the `make` and `model` attributes and print them.

When we create an instance of the `Car` class (`my_car`), we pass in the `make` and `model` parameters. We then call the `display_info` method on the `my_car` instance, which uses the `self` parameter to access the `make` and `model` attributes and print them.

In summary, `self` is an important concept in Python that is used to refer to the current instance of a class and to access its attributes and methods.

Understanding the __init__ Method in Python

The `__init__` method in Python is a special method that gets called automatically when an object of a class is created. It is commonly used to initialize the instance variables of a class. The `self` parameter in the `__init__` method represents the instance of the class and is used to access and modify the instance variables.

Here is an example:

class Person: def __init__(self, name, age): self.name = name self.age = age

In the above example, the `Person` class has an initializer method called `__init__`. It takes two parameters `name` and `age`, which are used to initialize the `name` and `age` instance variables respectively.

When an object of the `Person` class is created, the `__init__` method is automatically called with the passed arguments, and the instance variables are initialized.

person1 = Person("John", 30)

In the above example, the `person1` object is created using the `Person` class and the `__init__` method is called with the arguments `"John"` and `30`. This initializes the `name` variable to `"John"` and the `age` variable to `30`.

The `__init__` method can also be used to perform any other initialization tasks that need to be done when an object is created.

Understanding break, continue, and pass statements in Python

In Python, there are three control flow statements that help us to handle loops efficiently.

1.

break

is used to terminate a loop prematurely. When the

break

statement is executed, the loop immediately stops and the program execution continues from the next statement outside the loop.

2.

continue

is used to skip to the next iteration of a loop. When the

continue

statement is executed, the current iteration of the loop is stopped and the program proceeds to the next iteration.

3.

pass

is a null statement in Python that is used when syntax requires a statement, but you want to do nothing. It is usually used as a placeholder when writing code that is incomplete or not implemented yet. When

pass

is executed, nothing happens and the program moves to the next statement.

Understanding Unit Tests in Python

In Python, unit tests are used to verify that individual units or components of a codebase are functioning properly. These tests are written in the form of functions that check specific inputs and outputs of a module or function in isolation, without relying on any external dependencies.

Unit tests help ensure that changes made to the code do not break existing functionality, and serve as a form of documentation for how different parts of the code should behave. In addition, writing unit tests can help catch bugs early in the development process, making it easier and less expensive to fix them.

Python provides a built-in `unittest` module for creating and running unit tests. Other popular testing frameworks for Python include `pytest` and `nose`.

Explanation of Docstring in Python

In Python, a docstring is a documentation string that is used to describe the functionality of a module, function, class or a method. It is a string literal that is placed at the beginning of the code block after the import statements and before the actual code. The purpose of a docstring is to provide a brief description of what the code does, and it is very helpful for others who will read or use your code.

A docstring can be in the form of a single-line or a multi-line string, and it uses triple quotes (''' or """) to define the string. The first line of the docstring should be a brief summary of the code's purpose and start with a capital letter. The following lines should provide more details about the code.

Here is an example of a docstring for a simple function:


def add_numbers(a, b):
    """
    This function adds two numbers.
    Parameters:
        a (int): First number
        b (int): Second number
    Returns:
        int: Sum of a and b    
    """
    return a + b

In the above example, the docstring provides a brief description of the function's purpose, along with the parameters it takes and the value it returns. By using proper documentation with the help of a docstring, it is easier to maintain, debug, and reuse code.

Understanding Python Slicing

Python slicing is a technique to extract a specific portion of a sequence like a list, string, tuple or array. It involves specifying a range of elements to be extracted from the sequence using indexes. The basic syntax for slicing is `sequence[start:end:step]`.

- `start`: The index of the first element to be included in the slice. Default is 0. - `end`: The index of the first element to be excluded from the slice. Default is the length of the sequence. - `step`: The increment between each index in the slice. Default is 1.

Slicing can also be performed on multi-dimensional arrays or lists, resulting in a sub-array or sub-list. Slicing in Python is a powerful tool that can simplify code and make it more efficient.H3. Making a Python Script Executable on Unix

To make a Python script executable on Unix, you need to perform the following steps:

1. Add a shebang line at the beginning of your Python script. This line specifies the path of the Python interpreter that you want to use to execute the script. The shebang line starts with #! and the path of the interpreter follows.

2. Set the execute permission of the script using the chmod command. This makes the script executable.

Here is an example of how to make a Python script executable on Unix:

First, add the shebang line at the beginning of your script:


#!/usr/bin/env python

This tells Unix to use the Python interpreter to execute the script.

Save your Python script and navigate to the directory where it is saved using the terminal.

Next, set the execute permission of the script using the chmod command:


chmod +x your_script_name.py

This gives the execute permission to your Python script.

Now you can run your script by typing:


./your_script_name.py

This will execute your Python script on Unix.

Difference between Python Arrays and Lists

In Python, arrays and lists are two different types of data structures.

Lists are more flexible and can contain elements of different data types. They are created using square brackets and can be modified after creation. Example:


my_list = [1, "hello", 3.4]

Arrays, on the other hand, are homogeneous collections of elements with a fixed size and type. They are created using the array module and cannot be modified after creation. Example:


import array as arr
my_array = arr.array('i', [1, 2, 3])

In summary, lists are more versatile and can be modified after creation, while arrays have a fixed size and type and are more efficient for numerical operations.

PYTHON INTERVIEW QUESTION: HOW DOES PYTHON MANAGE MEMORY?

In Python, memory is managed using a private heap space that is made available to the Python interpreter. The interpreter takes care of allocation and deallocation of memory. When a Python program creates a variable, space is allocated on the heap to store the variable's value. When the variable is no longer needed, the interpreter automatically deallocates the memory used by the variable.

Python uses a technique called "garbage collection" to automatically free up memory that is no longer being used by the program. The garbage collector runs in the background and monitors the program's use of memory. When the garbage collector determines that a piece of memory is no longer being used by the program, it frees up that memory for reuse.

Python also provides tools that allow developers to manipulate memory directly if needed. For example, the "gc" module provides a way to disable or modify the behavior of the garbage collector, and the "ctypes" module allows developers to access memory at a low level.

Overall, Python's memory management system is designed to make it easy for developers to create programs without worrying too much about memory management. However, if developers need to work with memory directly, Python provides the tools to do so.

Python Namespaces: What are they and Why are they Used?

In Python, a namespace is a system that ensures that all object names are unique and can be used without any name conflicts among different modules.

A namespace is essentially a dictionary of variable names to object references. Python implements namespaces as dictionaries.

Namespaces can be created at module, class, or function levels. This means that names that are defined in a function or module are not accessible in other functions or modules unless they are specifically imported.

Namespaces are used to avoid naming conflicts that can arise when different modules or functions have the same variable name. Namespaces also make it easier to organize code and avoid errors caused by naming collisions.

In practice, Python namespaces are powerful tools for code organization and management. They improve code clarity, reduce the likelihood of errors, and make code more modular and easier to maintain.

Scope Resolution in Python

Scope resolution in Python refers to the process of identifying the value of a variable within a particular scope. In Python, there are two types of scope: local and global.

Local scope is the scope of a variable within a function, meaning that it can only be accessed within that function. Global scope, on the other hand, refers to the scope of a variable that can be accessed from any part of the code.

To resolve variable names in Python, the interpreter searches for the variable name starting from the current scope and then moving out to the global scope. If the variable is not found in any scope, a NameError will be raised.

To explicitly refer to a global variable within a function, the global keyword can be used to indicate that the variable is in the global scope. For example:


x = 'global'

def func():
    global x
    x = 'local'

func()
print(x) # Output: 'local'

In this example, the global keyword is used to indicate that the variable x is in the global scope, so when the func() function is called and the x variable is assigned a new value, it is changing the global variable x rather than creating a new local variable within the function scope.

Decorators in Python

Decorators are a feature of Python that allow you to modify or enhance the behavior of a function by wrapping it with another function. They use the "@" symbol and are placed above the function definition. Decorators provide an easy and clean way to add functionality to a function without modifying the function's source code. They are commonly used in frameworks like Flask and Django to add authentication, rate limiting, and caching to endpoints.

Difference between Dict and List Comprehensions

Dict and list comprehensions are shorthand ways of creating a new dictionary or a new list using an existing dictionary or list.

List comprehension is used to create a new list by iterating over an existing sequence and applying some operation to each item. It has a typically simple and concise syntax that makes it easy to read and write. Here's an example:


numbers = [1, 2, 3, 4, 5]
squares = [x**2 for x in numbers]
print(squares)

This will produce the following output:


[1, 4, 9, 16, 25]

Dict comprehension is used to create a new dictionary by iterating over an existing dictionary and applying some operation to each key-value pair. It also has a simple and concise syntax that makes it easy to use. Here's an example:


ages = {'Tom': 25, 'Jane': 34, 'John': 42, 'Dick': 23}
adults = {name: age for name, age in ages.items() if age >= 18}
print(adults)

This will produce the following output:


{'Tom': 25, 'Jane': 34, 'John': 42}

In summary, list comprehensions and dict comprehensions are powerful ways to create new lists and dictionaries in a concise and readable way.

Explanation of Lambda in Python

In Python, lambda is a tool for creating simple, anonymous functions. It's used as a shortcut for defining small, one-line functions without needing to define an entire function block.

Lambda functions are often used for operations such as sorting, filtering, and mapping. They are also useful for passing as parameters to functions that expect a function as an argument.

An example of a lambda function in Python would look like this:


lambda x: x**2

This creates a function that takes one argument, `x`, and returns its square.

Lambda functions can also be stored in variables or used directly in code without assigning them to a variable. For instance:


# stored in a variable
square = lambda x: x**2
result = square(5)
print(result)

# used directly
result2 = (lambda x: x**2)(5)
print(result2)

Both of these examples would output `25`, which is the square of `5`.

Overall, lambda functions in Python are a concise and convenient way to define small, one-off functions without needing to create a named function block.

Copying an Object in Python

In Python, there are two ways to copy an object:

shallow copy

and

deep copy

.

Shallow Copy:

This creates a new object which stores a reference to the original object. If the original object is modified, the copied object is also modified.

Deep Copy:

This creates a completely new object with a new memory address. Changes to the original object do not affect the cloned object.

To copy an object using "shallow copy", you can use the built-in function

copy.copy()

.

Here's an example:

import copy

original_list = [1, 2, 3, [4, 5, 6]]

shallow_copy = copy.copy(original_list)
shallow_copy.append(4)

print(original_list)
print(shallow_copy)

Output:

[1, 2, 3, [4, 5, 6]]
[1, 2, 3, [4, 5, 6], 4]

As you can see, the new object "shallow_copy" has been created with a reference to the original list. Therefore, when the new item "4" is added to "shallow_copy", it is also added to the original list.

To copy an object using "deep copy", you can use the built-in function

copy.deepcopy()

.

Here's an example:

import copy

original_list = [1, 2, 3, [4, 5, 6]]

deep_copy = copy.deepcopy(original_list)
deep_copy.append(4)
deep_copy[3].append(7)

print(original_list)
print(deep_copy)

Output:

[1, 2, 3, [4, 5, 6]]
[1, 2, 3, [4, 5, 6, 7], 4]

In this example, the new object "deep_copy" has been created with a separate memory allocation for each element, including the nested list. Therefore, any changes made to "deep_copy" do not affect the original list.

Difference between xrange and range in Python

In Python 2, `range()` returns a list whereas `xrange()` returns an iterator object.

Range:

python
for i in range(5):
    print(i)  # prints 0 to 4

Xrange:

python
for i in xrange(5):
    print(i)  # prints 0 to 4

In Python 3, `range()` returns an iterator object by default, so `xrange()` is not available.

Explanation of Pickling and Unpickling

Pickling:
Pickling is the process of converting a Python object into a byte stream, which can be stored or transmitted over a network. This process allows the object to be saved as a file, which can then be loaded later for use. The pickle module in Python provides functions for pickling and unpickling objects.

Unpickling:
Unpickling is the reverse process of pickling. It converts the byte stream back into a Python object, allowing the object to be restored to its original state.

Both pickling and unpickling are commonly used in Python for saving and loading data structures, such as lists, dictionaries, and classes. However, care should be taken when using them with untrusted data, as pickled data can contain harmful executable code.

Generators in Python

Generators in Python are functions that use the "yield" keyword instead of "return." When a generator is called, it returns an iterator object, which generates a sequence of values on-the-fly instead of returning a single value. This means generators can be used to create large sequences without having to store the entire sequence in memory at once, making them more memory-efficient than lists. Generators are especially useful for generating sequences in a lazy or iterative manner.

Explanation of PYTHONPATH in Python

In Python, PYTHONPATH is an environment variable that contains a list of directories. When a module is imported, Python searches for it in these directories. If the module is not found in any of these directories, an ImportError is thrown.

PYTHONPATH can be set in a few different ways, such as through the command line or through the system’s environment variables settings.

An example of setting the PYTHONPATH using the command line is:

export PYTHONPATH=/path/to/directory

This would add the “/path/to/directory” to the PYTHONPATH and tell Python to search that directory for modules.

It’s important to note that PYTHONPATH should not be used to modify the Python standard library directory. Doing so can create conflicts and cause unpredictable behavior.

Explanation of the help() and dir() functions in Python

The

help()

and

dir()

functions are important in Python because they provide useful information about modules, classes, functions, and other objects in Python.

The help() Function: When you use the

help()

function, you can get detailed information about a particular object or module in Python. For example, you can use

help(list)

to get information about the list class in Python.

The dir() Function: The

dir()

function, on the other hand, returns a list of all the attributes and methods associated with an object. This can be useful when you're working with an unfamiliar class or object and you want to see what methods and attributes are available for use. For example, you can use

dir(list)

to get a list of all the attributes and methods available for the list class in Python.

Overall, the

help()

and

dir()

functions are powerful tools that can help you learn more about Python and the objects and modules that you use in your code.

Differences between .py and .pyc files

.py files are Python source files that contain code written in the Python programming language. These files are human-readable and can be edited using a basic text editor. When you run a .py file, the Python interpreter reads and executes the code in the file.

.pyc files, on the other hand, are compiled versions of .py files. When you run a .py file, Python translates the code into bytecode and saves the bytecode in a .pyc file. The next time you run the .py file, Python can use the .pyc file instead of recompiling the code from scratch. This can make the code run faster since Python doesn't have to recompile the code each time you run it.

To summarize: .py files are human-readable Python source code files, while .pyc files are compiled bytecode files that Python can use to run the code faster.


# Example code to show how Python works with .py and .pyc files

# my_script.py - a Python source file
def hello():
    print("Hello, world!")

# When you run this file, Python compiles the code and saves it to my_script.pyc
# The .pyc file is saved in the same directory as the .py file
$ python my_script.py

# Now, when you run the .py file again, Python can use the .pyc file instead of recompiling the code
$ python my_script.py
Hello, world!

How Python is Interpreted?

Python is an interpreted language which means that the Python interpreter reads and executes the code line by line, instead of compiling the entire code into machine language before running it. This makes the development process faster as changes can be made and tested quickly. The interpreter converts the code into byte code which is then executed by the Python Virtual Machine (PVM).

Passing Arguments by Value or Reference in Python

In Python, all arguments are passed by reference. However, the way this works can lead to confusion.

When an immutable object, such as a string or number, is passed to a function, a new reference to that object is created, effectively creating a copy of the object. Any changes made to the copy do not affect the original object outside of the function.

On the other hand, when a mutable object, such as a list or dictionary, is passed to a function, a new reference to that object is not created. Instead, the function receives a reference to the original object. Any changes made to the object within the function will also affect the original object outside of the function.

Here's an example to demonstrate this behavior:


def modify_list(lst):
    lst.append(4)
    print("List inside function: ", lst)

my_list = [1, 2, 3]
modify_list(my_list)
print("List outside function: ", my_list)

In this example, when we pass

my_list

to the

modify_list

function, we are passing a reference to the original list object. When we append the value 4 to the list inside the function, this change also affects the original list outside of the function.

Output:


List inside function:  [1, 2, 3, 4]
List outside function:  [1, 2, 3, 4]

Iterators in Python

Iterators in Python are used to retrieve values from a collection of data, such as a list or a tuple. An iterator is an object that implements the iterator protocol, which requires the use of two methods: `__iter__()` and `__next__()`.

The `__iter__()` method returns the iterator object and the `__next__()` method returns the next value in the collection. Once all the values have been retrieved, the `__next__()` method will raise a StopIteration exception.

Iterators are used in loops to retrieve values from a collection. They are also used to provide lazy evaluation, which means that values are only computed when they are needed. This can be useful for working with large data sets, as it can save memory and processing time.

Here is an example of using an iterator to retrieve values from a tuple:

python
my_tuple = (1, 2, 3, 4)
my_iterator = iter(my_tuple)

print(next(my_iterator))  # Output: 1
print(next(my_iterator))  # Output: 2
print(next(my_iterator))  # Output: 3
print(next(my_iterator))  # Output: 4

In this example, the `iter()` function is used to create an iterator object from the tuple `my_tuple`. The `next()` method is then used to retrieve each value from the iterator in sequence.

Deleting a File in Python

To delete a file in Python, you can use the `os.remove()` method. Here's an example of how to use it:

Code:


import os

# specify the file path
file_path = "example.txt"

# delete the file
try:
    os.remove(file_path)
    print(f"{file_path} has been deleted.")
except FileNotFoundError:
    print(f"{file_path} does not exist.")

In this example, we imported the `os` module and specified the file path of the file we want to delete. We then used a `try-except` block to attempt to delete the file using `os.remove()`. If the file is successfully deleted, we print a message confirming it. If the file does not exist, we print a message indicating that.

It's important to note that `os.remove()` permanently deletes the file, so be careful when using this method.

Explanation of split() and join() Functions in Python

In Python,

split()

and

join()

are built-in functions that are used to manipulate strings. Here is a brief explanation of each:

split()

: This function is used to split a string into a list of substrings based on a specified delimiter. For example:

string = "Hello World"
list = string.split(" ")

In this example, the string "Hello World" is split into a list of two substrings ["Hello", "World"] based on the delimiter " ". The delimiter can be any character or string that you want to use to split the string.

join()

: This function is used to join a list of strings into a single string using a specified delimiter. For example:

list = ["Hello", "World"]
string = " ".join(list)

In this example, the list of two substrings ["Hello", "World"] is joined together into a single string "Hello World" using the delimiter " ". The delimiter can be any character or string that you want to use to join the list together.

By using these two functions, you can easily manipulate strings in Python according to your needs.

What do *args and **kwargs mean?

In Python, *args and **kwargs are special syntax used for passing a variable number of arguments to a function.

*args: This parameter is used to pass a variable number of non-keyword arguments to a function. The *args parameter is treated as a tuple of arguments inside the function.

**kwargs: This parameter is used to pass a variable number of keyword arguments to a function. The **kwargs parameter is treated as a dictionary of keyword arguments inside the function.

Here is an example of how to use *args and **kwargs in a function:


def example_function(arg1, arg2, *args, **kwargs):
    print("arg1:", arg1)
    print("arg2:", arg2)
    print("*args:", args)
    print("**kwargs:", kwargs)

In this example function, arg1 and arg2 are positional arguments that must be passed to the function. The *args parameter allows any number of additional non-keyword arguments to be passed to the function. The **kwargs parameter allows any number of additional keyword arguments to be passed to the function.

Understanding Negative Indexes and Their Use

Negative indexes are used in programming languages like Python to access elements in a sequence such as a list or a string from the end of it instead of the beginning. In Python, for instance, the index -1 refers to the last item in the list and the index -2 refers to the second-to-last item, and so on.

The main advantage of using negative indexes is that it makes it easy to access elements near the end of a list or string without the need to know its length. This saves time when we are dealing with large amounts of data and we need to access elements quickly and efficiently.

For example, if we have a list with 10 elements and we want to access the last element in the list, we can use the index -1 instead of the index 9, which is the length of the list minus one. This makes the code more readable and easier to understand.

Overall, negative indexes are a useful feature in programming languages that can save time and make code more concise and readable.

Python OOP Interview Question:

Question 39: How do you define a class in Python?

Answer: In Python, we can create a class using the `class` keyword followed by the name of the class. Here's an example of how to define a simple class:


class MyClass:
    # class variables
    x = 5
    y = 10

    # class methods
    def my_method(self):
        print("Hello, World!")

In this example, we defined a class called `MyClass` with two class variables (`x` and `y`) and a class method (`my_method()`). The `self` parameter passed to the method is a reference to the instance of the class, and is used to access the class variables and other methods.

Once the class is defined, we can create an instance of the class by calling the class constructor:


obj = MyClass()

Now we can access the class variables and methods using the object `obj`:


print(obj.x) # Output: 5
obj.my_method() # Output: Hello, World!


Inheritance in Python

Inheritance is a way to create a new class, called the derived class, from an existing class, called the base class. The derived class inherits all the properties and methods of the base class, and can also add its own unique properties and methods.

Here is an example of inheritance in Python:


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

  def make_sound(self):
    print("The animal makes a sound.")

class Dog(Animal):
  def __init__(self, name):
    super().__init__("Dog")
    self.name = name

  def make_sound(self):
    print("The dog barks.")

my_dog = Dog("Fido")
print("Species:", my_dog.species)
print("Name:", my_dog.name)
my_dog.make_sound()

In this example, we have a base class called Animal that has a constructor method that takes a species parameter and a method called make_sound that prints out a message about the animal making a sound.

We also have a derived class called Dog that inherits from the Animal class. The Dog class has a constructor method that takes a name parameter and calls the constructor of the base class. It also has a make_sound method that overrides the make_sound method of the base class with a message about the dog barking.

We create an instance of the Dog class and call its methods to demonstrate that it has both the properties of the Animal class and the Dog class.

How to Access Parent Members in a Child Class?

In order to access parent members in a child class, you can use the `super` keyword followed by a dot and the name of the member you want to access. This will allow you to call methods or access properties of the parent class.

Here's an example:


class ParentClass:
    def __init__(self):
        self.parent_property = "I am a property from the parent class"
    
    def parent_method(self):
        print("This is a method of the parent class")

class ChildClass(ParentClass):
    def child_method(self):
        super().parent_method() # calling parent method using super()
        print(super().parent_property) # accessing parent property using super()

child_object = ChildClass()
child_object.child_method() # output: "This is a method of the parent class"
                           #         "I am a property from the parent class"

In this example, the `ChildClass` inherits from the `ParentClass`. The `child_method` not only prints the message from the `parent_method` by calling it using the `super` keyword, but also accesses the `parent_property` using `super()`.

Are Access Specifiers Used in Python?

Access specifiers (e.g. public, private, protected) are not used in Python like they are in languages such as Java and C++. In Python, the convention is to use underscores to indicate the intended level of access to a class attribute or method. A single underscore indicates that the attribute/method should not be accessed directly from outside the class, while a double underscore indicates that the attribute/method is "private" and not intended to be accessed directly from anywhere other than inside the class. However, it is important to note that this is only a convention and does not actually prevent accessing the attribute/method if desired.

Can a Parent Class be Called Without Creating an Instance?

In Python, it is possible to call a parent class without creating an instance by using the class name followed by the method you want to call, and passing in the relevant parameters. This is known as a class method. However, you should keep in mind that class methods can only access class-level variables, and not instance-level variables.

Here's an example of how to call a parent class method without instance creation:


class ParentClass:
    def __init__(self):
        self.name = "Parent"
    
    @classmethod
    def parent_method(cls):
        print("This is a parent class method")
        print(cls.name)  # Accessing class-level variable


class ChildClass(ParentClass):
    def __init__(self):
        super().__init__()
        self.name = "Child"

ChildClass.parent_method()  # Calling the parent method without instance creation

In the above example, we have a `ParentClass` with a `parent_method` class method that prints a message. We also have a `ChildClass` that inherits from `ParentClass` and has its own `__init__` method.

We then call `ChildClass.parent_method()` without creating an instance of `ChildClass`. The output will be:


This is a parent class method
Parent

Note that we are accessing the class-level variable `name` using `cls.name`.

Overall, while it is possible to call a parent class method without instance creation, it may not always be the best approach depending on the specific use case.

Creating an Empty Class in Python

To create an empty class in Python, use the `class` keyword followed by the name of the class. For example, to create an empty class named `MyClass`, you would write:

python
class MyClass:
    pass

The `pass` keyword is used as a placeholder to indicate that the class is empty. If you define an empty class without the `pass` keyword, you will get a `SyntaxError`.

python
class Empty:
    #no pass keyword

Output:


IndentationError: expected an indented block

You can add attributes and methods to your class later as needed.

Difference between new and override modifiers in C#

In C#, both the 'new' and 'override' modifiers are used to modify the behavior of methods in derived classes that are inherited from a base class. However, the main difference between the 'new' and 'override' modifiers is how they handle method overrides.

'new' modifier:

  1. Creates a new method with the same name and signature as the base class method.
  2. Does not call the original base class method.
  3. Hides the base class method, so it can only be called through the base class reference.

'override' modifier:

  1. Modifies the base class method in the derived class.
  2. Uses the same method name, input parameters, and return type as the base class method.
  3. Requires that the base class method be marked as 'virtual' or 'abstract'.
  4. Allows the derived class to provide its own implementation of the method.

When to use each modifier:

  • Use 'new' when you want to create a method in the derived class that has the same name and signature as the base class method but with a different implementation.
  • Use 'override' when you want to modify the behavior of the base class method in the derived class.

//Example of using 'new' modifier:
class BaseClass
{
   public void MyMethod()
   {
      Console.WriteLine("Base class method");
   }
}

class DerivedClass : BaseClass
{
   public new void MyMethod()
   {
      Console.WriteLine("Derived class method");
   }
}

BaseClass b = new BaseClass();
DerivedClass d = new DerivedClass();

b.MyMethod(); //Output: "Base class method"
d.MyMethod(); //Output: "Derived class method"

BaseClass bd = new DerivedClass();
bd.MyMethod(); //Output: "Base class method"


Why is the "finalize" method used in Java?

In Java, the "finalize" method is used to perform any necessary cleanup actions for an object when it is no longer being used. This method is called by the garbage collector before the object is destroyed. The "finalize" method can be used to free up any resources that the object is holding onto, such as file handles or database connections. However, it is important to note that the "finalize" method should not be relied upon for critical cleanup tasks, as there is no guarantee as to when it will be called by the garbage collector. Overall, the use of the "finalize" method should be limited and alternative cleanup strategies should be considered when possible.

//Example usage of finalize method
class ExampleClass {
   //constructor
   ExampleClass() {
      //Object creation
   }
   
   //Finalize method
   protected void finalize() { 
      //cleanup actions
   } 
  
   //Other methods and variables
   ...
}

Explanation of the Python Initialization Method

In Python, the `__init__()` method is a class constructor method that is invoked automatically every time a new instance of the class is created. The main purpose of this method is to initialize the attributes of the class.

Here's an example:

class Dog: def __init__(self, name, breed): self.name = name self.breed = breed self.age = 0

def bark(self): print("Woof!")

my_dog = Dog("Fido", "Labrador") print(my_dog.name) # Output: Fido print(my_dog.breed) # Output: Labrador print(my_dog.age) # Output: 0 my_dog.bark() # Output: Woof!

In the above code, the `__init__()` method initializes the `name`, `breed`, and `age` attributes of the `Dog` class. The `self` parameter refers to the instance of the class that is being created.

The `bark()` method is also defined in the class, which prints "Woof!" to the console.

Finally, a new instance of the `Dog` class is created with the `name` and `breed` arguments, and then the attributes of the class are accessed using the dot notation.

Checking if a Class is a Subclass of Another Class

In Python, you can determine if a class is a subclass of another class by using the `issubclass()` function.

The syntax of this function is:

python
issubclass(subclass, superclass)

where `subclass` is the class you want to check, and `superclass` is the class you want to check if the subclass inherits from.

Example:

python
class Animal:
    pass

class Dog(Animal):
    pass

print(issubclass(Dog, Animal)) # True
print(issubclass(Animal, Dog)) # False

In this example, the `Animal` class is the superclass and the `Dog` class is the subclass. The `issubclass()` function returns `True` if `Dog` is a subclass of `Animal`, and `False` if `Animal` is a subclass of `Dog`.

Pandas Overview

Pandas is an open-source library that provides easy-to-use data structures and data analysis tools for Python. It is built on top of NumPy and is well-suited for working with structured data, such as data from spreadsheets and SQL databases.

Pandas provides two main data structures: Series for one-dimensional data and DataFrame for two-dimensional data. It also has a variety of functions for data manipulation, aggregation, filtering, and cleaning. Some common Pandas functions include `groupby`, `merge`, `pivot_table`, and `fillna`.

Overall, Pandas is a powerful tool for data analysis in Python and is widely used in industry and academia.

Definition of Pandas DataFrame

A pandas DataFrame is a two-dimensional tabular data structure with labeled axes (rows and columns). It is an efficient tool for data manipulation and analysis. It is similar to a spreadsheet or a SQL table, and has various methods to perform arithmetic operations, filtering, sorting, and merging of data.


import pandas as pd <br>
df = pd.DataFrame({‘A’: [1,2,3], ‘B’:[4,5,6]})<br>
print(df)

This code snippet creates a DataFrame with two columns labeled ‘A’ and ‘B’. The first column contains the values 1, 2, 3, and the second column contains 4, 5, 6.

Combining Pandas DataFrames

To combine different Pandas DataFrames, we can use methods such as `concat()`, `merge()`, and `join()`.

  • The `concat()` method is used for concatenating DataFrames vertically or horizontally
  • The `merge()` method is used for merging DataFrames based on common columns or indices
  • The `join()` method is used for joining DataFrames based on their indices

Here is an example of using `concat()` to combine two DataFrames vertically:


import pandas as pd

df1 = pd.DataFrame({'A': [1, 2, 3],
                    'B': [4, 5, 6]})

df2 = pd.DataFrame({'A': [4, 5, 6],
                    'B': [7, 8, 9]})

df_combined = pd.concat([df1, df2], axis=0)

print(df_combined)

This code will output a new DataFrame, `df_combined`, that combines `df1` and `df2` vertically (i.e., stacking the rows on top of each other).

We can also use `concat()` to combine DataFrames horizontally (i.e., adding new columns). To do this, we simply set the `axis` parameter to 1:


df3 = pd.DataFrame({'C': [10, 11, 12],
                    'D': [13, 14, 15]})

df_combined = pd.concat([df1, df3], axis=1)

print(df_combined)

This code will output a new DataFrame, `df_combined`, that combines `df1` and `df3` horizontally (i.e., adding the columns from `df3` to `df1`).

Note that in both cases, the indices of the original DataFrames are preserved in the combined DataFrame. We can use the `reset_index()` method to reset the index if desired.

Creating a Pandas Series from a Dictionary

Yes, you can create a Pandas Series from a dictionary object. This can be done by passing the dictionary into the `pd.Series()` method. The resulting Series will have the keys of the dictionary as the index labels and the values of the dictionary as the values in the Series.

Here is an example code snippet:


import pandas as pd

my_dict = {'apple': 3, 'banana': 5, 'orange': 2}

my_series = pd.Series(my_dict)

print(my_series)

This code will output the following:


apple     3
banana    5
orange    2
dtype: int64

Note that the index labels are the keys of the dictionary and the values are the values of the dictionary.

Identifying and Dealing with Missing Values in a DataFrame

In Python's Pandas library, missing values are typically represented by NaN or None. To identify and deal with missing values in a DataFrame, we can follow these steps:

1. Identify missing values: We can use the .isnull() method to identify all rows and columns containing missing values in a DataFrame. We can use .sum() to count the number of missing data points in each column.

2. Drop missing values: We can use the .dropna() method to remove any rows or columns containing missing values. By setting the axis parameter to 0 or 'rows', we can remove rows with missing values. By setting it to 1 or 'columns', we can remove columns.

3. Fill missing values: We can use the .fillna() method to fill missing values in a DataFrame with a specific value or a calculation. We can also use forward fill or backward fill methods to propagate the last valid observation forward or backward to replace missing values.

Example code:

python
import pandas as pd

# create a sample DataFrame with missing values
df = pd.DataFrame({'A': [1, 2, None, 4, 5],
                   'B': [None, 7, 8, 9, 10],
                   'C': [11, 12, 13, 14, None]})

# identify missing values
print(df.isnull().sum())

# drop missing values
df_dropped = df.dropna(axis=1)
print(df_dropped)

# fill missing values
df_filled = df.fillna(0) # fill with 0
print(df_filled)

df_ffill = df.fillna(method='ffill') # forward fill
print(df_ffill)

Understanding Reindexing in Pandas

Reindexing is a method in Pandas that changes the order of the rows and/or columns in a DataFrame or Series. It is done by creating a new object that conforms to the specified index.

For example, if you have a DataFrame with an index that ranges from 0 to 4, and you want to change it to range from 1 to 5, you can use the reindex method to create a new DataFrame with the same data, but with the new index.

The reindex method can also be used to add or remove rows and/or columns from a DataFrame or Series, and to fill in missing values with a default value or a specified fill method.

Overall, reindexing is a useful tool in Pandas for manipulating the structure of data in a DataFrame or Series to fit the needs of a particular analysis or visualization task.

Adding a New Column to a Pandas Dataframe

To add a new column to a Pandas dataframe, you can access the dataframe object and use brackets to create a new column, specifying the name of the new column inside quotes. For example:

import pandas as pd

# create a sample dataframe
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})

# add a new column to the existing dataframe
df['C'] = [7, 8, 9]

In this example, a new column named 'C' is added to the existing dataframe 'df'. The values for this new column are specified as a list [7, 8, 9].

You can also use mathematical operations between columns to create a new column. For example:

# add a new column 'D' as the sum of columns A and B
df['D'] = df['A'] + df['B']

In this case, a new column named 'D' is added to the dataframe, and its values are obtained by adding the values in columns 'A' and 'B'.

After adding a new column, make sure to save the dataframe object if you want to preserve the changes.

How to delete indices, rows, and columns from a dataframe?

To delete particular row or column from a dataframe, we can make use of the drop() function.

To delete an index
Syntax: df.drop(index_name)

To delete a column
Syntax: df.drop(column_name, axis=1)

To delete a row
Syntax: df.drop(row_index, axis=0)

Retrieving Items from Series A that are Not Available in Series B

Yes, it is possible to retrieve items from Series A that are not present in Series B. This can be achieved using the `isin()` function in Pandas library.

**Code:**

python
import pandas as pd

# Creating Series A and Series B
series_a = pd.Series([1, 2, 3, 4, 5])
series_b = pd.Series([3, 4, 5, 6, 7])

# Retrieving items from Series A that are not present in Series B
items_not_in_b = series_a[~series_a.isin(series_b)]

print(items_not_in_b)

In the code snippet, we first import the Pandas library and create two Series - A and B. The `isin()` function checks for each element in Series A if it is present in Series B or not. The `~` operator is used to invert the boolean mask so that we can retrieve items from Series A that are not present in Series B.

The output will be a new Series containing the items that are not available in Series B.

Finding Non-Common Items between Two Series

To obtain the items that are not common to both Series A and B, you can use the set difference operation. This can be achieved using the "-" operator or the difference() function in Python. Here's an example:

Code:


series_a = [1, 2, 3, 4, 5]
series_b = [4, 5, 6, 7, 8]

non_common_items = set(series_a) - set(series_b)

print(non_common_items)

Output:


{1, 2, 3}

Here, we first convert `series_a` and `series_b` to sets and then use the set difference operation to obtain non-common items. In this case, the items 1, 2, and 3 are present in `series_a`, but not in `series_b`.

Note: If you want to obtain non-common items from both `series_a` and `series_b`, you can use the symmetric difference operation using "^" operator or symmetric_difference() function in Python.

Can Pandas Library Recognize Dates When Importing Data from Different Sources?

Yes, the Pandas library has the ability to recognize dates when importing data from different sources. One way to do this is by using the `read_csv` function and specifying the `parse_dates` parameter to the column(s) containing dates. For example:

python
import pandas as pd

data = pd.read_csv('file.csv', parse_dates=['date_column'])

This will automatically parse the dates in the `date_column` and convert them to the `datetime` data type. Additionally, Pandas provides several other functions for working with dates, such as `to_datetime` and `date_range`, that make it easy to manipulate dates within the DataFrame.

What is NumPy?

NumPy is a Python library used for numerical operations. It stands for Numerical Python. NumPy provides support for large arrays and matrices, along with a large collection of high-level mathematical functions to operate on these arrays. It is an essential library for scientific and data analysis in Python.

Advantages of NumPy Arrays over Python Lists

In terms of handling numerical calculations and data, NumPy arrays offer the following advantages over Python lists:

1.

Speed: NumPy arrays are faster and more efficient for numerical calculations and operations.

2.

Size: NumPy arrays take up less memory than Python lists.

3.

Functionality: NumPy arrays have built-in functions for data processing and analysis, such as statistical and linear algebra functions.

4.

Compatibility: NumPy arrays can easily be integrated with other libraries and tools for data analysis and scientific computing in Python, such as Pandas and SciPy.

Overall, NumPy arrays are a more powerful and efficient tool for numerical computing and data analysis in Python compared to Python lists.

Steps to Create 1D, 2D, and 3D Arrays

To create arrays in programming languages like C++, Java, Python, and others, the following steps are usually followed:

1D Array:

1. Declare the array type and name.
Example:

int arr[5];

2. Assign values to the array using a loop or individually.
Example:

c++
for(int i=0;i<5;i++){
  arr[i] = i+1;
}

2D Array:

1. Declare the array type, name, rows, and columns.
Example:

int arr[3][3];

2. Assign values to the array using nested loops or individually.
Example:

c++
for(int i=0;i<3;i++){
  for(int j=0;j<3;j++){
    arr[i][j] = i+j;
  }
}

3D Array:

1. Declare the array type, name, rows, columns, and depth.
Example:

int arr[2][3][4];

2. Assign values to the array using nested loops or individually.
Example:

c++
for(int i=0;i<2;i++){
  for(int j=0;j<3;j++){
    for(int k=0;k<4;k++){
      arr[i][j][k] = i+j+k;
    }
  }
}

Replacing a Column in a NumPy Array

Assuming we want to replace the second column with a new column, the following code shows one way to accomplish this:


import numpy as np

# create a sample array
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# create a new column with the same number of rows as the array
new_col = np.array([10, 11, 12])

# delete the second column (index 1) and insert the new column in its place
arr = np.delete(arr, 1, 1)
arr = np.insert(arr, 1, new_col, axis=1)

print(arr)

This code creates a 2-dimensional NumPy array with 3 rows and 3 columns, then creates a new column with 3 values to replace the second column of the array. The

np.delete

function removes the second column (index 1), and the

np.insert

function inserts the new column at index 1.

The code then prints the resulting array, which should have the same number of rows as the original array, but with the second column replaced by the new column.

Efficiently Loading Data from a Text File

To efficiently load data from a text file, you can follow these steps:

1. Open the file using the appropriate file handling function in Python. 2. Use a loop to read each line of the text file. 3. For each line, split the data values into a list using a delimiter, such as a comma or a tab. 4. Convert the data type of each value as necessary using Python's built-in functions such as int() or float(). 5. Append the processed data to a list or any other appropriate data structure in Python.

Here's an example code snippet that demonstrates these steps:


data = []

with open('my_file.txt', 'r') as f:
    for line in f:
        # remove any leading/trailing whitespaces and split the line into a list
        values = line.strip().split(',')
        
        # convert the data type of each value and append to the list
        try:
            converted_values = [int(val) for val in values]
            data.append(converted_values)
        except ValueError:
            print(f"Skipping line: {line}. Expected integer values.")

In this example, the code reads each line of a text file named 'my_file.txt'. It then uses a comma as the delimiter to split the line into a list of values. The code attempts to convert each value to an integer using a list comprehension and appends the resulting list to the 'data' list. If some values cannot be converted to integers, the code will skip that line and print a warning message.

By following these steps, you can efficiently load data from a text file in Python.

Reading CSV Data into a NumPy Array

To read CSV data into a NumPy array, first, we need to import the NumPy module. We can use the `numpy.genfromtxt()` function to read the CSV file and store the data in a NumPy array.

Here's a sample code that reads a CSV file named 'data.csv' and stores its data in a 2-d NumPy array:

Code:

python
import numpy as np

data = np.genfromtxt('data.csv', delimiter=',')

In the above code, `np.genfromtxt()` is used to read the data from the 'data.csv' file. The `delimiter` attribute is set to ',' to indicate that the values in the CSV file are separated by a comma.

You can also specify different data types for each column using the `dtype` parameter. Here's how you can do it:

python
data = np.genfromtxt('data.csv',
                     delimiter=',',
                     dtype=[('name', 'S20'), ('age', 'i4'), ('salary', 'f4')])

In the above code, we are specifying the `dtype` parameter with a list of tuples, where each tuple contains the name of the column and its data type.

That's it! You can now perform various operations on the NumPy array obtained from the CSV data.

Sorting Array based on the nth Column

To sort an array based on the nth column, we can use the `sort()` function in JavaScript. Here's an example code:

javascript
// Sample array
var arr = [
  [4, 6, 2],
  [7, 3, 9],
  [10, 1, 5]
];

var n = 1; // Sort based on the second column (index 1)

// Sort the array
arr.sort(function(a, b) {
  return a[n] - b[n];
});

// Display the sorted array
console.log(arr);

In the above code, we have a sample array with three rows and three columns. We want to sort the array based on the second column (index 1), which contains the values 6, 3, and 1.

To accomplish this, we use the `sort()` function and pass in a comparison function as a parameter. This function takes in two parameters, `a` and `b`, which represent the current row being compared and the next row being compared, respectively.

Inside the comparison function, we access the nth column by using the index `n`. We then subtract the value of `b[n]` from `a[n]` to determine the correct order.

Finally, we display the sorted array using the `console.log()` function.

Finding the Nearest Value in a Numpy Array

To find the nearest value in a given numpy array, you can use the `numpy.abs()` function to get the absolute difference between each element in the array and the given value. Then, you can use the `numpy.argmin()` function to find the index of the element with the smallest absolute difference. Finally, you can use the index to get the nearest value from the array.

Here's the code:


import numpy as np

def find_nearest(array, value):
    """
    Function that finds the nearest value in a numpy array
    :param array: numpy array
    :param value: scalar value
    :return: element of the input array that is nearest to the given value
    """
    idx = np.abs(array - value).argmin()
    return array[idx]

You can call this function with your numpy array and the value you want to find the nearest element to:


my_array = np.array([1.2, 3.5, 5.1, 7.9, 9.3])
nearest_val = find_nearest(my_array, 4.8)
print(nearest_val)

In this example, the nearest value in the array `[1.2, 3.5, 5.1, 7.9, 9.3]` to the value `4.8` is `5.1`.

Reverse a NumPy Array in One Line of Code

To reverse a NumPy array using only one line of code, you can use the following:

numpy_array[::-1]

This method uses array slicing to reverse the order of the elements in the array. The

::

signifies the start and end of the array, while

-1

indicates the stride to use when moving through the array. Specifying a stride of

-1

effectively reverses the order of the array.

Here's an example:

import numpy as np

arr = np.array([1,2,3,4,5])

print(arr[::-1])

Output:

[5 4 3 2 1]

H3. Finding the Shape of a NumPy Array

To find the shape of a NumPy array, you can use the `.shape` attribute. This will return a tuple containing the length of each dimension of the array.

Code:


import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])

print(arr.shape)

Output:


(2, 3)

This means that the NumPy array `arr` has two rows and three columns.

Difference between a Package and a Module in Python

In Python, a module is a single file that contains Python definitions, statements, and functions. A package, on the other hand, is a collection of related modules that are stored in a directory and have an __init__.py file.

Packages can be nested, meaning a package can contain other packages as well as modules. Modules can be accessed from inside the package by importing them using their names.

For example, let's say we have a package named "animals" with modules for different types of animals: dogs, cats, and birds. The directory structure would look like this:


/animals
    __init__.py
    /dogs
        __init__.py
        labrador.py
        poodle.py
    /cats
        __init__.py
        persian.py
        siamese.py
    /birds
        __init__.py
        parrot.py
        canary.py

To use a specific module from the animals package, we would import it like this:


from animals.dogs import labrador

This would import the labrador module from the dogs package within the animals package.

In summary, while a module contains code to perform a specific function, a package is a collection of related modules and sub-packages that provide a complete solution for a particular problem domain.

Most commonly used built-in modules in Python

Python has a plethora of built-in modules that make it a versatile programming language. Some of the most commonly used built-in modules in Python are:

math

- for mathematical calculations

os

- for operating system related tasks

datetime

- for working with dates and times

random

- for generating random numbers

json

- for parsing and creating JSON data

Other commonly used modules include

csv

,

sys

,

re

,

urllib

,

argparse

, and

unittest

.

Lambda Functions in Python

Lambda functions, also known as anonymous functions, are small, single-expression functions without a name in Python. They are useful when you need a short function, typically for use in a functional programming paradigm.

Lambda functions are defined using the `lambda` keyword, followed by the function arguments, a colon, and the expression to be evaluated. For example:


square = lambda x: x**2

Here, the `lambda` function takes in an argument `x` and returns its square. The `square` variable is now a function object that can be called with an argument to produce the result.

Lambda functions are often used in conjunction with other functions that expect a function object as an argument, such as `map`, `filter`, and `reduce`. They can also be assigned to variables, used in conditional statements, and passed as arguments to other functions.

Overall, lambda functions provide a simple and concise way to create small, one-off functions in Python without the need for a formal definition.

Generating Random Numbers in Java

In Java, you can generate random numbers using the `java.util.Random` class. Here's an example code that generates a random integer between 0 and 10:


import java.util.Random;

public class RandomNumberGenerator {
    public static void main(String[] args) {
        Random random = new Random();
        int randomNumber = random.nextInt(11); // generates a random number between 0 and 10
        System.out.println("Random number: " + randomNumber);
    }
}

In the code above, we first import the `java.util.Random` class. Then, we create a new instance of the `Random` class. Finally, we use the `nextInt()` method to generate a random integer between 0 (inclusive) and 11 (exclusive), and we print the result to the console.

You can also generate double and float random numbers using the `nextDouble()` and `nextFloat()` methods of the `Random` class, respectively. For example:


import java.util.Random;

public class RandomNumberGenerator {
    public static void main(String[] args) {
        Random random = new Random();
        double randomDouble = random.nextDouble(); // generates a random double between 0.0 (inclusive) and 1.0 (exclusive)
        float randomFloat = random.nextFloat(); // generates a random float between 0.0f (inclusive) and 1.0f (exclusive)
        System.out.println("Random double: " + randomDouble);
        System.out.println("Random float: " + randomFloat);
    }
}

Note that the `Random` class uses a seed value to generate pseudo-random numbers. If you don't provide a seed value, it uses the current time in milliseconds as the default seed. Therefore, if you create multiple instances of the `Random` class without specifying a seed, you may get the same sequence of random numbers. To avoid this, you can use a single instance of the `Random` class throughout your program, or provide a seed value when creating new instances of the class.

Checking if a String is Alphanumeric in Java

Yes, you can easily check if all characters in a given string are alphanumeric in Java by using the isAlphanumeric() method of the StringUtils class. This method returns true if the string contains only letters or digits, and false otherwise. Here's an example:


import org.apache.commons.lang3.StringUtils;

public class AlphanumericChecker {
    public static void main(String[] args) {
        String str1 = "abc123";
        String str2 = "abc#123";

        System.out.println(StringUtils.isAlphanumeric(str1)); // true
        System.out.println(StringUtils.isAlphanumeric(str2)); // false
    }
}

In this example, we import the StringUtils class from the Apache Commons Lang library to use the isAlphanumeric() method. We then create a main() method where we define two strings, str1 and str2. We pass each string to the isAlphanumeric() method and print the result to the console.

The output of this program will be:


true
false

So, we see that the isAlphanumeric() method correctly identifies which strings are alphanumeric and which are not.

Differences between pickling and unpickling

Pickling and unpickling are two processes in Python for serializing and deserializing data. The main differences between pickling and unpickling are:

  • Pickling involves converting a Python object to a byte stream, while unpickling involves converting the byte stream back to a Python object.
  • Pickling is useful for storing data, transmitting data over a network, or sending data to another process, while unpickling is useful for loading data from a file or receiving data from another process.
  • Pickling can be used to store any object in Python, while unpickling can only be used to load objects that were previously pickled.
  • Pickling and unpickling should only be used for trusted data, as unpickling can execute arbitrary code.

# Example of Pickling and Unpickling
import pickle
 
# Creating dictionary
dictionary = {'key': 'value', 'key2': 'value2'}
 
# Pickling the dictionary
pickled_dict = pickle.dumps(dictionary)
 
# Unpickling the dictionary
unpickled_dict = pickle.loads(pickled_dict)
 
# Printing the original and unpickled dictionary
print('Original Dictionary:', dictionary)
print('Unpickled Dictionary:', unpickled_dict)


What is PYTHONPATH in Python?

In Python, PYTHONPATH is an environment variable that tells the interpreter where to locate the module files imported into a program. It is essentially a list of directories that Python searches for when you import a module in your code. When you import a module, Python searches for it in all the directories listed in the PYTHONPATH variable, in the order they are listed.

By default, PYTHONPATH is set to the working directory, which means that Python will search for modules in the same directory as the script you are running. However, if you have module files in a separate directory, you can add that directory to the PYTHONPATH variable so that Python can find them.

You can set the PYTHONPATH variable in several ways, such as using the command line, modifying the system environment variables, or adding it to your code using the sys.path.append() method.

Tools for bug identification and static analysis in Python

Are there any tools available for identifying bugs and performing static analysis in Python?

Difference between Deep and Shallow Copies

Deep copy and shallow copy are two ways to copy or clone a variable or object in Python. The main difference between these two types of copy is that a deep copy creates a new object with a new memory address, while a shallow copy creates a new object that points to the same memory addresses as the original object.

In simple terms, a deep copy creates a completely independent copy of the original object, while a shallow copy creates a copy that is linked to the original object. If you make changes to the original object after creating a shallow copy, those changes will also be reflected in the shallow copy, but they will not be reflected in a deep copy.

For example, consider a list object "my_list" with elements [1, 2, [3, 4]]. A shallow copy of this list would create a new list that points to the same memory address as the original list, so any changes made to the original list would also be visible in the shallow copy. A deep copy of this list would create a new list with a new memory address, so any changes made to the original list would not affect the deep copy.

Code Examples:


import copy

# creating a list
my_list = [1, 2, [3, 4]]

# shallow copy
shallow_copy = copy.copy(my_list)

# deep copy
deep_copy = copy.deepcopy(my_list)

# modifying the original list
my_list[2][0] = 5

# checking the values in each copy
print("Original List:", my_list)
print("Shallow Copy:", shallow_copy)
print("Deep Copy:", deep_copy)

In the above example, we use the "copy" module to create shallow and deep copies of our list object. We then modify the original list by changing the first element of the nested list. We then print out the values of each copy to see how they have been affected.

As you can see, the shallow copy has been affected by the change to the original list, while the deep copy has not.

Explanation:

The main function in Python is the entry point of any program. It is where the program starts executing. In Python, the main function is defined using the `def` keyword. The main function can be invoked by calling it anywhere in the program or by using the `if __name__ == "__main__"` statement.

When a Python file is executed, Python interpreter sets the special variable `__name__` to `"__main__"`. If the `__name__` variable in a module is equal to `"__main__"`, it means that it is the main module of the program, and its main function will be executed.

Here is an example of how to define and invoke the main function in Python:

def main(): print("Hello, world!")

if __name__ == "__main__": main()

In this example, we define the `main()` function to print `"Hello, world!"`. Then, we use the `if __name__ == "__main__"` statement to check whether the current module is the main module, and if so, we invoke the `main()` function.

Python Program: Function with Variable Number of Arguments


    
    def find_sum(*args):
        sum = 0
        for num in args:
            sum += num
        return sum

    # Test the function
    print(find_sum(1, 2, 3, 4)) # Output: 10
    print(find_sum(3, 5))      # Output: 8
    print(find_sum(2, 4, 6))   # Output: 12

In the above Python program, we have created a function find_sum() that takes a variable number of arguments using the asterisk (*) symbol before the parameter name. Inside the function, a for loop is used to iterate through all the numbers in the arguments and add them up. The final sum is returned to the calling function. We have tested the function by passing different argument sets and checking the sum output.

Checking for Unique Numbers in a Sequence


def check_unique(sequence):
    """
    This function takes a sequence of numbers as input and checks whether all numbers are unique.
    Returns True if all numbers are unique, otherwise returns False.
    """
    if len(sequence) == len(set(sequence)):
        return True
    else:
        return False
    
# Example usage
sequence1 = [1, 2, 3, 4, 5] # All numbers are unique
print(check_unique(sequence1)) # Output: True

sequence2 = [1, 2, 3, 4, 4] # Duplicate number
print(check_unique(sequence2)) # Output: False

The code above defines a function called "check_unique" which checks if all numbers in a sequence are unique. It takes a sequence of numbers as its input and returns True if all numbers are unique, otherwise it returns False.

To check if the sequence has unique numbers, we compare the length of the input sequence to the length of the set of the sequence. If both lengths are equal, it means that all numbers in the sequence are unique. If not, it means that the sequence has duplicate numbers.

The function is demonstrated using two examples, where sequence1 has all unique numbers and sequence2 has a duplicate number. The output shows that the function correctly identifies the uniqueness in both the sequences.

Counting Characters in a Text File


filename = 'example.txt'   # replace with desired filename

# opening file in read mode
with open(filename, 'r') as file:
    data = file.read()

# counting occurrence of each character and storing in dictionary
char_count = {}
for char in data:
    if char in char_count:
        char_count[char] += 1
    else:
        char_count[char] = 1

# displaying character count
for key, value in char_count.items():
    # ignoring special characters and white spaces
    if key.isalnum():
        print(key, ':', value)

The above program reads a text file, counts the occurrence of each character, and displays the count in the console. The file to be processed is specified by assigning its filename to the variable 'filename'. The program then opens the file in read mode, reads the file content, and stores it in a string variable 'data'.

The program then performs character counting by iterating through each character in 'data' and incrementing the count for each occurrence of the character. The counts are stored in a dictionary named 'char_count', with the character as the key and the count as the value.

Finally, the program prints the character count for each character that is alphanumeric (i.e., alphabets and digits) and ignores special characters and white spaces.

Program to Find Pairs in an Array That Add Up to a Target Value


function findPairs(array, target) {
  const pairs = [];
  const len = array.length;

  // iterate over each element in the array
  for (let i = 0; i < len; i++) {
    // iterate over remaining elements to find pairs
    for (let j = i + 1; j < len; j++) {
      if (array[i] + array[j] === target) {
        pairs.push([array[i], array[j]]);
      }
    }
  }

  // return pairs that add up to target
  return pairs;
}

// example usage
const arr = [3, 4, 5, 6, 7];
const targetVal = 10;
const result = findPairs(arr, targetVal);

console.log(result); // outputs [[3, 7], [4, 6]]

This program defines a function

findPairs

that takes an array and a target value as arguments. It then iterates over the array, and for each element, it iterates over the remaining elements to find any pairs that add up to the target value. When it finds a pair, it adds it to the

pairs

array. Finally, the function returns the

pairs

array.

The example usage section demonstrates how to call the function and save the result to a variable. It then logs the result to the console. In this case, the array

[3, 4, 5, 6, 7]

has two pairs of elements that add up to 10:

[3, 7]

and

[4, 6]

.

Program to add two integers without using the plus operator


//Function to add two integers without using the plus operator
function addIntegers(num1, num2) {
   while(num2 != 0) {
      //carry contains common bits of num1 and num2
      const carry = num1 & num2;

      //sum of bits of num1 and num2 that are different
      num1 = num1 ^ num2;

      //shifts carry to 1 bit to calculate sum
      num2 = carry << 1;
   }
   return num1;
}

//Example
const num1 = 12;
const num2 = 8;
const sum = addIntegers(num1, num2);
console.log("Sum of " + num1 + " and " + num2 + " is: " + sum);

This program uses bitwise operators to add two positive integers without using the plus operator. "num1" and "num2" are the integer inputs, and the function "addIntegers" takes them as parameters. The while loop keeps running until num2 becomes zero. The carry contains common bits of num1 and num2, and the sum of bits of num1 and num2 that are different. The carry is shifted to 1 bit to calculate the sum. Finally, the sum of the two integers is returned. As an example, the program adds 12 and 8 without using the plus operator and prints the sum.

Program to Solve a Given Equation with Constants a, b, c, m, n, o


  // taking input values of constants from user
  let a = parseFloat(prompt("Enter the value of 'a' constant:"));
  let b = parseFloat(prompt("Enter the value of 'b' constant:"));
  let c = parseFloat(prompt("Enter the value of 'c' constant:"));
  let m = parseFloat(prompt("Enter the value of 'm' constant:"));
  let n = parseFloat(prompt("Enter the value of 'n' constant:"));
  let o = parseFloat(prompt("Enter the value of 'o' constant:"));

  // equation to be solved
  let result = ((a * b * c) / (m * n)) - o;

  // printing the result on the console
  console.log(`Result: ${result}`);

This program takes the constants a, b, c, m, n, and o as input from the user and then solves the given equation by using the input values. The result is then printed on the console.

Matching a String with 'A' followed by 4 to 8 'B's


string = input("Enter a string: ")  # taking input from user

# using regex to match string with 'A' followed by 4 to 8 'B's
import re
if re.match(r"A[bB]{4,8}", string):
  print("Match found!")
else:
  print("Match not found.")

This program prompts the user to enter a string and uses regular expression to match the string if it contains 'A' followed by 4 to 8 'B's. The

re.match()

function is used to match the pattern with the input string. The pattern used in the program is

A[bB]{4,8}

, where:

  • A

    matches the character 'A'

  • [bB]

    matches any character 'b' or 'B'

  • {4,8}

    matches the preceding character or character set (i.e., [bB]) for 4 to 8 times only

Converting Date Format


# This program converts a date string from yyyy-mm-dd format to dd-mm-yyyy format.

date_string = input("Enter a date in yyyy-mm-dd format: ")

# Splitting the date string into year, month, and day
date_list = date_string.split("-")

# Reversing the date list to dd-mm-yyyy format
date_list.reverse()

# Joining the date list to a string with "-" separator
new_date_string = "-".join(date_list)

print("The date in dd-mm-yyyy format is:", new_date_string)

This program prompts the user to enter a date in yyyy-mm-dd format and then converts the date string to dd-mm-yyyy format. The date string is split into a list of year, month, and day, which is then reversed to put the day first. Finally, the reversed list is joined into a new date string with a "-" separator.

Combining Two Dictionaries

This code will take two dictionaries and merge them together. If there are duplicate keys in the dictionaries, their values will be added.


def merge_dict(dict1, dict2):
    """
    This function takes two dictionaries and merges them.
    If there are duplicate keys, their values are added.
    """
    for key in dict2:
        if key in dict1:
            dict1[key] += dict2[key]
        else:
            dict1[key] = dict2[key]
    return dict1

dict1 = {'a': 10, 'b': 20, 'c': 30}
dict2 = {'b': 5, 'c': 15, 'd': 25}

merged_dict = merge_dict(dict1, dict2)
print(merged_dict)

Output: {'a': 10, 'b': 25, 'c': 45, 'd': 25}

Accessing a Public CSV Dataset in Google Drive

To access a publicly shared CSV dataset stored in Google Drive, you can follow these steps:

1. Open a web browser and go to the Google Drive website. 2. Search for the CSV dataset file you want to access by clicking on the magnifying glass icon and entering the file name or relevant keywords. 3. Once you find the file, right-click on it and select the "Get link" option. 4. In the "Link sharing" window that appears, make sure that "Anyone with the link" is selected under "Link sharing on." 5. Copy the link provided in the "Link to share" field. 6. Open a code editor or Jupyter notebook and use the pandas library to read in the CSV file using the link you copied. For example:


import pandas as pd

url = "paste the copied link here"
df = pd.read_csv(url)

7. You should now have access to the dataset and be able to manipulate it using pandas methods.

Technical Interview Guides

Here are guides for technical interviews, categorized from introductory to advanced levels.

View All

Best MCQ

As part of their written examination, numerous tech companies necessitate candidates to complete multiple-choice questions (MCQs) assessing their technical aptitude.

View MCQ's
Made with love
This website uses cookies to make IQCode work for you. By using this site, you agree to our cookie policy

Welcome Back!

Sign up to unlock all of IQCode features:
  • Test your skills and track progress
  • Engage in comprehensive interactive courses
  • Commit to daily skill-enhancing challenges
  • Solve practical, real-world issues
  • Share your insights and learnings
Create an account
Sign in
Recover lost password
Or log in with

Create a Free Account

Sign up to unlock all of IQCode features:
  • Test your skills and track progress
  • Engage in comprehensive interactive courses
  • Commit to daily skill-enhancing challenges
  • Solve practical, real-world issues
  • Share your insights and learnings
Create an account
Sign up
Or sign up with
By signing up, you agree to the Terms and Conditions and Privacy Policy. You also agree to receive product-related marketing emails from IQCode, which you can unsubscribe from at any time.