Python Project
Automated File Organizer
A file organizer is a deceptively good beginner project because it moves real files, which means a bug destroys data. Building it forces you to learn dry-run modes, collision handling and reversibility — habits that matter far more than the sorting logic itself.
The brief
Take a cluttered folder and sort its contents into subfolders by rule. It must default to a dry run, never overwrite a file silently, and record what it did so the operation can be reversed.
What it demonstrates
That you think about destructive operations before running them — the instinct that separates a safe engineer from a fast one.
What "done" looks like
Build all of these and the project is finished. Anything past that is in the stretch goals.
- Sort files into subfolders by extension, and optionally by date
- A dry-run mode that is the default
- Collision handling that never overwrites silently
- A log of every move, and a command to undo it
- Configurable rules rather than hardcoded categories
- Tests that run against a temporary directory
How to build it
- 1
Walk the directory safely
Use pathlib. Decide up front whether you recurse, and never follow symlinks out of the target folder.
- 2
Build the rule engine
Map extensions to destinations in a config file, so adding a category needs no code change.
- 3
Implement dry run first
Print every planned move before you write the code that performs one. This ordering is the whole safety argument.
- 4
Handle collisions
Append a suffix, skip, or prompt — pick one, make it explicit, and never let a file vanish under another.
- 5
Write the undo log
Record source and destination for every move as you go, so a reversal is a replay rather than a reconstruction.
- 6
Test against a temp directory
Generate a fake messy folder in a fixture, run the organizer, assert the layout. Never test against your real files.
Once it works
Only after the definition of done is met. Half-finished ambition reads worse than a small finished thing.
- Watch the folder and organise continuously
- Add content-based rules — read the file type rather than trusting the extension
- Deduplicate identical files by hash before moving them
Frequently Asked Questions
Why does this need a dry-run mode?
Because it moves files, and the first version of any such script has a bug. A dry run that prints what would happen costs an hour to build and prevents the one mistake that would put you off the project entirely. Every real tool that touches a filesystem works this way.
What should happen on a name collision?
Never overwrite. Rename with a suffix, skip with a warning, or ask — whichever you choose, make it explicit and configurable. Silent overwriting is the bug that turns a helpful script into a data-loss incident.
How do I make it undoable?
Write a log of every move as source-to-destination pairs, then add a command that replays it backwards. That is a small amount of work and it is the feature that makes the tool genuinely trustworthy.