Automating files

Part of the free LogicWiz Python course, Pack B: College Semester Pack. The examples and practice run in the app.

Meher's Downloads folder has 300 files: lecture PDFs, WhatsApp photos, marks(3).csv. Sorting them by hand takes an evening. A 10-line Python script does it in a second, and it's a lab program too.

You'll learn to

  • List, inspect and build paths with `os` and `os.path`
  • Copy, move and rename with `shutil` and `os`, and make folders
  • Walk a whole folder tree with `os.walk`, and zip files with `zipfile`

Learn

Your toolbox

Task Function
list a folder os.listdir(folder) (names only, any order)
build a path os.path.join("sem1", "notes.pdf")
split a name os.path.splitext("notes.pdf") → ('notes', '.pdf')
file or folder? os.path.isfile(p), os.path.isdir(p), os.path.exists(p)
size in bytes os.path.getsize(p)
make folders os.makedirs(p, exist_ok=True)
copy / move shutil.copy(src, dst), shutil.move(src, dst)
rename os.rename(old, new)
every file below os.walk(top)

Here the files live in the browser's own pretend disk, so nothing on your phone is touched.

Look inside a folder

import os

folder = "downloads"
for name in sorted(os.listdir(folder)):
    path = os.path.join(folder, name)
    base, ext = os.path.splitext(name)
    print(f"{name:<18} ext={ext or '(none)':<7} {os.path.getsize(path)} bytes")

os.listdir gives just the names, in no promised order, so we sort them and join the folder back on before using a name as a path.

Sort files into folders by type

import os
import shutil

folder = "downloads"
for name in os.listdir(folder):
    path = os.path.join(folder, name)
    if not os.path.isfile(path):
        continue
    ext = os.path.splitext(name)[1].lower().lstrip(".") or "others"
    target = os.path.join(folder, ext)
    os.makedirs(target, exist_ok=True)
    shutil.move(path, os.path.join(target, name))

for sub in sorted(os.listdir(folder)):
    print(sub + "/", sorted(os.listdir(os.path.join(folder, sub))))

.lower() puts timetable.PDF with the other PDFs. exist_ok=True means "fine if the folder is already there". Copy instead of move with shutil.copy.

os.walk: every folder, every file

import os

for folder, subfolders, files in os.walk("college"):
    subfolders.sort()                       # walk in a fixed order
    depth = folder.count(os.sep)
    print("  " * depth + os.path.basename(folder) + "/")
    for f in sorted(files):
        print("  " * (depth + 1) + f)

For each folder under the top, os.walk gives a triple: the folder's path, the names of its subfolders, and the names of its files. Sorting subfolders in place also fixes the order it walks them.

Zip a backup

import os
import zipfile

with zipfile.ZipFile("lab_backup.zip", "w") as z:
    for folder, _, files in os.walk("labs"):
        for f in files:
            if f.endswith(".py"):
                path = os.path.join(folder, f)
                z.write(path, arcname=os.path.relpath(path, "labs"))

with zipfile.ZipFile("lab_backup.zip") as z:
    print(sorted(z.namelist()))
    print(z.read("week1/hello.py").decode())

arcname is the name inside the zip; relpath keeps it short (week1/hello.py, not labs/week1/hello.py). Open with "r" (the default) to read, "w" to create, "a" to add.

Deleting is forever. os.remove(file) and shutil.rmtree(folder) skip the Recycle Bin. When you write a cleanup script, first run it with the delete line replaced by a print("would delete", path) (a dry run), check the list, then switch it on. And never assume os.listdir order: always sorted(...).

Lab mapping. VTU's Python course is built on Automate the Boring Stuff, and its "organising files" unit is exactly this lesson: shutil copy/move/rename, os.walk, and zipfile. File-handling programs (list a folder, count files by type, copy or back up files) also appear in AKTU, JNTU, Anna, DU and Mumbai labs.

Viva: "Difference between os.listdir and os.walk?" (one folder vs the whole tree) "Why os.path.join instead of + "/"?" (it uses the right separator on every OS) "shutil.copy vs shutil.move?"

In one line

os.listdir gives names (join them back with os.path.join); os.walk visits the whole tree; shutil.copy/move and os.makedirs(exist_ok=True) organise; zipfile backs up; deleting is permanent.