Module 4 Python
Module 4 Python
MODULE 4 PYTHON
Syllabus: 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.
E
Textbook 1: Chapters 9-10
C
1. ORGANIZING THE FILES
N
Python can automate file management tasks like copying, renaming, moving, or compressing files to save
JN
time and avoid errors. Examples include:
L,
● Copying all PDF files from multiple folders.
● Renaming files, like removing leading zeros.
IM
● Creating ZIP backups of folders.
,A
To see file extensions (e.g., .txt, .pdf), make sure they’re visible in your file browser. In Windows, enable
this via Control Panel > Appearance > Folder Options > View > Uncheck "Hide extensions for known file
types."
M
The shutil module in Python provides functions to handle file and folder operations like copying, moving,
AS
shutil.copy(source, destination)
W
● This function copies a file from the source path to the destination path.
● If a folder is specified as the destination, the original filename is used for the new copied file.
YA
● Example
LI
import shutil, os
os.chdir('C:\\')
AA
shutil.copytree('C:\\bacon', 'C:\\bacon_backup')
● Output: C:\\delicious\\spam.txt
shutil.copytree(source, destination)
This function copies an entire folder along with all its subfolders and files to a new location.
Example
import shutil, os
os.chdir('C:\\')
shutil.copytree('C:\\bacon', 'C:\\bacon_backup')
shutil.move(source, destination)
E
● If destination is a folder, the file is moved into that folder.
C
Example:
N
import shutil
JN
shutil.move('C:\\bacon.txt', 'C:\\eggs')
Output: C:\\eggs\\bacon.txt
L,
Renaming Files You can move and rename files at the same time.
IM
Example:
,A
shutil.move('C:\\bacon.txt', 'C:\\eggs\\new_bacon.txt')
M
Output: C:\\eggs\\new_bacon.txt
EE
shutil.move('spam.txt', 'c:\\does_not_exist\\eggs\\ham')
W
Example:
LI
AA
shutil.move('C:\\bacon.txt', 'C:\\eggs')
If the eggs folder exists, the file bacon.txt will be moved there. If a file with the same name already exists,
it will be overwritten.
os.unlink(path)
os.rmdir(path)
shutil.rmtree(path)
Example:
E
import os
C
os.unlink('file.txt') # Deletes a file
N
JN
os.rmdir('empty_folder') # Deletes an empty folder
L,
Caution!
IM
Be careful when deleting files or folders. Always check what will be deleted first to avoid accidental loss
,A
of important data. Use print statements to review the files before deleting them
The concept of walking a directory tree in Python involves going through each folder, its subfolders, and
EE
files within them. This allows you to perform tasks such as renaming, copying, deleting, or organizing
files systematically.
AS
os.walk() Function
W
The os.walk() function helps traverse the directory tree. It takes the path of a folder and returns:
Example Scenario
AA
Let's say you have a folder C:\delicious with subfolders and files inside it. You want to print the names of
all subfolders and files in each folder.
Example Program:
import os
E
C
N
JN
L,
IM
,A
M
EE
Output:
Explanation
You can use the information from os.walk() to perform actions on each folder or file as needed.
ZIP files are compressed files that can contain multiple files and subfolders. Python provides
functions in the zipfile module to create, read, extract, and modify ZIP files.
E
To work with a ZIP file, you need to create a ZipFile object:
C
import zipfile, os
N
os.chdir('C:\\') # Move to folder with ZIP file
JN
exampleZip = zipfile.ZipFile('example.zip')
L,
● exampleZip.getinfo('spam.txt') gives details like file size and compressed size.
IM
You can calculate how much space is saved by compression:
,A
'Compressed file is %sx smaller!' % (round(spamInfo.file_size / spamInfo.compress_size, 2))
M
3. Creating and Adding to ZIP Files To create a new ZIP file and add files:
YA
newZip.close()
AA
The write() method compresses and adds files into the ZIP file.
newZip.close()
Append mode ('a') allows adding new files without deleting existing content.
Conclusion
● ZIP Files: Compressed files that hold multiple files and folders.
● ZipFile Object: Acts like a File object, allowing interaction with ZIP files (reading,
writing, extracting).
E
● extractall(): Extracts all files from ZIP.
C
● extract(): Extracts specific files.
N
● write(): Adds a file to a ZIP file with compression.
● append mode: Adds files to an existing ZIP file without removing current contents.
JN
4. PROJECT: RENAMING FILES WITH AMERICAN-STYLE DATES TO
L,
EUROPEAN-STYLE DATES SAY YOUR BOSS EMAILS
IM
This project involves writing a Python program to rename files with American-style dates
(MM-DD-YYYY) in their filenames to European-style dates (DD-MM-YYYY).
,A
Step-by-Step Explanation:
M
The first part of the program involves creating a regex pattern to match filenames with American-style
dates.
AS
2. Create a Regex:
YA
""", re.VERBOSE)
Explanation:
((0|1)?\d) matches the month, with optional leading zeros or 0 or 1 in some cases.
E
C
Step 2: Identify the Date Parts from the Filenames
N
Next, the program loops over the filenames in the current working directory and matches them against the
JN
regex pattern.
L,
for amerFilename in os.listdir('.'):
IM
mo = datePattern.search(amerFilename)
,A
2. Skip files without dates:
M
if mo == None:
EE
continue
beforePart = mo.group(1)
W
monthPart = mo.group(2)
YA
dayPart = mo.group(4)
yearPart = mo.group(6)
LI
afterPart = mo.group(8)
AA
Once you have the different parts, concatenate them to form the European-style date format.
absWorkingDir = os.path.abspath('.')
E
shutil.move(amerFilename, euroFilename)
C
Testing the Program
N
JN
Before actually renaming the files, you can print the filenames to confirm they will be renamed correctly:
L,
Uncomment the shutil.move() line after confirming the results.
IM
Example Workflow:
,A
1. The program searches for files like 03-25-2025-report.docx and renames them to
25-03-2025-report.docx.
M
2. It skips files that do not contain dates in the American format.
EE
Similar Programs:
AS
5. DEBUGGING
LI
Debugging means finding and fixing mistakes (called bugs) in your code. Bugs are errors that cause your
AA
program to behave in unexpected ways. Debugging helps you figure out what’s going wrong so you can
fix it.
Imagine you’re writing instructions for a robot to make a peanut butter sandwich. You give it these steps:
But when you run the program, the robot puts the peanut butter on the outside of the sandwich instead of
inside! Something went wrong, so now you need to debug.
Debugging Tools: To debug your program, you have tools and techniques to help you:
1. Logging:Think of logging as leaving notes while the robot works. For example:
E
● After Step 2, leave a note: “Spread peanut butter.”
C
● After Step 3, leave a note: “Sandwich done.”
N
When the sandwich looks wrong, you can read the notes to see where the problem happened. For
JN
instance, if the note says: “Spread peanut butter on both sides,” you’ll know that Step 2 needs fixing.
2. Assertions: Assertions are checkpoints in your program. They stop the robot if something goes wrong.
L,
For example:
IM
● After Step 2, add an assertion: "Check that peanut butter is on one slice of bread, not both.”
,A
If the robot spreads peanut butter on both slices, the assertion will catch the mistake immediately, so you
can fix it early.
M
3. Debugger: The debugger works like a super-slow robot. Instead of doing all the steps quickly, it goes
EE
one step at a time. This way, you can check exactly what the robot is doing and what the sandwich looks
like after each step. It’s like watching the robot in slow motion to see where it messes up.
AS
Without debugging tools, you’d be guessing why your sandwich looks wrong. With them, you can find
W
out exactly where the robot misunderstood your instructions and fix it without frustration. Debugging is a
normal and important part of programming—everyone makes mistakes, even experts
YA
6. RAISING EXCEPTIONS
LI
When you write a program, sometimes things don’t go as planned—someone might give wrong inputs or
do something unexpected. Exceptions are Python’s way of stopping and saying, "Hey, something’s not
AA
right!" You can handle these exceptions to prevent the program from crashing, and you can even create
your own exceptions to stop the program when specific rules aren’t followed.
Imagine you’re writing a recipe for a cake. Here’s what you want to do:
If someone gives wrong information, you want to stop and say what went wrong, instead of baking a bad
cake.
You can create rules for your recipe and raise exceptions if those rules aren’t followed. For example:
E
def bakeCake(flour, temperature, time):
if len(flour) != 1:
C
raise Exception("You must choose exactly one type of flour!")
N
if temperature <= 300:
raise Exception("The oven temperature must be greater than 300°F!")
JN
if time <= 15:
raise Exception("The baking time must be longer than 15 minutes!")
L,
print("Cake is baking!")
IM
Here’s how this works:
1. If there’s more than one type of flour, the program stops and says: "You must choose exactly one
,A
type of flour!"
2. If the temperature is too low, it says: "The oven temperature must be greater than 300°F!"
M
3. If the baking time is too short, it says: "The baking time must be longer than 15 minutes!"
EE
Now, if you’re trying out different combinations of ingredients, you don’t want the program to crash
AS
every time. Instead, you can use try and except to catch the exceptions and print friendly error messages.
for flour, temp, time in [("all-purpose", 350, 20), ("", 400, 30), ("whole-wheat, almond", 200, 25)]:
W
try:
YA
Using exceptions lets you enforce rules in your program. If something isn’t right, you can stop, explain
the problem, and prevent bad results. By using try and except, you can handle these errors gracefully and
keep the program running for other tasks
When Python encounters an error (called an exception), it provides a detailed report called a traceback.
E
The traceback tells you:
C
1. What went wrong (the error message).
N
2. Where it happened (the file and line number).
3. How it got there (a list of function calls leading to the error, called the call stack).
JN
You can see the traceback when Python prints it out during an error, but you can also save this
L,
information to a file for later debugging using the traceback module.
IM
Scenario: A Cookie-Baking Program ( for understanding purpose)
Imagine you're writing a program that calls multiple functions to bake cookies. If something goes wrong,
,A
you want to know exactly which step caused the problem. Here’s the setup:
M
Program
EE
def startBaking():
mixIngredients()
W
def mixIngredients():
bake()
YA
def bake():
raise Exception("Oven temperature is too low!")
startBaking()
LI
Traceback: What Happens When It Breaks When you run this code, Python crashes and shows
AA
bake()
File "cookieProgram.py", line 8, in bake
raise Exception("Oven temperature is too low!")
Exception: Oven temperature is too low!
E
3. The call stack shows how the program got there:
startBaking → mixIngredients → bake.
C
N
Getting and Saving the Traceback
JN
Instead of crashing the program, you can catch the error and save the traceback to a file using the
traceback module. For example:
L,
import traceback
IM
try:
startBaking()
,A
except Exception as e:
with open('errorLog.txt', 'w') as errorFile:
errorFile.write(traceback.format_exc())
M
print("An error occurred, but the details have been saved to errorLog.txt.")
EE
How It Works:
1. try block: Runs the code and watches for errors.
AS
4. Saving to a file: Writes the traceback to a file (e.g., errorLog.txt) so you can look at it later.
Example Output
YA
bake()
File "cookieProgram.py", line 8, in bake
raise Exception("Oven temperature is too low!")
Exception: Oven temperature is too low!
1. Debug Later: If the program is used by someone else, they don’t see scary error messages.
Instead, you get all the details in a log file.
E
2. Graceful Handling: Your program doesn’t crash—it keeps running after saving the error.
3. Track Issues: The traceback helps you pinpoint exactly where things went wrong, making
C
debugging much easier.
N
8. ASSERTIONS
JN
An assertion is like a quick check in your program to make sure something is working as expected. It
L,
says:
IM
1. "I expect this to be true."
2. "If it's not true, stop everything and show me what's wrong!"
,A
If the condition in the assertion fails, Python raises an AssertionError and stops running. This helps catch
mistakes early before they cause bigger problems later.
M
● Condition: Something that should always be true (like x > 0 or status == "open").
W
Imagine you're coding a simulation of an airplane's pod bay doors. You want to ensure the doors are
LI
This helps you immediately notice the problem and fix it.
E
Imagine you're building a traffic light simulation where:
C
1. North-south (NS) and east-west (EW) lights must always follow traffic rules.
N
2. One light must always be red to avoid accidents.
JN
Code to Switch Traffic Lights
def switchLights(stoplight):
L,
for key in stoplight.keys():
if stoplight[key] == 'green':
IM
stoplight[key] = 'yellow'
elif stoplight[key] == 'yellow':
,A
stoplight[key] = 'red'
elif stoplight[key] == 'red':
stoplight[key] = 'green'
M
switchLights(market_2nd)
What Happens?
YA
1. When you switch the lights, they change like this:
○ 'ns': 'green' becomes 'yellow'.
LI
This prevents potential accidents in the simulation by ensuring the logic is fixed right away.
1. Catch Bugs Early: They help detect logic errors before they cause bigger problems.
2. Fail Fast: If something’s wrong, the program stops immediately, pointing you to the issue.
3. Save Debugging Time: You know exactly where the problem is and what caused it.
Disabling Assertions
When you're done testing, you can disable assertions by running Python with the -O option (optimized
mode). This skips all assertions to improve performance in the final product.
E
Conclusion
C
● Assertions are sanity checks to ensure your program logic is correct.
N
● They’re for development, not for handling user errors.
● Use assertions to fail fast and debug more effectively.
JN
● Example: Ensure one traffic light is always red to prevent simulation accidents.
L,
9.LOGGING
IM
Logging is a way to track events or messages from your program as it runs. It helps programmers see
what the program is doing, find issues, and understand its behavior. Instead of just printing messages
using print(), logging gives a more structured and organized way to collect information about the
,A
program’s execution.
M
○ Logging also shows the sequence in which events happen, helping you catch problems in
your code.
W
Example Scenario Imagine This Situation:You're writing a program that calculates the factorial of a
number. However, there's a bug in your code. You want to find where the error occurs without printing
hundreds of messages manually.
Code Example
E
import logging
C
# Setup logging to show DEBUG messages and format them
N
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')
# Start of program
JN
logging.debug('Start of program')
def factorial(n):
L,
logging.debug(f'Start of factorial({n})') # Log the start of the function
total = 1
IM
for i in range(1, n + 1): # Corrected the range to start from 1
total *= i
,A
logging.debug(f'i is {i}, total is {total}') # Log each step in the loop
logging.debug(f'End of factorial({n})')
M
return total
result = factorial(5) # Calculate factorial of 5
EE
1. If the program doesn’t work as expected, the log messages help pinpoint the issue.
○ Example: If i starts from 0 instead of 1, the log will show i = 0, causing incorrect results.
2. You can save logs to a file for review without cluttering your screen:
E
● More organized: Logs show timestamps and levels of importance.
● Easily disable or enable: Use logging.disable(logging.CRITICAL) to turn off all logs.
C
● Keeps code clean: No need to remove debug messages manually.
N
● Saves time: Provides detailed insights into program execution.
JN
Logging is like having a diary of what your program does, helping you find and fix problems much faster
L,
10. IDLE’S DEBUGGER
IM
The IDLE Debugger is a tool in Python's IDLE environment that helps you find and fix errors in your
code by running it one line at a time. While using the debugger, you can check the values of variables at
,A
different points in your program to understand what's happening.
M
EE
AS
W
YA
LI
AA
○ To understand code flow: It shows the order in which your code is executed.
3. How It Works:
○ When you enable the debugger, it shows:
■ The next line of code to be executed.
■ Local variables: Variables inside the current function.
■ Global variables: Variables defined outside of functions or available to the whole
program.
○ It pauses until you tell it what to do next.
4. Debugging Buttons:
E
○ Go: Runs the program normally until it ends or hits a breakpoint (a marker where the
C
program pauses).
○ Step: Runs the next line of code and pauses again.
N
○ Over: Runs the next line of code, skipping over the details of any function calls.
JN
○ Out: Runs the code until the current function is finished.
○ Quit: Stops the debugger and the program.
L,
Example Scenario
IM
Imagine you wrote a program to calculate the average of three numbers:
,A
def calculate_average(a, b, c):
total = a + b + c
M
average = total / 3
return average
EE
result = calculate_average(4, 5, 6)
print("The average is:", result)
AS
But it gives the wrong output. To debug this, you can use the IDLE Debugger.
2. Click Debug > Debugger in the IDLE menu to enable the debugger.
3. Run your program. The Debug Control window appears.
4. Use the buttons:
LI
○ Step: To see each line of code execute. You can check the values of total and average
after each step.
AA
○ Over: If you don’t need to see inside built-in functions (like print()).
○ Out: To exit a function after stepping into it.
5. Check the variable values in the Locals or Globals sections of the Debug Control window.
● If total has the wrong value, you'll catch the error as soon as the total = a + b + c line runs.
● If the average is calculated incorrectly, you'll see it immediately after the division step.
Using IDLE’s Debugger lets you find errors without guessing, making debugging faster and easier
The IDLE debugger lets you control how your program runs and pauses. Here's what each button
does:
1. Go
● What it does: Runs your program normally until it finishes or reaches a breakpoint (a special
pause point you set in your code).
E
● When to use it: When you're done stepping through the code and want to see the rest of the
program run without interruptions.
C
N
2. Step
JN
● What it does: Runs the next line of code and then pauses.
○ If the next line is a function call, the debugger steps into the function to show you the
L,
first line of its code.
● When to use it: When you want to see every single line of code being executed, including what
IM
happens inside functions.
3. Over
,A
● What it does: Runs the next line of code, but if it’s a function call, it skips over the details inside
M
the function. The function runs, but the debugger pauses after the function finishes.
● When to use it: When you don’t need to see the details inside a function (e.g., you know how
EE
4. Out
AS
● What it does: Runs the program until it finishes the current function and pauses once it's back
to the main code.
W
● When to use it: If you’ve stepped into a function by mistake or are done inspecting it and want to
return to the main program.
YA
5. Quit
LI
● What it does: Stops the debugger and ends the program immediately.
● When to use it: If you don’t want to debug anymore or need to stop the program right away.
AA
● If you click Step, the debugger will pause at each line (even inside add_numbers).
● If you click Over at result = add_numbers(x, y), it will skip the details of add_numbers and pause
after it returns the value.
● If you’re inside the add_numbers function and click Out, the debugger will finish running the
function and return to the main program.
● If you’re done with debugging, click Go to run the rest of the program normally.
● If you need to stop the program, click Quit.
E
C
N
JN
L,
IM
,A
M
EE
AS
The Problem: The code asks for three numbers, but it joins them as text instead of adding them as
W
numbers.
YA
Example output:
5
Enter the second number to add:
AA
3
Enter the third number to add:
42
The sum is 5342
Solution:
Use the debugger to find the issue by running the program step-by-step.
How to Debug:
● Enable Debug Mode in IDLE (click Debug > Debugger, check all boxes).
● Run the program (press F5).
● The program pauses at each line of code, letting you see the value of variables.
E
Fix:
C
Convert inputs to numbers using int():
N
JN
first = int(input('Enter the first number to add: '))
second = int(input('Enter the second number to add: '))
third = int(input('Enter the third number to add: '))
L,
print('The sum is', first + second + third)
IM
,A
M
EE
AS
W
Using "Over"
LI
3. Repeat this for the next inputs (e.g., 3 and 42).
4. By the end, you'll notice the variables are strings ('5', '3', '42'), causing the bug when
concatenating them.
Breakpoints
E
C
N
JN
L,
IM
,A
M
EE
AS
W
YA
LI
AA
E
C
N
JN
L,
IM
,A
M
EE
AS
W
YA
LI
AA
E
C
N
JN
L,
IM
,A
M
EE
AS
W
YA
LI
AA