* **All functions and classes have a call() method, hence are callable.**
* **Use `'callable(<obj>)'` or `'isinstance(<obj>, collections.abc.Callable)'` to check if object is callable.**
* **Use `'callable(<obj>)'` or `'isinstance(<obj>, collections.abc.Callable)'` to check if object is callable. Calling an uncallable object raises `'TypeError'`.**
* **When this cheatsheet uses `'<function>'` as an argument, it means `'<callable>'`.**
```python
class Counter:
@ -2435,7 +2434,7 @@ Console App
```python
# $ pip3 install windows-curses
import curses, os
from curses import A_REVERSE, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ENTER
from curses import A_REVERSE, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT
* **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.**
* **Debug mode restarts the app whenever script changes and displays errors in the browser.**
<li><strong><codeclass="python hljs"><spanclass="hljs-string">'int(<str>)'</span></code> and <codeclass="python hljs"><spanclass="hljs-string">'float(<str>)'</span></code> raise ValueError on malformed strings.</strong></li>
<li><strong>Decimal numbers are stored exactly, unlike most floats where <codeclass="python hljs"><spanclass="hljs-string">'1.1 + 2.2 != 3.3'</span></code>.</strong></li>
<li><strong>Floats can be compared with: <codeclass="python hljs"><spanclass="hljs-string">'math.isclose(<float>, <float>)'</span></code>.</strong></li>
<li><strong>Precision of decimal operations is set with: <codeclass="python hljs"><spanclass="hljs-string">'decimal.getcontext().prec = <int>'</span></code>.</strong></li>
<li><strong>Bools can be used anywhere ints can, because bool is a subclass of int: <codeclass="python hljs"><spanclass="hljs-string">'True + 1 == 2'</span></code>.</strong></li>
<num> = round(<num> [, ±ndigits]) <spanclass="hljs-comment"># Also math.floor/ceil(<number>).</span>
<num> = min(<collection>) <spanclass="hljs-comment"># Also max(<num>, <num> [, ...]).</span>
<num> = sum(<collection>) <spanclass="hljs-comment"># Also math.prod(<collection>).</span>
</code></pre></div>
<div><h3id="math">Math</h3><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">from</span> math <spanclass="hljs-keyword">import</span> e, pi, inf, nan, isinf, isnan <spanclass="hljs-comment"># `<el> == nan` is always False.</span>
<spanclass="hljs-keyword">from</span> math <spanclass="hljs-keyword">import</span> sin, cos, tan, asin, acos, atan <spanclass="hljs-comment"># Also: degrees, radians.</span>
<spanclass="hljs-keyword">from</span> math <spanclass="hljs-keyword">import</span> log, log10, log2 <spanclass="hljs-comment"># Log can accept base as second arg.</span>
<div><h3id="math">Math</h3><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">from</span> math <spanclass="hljs-keyword">import</span> e, pi, inf, nan, isnan <spanclass="hljs-comment"># `inf*0` and `nan+1` return nan.</span>
<spanclass="hljs-keyword">from</span> math <spanclass="hljs-keyword">import</span> sqrt, factorial <spanclass="hljs-comment"># `sqrt(-1)` raises ValueError.</span>
<spanclass="hljs-keyword">from</span> math <spanclass="hljs-keyword">import</span> sin, cos, tan <spanclass="hljs-comment"># Also: asin, degrees, radians.</span>
<spanclass="hljs-keyword">from</span> math <spanclass="hljs-keyword">import</span> log, log10, log2 <spanclass="hljs-comment"># Log accepts base as second arg.</span>
<div><h3id="statistics">Statistics</h3><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">from</span> statistics <spanclass="hljs-keyword">import</span> mean, median, mode <spanclass="hljs-comment"># Mode returns the most common value.</span>
<pre><codeclass="python language-python hljs"><spanclass="hljs-meta">>>></span>list(it.product(<spanclass="hljs-string">'abc'</span>, repeat=<spanclass="hljs-number">2</span>)) <spanclass="hljs-comment"># a b c</span>
[(<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'a'</span>), (<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'b'</span>), (<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'c'</span>), <spanclass="hljs-comment"># a x x x</span>
(<spanclass="hljs-string">'b'</span>, <spanclass="hljs-string">'a'</span>), (<spanclass="hljs-string">'b'</span>, <spanclass="hljs-string">'b'</span>), (<spanclass="hljs-string">'b'</span>, <spanclass="hljs-string">'c'</span>), <spanclass="hljs-comment"># b x x x</span>
(<spanclass="hljs-string">'c'</span>, <spanclass="hljs-string">'a'</span>), (<spanclass="hljs-string">'c'</span>, <spanclass="hljs-string">'b'</span>), (<spanclass="hljs-string">'c'</span>, <spanclass="hljs-string">'c'</span>)] <spanclass="hljs-comment"># c x x x</span>
</code></pre>
<pre><codeclass="python language-python hljs"><spanclass="hljs-meta">>>></span>list(it.product(<spanclass="hljs-string">'abc'</span>, <spanclass="hljs-string">'abc'</span>))<spanclass="hljs-comment"># a b c</span>
[(<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'a'</span>), (<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'b'</span>), (<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'c'</span>),<spanclass="hljs-comment"># a x x x</span>
(<spanclass="hljs-string">'b'</span>, <spanclass="hljs-string">'a'</span>), (<spanclass="hljs-string">'b'</span>, <spanclass="hljs-string">'b'</span>), (<spanclass="hljs-string">'b'</span>, <spanclass="hljs-string">'c'</span>),<spanclass="hljs-comment"># b x x x</span>
(<spanclass="hljs-string">'c'</span>, <spanclass="hljs-string">'a'</span>), (<spanclass="hljs-string">'c'</span>, <spanclass="hljs-string">'b'</span>), (<spanclass="hljs-string">'c'</span>, <spanclass="hljs-string">'c'</span>)]<spanclass="hljs-comment"># c x x x</span>
<pre><codeclass="python language-python hljs"><spanclass="hljs-meta">>>></span>list(it.permutations(<spanclass="hljs-string">'abc'</span>, <spanclass="hljs-number">2</span>)) <spanclass="hljs-comment"># a b c</span>
[(<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'b'</span>), (<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'c'</span>), <spanclass="hljs-comment"># a . x x</span>
(<spanclass="hljs-string">'b'</span>, <spanclass="hljs-string">'a'</span>), (<spanclass="hljs-string">'b'</span>, <spanclass="hljs-string">'c'</span>), <spanclass="hljs-comment"># b x . x</span>
(<spanclass="hljs-string">'c'</span>, <spanclass="hljs-string">'a'</span>), (<spanclass="hljs-string">'c'</span>, <spanclass="hljs-string">'b'</span>)] <spanclass="hljs-comment"># c x x .</span>
</code></pre>
<pre><codeclass="python language-python hljs"><spanclass="hljs-meta">>>></span>list(it.permutations(<spanclass="hljs-string">'abc'</span>, <spanclass="hljs-number">2</span>)) <spanclass="hljs-comment"># a b c</span>
[(<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'b'</span>), (<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'c'</span>), <spanclass="hljs-comment"># a . x x</span>
(<spanclass="hljs-string">'b'</span>, <spanclass="hljs-string">'a'</span>), (<spanclass="hljs-string">'b'</span>, <spanclass="hljs-string">'c'</span>), <spanclass="hljs-comment"># b x . x</span>
(<spanclass="hljs-string">'c'</span>, <spanclass="hljs-string">'a'</span>), (<spanclass="hljs-string">'c'</span>, <spanclass="hljs-string">'b'</span>)] <spanclass="hljs-comment"># c x x .</span>
</code></pre>
<pre><codeclass="python language-python hljs"><spanclass="hljs-meta">>>></span>list(it.combinations(<spanclass="hljs-string">'abc'</span>, <spanclass="hljs-number">2</span>)) <spanclass="hljs-comment"># a b c</span>
[(<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'b'</span>), (<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'c'</span>), <spanclass="hljs-comment"># a . x x</span>
(<spanclass="hljs-string">'b'</span>, <spanclass="hljs-string">'c'</span>), <spanclass="hljs-comment"># b . . x</span>
] <spanclass="hljs-comment"># c . . .</span>
<pre><codeclass="python language-python hljs"><spanclass="hljs-meta">>>></span>list(it.combinations(<spanclass="hljs-string">'abc'</span>, <spanclass="hljs-number">2</span>)) <spanclass="hljs-comment"># a b c</span>
[(<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'b'</span>), (<spanclass="hljs-string">'a'</span>, <spanclass="hljs-string">'c'</span>), <spanclass="hljs-comment"># a . x x</span>
(<spanclass="hljs-string">'b'</span>, <spanclass="hljs-string">'c'</span>), <spanclass="hljs-comment"># b . . x</span>
] <spanclass="hljs-comment"># c . . .</span>
</code></pre>
<div><h2id="datetime"><ahref="#datetime"name="datetime">#</a>Datetime</h2><p><strong>Provides 'date', 'time', 'datetime' and 'timedelta' classes. All are immutable and hashable.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-comment"># $ pip3 install python-dateutil</span>
<spanclass="hljs-keyword">from</span> datetime <spanclass="hljs-keyword">import</span> date, time, datetime, timedelta, timezone
@ -1012,7 +1013,7 @@ P = make_dataclass(<span class="hljs-string">'P'</span>, [(<span class="hljs-str
<li><strong>File objects returned by the <ahref="#open">open()</a> function, etc.</strong></li>
</ul><div><h3id="callable">Callable</h3><ul>
<li><strong>All functions and classes have a call() method, hence are callable.</strong></li>
<li><strong>Use <codeclass="python hljs"><spanclass="hljs-string">'callable(<obj>)'</span></code> or <codeclass="python hljs"><spanclass="hljs-string">'isinstance(<obj>, collections.abc.Callable)'</span></code> to check if object is callable.</strong></li>
<li><strong>Use <codeclass="python hljs"><spanclass="hljs-string">'callable(<obj>)'</span></code> or <codeclass="python hljs"><spanclass="hljs-string">'isinstance(<obj>, collections.abc.Callable)'</span></code> to check if object is callable. Calling an uncallable object raises <codeclass="python hljs"><spanclass="hljs-string">'TypeError'</span></code>.</strong></li>
<li><strong>When this cheatsheet uses <codeclass="python hljs"><spanclass="hljs-string">'<function>'</span></code> as an argument, it means <codeclass="python hljs"><spanclass="hljs-string">'<callable>'</span></code>.</strong></li>
<div><h2id="consoleapp"><ahref="#consoleapp"name="consoleapp">#</a>Console App</h2><div><h4id="runsabasicfileexplorerintheconsole">Runs a basic file explorer in the console:</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-comment"># $ pip3 install windows-curses</span>
<spanclass="hljs-keyword">import</span> curses, os
window[<spanclass="hljs-string">'-OUTPUT-'</span>].update(value=<spanclass="hljs-string">f'<spanclass="hljs-subst">{quantity}</span><spanclass="hljs-subst">{unit}</span> is <spanclass="hljs-subst">{lbs:g}</span> lbs.'</span>)
window[<spanclass="hljs-string">'OUTPUT'</span>].update(value=<spanclass="hljs-string">f'<spanclass="hljs-subst">{quantity}</span><spanclass="hljs-subst">{unit}</span> is <spanclass="hljs-subst">{lbs:g}</span> lbs.'</span>)
<li><strong>Install a WSGI server like <ahref="https://flask.palletsprojects.com/en/latest/deploying/waitress/">Waitress</a> and a HTTP server such as <ahref="https://flask.palletsprojects.com/en/latest/deploying/nginx/">Nginx</a> for better security.</strong></li>
<li><strong>Debug mode restarts the app whenever script changes and displays errors in the browser.</strong></li>
<li><strong><codeclass="python hljs"><spanclass="hljs-string">'fl.request.args[<str>]'</span></code> returns parameter from query string (URL part 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>