@ -2238,49 +2243,64 @@ ValueError: malformed node or string
```
Coroutine
---------
* **Any function that contains a `'(yield)'` expression returns a coroutine.**
* **Coroutines are similar to iterators, but data needs to be pulled out of an iterator by calling `'next(<iter>)'`, while we push data into the coroutine by calling `'<coroutine>.send(<el>)'`.**
* **Coroutines provide more powerful data routing possibilities than iterators.**
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.**
* **Fucntions wait(), gather() and as_completed() can be used when multiple coroutines need to be started at the same time.**
### Helper Decorator
* **All coroutines must first be "primed" by calling `'next(<coroutine>)'`.**
* **Remembering to call next() is easy to forget.**
* **Solved by wrapping coroutine functions with the following decorator:**
#### Starts a terminal game where you control an asterisk that must avoid numbers:
```python
def coroutine(func):
def out(*args, **kwargs):
cr = func(*args, **kwargs)
next(cr)
return cr
return out
```
import asyncio, collections, curses, enum, random
### Pipeline Example
```python
def reader(target):
for i in range(10):
target.send(i)
target.close()
P = collections.namedtuple('P', 'x y') # Position
D = enum.Enum('D', 'n e s w') # Direction
@coroutine
def adder(target):
def main(screen):
curses.curs_set(0) # Makes cursor invisible.
screen.nodelay(True) # Makes getch() non-blocking.
</ul><div><h4id="integertypesuseacapitalletterforunsignedtypestandardsizesareinbrackets">Integer types. Use a capital letter for unsigned type. Standard sizes are in brackets:</h4><ul>
</ul></div><div><h4id="integertypesuseacapitalletterforunsignedtypestandardsizesareinbrackets">Integer types. Use a capital letter for unsigned type. Standard sizes are in brackets:</h4><ul>
<li><strong><codeclass="python hljs"><spanclass="hljs-string">'x'</span></code> - pad byte</strong></li>
<li><strong>Any function that contains a <codeclass="python hljs"><spanclass="hljs-string">'(yield)'</span></code> expression returns a coroutine.</strong></li>
<li><strong>Coroutines are similar to iterators, but data needs to be pulled out of an iterator by calling <codeclass="python hljs"><spanclass="hljs-string">'next(<iter>)'</span></code>, while we push data into the coroutine by calling <codeclass="python hljs"><spanclass="hljs-string">'<coroutine>.send(<el>)'</span></code>.</strong></li>
<li><strong>Coroutines provide more powerful data routing possibilities than iterators.</strong></li>
<li><strong>All coroutines must first be "primed" by calling <codeclass="python hljs"><spanclass="hljs-string">'next(<coroutine>)'</span></code>.</strong></li>
<li><strong>Remembering to call next() is easy to forget.</strong></li>
<li><strong>Solved by wrapping coroutine functions with the following decorator:</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>Fucntions wait(), gather() and as_completed() can be used when multiple coroutines need to be started at the same time.</strong></li>
</ul><div><h4id="startsaterminalgamewhereyoucontrolanasteriskthatmustavoidnumbers">Starts a terminal game where you control an asterisk that must avoid numbers:</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">import</span> asyncio, collections, curses, enum, random
P = collections.namedtuple(<spanclass="hljs-string">'P'</span>, <spanclass="hljs-string">'x y'</span>) <spanclass="hljs-comment"># Position</span>
D = enum.Enum(<spanclass="hljs-string">'D'</span>, <spanclass="hljs-string">'n e s w'</span>) <spanclass="hljs-comment"># Direction</span>
<div><h2id="curses"><ahref="#curses"name="curses">#</a>Curses</h2><div><h4id="clearstheterminalprintsamessageandwaitsforanesckeypress">Clears the terminal, prints a message and waits for an ESC key press:</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">from</span> curses <spanclass="hljs-keyword">import</span> wrapper, curs_set, ascii
<div><h2id="curses"><ahref="#curses"name="curses">#</a>Curses</h2><div><h4id="clearstheterminalprintsamessageandwaitsfortheesckeypress">Clears the terminal, prints a message and waits for the ESC key press:</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">from</span> curses <spanclass="hljs-keyword">import</span> wrapper, curs_set, ascii
xxxxxxxxxx