[Go to site: main page, start]

0% found this document useful (0 votes)
4 views5 pages

Module 4 Answers Python

An exception in Python is an error that interrupts normal program flow during execution, with common built-in exceptions including ZeroDivisionError and ValueError. The try, except, else, and finally blocks are used for structured exception handling, allowing code to manage errors gracefully. Context management with the 'with' statement ensures proper resource handling, while threading allows concurrent execution of tasks, with the Global Interpreter Lock (GIL) ensuring thread safety in Python.

Uploaded by

sadiesinkdhan01
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)
4 views5 pages

Module 4 Answers Python

An exception in Python is an error that interrupts normal program flow during execution, with common built-in exceptions including ZeroDivisionError and ValueError. The try, except, else, and finally blocks are used for structured exception handling, allowing code to manage errors gracefully. Context management with the 'with' statement ensures proper resource handling, while threading allows concurrent execution of tasks, with the Global Interpreter Lock (GIL) ensuring thread safety in Python.

Uploaded by

sadiesinkdhan01
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

5. Define exception in Python. What are the common built-in exceptions?

Explain with examples.

Ans: An exception in Python is an error that occurs during program


execution (runtime).
When an exception occurs, normal program flow is interrupted. Exceptions
help in handling errors gracefully without crashing the program.

Common Built-in Exceptions

1. ZeroDivisionError – dividing a number by zero


2. ValueError – converting invalid data type
3. TypeError – incompatible data types in an operation
4. IndexError – accessing invalid index of a list
5. KeyError – accessing invalid dictionary key
6. FileNotFoundError – opening a file that does not exist
7. NameError – using a variable that is not defined

Example:

try:
x = int("abc") # ValueError
except ValueError:
print("Invalid number!")

6. What is the purpose of try, except, else, and finally blocks? Explain with
examples.

Ans: Python uses these blocks for structured exception handling.

1. try block

Contains the code that may raise an exception.

2. except block

Executes when an exception occurs.

3. else block
Executes only if no exception occurs.

4. finally block

Executes always, whether exception occurs or not.

Example:

try:
x = 10 / 2
except ZeroDivisionError:
print("Cannot divide by zero.")
else:
print("Division successful:", x)
finally:
print("Execution completed.")

7. Explain raising exceptions using the raise keyword in Python.

Ans: The raise keyword is used to manually throw an exception.


It is useful to enforce rules or validate conditions.

Example:

def set_age(age):
if age < 0:
raise ValueError("Age cannot be negative!")
print("Age set to", age)

set_age(-5)

Output → ValueError: Age cannot be negative!

8. Describe context management in Python. How does the with statement help
in handling resources?
Ans: Context management ensures proper handling of resources like files,
network connections, or database connections.
It makes sure resources are opened and closed automatically.

The with statement:

 Eliminates the need to manually close resources


 Automatically calls __enter__() and __exit__() of context manager
 Prevents resource leaks

Example: File Handling with with

with open("[Link]", "r") as f:


content = [Link]()

# File automatically closes here

Even if an error occurs, the file will close safely.

9. Python program to handle multiple exceptions (ZeroDivisionError &


ValueError)

try:
a = int(input("Enter number: "))
b = int(input("Enter divisor: "))
result = a / b
print("Result =", result)

except ZeroDivisionError:
print("Error: Cannot divide by zero.")

except ValueError:
print("Error: Invalid input. Enter numbers only.")

10. Simple Python program to create two threads using threading module

import threading
import time
def task1():
for i in range(3):
print("Task 1 running")
[Link](1)

def task2():
for i in range(3):
print("Task 2 running")
[Link](1)

t1 = [Link](target=task1)
t2 = [Link](target=task2)

[Link]()
[Link]()

[Link]()
[Link]()

print("Both threads completed.")

11. Differentiate between Threads and Processes. Why does Python use GIL?

Ans: Threads

 Lightweight
 Share same memory space
 Faster communication
 Suitable for I/O-bound tasks

Processes

 Heavyweight
 Have separate memory
 More secure but slower
 Suitable for CPU-bound tasks
GIL (Global Interpreter Lock)

Python uses the GIL to:

 Allow only one thread to execute Python bytecode at a time


 Protect Python objects from race conditions
 Simplify memory management in CPython

Reason: CPython uses reference counting, and GIL ensures thread safety.

12. Compare Thread module and Threading module in Python with


advantages

Ans:

Thread Module Threading Module

Low-level module High-level module

Older and less used Recommended for modern Python

Requires more manual handling Provides Thread class, locks, timers

Rich features like Thread, Lock, RLock,


Limited functionality
Event

Hard to manage complex


Easy to manage multiple threads
threads

Advantages of threading module

 Object-oriented approach

 Easy thread creation and management

 Supports synchronization (Locks, Events)

 Better readability and maintainability

Common questions

Powered by AI

The Global Interpreter Lock (GIL) in Python is a mutex that protects access to Python objects, preventing multiple native threads from executing Python bytecode simultaneously. This is necessary to avoid race conditions among threads and simplify memory management in CPython, which uses reference counting . The GIL allows only one thread to execute in the interpreter at any given time, which can be a bottleneck for CPU-bound tasks, as it prevents utilizing multiple cores effectively. Hence, while threads share the same memory space allowing for faster communication in I/O-bound tasks, CPU-bound tasks perform better with multiprocessing as processes have separate memory spaces and are not restricted by the GIL .

Threads in Python offer lightweight execution, sharing the same memory space, which allows for fast communication between threads, making them suitable for I/O-bound tasks. However, the Global Interpreter Lock (GIL) limits threads to execute one at a time, hindering CPU-bound parallelism . Processes, though heavier as they require more memory and have separate memory spaces, bypass the GIL, allowing true parallelism on multi-core systems. As a result, while processes are slower and more resource-intensive due to separate memory spaces, they are more suitable for CPU-bound tasks that require concurrent execution .

Context management in Python refers to the efficient management of resources, ensuring they are properly acquired and released. The 'with' statement is a tool for context management that handles resources automatically. For instance, in file handling, 'with open("data.txt", "r") as f: content = f.read()' simplifies the process by automatically closing the file once the block is exited, even if an error occurs. This eliminates the need for explicit resource release code, reducing the risk of resource leaks .

In Python, structured exception handling using 'try', 'except', 'else', and 'finally' blocks allows for robust error management. The 'try' block contains code that might raise exceptions; if an exception occurs, control is transferred to the 'except' block, which handles the specific exception. If no exceptions occur, the 'else' block executes, allowing any success-dependent code to run. Regardless of whether an exception occurs, the 'finally' block will execute, useful for clean-up actions like closing files or releasing resources .

Multiple exceptions can be handled in a single try-except construct by specifying each possible exception within the except blocks. An example is handling ZeroDivisionError and ValueError in arithmetic operations: try: a = int(input("Enter number: ")) b = int(input("Enter divisor: ")) result = a / b print("Result =", result) except ZeroDivisionError: print("Error: Cannot divide by zero.") except ValueError: print("Error: Invalid input. Enter numbers only.") This structure allows different error types to be managed separately, providing specific responses to each exception type .

Exceptions in Python can be manually raised using the 'raise' keyword. This is particularly useful in scenarios that require enforcing certain conditions or input validations within a program. For example, raising a ValueError when a function input is invalid allows developers to control and maintain program integrity by providing meaningful error messages. An example is 'def set_age(age): if age < 0: raise ValueError("Age cannot be negative!")' which ensures that the age parameter is always non-negative, useful in applications dealing with age data .

Python's Threading module provides several synchronization primitives such as Lock, RLock, and Event, which are essential for managing concurrency. These tools help prevent race conditions and optimize resource-sharing among threads by ensuring that only one thread can access a resource at a time. This is crucial in applications where data integrity and thread coordination are vital. The Threading module's object-oriented approach further simplifies thread creation and management, improving the readability and maintainability of concurrent programs, and making it easier to implement complex threading scenarios in modern applications .

The primary differences between Python's Thread and Threading modules lie in their abstraction level and usability. The Thread module is low-level, older, and requires more manual handling, making it less suitable for complex threading needs. It has limited functionality and can make thread management more complex . On the other hand, the Threading module is high-level, recommended for modern applications due to its object-oriented approach, ease of thread creation and management, and built-in features like Lock, RLock, and Event for synchronization. These features improve code readability and maintainability, which are crucial for scalable applications .

Exception handling is crucial in Python programming for ensuring program reliability and robustness. It allows the program to handle errors gracefully without crashing, which is essential for building stable applications. By catching and managing exceptions, developers can provide informative error messages and alternative code paths, maintaining a controlled program flow when unforeseen issues arise. This not only improves user experience but also aids in debugging and maintaining the code .

The 'with' statement in Python optimizes resource management by ensuring resources are opened and closed automatically through context management protocols. It is particularly advantageous over traditional try-finally blocks because it reduces boilerplate code and enhances readability. The 'with' statement automatically calls the '__enter__()' and '__exit__()' methods of the context manager, closing resources even if an exception occurs, thus preventing resource leaks . It is beneficial when dealing with file I/O, network connections, or any resource management where manual closing is error-prone.

You might also like