Browse Source

Arguments, Exceptions, Profiling

pull/135/head
Jure Šorn 2 years ago
parent
commit
c15942fc77
3 changed files with 173 additions and 27 deletions
  1. 19
      README.md
  2. 33
      index.html
  3. 148
      parse.js

19
README.md

@ -668,9 +668,9 @@ Arguments
--------- ---------
### Inside Function Call ### Inside Function Call
```python ```python
func(<positional_args>) # func(1, 2)
func(<keyword_args>) # func(x=1, y=2)
func(<positional_args>, <keyword_args>) # func(1, y=2)
func(<positional_args>) # func(0, 0)
func(<keyword_args>) # func(x=0, y=0)
func(<positional_args>, <keyword_args>) # func(0, y=0)
``` ```
### Inside Function Definition ### Inside Function Definition
@ -744,7 +744,7 @@ def f(*args, y, **kwargs): ... # f(x=1, y=2, z=3) | f(1, y=2, z=3)
``` ```
```python ```python
head, *body, tail = <coll.> # Also `head, *body = <coll.>` and `*body, tail = <coll.>`.
head, *body, tail = <coll.> # Head or tail can be omitted.
``` ```
@ -1398,10 +1398,10 @@ finally:
### Catching Exceptions ### Catching Exceptions
```python ```python
except <exception>:
except <exception> as <name>:
except (<exception>, [...]):
except (<exception>, [...]) as <name>:
except <exception>: ...
except <exception> as <name>: ...
except (<exception>, [...]): ...
except (<exception>, [...]) as <name>: ...
``` ```
* **Also catches subclasses of the exception.** * **Also catches subclasses of the exception.**
* **Use `'traceback.print_exc()'` to print the error message to stderr.** * **Use `'traceback.print_exc()'` to print the error message to stderr.**
@ -2615,8 +2615,7 @@ Line # Mem usage Increment Line Contents
### Call Graph ### Call Graph
#### Generates a PNG image of the call graph with highlighted bottlenecks: #### Generates a PNG image of the call graph with highlighted bottlenecks:
```python ```python
# $ pip3 install pycallgraph2
# $ apt install graphviz
# $ pip3 install pycallgraph2; brew/apt install graphviz
import pycallgraph2 as cg, datetime import pycallgraph2 as cg, datetime
filename = f'profile-{datetime.datetime.now():%Y%m%d%H%M%S}.png' filename = f'profile-{datetime.datetime.now():%Y%m%d%H%M%S}.png'
drawer = cg.output.GraphvizOutput(output_file=filename) drawer = cg.output.GraphvizOutput(output_file=filename)

33
index.html

@ -54,7 +54,7 @@
<body> <body>
<header> <header>
<aside>June 20, 2022</aside>
<aside>June 21, 2022</aside>
<a href="https://gto76.github.io" rel="author">Jure Šorn</a> <a href="https://gto76.github.io" rel="author">Jure Šorn</a>
</header> </header>
@ -589,9 +589,9 @@ to_exclusive = &lt;range&gt;.stop
&lt;float&gt; = &lt;TD&gt; / &lt;TD&gt; <span class="hljs-comment"># How many weeks/years there are in TD. Also //.</span> &lt;float&gt; = &lt;TD&gt; / &lt;TD&gt; <span class="hljs-comment"># How many weeks/years there are in TD. Also //.</span>
</code></pre></div> </code></pre></div>
<div><h2 id="arguments"><a href="#arguments" name="arguments">#</a>Arguments</h2><div><h3 id="insidefunctioncall">Inside Function Call</h3><pre><code class="python language-python hljs">func(&lt;positional_args&gt;) <span class="hljs-comment"># func(1, 2)</span>
func(&lt;keyword_args&gt;) <span class="hljs-comment"># func(x=1, y=2)</span>
func(&lt;positional_args&gt;, &lt;keyword_args&gt;) <span class="hljs-comment"># func(1, y=2)</span>
<div><h2 id="arguments"><a href="#arguments" name="arguments">#</a>Arguments</h2><div><h3 id="insidefunctioncall">Inside Function Call</h3><pre><code class="python language-python hljs">func(&lt;positional_args&gt;) <span class="hljs-comment"># func(0, 0)</span>
func(&lt;keyword_args&gt;) <span class="hljs-comment"># func(x=0, y=0)</span>
func(&lt;positional_args&gt;, &lt;keyword_args&gt;) <span class="hljs-comment"># func(0, y=0)</span>
</code></pre></div></div> </code></pre></div></div>
@ -645,7 +645,7 @@ func(*args, **kwargs)
&lt;dict&gt; = {**&lt;dict&gt; [, ...]} <span class="hljs-comment"># Or: dict(**&lt;dict&gt; [, ...])</span> &lt;dict&gt; = {**&lt;dict&gt; [, ...]} <span class="hljs-comment"># Or: dict(**&lt;dict&gt; [, ...])</span>
</code></pre></div> </code></pre></div>
<pre><code class="python language-python hljs">head, *body, tail = &lt;coll.&gt; <span class="hljs-comment"># Also `head, *body = &lt;coll.&gt;` and `*body, tail = &lt;coll.&gt;`.</span>
<pre><code class="python language-python hljs">head, *body, tail = &lt;coll.&gt; <span class="hljs-comment"># Head or tail can be omitted.</span>
</code></pre> </code></pre>
<div><h2 id="inline"><a href="#inline" name="inline">#</a>Inline</h2><div><h3 id="lambda">Lambda</h3><pre><code class="python language-python hljs">&lt;func&gt; = <span class="hljs-keyword">lambda</span>: &lt;return_value&gt; <span class="hljs-comment"># A single statement function.</span> <div><h2 id="inline"><a href="#inline" name="inline">#</a>Inline</h2><div><h3 id="lambda">Lambda</h3><pre><code class="python language-python hljs">&lt;func&gt; = <span class="hljs-keyword">lambda</span>: &lt;return_value&gt; <span class="hljs-comment"># A single statement function.</span>
&lt;func&gt; = <span class="hljs-keyword">lambda</span> &lt;arg_1&gt;, &lt;arg_2&gt;: &lt;return_value&gt; <span class="hljs-comment"># Also accepts default arguments.</span> &lt;func&gt; = <span class="hljs-keyword">lambda</span> &lt;arg_1&gt;, &lt;arg_2&gt;: &lt;return_value&gt; <span class="hljs-comment"># Also accepts default arguments.</span>
@ -790,7 +790,7 @@ creature = Creature(point, direction)
</ul> </ul>
<div><h3 id="parametrizeddecorator">Parametrized Decorator</h3><p><strong>A decorator that accepts arguments and returns a normal decorator that accepts a function.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> wraps <div><h3 id="parametrizeddecorator">Parametrized Decorator</h3><p><strong>A decorator that accepts arguments and returns a normal decorator that accepts a function.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> wraps
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">debug</span><span class="hljs-params">(print_result=False)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">debug</span><span class="hljs-params">(print_result=<span class="hljs-keyword">False</span>)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">decorator</span><span class="hljs-params">(func)</span>:</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">decorator</span><span class="hljs-params">(func)</span>:</span>
<span class="hljs-meta"> @wraps(func)</span> <span class="hljs-meta"> @wraps(func)</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">out</span><span class="hljs-params">(*args, **kwargs)</span>:</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">out</span><span class="hljs-params">(*args, **kwargs)</span>:</span>
@ -1200,10 +1200,10 @@ LogicOp = Enum(<span class="hljs-string">'LogicOp'</span>, {<span class="hljs-st
<li><strong>Code inside the <code class="python hljs"><span class="hljs-string">'else'</span></code> block will only be executed if <code class="python hljs"><span class="hljs-string">'try'</span></code> block had no exceptions.</strong></li> <li><strong>Code inside the <code class="python hljs"><span class="hljs-string">'else'</span></code> block will only be executed if <code class="python hljs"><span class="hljs-string">'try'</span></code> block had no exceptions.</strong></li>
<li><strong>Code inside the <code class="python hljs"><span class="hljs-string">'finally'</span></code> block will always be executed (unless a signal is received).</strong></li> <li><strong>Code inside the <code class="python hljs"><span class="hljs-string">'finally'</span></code> block will always be executed (unless a signal is received).</strong></li>
</ul> </ul>
<div><h3 id="catchingexceptions">Catching Exceptions</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">except</span> &lt;exception&gt;:
<span class="hljs-keyword">except</span> &lt;exception&gt; <span class="hljs-keyword">as</span> &lt;name&gt;:
<span class="hljs-keyword">except</span> (&lt;exception&gt;, [...]):
<span class="hljs-keyword">except</span> (&lt;exception&gt;, [...]) <span class="hljs-keyword">as</span> &lt;name&gt;:
<div><h3 id="catchingexceptions">Catching Exceptions</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">except</span> &lt;exception&gt;: ...
<span class="hljs-keyword">except</span> &lt;exception&gt; <span class="hljs-keyword">as</span> &lt;name&gt;: ...
<span class="hljs-keyword">except</span> (&lt;exception&gt;, [...]): ...
<span class="hljs-keyword">except</span> (&lt;exception&gt;, [...]) <span class="hljs-keyword">as</span> &lt;name&gt;: ...
</code></pre></div> </code></pre></div>
<ul> <ul>
@ -1936,7 +1936,7 @@ W, H = <span class="hljs-number">15</span>, <span class="hljs-number">7</span>
offset = P(curses.COLS//<span class="hljs-number">2</span> - W//<span class="hljs-number">2</span>, curses.LINES//<span class="hljs-number">2</span> - H//<span class="hljs-number">2</span>) offset = P(curses.COLS//<span class="hljs-number">2</span> - W//<span class="hljs-number">2</span>, curses.LINES//<span class="hljs-number">2</span> - H//<span class="hljs-number">2</span>)
<span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>: <span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:
screen.erase() screen.erase()
curses.textpad.rectangle(screen, offset.y<span class="hljs-number">-1</span>, offset.x<span class="hljs-number">-1</span>, offset.y+H, offset.x+W)
curses.textpad.rectangle(screen, offset.y-<span class="hljs-number">1</span>, offset.x-<span class="hljs-number">1</span>, offset.y+H, offset.x+W)
<span class="hljs-keyword">for</span> id_, p <span class="hljs-keyword">in</span> state.items(): <span class="hljs-keyword">for</span> id_, p <span class="hljs-keyword">in</span> state.items():
screen.addstr(offset.y + (p.y - state[<span class="hljs-string">'*'</span>].y + H//<span class="hljs-number">2</span>) % H, screen.addstr(offset.y + (p.y - state[<span class="hljs-string">'*'</span>].y + H//<span class="hljs-number">2</span>) % H,
offset.x + (p.x - state[<span class="hljs-string">'*'</span>].x + W//<span class="hljs-number">2</span>) % W, str(id_)) offset.x + (p.x - state[<span class="hljs-string">'*'</span>].x + W//<span class="hljs-number">2</span>) % W, str(id_))
@ -2140,8 +2140,7 @@ Line # Mem usage Increment Line Contents
3 38.012 MiB 0.344 MiB a = [*range(10000)] 3 38.012 MiB 0.344 MiB a = [*range(10000)]
4 38.477 MiB 0.465 MiB b = {*range(10000)} 4 38.477 MiB 0.465 MiB b = {*range(10000)}
</code></pre> </code></pre>
<div><h3 id="callgraph">Call Graph</h3><div><h4 id="generatesapngimageofthecallgraphwithhighlightedbottlenecks">Generates a PNG image of the call graph with highlighted bottlenecks:</h4><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install pycallgraph2</span>
<span class="hljs-comment"># $ apt install graphviz</span>
<div><h3 id="callgraph">Call Graph</h3><div><h4 id="generatesapngimageofthecallgraphwithhighlightedbottlenecks">Generates a PNG image of the call graph with highlighted bottlenecks:</h4><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install pycallgraph2; brew/apt install graphviz</span>
<span class="hljs-keyword">import</span> pycallgraph2 <span class="hljs-keyword">as</span> cg, datetime <span class="hljs-keyword">import</span> pycallgraph2 <span class="hljs-keyword">as</span> cg, datetime
filename = <span class="hljs-string">f'profile-<span class="hljs-subst">{datetime.datetime.now():%Y%m%d%H%M%S}</span>.png'</span> filename = <span class="hljs-string">f'profile-<span class="hljs-subst">{datetime.datetime.now():%Y%m%d%H%M%S}</span>.png'</span>
drawer = cg.output.GraphvizOutput(output_file=filename) drawer = cg.output.GraphvizOutput(output_file=filename)
@ -2479,8 +2478,8 @@ W, H, MAX_S = <span class="hljs-number">50</span>, <span class="hljs-number">50<
Mario = dataclasses.make_dataclass(<span class="hljs-string">'Mario'</span>, <span class="hljs-string">'rect spd facing_left frame_cycle'</span>.split()) Mario = dataclasses.make_dataclass(<span class="hljs-string">'Mario'</span>, <span class="hljs-string">'rect spd facing_left frame_cycle'</span>.split())
<span class="hljs-keyword">return</span> Mario(get_rect(<span class="hljs-number">1</span>, <span class="hljs-number">1</span>), P(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>), <span class="hljs-keyword">False</span>, it.cycle(range(<span class="hljs-number">3</span>))) <span class="hljs-keyword">return</span> Mario(get_rect(<span class="hljs-number">1</span>, <span class="hljs-number">1</span>), P(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>), <span class="hljs-keyword">False</span>, it.cycle(range(<span class="hljs-number">3</span>)))
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_tiles</span><span class="hljs-params">()</span>:</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_tiles</span><span class="hljs-params">()</span>:</span>
border = [(x, y) <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> range(W) <span class="hljs-keyword">for</span> y <span class="hljs-keyword">in</span> range(H) <span class="hljs-keyword">if</span> x <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, W<span class="hljs-number">-1</span>] <span class="hljs-keyword">or</span> y <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, H<span class="hljs-number">-1</span>]]
platforms = [(randint(<span class="hljs-number">1</span>, W<span class="hljs-number">-2</span>), randint(<span class="hljs-number">2</span>, H<span class="hljs-number">-2</span>)) <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> range(W*H // <span class="hljs-number">10</span>)]
border = [(x, y) <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> range(W) <span class="hljs-keyword">for</span> y <span class="hljs-keyword">in</span> range(H) <span class="hljs-keyword">if</span> x <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, W-<span class="hljs-number">1</span>] <span class="hljs-keyword">or</span> y <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, H-<span class="hljs-number">1</span>]]
platforms = [(randint(<span class="hljs-number">1</span>, W-<span class="hljs-number">2</span>), randint(<span class="hljs-number">2</span>, H-<span class="hljs-number">2</span>)) <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> range(W*H // <span class="hljs-number">10</span>)]
<span class="hljs-keyword">return</span> [get_rect(x, y) <span class="hljs-keyword">for</span> x, y <span class="hljs-keyword">in</span> border + platforms] <span class="hljs-keyword">return</span> [get_rect(x, y) <span class="hljs-keyword">for</span> x, y <span class="hljs-keyword">in</span> border + platforms]
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_rect</span><span class="hljs-params">(x, y)</span>:</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_rect</span><span class="hljs-params">(x, y)</span>:</span>
<span class="hljs-keyword">return</span> pg.Rect(x*<span class="hljs-number">16</span>, y*<span class="hljs-number">16</span>, <span class="hljs-number">16</span>, <span class="hljs-number">16</span>) <span class="hljs-keyword">return</span> pg.Rect(x*<span class="hljs-number">16</span>, y*<span class="hljs-number">16</span>, <span class="hljs-number">16</span>, <span class="hljs-number">16</span>)
@ -2528,7 +2527,7 @@ W, H, MAX_S = <span class="hljs-number">50</span>, <span class="hljs-number">50<
mario.facing_left = (D.w <span class="hljs-keyword">in</span> pressed) <span class="hljs-keyword">if</span> {D.w, D.e} &amp; pressed <span class="hljs-keyword">else</span> mario.facing_left mario.facing_left = (D.w <span class="hljs-keyword">in</span> pressed) <span class="hljs-keyword">if</span> {D.w, D.e} &amp; pressed <span class="hljs-keyword">else</span> mario.facing_left
screen.blit(images[get_marios_image_index() + mario.facing_left * <span class="hljs-number">9</span>], mario.rect) screen.blit(images[get_marios_image_index() + mario.facing_left * <span class="hljs-number">9</span>], mario.rect)
<span class="hljs-keyword">for</span> t <span class="hljs-keyword">in</span> tiles: <span class="hljs-keyword">for</span> t <span class="hljs-keyword">in</span> tiles:
screen.blit(images[<span class="hljs-number">18</span> <span class="hljs-keyword">if</span> t.x <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, (W<span class="hljs-number">-1</span>)*<span class="hljs-number">16</span>] <span class="hljs-keyword">or</span> t.y <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, (H<span class="hljs-number">-1</span>)*<span class="hljs-number">16</span>] <span class="hljs-keyword">else</span> <span class="hljs-number">19</span>], t)
screen.blit(images[<span class="hljs-number">18</span> <span class="hljs-keyword">if</span> t.x <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, (W-<span class="hljs-number">1</span>)*<span class="hljs-number">16</span>] <span class="hljs-keyword">or</span> t.y <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, (H-<span class="hljs-number">1</span>)*<span class="hljs-number">16</span>] <span class="hljs-keyword">else</span> <span class="hljs-number">19</span>], t)
pg.display.flip() pg.display.flip()
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>: <span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
@ -2902,7 +2901,7 @@ $ pyinstaller script.py --add-data '&lt;path&gt;:.' <span class="hljs-comment">
<footer> <footer>
<aside>June 20, 2022</aside>
<aside>June 21, 2022</aside>
<a href="https://gto76.github.io" rel="author">Jure Šorn</a> <a href="https://gto76.github.io" rel="author">Jure Šorn</a>
</footer> </footer>

148
parse.js

@ -51,6 +51,23 @@ const LRU_CACHE =
'<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fib</span><span class="hljs-params">(n)</span>:</span>\n' + '<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fib</span><span class="hljs-params">(n)</span>:</span>\n' +
' <span class="hljs-keyword">return</span> n <span class="hljs-keyword">if</span> n &lt; <span class="hljs-number">2</span> <span class="hljs-keyword">else</span> fib(n-<span class="hljs-number">2</span>) + fib(n-<span class="hljs-number">1</span>)\n'; ' <span class="hljs-keyword">return</span> n <span class="hljs-keyword">if</span> n &lt; <span class="hljs-number">2</span> <span class="hljs-keyword">else</span> fib(n-<span class="hljs-number">2</span>) + fib(n-<span class="hljs-number">1</span>)\n';
const PARAMETRIZED_DECORATOR =
'<span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> wraps\n' +
'\n' +
'<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">debug</span><span class="hljs-params">(print_result=<span class="hljs-keyword">False</span>)</span>:</span>\n' +
' <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">decorator</span><span class="hljs-params">(func)</span>:</span>\n' +
'<span class="hljs-meta"> @wraps(func)</span>\n' +
' <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">out</span><span class="hljs-params">(*args, **kwargs)</span>:</span>\n' +
' result = func(*args, **kwargs)\n' +
' print(func.__name__, result <span class="hljs-keyword">if</span> print_result <span class="hljs-keyword">else</span> <span class="hljs-string">\'\'</span>)\n' +
' <span class="hljs-keyword">return</span> result\n' +
' <span class="hljs-keyword">return</span> out\n' +
' <span class="hljs-keyword">return</span> decorator\n' +
'\n' +
'<span class="hljs-meta">@debug(print_result=True)</span>\n' +
'<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add</span><span class="hljs-params">(x, y)</span>:</span>\n' +
' <span class="hljs-keyword">return</span> x + y\n';
const REPR_USE_CASES = const REPR_USE_CASES =
'print/str/repr([&lt;el&gt;])\n' + 'print/str/repr([&lt;el&gt;])\n' +
'<span class="hljs-string">f\'<span class="hljs-subst">{&lt;el&gt;!r}</span>\'</span>\n' + '<span class="hljs-string">f\'<span class="hljs-subst">{&lt;el&gt;!r}</span>\'</span>\n' +
@ -89,6 +106,59 @@ const EVAL =
'<span class="hljs-meta">&gt;&gt;&gt; </span>literal_eval(<span class="hljs-string">\'1 + 2\'</span>)\n' + '<span class="hljs-meta">&gt;&gt;&gt; </span>literal_eval(<span class="hljs-string">\'1 + 2\'</span>)\n' +
'ValueError: malformed node or string\n'; 'ValueError: malformed node or string\n';
const COROUTINES =
'<span class="hljs-keyword">import</span> asyncio, collections, curses, curses.textpad, enum, random\n' +
'\n' +
'P = collections.namedtuple(<span class="hljs-string">\'P\'</span>, <span class="hljs-string">\'x y\'</span>) <span class="hljs-comment"># Position</span>\n' +
'D = enum.Enum(<span class="hljs-string">\'D\'</span>, <span class="hljs-string">\'n e s w\'</span>) <span class="hljs-comment"># Direction</span>\n' +
'W, H = <span class="hljs-number">15</span>, <span class="hljs-number">7</span> <span class="hljs-comment"># Width, Height</span>\n' +
'\n' +
'<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span><span class="hljs-params">(screen)</span>:</span>\n' +
' curses.curs_set(<span class="hljs-number">0</span>) <span class="hljs-comment"># Makes cursor invisible.</span>\n' +
' screen.nodelay(<span class="hljs-keyword">True</span>) <span class="hljs-comment"># Makes getch() non-blocking.</span>\n' +
' asyncio.run(main_coroutine(screen)) <span class="hljs-comment"># Starts running asyncio code.</span>\n' +
'\n' +
'<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main_coroutine</span><span class="hljs-params">(screen)</span>:</span>\n' +
' state = {<span class="hljs-string">\'*\'</span>: P(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>), **{id_: P(W//<span class="hljs-number">2</span>, H//<span class="hljs-number">2</span>) <span class="hljs-keyword">for</span> id_ <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)}}\n' +
' moves = asyncio.Queue()\n' +
' coros = (*(random_controller(id_, moves) <span class="hljs-keyword">for</span> id_ <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)),\n' +
' human_controller(screen, moves), model(moves, state), view(state, screen))\n' +
' <span class="hljs-keyword">await</span> asyncio.wait(coros, return_when=asyncio.FIRST_COMPLETED)\n' +
'\n' +
'<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">random_controller</span><span class="hljs-params">(id_, moves)</span>:</span>\n' +
' <span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:\n' +
' d = random.choice(list(D))\n' +
' moves.put_nowait((id_, d))\n' +
' <span class="hljs-keyword">await</span> asyncio.sleep(random.triangular(<span class="hljs-number">0.01</span>, <span class="hljs-number">0.65</span>))\n' +
'\n' +
'<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">human_controller</span><span class="hljs-params">(screen, moves)</span>:</span>\n' +
' <span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:\n' +
' ch = screen.getch()\n' +
' key_mappings = {<span class="hljs-number">258</span>: D.s, <span class="hljs-number">259</span>: D.n, <span class="hljs-number">260</span>: D.w, <span class="hljs-number">261</span>: D.e}\n' +
' <span class="hljs-keyword">if</span> ch <span class="hljs-keyword">in</span> key_mappings:\n' +
' moves.put_nowait((<span class="hljs-string">\'*\'</span>, key_mappings[ch]))\n' +
' <span class="hljs-keyword">await</span> asyncio.sleep(<span class="hljs-number">0.005</span>)\n' +
'\n' +
'<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">model</span><span class="hljs-params">(moves, state)</span>:</span>\n' +
' <span class="hljs-keyword">while</span> state[<span class="hljs-string">\'*\'</span>] <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> (state[id_] <span class="hljs-keyword">for</span> id_ <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)):\n' +
' id_, d = <span class="hljs-keyword">await</span> moves.get()\n' +
' x, y = state[id_]\n' +
' deltas = {D.n: P(<span class="hljs-number">0</span>, <span class="hljs-number">-1</span>), D.e: P(<span class="hljs-number">1</span>, <span class="hljs-number">0</span>), D.s: P(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>), D.w: P(<span class="hljs-number">-1</span>, <span class="hljs-number">0</span>)}\n' +
' state[id_] = P((x + deltas[d].x) % W, (y + deltas[d].y) % H)\n' +
'\n' +
'<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">view</span><span class="hljs-params">(state, screen)</span>:</span>\n' +
' offset = P(curses.COLS//<span class="hljs-number">2</span> - W//<span class="hljs-number">2</span>, curses.LINES//<span class="hljs-number">2</span> - H//<span class="hljs-number">2</span>)\n' +
' <span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:\n' +
' screen.erase()\n' +
' curses.textpad.rectangle(screen, offset.y-<span class="hljs-number">1</span>, offset.x-<span class="hljs-number">1</span>, offset.y+H, offset.x+W)\n' +
' <span class="hljs-keyword">for</span> id_, p <span class="hljs-keyword">in</span> state.items():\n' +
' screen.addstr(offset.y + (p.y - state[<span class="hljs-string">\'*\'</span>].y + H//<span class="hljs-number">2</span>) % H,\n' +
' offset.x + (p.x - state[<span class="hljs-string">\'*\'</span>].x + W//<span class="hljs-number">2</span>) % W, str(id_))\n' +
' <span class="hljs-keyword">await</span> asyncio.sleep(<span class="hljs-number">0.005</span>)\n' +
'\n' +
'<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">\'__main__\'</span>:\n' +
' curses.wrapper(main)\n';
const PROGRESS_BAR = const PROGRESS_BAR =
'<span class="hljs-comment"># $ pip3 install tqdm</span>\n' + '<span class="hljs-comment"># $ pip3 install tqdm</span>\n' +
'<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> tqdm <span class="hljs-keyword">import</span> tqdm\n' + '<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> tqdm <span class="hljs-keyword">import</span> tqdm\n' +
@ -97,6 +167,81 @@ const PROGRESS_BAR =
'<span class="hljs-meta">... </span> sleep(<span class="hljs-number">1</span>)\n' + '<span class="hljs-meta">... </span> sleep(<span class="hljs-number">1</span>)\n' +
'Processing: 100%|████████████████████| 3/3 [00:03&lt;00:00, 1.00s/it]\n'; 'Processing: 100%|████████████████████| 3/3 [00:03&lt;00:00, 1.00s/it]\n';
const MARIO =
'<span class="hljs-keyword">import</span> collections, dataclasses, enum, io, itertools <span class="hljs-keyword">as</span> it, pygame <span class="hljs-keyword">as</span> pg, urllib.request\n' +
'<span class="hljs-keyword">from</span> random <span class="hljs-keyword">import</span> randint\n' +
'\n' +
'P = collections.namedtuple(<span class="hljs-string">\'P\'</span>, <span class="hljs-string">\'x y\'</span>) <span class="hljs-comment"># Position</span>\n' +
'D = enum.Enum(<span class="hljs-string">\'D\'</span>, <span class="hljs-string">\'n e s w\'</span>) <span class="hljs-comment"># Direction</span>\n' +
'W, H, MAX_S = <span class="hljs-number">50</span>, <span class="hljs-number">50</span>, P(<span class="hljs-number">5</span>, <span class="hljs-number">10</span>) <span class="hljs-comment"># Width, Height, Max speed</span>\n' +
'\n' +
'<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span><span class="hljs-params">()</span>:</span>\n' +
' <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_screen</span><span class="hljs-params">()</span>:</span>\n' +
' pg.init()\n' +
' <span class="hljs-keyword">return</span> pg.display.set_mode((W*<span class="hljs-number">16</span>, H*<span class="hljs-number">16</span>))\n' +
' <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_images</span><span class="hljs-params">()</span>:</span>\n' +
' url = <span class="hljs-string">\'https://gto76.github.io/python-cheatsheet/web/mario_bros.png\'</span>\n' +
' img = pg.image.load(io.BytesIO(urllib.request.urlopen(url).read()))\n' +
' <span class="hljs-keyword">return</span> [img.subsurface(get_rect(x, <span class="hljs-number">0</span>)) <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> range(img.get_width() // <span class="hljs-number">16</span>)]\n' +
' <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_mario</span><span class="hljs-params">()</span>:</span>\n' +
' Mario = dataclasses.make_dataclass(<span class="hljs-string">\'Mario\'</span>, <span class="hljs-string">\'rect spd facing_left frame_cycle\'</span>.split())\n' +
' <span class="hljs-keyword">return</span> Mario(get_rect(<span class="hljs-number">1</span>, <span class="hljs-number">1</span>), P(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>), <span class="hljs-keyword">False</span>, it.cycle(range(<span class="hljs-number">3</span>)))\n' +
' <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_tiles</span><span class="hljs-params">()</span>:</span>\n' +
' border = [(x, y) <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> range(W) <span class="hljs-keyword">for</span> y <span class="hljs-keyword">in</span> range(H) <span class="hljs-keyword">if</span> x <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, W-<span class="hljs-number">1</span>] <span class="hljs-keyword">or</span> y <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, H-<span class="hljs-number">1</span>]]\n' +
' platforms = [(randint(<span class="hljs-number">1</span>, W-<span class="hljs-number">2</span>), randint(<span class="hljs-number">2</span>, H-<span class="hljs-number">2</span>)) <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> range(W*H // <span class="hljs-number">10</span>)]\n' +
' <span class="hljs-keyword">return</span> [get_rect(x, y) <span class="hljs-keyword">for</span> x, y <span class="hljs-keyword">in</span> border + platforms]\n' +
' <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_rect</span><span class="hljs-params">(x, y)</span>:</span>\n' +
' <span class="hljs-keyword">return</span> pg.Rect(x*<span class="hljs-number">16</span>, y*<span class="hljs-number">16</span>, <span class="hljs-number">16</span>, <span class="hljs-number">16</span>)\n' +
' run(get_screen(), get_images(), get_mario(), get_tiles())\n' +
'\n' +
'<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">run</span><span class="hljs-params">(screen, images, mario, tiles)</span>:</span>\n' +
' clock = pg.time.Clock()\n' +
' <span class="hljs-keyword">while</span> all(event.type != pg.QUIT <span class="hljs-keyword">for</span> event <span class="hljs-keyword">in</span> pg.event.get()):\n' +
' keys = {pg.K_UP: D.n, pg.K_RIGHT: D.e, pg.K_DOWN: D.s, pg.K_LEFT: D.w}\n' +
' pressed = {keys.get(ch) <span class="hljs-keyword">for</span> ch, is_prsd <span class="hljs-keyword">in</span> enumerate(pg.key.get_pressed()) <span class="hljs-keyword">if</span> is_prsd}\n' +
' update_speed(mario, tiles, pressed)\n' +
' update_position(mario, tiles)\n' +
' draw(screen, images, mario, tiles, pressed)\n' +
' clock.tick(<span class="hljs-number">28</span>)\n' +
'\n' +
'<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">update_speed</span><span class="hljs-params">(mario, tiles, pressed)</span>:</span>\n' +
' x, y = mario.spd\n' +
' x += <span class="hljs-number">2</span> * ((D.e <span class="hljs-keyword">in</span> pressed) - (D.w <span class="hljs-keyword">in</span> pressed))\n' +
' x -= (x &gt; <span class="hljs-number">0</span>) - (x &lt; <span class="hljs-number">0</span>)\n' +
' y += <span class="hljs-number">1</span> <span class="hljs-keyword">if</span> D.s <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> get_boundaries(mario.rect, tiles) <span class="hljs-keyword">else</span> (D.n <span class="hljs-keyword">in</span> pressed) * <span class="hljs-number">-10</span>\n' +
' mario.spd = P(x=max(-MAX_S.x, min(MAX_S.x, x)), y=max(-MAX_S.y, min(MAX_S.y, y)))\n' +
'\n' +
'<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">update_position</span><span class="hljs-params">(mario, tiles)</span>:</span>\n' +
' x, y = mario.rect.topleft\n' +
' n_steps = max(abs(s) <span class="hljs-keyword">for</span> s <span class="hljs-keyword">in</span> mario.spd)\n' +
' <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> range(n_steps):\n' +
' mario.spd = stop_on_collision(mario.spd, get_boundaries(mario.rect, tiles))\n' +
' x, y = x + mario.spd.x / n_steps, y + mario.spd.y / n_steps\n' +
' mario.rect.topleft = x, y\n' +
'\n' +
'<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_boundaries</span><span class="hljs-params">(rect, tiles)</span>:</span>\n' +
' deltas = {D.n: P(<span class="hljs-number">0</span>, <span class="hljs-number">-1</span>), D.e: P(<span class="hljs-number">1</span>, <span class="hljs-number">0</span>), D.s: P(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>), D.w: P(<span class="hljs-number">-1</span>, <span class="hljs-number">0</span>)}\n' +
' <span class="hljs-keyword">return</span> {d <span class="hljs-keyword">for</span> d, delta <span class="hljs-keyword">in</span> deltas.items() <span class="hljs-keyword">if</span> rect.move(delta).collidelist(tiles) != <span class="hljs-number">-1</span>}\n' +
'\n' +
'<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">stop_on_collision</span><span class="hljs-params">(spd, bounds)</span>:</span>\n' +
' <span class="hljs-keyword">return</span> P(x=<span class="hljs-number">0</span> <span class="hljs-keyword">if</span> (D.w <span class="hljs-keyword">in</span> bounds <span class="hljs-keyword">and</span> spd.x &lt; <span class="hljs-number">0</span>) <span class="hljs-keyword">or</span> (D.e <span class="hljs-keyword">in</span> bounds <span class="hljs-keyword">and</span> spd.x &gt; <span class="hljs-number">0</span>) <span class="hljs-keyword">else</span> spd.x,\n' +
' y=<span class="hljs-number">0</span> <span class="hljs-keyword">if</span> (D.n <span class="hljs-keyword">in</span> bounds <span class="hljs-keyword">and</span> spd.y &lt; <span class="hljs-number">0</span>) <span class="hljs-keyword">or</span> (D.s <span class="hljs-keyword">in</span> bounds <span class="hljs-keyword">and</span> spd.y &gt; <span class="hljs-number">0</span>) <span class="hljs-keyword">else</span> spd.y)\n' +
'\n' +
'<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">draw</span><span class="hljs-params">(screen, images, mario, tiles, pressed)</span>:</span>\n' +
' <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_marios_image_index</span><span class="hljs-params">()</span>:</span>\n' +
' <span class="hljs-keyword">if</span> D.s <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> get_boundaries(mario.rect, tiles):\n' +
' <span class="hljs-keyword">return</span> <span class="hljs-number">4</span>\n' +
' <span class="hljs-keyword">return</span> next(mario.frame_cycle) <span class="hljs-keyword">if</span> {D.w, D.e} &amp; pressed <span class="hljs-keyword">else</span> <span class="hljs-number">6</span>\n' +
' screen.fill((<span class="hljs-number">85</span>, <span class="hljs-number">168</span>, <span class="hljs-number">255</span>))\n' +
' mario.facing_left = (D.w <span class="hljs-keyword">in</span> pressed) <span class="hljs-keyword">if</span> {D.w, D.e} &amp; pressed <span class="hljs-keyword">else</span> mario.facing_left\n' +
' screen.blit(images[get_marios_image_index() + mario.facing_left * <span class="hljs-number">9</span>], mario.rect)\n' +
' <span class="hljs-keyword">for</span> t <span class="hljs-keyword">in</span> tiles:\n' +
' screen.blit(images[<span class="hljs-number">18</span> <span class="hljs-keyword">if</span> t.x <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, (W-<span class="hljs-number">1</span>)*<span class="hljs-number">16</span>] <span class="hljs-keyword">or</span> t.y <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, (H-<span class="hljs-number">1</span>)*<span class="hljs-number">16</span>] <span class="hljs-keyword">else</span> <span class="hljs-number">19</span>], t)\n' +
' pg.display.flip()\n' +
'\n' +
'<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">\'__main__\'</span>:\n' +
' main()\n';
const PYINSTALLER = const PYINSTALLER =
'$ pip3 install pyinstaller\n' + '$ pip3 install pyinstaller\n' +
'$ pyinstaller script.py <span class="hljs-comment"># Compiles into \'./dist/script\' directory.</span>\n' + '$ pyinstaller script.py <span class="hljs-comment"># Compiles into \'./dist/script\' directory.</span>\n' +
@ -570,6 +715,7 @@ function fixClasses() {
function fixHighlights() { function fixHighlights() {
$(`code:contains(@lru_cache(maxsize=None))`).html(LRU_CACHE); $(`code:contains(@lru_cache(maxsize=None))`).html(LRU_CACHE);
$(`code:contains(@debug(print_result=True))`).html(PARAMETRIZED_DECORATOR);
$(`code:contains((self, a=None):)`).html(CONSTRUCTOR_OVERLOADING); $(`code:contains((self, a=None):)`).html(CONSTRUCTOR_OVERLOADING);
$(`code:contains(print/str/repr([<el>]))`).html(REPR_USE_CASES); $(`code:contains(print/str/repr([<el>]))`).html(REPR_USE_CASES);
$(`code:contains(make_dataclass(\'<class_name>\')`).html(DATACLASS); $(`code:contains(make_dataclass(\'<class_name>\')`).html(DATACLASS);
@ -578,7 +724,9 @@ function fixHighlights() {
$(`code:contains(\'<n>s\')`).html(STRUCT_FORMAT); $(`code:contains(\'<n>s\')`).html(STRUCT_FORMAT);
$(`code:contains(\'<class_name>\', <tuple_of_parents>, <dict_of_class_attributes>)`).html(TYPE); $(`code:contains(\'<class_name>\', <tuple_of_parents>, <dict_of_class_attributes>)`).html(TYPE);
$(`code:contains(ValueError: malformed node)`).html(EVAL); $(`code:contains(ValueError: malformed node)`).html(EVAL);
$(`code:contains(import asyncio, collections, curses, curses.textpad, enum, random)`).html(COROUTINES);
$(`code:contains(pip3 install tqdm)`).html(PROGRESS_BAR); $(`code:contains(pip3 install tqdm)`).html(PROGRESS_BAR);
$(`code:contains(collections, dataclasses, enum, io, itertools)`).html(MARIO);
$(`code:contains(pip3 install pyinstaller)`).html(PYINSTALLER); $(`code:contains(pip3 install pyinstaller)`).html(PYINSTALLER);
$(`ul:contains(Only available in)`).html(INDEX); $(`ul:contains(Only available in)`).html(INDEX);
} }

Loading…
Cancel
Save