Course 3.2Lesson 5 of 5
In this project we walk through folders inside folders. A folder is a dictionary, and a file is a number that is its size, so a folder can hold folders to any depth. A loop cannot easily handle a depth that is not known, but a recursive function can: for each item, if it is a folder, ask the same question inside it, and if it is a file, use its size. We write functions for the total size, the number of files, a printed tree with indents, and a search that gives the path of a file. We plan the expected answers by hand, test the empty folder and a folder with only folders, and extend the project with the biggest file and the depth.
Try the code and the simulations beside the lesson.
After this lesson you can
isinstance to tell a folder from a file, andOn your computer, a folder can hold files and other folders, and those hold more files and folders, to any depth. You want to know the total size of a folder, how many files it holds, to show it as a tree, and to find a file by name. How deep the folders go is not known in advance. A loop alone cannot handle that. Recursion can.
A folder is a dictionary. Each key is a name. The value is either a number (a file, and the number is its size) or a dictionary (a folder inside).
For example:
tree
docs/ a.txt (10) b.txt (20)
pics/ x.png (300) old/ -> y.png (50)
readme.txt (5)Work out the answers by hand.
y.png: pics/old/y.png.total_size(folder). The structure of a recursive function over a folder:
total_size(item). This is the recursive call. We trust it to give the size of that folder.Where is the base case? It is hidden. A folder with no folders inside never makes a recursive call: the loop only meets files, and the function returns. So the calls stop by themselves when the folders run out. (An empty folder is the simplest case: the loop does not run, and the total is 0.)
isinstance(item, dict) asks whether item is a dictionary. It is a yes or no question about the type, and it is the way to tell a folder from a file here.
count_files(folder). The same shape. A file counts 1, a folder counts the files inside it.
show(folder, depth). It prints each name with two spaces of indent for each level. A folder prints its name with /, and then calls show on its content with depth + 1. The parameter depth is the extra information that grows as the calls go down. sorted(folder) puts the names in order.
find(folder, target, path). It builds the path as it goes down. Each call adds the name of the folder to path. When it finds the file, it returns the whole path. The important point is that a recursive call may find nothing (None), and then the loop must go on to the next item. Only an answer that is not None is returned at once.
| Test | Expected |
|---|---|
an empty folder {} | size 0, 0 files |
| a folder with only a file | the size of the file, 1 file |
| a folder with only empty folders | size 0, 0 files |
| a folder five levels deep | the size of the one file at the bottom |
| a file name that appears twice | find gives the first one that it meets |
| a name that is not there | None |
The third row is the true test of the base case: folders inside folders with nothing in them. The functions must return 0, and not stop with an error.
The function never needs to know how deep the tree goes. Each call handles one folder and trusts the calls inside it.
Pick one or two, and do them without looking at a solution. Write the expected answers first.
total_size(item) on its own line does nothing. You must add the result to the total.== to compare with a type. Use isinstance.find. If the first folder does not hold the file, you must go on to the next. Return only when the answer is not None.depth.Start with two quick questions. Each New numbers gives you a fresh one, so you can practise as long as you like.
Then the labs and the problems:
isinstance(item, dict) tells a folder from a file.Try each one on your own first. If you are stuck, open a hint. Then check with Show the answer.
total_size({}) give?find not return when a recursive call gives None?Every lesson is open to read. Enrolling also lets you:
Log in to join the discussion.
Loading…
This lesson is free to read. Enroll free to keep your place and take the tests.