<bool> = <sub_str> in <str> # Checks if string contains the substring.
<bool> = <sub_str> in <str> # Checks if string contains the substring.
<bool> = <str>.startswith(<sub_str>) # Pass tuple of strings for multiple options.
<bool> = <str>.startswith(<sub_str>) # Pass tuple of strings for multiple options.
<bool> = <str>.endswith(<sub_str>) # Pass tuple of strings for multiple options.
<int> = <str>.find(<sub_str>) # Returns start index of the first match or -1.
<int> = <str>.find(<sub_str>) # Returns start index of the first match or -1.
<int> = <str>.index(<sub_str>) # Same, but raises ValueError if missing.
<int> = <str>.index(<sub_str>) # Same, but raises ValueError if missing.
```
```
@ -333,6 +335,7 @@ String
<int> = ord(<str>) # Converts Unicode character to int.
<int> = ord(<str>) # Converts Unicode character to int.
```
```
* **Use `'unicodedata.normalize("NFC", <str>)'` on strings that may contain characters like `'Ö'` before comparing them, because they can be stored as one or two characters.**
* **Use `'unicodedata.normalize("NFC", <str>)'` on strings that may contain characters like `'Ö'` before comparing them, because they can be stored as one or two characters.**
* **`'NFC'` converts such characters to a single character, while `'NFD'` converts them to two.**
### Property Methods
### Property Methods
```python
```python
@ -351,9 +354,6 @@ Regex
```python
```python
import re
import re
```
```python
<str> = re.sub(<regex>, new, text, count=0) # Substitutes all occurrences with 'new'.
<str> = re.sub(<regex>, new, text, count=0) # Substitutes all occurrences with 'new'.
<list> = re.findall(<regex>, text) # Returns all occurrences as strings.
<list> = re.findall(<regex>, text) # Returns all occurrences as strings.
<list> = re.split(<regex>, text, maxsplit=0) # Add brackets around regex to include matches.
<list> = re.split(<regex>, text, maxsplit=0) # Add brackets around regex to include matches.
@ -368,6 +368,7 @@ import re
* **Argument `'flags=re.DOTALL'` makes `'.'` also accept the `'\n'`.**
* **Argument `'flags=re.DOTALL'` makes `'.'` also accept the `'\n'`.**
* **Use `r'\1'` or `'\\1'` for backreference (`'\1'` returns a character with octal code 1).**
* **Use `r'\1'` or `'\\1'` for backreference (`'\1'` returns a character with octal code 1).**
* **Add `'?'` after `'*'` and `'+'` to make them non-greedy.**
* **Add `'?'` after `'*'` and `'+'` to make them non-greedy.**
* **`'re.compile(<regex>)'` returns a Pattern object with listed methods.**
### Match Object
### Match Object
```python
```python
@ -589,7 +590,7 @@ Datetime
**Provides 'date', 'time', 'datetime' and 'timedelta' classes. All are immutable and hashable.**
**Provides 'date', 'time', 'datetime' and 'timedelta' classes. All are immutable and hashable.**
```python
```python
# pip3 install python-dateutil
# $ pip3 install python-dateutil
from datetime import date, time, datetime, timedelta, timezone
from datetime import date, time, datetime, timedelta, timezone
* **New() is a class method that gets called before init(). If it returns an instance of its class, then that instance gets passed to init() as a 'self' argument.**
* **It receives the same arguments as init(), except for the first one that specifies the desired type of the returned instance (MyMetaClass in our case).**
* **Like in our case, new() can also be called directly, usually from a new() method of a child class (**`def __new__(cls): return super().__new__(cls)`**).**
* **The only difference between the examples above is that my\_meta\_class() returns a class of type type, while MyMetaClass() returns a class of type MyMetaClass.**
### Metaclass Attribute
**Right before a class is created it checks if it has the 'metaclass' attribute defined. If not, it recursively checks if any of its parents has it defined and eventually comes to type().**
Logging
-------
```python
```python
class MyClass(metaclass=MyMetaClass):
b = 12345
import logging
```
```
```python
```python
>>> MyClass.a, MyClass.b
('abcde', 12345)
logging.basicConfig(filename=<path>, level='DEBUG') # Configures the root logger (see Setup).
logging.debug/info/warning/error/critical(<str>) # Logs to the root logger.
<Logger> = logging.getLogger(__name__) # Logger named after the module.
<Logger>.<level>(<str>) # Logs to the logger.
<Logger>.exception(<str>) # Calls error() with caught exception.
```
```
### Type Diagram
### Setup
```python
```python
type(MyClass) == MyMetaClass # MyClass is an instance of MyMetaClass.
type(MyMetaClass) == type # MyMetaClass is an instance of type.
```
```text
+-------------+-------------+
| Classes | Metaclasses |
+-------------+-------------|
| MyClass <--MyMetaClass|
| | ^ |
| object <-----type<+|
| | | +--+ |
| str <---------+|
+-------------+-------------+
logging.basicConfig(
filename=None, # Logs to console (stderr) by default.
format='%(levelname)s:%(name)s:%(message)s', # Add '%(asctime)s' for local datetime.
level=logging.WARNING, # Drops messages with lower priority.
handlers=[logging.StreamHandler(sys.stderr)] # Uses FileHandler if filename is set.
)
```
```
### Inheritance Diagram
```python
```python
MyClass.__base__ == object # MyClass is a subclass of object.
MyMetaClass.__base__ == type # MyMetaClass is a subclass of type.
```
```text
+-------------+-------------+
| Classes | Metaclasses |
+-------------+-------------|
| MyClass | MyMetaClass |
| ^ | ^ |
| object -----> type |
| v | |
| str | |
+-------------+-------------+
<Formatter> = logging.Formatter('<format>') # Creates a Formatter.
<Handler> = logging.FileHandler(<path>, mode='a') # Creates a Handler. Also `encoding=None`.
<Handler>.setFormatter(<Formatter>) # Adds Formatter to the Handler.
<Handler>.setLevel(<int/str>) # Processes all messages by default.
<Logger>.addHandler(<Handler>) # Adds Handler to the Logger.
<Logger>.setLevel(<int/str>) # What is sent to its/ancestor's handlers.
```
```
* **Parent logger can be specified by naming the child logger `'<parent>.<name>'`.**
* **If logger doesn't have a set level it inherits it from the first ancestor that does.**
* **Formatter also accepts: pathname, filename, funcName, lineno, thread and process.**
* **A `'handlers.RotatingFileHandler'` creates and deletes log files based on 'maxBytes' and 'backupCount' arguments.**
Eval
----
#### Creates a logger that writes all messages to file and sends them to the root's handler that prints warnings or higher:
<li><strong>Use <codeclass="python hljs"><spanclass="hljs-string">'unicodedata.normalize("NFC", <str>)'</span></code> on strings that may contain characters like <codeclass="python hljs"><spanclass="hljs-string">'Ö'</span></code> before comparing them, because they can be stored as one or two characters.</strong></li>
<li><strong>Use <codeclass="python hljs"><spanclass="hljs-string">'unicodedata.normalize("NFC", <str>)'</span></code> on strings that may contain characters like <codeclass="python hljs"><spanclass="hljs-string">'Ö'</span></code> before comparing them, because they can be stored as one or two characters.</strong></li>
<li><strong><codeclass="python hljs"><spanclass="hljs-string">'NFC'</span></code> converts such characters to a single character, while <codeclass="python hljs"><spanclass="hljs-string">'NFD'</span></code> converts them to two.</strong></li>
</ul>
</ul>
<div><h3id="propertymethods">Property Methods</h3><pre><codeclass="python language-python hljs"><bool> = <str>.isdecimal() <spanclass="hljs-comment"># Checks for [0-9].</span>
<div><h3id="propertymethods">Property Methods</h3><pre><codeclass="python language-python hljs"><bool> = <str>.isdecimal() <spanclass="hljs-comment"># Checks for [0-9].</span>
<bool> = <str>.isdigit() <spanclass="hljs-comment"># Checks for [²³¹] and isdecimal().</span>
<bool> = <str>.isdigit() <spanclass="hljs-comment"># Checks for [²³¹] and isdecimal().</span>
<div><h2id="regex"><ahref="#regex"name="regex">#</a>Regex</h2><p><strong>Functions for regular expression matching.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">import</span> re
<div><h2id="regex"><ahref="#regex"name="regex">#</a>Regex</h2><p><strong>Functions for regular expression matching.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">import</span> re
</code></pre></div>
<pre><codeclass="python language-python hljs"><str> = re.sub(<regex>, new, text, count=<spanclass="hljs-number">0</span>) <spanclass="hljs-comment"># Substitutes all occurrences with 'new'.</span>
<str> = re.sub(<regex>, new, text, count=<spanclass="hljs-number">0</span>) <spanclass="hljs-comment"># Substitutes all occurrences with 'new'.</span>
<list> = re.findall(<regex>, text) <spanclass="hljs-comment"># Returns all occurrences as strings.</span>
<list> = re.findall(<regex>, text) <spanclass="hljs-comment"># Returns all occurrences as strings.</span>
<list> = re.split(<regex>, text, maxsplit=<spanclass="hljs-number">0</span>) <spanclass="hljs-comment"># Add brackets around regex to include matches.</span>
<list> = re.split(<regex>, text, maxsplit=<spanclass="hljs-number">0</span>) <spanclass="hljs-comment"># Add brackets around regex to include matches.</span>
<Match> = re.search(<regex>, text) <spanclass="hljs-comment"># First occurrence of the pattern or None.</span>
<Match> = re.search(<regex>, text) <spanclass="hljs-comment"># First occurrence of the pattern or None.</span>
<Match> = re.match(<regex>, text) <spanclass="hljs-comment"># Searches only at the beginning of the text.</span>
<Match> = re.match(<regex>, text) <spanclass="hljs-comment"># Searches only at the beginning of the text.</span>
<iter> = re.finditer(<regex>, text) <spanclass="hljs-comment"># Returns all occurrences as Match objects.</span>
<iter> = re.finditer(<regex>, text) <spanclass="hljs-comment"># Returns all occurrences as Match objects.</span>
</code></pre>
</code></pre></div>
<ul>
<ul>
<li><strong>Argument 'new' can be a function that accepts a Match object and returns a string.</strong></li>
<li><strong>Argument 'new' can be a function that accepts a Match object and returns a string.</strong></li>
<li><strong>Argument <codeclass="python hljs"><spanclass="hljs-string">'flags=re.IGNORECASE'</span></code> can be used with all functions.</strong></li>
<li><strong>Argument <codeclass="python hljs"><spanclass="hljs-string">'flags=re.IGNORECASE'</span></code> can be used with all functions.</strong></li>
<li><strong>Argument <codeclass="python hljs"><spanclass="hljs-string">'flags=re.DOTALL'</span></code> makes <codeclass="python hljs"><spanclass="hljs-string">'.'</span></code> also accept the <codeclass="python hljs"><spanclass="hljs-string">'\n'</span></code>.</strong></li>
<li><strong>Argument <codeclass="python hljs"><spanclass="hljs-string">'flags=re.DOTALL'</span></code> makes <codeclass="python hljs"><spanclass="hljs-string">'.'</span></code> also accept the <codeclass="python hljs"><spanclass="hljs-string">'\n'</span></code>.</strong></li>
<li><strong>Use <codeclass="python hljs"><spanclass="hljs-string">r'\1'</span></code> or <codeclass="python hljs"><spanclass="hljs-string">'\\1'</span></code> for backreference (<codeclass="python hljs"><spanclass="hljs-string">'\1'</span></code> returns a character with octal code 1).</strong></li>
<li><strong>Use <codeclass="python hljs"><spanclass="hljs-string">r'\1'</span></code> or <codeclass="python hljs"><spanclass="hljs-string">'\\1'</span></code> for backreference (<codeclass="python hljs"><spanclass="hljs-string">'\1'</span></code> returns a character with octal code 1).</strong></li>
<li><strong>Add <codeclass="python hljs"><spanclass="hljs-string">'?'</span></code> after <codeclass="python hljs"><spanclass="hljs-string">'*'</span></code> and <codeclass="python hljs"><spanclass="hljs-string">'+'</span></code> to make them non-greedy.</strong></li>
<li><strong>Add <codeclass="python hljs"><spanclass="hljs-string">'?'</span></code> after <codeclass="python hljs"><spanclass="hljs-string">'*'</span></code> and <codeclass="python hljs"><spanclass="hljs-string">'+'</span></code> to make them non-greedy.</strong></li>
<li><strong><codeclass="python hljs"><spanclass="hljs-string">'re.compile(<regex>)'</span></code> returns a Pattern object with listed methods.</strong></li>
</ul>
</ul>
<div><h3id="matchobject">Match Object</h3><pre><codeclass="python language-python hljs"><str> = <Match>.group() <spanclass="hljs-comment"># Returns the whole match. Also group(0).</span>
<div><h3id="matchobject">Match Object</h3><pre><codeclass="python language-python hljs"><str> = <Match>.group() <spanclass="hljs-comment"># Returns the whole match. Also group(0).</span>
<str> = <Match>.group(<spanclass="hljs-number">1</span>) <spanclass="hljs-comment"># Returns the part inside first brackets.</span>
<str> = <Match>.group(<spanclass="hljs-number">1</span>) <spanclass="hljs-comment"># Returns the part inside first brackets.</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">'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>
(<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>
</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>
<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
<spanclass="hljs-keyword">from</span> datetime <spanclass="hljs-keyword">import</span> date, time, datetime, timedelta, timezone
<li><strong>Bitwise operators require objects to have or(), xor(), and(), lshift(), rshift() and invert() special methods, unlike logical operators that work on all types of objects.</strong></li>
<li><strong>Bitwise operators require objects to have or(), xor(), and(), lshift(), rshift() and invert() special methods, unlike logical operators that work on all types of objects.</strong></li>
<div><h2id="matchstatement"><ahref="#matchstatement"name="matchstatement">#</a>Match Statement</h2><p><strong>Executes the first block with matching pattern. Added in Python 3.10.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">match</span><object/expression>:
<div><h3id="patterns">Patterns</h3><pre><codeclass="python language-python hljs"><value_pattern> = <spanclass="hljs-number">1</span>/<spanclass="hljs-string">'abc'</span>/<spanclass="hljs-keyword">True</span>/<spanclass="hljs-keyword">None</span>/math.pi <spanclass="hljs-comment"># Matches the literal or a dotted name.</span>
<class_pattern> = <type>() <spanclass="hljs-comment"># Matches any object of that type.</span>
<capture_patt> = <name><spanclass="hljs-comment"># Matches any object and binds it to name.</span>
<or_pattern> = <pattern> | <pattern> [| ...] <spanclass="hljs-comment"># Matches any of the patterns.</span>
<as_pattern> = <pattern><spanclass="hljs-keyword">as</span><name><spanclass="hljs-comment"># Binds the match to the name.</span>
<sequence_patt> = [<pattern>, ...] <spanclass="hljs-comment"># Matches sequence with matching items.</span>
<class_pattern> = <type>(<attr_name>=<patt>, ...) <spanclass="hljs-comment"># Matches object with matching attributes.</span>
</code></pre></div>
<ul>
<li><strong>Sequence pattern can also be written as a tuple.</strong></li>
<li><strong>Use <codeclass="python hljs"><spanclass="hljs-string">'*<name>'</span></code> and <codeclass="python hljs"><spanclass="hljs-string">'**<name>'</span></code> in sequence/mapping patterns to bind remaining items.</strong></li>
<li><strong>Patterns can be surrounded with brackets to override precedence (<codeclass="python hljs"><spanclass="hljs-string">'|'</span></code>><codeclass="python hljs"><spanclass="hljs-string">'as'</span></code>><codeclass="python hljs"><spanclass="hljs-string">','</span></code>).</strong></li>
<li><strong>Built-in types allow a single positional pattern that is matched against the entire object.</strong></li>
<li><strong>All names that are bound in the matching case, as well as variables initialized in its block, are visible after the match statement.</strong></li>
<spanclass="hljs-meta">... </span> print(<spanclass="hljs-string">f'<spanclass="hljs-subst">{stem}</span><spanclass="hljs-subst">{suffix}</span> is a readme file that belongs to user <spanclass="hljs-subst">{user}</span>.'</span>)
<spanclass="hljs-string">'README.md is a readme file that belongs to user gto.'</span>
</code></pre></div>
<div><h2id="introspection"><ahref="#introspection"name="introspection">#</a>Introspection</h2><pre><codeclass="python language-python hljs"><list> = dir() <spanclass="hljs-comment"># Names of local variables, functions, classes, etc.</span>
<div><h2id="introspection"><ahref="#introspection"name="introspection">#</a>Introspection</h2><pre><codeclass="python language-python hljs"><list> = dir() <spanclass="hljs-comment"># Names of local variables, functions, classes, etc.</span>
<dict> = vars() <spanclass="hljs-comment"># Dict of local variables, etc. Also locals().</span>
<dict> = vars() <spanclass="hljs-comment"># Dict of local variables, etc. Also locals().</span>
<dict> = globals() <spanclass="hljs-comment"># Dict of global vars, etc. (incl. '__builtins__').</span>
<dict> = globals() <spanclass="hljs-comment"># Dict of global vars, etc. (incl. '__builtins__').</span>
<dict> = vars(<object>) <spanclass="hljs-comment"># Dict of writable attributes. Also <obj>.__dict__.</span>
<dict> = vars(<object>) <spanclass="hljs-comment"># Dict of writable attributes. Also <obj>.__dict__.</span>
<bool> = hasattr(<object>, <spanclass="hljs-string">'<attr_name>'</span>) <spanclass="hljs-comment"># Checks if getattr() raises an AttributeError.</span>
<bool> = hasattr(<object>, <spanclass="hljs-string">'<attr_name>'</span>) <spanclass="hljs-comment"># Checks if getattr() raises an AttributeError.</span>
value = getattr(<object>, <spanclass="hljs-string">'<attr_name>'</span>) <spanclass="hljs-comment"># Raises AttributeError if attribute is missing.</span>
value = getattr(<object>, <spanclass="hljs-string">'<attr_name>'</span>) <spanclass="hljs-comment"># Raises AttributeError if attribute is missing.</span>
setattr(<object>, <spanclass="hljs-string">'<attr_name>'</span>, value) <spanclass="hljs-comment"># Only works on objects with '__dict__' attribute.</span>
setattr(<object>, <spanclass="hljs-string">'<attr_name>'</span>, value) <spanclass="hljs-comment"># Only works on objects with '__dict__' attribute.</span>
delattr(<object>, <spanclass="hljs-string">'<attr_name>'</span>) <spanclass="hljs-comment"># Same. Also `del <object>.<attr_name>`.</span>
delattr(<object>, <spanclass="hljs-string">'<attr_name>'</span>) <spanclass="hljs-comment"># Same. Also `del <object>.<attr_name>`.</span>
<dict> = <Sig>.parameters <spanclass="hljs-comment"># Dict of Parameter objects.</span>
<dict> = <Sig>.parameters <spanclass="hljs-comment"># Dict of Parameter objects.</span>
<memb> = <Param>.kind <spanclass="hljs-comment"># Member of ParameterKind enum.</span>
<memb> = <Param>.kind <spanclass="hljs-comment"># Member of ParameterKind enum.</span>
<obj> = <Param>.default <spanclass="hljs-comment"># Default value or Parameter.empty.</span>
<obj> = <Param>.default <spanclass="hljs-comment"># Default value or Parameter.empty.</span>
<type> = <Param>.annotation <spanclass="hljs-comment"># Type or Parameter.empty.</span>
<type> = <Param>.annotation <spanclass="hljs-comment"># Type or Parameter.empty.</span>
</code></pre></div>
<div><h2id="metaprogramming"><ahref="#metaprogramming"name="metaprogramming">#</a>Metaprogramming</h2><p><strong>Code that generates code.</strong></p><div><h3id="type-1">Type</h3><p><strong>Type is the root class. If only passed an object it returns its type (class). Otherwise it creates a new class.</strong></p><pre><codeclass="python language-python hljs"><class> = type(<spanclass="hljs-string">'<class_name>'</span>, <tuple_of_parents>, <dict_of_class_attributes>)</code></pre></div></div>
<div><h3id="metaclass">Meta Class</h3><p><strong>A class that creates classes.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-function"><spanclass="hljs-keyword">def</span><spanclass="hljs-title">my_meta_class</span><spanclass="hljs-params">(name, parents, attrs)</span>:</span>
<li><strong>New() is a class method that gets called before init(). If it returns an instance of its class, then that instance gets passed to init() as a 'self' argument.</strong></li>
<li><strong>It receives the same arguments as init(), except for the first one that specifies the desired type of the returned instance (MyMetaClass in our case).</strong></li>
<li><strong>Like in our case, new() can also be called directly, usually from a new() method of a child class (</strong><codeclass="python hljs"><spanclass="hljs-function"><spanclass="hljs-keyword">def</span><spanclass="hljs-title">__new__</span><spanclass="hljs-params">(cls)</span>:</span><spanclass="hljs-keyword">return</span> super().__new__(cls)</code><strong>).</strong></li>
<li><strong>The only difference between the examples above is that my_meta_class() returns a class of type type, while MyMetaClass() returns a class of type MyMetaClass.</strong></li>
</ul>
<div><h3id="metaclassattribute">Metaclass Attribute</h3><p><strong>Right before a class is created it checks if it has the 'metaclass' attribute defined. If not, it recursively checks if any of its parents has it defined and eventually comes to type().</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-class"><spanclass="hljs-keyword">class</span><spanclass="hljs-title">MyClass</span><spanclass="hljs-params">(metaclass=MyMetaClass)</span>:</span>
<div><h3id="typediagram">Type Diagram</h3><pre><codeclass="python language-python hljs">type(MyClass) == MyMetaClass <spanclass="hljs-comment"># MyClass is an instance of MyMetaClass.</span>
type(MyMetaClass) == type <spanclass="hljs-comment"># MyMetaClass is an instance of type.</span>
<pre><codeclass="python language-python hljs">logging.basicConfig(filename=<path>, level=<spanclass="hljs-string">'DEBUG'</span>) <spanclass="hljs-comment"># Configures the root logger (see Setup).</span>
logging.debug/info/warning/error/critical(<str>) <spanclass="hljs-comment"># Logs to the root logger.</span>
<Logger> = logging.getLogger(__name__) <spanclass="hljs-comment"># Logger named after the module.</span>
<Logger>.<level>(<str>) <spanclass="hljs-comment"># Logs to the logger.</span>
<Logger>.exception(<str>) <spanclass="hljs-comment"># Calls error() with caught exception.</span>
</code></pre>
</code></pre>
<div><h3id="inheritancediagram">Inheritance Diagram</h3><pre><codeclass="python language-python hljs">MyClass.__base__ == object <spanclass="hljs-comment"># MyClass is a subclass of object.</span>
MyMetaClass.__base__ == type <spanclass="hljs-comment"># MyMetaClass is a subclass of type.</span>
<pre><codeclass="python language-python hljs"><Formatter> = logging.Formatter(<spanclass="hljs-string">'<format>'</span>) <spanclass="hljs-comment"># Creates a Formatter.</span>
<Handler> = logging.FileHandler(<path>, mode=<spanclass="hljs-string">'a'</span>) <spanclass="hljs-comment"># Creates a Handler. Also `encoding=None`.</span>
<Handler>.setFormatter(<Formatter>) <spanclass="hljs-comment"># Adds Formatter to the Handler.</span>
<Handler>.setLevel(<int/str>) <spanclass="hljs-comment"># Processes all messages by default.</span>
<Logger>.addHandler(<Handler>) <spanclass="hljs-comment"># Adds Handler to the Logger.</span>
<Logger>.setLevel(<int/str>) <spanclass="hljs-comment"># What is sent to its/ancestor's handlers.</span>
<li><strong>Parent logger can be specified by naming the child logger <codeclass="python hljs"><spanclass="hljs-string">'<parent>.<name>'</span></code>.</strong></li>
<li><strong>If logger doesn't have a set level it inherits it from the first ancestor that does.</strong></li>
<li><strong>Formatter also accepts: pathname, filename, funcName, lineno, thread and process.</strong></li>
<li><strong>A <codeclass="python hljs"><spanclass="hljs-string">'handlers.RotatingFileHandler'</span></code> creates and deletes log files based on 'maxBytes' and 'backupCount' arguments.</strong></li>
</ul>
<div><h4id="createsaloggerthatwritesallmessagestofileandsendsthemtotherootshandlerthatprintswarningsorhigher">Creates a logger that writes all messages to file and sends them to the root's handler that prints warnings or higher:</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-meta">>>></span>logger = logging.getLogger(<spanclass="hljs-string">'my_module'</span>)
@ -1894,7 +1901,7 @@ ValueError: malformed node or string
<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><codeclass="python hljs"><spanclass="hljs-string">'asyncio.run(<coroutine>)'</span></code> is the main entry point for asynchronous programs.</strong></li>
<li><strong>Functions wait(), gather() and as_completed() start multiple coroutines at the same time.</strong></li>
<li><strong>Functions wait(), gather() and as_completed() start multiple coroutines at the same time.</strong></li>
<li><strong>Asyncio module also provides its own <ahref="#queue">Queue</a>, <ahref="#semaphoreeventbarrier">Event</a>, <ahref="#lock">Lock</a> and <ahref="#semaphoreeventbarrier">Semaphore</a> classes.</strong></li>
<li><strong>Asyncio module also provides its own <ahref="#queue">Queue</a>, <ahref="#semaphoreeventbarrier">Event</a>, <ahref="#lock">Lock</a> and <ahref="#semaphoreeventbarrier">Semaphore</a> classes.</strong></li>
</ul><div><h4id="runsaterminalgamewhereyoucontrolanasteriskthatmustavoidnumbers">Runs 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, curses.textpad, enum, random
</ul><div><h4id="runsaterminalgamewhereyoucontrolanasteriskthatmustavoidnumbers">Runs 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, curses.textpad, enum, random, time
P = collections.namedtuple(<spanclass="hljs-string">'P'</span>, <spanclass="hljs-string">'x y'</span>) <spanclass="hljs-comment"># Position</span>
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>
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="runsabasicfileexplorerintheconsole">Runs a basic file explorer in the console:</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-comment"># pip3 install windows-curses</span>
<div><h2id="curses"><ahref="#curses"name="curses">#</a>Curses</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
<spanclass="hljs-keyword">import</span> curses, os
unit = values[<spanclass="hljs-string">'-UNIT-'</span>]
units = {<spanclass="hljs-string">'g'</span>: <spanclass="hljs-number">0.001</span>, <spanclass="hljs-string">'kg'</span>: <spanclass="hljs-number">1</span>, <spanclass="hljs-string">'t'</span>: <spanclass="hljs-number">1000</span>}
lbs = value * units[unit] / <spanclass="hljs-number">0.45359237</span>
window[<spanclass="hljs-string">'-OUTPUT-'</span>].update(value=<spanclass="hljs-string">f'<spanclass="hljs-subst">{value}</span><spanclass="hljs-subst">{unit}</span> is <spanclass="hljs-subst">{lbs:g}</span> lbs.'</span>)
window.close()
</code></pre></div></div>
<pre><codeclass="python language-python hljs"><Formatter> = logging.Formatter(<spanclass="hljs-string">'<format>'</span>) <spanclass="hljs-comment"># Creates a Formatter.</span>
<Handler> = logging.FileHandler(<path>, mode=<spanclass="hljs-string">'a'</span>) <spanclass="hljs-comment"># Creates a Handler. Also `encoding=None`.</span>
<Handler>.setFormatter(<Formatter>) <spanclass="hljs-comment"># Adds Formatter to the Handler.</span>
<Handler>.setLevel(<int/str>) <spanclass="hljs-comment"># Processes all messages by default.</span>
<Logger>.addHandler(<Handler>) <spanclass="hljs-comment"># Adds Handler to the Logger.</span>
<Logger>.setLevel(<int/str>) <spanclass="hljs-comment"># What is sent to its/ancestor's handlers.</span>
</code></pre>
<ul>
<li><strong>Parent logger can be specified by naming the child logger <codeclass="python hljs"><spanclass="hljs-string">'<parent>.<name>'</span></code>.</strong></li>
<li><strong>If logger doesn't have a set level it inherits it from the first ancestor that does.</strong></li>
<li><strong>Formatter also accepts: pathname, filename, funcName, lineno, thread and process.</strong></li>
<li><strong>A <codeclass="python hljs"><spanclass="hljs-string">'handlers.RotatingFileHandler'</span></code> creates and deletes log files based on 'maxBytes' and 'backupCount' arguments.</strong></li>
</ul>
<div><h4id="createsaloggerthatwritesallmessagestofileandsendsthemtotherootshandlerthatprintswarningsorhigher">Creates a logger that writes all messages to file and sends them to the root's handler that prints warnings or higher:</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-meta">>>></span>logger = logging.getLogger(<spanclass="hljs-string">'my_module'</span>)
2023-02-07 23:21:01,430 CRITICAL:my_module:Running out of disk space.
</code></pre></div>
<div><h2id="scraping"><ahref="#scraping"name="scraping">#</a>Scraping</h2><div><h4id="scrapespythonsurlandlogofromitswikipediapage">Scrapes Python's URL and logo from its Wikipedia page:</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-comment"># $ pip3 install requests beautifulsoup4</span>
<div><h2id="scraping"><ahref="#scraping"name="scraping">#</a>Scraping</h2><div><h4id="scrapespythonsurlandlogofromitswikipediapage">Scrapes Python's URL and logo from its Wikipedia page:</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-comment"># $ pip3 install requests beautifulsoup4</span>
<condition> = [<sub_cond> [<spanclass="hljs-keyword">and</span>/<spanclass="hljs-keyword">or</span><sub_cond>]] <spanclass="hljs-comment"># `and` is same as chaining conditions.</span>
<sub_cond> = contains(@<attr>, <spanclass="hljs-string">"<val>"</span>) <spanclass="hljs-comment"># Is <val> a substring of attr's value?</span>
<sub_cond> = [//]<element><spanclass="hljs-comment"># Has matching child? Descendant if //.</span>
</code></pre></div>
<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>
<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>
<spanclass="hljs-keyword">import</span> flask
<spanclass="hljs-keyword">import</span> flask
</code></pre></div>
</code></pre></div>
@ -2219,7 +2233,7 @@ right = [[<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</
<div><h3id="example-2">Example</h3><div><h4id="foreachpointreturnsindexofitsnearestpoint010608121">For each point returns index of its nearest point (<codeclass="python hljs">[<spanclass="hljs-number">0.1</span>, <spanclass="hljs-number">0.6</span>, <spanclass="hljs-number">0.8</span>] => [<spanclass="hljs-number">1</span>, <spanclass="hljs-number">2</span>, <spanclass="hljs-number">1</span>]</code>):</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-meta">>>></span>points = np.array([<spanclass="hljs-number">0.1</span>, <spanclass="hljs-number">0.6</span>, <spanclass="hljs-number">0.8</span>])
<div><h3id="example-3">Example</h3><div><h4id="foreachpointreturnsindexofitsnearestpoint010608121">For each point returns index of its nearest point (<codeclass="python hljs">[<spanclass="hljs-number">0.1</span>, <spanclass="hljs-number">0.6</span>, <spanclass="hljs-number">0.8</span>] => [<spanclass="hljs-number">1</span>, <spanclass="hljs-number">2</span>, <spanclass="hljs-number">1</span>]</code>):</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-meta">>>></span>points = np.array([<spanclass="hljs-number">0.1</span>, <spanclass="hljs-number">0.6</span>, <spanclass="hljs-number">0.8</span>])
<pre><codeclass="python language-python hljs"><array> = np.array(<Image>) <spanclass="hljs-comment"># Creates a NumPy array from the image.</span>
<Image> = Image.fromarray(np.uint8(<array>)) <spanclass="hljs-comment"># Use <array>.clip(0, 255) to clip values.</span>
<pre><codeclass="python language-python hljs"><array> = np.array(<Image>) <spanclass="hljs-comment"># Creates a 2d/3d NumPy array from the image.</span>
<Image> = Image.fromarray(np.uint8(<array>)) <spanclass="hljs-comment"># Use `<array>.clip(0, 255)` to clip values.</span>
'<span class="hljs-meta">... </span> print(<span class="hljs-string">f\'<span class="hljs-subst">{stem}</span><span class="hljs-subst">{suffix}</span> is a readme file that belongs to user <span class="hljs-subst">{user}</span>.\'</span>)\n'+
'<span class="hljs-string">\'README.md is a readme file that belongs to user gto.\'</span>\n';