Skip to content

Commit 86cd566

Browse files
authored
Merge branch 'master' into advent-of-code
2 parents 48490ca + 543f3cc commit 86cd566

File tree

20 files changed

+605
-7
lines changed

20 files changed

+605
-7
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ __pycache__/
88

99
# C extensions
1010
*.so
11+
*.o
1112

1213
# Distribution / packaging
1314
.Python

python-bindings/tasks.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def build_cmult(c, path=None):
5757
c.run(path)
5858
else:
5959
print_banner("Building C Library")
60-
cmd = "gcc -c -Wall -Werror -fpic cmult.c -I /usr/include/python3.7"
60+
cmd = "gcc -c -Wall -Werror -fpic cmult.c"
6161
invoke.run(cmd)
6262
invoke.run("gcc -shared -o libcmult.so cmult.o")
6363
print("* Complete")
@@ -85,7 +85,7 @@ def test_ctypes_cpp(c):
8585
invoke.run("python3 ctypes_cpp_test.py", pty=True)
8686

8787

88-
@invoke.task()
88+
@invoke.task(build_cmult)
8989
def build_cffi(c):
9090
"""Build the CFFI Python bindings"""
9191
print_banner("Building CFFI Module")
@@ -118,7 +118,7 @@ def build_cffi(c):
118118
print("* Complete")
119119

120120

121-
@invoke.task()
121+
@invoke.task(build_cffi)
122122
def test_cffi(c):
123123
"""Run the script to test CFFI"""
124124
print_banner("Testing CFFI Module")
@@ -140,9 +140,9 @@ def compile_python_module(cpp_name, extension_name):
140140
invoke.run(
141141
"g++ -O3 -Wall -Werror -shared -std=c++11 -fPIC "
142142
"`python3 -m pybind11 --includes` "
143-
"-I /usr/include/python3.7 -I . "
143+
"-I . "
144144
"{0} "
145-
"-o {1}`python3.7-config --extension-suffix` "
145+
"-o {1}`python3-config --extension-suffix` "
146146
"-L. -lcppmult -Wl,-rpath,.".format(cpp_name, extension_name)
147147
)
148148

@@ -155,7 +155,7 @@ def build_pybind11(c):
155155
print("* Complete")
156156

157157

158-
@invoke.task()
158+
@invoke.task(build_pybind11)
159159
def test_pybind11(c):
160160
"""Run the script to test PyBind11"""
161161
print_banner("Testing PyBind11 Module")
@@ -174,7 +174,7 @@ def build_cython(c):
174174
print("* Complete")
175175

176176

177-
@invoke.task()
177+
@invoke.task(build_cython)
178178
def test_cython(c):
179179
"""Run the script to test Cython"""
180180
print_banner("Testing Cython Module")

python-get-all-files-in-directory/Desktop/Notes/hash-tables.md

Whitespace-only changes.

python-get-all-files-in-directory/Desktop/realpython/iterate-dict.md

Whitespace-only changes.

python-get-all-files-in-directory/Desktop/realpython/tictactoe.md

Whitespace-only changes.

python-get-all-files-in-directory/Desktop/scripts/rename_files.py

Whitespace-only changes.

python-get-all-files-in-directory/Desktop/scripts/request.py

Whitespace-only changes.

python-get-all-files-in-directory/Desktop/todo.txt

Whitespace-only changes.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# How to Get a List of All Files in a Directory With Python
2+
3+
The code samples and supporting materials for the [corresponding tutorial](https://realpython.com/get-all-files-in-directory-python/) on Real Python.
4+
5+
You'll find a directory to test your listing operations on, `Desktop`, which contains a few files, and a few subdirectories with a few files.
6+
7+
You'll also find a script called [`create_large_dir.py`](create_large_dir.py) which will create the `large_dir/` example shown in the tutorial. You can try tweaking the numbers there to bulk up the number of files or create custom directory trees.
8+
9+
You can use these directories to try out the different methods of listing.
10+
11+
The examples covered in the tutorial are in `examples.py`, with the recursive `.iterdir()` function in `skip_dirs.py`.
12+
13+
## Bonus Materials
14+
15+
You'll also find a `bonus` folder. Here you'll find scripts that time a whole range of methods from the `pathlib` and `os` modules when it comes to producing a list of files.
16+
17+
The main testing files are `testing_flat_dir.py` and `testing_nested_dir.py`/. You can tweak the constants at the beginning of these files to change the number of files and/or folders being tested. Along with the number of times the operations are tested. Be warned, though, that bumping up the numbers can cause the tests to take a long time.
18+
19+
These scripts use the `make_files.py` module to generate large flat and nested directories just for the test.
20+
21+
Testing all the methods to produce a basic list of files isn't a very fair test, because some methods are optimized to be faster for flat listing, whereas others perform better at recursive listing. That said, the results are interesting nonetheless. Try navigating to the bonus folder and running the following commands:
22+
23+
```
24+
$ python testing_flat_dir.py; python testing_nested_dir.py
25+
Done!
26+
27+
RESULTS FLAT DIRECTORY:
28+
29+
os listdir : 0.265 seconds
30+
os scandir : 0.338 seconds
31+
os walk : 0.430 seconds
32+
iterdir : 0.557 seconds
33+
glob * : 1.365 seconds
34+
rglob : 3.473 seconds
35+
glob **/* : 3.595 seconds
36+
37+
Done!
38+
39+
RESULTS NESTED DIRECTORY:
40+
41+
os scandir_gen : 1.116 seconds
42+
os scandir : 1.118 seconds
43+
os walk : 2.278 seconds
44+
rglob : 3.027 seconds
45+
glob : 3.494 seconds
46+
os listdir : 3.742 seconds
47+
os listdir_gen : 3.775 seconds
48+
iterdir : 4.823 seconds
49+
iterdir_gen : 4.865 seconds
50+
```
51+
52+
While the exact times will depend on your system, the relative speeds should be similar.
53+
54+
If you're running Python 3.12, you can uncomment some lines in `testing_flat_dir.py` and `testing_nested_dir.py` that'll enable testing for the new `walk()` method in the `pathlib` module.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import pathlib
2+
3+
4+
def recursive_iterdir(path: pathlib.Path):
5+
items = []
6+
for item in path.iterdir():
7+
items.append(item)
8+
if item.is_dir():
9+
items.extend(recursive_iterdir(item))
10+
11+
return items
12+
13+
14+
def recursive_iterdir_gen(path: pathlib.Path):
15+
for item in path.iterdir():
16+
yield item
17+
if item.is_dir():
18+
yield from recursive_iterdir_gen(item)
19+
20+
21+
if __name__ == "__main__":
22+
from pprint import pp
23+
24+
docs = pathlib.Path("Desktop")
25+
26+
print(list(docs.iterdir()))
27+
pp(list(recursive_iterdir(docs)))

0 commit comments

Comments
 (0)