Python course menu
Automate Boring Tasks With Python: Files, Folders, CSV Reports and Backups
Practical Python automation for beginners: organise a messy downloads folder by file type, batch rename files, turn CSV data into a summary report, zip backups, scan log files, and schedule scripts to run automatically.
On this page
One of the best reasons to learn Python is to make the computer do repetitive work for you. Tasks that take an hour of clicking (sorting files, renaming photos, building weekly reports) can become a script that runs in seconds. This lesson builds several small, real automations using only the standard library.
1. Organise a downloads folder by file type#
from pathlib import Path
folder = Path("downloads")
categories = {
"Documents": {".pdf", ".txt", ".csv"},
"Images": {".jpg", ".png"},
"Music": {".mp3"},
}
for file in folder.iterdir():
if not file.is_file():
continue
ext = file.suffix.lower() # ".PDF" -> ".pdf"
target = next((cat for cat, exts in categories.items() if ext in exts), "Other")
(folder / target).mkdir(exist_ok=True)
file.rename(folder / target / file.name)
for sub in sorted(folder.iterdir()):
print(sub.name, sorted(f.name for f in sub.iterdir()))Starting with report.pdf, photo.jpg, notes.txt, song.mp3, scan.PDF, data.csv and logo.png in the folder:
Documents ['data.csv', 'notes.txt', 'report.pdf', 'scan.PDF']
Images ['logo.png', 'photo.jpg']
Music ['song.mp3']Key ideas:
Path.iterdir()lists everything in a folder;is_file()skips sub-folders.file.suffix.lower()normalises extensions so.PDFand.pdfare treated the same.next(..., "Other")finds the first matching category, with a fallback.rename()moves the file.
2. Batch rename files#
Rename camera photos to something meaningful, with numbered, zero-padded names:
from pathlib import Path
folder = Path("photos")
for i, file in enumerate(sorted(folder.glob("*.jpg")), start=1):
new_name = f"goa-trip-{i:02d}{file.suffix}"
print(f"{file.name} -> {new_name}")
file.rename(file.with_name(new_name))
print(sorted(p.name for p in folder.iterdir()))IMG_0001.jpg -> goa-trip-01.jpg
IMG_0002.jpg -> goa-trip-02.jpg
IMG_0003.jpg -> goa-trip-03.jpg
['goa-trip-01.jpg', 'goa-trip-02.jpg', 'goa-trip-03.jpg']{i:02d} pads numbers to two digits so files sort correctly (02 before 10). A safe habit is a dry run: comment out the rename line, check the printed plan, then run it for real.
3. Turn raw CSV data into a summary report#
Given sales.csv:
date,region,amount
2026-10-01,North,1200
2026-10-01,South,800
2026-10-02,North,950
2026-10-02,South,1300
2026-10-03,North,700import csv
from pathlib import Path
totals = {}
with open("sales.csv", newline="", encoding="utf-8") as f:
for row in csv.DictReader(f):
totals[row["region"]] = totals.get(row["region"], 0) + int(row["amount"])
with open("summary.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["region", "total"])
for region, total in sorted(totals.items()):
writer.writerow([region, total])
print(Path("summary.csv").read_text(encoding="utf-8"))region,total
North,2850
South,2100The output CSV opens directly in Excel or Google Sheets. For bigger data work, the pandas library does this in one line, but the standard library is enough for many everyday reports.
4. Zip a dated backup#
import shutil
from datetime import date
archive = shutil.make_archive(f"backup-{date.today()}", "zip", "backup-source")shutil.make_archive zips a whole folder. With today's date of 23 October 2026, it creates backup-2026-10-23.zip. The shutil module also copies (copy2, copytree) and moves (move) files and folders.
5. Scan log files for errors#
from pathlib import Path
counts = {}
for log in sorted(Path("logs").glob("*.log")):
errors = sum(1 for line in log.read_text().splitlines() if line.startswith("ERROR"))
counts[log.name] = errors
print(counts, sum(counts.values())){'app-1.log': 1, 'app-2.log': 2} 3glob("*.log") picks only log files (a readme.txt in the same folder is ignored). Use rglob to search sub-folders too, and regular expressions for more complex patterns.
Running scripts automatically#
Once a script works, let the computer run it on a schedule:
For scripts that wait between checks, time.sleep(seconds) pauses the program.
Ideas for your own automations#
- Rename invoices using the date and client name found inside them.
- Send yourself an email summary of a spreadsheet each morning (
smtplib). - Resize every image in a folder (
Pillowlibrary). - Fill in Excel templates (
openpyxllibrary). - Download data from an API and save a daily CSV.
Common mistakes#
Practice#
Practice exercise
Write a script that lists every .txt file in a folder (including sub-folders) together with its size in bytes, largest first.
Show hint
Path(folder).rglob("*.txt") finds the files; f.stat().st_size gives the size. Collect (size, name) pairs and sort them in reverse.
Show solution
from pathlib import Path
def txt_sizes(folder):
files = [(f.stat().st_size, str(f)) for f in Path(folder).rglob("*.txt")]
for size, name in sorted(files, reverse=True):
print(f"{size:>8} bytes {name}")
txt_sizes(".")The output depends on your files, for example:
1500 bytes notes/big.txt
42 bytes todo.txt{size:>8} right-aligns the numbers so the column is easy to read.
Key takeaway#
Finished this lesson?