Unit 2: Data Types and OOP Concepts - Subjective Questions
CAP776 — Programming In Python • Practice Questions with Detailed Answers
20 questions
Define a Python string. Explain string immutability, indexing, and slicing with suitable examples.
String: A string is an immutable sequence of Unicode characters enclosed in single, double, or triple quotation marks.
text = "Python"- Immutability: Once a string is created, its characters cannot be changed in place. For example,
text[0] = "J"raises aTypeError. A new string must be created instead:
text = "J" + text[1:]- Indexing: Positive indices begin at
0, while negative indices count from the end.text[0]returns the first character.text[-1]returns the last character.
- Slicing: The syntax is
string[start:stop:step]. Thestopindex is excluded.
word = "Programming"
print(word[0:7]) # Program
print(word[::-1]) # gnimmargorPThus, indexing accesses one character, whereas slicing creates a new string containing a selected range of characters.
Describe commonly used string operators and methods in Python. Illustrate their use with examples.
Python provides operators and methods for processing strings.
Important operators:
+performs concatenation:"Data" + "Base"gives"DataBase".*performs repetition:"Hi" * 3gives"HiHiHi".inandnot intest membership.- Comparison operators compare strings lexicographically.
Common methods:
upper()andlower()change letter case.strip()removes leading and trailing whitespace.replace(old, new)replaces a substring.split(separator)divides a string into a list.join(iterable)combines strings using a separator.find(substring)returns the first matching index or-1.count(substring)counts occurrences.
message = " learn python "
clean = message.strip().title()
words = clean.split()
result = "-".join(words)
print(result) # Learn-PythonBecause strings are immutable, these methods return new strings rather than modifying the original string.
Explain Python lists and discuss their important characteristics, operations, and methods.
A list is an ordered and mutable collection that can contain values of different data types. It is created using square brackets.
items = [10, "Python", 3.5, True]Characteristics:
- Elements maintain insertion order.
- Duplicate elements are permitted.
- Elements are accessed using positive or negative indices.
- Lists are mutable, so elements can be inserted, updated, or removed.
- A list may contain nested lists.
Common operations and methods:
append(x)adds one element at the end.extend(values)adds all elements from another iterable.insert(i, x)inserts an element at a specified position.remove(x)removes the first matching value.pop(i)removes and returns an element.sort()arranges elements in place.reverse()reverses the list in place.
numbers = [30, 10, 20]
numbers.append(40)
numbers.sort()
print(numbers) # [10, 20, 30, 40]Lists are suitable when an ordered collection must be modified during program execution.
What is list comprehension? Explain its syntax and use it to generate and filter values.
A list comprehension is a concise method of constructing a list from an iterable.
Its general syntax is:
[expression for item in iterable if condition]The condition is optional.
Generating squares:
squares = [x * x for x in range(1, 6)]
# [1, 4, 9, 16, 25]For each value , the generated value is .
Filtering even numbers:
evens = [x for x in range(1, 11) if x % 2 == 0]
# [2, 4, 6, 8, 10]Transforming strings:
names = ["ana", "ravi", "li"]
capitals = [name.upper() for name in names if len(name) > 2]List comprehensions are often clearer and shorter than loops that repeatedly call append(). However, a normal loop is preferable when the logic contains several complex steps or side effects.
Define a tuple in Python. Explain tuple creation, packing, unpacking, and the significance of tuple immutability.
A tuple is an ordered and immutable sequence. It is commonly written as comma-separated values, usually enclosed in parentheses.
point = (10, 20)
single = (5,) # Comma is required for a one-element tupleTuple packing places several values into one tuple:
student = "Asha", 20, "Python"Tuple unpacking assigns tuple elements to separate variables:
name, age, course = studentExtended unpacking is also possible:
first, *middle, last = (1, 2, 3, 4, 5)Importance of immutability:
- Tuple elements cannot be added, deleted, or reassigned after creation.
- Tuples can protect fixed collections from accidental modification.
- A tuple containing only hashable elements can be used as a dictionary key or set element.
- Tuples are appropriate for coordinates, database records, and multiple return values.
A tuple may contain a mutable object such as a list; the tuple structure remains fixed, but the contained list can still be modified.
Distinguish between lists and tuples in Python. State suitable applications of each.
Lists and tuples are both ordered sequence types, but they differ in important ways.
| Feature | List | Tuple |
|---|---|---|
| Syntax | [1, 2, 3] |
(1, 2, 3) |
| Mutability | Mutable | Immutable |
| Available methods | Many modification methods | Mainly count() and index() |
| Hashability | Not hashable | Hashable if all elements are hashable |
| Dictionary key | Cannot be used | Can be used when hashable |
| Typical purpose | Changing collections | Fixed records |
List example:
shopping_cart = ["book", "pen"]
shopping_cart.append("bag")A list is appropriate because items may be added or removed.
Tuple example:
location = (12.5, 77.6)A tuple is appropriate because a coordinate is treated as one fixed record.
Therefore, lists should generally be selected for dynamic collections, while tuples are preferred for fixed data whose structure should not change.
Explain dictionaries in Python. Describe key-value storage, key restrictions, and important dictionary operations.
A dictionary is a mutable mapping that stores data as key: value pairs.
student = {"name": "Mira", "marks": 88}Properties:
- Each key is unique.
- Keys must be hashable, such as strings, numbers, or suitable tuples.
- Values may have any data type and need not be unique.
- Modern Python dictionaries preserve insertion order.
- Access is performed through keys rather than positional indices.
Operations:
student["name"] # Access
student["grade"] = "A" # Insert
student["marks"] = 91 # Update
student.get("age", "Unknown")
del student["grade"] # DeleteImportant methods:
keys()returns a view of keys.values()returns a view of values.items()returns key-value pairs.update()inserts or updates multiple entries.pop(key)removes and returns a value.clear()removes all entries.
Dictionaries are useful for records, configurations, lookup tables, counters, and data indexed by meaningful identifiers.
Describe dictionary traversal, dictionary comprehension, and nested dictionaries with suitable Python examples.
Dictionary traversal is commonly performed using items():
marks = {"Asha": 90, "Ravi": 75, "Noor": 84}
for name, score in marks.items():
print(name, score)A dictionary comprehension constructs a dictionary using a compact expression:
squares = {x: x * x for x in range(1, 6)}It may include filtering:
high_scores = {name: score for name, score in marks.items()
if score >= 80}A nested dictionary stores dictionaries as values and is useful for structured records:
students = {
101: {"name": "Asha", "marks": 90},
102: {"name": "Ravi", "marks": 75}
}
print(students[101]["name"])
students[102]["marks"] = 79Nested structures should be accessed one key at a time. Methods such as get() can be used when a key might be absent, thereby avoiding an unnecessary KeyError.
Define a set in Python and explain set operations such as union, intersection, difference, and symmetric difference.
A set is a mutable, unordered collection of unique hashable elements. It is created using braces or set().
A = {1, 2, 3, 4}
B = {3, 4, 5, 6}
empty = set(){} creates an empty dictionary, not an empty set.
Set operations:
- Union: Elements in either set, written as .
A | B # {1, 2, 3, 4, 5, 6}- Intersection: Elements common to both sets, written as .
A & B # {3, 4}- Difference: Elements in the first set but not the second, written as .
A - B # {1, 2}- Symmetric difference: Elements in exactly one set.
A ^ B # {1, 2, 5, 6}Methods such as add(), update(), remove(), discard(), and pop() modify a set. Sets are useful for duplicate removal, membership testing, and mathematical set calculations.
Compare sets with lists and tuples. Explain membership testing, duplicate elimination, and frozen sets.
Comparison:
| Feature | List | Tuple | Set |
|---|---|---|---|
| Ordered sequence | Yes | Yes | No positional ordering guarantee |
| Duplicates | Allowed | Allowed | Removed |
| Mutable | Yes | No | Yes |
| Indexing | Supported | Supported | Not supported |
| Typical use | Dynamic sequence | Fixed sequence | Unique elements and membership |
Set membership testing is generally efficient because sets use hashing:
allowed = {"read", "write", "execute"}
if "write" in allowed:
print("Permission found")A set can eliminate duplicate values:
values = [1, 2, 2, 3, 1]
unique_values = set(values) # {1, 2, 3}Converting back with list(set(values)) does not reliably preserve the original sequence order. Order-preserving duplicate removal can instead use list(dict.fromkeys(values)).
A frozen set is an immutable set:
permissions = frozenset({"read", "write"})It cannot be modified, but because it is hashable, it may be used as a dictionary key or as an element of another set.
Explain the range type in Python. Describe its forms, parameters, and use in iteration.
range represents an immutable sequence of integers and is commonly used with loops. It generates values lazily rather than storing a complete list.
Forms:
range(stop)starts at0.range(start, stop)uses a default step of1.range(start, stop, step)uses the specified increment or decrement.
The stop value is excluded.
list(range(5)) # [0, 1, 2, 3, 4]
list(range(2, 8)) # [2, 3, 4, 5, 6, 7]
list(range(10, 2, -2)) # [10, 8, 6, 4]Iteration example:
for i in range(1, 6):
print(i * i)A step value cannot be zero; range(1, 5, 0) raises ValueError. The range supports indexing, slicing, membership testing, and len(). Its memory efficiency makes it preferable to creating a list when only integer iteration is required.
Compare strings, lists, tuples, dictionaries, sets, and ranges based on ordering, mutability, duplicates, and access method.
Python's built-in collection types serve different purposes.
| Type | Ordered | Mutable | Duplicates | Access method |
|---|---|---|---|---|
| String | Yes | No | Allowed | Integer index or slice |
| List | Yes | Yes | Allowed | Integer index or slice |
| Tuple | Yes | No | Allowed | Integer index or slice |
| Dictionary | Insertion-ordered | Yes | Keys unique; values may repeat | Key |
| Set | No positional order | Yes | Not allowed | Membership, not indexing |
| Range | Yes | No | Normally no repeated generated values | Integer index or slice |
Selection guidelines:
- Use a string for textual data.
- Use a list for an ordered collection that changes.
- Use a tuple for a fixed record or immutable sequence.
- Use a dictionary for key-based lookup.
- Use a set for unique values and set operations.
- Use a range for memory-efficient integer sequences.
Mutability affects whether an object can be altered after creation. Hashable immutable values can often serve as dictionary keys or set elements, while mutable lists, dictionaries, and sets cannot.
What is object-oriented programming? Explain its major features and advantages in Python.
Object-oriented programming (OOP) is a programming approach that organizes software around objects. An object combines data with the operations that act on that data. A class is the blueprint from which objects are created.
Major OOP features:
- Encapsulation: Groups attributes and methods inside a class and controls access to internal data.
- Abstraction: Exposes essential behavior while hiding unnecessary implementation details.
- Inheritance: Creates a new class from an existing class, supporting code reuse.
- Polymorphism: Allows a common interface to produce behavior appropriate to different object types.
Advantages:
- Improves modularity by dividing a program into classes.
- Encourages code reuse through inheritance and composition.
- Simplifies maintenance because related data and behavior are grouped.
- Models real-world entities naturally.
- Protects object state through controlled methods and properties.
- Makes large programs easier to test and extend.
Python supports OOP through classes, objects, instance methods, class methods, static methods, properties, inheritance, method overriding, and special methods.
Explain classes, objects, constructors, instance attributes, and the self parameter with an example.
A class defines the data and behavior of a category of objects. An object is a particular instance of that class.
The __init__() method is an initializer automatically called after a new instance is created. It is commonly called a constructor in introductory Python. The self parameter refers to the current object and is used to access its attributes and methods.
class Student:
school = "Central School" # Class attribute
def __init__(self, name, marks):
self.name = name # Instance attribute
self.marks = marks
def display(self):
return f"{self.name}: {self.marks}"
s1 = Student("Asha", 90)
s2 = Student("Ravi", 78)
print(s1.display())Studentis the class.s1ands2are distinct objects.nameandmarksbelong to individual instances.schoolis shared through the class unless shadowed by an instance attribute.- Python supplies the object as the first argument when
s1.display()is called.
Although self is a naming convention rather than a reserved keyword, using this conventional name makes code understandable.
Define encapsulation. How are public, protected, and private members represented in Python?
Encapsulation is the practice of combining data and related methods in one class while controlling how the object's internal state is accessed or modified.
Python uses naming conventions and name mangling rather than strict access-control keywords.
- Public member: A normal name such as
balancecan be accessed from anywhere. - Protected member: A single leading underscore, such as
_balance, indicates that the member is intended for internal or subclass use. This is a convention, not enforcement. - Private member: A double leading underscore, such as
__balance, triggers name mangling.
class Account:
def __init__(self, balance):
self.owner = "Unknown" # Public
self._branch = "Main" # Protected convention
self.__balance = balance # Name-mangled
def deposit(self, amount):
if amount > 0:
self.__balance += amount
def get_balance(self):
return self.__balance__balance is internally transformed to a name similar to _Account__balance. This reduces accidental access but does not provide absolute security. Encapsulation is mainly achieved by exposing controlled methods or properties that validate changes.
Explain how properties support encapsulation in Python. Develop a class containing a validated property.
A property provides method-based control while allowing attribute-style syntax. It is useful for validating data and hiding internal representation.
class Employee:
def __init__(self, name, salary):
self.name = name
self.salary = salary
@property
def salary(self):
return self.__salary
@salary.setter
def salary(self, value):
if not isinstance(value, (int, float)):
raise TypeError("Salary must be numeric")
if value < 0:
raise ValueError("Salary cannot be negative")
self.__salary = value
employee = Employee("Mira", 50000)
employee.salary = 55000
print(employee.salary)Working:
@propertydefines the getter executed byemployee.salary.@salary.setterdefines controlled assignment.- The actual value is stored in the name-mangled attribute
__salary. - Invalid values are rejected before they corrupt the object's state.
Properties preserve a simple public interface while permitting validation, computed values, logging, or later implementation changes. This is generally more Pythonic than explicit get_salary() and set_salary() methods.
Define inheritance and explain single, multilevel, hierarchical, multiple, and hybrid inheritance.
Inheritance allows a derived class to acquire and extend the attributes and methods of one or more base classes.
Types of inheritance:
- Single inheritance: One child inherits from one parent.
class Dog(Animal):
pass- Multilevel inheritance: Inheritance occurs through several levels, such as
LivingThingtoAnimaltoDog. - Hierarchical inheritance: Several child classes inherit from one parent, such as
DogandCatinheriting fromAnimal. - Multiple inheritance: One child inherits from more than one parent.
class SmartPhone(Camera, Phone):
pass- Hybrid inheritance: A combination of two or more inheritance patterns, often including multiple and hierarchical inheritance.
Benefits:
- Reuses common functionality.
- Supports specialization of general classes.
- Enables overriding and polymorphism.
- Reduces repeated code.
Inheritance should represent a valid is-a relationship. If one object merely contains or uses another, composition is often more appropriate.
Explain method overriding and the use of super() in inheritance with a suitable example.
Method overriding occurs when a derived class defines a method with the same name as a method in its base class. Calls made through a derived object use the derived implementation.
super() returns a proxy that delegates method lookup according to the method resolution order. It is commonly used to extend rather than completely replace base-class behavior.
class Person:
def __init__(self, name):
self.name = name
def describe(self):
return f"Person: {self.name}"
class Student(Person):
def __init__(self, name, roll_number):
super().__init__(name)
self.roll_number = roll_number
def describe(self):
base_text = super().describe()
return f"{base_text}, Roll: {self.roll_number}"
student = Student("Asha", 101)
print(student.describe())Here, Student.__init__() reuses the initialization performed by Person, and Student.describe() extends the parent implementation. Using super() avoids directly naming the parent and works correctly with cooperative multiple inheritance when every class follows the same pattern.
What is the Method Resolution Order in Python? Explain its importance in multiple inheritance and the diamond inheritance problem.
The Method Resolution Order (MRO) is the sequence in which Python searches classes for a requested method or attribute. Python uses the C3 linearization algorithm to produce a consistent order.
Consider diamond inheritance:
class A:
def show(self):
return "A"
class B(A):
pass
class C(A):
def show(self):
return "C"
class D(B, C):
pass
print(D.mro())
print(D().show())The MRO is normally similar to:
[D, B, C, A, object]Therefore, D().show() finds show() in C before reaching A.
Importance:
- Resolves ambiguity when several parent classes provide the same method.
- Ensures local precedence and preserves declared parent order where possible.
- Prevents a shared ancestor from being processed repeatedly in cooperative calls.
- Determines how
super()delegates to the next class.
The MRO can be inspected with ClassName.mro() or ClassName.__mro__. In cooperative multiple inheritance, methods should generally use super() and compatible signatures.
Design an object-oriented Python program for a library that demonstrates encapsulation, inheritance, strings, lists, tuples, dictionaries, sets, and ranges. Explain the design.
A simplified design can use a base LibraryItem class and a derived Book class. The library stores indexed items, members, categories, and shelf positions.
class LibraryItem:
def __init__(self, item_id, title):
self.item_id = item_id
self.title = title.strip()
self.__available = True
@property
def available(self):
return self.__available
def borrow(self):
if not self.__available:
raise ValueError("Item is unavailable")
self.__available = False
def return_item(self):
self.__available = Trueclass Book(LibraryItem):
def init(self, item_id, title, author, categories):
super().init(item_id, title)
self.author = author
self.categories = set(categories)
def description(self):
return f"{self.title} by {self.author}"
class Library:
def init(self):
self.items = {}
self.members = []
self.shelves = tuple(range(1, 11))
def add_item(self, item):
if item.item_id in self.items:
raise ValueError("Duplicate item ID")
self.items[item.item_id] = item
def add_member(self, name):
name = name.strip()
if name and name not in self.members:
self.members.append(name)
def available_titles(self):
return [item.title for item in self.items.values()
if item.available]
Concepts demonstrated:
- Strings: Store and normalize titles, authors, and member names.
- Lists: Maintain a modifiable sequence of members.
- Tuples: Store fixed shelf numbers.
- Dictionaries: Map unique item IDs to objects.
- Sets: Store unique categories for each book.
- Range: Generate shelf numbers from
1through10. - Encapsulation: The
__availablestate is changed only through controlled methods. - Inheritance:
BookspecializesLibraryItemand reuses its initializer throughsuper().
The design can be extended with derived classes such as Magazine, loan records, due dates, and member-specific borrowing limits.
Define a Python string. Explain string immutability, indexing, and slicing with suitable examples.
String: A string is an immutable sequence of Unicode characters enclosed in single, double, or triple quotation marks.
text = "Python"- Immutability: Once a string is created, its characters cannot be changed in place. For example,
text[0] = "J"raises aTypeError. A new string must be created instead:
text = "J" + text[1:]- Indexing: Positive indices begin at
0, while negative indices count from the end.text[0]returns the first character.text[-1]returns the last character.
- Slicing: The syntax is
string[start:stop:step]. Thestopindex is excluded.
word = "Programming"
print(word[0:7]) # Program
print(word[::-1]) # gnimmargorPThus, indexing accesses one character, whereas slicing creates a new string containing a selected range of characters.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →