0% found this document useful (0 votes)
7 views

python

The document contains a series of questions and answers related to Python programming concepts, including Pure Functions, class design, Operator Overloading, Polymorphism, and database keys. It also covers web scraping with BeautifulSoup, JSON parsing, API security considerations, and SQL JOIN types. Each section provides explanations, examples, and code snippets to illustrate the concepts discussed.

Uploaded by

4MH21EC048
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

python

The document contains a series of questions and answers related to Python programming concepts, including Pure Functions, class design, Operator Overloading, Polymorphism, and database keys. It also covers web scraping with BeautifulSoup, JSON parsing, API security considerations, and SQL JOIN types. Each section provides explanations, examples, and code snippets to illustrate the concepts discussed.

Uploaded by

4MH21EC048
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 35

Question Paper 1

1. Explain the concept of Pure Functions in Python and discuss their benefits with an example.
o Answer: Pure functions are functions that, given the same inputs, will always return the same
outputs without causing any observable side effects. This means they do not alter any state or
data outside the function, nor do they rely on any external state. Benefits of pure functions
include easier testing, as they are deterministic and do not depend on external state. They are
also easier to debug, reason about, and parallelize.
Example:
python
Copy code
def add(a, b):
return a + b

result1 = add(2, 3) # result1 = 5


result2 = add(2, 3) # result2 = 5 (same inputs yield same outputs)
In the above example, the add function is pure because it always returns the same result for the same inputs, and
it does not modify any external state or depend on any external variables.
2. Design a Python class Time to represent time in hours and minutes. Implement methods to add
and subtract time, and override the __str__ method to print the time in a "hh
" format.
o Answer: The Time class represents time and includes methods for adding and subtracting time.
The __str__ method is overridden to provide a string representation of the time in "hh
" format. This implementation includes error handling for cases where the minutes exceed 60 or fall below 0.
python
Copy code
class Time:
def __init__(self, hours=0, minutes=0):
self.hours = hours
self.minutes = minutes

def add_time(self, t):


self.hours += t.hours
self.minutes += t.minutes
if self.minutes >= 60:
self.hours += self.minutes // 60
self.minutes = self.minutes % 60
def subtract_time(self, t):
self.hours -= t.hours
self.minutes -= t.minutes
if self.minutes < 0:
self.hours -= 1 + (-self.minutes // 60)
self.minutes = self.minutes % 60

def __str__(self):
return f"{self.hours:02}:{self.minutes:02}"

t1 = Time(2, 30)
t2 = Time(1, 45)
t1.add_time(t2)
print(t1) # Output: 04:15
t1.subtract_time(t2)
print(t1) # Output: 02:30
This Time class allows for manipulation of time objects by adding or subtracting time while ensuring the
minutes are within the range of 0 to 59.
3. What is Operator Overloading in Python? Provide an example with the + operator and discuss its
advantages.
o Answer: Operator overloading in Python allows custom implementation of operators (like +, -, *,
etc.) for user-defined classes. It provides a way to define the behavior of these operators based
on the operands. For example, the + operator can be overloaded to concatenate objects or
perform addition based on the context.
Example:
python
Copy code
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y

def __add__(self, other):


return Vector(self.x + other.x, self.y + other.y)

def __str__(self):
return f"Vector({self.x}, {self.y})"

v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2
print(v3) # Output: Vector(4, 6)
In this example, the + operator is overloaded to add two Vector objects by adding their corresponding
components. Operator overloading provides a more intuitive interface for class users and allows objects to be
manipulated using standard operators.
4. Discuss the differences between Polymorphism and Inheritance in object-oriented programming
with examples.
o Answer:
▪ Inheritance allows a class (called a subclass or derived class) to inherit attributes and
methods from another class (called a superclass or base class). It promotes code reuse
and establishes a relationship between the superclass and subclass.
▪ Polymorphism allows objects of different classes to be treated as objects of a common
superclass. It enables a single interface to represent different underlying forms (data
types).
Example of Inheritance:
python
Copy code
class Animal:
def speak(self):
pass

class Dog(Animal):
def speak(self):
return "Woof!"

class Cat(Animal):
def speak(self):
return "Meow!"
Here, Dog and Cat inherit from Animal and provide specific implementations of the speak method.
Example of Polymorphism:
python
Copy code
def make_animal_speak(animal):
print(animal.speak())

dog = Dog()
cat = Cat()
make_animal_speak(dog) # Output: Woof!
make_animal_speak(cat) # Output: Meow!
The make_animal_speak function demonstrates polymorphism as it works with any object that inherits from
Animal and implements the speak method.
5. Describe the process of retrieving an image over HTTP using Python, detailing the use of libraries
and handling potential errors.
o Answer: Retrieving an image over HTTP in Python can be done using the requests library, which
simplifies sending HTTP requests. The process involves sending a GET request to the image
URL and saving the content received in the response. Error handling is essential to manage
issues like network errors or invalid URLs.
Example:
python
Copy code
import requests

def download_image(url, filename):


try:
response = requests.get(url, stream=True)
response.raise_for_status() # Check for HTTP request errors
with open(filename, 'wb') as file:
for chunk in response.iter_content(8192):
file.write(chunk)
print(f"Image saved as {filename}")
except requests.exceptions.HTTPError as http_err:
print(f"HTTP error occurred: {http_err}")
except Exception as err:
print(f"Other error occurred: {err}")

image_url = "http://example.com/image.jpg"
download_image(image_url, "image.jpg")
This script downloads an image and saves it as image.jpg. It uses response.iter_content(8192) to download the
file in chunks, which is memory efficient. Error handling ensures that any issues during the request are properly
reported.
6. What is BeautifulSoup? How is it used in web scraping? Provide an example to extract all
hyperlinks from a webpage.
o Answer: BeautifulSoup is a Python library used for parsing HTML and XML documents. It
provides Pythonic idioms for iterating, searching, and modifying the parse tree. It is commonly
used in web scraping to extract data from websites by navigating through the HTML elements.
Example:
python
Copy code
from bs4 import BeautifulSoup
import requests

url = "http://example.com"
response = requests.get(url)
soup = BeautifulSoup(response.content, "html.parser")

links = soup.find_all('a')
for link in links:
print(link.get('href'))
In this example, BeautifulSoup is used to parse the HTML content of a webpage. The find_all method is used to
find all <a> tags, which are typically used for hyperlinks, and the get method retrieves the href attribute, which
contains the URL.
7. Explain the concept of JSON and how to parse JSON data in Python. Discuss common operations
and provide an example.
o Answer: JSON (JavaScript Object Notation) is a lightweight data interchange format that is easy
for humans to read and write and easy for machines to parse and generate. It is often used to
transmit data between a server and a web application. In Python, the json module provides
functions to parse JSON data into Python dictionaries and vice versa.
Example:
python
Copy code
import json

# JSON string
json_data = '{"name": "John", "age": 30, "city": "New York"}'
# Parse JSON into Python object (dictionary)
data = json.loads(json_data)
print(data["name"]) # Output: John

# Convert Python object back to JSON


json_string = json.dumps(data)
print(json_string) # Output: {"name": "John", "age": 30, "city": "New York"}
Common operations include converting JSON strings to Python dictionaries (json.loads) and converting Python
objects to JSON strings (json.dumps). JSON is widely used in APIs for data interchange.
8. What are the three kinds of keys in database design? Explain each with an example and discuss
their importance in relational databases.
o Answer:
▪ Primary Key: A unique identifier for each record in a database table. It ensures that each
record can be uniquely identified.
▪ Example: In a users table, the user_id column can be a primary key.
▪ Foreign Key: A field in one table that uniquely identifies a row of another table. It
establishes a link between the data in two tables.
▪ Example: In an orders table, a user_id column can be a foreign key referencing
the user_id in the users table.
▪ Candidate Key: A column or set of columns that can uniquely identify a record in a
table, from which the primary key is chosen.
▪ Example: In an employees table, both employee_id and email can serve as
candidate keys if both are unique.
The importance of these keys lies in maintaining data integrity and relationships between tables. They ensure
that each record is unique (primary key), maintain referential integrity (foreign key), and provide alternatives
for primary key selection (candidate keys).

Question Paper 2
1. Explain the concept of Modifiers in Python functions. Discuss the implications of using mutable
and immutable types with examples.
o Answer: Modifiers in Python functions are methods that modify the state of an object or change
the function's arguments. When using mutable types (like lists or dictionaries), modifications
within a function persist after the function call. With immutable types (like integers, strings, and
tuples), modifications result in the creation of new objects.
Mutable Example:
python
Copy code
def add_item_to_list(lst, item):
lst.append(item)
return lst
my_list = [1, 2, 3]
print(add_item_to_list(my_list, 4)) # Output: [1, 2, 3, 4]
print(my_list) # Output: [1, 2, 3, 4]
In this example, the list my_list is modified inside the function because lists are mutable.
Immutable Example:
python
Copy code
def add_to_number(num, value):
num += value
return num

original_number = 10
new_number = add_to_number(original_number, 5)
print(original_number) # Output: 10
print(new_number) # Output: 15
Here, original_number remains unchanged because integers are immutable in Python.
2. Create a Python program that retrieves a webpage using urllib, handles potential errors, and
prints the HTML content.
o Answer: The urllib library in Python provides a simple interface for network resource access.
The following example demonstrates how to fetch and print the content of a webpage, along
with error handling for common issues like network errors or invalid URLs.
python
Copy code
import urllib.request
import urllib.error

url = "http://example.com"
try:
response = urllib.request.urlopen(url)
html = response.read().decode('utf-8')
print(html)
except urllib.error.URLError as e:
print(f"Failed to retrieve the page: {e.reason}")
except urllib.error.HTTPError as e:
print(f"HTTP error occurred: {e.code}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
This script attempts to retrieve the HTML content of a webpage. It handles URLError for issues like network
connectivity, HTTPError for HTTP response errors, and a generic Exception for any other unforeseen issues.
3. What is Type-based dispatch in Python? Provide an example that demonstrates its use with a
custom hierarchy of shapes.
o Answer: Type-based dispatch, or method overloading by type, is a technique where the method
called depends on the type of the argument passed. This can be implemented using function
annotations or checking the type explicitly within a function.
Example:
python
Copy code
class Shape:
def area(self):
raise NotImplementedError("Subclasses should implement this!")

class Circle(Shape):
def __init__(self, radius):
self.radius = radius

def area(self):
return 3.14 * (self.radius ** 2)

class Square(Shape):
def __init__(self, side):
self.side = side

def area(self):
return self.side ** 2

def calculate_area(shape: Shape):


if isinstance(shape, Circle):
return f"Circle area: {shape.area()}"
elif isinstance(shape, Square):
return f"Square area: {shape.area()}"
else:
return "Unknown shape"

circle = Circle(5)
square = Square(4)
print(calculate_area(circle)) # Output: Circle area: 78.5
print(calculate_area(square)) # Output: Square area: 16
In this example, the calculate_area function uses type checking with isinstance to determine the type of shape
passed to it and calls the appropriate method. This demonstrates type-based dispatch where different methods
are invoked based on the object's type.
4. Describe the security considerations when using APIs. Discuss methods to secure API endpoints
and data.
o Answer: Security is crucial when using APIs to prevent unauthorized access and protect sensitive
data. Key security considerations include:
▪ Authentication: Ensuring that only authorized users can access the API, typically using
API keys, OAuth tokens, or JWTs.
▪ Encryption: Using HTTPS to encrypt data in transit to prevent interception.
▪ Rate Limiting: Limiting the number of requests a user can make to protect against
DDoS attacks.
▪ Data Validation: Validating incoming data to prevent injection attacks and other
exploits.
▪ Error Handling: Providing generic error messages that do not disclose sensitive
information.
▪ Audit Logging: Keeping logs of API access and operations to monitor for suspicious
activity.
Example of using an API key for authentication:
python
Copy code
import requests

api_key = "your_api_key_here"
headers = {
"Authorization": f"Bearer {api_key}"
}

response = requests.get("https://api.example.com/data", headers=headers)


if response.status_code == 200:
print("Data retrieved successfully")
else:
print("Failed to retrieve data")
5. Write a Python script that reads an XML file, parses it using ElementTree, and prints all node
names and values. Discuss how to handle XML namespaces.
o Answer: The xml.etree.ElementTree module provides methods to parse XML files and navigate
the XML tree. Handling XML namespaces is essential when dealing with XML documents that
use them, as tags may be prefixed with a namespace URI.
Example:
python
Copy code
import xml.etree.ElementTree as ET

def print_xml_nodes(file_path):
try:
tree = ET.parse(file_path)
root = tree.getroot()

def recurse(node):
for child in node:
print(f"Tag: {child.tag}, Text: {child.text}")
recurse(child)

recurse(root)
except ET.ParseError as e:
print(f"Error parsing XML: {e}")

print_xml_nodes('example.xml')
Handling Namespaces:
python
Copy code
namespaces = {'ns': 'http://example.com/ns'}
elements = root.findall('ns:element', namespaces)
for elem in elements:
print(f"Tag: {elem.tag}, Text: {elem.text}")
This script reads and prints nodes from an XML file. For XML documents using namespaces, you can define a
dictionary mapping prefixes to namespace URIs and use it with methods like findall.
6. What are JOINs in SQL? Explain INNER JOIN, LEFT JOIN, RIGHT JOIN, and FULL JOIN
with examples. Discuss scenarios where each would be used.
o Answer: JOINs in SQL are used to combine rows from two or more tables based on a related
column. They are essential in relational databases to fetch data from related tables.
o INNER JOIN: Returns records that have matching values in both tables.
▪ Example:
sql
Copy code
SELECT employees.name, departments.name
FROM employees
INNER JOIN departments ON employees.department_id = departments.id;
Use when you only want records with matches in both tables.
o LEFT JOIN (LEFT OUTER JOIN): Returns all records from the left table and matched
records from the right table. Unmatched records will have NULLs.
▪ Example:
sql
Copy code
SELECT employees.name, departments.name
FROM employees
LEFT JOIN departments ON employees.department_id = departments.id;
Use when you want all records from the left table, regardless of matches.
o RIGHT JOIN (RIGHT OUTER JOIN): Returns all records from the right table and matched
records from the left table. Unmatched records will have NULLs.
▪ Example:
sql
Copy code
SELECT employees.name, departments.name
FROM employees
RIGHT JOIN departments ON employees.department_id = departments.id;
Use when you want all records from the right table, regardless of matches.
o FULL JOIN (FULL OUTER JOIN): Returns all records when there is a match in either left or
right table. Unmatched records from both sides will have NULLs.
▪ Example:
sql
Copy code
SELECT employees.name, departments.name
FROM employees
FULL OUTER JOIN departments ON employees.department_id = departments.id;
Use when you want to include all records from both tables, showing NULLs where there are no matches.
7. Explain the concept of polymorphism in object-oriented programming. Provide an example with a
base class and derived classes in Python.
o Answer: Polymorphism in object-oriented programming refers to the ability of different classes
to be treated as instances of the same class through inheritance. It allows methods to be
overridden in derived classes to provide specific functionality while keeping the interface
consistent.
Example:
python
Copy code
class Animal:
def speak(self):
raise NotImplementedError("Subclass must implement abstract method")

class Dog(Animal):
def speak(self):
return "Woof!"

class Cat(Animal):
def speak(self):
return "Meow!"

def animal_speak(animal):
print(animal.speak())

dog = Dog()
cat = Cat()
animal_speak(dog) # Output: Woof!
animal_speak(cat) # Output: Meow!
In this example, the Animal class defines an abstract speak method. Dog and Cat override this method,
providing their specific implementations. The function animal_speak demonstrates polymorphism, as it can
accept any object of type Animal and call the speak method, irrespective of the actual class of the object.
8. Discuss the concept of basic data modeling in databases. Explain entities, attributes, and
relationships with an example.
o Answer: Basic data modeling in databases involves defining how data is structured and how
entities are related. An entity represents a real-world object or concept, an attribute describes
properties of an entity, and relationships define how entities are connected.
Example:
o Entity: Student
▪ Attributes: student_id (Primary Key), name, email, date_of_birth
o Entity: Course
▪ Attributes: course_id (Primary Key), course_name, credits
o Relationship: Enrollment (Many-to-Many)
▪ Attributes: student_id (Foreign Key), course_id (Foreign Key), enrollment_date
In this model:
o Entities Student and Course represent students and courses.
o Attributes provide details about each entity.
o The relationship Enrollment links students to courses they are enrolled in, indicating a many-to-
many relationship (a student can enroll in multiple courses, and a course can have multiple
students).
This basic data modeling approach helps in designing a database schema that is logical, efficient, and scalable,
ensuring data integrity and reducing redundancy.

Question Paper 3
1. What is the __init__ method in Python classes? Explain its role in object instantiation and provide
an example that initializes an object with default and custom attributes.
o Answer: The __init__ method in Python is a special method, also known as a constructor, which
is automatically called when a new instance of a class is created. It initializes the object's
attributes with initial values and can take arguments to customize the initialization. This method
is essential for setting up the state of the object.
Example:
python
Copy code
class Car:
def __init__(self, make, model, year=2020):
self.make = make
self.model = model
self.year = year

def display_info(self):
return f"Car: {self.year} {self.make} {self.model}"
car1 = Car("Toyota", "Corolla", 2021)
car2 = Car("Honda", "Civic")

print(car1.display_info()) # Output: Car: 2021 Toyota Corolla


print(car2.display_info()) # Output: Car: 2020 Honda Civic
In this example, the Car class has an __init__ method that initializes the make, model, and year attributes. The
year attribute has a default value of 2020. The display_info method returns a formatted string with the car's
details.
2. Discuss the concept of Prototyping versus Planning in software development. Explain the
advantages and disadvantages of each approach.
o Answer: Prototyping and planning are two approaches to software development.
o Prototyping involves creating a preliminary version of a product, known as a prototype, to
explore ideas and gather feedback. It is particularly useful in the early stages of development
when requirements are not well understood.
Advantages:
▪ Quick to develop and test ideas.
▪ Provides a tangible product for stakeholders to review and give feedback.
▪ Helps in identifying potential issues and requirements early.
Disadvantages:
▪ May lead to scope creep as stakeholders request additional features.
▪ Prototypes may be mistaken for final products, leading to unrealistic expectations.
▪ Can result in technical debt if prototypes are hastily constructed.
o Planning involves detailed design and specification before development begins. It focuses on
understanding requirements thoroughly and creating a clear roadmap.
Advantages:
▪ Provides a clear structure and direction for development.
▪ Helps in estimating costs and timelines accurately.
▪ Reduces the risk of major changes during development.
Disadvantages:
▪ Can be time-consuming and costly.
▪ May lead to inflexibility, as changes can be difficult to incorporate once development has
started.
▪ Risks not fully capturing user needs if requirements are not well understood initially.
Both approaches have their merits and are often used together in a hybrid model. Prototyping can be useful for
initial requirement gathering and exploration, while planning is essential for defining the scope and structure of
the final product.
3. Explain the concept of operator overloading in Python with a detailed example using the __mul__
method for a custom Matrix class. Discuss the implications of overloading operators in terms of
code readability and maintainability.
o Answer: Operator overloading in Python allows custom classes to define their behavior for
standard operators (e.g., +, -, *). This is done by implementing special methods like __add__,
__sub__, __mul__, etc., in the class. Overloading operators can make code more intuitive and
concise but may also obscure the actual operations being performed, affecting readability and
maintainability.
Example:
python
Copy code
class Matrix:
def __init__(self, data):
self.data = data

def __mul__(self, other):


if not isinstance(other, Matrix):
raise ValueError("Can only multiply with another Matrix")
result = []
for i in range(len(self.data)):
row = []
for j in range(len(other.data[0])):
sum = 0
for k in range(len(other.data)):
sum += self.data[i][k] * other.data[k][j]
row.append(sum)
result.append(row)
return Matrix(result)

def __str__(self):
return '\n'.join([' '.join(map(str, row)) for row in self.data])

m1 = Matrix([[1, 2], [3, 4]])


m2 = Matrix([[2, 0], [1, 3]])
m3 = m1 * m2
print(m3) # Output:
#46
# 10 12
In this example, the Matrix class defines the __mul__ method to overload the * operator for matrix
multiplication. The method ensures that the other operand is also a Matrix and performs the multiplication.
Implications:
o Readability: Operator overloading can make the code more readable and expressive, as
mathematical operations on objects can be represented using standard operators. However, if the
behavior of these operators is non-standard or unexpected, it can confuse readers who are not
familiar with the class implementation.
o Maintainability: While overloading operators can simplify code, it can also hide complex logic
behind simple operators. This can make debugging and maintenance challenging if the
overloaded operations are not well documented or intuitive.
4. What is the __str__ method in Python classes? How does it differ from the __repr__ method?
Provide an example that highlights these differences.
o Answer: The __str__ method in Python defines the "informal" or "nicely printable" string
representation of an object. It is called by the str() function and the print statement. The __repr__
method, on the other hand, defines the "official" string representation of an object, which is more
unambiguous and can be used to recreate the object. It is called by the repr() function and should
return a string that ideally could be used to recreate the object.
Example:
python
Copy code
class Point:
def __init__(self, x, y):
self.x = x
self.y = y

def __str__(self):
return f"Point({self.x}, {self.y})"

def __repr__(self):
return f"Point(x={self.x}, y={self.y})"

p = Point(10, 20)
print(p) # Output: Point(10, 20)
print(repr(p)) # Output: Point(x=10, y=20)
In this example, the Point class has both __str__ and __repr__ methods. The __str__ method provides a user-
friendly representation, while the __repr__ method provides a more detailed string that includes the names of
the attributes.
The key difference is the intended audience:
o __str__ is meant for end-users and should be readable.
o __repr__ is meant for developers and should be detailed enough to understand the object’s state
and ideally allow the recreation of the object.
5. Discuss the importance of data security and encryption when working with APIs. Provide a
Python example demonstrating the use of HTTPS and handling sensitive data securely.
o Answer: Data security and encryption are critical when working with APIs to protect sensitive
data from unauthorized access, interception, or tampering. HTTPS encrypts data in transit
between the client and server, ensuring that even if data is intercepted, it cannot be easily
understood.
Key considerations:
o Use HTTPS: Always use HTTPS to encrypt data in transit.
o Authentication: Implement strong authentication mechanisms like OAuth tokens or API keys.
o Secure Storage: Sensitive data like API keys and tokens should be stored securely, for example,
in environment variables, not hardcoded in the source code.
o Data Encryption: Sensitive data, such as user information, should be encrypted at rest and in
transit.
Example:
python
Copy code
import requests

API_URL = "https://api.example.com/data"
API_KEY = "your_secure_api_key"

headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}

try:
response = requests.get(API_URL, headers=headers)
response.raise_for_status()
data = response.json()
print(data)
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
In this example, the API request is made over HTTPS, and the API key is securely sent in the Authorization
header. It's important to handle exceptions and errors gracefully to avoid exposing sensitive information. The
use of response.raise_for_status() helps in handling HTTP errors by raising an exception for unsuccessful status
codes.
6. Explain how to parse and work with JSON data in Python. Provide an example where JSON data
is fetched from a web API and processed.
o Answer: JSON (JavaScript Object Notation) is a common format for data exchange. In Python,
the json module provides functionality to parse JSON data into Python objects (like dictionaries)
and serialize Python objects into JSON format.
Example:
python
Copy code
import requests
import json

url = "https://jsonplaceholder.typicode.com/posts"
response = requests.get(url)
if response.status_code == 200:
data = response.json() # Convert JSON data to Python object
for post in data[:5]: # Display first 5 posts
print(f"ID: {post['id']}, Title: {post['title']}")
else:
print(f"Failed to retrieve data: {response.status_code}")
Key operations:
o Parsing JSON: json.loads() parses a JSON string into a Python dictionary. response.json() is a
convenient method provided by requests to parse JSON from the response.
o Serializing JSON: json.dumps() converts a Python object into a JSON string.
This example fetches JSON data from a sample API and processes it to print the first five post titles. The json
module's methods ensure seamless conversion between JSON and Python data structures.
7. What is the importance of SQL normalization in database design? Explain the different normal
forms and their significance with examples.
o Answer: SQL normalization is a process used in database design to minimize redundancy and
dependency by organizing fields and table relationships. The goal is to reduce data redundancy
and improve data integrity. There are several normal forms, each with specific requirements:
o First Normal Form (1NF): Ensures that each column contains atomic (indivisible) values and
each column contains values of a single type.
▪ Example: A table with a column that holds multiple phone numbers should be split so
that each phone number is in its own column.
o Second Normal Form (2NF): Achieved when the table is in 1NF and all non-key attributes are
fully dependent on the primary key. It eliminates partial dependencies.
▪ Example: A table with a composite key where some attributes depend only on a part of
the key should be split into two tables.
o Third Normal Form (3NF): Ensures that the table is in 2NF and all attributes are only
dependent on the primary key, removing transitive dependencies.
▪ Example: A table where an attribute depends on another attribute that is not a primary
key (e.g., if city depends on postal_code) should be separated.
o Boyce-Codd Normal Form (BCNF): A stronger version of 3NF where every determinant is a
candidate key.
▪ Example: If in a table, a non-prime attribute determines another attribute, it should be
split.
Significance:
o Reduces Data Redundancy: Prevents storing the same data in multiple places, thus saving
space.
o Improves Data Integrity: Ensures that the data is logically stored and easily maintainable.
o Prevents Anomalies: Helps avoid insertion, update, and deletion anomalies.
Example:
o 1NF Example:
lua
Copy code
| StudentID | Name | PhoneNumbers |
|-----------|-----------|--------------------|
|1 | John Doe | 123-456, 789-012 |
This table is not in 1NF because the PhoneNumbers column contains multiple values. It should be split into
multiple rows or separate columns for each phone number.
o 2NF Example:
css
Copy code
| StudentID | CourseID | Grade |
|-----------|----------|-------|
|1 | 101 |A |
|1 | 102 |B |
If Grade depends only on CourseID, and not on StudentID, then it's partially dependent on the primary key and
needs normalization.
o 3NF Example:
lua
Copy code
| StudentID | CourseID | Instructor |
|-----------|----------|------------|
|1 | 101 | Prof. Smith|
If Instructor depends on CourseID rather than StudentID, it's a transitive dependency and should be removed by
creating a separate Course table.
8. Discuss the use of APIs for accessing web services, with a focus on geocoding services. Provide an
example using a public geocoding API to find the coordinates of a location.
o Answer: APIs (Application Programming Interfaces) are used to interact with web services,
enabling applications to request and exchange data over the internet. Geocoding APIs convert
addresses into geographic coordinates (latitude and longitude) and vice versa.
Example using OpenCage Geocoding API:
python
Copy code
import requests

def geocode_address(address):
api_url = "https://api.opencagedata.com/geocode/v1/json"
api_key = "your_api_key_here"
params = {
'q': address,
'key': api_key,
'limit': 1
}

try:
response = requests.get(api_url, params=params)
response.raise_for_status()
data = response.json()
if data['results']:
location = data['results'][0]['geometry']
print(f"Latitude: {location['lat']}, Longitude: {location['lng']}")
else:
print("No results found.")
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")

address = "1600 Amphitheatre Parkway, Mountain View, CA"


geocode_address(address)
Key points:
o API Request: The example uses the OpenCage Geocoding API to convert an address into
coordinates. The API key is required for authentication.
o Handling Responses: The response includes a status check and error handling to manage
potential issues like network errors or invalid responses.
o Data Parsing: The JSON response is parsed to extract the latitude and longitude.
Geocoding services are commonly used in applications involving maps, location tracking, and logistics. The
example demonstrates a typical API call workflow: sending a request, handling the response, and processing the
data.

Question Paper 4
1. Explain the role of object-oriented features like inheritance, encapsulation, and polymorphism in
Python with detailed examples.
o Answer:
▪ Inheritance: Inheritance allows a class (subclass) to inherit attributes and methods from
another class (superclass). It facilitates code reuse and establishes a hierarchical
relationship between classes.
Example:
python
Copy code
class Vehicle:
def __init__(self, brand, model):
self.brand = brand
self.model = model

def drive(self):
print(f"{self.brand} {self.model} is driving.")

class Car(Vehicle):
def __init__(self, brand, model, doors):
super().__init__(brand, model)
self.doors = doors

def open_doors(self):
print(f"Opening {self.doors} doors.")

car = Car("Toyota", "Corolla", 4)


car.drive() # Output: Toyota Corolla is driving.
car.open_doors() # Output: Opening 4 doors.
In this example, Car inherits from Vehicle, gaining its attributes and methods, while also adding specific
functionality like open_doors.
▪ Encapsulation: Encapsulation involves bundling data and methods that operate on that
data within a single unit, or class, and restricting access to some of the object's
components. It protects the internal state of an object from unauthorized access and
modification.
Example:
python
Copy code
class Account:
def __init__(self, owner, balance=0):
self.owner = owner
self.__balance = balance # Private attribute

def deposit(self, amount):


if amount > 0:
self.__balance += amount
print(f"Deposited {amount}. New balance is {self.__balance}.")
else:
print("Deposit amount must be positive.")

def withdraw(self, amount):


if amount <= self.__balance:
self.__balance -= amount
print(f"Withdrew {amount}. New balance is {self.__balance}.")
else:
print("Insufficient funds.")
def get_balance(self):
return self.__balance

account = Account("John Doe", 1000)


account.deposit(500) # Output: Deposited 500. New balance is 1500.
account.withdraw(200) # Output: Withdrew 200. New balance is 1300.
print(account.get_balance())# Output: 1300
print(account.__balance) # AttributeError: 'Account' object has no attribute '__balance'
Here, the __balance attribute is private, indicated by the double underscore prefix, and cannot be accessed
directly from outside the class. The deposit and withdraw methods provide controlled access to modify
__balance.
▪ Polymorphism: Polymorphism allows methods to do different things based on the object
it is acting upon, even when using a common interface. It is typically achieved through
method overriding in subclasses.
Example:
python
Copy code
class Animal:
def speak(self):
pass

class Dog(Animal):
def speak(self):
return "Woof!"

class Cat(Animal):
def speak(self):
return "Meow!"

animals = [Dog(), Cat(), Dog()]

for animal in animals:


print(animal.speak())
Output:
Copy code
Woof!
Meow!
Woof!
The speak method demonstrates polymorphism, where each Animal subclass (Dog and Cat) provides its own
implementation of the speak method.
2. These object-oriented features help in designing more modular, maintainable, and reusable code by
allowing abstraction, hiding complexity, and promoting the use of well-defined interfaces.
3. Describe the concept of databases and SQL. Explain how to create a database table, insert data,
and query it using Python's SQLite3 library with examples.
o Answer:
▪ Databases are organized collections of data that are easily accessible, managed, and
updated. They are crucial for storing large amounts of structured data. SQL (Structured
Query Language) is a standard programming language used to manage and manipulate
relational databases.
Creating a Database Table:
python
Copy code
import sqlite3

conn = sqlite3.connect('example.db') # Connect to the database


cursor = conn.cursor()

# Create a table
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER,
email TEXT UNIQUE
)
''')
conn.commit()
This example demonstrates creating a users table with columns id, name, age, and email.
Inserting Data:
python
Copy code
# Insert data into the table
cursor.execute('''
INSERT INTO users (name, age, email)
VALUES ('John Doe', 30, '[email protected]')
''')
conn.commit()
Data is inserted into the users table. The id is automatically incremented.
Querying Data:
python
Copy code
# Query data from the table
cursor.execute('SELECT * FROM users')
rows = cursor.fetchall()
for row in rows:
print(row)
This fetches all rows from the users table. The fetchall method retrieves all rows from the query result.
Closing the Connection:
python
Copy code
conn.close()
Closing the connection to the database ensures that all changes are saved and the resources are released.
Significance of SQL:
o SQL allows for the creation, querying, updating, and deletion of data.
o It supports powerful querying capabilities, including joins, subqueries, and aggregations.
o SQL databases enforce data integrity and support transactions, ensuring consistency and
reliability.
4. What is JSON? Explain its structure and typical uses in web development. Provide an example of
how to serialize a Python dictionary into JSON and deserialize it back.
o Answer:
▪ JSON (JavaScript Object Notation) is a lightweight data-interchange format that is
easy for humans to read and write and easy for machines to parse and generate. JSON is
built on two structures:
▪ A collection of key/value pairs: This is realized as an object in JavaScript (a
dictionary in Python).
▪ An ordered list of values: This is realized as an array in JavaScript (a list in
Python).
Typical Uses:
o Data Exchange: JSON is commonly used to transmit data between a server and web application
as text.
o Configuration Files: It is used for configuration files due to its simplicity and readability.
o APIs: Many web APIs use JSON to encode responses and requests.
Example:
python
Copy code
import json

# Python dictionary
person = {
"name": "Alice",
"age": 28,
"city": "Wonderland",
"is_student": False,
"languages": ["English", "French"]
}

# Serialize Python dictionary to JSON string


json_string = json.dumps(person, indent=4)
print(json_string)

# Deserialize JSON string back to Python dictionary


person_dict = json.loads(json_string)
print(person_dict)
Output:
sql
Copy code
{
"name": "Alice",
"age": 28,
"city": "Wonderland",
"is_student": false,
"languages": ["English", "French"]
}
{'name': 'Alice', 'age': 28, 'city': 'Wonderland', 'is_student': False, 'languages': ['English', 'French']}
In this example:
o json.dumps() converts a Python object into a JSON string, with indent=4 making the output
more readable.
o json.loads() parses a JSON string and returns a Python object.
JSON's structure and simplicity make it ideal for data interchange between systems and for storing structured
data in a lightweight format.
5. Describe the use of web scraping in data collection. Explain how to scrape web pages using
Python's requests and BeautifulSoup libraries, including handling dynamic content with
Selenium.
o Answer:
▪ Web Scraping is the process of extracting data from websites. It involves fetching a web
page and parsing its content to extract specific information. Web scraping is useful in
data collection for various applications like price monitoring, data analysis, and
competitive analysis.
Using requests and BeautifulSoup: The requests library is used to send HTTP requests to a web server, and
BeautifulSoup is used to parse and extract information from HTML or XML documents.
Example:
python
Copy code
import requests
from bs4 import BeautifulSoup

url = "http://example.com"
response = requests.get(url)
if response.status_code == 200:
soup = BeautifulSoup(response.content, 'html.parser')
title = soup.title.string
print(f"Page title: {title}")

# Extracting all hyperlinks


links = soup.find_all('a')
for link in links:
href = link.get('href')
print(href)
else:
print(f"Failed to retrieve the page: {response.status_code}")
In this example:
o The requests.get method fetches the web page content.
o BeautifulSoup parses the content and extracts the page title and hyperlinks.
Handling Dynamic Content with Selenium: For web pages with dynamic content loaded by JavaScript,
Selenium can be used. Selenium automates web browsers and can execute JavaScript to render content.
Example:
python
Copy code
from selenium import webdriver
from bs4 import BeautifulSoup

driver = webdriver.Chrome()
driver.get("http://example.com")

soup = BeautifulSoup(driver.page_source, 'html.parser')


title = soup.title.string
print(f"Page title: {title}")

driver.quit()
In this Selenium example:
o webdriver.Chrome() launches a Chrome browser.
o driver.get() loads the page, and driver.page_source captures the rendered HTML.
o BeautifulSoup is then used to parse the HTML and extract data.
Ethical Considerations and Legal Aspects:
o Ensure compliance with a website's robots.txt file and terms of service.
o Avoid excessive requests that can overload the server.
o Consider the ethical implications of data scraping and respect privacy.
6. Explain the concept of RESTful APIs. Discuss how to consume a RESTful API in Python,
including authentication and handling different HTTP methods.
o Answer:
▪ RESTful APIs (Representational State Transfer APIs) are web services that adhere to
REST architectural principles. They use HTTP methods explicitly and are stateless,
meaning each request from a client contains all the information needed to process the
request.
Key HTTP Methods:
o GET: Retrieve data from the server.
o POST: Submit data to the server.
o PUT: Update existing data.
o DELETE: Delete data.
Consuming a RESTful API in Python: The requests library is commonly used for interacting with RESTful
APIs in Python.
Example:
python
Copy code
import requests

base_url = "https://api.example.com"
endpoint = "/data"
url = f"{base_url}{endpoint}"
headers = {
"Authorization": "Bearer your_token_here",
"Content-Type": "application/json"
}

# GET request
response = requests.get(url, headers=headers)
if response.status_code == 200:
print("GET request successful")
print(response.json())
else:
print(f"GET request failed: {response.status_code}")

# POST request
data = {
"name": "Alice",
"email": "[email protected]"
}
response = requests.post(url, json=data, headers=headers)
if response.status_code == 201:
print("POST request successful")
print(response.json())
else:
print(f"POST request failed: {response.status_code}")

# PUT request
updated_data = {
"name": "Alice Wonderland"
}
update_url = f"{url}/1"
response = requests.put(update_url, json=updated_data, headers=headers)
if response.status_code == 200:
print("PUT request successful")
print(response.json())
else:
print(f"PUT request failed: {response.status_code}")

# DELETE request
delete_url = f"{url}/1"
response = requests.delete(delete_url, headers=headers)
if response.status_code == 204:
print("DELETE request successful")
else:
print(f"DELETE request failed: {response.status_code}")
In this example:
o GET: Retrieves data from the API. The response is checked for success and parsed as JSON.
o POST: Submits new data to the API, commonly used for creating resources.
o PUT: Updates existing data, typically identified by an ID.
o DELETE: Deletes a resource identified by an ID.
Authentication: APIs often require authentication to protect resources. This can be done using API keys,
OAuth tokens, or basic authentication.
Handling Responses: It's essential to handle different response statuses appropriately, such as checking for
success (2xx statuses), redirection (3xx), client errors (4xx), and server errors (5xx).
Consuming RESTful APIs in Python is straightforward with requests, making it easy to integrate external
services into Python applications.
7. What is the significance of the __name__ == "__main__" statement in Python scripts? Explain its
use and provide an example.
o Answer: The __name__ == "__main__" statement in Python is used to check whether a script is
being run directly or imported as a module in another script. When a script is run directly, the
__name__ variable is set to "__main__". If the script is imported, __name__ is set to the name of
the script/module.
Significance:
o It allows certain parts of code to run only when the script is executed directly, not when
imported.
o This is useful for including test code or script-specific functionality that should not run when the
module is imported elsewhere.
Example:
python
Copy code
def main():
print("This script is executed directly.")

def helper():
print("Helper function.")

if __name__ == "__main__":
main()
helper()
Explanation:
o If this script is run directly, the output will be:
vbnet
Copy code
This script is executed directly.
Helper function.
o If this script is imported into another module, the code inside the if __name__ == "__main__":
block will not run, preventing main() and helper() from being executed automatically.
This mechanism provides a way to include both reusable functions and script-specific code within the same file.
8. Discuss the role of object serialization and deserialization in Python. Explain with examples using
pickle and json modules.
o Answer:
▪ Serialization is the process of converting a Python object into a format that can be easily
stored or transmitted, such as a byte stream or a text format. Deserialization is the
process of converting this serialized format back into a Python object.
Uses:
o Persistence: Save Python objects to a file for later retrieval.
o Data Exchange: Transfer Python objects over a network.
o Caching: Store expensive-to-create objects for faster retrieval.
pickle Module:
o pickle serializes Python objects into a byte stream, which can be saved to a file or sent over a
network. It supports complex data types like objects and functions.
Example:
python
Copy code
import pickle

# Object to be serialized
data = {'key': 'value', 'number': 42}

# Serialize object to a file


with open('data.pkl', 'wb') as f:
pickle.dump(data, f)

# Deserialize object from a file


with open('data.pkl', 'rb') as f:
loaded_data = pickle.load(f)

print(loaded_data) # Output: {'key': 'value', 'number': 42}


json Module:
o The json module is used for serializing and deserializing JSON data. It works with simple data
types and structures like numbers, strings, lists, and dictionaries.
Example:
python
Copy code
import json

# Object to be serialized
data = {'name': 'Alice', 'age': 30, 'is_student': False}

# Serialize object to JSON string


json_string = json.dumps(data)
print(json_string) # Output: {"name": "Alice", "age": 30, "is_student": false}

# Deserialize JSON string back to Python object


loaded_data = json.loads(json_string)
print(loaded_data) # Output: {'name': 'Alice', 'age': 30, 'is_student': False}
Differences:
o pickle: Supports a wider range of Python data types, including custom objects, but the serialized
format is not human-readable and can be insecure if the source of the data is untrusted.
o json: Limited to basic data types (strings, numbers, lists, and dictionaries) but produces a
human-readable format that is widely used for data interchange. It's more secure and portable
compared to pickle.
Serialization and deserialization are essential for data storage, transmission, and inter-process communication.
The choice between pickle and json depends on the requirements for data compatibility and security.
9. Explain the principles of REST architecture. Discuss how to implement a simple RESTful API in
Python using Flask, including routing and handling HTTP methods.
o Answer: REST (Representational State Transfer) is an architectural style that uses standard
HTTP methods to perform CRUD (Create, Read, Update, Delete) operations on resources. It is
stateless, meaning each request contains all the information needed to process the request, and it
uses standard HTTP status codes to indicate the outcome of operations.
Principles of REST:
o Statelessness: Each client-server interaction contains all the information needed to fulfill the
request.
o Client-Server Architecture: Separates the user interface concerns from the data storage
concerns.
o Uniform Interface: A standardized way to access resources, typically using URLs and HTTP
methods.
o Resource Identification: Resources are identified by URLs, and actions are performed using
HTTP methods (GET, POST, PUT, DELETE).
o Representation: Resources can be represented in various formats, such as JSON or XML.
Implementing a RESTful API with Flask: Flask is a lightweight web framework in Python that is easy to use
for creating RESTful APIs.
Example:
python
Copy code
from flask import Flask, jsonify, request

app = Flask(__name__)
# Sample data
data = [
{'id': 1, 'name': 'Alice'},
{'id': 2, 'name': 'Bob'}
]

# Route for retrieving data (GET)


@app.route('/users', methods=['GET'])
def get_users():
return jsonify(data)

# Route for retrieving a single user (GET)


@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
user = next((item for item in data if item['id'] == user_id), None)
return jsonify(user) if user else ('', 404)

# Route for creating a new user (POST)


@app.route('/users', methods=['POST'])
def create_user():
new_user = request.get_json()
data.append(new_user)
return jsonify(new_user), 201

# Route for updating a user (PUT)


@app.route('/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
user = next((item for item in data if item['id'] == user_id), None)
if user:
updated_info = request.get_json()
user.update(updated_info)
return jsonify(user)
return ('', 404)
# Route for deleting a user (DELETE)
@app.route('/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
global data
data = [item for item in data if item['id'] != user_id]
return ('', 204)

if __name__ == '__main__':
app.run(debug=True)
Explanation:
o GET /users: Returns a list of users.
o GET /users/<id>: Returns a specific user based on ID.
o POST /users: Creates a new user.
o PUT /users/<id>: Updates an existing user based on ID.
o DELETE /users/<id>: Deletes a user based on ID.
Key Aspects:
o Flask Routing: Flask uses decorators to route requests to specific URL paths and HTTP
methods.
o Request Handling: The request object provides access to the request data.
o Response Handling: Responses are returned using jsonify to format data as JSON, with
appropriate HTTP status codes.
Flask's simplicity makes it an excellent choice for creating RESTful APIs. The provided example demonstrates
basic CRUD operations, and Flask can be extended to include more advanced features like authentication and
database integration.

You might also like