Writing Python Scripts to Automate Repetitive Developer Tasks
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:
- Repetitive: You do it at least weekly
- Multi-step: Easy to make mistakes manually
- Predictable: Same steps every time
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:
- cleanup.py: Delete node_modules, __pycache__, .DS_Store from project folders
- scaffold.py: Generate boilerplate for new features (creates files, adds imports)
- backup.py: Compress and upload specific folders to cloud storage
- rename.py: Batch rename files with regex patterns
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.