A common pattern is "run this function over all these inputs and give me the results in order." Add a map convenience that submits one job per item, runs them, and returns the results as a list, in the same order as the inputs.
map(fn, iterable): submit fn(item) for each item, run the pool, return [future.result() for ...] in input orderBecause you collect the futures in order, the results line up with the inputs even though the pool ran them as a batch.
from collections import deque
class Future:
def __init__(self):
self._done = False
self._result = None
self._exc = None
def set_result(self, value):
self._result = value
self._done = True
def set_exception(self, exc):
self._exc = exc
self._done = True
def done(self):
return self._done
def result(self):
if not self._done:
raise RuntimeError("future is not done")
if self._exc is not None:
raise self._exc
return self._result
class ThreadPool:
def __init__(self, num_workers):
self.num_workers = num_workers
self._queue = deque()
def submit(self, fn, *args, **kwargs):
fut = Future()
self._queue.append((fut, fn, args, kwargs))
return fut
def run(self):
while self._queue:
fut, fn, args, kwargs = self._queue.popleft()
try:
fut.set_result(fn(*args, **kwargs))
except Exception as e:
fut.set_exception(e)
def map(self, fn, iterable):
"""Submit fn over each item, run, and return results in input order."""
# TODO: submit fn against each item in turn, holding on to the futures in
# the order you created them, then drain the pool once and read every
# future's result into a list that lines up with the inputs. A job that
# blew up surfaces its exception at the moment its result is read.
pass
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
A common pattern is "run this function over all these inputs and give me the results in order." Add a map convenience that submits one job per item, runs them, and returns the results as a list, in the same order as the inputs.
map(fn, iterable): submit fn(item) for each item, run the pool, return [future.result() for ...] in input orderBecause you collect the futures in order, the results line up with the inputs even though the pool ran them as a batch.
Press Run Tests or ββ© to check your solution.