Challenge 3: Parallel Sum of Squares — Possible Solution ==================================================================== import multiprocessing def compute_square(n): return n ** 2 if __name__ == "__main__": with multiprocessing.Pool(4) as pool: results = pool.map(compute_square, range(20)) total = sum(results) print(results) print(total) Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361] 2470 WHY THIS WORKS AS AN ANSWER ------------------------------ compute_square(n) reuses this chapter's own multiprocessing example function exactly — a plain, simple function that must be defined at the module level (not nested inside another function) so that each separate process can import and call it correctly. multiprocessing.Pool(4) reuses the chapter's own Pool setup, creating 4 worker processes — each with its own separate memory space and its own GIL, exactly the "sidesteps the GIL entirely" mechanism the chapter explains. pool.map(compute_square, range(20)) distributes the 20 numbers across those 4 processes automatically, computing multiple squares in genuine parallel rather than one at a time on a single core, unlike anything threading (Challenge 1/2) could achieve for this CPU-bound math. if __name__ == "__main__": reuses the chapter's own guard around the Pool code — a required detail on multiprocessing specifically, since each new process re-imports the module, and without this guard, every worker process would try to spawn its own Pool of workers recursively. sum(results) reuses the built-in sum() from Course 1 to total up the 20 squared values pool.map() returned, in their original order (0 through 19, squared) — multiprocessing.Pool.map() preserves input order in its output, unlike some more advanced concurrent patterns that don't guarantee it.