0% found this document useful (0 votes)
3 views11 pages

Python Module 5

Uploaded by

shafiyasuhana2
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)
3 views11 pages

Python Module 5

Uploaded by

shafiyasuhana2
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

Module - V: Input/Output in Python

5.1 Basics of File Handling

File handling is a crucial concept in Python that allows a program to interact with the
permanent storage of a computer. In standard programming, data stored in variables is
volatile and gets erased as soon as the program terminates. File handling provides a
mechanism to read data from a file or write data to a file, ensuring data persistence.

To perform any operation on a file, the first step is to open it. Python provides the built-in
⁠open()⁠function for this purpose. The syntax is:

file_object = open("filename", "mode")

The file object acts as a pointer or a bridge between your Python program and the actual file
stored on the disk. The "mode" determines what you want to do with the file. The most
common modes are:

'⁠r'⁠: Read mode (default). It opens the file for reading and throws an error if the file does not
exist.

⁠'w'⁠: Write mode. It opens the file for writing, creates a new file if it doesn't exist, or truncates
(erases) the existing content if it does.

'⁠a'⁠: Append mode. It opens the file for writing but adds new data to the end of the file without
deleting existing content.

Once operations are complete, it is mandatory to close the file using ⁠file_object.close()⁠to
free up system resources.

5.1.1 Text Files and Their Formats, Reading and Writing Files

In Python, files are generally categorized into text files and binary files. Text files store data
as a sequence of characters, readable by humans. Examples include ⁠.txt⁠, ⁠.py⁠, and ⁠.csv⁠files.
Each line in a text file is terminated by a special character called the EOL (End of Line)
character, which is typically a newline character (⁠\n⁠).

Reading from a Text File

Python provides three primary methods to read data:

1. ⁠read(n)⁠: Reads ⁠n⁠bytes/characters. If ⁠n⁠is omitted, it reads the entire file.

2. ⁠readline()⁠: Reads a single line from the file up to the newline character.

3. ⁠readlines()⁠: Reads all lines and returns them as a list of strings.

# Example: Reading a file


file = open("[Link]", "r")
content = [Link]()
print(content)
[Link]()

Writing to a Text File

To write data, you must open the file in ⁠'w'⁠or ⁠'a'⁠mode. Python offers two methods:

1. ⁠write(string)⁠: Inserts the string into the file.

2. ⁠writelines(list)⁠: Inserts a list of strings into the file.

# Example: Writing to a file


file = open("[Link]", "w")
[Link]("Hello World!\n")
[Link](["Line 2\n", "Line 3\n"])
[Link]()

5.1.2 Accessing and Manipulating Files on the Disk

Beyond reading and writing, Python allows you to interact directly with the file system to
manipulate files on your disk. This includes checking if a file exists, renaming files, deleting
files, and retrieving file properties. These operations are performed using built-in modules,
primarily the ⁠os⁠module.

To use these functionalities, you must first import the module using ⁠import os⁠. Here are the
most frequently used functions for file manipulation:

Checking Existence: ⁠[Link]("filename")⁠returns ⁠True⁠if the file is present.

Renaming a File: ⁠[Link]("old_name.txt", "new_name.txt")⁠changes the file name.

Deleting a File: ⁠[Link]("[Link]")⁠permanently deletes the file from the disk.

import os

# Checking if a file exists before deleting it to avoid errors


if [Link]("old_data.txt"):
[Link]("old_data.txt", "archived_data.txt")
print("File renamed successfully.")
else:
print("The specified file does not exist.")

These operations are low-level system interactions, meaning they interact directly with your
operating system. Therefore, proper error checking is essential when writing these routines
in your exam.
5.1.3 Accessing and Manipulating Directories on the Disk

A directory (commonly known as a folder) is a collection of files and subdirectories. Python's


⁠os⁠module provides a powerful set of tools to create, navigate, list, and delete directories,
allowing comprehensive system-level automation.

Here are the vital directory manipulation commands:

Get Current Working Directory: ⁠[Link]()⁠returns the path of the folder your script is
currently running in.

Changing Directory: ⁠[Link]("path")⁠shifts the program's context to a different folder.

Creating a Directory: ⁠[Link]("new_folder")⁠creates a single folder.

Listing Contents: ⁠[Link](".")⁠returns a list of all files and folders inside the specified
directory.

Removing a Directory: ⁠[Link]("folder_name")⁠deletes an empty directory.

import os

# Displaying current path and listing contents


current_dir = [Link]()
print("Current Directory:", current_dir)

# Creating a new directory safely


if not [Link]("ExamNotes"):
[Link]("ExamNotes")
print("Directory created.")

# Listing all contents


print("Contents:", [Link]("."))

5.1.4 Format Operator, Command Line Arguments

Format Operator

When writing or displaying data, formatting is essential for readability. Python uses the
format operator ⁠%⁠or the modern ⁠.format()⁠method and f-strings to inject variables into
templates. The ⁠%⁠operator takes a format string on the left and values on the right. For
example, ⁠%d⁠is for integers, ⁠%s⁠for strings, and ⁠%f⁠for floats.

name = "Alice"
score = 95
# Using % operator
print("Student %s scored %d marks." % (name, score))
# Using modern f-string (Highly recommended)
print(f"Student {name} scored {score} marks.")
Command Line Arguments

Command-line arguments are inputs given to a script at the time of execution via the
terminal. In Python, these arguments are captured using the ⁠sys⁠module's list named
⁠[Link]⁠.

⁠[Link][0]⁠always stores the script name.

⁠[Link][1]⁠onwards stores the arguments passed by the user.

import sys

# Execution command: python [Link] arg1 arg2


print("Script Name:", [Link][0])
if len([Link]) > 1:
print("First argument received:", [Link][1])

5.1.5 Filenames and Paths

When working with files, specifying their location correctly is vital. A path is the address of a
file or folder on the storage drive. Paths are split into two categories:

1. Absolute Path: The complete address starting from the root directory (e.g.,
⁠C:\Users\Admin\Documents\[Link]⁠on Windows or ⁠/home/user/[Link]⁠on Linux).

2. Relative Path: The address relative to the current working directory where the script is
running (e.g., ⁠data/[Link]⁠or ⁠..\[Link]⁠).

Different operating systems use different separator characters (⁠\⁠for Windows, ⁠/⁠for
Unix/Linux). To write cross-platform code that runs smoothly on any system, Python provides
the ⁠[Link]⁠module.

import os

# Joining paths correctly independent of the OS


full_path = [Link]("Documents", "PythonProject", "[Link]")
print("Constructed Path:", full_path)

# Getting absolute path from a relative path


abs_path = [Link]("[Link]")
print("Absolute Path:", abs_path)

# Splitting a path into directory and file name


directory, filename = [Link](full_path)
print(f"Directory: {directory}, File: {filename}")
5.2 Exception Handling

During program execution, errors can occur. These are classified into compilation errors
(syntax errors discovered before running) and runtime errors (errors discovered during
execution). An Exception is a runtime error that disrupts the normal flow of instructions. If an
exception is not managed, the program crashes abruptly.

Exception handling is the process of intercepting these errors and executing alternative code
so the program can recover or terminate gracefully.

Python uses a structured mechanism containing blocks of code to handle these errors.
Without exception handling, simple issues like missing files or minor user input errors can
cause enterprise applications to crash completely. By incorporating exception handling,
developers ensure robust, fault-tolerant user experiences.

5.2.1 Errors and Exceptions

To handle errors effectively, we must distinguish between standard syntax errors and runtime
exceptions.

Syntax Errors

These happen when the developer violates the grammar rules of Python. The interpreter
detects them during the parsing stage before the program executes. Examples include
missing colons, unbalanced parentheses, or wrong indentation.

Exceptions

Even if a program is syntactically perfect, an error can occur when it executes. These are
Exceptions. Python represents exceptions as special built-in object classes. Common built-in
exceptions include:

⁠ZeroDivisionError⁠: Occurs when a number is divided by zero.

⁠FileNotFoundError⁠: Raised when a file cannot be found.

⁠ alueError⁠: Raised when a function receives an argument of the correct type but
V
inappropriate value.

⁠TypeError⁠: Raised when an operation is applied to an object of inappropriate type.

# Syntax Error example (detected before running):


# if True print("Hello") -> Missing colon and parenthesis

# Exception example (syntactically correct, but crashes at runtime):


# result = 10 / 0 -> Triggers ZeroDivisionError

5.2.2 Raising and Handling Exceptions


Handling Exceptions

Python uses ⁠try⁠and ⁠except⁠blocks to handle exceptions. Code that might cause an error is
placed inside the ⁠try⁠block. If an error occurs, execution jumps immediately to the ⁠except⁠
block.

try:
num = int(input("Enter a number: "))
result = 10 / num
print("Result is:", result)
except ZeroDivisionError:
print("Error: You cannot divide by zero!")
except ValueError:
print("Error: Please enter a valid integer!")

Raising Exceptions

Sometimes, you need to intentionally generate an error based on custom logic. This is
achieved using the ⁠raise⁠keyword. It forces a specific exception to occur.

def check_age(age):
if age < 0:
raise ValueError("Age cannot be a negative number!")
return f"Age is {age}"

try:
print(check_age(-5))
except ValueError as e:
print("Caught Custom Exception:", e)

5.2.3 Try and Finally Statement

The ⁠finally⁠block is a critical component of Python’s exception handling suite. It defines a


block of code that always executes, regardless of whether an exception was raised or
successfully handled inside the ⁠try⁠and ⁠except⁠structures.

The main purpose of the ⁠finally⁠block is resource cleanup. Tasks like closing open files,
breaking database connections, or disconnecting from networks must be executed under all
conditions to prevent resource leaks.

file = None
try:
file = open("[Link]", "r")
content = [Link]()
# Imagine an error occurs here unexpectedly
value = 1 / 0
except ZeroDivisionError:
print("Handled a division by zero error.")
finally:
if file:
[Link]()
print("File has been closed safely by finally block.")

Even if the ⁠try⁠block contains a ⁠return⁠statement, the ⁠finally⁠block will execute right before the
function exits. This makes it an incredibly reliable safety net for critical operations.

5.2.4 With Statement

The ⁠with⁠statement in Python is a clean, modern alternative to using ⁠try...finally⁠blocks for


managing system resources. It utilizes a design mechanism known as a Context Manager.

When working with files, omitting the ⁠.close()⁠function can lead to memory exhaustion or
corrupted data. The ⁠with⁠statement guarantees that clean-up operations are automatically
performed as soon as execution leaves its indented block, even if an exception occurs
mid-way.

# The traditional way requires manual closing:


# f = open("[Link]", "r") -> read -> [Link]()

# The clean, modern 'with' statement approach:


with open("exam_data.txt", "w") as file:
[Link]("Writing data using context managers.")
# No need to call [Link]()!

print("File closed automatically check:", [Link]) # Outputs True

Using ⁠with⁠makes your code shorter, significantly more readable, and robust against
developer oversight. In exams, using the ⁠with⁠statement when answering file I/O questions
demonstrates modern Python proficiency.

5.2.5 Catching Exceptions

When writing enterprise applications, multiple types of errors can arise from a single
complex block of code. Python offers flexible options to catch and handle these exceptions
collectively or granularly.

1. Catching Specific Exceptions

It is best practice to catch specific exceptions so you can provide precise solutions for each
unique issue, as demonstrated in topic 5.2.2.

2. Catching Multiple Exceptions in One Block

If separate errors share the same resolution path, you can group them as a tuple within a
single ⁠except⁠statement.
try:
# Code that could throw multiple errors
file = open("[Link]")
data = int([Link]())
except (FileNotFoundError, ValueError) as error_details:
print("An configuration or initialization error occurred:", error_details)

3. Catching All Exceptions

You can use a generic ⁠except Exception:⁠block to intercept any error that escapes previous
filters. This should generally be placed at the very bottom of your handling tree.

try:
result = 10 / int(input())
except Exception as e:
print(f"An unexpected error occurred: {e}")

5.3 Pickling

Data structures created in a running script (like nested lists, dictionaries, or custom object
instances) exist purely within temporary RAM memory. If you want to save these complex
objects to a file and reload them later exactly as they were, standard text-writing functions
are insufficient because they only accept flat strings.

Pickling is Python’s native process of converting a complex Python object hierarchy into a
byte stream (a series of 0s and 1s). This byte stream can then be written to a binary file or
transmitted across a network.

The reverse process—converting a serialized byte stream back into a fully functional live
Python object—is known as Unpickling. This entire methodology is widely referred to in
computer science as serialization or object persistence.

5.3.1 Working with Database

While pickling is highly efficient for saving standalone objects, large-scale applications
require a structured framework called a Database Management System (DBMS). Python
comes packaged with a lightweight, serverless relational database engine named SQLite.

To interface with a relational database in Python, you use the built-in ⁠sqlite3⁠module. The
standard workflow follows these precise stages:

1. Establish Connection: Create a connection object linking to the database file.

2. Create Cursor: Generate a cursor object to execute structured SQL statements.

3. Execute SQL queries: Run commands to create tables, insert records, or fetch entries.

4. Commit Changes: Save the executed transactions permanently.


5. Close Resources: Shut down connections cleanly.

import sqlite3

# Connect to database (creates file if missing)


conn = [Link]("[Link]")
cursor = [Link]()

# Create table
[Link]("CREATE TABLE IF NOT EXISTS Users (id INT, name TEXT)")

# Insert data
[Link]("INSERT INTO Users VALUES (1, 'Alice')")
[Link]()

# Retrieve data
[Link]("SELECT * FROM Users")
print([Link]())

# Close connection
[Link]()

5.3.2 Concept of Pickling and Unpickling

To implement serialization, Python utilizes its standard built-in library module named ⁠pickle⁠.
Because pickling processes complex data structures into raw byte encodings, files used for
pickling operations must always be opened in binary modes (⁠'wb'⁠for writing binary, ⁠'rb'⁠for
reading binary).

The module relies heavily on two primary functions:

⁠ [Link](object, file)⁠: Serializes the specified object and writes it directly to an open
p
binary file.

⁠[Link](file)⁠: Reads a serialized byte stream from an open binary file and reconstructs it
back into its original live Python object format.

Security Warning

It is vital to mention in your exam that you should never unpickle data received from an
untrusted source. Malicious byte streams can be engineered to execute arbitrary code
automatically during the unpickling stage, posing security risks.

5.3.3 Code Snippet Implementing the Concept of Pickling and Unpickling

Here is a clean, complete, and reproducible code snippet showing how to pickle a Python
dictionary into a file, followed by unpickling it back into program memory.

import pickle
# Define a complex Python object (a dictionary containing a list)
student_data = {
"roll_no": 101,
"name": "John Doe",
"subjects": ["Physics", "Chemistry", "Mathematics"]
}

# --- STAGE 1: PICKLING (Serialization) ---


# Opening file in 'wb' mode (write-binary)
with open("[Link]", "wb") as binary_file:
[Link](student_data, binary_file)
print("Object successfully serialized and saved to disk.")

# --- STAGE 2: UNPICKLING (Deserialization) ---


# Opening file in 'rb' mode (read-binary)
with open("[Link]", "rb") as binary_file:
loaded_data = [Link](binary_file)
print("\nObject successfully reconstructed from disk:")
print("Data Type:", type(loaded_data))
print("Content:", loaded_data)

5.3.4 Pipes

In operating systems and high-performance computing, a Pipe is a data communication


channel that connects the output stream of one active process directly to the input stream of
another process. Instead of writing data out to a slow physical file on the disk and having a
second program open and read that file, a pipe enables data to pass instantly via shared
volatile memory buffers.

In Python, you can interact with operating system pipes using modules like ⁠os⁠or the
advanced ⁠subprocess⁠module. Pipes are exceptionally powerful for automating CLI tasks,
allowing Python to spin up terminal commands, feed them parameters dynamically, and
capture their output strings programmatically.

import subprocess

# Using a subprocess pipe to execute an OS level command ('ls' or 'dir')


# and route its output directly back to our Python script memory.
process = [Link](['echo', 'Hello from OS Pipe!'],
stdout=[Link],
text=True)

# Read the output from the pipe channel


stdout, stderr = [Link]()
print("Captured Output via Pipe:", [Link]())

You might also like