Skip to main content

Add a couple of examples

ID
b16ac16
date
2021-10-25 07:28:58+00:00
author
Alex Chan <alex@alexwlchan.net>
parent
0e4bef3
message
Add a couple of examples
changed files
5 files, 73 additions, 5 deletions

Changed files

README.md (1327) → README.md (1387)

diff --git a/README.md b/README.md
index 656bf77..224c1a8 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ It allows me to write code like:
 ```python
 from concurrently import concurrently
 
-for (input, output) in concurrently(fn=perform, fn_inputs=get_tasks_to_do()):
+for (input, output) in concurrently(fn=perform, inputs=get_tasks_to_do()):
     print(input, output)
 ```
 
@@ -37,6 +37,8 @@ I would recommend using this code instead of the code in the original blog post.
 
 Copy and paste the file `concurrently.py` into your project.
 
+You can see examples in the [`examples` directory](examples).
+
 
 
 ## License

concurrently.py (1161) → concurrently.py (1155)

diff --git a/concurrently.py b/concurrently.py
index dea62fb..540b6b9 100644
--- a/concurrently.py
+++ b/concurrently.py
@@ -2,7 +2,7 @@ import concurrent.futures
 import itertools
 
 
-def concurrently(fn, fn_inputs, *, max_concurrency=5):
+def concurrently(fn, inputs, *, max_concurrency=5):
     """
     Calls the function ``fn`` on the values ``inputs``.
 
@@ -14,7 +14,7 @@ def concurrently(fn, fn_inputs, *, max_concurrency=5):
     """
     # Make sure we get a consistent iterator throughout, rather than
     # getting the first element repeatedly.
-    fn_inputs = iter(fn_inputs)
+    fn_inputs = iter(inputs)
 
     with concurrent.futures.ThreadPoolExecutor() as executor:
         futures = {

examples/downloading.py (0) → examples/downloading.py (835)

diff --git a/examples/downloading.py b/examples/downloading.py
new file mode 100755
index 0000000..ba9f94b
--- /dev/null
+++ b/examples/downloading.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+"""
+This example downloads a collection of images from https://http.cat/
+
+Rather than downloading the images one-by-one, it runs multiple instances
+of the download() function to complete the process faster.
+"""
+
+import tempfile
+import urllib.request
+
+from concurrently import concurrently
+
+
+def save_http_cat(status_code):
+    """
+    Saves the JPEG from https://http.cat/ associated with this status code.
+
+    Returns the path to the downloaded file.
+    """
+    _, path = tempfile.mkstemp(suffix=f"_{status_code}.jpg")
+    urllib.request.urlretrieve(f"https://http.cat/{status_code}", path)
+    return path
+
+
+if __name__ == '__main__':
+    codes = [200, 201, 202, 301, 302, 400, 405, 410, 418, 420, 451, 500]
+
+    for (input, output) in concurrently(save_http_cat, inputs=codes):
+        print(input, output)
+

examples/sleepy_multiply.py (0) → examples/sleepy_multiply.py (714)

diff --git a/examples/sleepy_multiply.py b/examples/sleepy_multiply.py
new file mode 100755
index 0000000..b880dc0
--- /dev/null
+++ b/examples/sleepy_multiply.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+"""
+This example does a "sleepy multiply".
+
+It multiples two numbers together, but with a delay before returning.
+This mimics a computation that has to be fetched from a remote server.
+
+This example also shows how to handle functions that take multiple inputs.
+"""
+
+import time
+
+from concurrently import concurrently
+
+
+def sleepy_multiply(x, y):
+    time.sleep(x / 10)
+    return x * y
+
+
+if __name__ == '__main__':
+    inputs = [
+        (1, 2),
+        (2, 3),
+        (7, 4),
+        (3, 1),
+        (5, 2),
+        (4, 9),
+        (7, 2),
+        (6, 1),
+    ]
+
+    for ((x, y), output) in concurrently(lambda x: sleepy_multiply(*x), inputs=inputs):
+        print(x, '*', y, '=', output)
+

test_concurrently.py (610) → test_concurrently.py (604)

diff --git a/test_concurrently.py b/test_concurrently.py
index e89ce83..391a2a3 100644
--- a/test_concurrently.py
+++ b/test_concurrently.py
@@ -10,7 +10,7 @@ def double(x):
 
 
 def test_handles_iterator():
-    result = set(concurrently(double, fn_inputs=range(10)))
+    result = set(concurrently(double, inputs=range(10)))
 
     assert result == {
         (0, 0),
@@ -27,6 +27,6 @@ def test_handles_iterator():
 
 
 def test_handles_list():
-    result = set(concurrently(double, fn_inputs=[1, 3, 5, 7, 9, 11, 13]))
+    result = set(concurrently(double, inputs=[1, 3, 5, 7, 9, 11, 13]))
 
     assert result == {(1, 2), (3, 6), (5, 10), (7, 14), (9, 18), (11, 22), (13, 26)}