* **Method iter() is required for `'isinstance(<obj>, abc.Iterable)'` to return True, however any object with getitem() will work with any code expecting an iterable.**
* **Names of their required methods are stored in `'<abc>.__abstractmethods__'`.**
* **MutableSequence, Set, MutableSet, Mapping and MutableMapping ABCs are also extendable. Use `'<abc>.__abstractmethods__'` to get names of required methods.**
Enum
@ -2161,7 +2160,7 @@ with <lock>: # Enters the block by calling acq
<bool> = <Future>.cancel() # Cancels or returns False if running/finished.
<iter> = as_completed(<coll_of_Futures>) # `next(<iter>)` returns next completed Future.
```
* **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 all threads have finished.**
* **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 all threads are done.**
* **Exceptions that happen inside threads are raised when map iterator's next() or Future's result() are called. Future's exception() method returns exception object 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, and executor should only be reachable via `'if __name__ == "__main__": ...'`.**
@ -2245,9 +2244,9 @@ import logging as log
```python
log.basicConfig(filename=<path>, level='DEBUG') # Configures the root logger (see Setup).
log.debug/info/warning/error/critical(<str>) # Logs to the root logger.
<Logger> = log.getLogger(__name__) # Logger named after the module.
<Logger>.<level>(<str>) # Logs to the logger.
log.debug/info/warning/error/critical(<str>) # Sends message to the root logger.
<Logger> = log.getLogger(__name__) # Returns logger named after the module.
<Logger>.<level>(<str>) # Sends message to the logger.
<Logger>.exception(<str>) # Error() that appends caught exception.
```
@ -2321,7 +2320,7 @@ Coroutines
----------
* **Coroutines have a lot in common with threads, but unlike threads, they only give up control when they call another coroutine and they don’t use as much memory.**
* **Coroutine definition starts with `'async'` and its call with `'await'`.**
* **`'asyncio.run(<coroutine>)'` is the main entry point for asynchronous programs.**
* **Use `'asyncio.run(<coroutine>)'` to start the first/main coroutine.**
```python
import asyncio as aio
@ -2329,9 +2328,9 @@ import asyncio as aio
```python
<coro> = <async_function>(<args>) # Creates a coroutine by calling async def function.
<obj> = await <coroutine> # Starts the coroutine and returns result.
<obj> = await <coroutine> # Starts the coroutine and returns its result.
<task> = aio.create_task(<coroutine>) # Schedules the coroutine for execution.
<obj> = await <task> # Returns result. Also <task>.cancel().
<obj> = await <task> # Returns coroutine's result. Also <task>.cancel().
```
```python
@ -2355,7 +2354,7 @@ def main(screen):
async def main_coroutine(screen):
moves = asyncio.Queue()
state = {'*': P(0, 0), **{id_: P(W//2, H//2) for id_ in range(10)}}
state = {'*': P(0, 0)} | {id_: P(W//2, H//2) for id_ in range(10)}
ai = [random_controller(id_, moves) for id_ in range(10)]
* **Starts the app at `'http://localhost:5000'`. Use `'host="0.0.0.0"'` to run externally.**
* **Install a WSGI server like [Waitress](https://flask.palletsprojects.com/en/latest/deploying/waitress/) and a HTTP server such as [Nginx](https://flask.palletsprojects.com/en/latest/deploying/nginx/) for better security.**
<li><strong>Method iter() is required for <codeclass="python hljs"><spanclass="hljs-string">'isinstance(<obj>, abc.Iterable)'</span></code> to return True, however any object with getitem() will work with any code expecting an iterable.</strong></li>
<li><strong>Names of their required methods are stored in <codeclass="python hljs"><spanclass="hljs-string">'<abc>.__abstractmethods__'</span></code>.</strong></li>
<li><strong>MutableSequence, Set, MutableSet, Mapping and MutableMapping ABCs are also extendable. Use <codeclass="python hljs"><spanclass="hljs-string">'<abc>.__abstractmethods__'</span></code> to get names of required methods.</strong></li>
</ul>
<div><h2id="enum"><ahref="#enum"name="enum">#</a>Enum</h2><p><strong>Class of named constants called members.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">from</span> enum <spanclass="hljs-keyword">import</span> Enum, auto
<iter> = as_completed(<coll_of_Futures>) <spanclass="hljs-comment"># `next(<iter>)` returns next completed Future.</span>
</code></pre>
<ul>
<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 all threads have finished.</strong></li>
<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 all threads are done.</strong></li>
<li><strong>Exceptions that happen inside threads are raised when map iterator's next() or Future's result() are called. Future's exception() method returns exception object 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, and executor should only be reachable via <codeclass="python hljs"><spanclass="hljs-string">'if __name__ == "__main__": ...'</span></code>.</strong></li>
<li><strong>Coroutines have a lot in common with threads, but unlike threads, they only give up control when they call another coroutine and they don’t use as much memory.</strong></li>
<li><strong>Coroutine definition starts with <codeclass="python hljs"><spanclass="hljs-string">'async'</span></code> and its call with <codeclass="python hljs"><spanclass="hljs-string">'await'</span></code>.</strong></li>
<li><strong><codeclass="python hljs"><spanclass="hljs-string">'asyncio.run(<coroutine>)'</span></code>is the main entry point for asynchronous programs.</strong></li>
<li><strong>Use <codeclass="python hljs"><spanclass="hljs-string">'asyncio.run(<coroutine>)'</span></code>to start the first/main coroutine.</strong></li>
<pre><codeclass="python language-python hljs"><coro> = <async_function>(<args>) <spanclass="hljs-comment"># Creates a coroutine by calling async def function.</span>
<obj> = <spanclass="hljs-keyword">await</span><coroutine><spanclass="hljs-comment"># Starts the coroutine and returns result.</span>
<obj> = <spanclass="hljs-keyword">await</span><coroutine><spanclass="hljs-comment"># Starts the coroutine and returns its result.</span>
<task> = aio.create_task(<coroutine>) <spanclass="hljs-comment"># Schedules the coroutine for execution.</span>
<obj> = <spanclass="hljs-keyword">await</span><task><spanclass="hljs-comment"># Returns result. Also <task>.cancel().</span>
<obj> = <spanclass="hljs-keyword">await</span><task><spanclass="hljs-comment"># Returns coroutine's result. Also <task>.cancel().</span>
</code></pre>
<pre><codeclass="python language-python hljs"><coro> = aio.gather(<coro/task>, ...) <spanclass="hljs-comment"># Schedules coros. Returns list of results on await.</span>
<div><h2id="web"><ahref="#web"name="web">#</a>Web</h2><p><strong>Flask is a micro web framework/server. If you just want to open a html file in a web browser use <codeclass="python hljs"><spanclass="hljs-string">'webbrowser.open(<path>)'</span></code> instead.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-comment"># $ pip3 install flask</span>
<li><strong>Starts the app at <codeclass="python hljs"><spanclass="hljs-string">'http://localhost:5000'</span></code>. Use <codeclass="python hljs"><spanclass="hljs-string">'host="0.0.0.0"'</span></code> to run externally.</strong></li>
<li><strong>Use <codeclass="python hljs"><spanclass="hljs-string">'render_template(filename, <kwargs>)'</span></code>to render file located in templates dir.</strong></li>
<li><strong>To return an error code use <codeclass="python hljs"><spanclass="hljs-string">'abort(<int>)'</span></code>and to redirect use<codeclass="python hljs"><spanclass="hljs-string">'redirect(<url>)'</span></code>.</strong></li>
<li><strong><codeclass="python hljs"><spanclass="hljs-string">'request.args[<str>]'</span></code> returns parameter from the query string (URL part after '?').</strong></li>
<li><strong><codeclass="python hljs"><spanclass="hljs-string">'fl.render_template(filename, <kwargs>)'</span></code> renders a file located in 'templates' dir.</strong></li>
<li><strong><codeclass="python hljs"><spanclass="hljs-string">'fl.request.args[<str>]'</span></code> returns parameter from the query string (URL right of '?').</strong></li>
<li><strong><codeclass="python hljs"><spanclass="hljs-string">'fl.session[<str>] = <obj>'</span></code> stores session data. It requires secret key to be set at the startup with<codeclass="python hljs"><spanclass="hljs-string">'app.secret_key = <str>'</span></code>.</strong></li>
xxxxxxxxxx