Every Friday I used to spend 20 minutes renaming screenshots, organizing downloads, and cleaning up temp files. It wasn't hard work, just tedious. Then I realized: I'm a programmer. Why am I doing this manually?

That weekend I wrote a 50-line Python script. Now my cleanup happens in 2 seconds while I get coffee. Cumulative time saved over two years? Probably 30+ hours.

What's Worth Automating?

Not everything should be automated. Good candidates have three qualities:

Examples: cleaning build artifacts, generating boilerplate code, converting file formats, syncing folders, batch renaming files.

pathlib: Modern File Handling

Forget os.path and string concatenation. pathlib treats paths as objects and handles Windows/Mac/Linux differences automatically.

from pathlib import Path
from datetime import datetime
import shutil

def organize_downloads():
    downloads = Path.home() / "Downloads"
    archive = downloads / "Archive"
    archive.mkdir(exist_ok=True)
    
    for file in downloads.iterdir():
        if file.is_file() and file.suffix == ".pdf":
            # Add date to filename
            date = datetime.now().strftime("%Y-%m-%d")
            new_name = f"{file.stem}_{date}{file.suffix}"
            
            destination = archive / new_name
            print(f"Moving {file.name} → {destination.name}")
            shutil.move(file, destination)

if __name__ == "__main__":
    organize_downloads()

The / operator joins paths. file.stem gives filename without extension. file.suffix gives the extension. Clean and readable.

Running Shell Commands

Sometimes you need to call git, docker, or other command-line tools. subprocess is your friend.

import subprocess
import sys

def git_backup(message):
    try:
        subprocess.run(["git", "add", "."], check=True)
        subprocess.run(["git", "commit", "-m", message], check=True)
        subprocess.run(["git", "push"], check=True)
        print("Backup complete!")
    except subprocess.CalledProcessError as e:
        print(f"Git command failed: {e}")
        sys.exit(1)

if __name__ == "__main__":
    git_backup("Daily backup")

check=True is important—it raises an exception if the command fails. Without it, your script continues even when something went wrong.

Making It Configurable

Hardcoded paths break when you share scripts with teammates. Use argparse to accept arguments:

import argparse
from pathlib import Path

def main():
    parser = argparse.ArgumentParser(description="Organize files by type")
    parser.add_argument("folder", type=Path, help="Folder to organize")
    parser.add_argument("--dry-run", action="store_true", 
                        help="Show what would happen without doing it")
    
    args = parser.parse_args()
    
    for file in args.folder.iterdir():
        if file.is_file():
            dest = args.folder / file.suffix.lstrip('.') / file.name
            if args.dry_run:
                print(f"Would move: {file} → {dest}")
            else:
                dest.parent.mkdir(exist_ok=True)
                file.rename(dest)
                print(f"Moved: {file.name}")

if __name__ == "__main__":
    main()

Now you can run python organize.py ~/Downloads --dry-run to preview changes before committing.

Handling Errors Gracefully

Scripts run unattended. When something fails at 3am, you need to know what happened.

import logging
import sys

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

def main():
    try:
        do_the_work()
    except KeyboardInterrupt:
        print("\nCancelled by user")
        sys.exit(0)
    except Exception as e:
        logging.exception("Script failed")
        sys.exit(1)

if __name__ == "__main__":
    main()

logging.exception() captures the full stack trace. Much better than a cryptic error message.

My Actual Automation Scripts

Some scripts I use regularly:

None of them are over 100 lines. Simple scripts that save real time.

Start Small

Next time you catch yourself doing something tedious for the third time, stop. Open a new Python file. Write a script. It doesn't have to be perfect—it just has to work.

The best automation scripts are the ones you actually use. Start with your biggest annoyance and go from there.

← Back to Python Articles

Back to Home