Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
412: Building a File Organizer Script
A few years ago, I was working on a massive data migration project. My "Downloads" folder had become a digital landfill—hundreds of CSVs, PDF specs, random ZIP archives, and a few stray JPGs. During a high-pressure screen-share with a lead architect, I spent a solid minute scrolling through a chaotic list of files, trying to find a specific schema document while the architect watched in silence. The embarrassment was real. I realized that as developers, we spend so much time optimizing our code that we often ignore the mess of the environment we're actually working in. I spent that evening writing a script to handle it for me, and it's a tool I've iterated on for years.
Defining Your Organization Logic
The secret to a clean organizer isn't a complex algorithm; it's a well-structured mapping. You don't want to write a dozen if/elif statements for every possible file extension. Instead, use a dictionary where the keys are your target folder names and the values are lists of extensions that belong there. It makes the script easy to update when you suddenly decide that .svg files should go in "Images" instead of "Documents".
import os
from pathlib import Path
import shutil
# Define where things go
FILE_TYPES = {
"Images": [".jpg", ".jpeg", ".png", ".gif", ".svg"],
"Documents": [".pdf", ".docx", ".txt", ".xlsx"],
"Archives": [".zip", ".tar", ".gz", ".rar"],
"Scripts": [".py", ".js", ".bash", ".sh"]
}
TARGET_DIR = Path.home() / "Downloads"
Moving Files with Pathlib
While you might have used os.listdir() in earlier lessons, I highly recommend pathlib for this. It treats paths as objects rather than strings, which saves you from the headache of manually joining paths or worrying about trailing slashes. We need to iterate through every item in the directory, check if it's actually a file (because we don't want to accidentally move other folders into themselves), and then match its extension against our map.
def organize_folder():
for item in TARGET_DIR.iterdir():
if item.is_dir():
continue # Skip folders to avoid recursive chaos
# Get the extension in lowercase to avoid .JPG vs .jpg issues
extension = item.suffix.lower()
for folder_name, extensions in FILE_TYPES.items():
if extension in extensions:
dest_folder = TARGET_DIR / folder_name
dest_folder.mkdir(exist_ok=True) # Create folder if it doesn't exist
shutil.move(str(item), str(dest_folder / item.name))
print(f"Moved {item.name} to {folder_name}")
break
Guarding Against Overwrites
Here is where most beginner scripts fail: name collisions. If you have two files named invoice.pdf—one from January and one from February—and they both end up in the "Documents" folder, shutil.move will happily overwrite the first one with the second. That's a great way to lose data.
To fix this, you should implement a check to see if the destination file already exists. If it does, you can append a counter to the filename. It's a small addition, but it's the difference between a "toy script" and a tool you actually trust with your files. I usually wrap the move logic in a helper function that handles this renaming loop before calling the actual move command.
📋 Practical Task
Build a Collision-Resistant File Sorter
Your task is to expand the file organizer logic discussed in this lesson. Create a script that organizes a specific test directory on your machine. However, you must implement a "Rename on Collision" feature.
Requirements:
- Use a dictionary to map at least three different categories of files to their extensions.
- Use
pathlibto iterate through the directory. - Crucial: Before moving a file, check if a file with the same name already exists in the destination folder. If it does, rename the file by appending a number to the end (e.g.,
image.pngbecomesimage_1.png, thenimage_2.png, and so on) until a unique filename is found. - Ensure the script creates the destination folders automatically if they don't exist.
There are no comments for now.