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

Python 2nd Assignment

The document explains various Python concepts including string manipulation methods (join() and split()), file path types (absolute and relative), and the use of the shelve module for variable storage. It also covers file operations using the shutil module, the role of assertions in debugging, and object-oriented programming principles such as classes, objects, and instance variables. Additional topics include copying objects with the copy module, printing objects with a custom __str__ method, and concepts like negative indexing, slicing, remove(), and pop().

Uploaded by

Vanni Singh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Python 2nd Assignment

The document explains various Python concepts including string manipulation methods (join() and split()), file path types (absolute and relative), and the use of the shelve module for variable storage. It also covers file operations using the shutil module, the role of assertions in debugging, and object-oriented programming principles such as classes, objects, and instance variables. Additional topics include copying objects with the copy module, printing objects with a custom __str__ method, and concepts like negative indexing, slicing, remove(), and pop().

Uploaded by

Vanni Singh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

1.

Illustrate join() and split() methods with examples


join() method:

• The join() method is used to concatenate (join) a sequence of strings using a specified
delimiter. It takes an iterable (e.g., a list, tuple, or string) as its argument and returns a single
string where each element of the iterable is separated by the specified delimiter.

Syntax: delimiter.join(iterable)

words = ["Hello", "world", "how", "are", "you"]

sentence = " ".join(words)

print(sentence) # Output: "Hello world how are you"

split() method:

• The split() method is used to split a string into a list of substrings based on a specified
delimiter. It takes the delimiter as an argument and returns a list of substrings.

Syntax: string.split(delimiter, maxsplit)

• delimiter: The character or substring at which the string should be split.

• maxsplit (optional): Specifies the maximum number of splits. If not provided, it splits the
string at all occurrences of the delimiter.

sentence = "Hello world how are you"

words = sentence.split(" ")

print(words) # Output: ["Hello", "world", "how", "are", "you"]

2.With the concept of file path, discuss absolute and relative file path.

In Python, the concepts of absolute and relative file paths are similar to those discussed earlier, but they are
used specifically within the context of Python programming to locate files and directories. Python provides
modules like os and os.path that allow you to work with file paths conveniently.

1. Absolute File Path in Python:

• An absolute file path in Python specifies the exact location of a file or directory on the file
system, starting from the root directory.

• You can create an absolute file path using the full directory structure from the root of the file
system.

• Python's os.path module can be used to construct absolute file paths in a platform-
independent manner.

Eg:

import os

absolute_path = os.path.abspath("/home/user/documents/file.txt")

print(absolute_path)
Relative File Path in Python:

• A relative file path in Python specifies the location of a file or directory relative to the current working
directory of the Python script.

• You can create relative file paths by specifying the path to a file or directory relative to the location of
your Python script.

• Python's os.path module can be used to work with relative file paths as well.

Eg:

import os

# Assuming the script is in the same directory as the file.txt

relative_path = "file.txt"

absolute_path = os.path.abspath(relative_path)

print(absolute_path)

3. Analyze saving variables with the shelve module.


1. Importing the shelve Module:
• To use the shelve module, you first need to import it in your Python script.
import shelve
2. Opening a Shelf:
• You create or open a shelf (a persistent storage file) using the shelve.open()
function.
• You can specify the name of the shelf file you want to work with. If the file doesn't
exist, it will be created.
with shelve.open('mydata') as shelf:
# Your code to save and retrieve variables goes here
• It's recommended to use the with statement to ensure that the shelf file is properly
closed after you're done with it. This helps prevent data corruption.
3. Saving Variables:
• Inside the with block, you can save variables to the shelf using keys.
• The keys are like labels that help you identify and retrieve the variables later.
with shelve.open('mydata') as shelf:
shelf['name'] = 'Alice'
shelf['age'] = 30
shelf['scores'] = [95, 89, 75]
4. Retrieving Variables:
• Later, in a different Python session or script, you can open the same shelf file and
retrieve the variables using their keys.
with shelve.open('mydata') as shelf:
name = shelf['name']
age = shelf['age']
scores = shelf['scores']
5. Using Retrieved Variables:
• Once you've retrieved the variables from the shelf, you can use them in your
program as needed.
print(name) # Output: 'Alice'
print(age) # Output: 30
print(scores) # Output: [95, 89, 75]

4. Illustrate the benefits of compressing files. Also, explain the reading of a


ZIP File with an example
Benefits of Compressing Files:
Compressing files involves reducing the size of one or more files to save space and make
them easier to transfer or store. Here are some key benefits of compressing files:
1. Saves storage space: Compressing files reduces their size, conserving storage space.
2. Faster file transfers: Smaller files transfer faster, which saves time and bandwidth.
3. Organizes data: Compression can bundle multiple files together for better
organization and management.
4. Efficient data backup: Compressed files require less backup storage, making backups
more efficient.
5. Reduces bandwidth usage: When downloading, compressed files use less
bandwidth, resulting in quicker downloads, especially on slow connections.
6. Adds security options: Certain compression formats offer security features like
passwords and encryption for added data protection.
Code:
import zipfile
zip_file_path = 'example.zip'
specific_file = 'file.txt'

with zipfile.ZipFile(zip_file_path, 'r') as zip_file:


file_list = zip_file.namelist()
print("Files in the ZIP file:", file_list)

if specific_file in file_list:
content = zip_file.read(specific_file).decode('utf-8')
print(f"\nContents of '{specific_file}':\n{content}")
else:
print(f"'{specific_file}' not found in the ZIP file.")
5. Bring about the use of the following file operation in Python with a suitable example.
i) Copying files and folders ii) Moving files and folders
iii)Permanently deleting files and folders

i) Copying Files and Folders:


In Python, you can use the shutil module to copy files and folders. Here's an example of
copying a file:
import shutil

# Source file to be copied


source_file = 'source_folder/source_file.txt'

# Destination directory where the file will be copied


destination_directory = 'destination_folder/'

# Copy the file to the destination


shutil.copy(source_file, destination_directory)

print(f'{source_file} has been copied to {destination_directory}')


ii) Moving Files and Folders:
To move files and folders in Python, you can also use the shutil module. Here's an example
of moving a file:
import shutil

# Source file to be moved


source_file = 'source_folder/source_file.txt'

# Destination directory where the file will be moved


destination_directory = 'destination_folder/'

# Move the file to the destination


shutil.move(source_file, destination_directory)

print(f'{source_file} has been moved to {destination_directory}')


iii) Permanently Deleting Files and Folders:
To permanently delete files and folders in Python, you can use the os module to remove
them. Be cautious when using this operation, as deleted files cannot be recovered. Here's an
example of permanently deleting a file:

import os
# File to be permanently deleted
file_to_delete = 'file_to_delete.txt'

# Check if the file exists before deleting


if os.path.exists(file_to_delete):
os.remove(file_to_delete)
print(f'{file_to_delete} has been permanently deleted.')
else:
print(f'{file_to_delete} does not exist.')
6. Develop the role of assertions in Python with suitable program.
Assertions in Python are used as debugging aids that help you catch and handle exceptional
cases in your code. They are often used to check if a condition holds true, and if it doesn't,
an exception (usually AssertionError) is raised. This can be useful for validating assumptions
about your program's state.
Here's the role of assertions in Python and a suitable program:
Role of Assertions:
• Assertions are primarily used during development and testing to catch and address
issues early.
• They help ensure that your code behaves as expected by verifying that certain
conditions are met.
• When an assertion fails, it indicates a bug or an unexpected condition in your code.
• Assertions should not be used for handling expected errors or exceptions during
regular program execution; instead, they are used to uncover and fix issues in the
development and testing phases.
def divide(a, b):
# Check if the divisor (b) is not zero using an assertion
assert b != 0, "Division by zero is not allowed"
return a / b

try:
# Get user input for the numerator and denominator
n = float(input("Enter the numerator: "))
m = float(input("Enter the denominator: "))

result = divide(n,m)
print("Result:", result)

except AssertionError as e:
print("Assertion Error:", e)

7. Write a function named DivExp which takes two parameters a,b and
returns a value c (c=a/b).Write suitable assertion for a>0 in function DivExp
and raise an exception for when b=0.Develop a suitable program,which
reads two values from the console and calls a function DivExp.

def DivExp(a, b):


# Assertion: Ensure 'a' is greater than 0
assert a > 0, "a must be greater than 0"

if b == 0:
raise ZeroDivisionError("Division by zero is not allowed")
return a / b

try:
# Get user input for 'a' and 'b'
a = float(input("Enter the value of 'a': "))
b = float(input("Enter the value of 'b': "))

result = DivExp(a, b)
print(f"Result (a / b): {result}")
except ZeroDivisionError as e:
print("Error:", e)
except AssertionError as e:
print("Assertion Error:", e)

8. Explain the terms with example:(i)Class,(ii)objects & (iii)instance


variables
(i) Class:
A class is a blueprint or a template for creating objects in object-oriented programming
(OOP). It defines the structure and behavior of objects that belong to it.
Eg:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age

def study(self):
return f"{self.name} is studying!"
(ii) Objects:
An object is an instance of a class. It is a concrete, tangible instance created based on the
structure and behavior defined by the class. Objects represent real-world entities and can
have unique data and behavior while still following the class's blueprint.
student1 = Student("Alice", 20)
student2 = Student("Bob", 22)
(iii) Instance Variables:
Instance variables (also known as instance attributes) are variables that belong to individual
objects created from a class. They store data unique to each object and are accessible using
dot notation (object.variable).
class Student:
def __init__(self, name, age):
self.name = name # Instance variable for name
self.age = age # Instance variable for age

student1 = Student("Alice", 20)


student2 = Student("Bob", 22)

print(student1.name) # Accessing instance variable


print(student2.age) # Accessing another instance variable

• A class is a blueprint or template for creating objects.


• Objects are instances of a class, representing real-world entities with unique data.
• Instance variables are variables associated with individual objects, storing their
unique data.
9. Explain how we can change the state of an object by making an
assignment to one of its attributes
Changing the state of an object in Python is accomplished by making an assignment to one
of its attributes. Objects in Python are mutable, which means you can modify their
attributes after they have been created. Here's an explanation of how this works:
1. Object Initialization:
• When you create an object from a class, it's initialized with certain attributes
based on the class's constructor (usually the __init__ method).
• These attributes represent the object's initial state.
2. Accessing Object Attributes:
• You can access an object's attributes using dot notation, like
object.attribute_name.
• For example, if you have a Student object with attributes name and age, you
can access them as student.name and student.age.
3. Changing Object State:
• To change the state of an object, you simply assign a new value to one of its
attributes using the assignment operator (=).
• This assignment modifies the attribute's value and updates the object's state.
class Student:
def __init__(self, name, age):
self.name = name
self.age = age

# Create a Student object


student = Student("Alice", 20)

# Print the initial state


print(f"Initial Name: {student.name}")
print(f"Initial Age: {student.age}")

# Change the state by assigning new values to attributes


student.name = "Bob"
student.age = 22

# Print the updated state


print(f"Updated Name: {student.name}")
print(f"Updated Age: {student.age}")

10. Define class and object, Construct the class called rectangle and
initialize it with height=100,width=200, starting point as (x=0.y=0).Write a
program to display the center point coordinates of a rectangle
class Rectangle:
def __init__(self):
self.height = 100
self.width = 200
self.x = 0
self.y = 0

def center(self):
center_x = self.x + (self.width / 2)
center_y = self.y + (self.height / 2)
return center_x, center_y

rectangle = Rectangle()
center_x, center_y = rectangle.center()
print(f"Center Point: ({center_x}, {center_y})")

11. Briefly explain the printing of objects with an example.


Printing objects in Python is achieved by defining a special method called __str__ within the
class. This method returns a string representation of the object, allowing you to customize
how the object's information is displayed when you print it.
Here's a brief explanation and an example:
Explanation:
• By default, when you print an object, Python displays a default string that includes
the object's memory address. This is not always informative or user-friendly.
• To make the printed output more meaningful, you can define a __str__ method in
your class. This method should return a string that represents the object's attributes
or state in a human-readable format.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def __str__(self):
return f"Person: {self.name}, Age: {self.age}"

# Create a Person object


person = Person("Alice", 30)

# When you print the object, it uses the __str__ method


print(person) # Output: "Person: Alice, Age: 30"
In this example:
• We define a Person class with a __str__ method that returns a formatted string
representing the person's name and age.
• We create a Person object named person.
• When we print the person object, Python automatically calls the __str__ method to
display a customized string representation. This makes the printed output more
informative and user-friendly.
By defining the __str__ method in your classes, you can control how objects of that class are
printed, making it easier to understand their content and state when you need to display
them.

12. Explain the concept of copying using copy module with an example.
The copy module offers two main functions for copying objects: copy.copy() for shallow
copies and copy.deepcopy() for deep copies.
Shallow Copy:
• A shallow copy of an object creates a new object but does not duplicate the objects
contained within it. Instead, it copies references to the contained objects. This
means that changes made to the inner objects in the copied structure will also be
reflected in the original.
import copy

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


shallow_copy = copy.copy(original_list)

# Modify the inner list in the shallow copy


shallow_copy[1][0] = 999

print("Original List:", original_list)


print("Shallow Copy:", shallow_copy)
Deep Copy:
• A deep copy of an object creates a completely independent duplicate of the object
and all objects contained within it, recursively. Changes made to the inner objects in
the copied structure do not affect the original.
import copy

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


deep_copy = copy.deepcopy(original_list)

# Modify the inner list in the deep copy


deep_copy[1][0] = 999

print("Original List:", original_list)


print("Deep Copy:", deep_copy)

13. Explain negative indexing, slicing, remove() and pop().


(1) Negative Indexing:
• Negative indexing allows you to access elements in a sequence (e.g., a list, string, or
tuple) from the end, counting backward.
• -1 refers to the last element, -2 to the second-to-last, and so on.
• It's a convenient way to access elements from the end of a sequence without
needing to know its length.
my_list = [1, 2, 3, 4, 5]
last_element = my_list[-1] # Access the last element
second_last_element = my_list[-2] # Access the second-to-last element

print("Last Element:", last_element)


print("Second-to-Last Element:", second_last_element)

(2) Slicing:
• Slicing is a way to extract a portion (subsequence) of a sequence, such as a list,
string, or tuple, by specifying a start and end index.
• The syntax for slicing is sequence[start:end], where start is inclusive, and end is
exclusive.
• You can also specify a step value as sequence[start:end:step] to skip elements.
my_list = [1, 2, 3, 4, 5]
sublist = my_list[1:4] # Extract elements from index 1 to 3 (exclusive)

print("Sublist:", sublist) # Output: [2, 3, 4]


(3) remove():
• remove() is a list method that removes the first occurrence of a specified value from
the list.
• If the value is not found, it raises a ValueError exception.
my_list = [1, 2, 3, 4, 3]
my_list.remove(3) # Remove the first occurrence of 3

print("Updated List:", my_list) # Output: [1, 2, 4, 3]


(4) pop():
• pop() is a list method that removes and returns the element at a specified index.
• If the index is not provided, it removes and returns the last element by default.
• It's useful when you want to extract and use an element from a list while also
removing it from the list.
my_list = [1, 2, 3, 4, 5]
popped_element = my_list.pop(2) # Remove and return the element at index 2

print("Popped Element:", popped_element)


print("Updated List:", my_list) # Output: [1, 2, 4, 5]

14. Explain the use of in and not in operators in list with suitable examples.
The in and not in operators in Python are used to check for the presence or absence of an
element in a list. These operators return a Boolean value (True or False) based on whether
the element is found in the list.
(1) Use of in Operator:
• The in operator checks if an element exists in a list and returns True if it does, or
False if it doesn't.

my_list = [1, 2, 3, 4, 5]

# Check if 3 exists in the list


if 3 in my_list:
print("3 is in the list.")
else:
print("3 is not in the list.")
(2) Use of not in Operator:
• The not in operator checks if an element does not exist in a list and returns True if it
doesn't, or False if it does exist.
my_list = [1, 2, 3, 4, 5]

# Check if 6 does not exist in the list


if 6 not in my_list:
print("6 is not in the list.")
else:
print("6 is in the list.")

16. List out the differences between shutil.copy() and shutil.copytree()


methods.
differences between shutil.copy() and shutil.copytree() in simple terms:
(1) Purpose:
• shutil.copy(): Copies one file at a time.
• shutil.copytree(): Copies entire directories (folders) with all their contents.
(2) Destination:
• shutil.copy(): You specify where to copy the file, and it can be either a file or a
folder.
• shutil.copytree(): You specify where to create a new copy of the entire directory,
and it should be a folder that doesn't exist.
(3) Overwriting:
• shutil.copy(): If the destination file exists, it can be overwritten.
• shutil.copytree(): If the destination directory exists, it usually can't be overwritten.
(4) Usage:
• shutil.copy(): For copying individual files.
• shutil.copytree(): For copying entire directories and their contents.
(5) Handling Errors:
• Both raise errors if the source doesn't exist or if there are permission issues.
import shutil

# Copy a file
shutil.copy("source_file.txt", "destination_folder/destination_file.txt")

# Copy a directory and its contents


shutil.copytree("source_directory", "destination_directory")

17. Explain different methods or modes for opening the file with example
(1) Read Mode ('r'):
• Use this mode to read the contents of an existing file.
• Example: with open("example.txt", 'r') as file:
# Read the contents of an existing file
with open("example.txt", 'r') as file:
content = file.read()
print(content)
(2) Write Mode ('w'):
• Use this mode to create or overwrite a file with new content.
• Example: with open("example.txt", 'w') as file:
# Create or overwrite a file with new content
with open("example.txt", 'w') as file:
file.write("This is new content.")
(3) Append Mode ('a'):
• Use this mode to add new content to the end of an existing file.
• Example: with open("example.txt", 'a') as file:
# Add new content to the end of an existing file
with open("example.txt", 'a') as file:
file.write("This is appended content.")
(4) Binary Mode ('b'):
• Use this mode when working with non-text files like images or audio.
• Example: with open("image.jpg", 'rb') as file:
# Read binary data from an image file
with open("image.jpg", 'rb') as file:
binary_data = file.read()
# Process binary data (e.g., save to another file)
(5) Read and Write Mode ('r+' or 'w+'):
• Use these modes for reading and writing in the same file.
• 'r+' for an existing file, 'w+' for a new or existing file.
• Example: with open("example.txt", 'r+') as file:
# Read and write in the same file
with open("example.txt", 'r+') as file:
content = file.read()
file.write("This is new content appended to the existing file.")

18. Develop a Python program to traverse the current directory by listing


sub-folders and files
import os

# Get the current directory


current_directory = os.getcwd()

print("Current Directory:", current_directory)

# List sub-folders and files


for item in os.listdir(current_directory):
print(item)
This program does the following:
1. It uses os.getcwd() to get the current working directory.
2. It lists all items (both files and directories) in the current directory using
os.listdir(current_directory).
3. It then prints the names of these items.
When you run this program, it will display the list of sub-folders and files in the current
directory.

19. Explain the methods __init__ and __str__ with suitable code example to
each.
In Python, the __init__ and __str__ methods are special methods used in classes for object
initialization and string representation, respectively.
(1) __init__ Method:
• The __init__ method is called when an object of a class is created. It initializes the
object's attributes or performs other setup tasks.
• It is also known as the constructor method.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

# Creating an instance of the Person class


person1 = Person("Alice", 30)

# Accessing object attributes


print("Name:", person1.name)
print("Age:", person1.age)
(2) __str__ Method:
• The __str__ method is used to define the string representation of an object. It's
called when you use the str() function or print() function on an object.
• It should return a human-readable string that represents the object.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def __str__(self):
return f"Person: {self.name}, Age: {self.age}"

# Creating an instance of the Person class


person1 = Person("Alice", 30)

# Printing the object using the __str__ method


print(person1)
20. Read a multi-digit number (as chars) from the console. Develop a program to
print the frequency of each digit with suitable message Explain the following with
syntax and suitable code snippet: i) Class definition ii) instantiation iii) passing
an instance (or objects) as an argument iv) instances as return values.
class DigitFrequencyCounter:
def __init__(self, number_str):
self.number_str = number_str

def count_digits(self):
unique_digits = set(self.number_str)
digit_count = {}

for digit in unique_digits:


if digit.isdigit():
count = self.number_str.count(digit)
digit_count[digit] = count

return digit_count

def display_frequency(self, digit_count):


for digit, count in digit_count.items():
print(f"Digit {digit} occurs {count} times")

# Read a multi-digit number as characters


number_str = input("Enter the multi-digit number as characters: ")

# Create an instance of DigitFrequencyCounter


counter = DigitFrequencyCounter(number_str)

# Count the digits and get the result


digit_count = counter.count_digits()

# Display the digit frequencies


counter.display_frequency(digit_count)
In this program:
• We define a class DigitFrequencyCounter.
• The constructor (__init__) takes the input number as a parameter and initializes the
instance's attribute.
• The count_digits method counts the digit frequencies and returns a dictionary.
• The display_frequency method takes the digit count dictionary and displays the
frequencies.
We create an instance of DigitFrequencyCounter, pass the input number to it, count the
digits, and then display the digit frequencies using the class methods.

21. Define a function which takes 2 objects representing complex numbers


and returns a new complex number with the addition of 2 complex
numbers. Define a suitable class ‘complex’ to represent the complex
number. Develop a program to read N (N≥2) complex numbers and to
compute the addition of N complex numbers.
class ComplexNumber:
def __init__(self, real, imaginary):
self.real = real
self.imaginary = imaginary

def __add__(self, other):


return ComplexNumber(self.real + other.real, self.imaginary + other.imaginary)

def read_complex_number():
real = float(input("Enter the real part: "))
imaginary = float(input("Enter the imaginary part: "))
return ComplexNumber(real, imaginary)
N = int(input("Enter the number of complex numbers (N): "))

if N < 2:
print("N should be greater than or equal to 2.")
else:
result = read_complex_number()

for _ in range(N - 1):


next_complex = read_complex_number()
result = result + next_complex

print("Sum of the complex numbers:", result.real, "+", result.imaginary, "i")


output:
Enter the number of complex numbers (N): 3

Enter the real part: 1


Enter the imaginary part: 2

Enter the real part: 3


Enter the imaginary part: 4

Enter the real part: 5


Enter the imaginary part: 6

Sum of the complex numbers: 9.0 + 12.0 i

22. Create a Time class with hour, min and sec as attributes. Demonstrate
how two Time objects would be added
class Time:
def __init__(self, hour, minute, second):
self.hour = hour
self.minute = minute
self.second = second

def __add__(self, other):


total_seconds = (self.hour + other.hour) * 3600 + (self.minute + other.minute) * 60 +
(self.second + other.second)

hours, remainder = divmod(total_seconds, 3600)


minutes, seconds = divmod(remainder, 60)

return Time(hours, minutes, seconds)

def __str__(self):
return f"{self.hour:02d}:{self.minute:02d}:{self.second:02d}"

# Create two Time objects


time1 = Time(3, 45, 30)
time2 = Time(1, 30, 45)

# Add the Time objects


result = time1 + time2

# Display the result


print("Time 1:", time1)
print("Time 2:", time2)
print("Sum:", result)

• We define a Time class with attributes for hours, minutes, and seconds.
• We override the __add__ method to define how two Time objects should be added.
It calculates the total seconds, converts them to hours, minutes, and seconds, and
returns a new Time object.
• The __str__ method is overridden to format the time as a string in HH:MM:SS
format.

24. Briefly, explain the printing of objects with suitable examples.


Printing objects in Python is achieved by defining a special method called __str__ within a
class. This method is used to return a human-readable string representation of an object
when the print() function is called with an instance of that class. Here's a brief explanation
with an example:
1. Define the __str__ Method: To customize how an object is printed, you define the
__str__ method within the class. This method should return a string that represents
the object in a clear and informative way.
2. Example: Let's say you have a Person class, and you want to print instances of this
class in a user-friendly format. You can define the __str__ method to return a
formatted string:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def __str__(self):
return f"Name: {self.name}, Age: {self.age}"

# Create a Person object


person1 = Person("Alice", 30)

# Print the object


print(person1)
output: Name: Alice, Age: 30

You might also like