**CPython interpreter can only run a single thread at a time. Using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.**
```python
from threading import Thread, RLock, Semaphore, Event, Barrier
from threading import Thread, Lock, RLock, Semaphore, Event, Barrier
from concurrent.futures import ThreadPoolExecutor, as_completed
```
### Thread
```python
<Thread> = Thread(target=<function>) # Use `args=<collection>` to set the arguments.
<Thread>.start() # Starts the thread.
<bool> = <Thread>.is_alive() # Checks if the thread has finished executing.
<Thread>.start() # Starts the thread. Also <Thread>.is_alive().
<Thread>.join() # Waits for the thread to finish.
```
* **Use `'kwargs=<dict>'` to pass keyword arguments to the function.**
@ -2116,7 +2115,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
### Lock
```python
<lock> = RLock() # Lock that can only be released by acquirer.
<lock> = Lock/RLock() # RLock can only be released by acquirer.
<lock>.acquire() # Waits for the lock to be available.
<lock>.release() # Makes the lock available again.
```
@ -2159,7 +2158,7 @@ with <lock>: # Enters the block by calling acq
```
* **Map() and as\_completed() also accept 'timeout'. It causes futures.TimeoutError when next() is called/blocking. Map() times from original call and as_completed() from first call to next(). As\_completed() fails if next() is called too late, even if thread finished on time.**
* **Exceptions that happen inside threads are raised when next() is called on map's iterator or when result() is called on a Future. Its exception() method returns exception or None.**
* **ProcessPoolExecutor provides true parallelism, but everything sent to/from workers must be [pickable](#pickle). Queues must be sent using executor's 'initargs' and 'initializer' parameters.**
* **ProcessPoolExecutor provides true parallelism but: everything sent to/from workers must be [pickable](#pickle), queues must be sent using executor's 'initargs' and 'initializer' parameters, and executor needs to be reachable via `'if __name__ == "__main__": ...'`.**
Operator
@ -2167,20 +2166,20 @@ Operator
**Module of functions that provide the functionality of operators. Functions are ordered by operator precedence, starting with least binding.**
```python
import operator as op
<bool> = op.not_(<obj>) # or, and, not (or/and missing)
<bool> = op.eq/ne/lt/le/gt/ge/is_/contains(<obj>, <obj>) # ==, !=, <, <=, >, >=, is, in
<deque>.rotate(n=<spanclass="hljs-number">1</span>) <spanclass="hljs-comment"># Last element becomes first.</span>
<el> = <deque>.popleft() <spanclass="hljs-comment"># Raises IndexError if deque is empty.</span>
</code></pre>
<div><h2id="threading"><ahref="#threading"name="threading">#</a>Threading</h2><p><strong>CPython interpreter can only run a single thread at a time. Using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">from</span> threading <spanclass="hljs-keyword">import</span> Thread, RLock, Semaphore, Event, Barrier
<div><h2id="threading"><ahref="#threading"name="threading">#</a>Threading</h2><p><strong>CPython interpreter can only run a single thread at a time. Using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">from</span> threading <spanclass="hljs-keyword">import</span> Thread, Lock, RLock, Semaphore, Event, Barrier
<div><h3id="thread">Thread</h3><pre><codeclass="python language-python hljs"><Thread> = Thread(target=<function>) <spanclass="hljs-comment"># Use `args=<collection>` to set the arguments.</span>
<Thread>.start() <spanclass="hljs-comment"># Starts the thread.</span>
<bool> = <Thread>.is_alive() <spanclass="hljs-comment"># Checks if the thread has finished executing.</span>
<Thread>.start() <spanclass="hljs-comment"># Starts the thread. Also <Thread>.is_alive().</span>
<Thread>.join() <spanclass="hljs-comment"># Waits for the thread to finish.</span>
<li><strong>Use <codeclass="python hljs"><spanclass="hljs-string">'kwargs=<dict>'</span></code> to pass keyword arguments to the function.</strong></li>
<li><strong>Use <codeclass="python hljs"><spanclass="hljs-string">'daemon=True'</span></code>, or the program will not be able to exit while the thread is alive.</strong></li>
</ul>
<div><h3id="lock">Lock</h3><pre><codeclass="python language-python hljs"><lock> = RLock()<spanclass="hljs-comment"># Lock that can only be released by acquirer.</span>
<div><h3id="lock">Lock</h3><pre><codeclass="python language-python hljs"><lock> = Lock/RLock() <spanclass="hljs-comment"># RLock can only be released by acquirer.</span>
<lock>.acquire() <spanclass="hljs-comment"># Waits for the lock to be available.</span>
<lock>.release() <spanclass="hljs-comment"># Makes the lock available again.</span>
<li><strong>Map() and as_completed() also accept 'timeout'. It causes futures.TimeoutError when next() is called/blocking. Map() times from original call and as_completed() from first call to next(). As_completed() fails if next() is called too late, even if thread finished on time.</strong></li>
<li><strong>Exceptions that happen inside threads are raised when next() is called on map's iterator or when result() is called on a Future. Its exception() method returns exception or None.</strong></li>
<li><strong>ProcessPoolExecutor provides true parallelism, but everything sent to/from workers must be <ahref="#pickle">pickable</a>. Queues must be sent using executor's 'initargs' and 'initializer' parameters.</strong></li>
<li><strong>ProcessPoolExecutor provides true parallelism but: everything sent to/from workers must be <ahref="#pickle">pickable</a>, queues must be sent using executor's 'initargs' and 'initializer' parameters, and executor needs to be reachable via <codeclass="python hljs"><spanclass="hljs-string">'if __name__ == "__main__": ...'</span></code>.</strong></li>
</ul>
<div><h2id="operator"><ahref="#operator"name="operator">#</a>Operator</h2><p><strong>Module of functions that provide the functionality of operators. Functions are ordered by operator precedence, starting with least binding.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">import</span> operator <spanclass="hljs-keyword">as</span> op
<bool> = op.not_(<obj>) <spanclass="hljs-comment"># or, and, not (or/and missing)</span>
@ -2265,7 +2264,7 @@ right = [[<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</
<pre><codeclass="python language-python hljs"><Image> = Image.new(<spanclass="hljs-string">'<mode>'</span>, (width, height)) <spanclass="hljs-comment"># Creates new image. Also `color=<int/tuple>`.</span>
<Image> = Image.open(<path>) <spanclass="hljs-comment"># Identifies format based on file's contents.</span>
<Image> = <Image>.convert(<spanclass="hljs-string">'<mode>'</span>) <spanclass="hljs-comment"># Converts image to the new mode.</span>
<Image>.save(<path>) <spanclass="hljs-comment"># Selects format based on the path extension.</span>
<Image>.save(<path>) <spanclass="hljs-comment"># Selects format based on extension (png/jpg…).</span>
<Image>.show() <spanclass="hljs-comment"># Opens image in the default preview app.</span>
'<strong>To print the spreadsheet to the console use <a href="#table">Tabulate</a> library.</strong>':'<strong>To print the spreadsheet to the console use Tabulate library (p. 34).</strong>',
'<strong>For XML and binary Excel files (xlsx, xlsm and xlsb) use <a href="#dataframeplotencodedecode">Pandas</a> library.</strong>':'<strong>For XML and binary Excel files (xlsx, xlsm and xlsb) use Pandas library (p. 46).</strong>',
'<strong>Bools will be stored and returned as ints and dates as <a href="#encode">ISO formatted strings</a>.</strong>':'<strong>Bools will be stored and returned as ints and dates as ISO formatted strings (p. 9).</strong>',
'<strong>An object with the same interface called ProcessPoolExecutor provides true parallelism by running a separate interpreter in each process. Arguments/results must be <a href="#pickle">pickable</a>.</strong>':'<strong>An object with the same interface called ProcessPoolExecutor provides true parallelism by running a separate interpreter in each process. Arguments/results must be pickable.</strong>',
'<strong>ProcessPoolExecutor provides true parallelism, but everything sent to/from workers must be <a href="#pickle">pickable</a>. Queues must be sent using executor\'s \'initargs\' and \'initializer\' parameters.</strong>':'<strong>ProcessPoolExecutor provides true parallelism, but everything sent to/from workers must be pickable. Queues must be sent using executor\'s \'initargs\' and \'initializer\' parameters.</strong>',
'<strong>ProcessPoolExecutor provides true parallelism but: everything sent to/from workers must be <a href="#pickle">pickable</a>, queues must be sent using executor\'s \'initargs\' and \'initializer\' parameters, and executor needs to be reachable via <code class="python hljs"><span class="hljs-string">\'if __name__ == "__main__": ...\'</span></code>.</strong>':'<strong>ProcessPoolExecutor provides true parallelism but: everything sent to/from workers must be pickable, queues must be sent using executor\'s \'initargs\' and \'initializer\' parameters, and executor needs to be reachable via <code class="python hljs"><span class="hljs-string">\'if __name__ == "__main__": ...\'</span></code>.</strong>',
'<strong>Asyncio module also provides its own <a href="#queue">Queue</a>, <a href="#semaphoreeventbarrier">Event</a>, <a href="#lock">Lock</a> and <a href="#semaphoreeventbarrier">Semaphore</a> classes.</strong>':'<strong>Asyncio module also provides its own Queue, Event, Lock and Semaphore classes (p. 30).</strong>',
'<strong>Install a WSGI server like <a href="https://flask.palletsprojects.com/en/latest/deploying/waitress/">Waitress</a> and a HTTP server such as <a href="https://flask.palletsprojects.com/en/latest/deploying/nginx/">Nginx</a> for better security.</strong>':'<strong>Install a WSGI server like Waitress and a HTTP server such as Nginx for better security.</strong>',
'<strong>The "latest and greatest" profiler that can also monitor GPU usage is called <a href="https://github.com/plasma-umass/scalene">Scalene</a>.</strong>':'<strong>The "latest and greatest" profiler that can also monitor GPU usage is called Scalene.</strong>',
xxxxxxxxxx