0% found this document useful (0 votes)
14 views9 pages

Python File Management and Debugging Guide

This document provides an introduction to Python programming, focusing on file organization, debugging techniques, and practical projects. It covers the use of the shutil and zipfile modules for file management, as well as debugging methods like raising exceptions, logging, and using IDLE's debugger. Additionally, it includes projects for renaming files with different date formats and backing up folders into ZIP files.

Uploaded by

Roots V
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)
14 views9 pages

Python File Management and Debugging Guide

This document provides an introduction to Python programming, focusing on file organization, debugging techniques, and practical projects. It covers the use of the shutil and zipfile modules for file management, as well as debugging methods like raising exceptions, logging, and using IDLE's debugger. Additionally, it includes projects for renaming files with different date formats and backing up folders into ZIP files.

Uploaded by

Roots V
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

An Autonomous Institute

NEAR ITPB, CHANNASANDRA, BENGALURU – 560 067


Affiliated to VTU,Belagavi
Approved by AICTE, New Delhi
Recognized by UGC under 2(f) & 12(B)
Accredited by NBA & NAAC

DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

INTRODUCTION TO PYTHON PROGRAMMING – MVJ22PCLK25B


~PREPARED BY DEEPTHI S S , ASSISTANT PROFESSOR - CSE
Module 4:
Organizing Files: The shutil Module, Walking a Directory Tree, Compressing Files with the
zipfile Module, Project: Renaming Files with American-Style Dates to European-Style
Dates, Project: Backing Up a Folder into a ZIP File,
Debugging: Raising Exceptions, Getting the Traceback as a String, Assertions, Logging, IDLE‟s
Debugger

Organising Files:

1. Organizing Files: The shutil Module

The shutil (shell utilities) module lets you copy, move, rename, and delete files or entire
directories.

Important shutil functions:

• [Link](source, destination)
Copies the file at source to destination.
If destination is a folder, the file is copied into it.
• [Link](source_folder, destination_folder)
Recursively copies an entire directory tree.
• [Link](source, destination)
Moves a file or folder. Renames if the destination is just a filename.
• [Link](path)
Deletes a folder and all its contents.
2. Walking a Directory Tree

Python’s [Link]() function generates the file names in a directory tree by walking the tree
either top-down or bottom-up.

Syntax:

import os

for foldername, subfolders, filenames in [Link]('your_path'):


print(f'Folder: {foldername}')
print(f'Subfolders: {subfolders}')
print(f'Files: {filenames}')

Explanation:
• foldername: Current folder being walked through.

• subfolders: List of subfolders in that folder.

• filenames: List of filenames in that folder.

3. Compressing Files with the zipfile Module

Python’s zipfile module allows you to create, read, write, extract, and list ZIP files.

Creating and Writing ZIP Files:

Reading and Extracting:


4. Project: Renaming Files with American-Style Dates to European-Style Dates

Goal:

Rename files with dates in MM-DD-YYYY format to DD-MM-YYYY format.

Steps:

1. Use [Link]() and re module to find files with date format.


2. Identify and extract parts: month, day, year, and the rest of the filename.
3. Construct the new filename with European-style date.
4. Rename using [Link]().

Explanation:

There are two files with names :

report_03-[Link] and want to rename as report_25-[Link]

Line by line Exaplanation:

import shutil, os, re

• shutil: for moving (renaming) files.

• os: to list files in the current directory.

• re: for using regular expressions to detect American-style dates.


This regular expression finds files with American-style dates: MM-DD-YYYY.

• ^(.*?): Matches and captures any characters at the start of the filename.

• ((0|1)?\d)-: Matches the month part, allowing one or two digits.

• ((0|1|2|3)?\d)-: Matches the day part.

• ((19|20)\d\d): Matches the year part, starting with 19 or 20.

• (.*?)$: Matches anything after the date.

• The use of [Link] allows comments and spacing in the regex for readability.

for filename in [Link]('.'): // Lists every file and folder in the current directory (.).
mo = date_pattern.search(filename)
• mo stands for "match object".
• search() looks for a match of the date pattern in the filename.
• If the pattern is found, mo will contain the matched text and groups.

if mo is None:
continue // If no date is found in the filename, skip to the next file.

before = [Link](1) // Text before the date.


month = [Link](2) // The American-style month.
day = [Link](4) // the day part
year = [Link](6) // the year part
after = [Link](8) // text after the date

euro_filename = f'{before}{day}-{month}-{year}{after}' //Constructs the new filename in


European-style date format: DD-MM-YYYY.

[Link](filename, euro_filename) // Renames (moves) the file from the original name to the new
name.

example
Project: Backing Up a Folder into a ZIP File

Goal:

Create a ZIP file that contains the entire contents of a folder and ensures previous backups
aren’t overwritten.

Features:

• Automatically names ZIPs like foldername_1.zip, foldername_2.zip, etc.


• Avoids re-zipping ZIP files already in the folder.
• Uses [Link]() to gather all files.

import zipfile, os # Import the modules needed for zipping files and navigating the file system

def backup_to_zip(folder):
# Convert the folder name to an absolute path (for consistency and avoiding confusion)
folder = [Link](folder)

# Start with a number to create unique backup file names


number = 1

# Keep incrementing the number until we find a filename that doesn't exist yet
while True:
zip_filename = [Link](folder) + f'_{number}.zip' # e.g., 'myfolder_1.zip'
if not [Link](zip_filename): # Check if this ZIP file already exists
break # If not, we can use this name
number += 1 # Otherwise, try the next number

print(f'Creating {zip_filename}...')

# Create the new ZIP file in write mode


backup_zip = [Link](zip_filename, 'w')

# Walk through every folder, subfolder, and file in the given folder
for foldername, subfolders, filenames in [Link](folder):
print(f'Adding files in {foldername}...')

# Add the current folder to the ZIP file


backup_zip.write(foldername)

# Loop through each file in the folder


for filename in filenames:
new_base = [Link](folder) + '_' # This helps us detect previous backup files

# Skip any files that are already backup ZIPs made by this script
if [Link](new_base) and [Link]('.zip'):
continue # Don’t back up backup ZIP files

# Create the full path of the file and add it to the ZIP
file_path = [Link](foldername, filename)
backup_zip.write(file_path)

# Close the ZIP file after writing all files


backup_zip.close()
print('Done.')
Debugging

1. Raising Exceptions

Purpose:

To intentionally cause an error in your code when something goes wrong.

Example & Explanation:

def box_print(symbol, width, height):


if len(symbol) != 1:
raise Exception('Symbol must be a single character string.')
# Custom error if symbol isn't 1 character

if width <= 2:
raise Exception('Width must be greater than 2.') # Width
must allow drawing a box

if height <= 2:
raise Exception('Height must be greater than 2.') #
Height too small to make a box

print(symbol * width) # Top of the box


for i in range(height - 2):
print(symbol + ' ' * (width - 2) + symbol) # Middle rows
print(symbol * width) # Bottom of the box

box_print('*', 4, 4)

Output:

markdown
Copy code
****
* *
* *
****

If input is invalid:

box_print('**', 4, 4)

Raises:

Exception: Symbol must be a single character string.

2. Getting the Traceback as a String

Purpose:

To log or display the full traceback message without crashing the program.

Example:

import traceback
try:
raise Exception('This is the error message.')
except:
error_file = open('error_log.txt', 'w')
error_file.write(traceback.format_exc()) # Get the traceback
as a string and write it to a file
error_file.close()
print('The traceback info was written to error_log.txt')

What It Does:

• traceback.format_exc() captures the error message and stack trace.


• It’s useful in production code to log errors instead of showing them to users.

3. Assertions

Purpose:

To check if a condition is true while the program runs.


If not, an AssertionError is raised.

Example:

pod_bay_door_status = 'open'

assert pod_bay_door_status == 'closed', 'The pod bay doors need to


be "closed".'

Output:

AssertionError: The pod bay doors need to be "closed".

Tip:

Use assertions for sanity checks during development, not for handling runtime user input.

4. Logging

Purpose:

To track and record what the program is doing, especially useful in debugging large programs.

Example:

import logging

[Link](level=[Link], format='%(asctime)s -
%(levelname)s - %(message)s')
[Link]('Start of program')

def factorial(n):
[Link](f'Start of factorial({n})')
total = 1
for i in range(1, n + 1):
total *= i
[Link](f'i = {i}, total = {total}')
[Link](f'End of factorial({n})')
return total

print(factorial(5))
[Link]('End of program')

Output:

(Logged in console)

2025-05-20 18:30:01,123 - DEBUG - Start of program


2025-05-20 18:30:01,123 - DEBUG - Start of factorial(5)
...
2025-05-20 18:30:01,123 - DEBUG - End of program

Logging Levels:

• DEBUG: Details for diagnosing problems.


• INFO: Confirmation that things work.
• WARNING: Something unexpected.
• ERROR: A more serious problem.
• CRITICAL: Program may not continue.

5. IDLE’s Debugger

Purpose:

To step through your code line by line and watch variables change.

How to Use:

1. Open your script in IDLE.


2. From the menu: Debug → Debugger.
3. Run your script.
4. You can now:
o Step through the code (Step button)
o View the call stack and local variables
o Watch execution line-by-line

Example:

If you run this:

def add(x, y):

total = x + y
return total

result = add(5, 7)
print(result)

Using the Debugger:

• You can see x = 5, y = 7, total = 12, and result = 12 as it runs.


Summary Table

Feature Purpose Output Example / Use Case


raise Exception() Stop execution when "Symbol must be a
something’s wrong single character"
traceback.format_exc() Get error details as a Log error to file
string
assert condition Ensure something is true Raises AssertionError if not
during execution
[Link]() Track what's happening See values, logic, steps during
program execution
IDLE Debugger Step-by-step run and Visual debugging tool
variable view

Common questions

Powered by AI

Assertions in Python serve as a debugging aid to verify that certain conditions hold true while the program runs. They help catch bugs by raising an AssertionError when a specified condition evaluates to false, aiding in early error detection during development. For example, `assert pod_bay_door_status == 'closed', 'The pod bay doors need to be "closed".'` checks that a variable `pod_bay_door_status` is 'closed'; if it's not, an AssertionError is raised with a custom message .

Assertions are intended for use as sanity checks during development because they help verify assumptions made in the code, detecting logical errors early in the development cycle. They raise an AssertionError when a condition presumed to be true fails. This guiding principle encourages finding and fixing bugs preemptively. However, they should not be used for handling runtime user input since assertions can be globally disabled, making them unreliable for enforcing constraints or validating user data in production environments. Proper error handling techniques and input validation mechanisms are more suitable for such purposes .

A Python project automating ZIP backups to prevent overwriting involves creating uniquely named ZIP files that contain a folder's contents. The logic starts by obtaining an absolute path of the folder using os.path.abspath() to avoid confusion. A numerical suffix appended to the folder name forms a prospective ZIP name (e.g., myfolder_1.zip). A loop checks for existing files with the constructed names; if a file exists, the number increments until an unused name is found. os.walk() collects all the files while excluding existing backup ZIPs, and zipfile.ZipFile() writes these files into the newly named archive. This ensures unique backups while preventing overwriting .

Python's os.walk() function is employed to generate file names in a directory tree by walking the tree either top-down or bottom-up. The function returns the current folder path, lists of its subfolders, and filenames, allowing users to systematically navigate through directories. This is particularly useful for large file systems, where users need to process or organize files efficiently without manually traversing the directory structure. The flexibility in traversal order (top-down or bottom-up) adds to its utility in various file management tasks .

Python's os.path.abspath() is used to convert a folder name into its absolute path, ensuring consistency and avoiding confusion during file operations. In the context of backing up a folder into a ZIP file, using the absolute path helps eliminate issues related to relative path dependencies, ensuring that the backup process is executed correctly regardless of the user's current directory. This reliability is crucial for automating and validating backup operations across different environments .

In the project to rename files with American-style dates to European-style dates, regular expressions are used to identify and extract date components from filenames. The pattern is designed to match dates in the MM-DD-YYYY format through groups: capturing the month, day, and year separately. For example, a regular expression `(0|1)?\d-` matches the month, `((0|1|2|3)?\d)-` the day, and `((19|20)\d\d)` the year. These components are rearranged into the DD-MM-YYYY format for renaming. The re module facilitates these operations with search and group methods, which find and restructure the file names accurately .

Python's zipfile module facilitates file compression by enabling the creation, reading, writing, extraction, and listing of ZIP files. This module is particularly advantageous for backing up data, reducing file storage space, and bundling files for distribution. By using methods like zipfile.ZipFile(), users can manipulate ZIP files efficiently within scripts, allowing automation of file handling processes such as backups and archiving without manual intervention. Additionally, it helps avoid overwriting by appending numeric identifiers to ZIP file names, enhancing its utility in systematic data management .

The shutil module in Python is designed to assist in file organization by allowing users to perform high-level file operations such as copying, moving, renaming, and deleting files or entire directories. Its primary functions include shutil.copy(), which copies a file to a specified destination; shutil.copytree(), which recursively copies an entire directory tree; shutil.move(), which moves a file or directory, renaming it if the destination name is provided; and shutil.rmtree(), which deletes a directory and all its contents .

Python's IDLE debugger allows developers to perform step-by-step execution of their code, facilitating detailed analysis and understanding of program flow. By opening a script in IDLE and activating the debugger through the menu (Debug → Debugger), users can proceed through code execution line-by-line. The debugger displays the call stack and current local variables, enabling close observation of how variables change over time. This visual and interactive debugging method enhances problem-solving by clearly showing each step and the impact on program state, making it invaluable for resolving complex logic errors .

Error handling in Python is efficiently managed using the logging and traceback modules. The logging module is used to record events that happen during execution, particularly for debugging larger applications. It provides various log levels (DEBUG, INFO, WARNING, ERROR, CRITICAL) and formats to keep track of the flow and state of an application. Meanwhile, the traceback module helps capture error messages and stack traces using traceback.format_exc(), allowing developers to extract and log comprehensive error information without terminating the application. This combination offers a robust mechanism for monitoring and managing runtime issues .

You might also like