ToC =3D {
+ '1. Col=
+lections': [List, Dictionary, Set, Tuple, Range, Enumerate, Iterator, Generator],
+ '2. Typ=
+es': [Type, String, Regular_Exp, Format, Numbers, Combinatorics, Datetime],
+ '3. Syn=
+tax': [Args, Inline, Import, Decorator, Class, Duck_Types, Enum, Exception],
+ '4. Sys=
+tem': [Exit, Print, Input, Command_Line_Arguments, Open, Path, OS_Commands],
+ '5. Dat=
+a': [JSON, Pickle, CSV, SQLite, Bytes, Struct, Array, Memory_View, Deque],
+ '6. Adv=
+anced': [Threading, Operator, Introspection, Metaprograming, Eval, Coroutine],
+ '7. Lib=
+raries': [Progress_Bar, Plot, Table, Curses, Logging, Scraping, Web, Profile,
+ NumPy, Image, Audio, Games, D=
+ata]
+}
+
if __name__ =3D=3D '__main__': # Runs=
+ main() if file wasn't imported.
+ main()
+
<list> =3D <list>[<slice>] # Or: <list>[from_inclusive : to_exclusive : =C2=B1step]=
+
+
<list>.append(<el=
+>) # Or: <list> +=3D [<=
+el>]
+<list>.extend(<collection>) # O=
+r: <list> +=3D <collection>
+
+<list>.sort() =
+ # Sorts in ascending order.
+<list>.reverse() # Reverse=
+s the list in-place.
+<list> =3D sorted(<collection>) #=
+ Returns a new sorted list.
+<iter> =3D reversed(<list>) #=
+ Returns reversed iterator.
+
+sum_of_elements =3D sum(&=
+lt;collection>)
+elementwise_sum =3D [sum(pair) for pai=
+r in zip(list_a, list_b)]
+sorted_by_second =3D sorted(<collection>, key=3Dlambda el: el[1])
+sorted_by_both =3D sorted(<collection>, key=3Dlambda el: (el[1], el[0]))
+flatter_list =3D list(itertools.chain.from_iterable(<list>))
+product_of_elems =3D functools.reduce(lambda=
+span> out, el: out * el, <collection>)
+list_of_chars =3D list(<str>)
+
+<list>.insert(<in=
+t>, <el>) # Inserts item at index=
+ and moves the rest to the right.
+<el> =3D <list>.pop([<int>]) # Removes and returns item at index or from the end.
+<int> =3D <list>.count(<el>) # Returns number of occurrences. Also works on strings.
+<int> =3D <list>.index(<el>) # Returns index of the first occurrence or raises ValueError.
+<list>.remove(<el>) # R=
+emoves first occurrence of the item or raises ValueError.
+<list>.clear() # Removes=
+ all items. Also works on dictionary and set.
+
+<view> =3D <dict>.keys() =
+ # Coll. of keys that refle=
+cts changes.
+<view> =3D <dict>.values() # Coll. of values that reflects changes.
+<view> =3D <dict>.items() # Coll. of key-value tuples that reflects chgs.
+
value =3D <dict>.ge=
+t(key, default=3DNone) # Returns default if key is missing.
+value =3D <dict>.setdefault(key, default=3DNone) # Returns and writes defaul=
+t if key is missing.
+<dict> =3D collections.defaultdict(<type>) # Returns a dict with default value of type.
+<dict> =3D collections.defaultdict(lambd=
+a: 1) # Returns a dict with default value 1.
+
+<dict> =3D dict(<=
+collection>) # Creates =
+a dict from coll. of key-value pairs.
+<dict> =3D dict(zip(keys, values)) # Creates a dict from two collections.
+<dict> =3D dict.fromkeys(keys [, value]) # Creates a dict from collection of keys.
+
+<dict>.update(<di=
+ct>) # Adds items=
+. Replaces ones with matching keys.
+value =3D <dict>.pop(key) # Removes item or raises KeyError.
+{k for k, v in <dict>.items() if v =
+=3D=3D value} # Returns set of keys that po=
+int to the value.
+{k: v for k, v in <dict>.items() if =
+k in keys} # Returns a dictionary, filtered by keys.
+
+from collections import Counter
+ colors =3D ['blue', 'blue', 'blue', 'red', 'red']
+ counter =3D Counter(colors)
+ counter['yellow'] +=3D 1
+Counter({'blue': 3, 'red': 2, 'yellow': 1})
+ counter.most_common()[0]
+('blue', 3=
+span>)
+
<set> =3D set() # `{}` returns a dictionary.
+
<set>.add(<el>=
+) # Or: <se=
+t> |=3D {<el>}
+<set>.update(<collection> [, ...]) # Or: <set> |=3D <set>
+
+<set> =3D <set&g=
+t;.union(<coll.>) # Or=
+: <set> | <set>
+<set> =3D <set>.intersection(<coll.>) # Or: <set> & <set>
+<set> =3D <set>.difference(<coll.>) # Or: <set> - <set>
+<set> =3D <set>.symmetric_difference(<coll.>) # Or: <set> ^ <set>
+<bool> =3D <set>.issubset(<coll.>) # Or: <set> <=3D <set>
+<bool> =3D <set>.issuperset(<coll.>) # Or: <set> >=3D <set>
+
+<el> =3D <set>=
+.pop() # Raises K=
+eyError if empty.
+<set>.remove(<el>) # Raises KeyError if missing.
+<set>.discard(<el>) # Doesn't raise an error.
+
+<frozenset> =3D=
+ frozenset(<collection>)
+
Tuple is an immutable and = +hashable list.
<tuple> =3D () # Empty tuple.
+<tuple> =3D (<el>,) # Or: <el>,
+<tuple> =3D (<el_1>, <el_2> [, ...]) # Or: <el_1>, <el_2> [, ...]
+
Tuple's subclass with= + named elements.
from collections import named=
+tuple
+ Point =3D namedtuple('Point', 'x y')
+ p =3D Point(1, y=3D2)
+Point(x=3D1, y=3D2)
+ p[0]
+1
+ p.x
+1
+ getattr(p, 'y')
+2
+
Immutable and hashable seq= +uence of integers.
<range> =3D range(stop) # range(to_exclusive)
+<range> =3D range(start, stop) # range(from_inclusive, to_exclusive)
+<range> =3D range(start, stop, =C2=B1step) # range(from_inclusive, to_exclusive, =C2=B1step_size)
+
for i in range(3)]
+[0, 1=
+, 2]
+
[i
+for i, el <=
+span class=3D"hljs-keyword">in enumerate(<collection> [, i_sta=
+rt]):
+ ...
+
<iter> =3D iter(<collection>) =
+ # `iter(<iter>)` returns unmodifi=
+ed iterator.
+<iter> =3D iter(<function>, to_exclusive) # A sequence of return values until 'to_exclusive'.
+<el> =3D next(<iter> [, default]) # Raises StopIteration or returns 'default' on end.
+<list> =3D list(<iter>) # Returns a list of iterator's remaining elements.
+
import itertools as it
+
<iter> =3D it.count(=
+start=3D0, step=3D1) # Returns updated val=
+ue endlessly. Accepts floats.
+<iter> =3D it.repeat(<el> [, times]) # Returns element endlessly or 'times' times.
+<iter> =3D it.cycle(<collection>) # Repeats the sequence endlessly.
+
+<iter> =3D it.chain(=
+<coll>, <coll> [, ...]) # Emptie=
+s collections in order (figuratively).
+<iter> =3D it.chain.from_iterable(<coll>) # Empties collections inside a collection in order.
+
+<iter> =3D it.islice=
+(<coll>, to_exclusive) # Only returns=
+ first 'to_exclusive' elements.
+<iter> =3D it.islice(<coll>, from_inc, =E2=80=A6) # `to_exclusive, +step_size`. Indices can be None.
+
+def count(start, step):
+ while =
+True:
+ yield start
+ start +=3D step
+
10=
+, 2)
+ next(counter), next(counter),=
+ next(counter)
+(10, 12, 14)
+
counter =3D count(
+<type> =3D type=
+(<el>) # Or: &l=
+t;el>.__class__
+<bool> =3D isinstance(<el>, <type>) # Or: issubclass(type(<el>), <type>)
+
'a'), 'a'.__class__, str
+(<class 'str'>, <cl=
+ass 'str'>, <class 'str'>)
+
type(
+from=
+ types import FunctionType, MethodType,=
+ LambdaType, GeneratorType, ModuleType
+
Ea= +ch abstract base class specifies a set of virtual subclasses. These classes= + are then recognized by isinstance() and issubclass() as subclasses of the = +ABC, although they are really not. ABC can also manually decide whether or = +not a specific class is its virtual subclass, usually based on which method= +s the class has implemented. For instance, Iterable ABC looks for method it= +er(), while Collection ABC looks for iter(), contains() and len().= +
>>> from collection=
+s.abc import Iterable, Collection, Sequ=
+ence
+ isinstance([1, 2, 3], Iterable)
+True
+
=E2=94=8F=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 Iterable =E2=94=82 Collection =E2=94=
+=82 Sequence =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=A8
+=E2=94=83 list, range, str =E2=94=82 =E2=9C=93 =E2=94=82 =E2=
+=9C=93 =E2=94=82 =E2=9C=93 =E2=94=83
+=E2=94=83 dict, set =E2=94=82 =E2=9C=93 =E2=94=82 =E2=
+=9C=93 =E2=94=82 =E2=94=83
+=E2=94=83 iter =E2=94=82 =E2=9C=93 =E2=94=82 =
+ =E2=94=82 =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=9B
+
+from numbers import Number, Complex, Real, Rational, Integ=
+ral
+ isinstance(123, Number)
+True
+
+=E2=94=8F=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 Number =E2=94=82 Complex =E2=94=
+=82 Real =E2=94=82 Rational =E2=94=82 Integral =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=A8
+=E2=94=83 int =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=
+=93 =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=93 =E2=94=82 =
+=E2=9C=93 =E2=94=83
+=E2=94=83 fractions.Fraction =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=
+=93 =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=93 =E2=94=82 =
+ =E2=94=83
+=E2=94=83 float =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=
+=93 =E2=94=82 =E2=9C=93 =E2=94=82 =E2=94=82 =
+=E2=94=83
+=E2=94=83 complex =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=
+=93 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=83
+=E2=94=83 decimal.Decimal =E2=94=82 =E2=9C=93 =E2=94=82 =
+=E2=94=82 =E2=94=82 =E2=94=82 =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=9B
+
+<str> =3D <str>.strip() =
+# Strips all whitespace characters from both e=
+nds.
+<str> =3D <str>.strip('<chars&g=
+t;') # Strips all passed c=
+haracters from both ends.
+
<list> =3D <str&g=
+t;.split() # Splits on o=
+ne or more whitespace characters.
+<list> =3D <str>.split(sep=3DNone<=
+/span>, maxsplit=3D-1) # Splits on 'sep' str at most 'maxsplit' times.
+<list> =3D <str>.splitlines(keepends=3DFalse) # On [\n\r\f\v\x1c-\x1e\=
+x85\u2028\u2029] and \r\n.
+<str> =3D <str>.join(<coll_of_strings>) # Joins elements using string as a separator.
+
+<bool> =3D <sub_s=
+tr> in <str> =
+# Checks if string contains the substring.
+<bool> =3D <str>.startswith(<sub_str>) # Pass tuple of strings for multiple options.
+<bool> =3D <str>.endswith(<sub_str>) # Pass tuple of strings for multiple options.
+<int> =3D <str>.find(<sub_str>) # Returns start index of the first match or -1.
+<int> =3D <str>.index(<sub_str>) # Same, but raises ValueError if missing.
+
+<str> =3D <str&g=
+t;.replace(old, new [, count]) # Replaces 'o=
+ld' with 'new' at most 'count' times.
+<str> =3D <str>.translate(<table>) # Use `str.maketrans(<dict>)` to generate table.=
+span>
+
+<str> =3D chr(<i=
+nt>) # Converts in=
+t to Unicode character.
+<int> =3D ord(<str>) # Converts Unicode character to int.
+
+'=
+lstrip()'
, 'rstrip()'
and 'rsplit()'
.'=
+lower()'
, 'upper()'
, 'capitalize()'
and 'title()'
.=E2=94=8F=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 [ !#$%=E2=80=A6] =E2=94=82 [a-zA-Z] =E2=
+=94=82 [=C2=BC=C2=BD=C2=BE] =E2=94=82 [=C2=B2=C2=B3=C2=B9] =E2=94=82 =
+ [0-9] =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 isprintable() =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=93 =
+ =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=93 =E2=94=82 =E2=
+=9C=93 =E2=94=83
+=E2=94=83 isalnum() =E2=94=82 =E2=94=82 =E2=9C=93 =E2=
+=94=82 =E2=9C=93 =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=93 =
+ =E2=94=83
+=E2=94=83 isnumeric() =E2=94=82 =E2=94=82 =E2=94=82 =
+=E2=9C=93 =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=93 =E2=94=
+=83
+=E2=94=83 isdigit() =E2=94=82 =E2=94=82 =E2=94=82 =
+ =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=93 =E2=94=83
+=E2=94=83 isdecimal() =E2=94=82 =E2=94=82 =E2=94=82 =
+ =E2=94=82 =E2=94=82 =E2=9C=93 =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=9B
+
'isspac=
+e()'
checks for whitespaces: '[ \t\n\r\f\v\x1c-\x1f\x85\xa0\u1680=E2=80=A6]'
.import re
+<str> =3D re.sub(<regex>, new, text, count=3D0) # Substitutes all occur=
+rences with 'new'.
+<list> =3D re.findall(<regex>, text) # Returns all occurrences as strings.
+<list> =3D re.split(<regex>, text, maxsplit=3D0) # Use brackets in regex=
+ to include the matches.
+<Match> =3D re.search(<regex>, text) # Searches for first occurrence of the pattern.
+<Match> =3D re.match(<regex>, text) # Searches only at the beginning of the text.
+<iter> =3D re.finditer(<regex>, text) # Returns all occurrences as Match objects.
+
'flags=3Dre.IGNORECASE'
can be used with all functions.'flags=3Dre.MULTILINE'
makes '^'
and '$'
match the start/end of each =
+line.'flags=3Dre.DOTALL'
makes '.'
also accept the '\n'
.r'\=
+1'
or '\\1'
for backreference ('\1'
returns a character with octal code=
+ 1).'?'=
+
after '*'
and '+'
to make them non-greedy.<str> =3D <Match>.group() =
+ # Returns the whole match. Also group(0).=
+
+<str> =3D <Match>.group(1)=
+ # Returns part in the fir=
+st bracket.
+<tuple> =3D <Match>.groups() # Returns all bracketed parts.
+<int> =3D <Match>.start() # Returns start index of the match.
+<int> =3D <Match>.end() # Returns exclusive end index of the match.
+
'\d' =3D=3D=
+ '[0-9]' =
+# Matches decimal characters.
+'\w' =3D=3D =
+'[a-zA-Z0-9_]' =
+# Matches alphanumerics and underscore.
+'\s' =3D=3D =
+'[ \t\n\r\f\v]' =
+# Matches whitespaces.
+
'flags=3Dre.ASCII'
argument is used.'\s'
from accepting '[\x1c-\x1f]'
(the so-called =
+separator characters).=
+<str> =3D f'{&=
+lt;el_1>}, {<el_2>}' # Curly brackets can also contai=
+n expressions.
+<str> =3D '{}, {}'.format(<el_1=
+>, <el_2>) # Or: '{0}, {a}'.format(&=
+lt;el_1>, a=3D<el_2>)
+<str> =3D '%s, %s' % (<el_1>=
+, <el_2>) # Redundant and inferior =
+C-style formatting.
+
'Person', 'name height')
+ person =3D Person('Jean-Luc', 187)
+f=
+'{person.name} is {person.height / 100} meters =
+tall.'
+'Jean-Luc is 1.87 meters tall.'
+
Person =3D collecti=
+ons.namedtuple(
{<el>:<10} # '<el&g=
+t; '
+{<el>:^10} =
+ # ' <el> '
+{<el>:>10} =
+ # ' <el>'
+{<el>:.<10} =
+ # '<el>......'
+{<el>:0} =
+ # '<el>'
+
f'{<el>:{&l=
+t;str/int>}[=E2=80=A6]}'
.=
+'=3D'
to the expression prepends it to the output: f'=
+{1+1=
+=3D}'
returns '1+1=3D2'
.=
+'!r'
to the expression converts object to string by calling i=
+ts repr() =
+method.{'abcde':10} =
+# 'abcde '
+{'abcde':10.=
+3} # 'abc =
+ '
+{'abcde':.3<=
+/span>} # 'abc'
+{'abcde'!r:1=
+0} # "'abcde'=
+ "
+
{123456:10} # ' 123456'
+{123456:10=
+span>,} # ' 123,=
+456'
+{123456:10=
+span>_} # ' 123_=
+456'
+{123456:+10<=
+/span>} # ' +123=
+456'
+{123456:=3D+=
+10} # '+ 1=
+23456'
+{123456: } =
+ # ' 123456'
+{-123456: } =
+ # '-123456'
+
{1.23456:10.3} # =
+' 1.23'
+{1.23456:10.=
+3f} # ' 1.=
+235'
+{1.23456:10.=
+3e} # ' 1.235e=
++00'
+{1.23456:10.=
+3%} # ' 123.4=
+56%'
+
=E2=94=8F=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 {<float>} =E2=94=82 {<floa=
+t>:f} =E2=94=82 {<float>:e} =E2=94=82 {<float>:%} =E2=
+=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=A8
+=E2=94=83 0.000056789 =E2=94=82 '5.6789e-05' =E2=94=82 '0.000057' =
+=E2=94=82 '5.678900e-05' =E2=94=82 '0.005679%' =E2=94=83
+=E2=94=83 0.00056789 =E2=94=82 '0.00056789' =E2=94=82 '0.000568' =
+=E2=94=82 '5.678900e-04' =E2=94=82 '0.056789%' =E2=94=83
+=E2=94=83 0.0056789 =E2=94=82 '0.0056789' =E2=94=82 '0.005679' =
+=E2=94=82 '5.678900e-03' =E2=94=82 '0.567890%' =E2=94=83
+=E2=94=83 0.056789 =E2=94=82 '0.056789' =E2=94=82 '0.056789' =
+=E2=94=82 '5.678900e-02' =E2=94=82 '5.678900%' =E2=94=83
+=E2=94=83 0.56789 =E2=94=82 '0.56789' =E2=94=82 '0.567890' =
+=E2=94=82 '5.678900e-01' =E2=94=82 '56.789000%' =E2=94=83
+=E2=94=83 5.6789 =E2=94=82 '5.6789' =E2=94=82 '5.678900' =
+=E2=94=82 '5.678900e+00' =E2=94=82 '567.890000%' =E2=94=83
+=E2=94=83 56.789 =E2=94=82 '56.789' =E2=94=82 '56.789000' =
+=E2=94=82 '5.678900e+01' =E2=94=82 '5678.900000%' =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=9B
+
+=E2=94=8F=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=93
+=E2=94=83 =E2=94=82 {<float>:.2} =E2=94=82 {<float=
+>:.2f} =E2=94=82 {<float>:.2e} =E2=94=82 {<float>:.2%} =E2=
+=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=A8
+=E2=94=83 0.000056789 =E2=94=82 '5.7e-05' =E2=94=82 '0.00' =
+=E2=94=82 '5.68e-05' =E2=94=82 '0.01%' =E2=94=83
+=E2=94=83 0.00056789 =E2=94=82 '0.00057' =E2=94=82 '0.00' =
+=E2=94=82 '5.68e-04' =E2=94=82 '0.06%' =E2=94=83
+=E2=94=83 0.0056789 =E2=94=82 '0.0057' =E2=94=82 '0.01' =
+=E2=94=82 '5.68e-03' =E2=94=82 '0.57%' =E2=94=83
+=E2=94=83 0.056789 =E2=94=82 '0.057' =E2=94=82 '0.06' =
+=E2=94=82 '5.68e-02' =E2=94=82 '5.68%' =E2=94=83
+=E2=94=83 0.56789 =E2=94=82 '0.57' =E2=94=82 '0.57' =
+=E2=94=82 '5.68e-01' =E2=94=82 '56.79%' =E2=94=83
+=E2=94=83 5.6789 =E2=94=82 '5.7' =E2=94=82 '5.68' =
+=E2=94=82 '5.68e+00' =E2=94=82 '567.89%' =E2=94=83
+=E2=94=83 56.789 =E2=94=82 '5.7e+01' =E2=94=82 '56.79' =
+=E2=94=82 '5.68e+01' =E2=94=82 '5678.90%' =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=9B
+
'{<f=
+loat>:g}'
is '{<float>:.6}'
with stripped zeros, exponent=
+ starting at 7 figures.'{6.5:.0f}'
a '{7.5:.0f}'=
+
an '8'
..5
, .25
, =E2=80=A6).{90:c} =
+ # 'Z'
+{90:b} =
+ # '1011010'
+{90:X} =
+ # '5A'
+
<int> =3D int(<float/str/bool>) =
+ # Or: math.floor(<float>)
+<float> =3D float(<int/str/bool>) # Or: <real>e=C2=B1<int>
+<complex> =3D complex(real=3D0, i=
+mag=3D0) # Or: <real> =C2=B1 <real>j
+<Fraction> =3D fractions.Fraction(0, 1) # Or: Fraction(numerator=3D0, denominator=3D1)
+<Decimal> =3D decimal.Decimal(<str/int>) # Or: Decimal((sign, digits, exponent))
+
'int(&l=
+t;str>)'
and 'float(<str>)'
raise ValueError on malformed=
+ strings.'math.isclose(<float>, <float>)'=
+code>.
'decimal.getcontext().prec =3D <in=
+t>'
.<num> =3D pow(<num>, <num>) =
+ # Or: <num> ** <n=
+um>
+<num> =3D abs(<num>) # <float> =3D abs(<complex>)
+<num> =3D round(<num> [, =C2=B1ndigits]) # `round(126, -1) =3D=3D 130`
+
from math import e, pi, inf, nan, isinf, isnan # `<el> =3D=3D nan` is always False.
+from math =
+import sin, cos, tan, asin, acos, atan # Also: degrees, radians.
+from math =
+import log, log10, log2 # Log can accept base as second arg.
+
from statistics import mean, median, variance # Also: stdev, quantiles, groupby.
+
from random import random, randint, choice # Also: shuffle, gauss, triangular, seed.
+<float> =3D random() # A float inside [0, 1).
+<int> =3D randint(from_inc, to_inc) # An int inside [from_inc, to_inc].
+<el> =3D choice(<sequence>) # Keeps the sequence intact.
+
<int> =3D =C2=B10b<bi=
+n> # Or: =
+=C2=B10x<hex>
+<int> =3D int('=C2=B1<bin>',=
+ 2) # Or: int('=C2=B1<hex>', 16)
+<int> =3D int('=C2=B10b<bin>', 0) # Or: int('=C2=B10x<hex>', 0)
+<str> =3D bin(<int>) # Returns '[-]0b<bin>'.
+
<int> =3D <int> & <int> =
+ # And (0b1100 &=
+; 0b1010 =3D=3D 0b1000).
+<int> =3D <int> | <int> # Or (0b1100 | 0b1010 =3D=3D 0b1110).
+<int> =3D <int> ^ <int> # Xor (0b1100 ^ 0b1010 =3D=3D 0b0110).
+<int> =3D <int> << n_bits # Left shift. Use >> for right.
+<int> =3D ~<int> # Not. Also -<int> - 1.
+
import itertools as it
+
0, 1], repeat=3D3)
+[(0, 0, 0), (0, 0, 1=
+span>), (0, =
+1, 0), (0, 1, 1),
+ (1, 0, 0), (1, 0, 1=
+span>), (1, =
+1, 0), (1, 1, 1)]
+
it.product([
+'abc', 'abc') # a b c
+[('a', 'a'=
+span>), ('a', 'b'), ('a', 'c'), # a x x x<=
+/span>
+ ('b', 'a'=
+span>), ('b', 'b'), ('b', 'c'), # b x x x<=
+/span>
+ ('c', 'a'=
+span>), ('c', 'b'), ('c', 'c')] # c x x x<=
+/span>
+
it.product(
+'abc', 2) # a b c
+[('a', 'b'=
+span>), ('a', 'c'), # a . =
+x x
+ ('b', 'c'=
+span>)] # =
+b . . x
+
it.combinations(
+'abc', 2) # a b c
+[('a', 'a'=
+span>), ('a', 'b'), ('a', 'c'), # a x x x<=
+/span>
+ ('b', 'b'=
+span>), ('b', 'c'), # b . =
+x x
+ ('c', 'c'=
+span>)] # =
+c . . x
+
it.combinations_with_replacement(
+'abc', 2) # a b c
+[('a', 'b'=
+span>), ('a', 'c'), # a . =
+x x
+ ('b', 'a'=
+span>), ('b', 'c'), # b x =
+. x
+ ('c', 'a'=
+span>), ('c', 'b')] # c x =
+x .
+
it.permutations(
+<=
+span class=3D"hljs-section"><D>
, 'time' <T>
, 'datetim=
+e' <DT>
and 'timedelta' <TD>
classes. All are immutable and hashable.=
+strong><a>
, meaning they ha=
+ve defined timezone, or 'naive' <n>
, meaning they don't.from datetime import dat=
+e, time, datetime, timedelta
+from dateutil.tz import UTC, tzlocal, gettz, datetime_exists, resolve_imaginar=
+y
+
<D> =3D date(year, month, day) =
+ # Only accepts valid dates from 1 to 9999 =
+AD.
+<T> =3D time(hour=3D0, minute=3D<=
+span class=3D"hljs-number">0, second=3D0=
+) # Also: `microsecond=3D0, tzinfo=
+=3DNone, fold=3D0`.
+<DT> =3D datetime(year, month, day, hour=3D0) # Also: `minute=3D0, second=3D0,=
+ microsecond=3D0, =E2=80=A6`.
+<TD> =3D timedelta(weeks=3D0, days=
+=3D0, hours=3D0) # Also: `minutes=3D0, seconds=3D0=
+, microseconds=3D0`.
+
'&l=
+t;D/DT>.weekday()'
to get the day of the week as an int, w=
+ith Monday being 0.'fold=
+=3D1'
means the second pass in case of time jumping back for =
+one hour.'<DT=
+a> =3D resolve_imaginary(<DTa>)'
fixes DTs that fall=
+ into the missing hour.<D/DTn> =3D D/DT.today() # Current local date or naive datetime.
+<DTn> =3D DT.utcnow() # Naive datetime from current UTC time.
+<DTa> =3D DT.now(<tzinfo>) # Aware datetime from current tz time.
+
'<DTn>.time()'
, '<DTa>.time()'
or '<DTa>.timetz()'
.<tzinfo> =3D UTC # UTC timezone. London without DST.
+<tzinfo> =3D tzlocal() # Local timezone. Also gettz().
+<tzinfo> =3D gettz('<Continent>/<=
+;City>') # 'Continent/City_Name=
+' timezone or None.
+<DTa> =3D <DT>.astimezone(<tzinfo>) # Datetime, converted to the passed timezone.
+<Ta/DTa> =3D <T/DT>.replace(tzinfo=3D<tzinfo>) # Unconverted object with a new timezone.
+
<D/T/DT> =3D D/T/DT.fromisoformat('<iso>') # Object from=
+ ISO string. Raises ValueError.
+<DT> =3D DT.strptime(<str>, '&l=
+t;format>') # Datetime from str, a=
+ccording to format.
+<D/DTn> =3D D/DT.fromordinal(<int>) # D/DTn from days since the Gregorian NYE 1.
+<DTn> =3D DT.fromtimestamp(<real>) # Local time DTn from seconds since the Epoch.
+<DTa> =3D DT.fromtimestamp(<real>, <tz.>) # Aware datetime from seconds since the Epoch.
+
'YYYY-MM-DD'
, 'HH:MM:SS.mmmuuu[=C2=B1HH:MM]'
, or both separated by an arbitrary character. All parts following =
+the hours are optional.'1970-01-01 00:00 UTC'
, '1970-01-01 01:00 CET'
, =E2=80=A6<str> =3D <D/T/DT>.isoformat(sep=3D'T') # Also `timespec=
+=3D'auto/hours/minutes/seconds/=E2=80=A6'`.
+<str> =3D <D/T/DT>.strftime('<=
+;format>') # Custom string repres=
+entation.
+<int> =3D <D/DT>.toordinal() # Days since Gregorian NYE 1, ignoring time and tz.
+<float> =3D <DTn>.timestamp() # Seconds since the Epoch, from DTn in local tz.
+<float> =3D <DTa>.timestamp() # Seconds since the Epoch, from aware datetime.
+
'2015-05-14 23:39:00.00 +0200', '%Y-%m-%d %H:%M:%S.%f %z')
+"%A, %dth of %B '%y, %I:%M%p %Z")
+"Thursday, 14th of May '15, 11:39PM UTC+02:00"<=
+/span>
+ dt.strftime(
dt =3D datetime.str=
+ptime(
'%z'
accepts '=C2=B1HH[:]MM'
and returns '=C2=B1HHMM'
(or ''
if datetim=
+e is naive).'%a'
and '%b'
.<D/DT> =3D <D/DT> =C2=B1 <TD>=
+ # Returned datetime can fal=
+l into missing hour.
+<TD> =3D <D/DTn> - <D/DTn> # Returns the difference. Ignores time jumps.
+<TD> =3D <DTa> - <DTa> # Ignores time jumps if they share tzinfo object.
+<TD> =3D <TD> * <real> # Also: <TD> =3D abs(<TD>) and <TD> =3D=
+ <TD> =C2=B1% <TD>.
+<float> =3D <TD> / <TD> # How many weeks/years there are in TD. Also //.
+
func(<positional_args>) # func(0, 0)
+func(<keyword_args>) # func(x=3D0, y=3D0)
+func(<positional_args>, <keyword_args>) # func(0, y=3D0)
+
def func(<nondefault_args>): ..=
+. # def func(x, y): ...
+def func(<default_a=
+rgs>): ... # def func(x=3D0, y=3D0): ...
+def func(<nondefaul=
+t_args>, <default_args>): ... # def func(x, y=3D0): ...
+
Splat = +expands a collection into positional arguments, while splatty-splat expands= + a dictionary into keyword arguments.
args =3D (1, <=
+span class=3D"hljs-number">2)
+kwargs =3D {'x': 3, 'y': 4, 'z': 5}
+func(*args, **kwargs)
+
func(1, 2, x=3D3, y=3D<=
+span class=3D"hljs-number">4, z=3D5)
+
def add(*a):
+ return sum(a)
+
1, 2, 3)
+6
+
add(
+def f(*args): ... # f(1, 2, 3)
+def f(x, *args)=
+: ... # f(1, 2, 3)
+def f(*args, z)=
+: ... # f(1, 2, z=3D3)
+
def f(**kwargs): ... # f(x=3D1, y=3D2, z=3D3)
+def f(x, **kwargs): ... # f(x=3D1, y=3D2, z=3D=
+3) | f(1, y=3D2, z=3D3)
+
+def f(*args, **kwargs): ... # f(x=3D1, y=3D2, z=3D3) | f(1, y=3D2, z=3D3) | =
+f(1, 2, z=3D3) | f(1, 2, 3)
+def f(x, *args, **kwar=
+gs): ... # f(x=3D1, y=3D2, z=3D=
+3) | f(1, y=3D2, z=3D3) | f(1, 2, z=3D3) | f(1, 2, 3)
+def f(*args, y, **kwar=
+gs): ... # f(x=3D1, y=3D2, z=3D=
+3) | f(1, y=3D2, z=3D3)
+
+def f(*, x, y, z): ... # f(x=3D1, y=3D2, z=3D3)
+def f(x, *, y, z): ... # f(x=3D1, y=3D2, z=3D=
+3) | f(1, y=3D2, z=3D3)
+def f(x, y, *, z): ... # f(x=3D1, y=3D2, z=3D=
+3) | f(1, y=3D2, z=3D3) | f(1, 2, z=3D3)
+
+<list> =3D [*<coll.> [, ...]] # Or: list(<collection>) [+ ...]
+<tuple> =3D (*<coll.>, [...]) =
+# Or: tuple(<collection>) [+ ...]
+<set> =3D {*<coll.> [, ...]} =
+# Or: set(<collection>) [| ...]
+<dict> =3D {**<dict> [, ...]} =
+# Or: dict(**<dict> [, ...])
+
head, *body, tail =3D <=
+coll.> # Head or tail can be omitted.=
+span>
+
+<func> =3D lambda: <return_value> =
+ # A single statement function.
+<func> =3D lambda <arg_1>, =
+<arg_2>: <return_value> # Also =
+accepts default arguments.
+
<list> =3D [i+1=
+span> for i in range(10)] =
+ # Or: [1, 2, ..., 10]
+<iter> =3D (i for i in range(10) if i > 5=
+span>) # Or: iter([6, 7, 8, 9])
+<set> =3D {i+5 for i in range(10)} # Or: {5, 6, ..., 14}
+<dict> =3D {i: i*2 for i in range(10 )} # Or: {0: 0, 1: 2, ..., 9: 18}
+
for l in 'abc' for r in 'abc']
+['aa', 'ab'<=
+/span>, 'ac', ..., 'cc']
+
[l+r
+from func=
+tools import reduce
+
<iter> =3D map(lambda x: x + 1<=
+/span>, range(10)) # Or: iter([1, 2, ..., 10])
+<iter> =3D filter(lambda x: x >=
+; 5, range(1=
+0)) # Or: iter([6, 7, 8, 9])
+<obj> =3D reduce(lambda out, x: =
+out + x, range(10)) # Or: 45
+
+<bool> =3D any(<collection>) =
+ # Is `bool(<el>)` True for any element.=
+
+<bool> =3D all(<collection>) # Is True for all elements or empty.
+
<obj> =3D <exp> if <condition> else <exp> # Only =
+one expression gets evaluated.
+
if a else 'zero' for a in (0, 1 , 2, 3)] # `any([0, '', [], None]) =3D=3D F=
+alse`
+['zero', 1=
+span>, 2, 3<=
+/span>]
+
[a
+from collections import namedtu=
+ple
+Point =3D namedtuple('Point', 'x y') # Creates a tuple's subclass.
+point =3D Point(0, 0) # Returns its instance.
+
from enum import Enum
+Direction =3D Enum('Direction', 'N E S W') # Creates an enum.
+direction =3D Direction.N # Returns its member.
+
+from dataclasses import make_=
+dataclass
+Player =3D make_dataclass('Player', ['loc', 'dir']) # Creates a class.
+player =3D Player(point, direction) # Returns its instance.
+
+import <module&g=
+t; # Imports a built-in or '<mod=
+ule>.py'.
+import <package> # Imports a built-in or '<package>/__init__.py=
+'.
+import <package>.<module> =
+# Imports a built-in or '<package>/<m=
+odule>.py'.
+
'import <package>'
does not automatically provide acce=
+ss to the package's modules unless they are explicitly imported in its init=
+ script.We have/get a clos= +ure in Python when:
def get_multiplier(a):
+ def <=
+span class=3D"hljs-title">out(b):=
+
+ return a * b
+ return out
+
3)
+ multiply_by_3(10)
+30
+
multiply_by_3 =3D get_multiplier(
+'<function>.__closu=
+re__[0].cell_contents'
.from functools import partial
+<function> =3D partial(<function> [, <arg_1>, <arg_2&g=
+t;, ...])
+
def multiply(a, b):
+ retur=
+n a * b
+ multiply_by_3 =3D partial(mul=
+tiply, 3)
+ multiply_by_3(10)
+30
+
+'defaultdict(<function>)'
, 'iter(<function>, to_exc=
+lusive)'
and dataclass's 'field(default_factory=3D<function>)'.
If variable is being assi= +gned to anywhere in the scope, it is regarded as a local variable, unless i= +t is declared as a 'global' or a 'nonlocal'.
def get_counter<=
+span class=3D"hljs-params">():
+ i =3D 0
+ def <=
+span class=3D"hljs-title">out():<=
+/span>
+ nonlocal i
+ i +=3D 1
+ return i
+ return out
+
1, 2=
+, 3)
+
counter =3D get_counter()
+ counter(), counter(), counter=
+()
+(
+@decorator_name
+def function_that_gets_passed_to_decorator():
+ ...
+
Decorator t= +hat prints function's name every time the function is called.
<= +pre>from functools import wraps
+
+def debug(func)=
+:
+
+ def <=
+span class=3D"hljs-title">out(*args, **k=
+wargs):
+ print(func.__name__)
+ return func(*args, **kwargs)
+ return out
+
+
+def add(x, y):<=
+/span>
+ return x + y
+
'add.__name__'
would return <=
+span class=3D"hljs-string">'out'
.Decorator that caches fun= +ction's return values. All function's arguments must be hashable.<= +/p>
from functools import lru_=
+cache
+
+
+def fib(n):
+ return n if n < 2 else fib(n-2) + fib(n-=
+1)
+
'maxsize=3DNone'
ma=
+kes it unbounded.=
+'sys.setrecursionlimit(<depth>)'
.A decorator that accepts arguments and returns a normal decorator that acc= +epts a function.
from functools import wraps
+
+def debug(print_result=
+=3DFalse):
+ def <=
+span class=3D"hljs-title">decorator(func=
+):
+
+ def out(*args,=
+ **kwargs):
+ result =3D func(*args, **kwargs)
+ print(func.__name__, result if print_result else '')
+ return result
+ return out
+ return decorator
+
+
+def add(x, y):<=
+/span>
+ return x + y
+
'@debug'
to decorate the add() function would not work he=
+re, because debug would then receive the add() function as a 'print_result'=
+ argument. Decorators can however manually check if the argument they recei=
+ved is a function and act accordingly.class=
+span> <name>:
+ def <=
+span class=3D"hljs-title">__init__(self,=
+ a):
+ self.a =3D a
+ def <=
+span class=3D"hljs-title">__repr__(self)=
+:
+ class_name =3D self.__class__.__name__
+ return f'{class_name}({self.a!r})'
+ def <=
+span class=3D"hljs-title">__str__(self)<=
+/span>:
+ return str(self.a)
+
+
+ def <=
+span class=3D"hljs-title">get_class_name=
+(cls):
+ return cls.__name__
+
'@staticmethod'
do not receive 'self' nor 'c=
+ls' as their first arg.print(<=
+;el>)
+f'{<el>}'
+logging.warning(<el>)
+csv.writer(<file>).writerow([<el>])
+raise Exception(<el>)
+
print/s=
+tr/repr([<el>])
+print/str/repr({<el>: <el>})
+f'{<el>!r}'
+Z =3D dataclasses.make_dataclass('Z', [<=
+span class=3D"hljs-string">'a']); print/str/repr(Z(<el>))
+ <el>
+
class <name>: + def <= +span class=3D"hljs-title">__init__(self,= + a=3DNone): + self.a =3D a +
c=
+lass Person:
+ def <=
+span class=3D"hljs-title">__init__(self,=
+ name, age):
+ self.name =3D name
+ self.age =3D age
+
+class Employee(Person):
+ def <=
+span class=3D"hljs-title">__init__(self,=
+ name, age, staff_num):
+ super().__init__(name, age)
+ self.staff_num =3D staff_num
+
class A: =
+pass
+class B: pass
+class C(A, B): pass
+
MRO determines the order in which parent classes are traversed w= +hen searching for a method or an attribute:
+class 'C'>, <clas=
+s 'A'>, <class 'B'>, <class 'object'=
+>]
+
C.mro()
+[<
+Pythonic way of implementi= +ng getters and setters.
class Person:
+
+ def <=
+span class=3D"hljs-title">name(self):
+ return ' '.join(self._name)
+
+
+ def <=
+span class=3D"hljs-title">name(self, val=
+ue):
+ self._name =3D value.split()
+
'\t Guido van Rossum \n'
+ person.name
+'Guido van Rossum'
+
person =3D Person()
+ person.name =3D
+Decorator that automatic= +ally generates init(), repr() and eq() special methods.
from= + dataclasses import dataclass, f= +ield + + +class < class_name>: + <attr_name>: <type> + <attr_name>: <type> =3D <default_value> + <attr_name>: list/dict/set =3D field(default_factory=3Dlist/dict/= +set) +
'order=3DTrue'
and immutable with 'frozen=3DTrue'.
=
+'<attr_name>: list =3D []'
=
+would make a list that is shared among all instances. Its 'default_factory'=
+ argument can be any callable.'typing.Any'
.from dataclasses import make_dataclass
+<class> =3D make_dataclass('<class_nam=
+e>', <coll_of_attribute_names>)
+<class> =3D make_dataclass('<class_nam=
+e>', <coll_of_tuples>)
+<tuple> =3D ('<attr_name>', =
+<type> [, <default_value>])
import=
+span> typing as tp, collections.abc as abc
+<var_name>: list/set/abc.Iterable/abc.Sequence/tp.Optional[<type&g=
+t;] [=3D <obj>]
+<var_name>: dict/tuple/tp.Union[<type>, ...] [=3D <obj>]
+def func(<arg_name&=
+gt;: <type> [=3D <obj>]) -> <type>: ...
+
Mechanism that restricts objects= + to attributes listed in 'slots' and significantly reduces their memory foo= +tprint.
class MyClassWithSlots:
+ __slots__ =3D ['a']
+ def <=
+span class=3D"hljs-title">__init__(self)=
+:
+ self.a =3D 1
+
from copy import copy, deepcopy
+<object> =3D copy(<object>)
+<object> =3D deepcopy(<object>)
+
A duck ty= +pe is an implicit type that prescribes a set of special methods. Any object= + that has those methods defined is considered a member of that duck type.= +strong>
'id(self) =3D=3D id(other)', which is the same as 'self is other'
.
class =
+MyComparable:
+ def <=
+span class=3D"hljs-title">__init__(self,=
+ a):
+ self.a =3D a
+ def <=
+span class=3D"hljs-title">__eq__(self, o=
+ther):
+ if isinstance(other, type(self)=
+):
+ return self.a =3D=3D other.=
+a
+ return NotImplemented
+
'id(self)'
will not do.class =
+MyHashable:
+ def <=
+span class=3D"hljs-title">__init__(self,=
+ a):
+ self._a =3D a
+
+ def <=
+span class=3D"hljs-title">a(self)=
+:
+ return self._a
+ def <=
+span class=3D"hljs-title">__eq__(self, o=
+ther):
+ if isinstance(other, type(self)=
+):
+ return self.a =3D=3D other.=
+a
+ return NotImplemented
+ def <=
+span class=3D"hljs-title">__hash__(self)=
+:
+ return hash(self.a)
+
from functools import to=
+tal_ordering
+
+
+class MySortable:
+ def <=
+span class=3D"hljs-title">__init__(self,=
+ a):
+ self.a =3D a
+ def <=
+span class=3D"hljs-title">__eq__(self, o=
+ther):
+ if isinstance(other, type(self)=
+):
+ return self.a =3D=3D other.=
+a
+ return NotImplemented
+ def <=
+span class=3D"hljs-title">__lt__(self, o=
+ther):
+ if isinstance(other, type(self)=
+):
+ return self.a < other.a
+ return NotImplemented
+
class =
+Counter:
+ def <=
+span class=3D"hljs-title">__init__(self)=
+:
+ self.i =3D 0
+ def <=
+span class=3D"hljs-title">__next__(self)=
+:
+ self.i +=3D 1
+ return self.i
+ def <=
+span class=3D"hljs-title">__iter__(self)=
+:
+ return self
+
1, 2=
+, 3)
+
counter =3D Counter()
+ next(counter), next(counter),=
+ next(counter)
+(
+'<function>'
as an argument, it actu=
+ally means '<cal=
+lable>'
.class =
+Counter:
+ def <=
+span class=3D"hljs-title">__init__(self)=
+:
+ self.i =3D 0
+ def <=
+span class=3D"hljs-title">__call__(self)=
+:
+ self.i +=3D 1
+ return self.i
+
1, 2=
+, 3)
+
counter =3D Counter()
+ counter(), counter(), counter=
+()
+(
+class =
+MyOpen:
+ def <=
+span class=3D"hljs-title">__init__(self,=
+ filename):
+ self.filename =3D filename
+ def <=
+span class=3D"hljs-title">__enter__(self=
+):
+ self.file =3D open(self.filename)
+ return self.file
+ def <=
+span class=3D"hljs-title">__exit__(self,=
+ exc_type, exception, traceback):
+ self.file.close()
+
with open('test.txt', 'w') as file:
+ file.write('Hello World!')
+=
+with MyOpen('test.txt') as file:
+ print(file.read())
+Hello World!
+
+class =
+MyIterable:
+ def <=
+span class=3D"hljs-title">__init__(self,=
+ a):
+ self.a =3D a
+ def <=
+span class=3D"hljs-title">__iter__(self)=
+:
+ return iter(self.a)
+ def <=
+span class=3D"hljs-title">__contains__(s=
+elf, el):
+ return el in self.a
+
1, 2, 3])
+for el in obj]
+[1, 2=
+, 3]
+1=
+ in obj
+True
+ [el
obj =3D MyIterable([
+'<iterable>'
when it uses '<collection>'
.class =
+MyCollection:
+ def <=
+span class=3D"hljs-title">__init__(self,=
+ a):
+ self.a =3D a
+ def <=
+span class=3D"hljs-title">__iter__(self)=
+:
+ return iter(self.a)
+ def <=
+span class=3D"hljs-title">__contains__(s=
+elf, el):
+ return el in self.a
+ def <=
+span class=3D"hljs-title">__len__(self)<=
+/span>:
+ return len(self.a)
+
class =
+MySequence:
+ def <=
+span class=3D"hljs-title">__init__(self,=
+ a):
+ self.a =3D a
+ def <=
+span class=3D"hljs-title">__iter__(self)=
+:
+ return iter(self.a)
+ def <=
+span class=3D"hljs-title">__contains__(s=
+elf, el):
+ return el in self.a
+ def <=
+span class=3D"hljs-title">__len__(self)<=
+/span>:
+ return len(self.a)
+ def <=
+span class=3D"hljs-title">__getitem__(se=
+lf, i):
+ return self.a[i]
+ def <=
+span class=3D"hljs-title">__reversed__(s=
+elf):
+ return reversed(self.a)
+
=
+'abc.Iterable'
and 'abc.Collection'
, it is not a duck type. That i=
+s why 'issubclass(M=
+ySequence, abc.Sequence)'
would return False even if MySequen=
+ce had all the methods defined. It however recognizes list, tuple, range, s=
+tr, bytes, bytearray, array, memoryview and deque, because they are registe=
+red as its virtual subclasses.from collections import =
+abc
+
+class MyAbcSequence(abc.S=
+equence):
+ def <=
+span class=3D"hljs-title">__init__(self,=
+ a):
+ self.a =3D a
+ def <=
+span class=3D"hljs-title">__len__(self)<=
+/span>:
+ return len(self.a)
+ def <=
+span class=3D"hljs-title">__getitem__(se=
+lf, i):
+ return self.a[i]
+
=E2=94=8F=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 Iterable =E2=94=82 Collection =E2=94=82 S=
+equence =E2=94=82 abc.Sequence =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=A8
+=E2=94=83 iter() =E2=94=82 ! =E2=94=82 ! =E2=94=82 =
+ =E2=9C=93 =E2=94=82 =E2=9C=93 =E2=94=83
+=E2=94=83 contains() =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=93 =
+ =E2=94=82 =E2=9C=93 =E2=94=82 =E2=9C=93 =E2=94=83
+=E2=94=83 len() =E2=94=82 =E2=94=82 ! =E2=94=82 =
+ ! =E2=94=82 ! =E2=94=83
+=E2=94=83 getitem() =E2=94=82 =E2=94=82 =E2=94=82 =
+ ! =E2=94=82 ! =E2=94=83
+=E2=94=83 reversed() =E2=94=82 =E2=94=82 =E2=94=82 =
+ =E2=9C=93 =E2=94=82 =E2=9C=93 =E2=94=83
+=E2=94=83 index() =E2=94=82 =E2=94=82 =E2=94=82 =
+ =E2=94=82 =E2=9C=93 =E2=94=83
+=E2=94=83 count() =E2=94=82 =E2=94=82 =E2=94=82 =
+ =E2=94=82 =E2=9C=93 =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=9B
+
'<abc>.__abstractmethods__'
.from enum import Enum, auto
+
class <e=
+num_name>(Enum):
+ <member_name> =3D auto()
+ <member_name> =3D <value>
+ <member_name> =3D <value>, <value>
+
+<member> =3D <enu=
+m>.<member_name> # Returns =
+a member.
+<member> =3D <enum>['<member_nam=
+e>'] # Returns a member. Rais=
+es KeyError.
+<member> =3D <enum>(<value>) # Returns a member. Raises ValueError.
+<str> =3D <member>.name # Returns member's name.
+<obj> =3D <member>.value # Returns member's value.
+
+<list> =3D list(&l=
+t;enum>) # Returns enum's=
+ members.
+<list> =3D [a.name for a in <enum>] # Returns enum's member names.
+<list> =3D [a.value for a in <enum>] # Returns enum's member values.
+<member> =3D random.choice(list(<enum>)) # Returns a random member.
+
+def get_=
+next_member(member):
+ members =3D list(type(member))
+ index =3D members.index(member) + 1
+ return members[index % len(members)=
+]
+
+Cutlery =3D Enum('Cutlery', 'FORK KNIFE SPOON')
+Cutlery =3D Enum('Cutlery', ['FORK', 'KNIFE',=
+ 'SPOON'])
+Cutlery =3D Enum('Cutlery', {'FORK': 1, 'KNIFE': 2=
+, 'SPOON': 3=
+})
+
from functools import partial
+LogicOp =3D Enum('LogicOp', {'AND': partial(lambda<=
+/span> l, r: l and r),
+ 'OR': partia=
+l(lambda l, r: l or r)})
+
try:
+ <code>
+except <exception>:
+ <code>
+
try:
+ <code_1>
+except <exception_a>:
+ <code_2_a>
+except <exception_b>:
+ <code_2_b>
+else:
+ <code_2_c>
+finally:
+ <code_3>
+
'else'
block will only be executed if 'try'
block had no =
+exceptions.'finally'
block will always be executed (unless a si=
+gnal is received).'signal.signal(signal_number, <func>)'
.=
+strong>except=
+ <exception>: ...
+except <exception> as <name>: ...
+except (<exception>, [...]): ...
+except (<exception>, [...]) as <name>: ...
+
'tr=
+aceback.print_exc()'
to print the error message to stderr.'pr=
+int(<name>)'
to print just the cause of the exception (=
+its arguments).'lo=
+gging.exception(<message>)'
to log the passed message, =
+followed by the full error message of the caught exception.raise =
+<exception>
+raise <exception>()
+raise <exception>(<el> [, .=
+..])
+
except <exception> [as &=
+lt;name>]:
+ ...
+ raise
+
arguments =3D <name>.args
+exc_type =3D <name>.__class__
+filename =3D <name>.__traceback__.tb_frame.f_code.co_filename
+func_name =3D <name>.__traceback__.tb_frame.f_code.co_name
+line =3D linecache.getline(filename, <name>.__traceback__.tb_lin=
+eno)
+trace_str =3D ''.join(traceback.format_t=
+b(<name>.__traceback__))
+error_msg =3D ''.join(traceback.format_e=
+xception(exc_type, <name>, <name>.__traceback__))
+
BaseException
+ =E2=94=9C=E2=94=80=E2=94=80 SystemExit # Raised by the sys.exit() function.
+ =E2=94=9C=E2=94=80=E2=94=80 KeyboardInterrupt # Raised when the user hits the interrupt key (ctrl-c).
+ =E2=94=94=E2=94=80=E2=94=80 Exception # User-defined exceptions should be derived from this class.
+ =E2=94=9C=E2=94=80=E2=94=80 ArithmeticError # Base class for arithmetic errors such as ZeroDivisionError.=
+span>
+ =E2=94=9C=E2=94=80=E2=94=80 AssertionError # Raised by `assert <exp>` if expression returns false va=
+lue.
+ =E2=94=9C=E2=94=80=E2=94=80 AttributeError # Raised when object doesn't have requested attribute/method.=
+span>
+ =E2=94=9C=E2=94=80=E2=94=80 EOFError # Raised by input() when it hits an end-of-file condition.
+ =E2=94=9C=E2=94=80=E2=94=80 LookupError # Base class for errors when a collection can't find an item.=
+span>
+ =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 IndexError # Raised when a sequence index is out of range.
+ =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 KeyError # Raised when a dictionary key or set element is missin=
+g.
+ =E2=94=9C=E2=94=80=E2=94=80 MemoryError # Out of memory. Could be too late to start deleting vars.
+ =E2=94=9C=E2=94=80=E2=94=80 NameError # Raised when nonexistent name (variable/func/class) is used.=
+span>
+ =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 UnboundLocalError # Raised when local name is used before it's being defi=
+ned.
+ =E2=94=9C=E2=94=80=E2=94=80 OSError # Errors such as FileExistsError/PermissionError (see #Open).=
+span>
+ =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 ConnectionError # Errors such as BrokenPipeError/ConnectionAbortedError=
+.
+ =E2=94=9C=E2=94=80=E2=94=80 RuntimeError # Raised by errors that don't fall into other categories.
+ =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 NotImplementedErr # Can be raised by abstract methods or by unfinished co=
+de.
+ =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 RecursionError # Raised when the maximum recursion depth is exceeded.<=
+/span>
+ =E2=94=9C=E2=94=80=E2=94=80 StopIteration # Raised by next() when run on an empty iterator.
+ =E2=94=9C=E2=94=80=E2=94=80 TypeError # Raised when an argument is of the wrong type.
+ =E2=94=94=E2=94=80=E2=94=80 ValueError # When argument has the right type but inappropriate value.
+
=E2=94=8F=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 List =E2=94=82 Set =E2=94=82 =
+Dict =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=A8
+=E2=94=83 getitem() =E2=94=82 IndexError =E2=94=82 =E2=94=82 Ke=
+yError =E2=94=83
+=E2=94=83 pop() =E2=94=82 IndexError =E2=94=82 KeyError =E2=94=82 Ke=
+yError =E2=94=83
+=E2=94=83 remove() =E2=94=82 ValueError =E2=94=82 KeyError =E2=94=82 =
+ =E2=94=83
+=E2=94=83 index() =E2=94=82 ValueError =E2=94=82 =E2=94=82 =
+ =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=9B
+
=
+raise TypeError('Argument is of the wron=
+g type!')
+raise ValueError('Argument has the right type but an inappropriate value!')
+raise RuntimeError('None of above!')
+
class MyError= +(Exception): pass +class MyInputError(MyErro= +r): pass +
Exits the interpreter by raisi= +ng SystemExit exception.
import sys
+sys.exit() # Exits with=
+ exit code 0 (success).
+sys.exit(<el>) # Prin=
+ts to stderr and exits with 1.
+sys.exit(<int>) # Exit=
+s with passed exit code.
+
print(<el_1>, ..., sep=3D' '<=
+/span>, end=3D'\n', file=3Dsys.stdout, f=
+lush=3DFalse)
+
'fi=
+le=3Dsys.stderr'
for messages about errors.'fl=
+ush=3DTrue'
to forcibly flush the stream.from pprint import pprint
+pprint(<collection>, width=3D80, d=
+epth=3DNone, compact=3DFalse, sort_dicts=3DTrue=
+span>)
+
<=
+span class=3D"hljs-keyword">import sys
+scripts_path =3D sys.argv[0]
+arguments =3D sys.argv[1:]
+
from argparse =
+import ArgumentParser, FileType
+p =3D ArgumentParser(description=3D<str>)
+p.add_argument('-<short_name>', '--<name>', action=3D'store_true') # Flag.
+p.add_argument('-<short_name>', '--<name>', type=3D<type>) =
+ # Option.
+p.add_argument('<name>', type=3D&l=
+t;type>, nargs=3D1) =
+ # First argument.
+p.add_argument('<name>', type=3D&l=
+t;type>, nargs=3D'+') =
+ # Remaining arguments.
+p.add_argument('<name>', type=3D&l=
+t;type>, nargs=3D'*') =
+ # Optional arguments.
+args =3D p.parse_args() # Exits on error.
+value =3D args.<name>
+
'he=
+lp=3D<str>'
to set argument description that will be di=
+splayed in help message.'de=
+fault=3D<el>'
to set the default value.'ty=
+pe=3DFileType(<mode>)'
for files. Accepts 'encoding', b=
+ut 'newline' is None.Opens the file and returns a c= +orresponding file object.
<file> =3D open(<path>, mode=3D'r', encoding=3DNone, ne=
+wline=3DNone)
+
'encodi=
+ng=3DNone'
means that the default encoding is used, which is =
+platform dependent. Best practice is to use 'encoding=3D"utf-8"'
whenever possib=
+le.'newlin=
+e=3DNone'
means all different end of line combinations are co=
+nverted to '\n' on read, while on write all '\n' characters are converted t=
+o system's default line separator.'newlin=
+e=3D""'
means no conversions take place, but input is still b=
+roken into chunks by readline() and readlines() on every '\n', '\r' and '\r=
+\n'.'r'
- Read (default).'w'
- Write (truncate).'x'
- Write or fail if the file already exists.'a'
- Append.'w+'
- Read and write (truncate).'r+'
- Read and write from the start.'a+'
- Read and write from the end.'t'
- Text mode (default).'b'
- Binary mode ('br'
, 'bw'
, 'bx'
, =E2=80=A6).'FileNo=
+tFoundError'
can be raised when reading with 'r'
or 'r+'
.'FileEx=
+istsError'
can be raised when writing with 'x'
.'IsADir=
+ectoryError'
and 'PermissionError'
can be raised by any.<=
+/li>
+'OSErro=
+r'
is the parent class of all listed exceptions.<file>.seek(0) # Moves to the start o=
+f the file.
+<file>.seek(offset) # Mo=
+ves 'offset' chars/bytes from the start.
+<file>.seek(0, 2) # Moves t=
+o the end of the file.
+<bin_file>.seek(=C2=B1offset, <anchor>) # Anchor: 0 start, 1 current position, 2 end.
+
<str/bytes> =3D <=
+file>.read(size=3D-1) # Reads 'size' chars/bytes or until EOF.
+<str/bytes> =3D <file>.readline() # Returns a line or empty string/bytes on EOF.
+<list> =3D <file>.readlines() # Returns a list of remaining lines.
+<str/bytes> =3D next(<file>) # Returns a line using buffer. Do not mix.
+
+<file>.write(<str=
+/bytes>) # Writes a string or byt=
+es object.
+<file>.writelines(<collection>) # Writes a coll. of strings or bytes objects.
+<file>.flush() # Fl=
+ushes write buffer. Runs every 4096/8192 B.
+
+def read_file(filename) :
+ with open(filename, encoding=3D'utf-8') as file:
+ return file.readlines()
+
def write_to_file(filename, text) :
+ with open(filename, 'w', encoding=3D'utf-8') as file:
+ file.write(text)
+
import os, glob
+from pathlib import Path
+
<str> =3D os.getcwd=
+() # Returns the current workin=
+g directory.
+<str> =3D os.path.join(<path>, ...) # Joins two or more pathname components.
+<str> =3D os.path.realpath(<path>) # Resolves symlinks and calls path.abspath().
+
+<str> =3D os.path.b=
+asename(<path>) # Returns final compon=
+ent of the path.
+<str> =3D os.path.dirname(<path>) # Returns path without the final component.
+<tup.> =3D os.path.splitext(<path>) # Splits on last period of the final component.
+
+<list> =3D os.listdi=
+r(path=3D'.') # Returns filenames located at the path.
+<list> =3D glob.glob('<pattern>') # Returns paths matching the wildcar=
+d pattern.
+
+<bool> =3D os.path.e=
+xists(<path>) # Or: <Path>.exi=
+sts()
+<bool> =3D os.path.isfile(<path>) # Or: <DirEntry/Path>.is_file()
+<bool> =3D os.path.isdir(<path>) # Or: <DirEntry/Path>.is_dir()
+
+<stat> =3D os.stat(&=
+lt;path>) # Or: <DirEntry/Pat=
+h>.stat()
+<real> =3D <stat>.st_mtime/st_size/=E2=80=A6 # Modification time, size in bytes, ...
+
+Unlike listdir(), scandir(= +) returns DirEntry objects that cache isfile, isdir and on Windows also sta= +t information, thus significantly increasing the performance of code that r= +equires it.
&l=
+t;iter> =3D os.scandir(path=3D'.') =
+ # Returns DirEntry objects located at the =
+path.
+<str> =3D <DirEntry>.path # Returns the whole path as a string.
+<str> =3D <DirEntry>.name # Returns final component as a string.
+<file> =3D open(<DirEntry>) # Opens the file and returns a file object.
+
<Path> =3D Path(<path> [, ...]) # Accepts strings, Paths and DirEntry objects.
+<Path> =3D <path> / <path> [/ ...] # First or second path must be a Path object.
+<Path> =3D <Path>.resolve() # Resolves symlinks and calls <Path>.absolute().
+
<Path> =3D Path() =
+ # Returns relative cwd. Also=
+ Path('.').
+<Path> =3D Path.cwd() # =
+Returns absolute cwd. Also Path().resolve().
+<Path> =3D Path.home() # =
+Returns user's home directory (absolute).
+<Path> =3D Path(__file__).resolve() # =
+Returns script's path if cwd wasn't changed.
+
+<Path> =3D <Path&=
+gt;.parent # Returns Path without=
+ the final component.
+<str> =3D <Path>.name # Returns final component as a string.
+<str> =3D <Path>.stem # Returns final component without extension.
+<str> =3D <Path>.suffix # Returns final component's extension.
+<tup.> =3D <Path>.parts # Returns all components as strings.
+
+<iter> =3D <Path&=
+gt;.iterdir() # Returns directory co=
+ntents as Path objects.
+<iter> =3D <Path>.glob('<pattern=
+>') # Returns Paths matching the w=
+ildcard pattern.
+
+<str> =3D str(<P=
+ath>) # Returns path as a st=
+ring.
+<file> =3D open(<Path>) # Also <Path>.read/write_text/bytes().
+
+import=
+ os, shutil, subprocess
+
os.chdir(<path>) =
+ # Changes the current working =
+directory.
+os.mkdir(<path>, mode=3D0o777) =
+ # Creates a directory. Permissions are in =
+octal.
+os.makedirs(<path>, mode=3D0o777) =
+ # Creates all path's dirs. Also `exist_ok=
+=3DFalse`.
+
+shutil.copy(from, to) =
+ # Copies the file. 'to' can exist or=
+ be a dir.
+shutil.copy2(from, to) # Also cop=
+ies creation and modification time.
+shutil.copytree(from, to) # Copies t=
+he directory. 'to' must not exist.
+
+os.rename(from, to) =
+ # Renames/moves the file or director=
+y.
+os.replace(from, to) # Same, bu=
+t overwrites file 'to' even on Windows.
+shutil.move(from, to) # Rename()=
+ that moves into 'to' if it's a dir.
+
+os.remove(<path>) =
+ # Deletes the file.
+os.rmdir(<path>) # De=
+letes the empty directory.
+shutil.rmtree(<path>) # De=
+letes the directory.
+
+<pipe> =3D os.popen('<command>') # Executes co=
+mmand in sh/cmd. Returns its stdout pipe.
+<str> =3D <pipe>.read(size=3D-1) # Reads 'size' chars or until EOF.=
+ Also readline/s().
+<int> =3D <pipe>.close() # Closes the pipe. Returns None on success (returncode 0).
+
'bc', input=3D'1 + 1\n', capture_output=3DTrue, text=3DTrue)
+CompletedProcess(args=3D'bc', returncode=
+=3D0, stdout=3D'2\n', stderr=3D'')
+
subprocess.run(
from shlex import=
+span> split
+'echo 1 + 1 > test.in')
+ subprocess.run(split('bc -s'), stdin=3Dopen('test.in'), stdout=3Dopen('test.out'<=
+/span>, 'w'))
+CompletedProcess(args=3D['bc', '-s'], returncode=3D0=
+)
+ open('test.out').read()
+'2\n'
+ os.popen(
Text file format for storing c= +ollections of strings and numbers.
import json
+<str> =3D json.dumps(<object>) # Converts object to JSON string.
+<object> =3D json.loads(<str>) # Converts JSON string to object.
+
=
+<=
+span class=3D"hljs-keyword">def read_json=
+_file(filename):
+ with open(filename, encoding=3D'utf-8') as file:
+ return json.load(file)
+
def write_to_js= +on_file(filename, an_object): + with open(filename, 'w', encoding=3D'utf-8') as file: + json.dump(an_object, file, ensure_ascii=3DFalse, indent=3D2) +
Binary file format for= + storing Python objects.
import pickle
+<bytes> =3D pickle.dumps(<object>) # Converts object to bytes object.
+<object> =3D pickle.loads(<bytes>) # Converts bytes object to object.
+
def read_pickle_file=
+span>(filename):
+ with open(filename, 'rb') as file:
+ return pickle.load(file)
+
def write_to_pickle_fil=
+e(filename, an_object):
+ with open(filename, 'wb') as file:
+ pickle.dump(an_object, file)
+
<reader> =3D csv.reader(<file>) # Also: `dialect=3D'excel', delimiter=3D','`.
+<list> =3D next(<reader>) # Returns next row as a list of strings.
+<list> =3D list(<reader>) # Returns a list of remaining rows.
+
'newline=3D""'
argument, or newlines embe=
+dded inside quoted fields will not be interpreted correctly!<writer> =3D csv.writer(<file>) # Also: `dialect=3D'excel', delimiter=3D','`.
+<writer>.writerow(<collection>) # Encodes objects using `str(<el>)`.
+<writer>.writerows(<coll_of_coll>) # Appends multiple rows.
+
'newline=3D""'
argument, or '\r' will be =
+added in front of every '\n' on platforms that use '\r\n' line endings!'dialec=
+t'
- Master parameter that sets the default values. String or=
+ a 'csv.Dialect' object.'delimi=
+ter'
- A one-character string used to separate fields.'quotec=
+har'
- Character for quoting fields that contain special char=
+acters.'double=
+quote'
- Whether quotechars inside fields are/get doubled or =
+escaped.'skipin=
+itialspace'
- Is space character at the start of the field st=
+ripped by the reader.'linete=
+rminator'
- How writer terminates rows. Reader is hardcoded t=
+o '\n', '\r', '\r\n'.'quotin=
+g'
- 0: As necessary, 1: All, 2: All but numbers which are re=
+ad as floats, 3: None.'escape=
+char'
- Character for escaping quotechars if doublequote is F=
+alse.=E2=94=8F=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 excel =E2=94=82 excel-tab =
+=E2=94=82 unix =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 delimiter =E2=94=82 ',' =E2=94=82 '\t' =
+=E2=94=82 ',' =E2=94=83
+=E2=94=83 quotechar =E2=94=82 '"' =E2=94=82 '"' =
+=E2=94=82 '"' =E2=94=83
+=E2=94=83 doublequote =E2=94=82 True =E2=94=82 True =
+=E2=94=82 True =E2=94=83
+=E2=94=83 skipinitialspace =E2=94=82 False =E2=94=82 False =
+=E2=94=82 False =E2=94=83
+=E2=94=83 lineterminator =E2=94=82 '\r\n' =E2=94=82 '\r\n' =
+=E2=94=82 '\n' =E2=94=83
+=E2=94=83 quoting =E2=94=82 0 =E2=94=82 0 =
+=E2=94=82 1 =E2=94=83
+=E2=94=83 escapechar =E2=94=82 None =E2=94=82 None =
+=E2=94=82 None =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=9B
+
def read_csv_file=
+span>(filename, dialect=3D'excel'):
+ with open(filename, encoding=3D'utf-8' , newline=3D'') as file:
+ return list(csv.reader(file, di=
+alect))
+
def write_to_csv_file=
+(filename, rows, dialect=3D'excel'):
+ with open(filename, 'w', encoding=3D'utf-8', newline=3D'') as file:
+ writer =3D csv.writer(file, dialect)
+ writer.writerows(rows)
+
A server-less database= + engine that stores each database into a separate file.
impo= +rt sqlite3 +<conn> =3D sqlite3.connect(<path>) # Opens existing or new file. Also ':memory:'. +<conn>.close() # Closes the connection. +
<cursor> =3D <conn>.execute('=
+<query>') # Can raise =
+a subclass of sqlite3.Error.
+<tuple> =3D <cursor>.fetchone() # Returns next row. Also next(<cursor>).
+<list> =3D <cursor>.fetchall() # Returns remaining rows. Also list(<cursor>).
+
<conn>.execute('<query>') # Can raise a subc=
+lass of sqlite3.Error.
+<conn>.commit() # Saves all changes since the last commit.
+<conn>.rollback() # Discards all changes since the last commit.
+
with <conn>: =
+ # Exits the block with commit(=
+) or rollback(),
+ <conn>.execute('<query>'=
+) # depending on whether any=
+ exception occurred.
+
<conn>.execute('<q=
+uery>', <list/tuple>) =
+# Replaces '?'s in query with values.
+<conn>.execute('<query>', &l=
+t;dict/namedtuple>) # Replaces ':<key=
+>'s with values.
+<conn>.executemany('<query>'=
+, <coll_of_above>) # Runs execute() mul=
+tiple times.
+
Values are not actually sa=
+ved in this example because 'conn.commit()'
is omitted!
'test.db')
+'CREATE TABLE person (person_id INTEGER PRIMARY KEY, name, heig=
+ht)')
+ conn.execute('INSERT INTO person VALUES (NULL, ?, ?)', ('Jean-Luc', 187)=
+).lastrowid
+1
+ conn.execute('SELECT * FROM person').fetchall()
+[(1, 'Jean-L=
+uc', 187)]
+ conn.execute(
conn =3D sqlite3.connect(
# $ pip3 install sqlalchemy
+from sqlalchemy import create_engine, text
+<engine> =3D create_engine('<url>'<=
+/span>) # Url: 'dialect://user:p=
+assword@host/dbname'.
+<conn> =3D <engine>.connect() # Creates a connection. Also <conn>.close().
+<cursor> =3D <conn>.execute(text('&=
+lt;query>'), =E2=80=A6) # Replaces=
+ ':<key>'s with keyword arguments.
+with <conn>.begin(): ... =
+ # Exits the block with commit o=
+r rollback.
+
=E2=94=8F=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 Dialect =E2=94=82 pip3 install =E2=94=82 import =E2=94=82 =
+ Dependencies =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 mysql =E2=94=82 mysqlclient =E2=94=82 MySQLdb =E2=94=82 ww=
+w.pypi.org/project/mysqlclient =E2=94=83
+=E2=94=83 postgresql =E2=94=82 psycopg2 =E2=94=82 psycopg2 =E2=94=82 ww=
+w.pypi.org/project/psycopg2 =E2=94=83
+=E2=94=83 mssql =E2=94=82 pyodbc =E2=94=82 pyodbc =E2=94=82 ww=
+w.pypi.org/project/pyodbc =E2=94=83
+=E2=94=83 oracle =E2=94=82 oracledb =E2=94=82 oracledb =E2=94=82 ww=
+w.pypi.org/project/oracledb =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=9B
+
+Bytes object is an immutab= +le sequence of single bytes. Mutable version is called bytearray.<= +/p>
<bytes> =3D b'<str>' # Only accepts ASCII characters and \x00-\xff.
+<int> =3D <bytes>[<index>] # Returns an int in range from 0 to 255.
+<bytes> =3D <bytes>[<slice>] # Returns bytes even if it has only one element.
+<bytes> =3D <bytes>.join(<coll_of_bytes>) # Joins elements using bytes as a separator.
+
<bytes> =3D bytes(<coll_of_ints>) # Ints must be in range from 0 to 255.
+<bytes> =3D bytes(<str>, 'utf-8') # Or: <str>.encode('ut=
+f-8')
+<bytes> =3D <int>.to_bytes(n_bytes, =E2=80=A6) # `byteorder=3D'big/little', signed=3DFalse`.
+<bytes> =3D bytes.fromhex('<hex>'=
+span>) # Hex pairs can be separated=
+ by whitespaces.
+
<list> =3D list(<bytes>) # Returns ints in range from 0 to 255.
+<str> =3D str(<bytes>, 'utf-8') # Or: <bytes>.decode('=
+utf-8')
+<int> =3D int.from_bytes(<bytes>, =E2=80=A6) # `byteorder=3D'big/little', signed=3DFalse`.
+'<hex>' =3D <bytes>.hex() =
+ # Returns hex pairs. Accepts=
+ `sep=3D<str>`.
+
def read_bytes(filename):
+ with open(filename, 'rb') as file:
+ return file.read()
+
def write_bytes<=
+span class=3D"hljs-params">(filename, bytes_obj):
+ with open(filename, 'wb') as file:
+ file.write(bytes_obj)
+
from struct import pack,=
+ unpack
+<bytes> =3D pack('<format>',=
+ <el_1> [, ...]) # Packages arguments o=
+r raises struct.error.
+<tuple> =3D unpack('<format>', <bytes>) # Use iter_unpack() fo=
+r iterator of tuples.
+
'>hhl', 1, 2, 3)
+b'\x00\x01\x00\x02\x00\x00\x00\x03'
+ unpack('>hhl', b'\x00\x01\x00\x02\x00\=
+x00\x00\x03')
+(1, 2=
+, 3)
+
pack(
+'=3D'=
+span>
- System's byte order (usually little-endian).'<'<=
+/span>
- Little-endian.'>'<=
+/span>
- Big-endian (also '!'
).'c'
- A bytes object with a single element. For pad byte use 'x'
.'<n=
+>s'
- A bytes object=
+ with n elements.'b'
- char (1/1)'h'
- short (2/2)'i'
- int (2/4)'l'
- long (4/4)'q'
- long long (8/8)'f'
- float (4/4)'d'
- double (8/8)List that can only hold nu= +mbers of a predefined type. Available types and their minimum sizes in byte= +s are listed above. Sizes and byte order are always determined by the syste= +m, however bytes of each element can be swapped with byteswap() method.
from array import ar=
+ray
+<array> =3D array('<typecode>', <collection>) # Array from collec=
+tion of numbers.
+<array> =3D array('<typecode>', <bytes>) # Array from bytes =
+object.
+<array> =3D array('<typecode>', <array>) # Treats array as a=
+ sequence of numbers.
+<bytes> =3D bytes(<array>) # Or: <array>.tobytes()
+<file>.write(<array>) # Writes array to the binary file.
+
<mview> =3D mem=
+oryview(<bytes/bytearray/array>) # Immu=
+table if bytes, else mutable.
+<real> =3D <mview>[<index>] # Returns an int or a float.
+<mview> =3D <mview>[<slice>] # Mview with rearranged elements.
+<mview> =3D <mview>.cast('<typec=
+ode>') # Casts memoryview =
+to the new format.
+<mview>.release() # Releases the object's memory buffer.
+
<bytes> =3D bytes(&l=
+t;mview>) # Returns a=
+ new bytes object.
+<bytes> =3D <bytes>.join(<coll_of_mviews>) # Joins mviews using bytes object as sep.
+<array> =3D array('<typecode>', <mview>) # Treats mview as a=
+ sequence of numbers.
+<file>.write(<mview>) # Writes mview to the binary file.
+
+<list> =3D list(<=
+;mview>) # Returns a=
+ list of ints or floats.
+<str> =3D str(<mview>, 'utf-8') # Treats mview as a bytes=
+ object.
+<int> =3D int.from_bytes(<mview>, =E2=80=A6) # `byteorder=3D'big/little', signed=3DFalse`.
+'<hex>' =3D <mview>.hex() =
+ # Treats mview as a bytes=
+ object.
+
+A thread-safe list with ef= +ficient appends and pops from either side. Pronounced "deck".
<= +pre>from collections import deque
+<deque> =3D deque(<collection>, maxlen=3DNone)
+
<deque>.appendleft(&=
+lt;el>) # Opposite el=
+ement is dropped if full.
+<deque>.extendleft(<collection>) # Collection gets reversed.
+<el> =3D <deque>.popleft() # Raises IndexError if empty.
+<deque>.rotate(n=3D1) =
+ # Rotates elements to the right=
+.
+
+from threading import Th=
+read, RLock, Semaphore, Event, Barrier
+from concurrent.futures import ThreadPoolExecutor, as_completed
+
<Thread> =3D Thread(target=3D<function>) # Use `args=3D<collection>` to set the argum=
+ents.
+<Thread>.start() # Starts the thread.
+<bool> =3D <Thread>.is_alive() # Checks if the thread has finished executing.
+<Thread>.join() # Waits for the thread to finish.
+
'kw=
+args=3D<dict>'
to pass keyword arguments to the functio=
+n.'da=
+emon=3DTrue'
, or the program will not be able to exit while t=
+he thread is alive.<lock> =3D RLock() # Lock that can only be released by acquirer.
+<lock>.acquire() # Waits for the lock to be available.
+<lock>.release() # Makes the lock available again.
+
with <lock>: =
+ # Enters the block by calling=
+ acquire() and
+ ... # exits it with release(), even on error.
+
<Semaphore> =3D Semaphore(v= +alue=3D1) # Lock that can be acquired by 'value' threads. +<Event> =3D Event() # Method wait() blocks until set() is called. +<Barrier> =3D Barrier(n_times) # Wait() blocks until it's called n_times. +
<Queue> =3D queue.Queue(maxsize=3D0=
+) # A thread-safe FIFO qu=
+eue. Also LifoQueue.
+<Queue>.put(<el>) # Blocks until queue stops being full.
+<Queue>.put_nowait(<el>) # Raises queue.Full exception if full.
+<el> =3D <Queue>.get() # Blocks until queue stops being empty.
+<el> =3D <Queue>.get_nowait() # Raises queue.Empty exception if empty.
+
<Exec> =3D ThreadPoolExecutor(max_w=
+orkers=3DNone) # Or: `with ThreadPoolExecutor() as <name>: =E2=80=A6`
+<iter> =3D <Exec>.map(<func>, <args_1>, ...) # Multithreaded and non-lazy map(). Keeps order.=
+
+<Futr> =3D <Exec>.submit(<func>, <arg_1>, ...) # Creates a thread and returns its Future obj.=
+span>
+<Exec>.shutdown(wait=3DTrue) =
+ # Blocks until all threads fin=
+ish executing.
+
<bool> =3D <Futur=
+e>.done() # Checks if=
+ the thread has finished executing.
+<obj> =3D <Future>.result(timeout=3DNone) # Waits for thread to =
+finish and returns result.
+<bool> =3D <Future>.cancel() # Returns False if thread is already running.
+<iter> =3D as_completed(<coll_of_Futures>) # Each Future is yielded as it completes.
+
+Module of func= +tions that provide the functionality of operators.
import operator as op
+<obj> =3D op.add/sub/mul/truediv/floordiv/mod(<obj>, <ob=
+j>) # +, -, *, /, //, %
+<int/set> =3D op.and_/or_/xor(<int/set>, <int/set>) =
+ # &, |, ^
+<bool> =3D op.eq/ne/lt/le/gt/ge(<sortable>, <sortable>=
+) # =3D=3D, !=3D, <, <=3D, >=
+, >=3D
+<func> =3D op.itemgetter/attrgetter/methodcaller(<obj> [, ..=
+.]) # [index/key], .name, .name()
+
elementwise_sum =3D map(o=
+p.add, list_a, list_b)
+sorted_by_second =3D sorted(<collection>, key=3Dop.itemgetter(1))
+sorted_by_both =3D sorted(<collection>, key=3Dop.itemgetter(1, 0))
+product_of_elems =3D functools.reduce(op.mul, <collection>)
+union_of_sets =3D functools.reduce(op.or_, <coll_of_sets>)
+first_element =3D op.methodcaller('pop', 0)(<list>)
+
+'=
+<bool> =3D <bool> &|^ <bool>'
and '<int> =3D <boo=
+l> &|^ <int>'
.Inspecting code at runtime.
<list> =
+=3D dir() # Names =
+of local variables (incl. functions).
+<dict> =3D vars() # Dict of local variables. Also locals().
+<dict> =3D globals() # Dict of global variables.
+
<list> =3D dir(<object>) # Names of object's attributes (incl. methods).<=
+/span>
+<dict> =3D vars(<object>) # Dict of writable attributes. Also <obj>.__dict__.
+<bool> =3D hasattr(<object>, '<a=
+ttr_name>') # Checks if getattr() r=
+aises an AttributeError.
+value =3D getattr(<object>, '<attr_na=
+me>') # Raises AttributeError if at=
+tribute is missing.
+setattr(<object>, '<attr_name>', value) # Only works on objects with '_=
+_dict__' attribute.
+delattr(<object>, '<attr_name>') # Same. Also `del <object>=
+;.<attr_name>`.
+
<Sig> =3D inspect.signature(<function>) =
+# Function's Signature object.
+<dict> =3D <Sig>.parameters # Dict of Parameter objects.
+<memb> =3D <Param>.kind # Member of ParameterKind enum.
+<obj> =3D <Param>.default # Default value or Parameter.empty.
+<type> =3D <Param>.annotation # Type or Parameter.empty.
+
Code that generates code.
Type is the root class. If only passed an object it ret= +urns its type (class). Otherwise it creates a new class.
<=
+code class=3D"python language-python hljs"><class> =3D type('<class_name>', <tuple_of_parents>, &=
+lt;dict_of_class_attributes>)
'Z', (), =
+{'a': 'abcde=
+', 'b': 12345})
+ z =3D Z()
+
Z =3D type(
+A class that creates cl= +asses.
def my_meta_class(name, pare=
+nts, attrs):
+ attrs['a'] =3D 'abcde'
+ return type(name, parents, attrs)
+
class MyMetaClass (type=
+):
+ def <=
+span class=3D"hljs-title">__new__(cls, n=
+ame, parents, attrs):
+ attrs['a'] =3D 'abcde'
+ return type.__new__(cls, name, =
+parents, attrs)
+
def __new__(cls):=
+ return super().__new__(cls)).
Right= + before a class is created it checks if it has the 'metaclass' attribute de= +fined. If not, it recursively checks if any of his parents has it defined a= +nd eventually comes to type().
cl=
+ass MyClass(metaclass=3DMyMetaClass):
+ b =3D 12345
+
'abcde', 12=
+345)
+
MyClass.a, MyClass.b
+(
+type(MyClass) =3D=3D MyMetaClass # MyClass is an instance of MyMetaClass.
+type(MyMetaClass) =3D=3D type # MyM=
+etaClass is an instance of type.
+
=E2=94=8F=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=93
+=E2=94=83 Classes =E2=94=82 Metaclasses =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 MyClass =E2=86=90=E2=94=80=E2=94=80=E2=95=B4MyMetaClass =E2=94=
+=83
+=E2=94=83 =E2=94=82 =E2=86=91 =E2=94=83
+=E2=94=83 object =E2=86=90=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=95=B4type =E2=86=90=E2=95=AE =E2=94=83
+=E2=94=83 =E2=94=82 =E2=94=82 =E2=95=B0=E2=94=80=E2=94=80=
+=E2=95=AF =E2=94=83
+=E2=94=83 str =E2=86=90=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=95=AF =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=9B
+
+MyClass.__base__ =3D=3D object <=
+span class=3D"hljs-comment"># MyClass is a subclass of object.
+MyMetaClass.__base__ =3D=3D type # MyM=
+etaClass is a subclass of type.
+
=E2=94=8F=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=93
+=E2=94=83 Classes =E2=94=82 Metaclasses =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 MyClass =E2=94=82 MyMetaClass =E2=94=83
+=E2=94=83 =E2=86=91 =E2=94=82 =E2=86=91 =E2=94=83
+=E2=94=83 object=E2=95=B6=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=86=92 type =E2=94=83
+=E2=94=83 =E2=86=93 =E2=94=82 =E2=94=83
+=E2=94=83 str =E2=94=82 =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=9B
+
+from ast import literal_=
+eval
+ literal_eval('[1, 2, 3]')
+[1, 2=
+, 3]
+ literal_eval('1 + 2')
+ValueError: malformed node or string
+
'async'
and its call with 'await'
.'asynci=
+o.run(<coroutine>)'
is the main entry point for asynchr=
+onous programs.import asyncio, collections, curses, curses.textpa=
+d, enum, random
+
+P =3D collections.namedtuple('P', 'x y') # =
+Position
+D =3D enum.Enum('D', 'n e s w') # =
+Direction
+W, H =3D 15, 7 # =
+Width, Height
+
+def main(screen):
+ curses.curs_set(0) =
+ # Makes cursor invisible.
+ screen.nodelay(True) =
+ # Makes getch() non-blocking.
+ asyncio.run(main_coroutine(screen)) # Starts running asyncio code.
+
+async def main_corout=
+ine(screen):
+ moves =3D asyncio.Queue()
+ state =3D {'*': P(0, 0), **{id_: P(W//2, H//2)=
+ for id_ i=
+n range(10)}}
+ ai =3D [random_controller(id_, moves) f=
+or id_ in range(10)]
+ mvc =3D [human_controller(screen, moves), model(moves, state), view(s=
+tate, screen)]
+ tasks =3D [asyncio.create_task(cor) for cor in ai + mvc]
+ await asyncio.wait(tasks, return_wh=
+en=3Dasyncio.FIRST_COMPLETED)
+
+async def random_cont=
+roller(id_, moves):
+ while =
+True:
+ d =3D random.choice(list(D))
+ moves.put_nowait((id_, d))
+ await asyncio.sleep(random.tria=
+ngular(0.01, 0.65))
+
+async def human_contr=
+oller(screen, moves):
+ while =
+True:
+ key_mappings =3D {258: D.s, 259: D.n, 260: D.w, 261: D.e}
+ if d :=3D key_mappings.get(scre=
+en.getch()):
+ moves.put_nowait(('*', d))
+ await asyncio.sleep(0.005)
+
+async def model(moves, state):
+ while state['*'] not in (state[id_] for id=
+_ in range(=
+10)):
+ id_, d =3D await moves.get()
+ x, y =3D state[id_]
+ deltas =3D {D.n: P(0, -1), D.e: P(1, =
+0), D.s: P(0=
+, 1), D.w: P(-1, 0)}
+ state[id_] =3D P((x + deltas[d].x) % W, (y + deltas[d].y) % H)
+
+async def view=
+(state, screen):
+ offset =3D P(curses.COLS//2 - W//2, curses.LINES//2 - H//2)
+ while =
+True:
+ screen.erase()
+ curses.textpad.rectangle(screen, offset.y-1, offset.x-1, offset.y+H, off=
+set.x+W)
+ for id_, p in state.items():
+ screen.addstr(offset.y + (p.y - state['*'].y + H//2) % H,
+ offset.x + (p.x - state['*'].x + W//2) % W, str(id_))
+ screen.refresh()
+ await asyncio.sleep(0.005)
+
+if __name__ =3D=3D '__main__':
+ curses.wrapper(main)
+
# $ pip3 install tqdm
+=
+from tqdm import tqdm
+=
+from time import sleep
+=
+for el in tqdm([1, 2, 3], desc=3D'Processing'):
+=
+1)
+Processing: 100%|=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=
+=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=
+=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88| 3/3 [00:03<00:00, 1.0=
+0s/it]
+ sleep(
# $ pip3 install matplotlib
+import matplotlib.pyplot as plt
+plt.plot/bar/scatter(x_data, y_data [, label=3D<str>]) # Or: plt.plot(y_data)
+plt.legend() # Adds a legend.
+plt.savefig(<path>) # Saves the figure.
+plt.show() # Displays the figure.
+plt.clf() # Clears the figure.
+
# $ pip3 install tabula=
+te
+import csv, tabulate
+with open('=
+test.csv', encoding=3D'utf-8', ne=
+wline=3D'') as file:
+ rows =3D csv.reader(file)
+ header =3D next(rows)
+ table =3D tabulate.tabulate(rows, header)
+print(table)
+
impor= +t curses, curses.ascii, os +from curses import A_REVERSE, KEY_DOWN, KEY_UP, KEY_LEFT, KEY_RIGHT, KEY_ENTER + +def main(screen): + ch, first, selected, paths =3D 0, 0, 0, o= +s.listdir() + while ch !=3D curses.ascii.ESC: + height, width =3D screen.getmaxyx() + screen.erase() + for y, filename in enumerate(paths[first : first+height]): + color =3D A_REVERSE if file= +name =3D=3D paths[selected] else 0 + screen.addstr(y, 0, filename= +[:width-1], color) + ch =3D screen.getch() + selected +=3D (ch =3D=3D KEY_DOWN) - (ch =3D=3D KEY_UP) + selected =3D max(0, min(len(path= +s)-1, selected)) + first +=3D (selected >=3D first + height) - (selected < first= +) + if ch in [KEY_LEFT, KEY_RIGHT, KEY_ENTER, ord('\n'), ord('\r')]: + new_dir =3D '..' if ch =3D=3D KEY_LEFT else paths[selected] + if os.path.isdir(new_dir): + os.chdir(new_dir) + first, selected, paths =3D 0, 0, os.listdir() + +if __name__ =3D=3D '__main__': + curses.wrapper(main) +
import logging
+
logging.basicConfig(filena=
+me=3D<path>) # Configures t=
+he root logger.
+logging.debug/info/warning/error/critical(<str>) # Logs to the root logger.
+<Logger> =3D logging.getLogger(__name__) # Logger named after the module.
+<Logger>.<level>(<str>) # Messages propagate to the root logger.
+<Logger>.exception(<str>) # Calls error() with caught exception.
+
+logging.basicConfig(
+ filename=3DNone, =
+ # Logs to console by default.
+ format=3D'%(levelname)s:%(name)s:%(message)=
+s', # Add `%(asctime)s` for datetime.<=
+/span>
+ level=3Dlogging.WARNING, # Drops messages with lower priority.
+ handlers=3D[logging.StreamHandler()] # Uses FileHandler if filename is set.
+)
+
<Formatter> =3D logg=
+ing.Formatter('<format>') # Creates a Formatter.
+<Handler> =3D logging.FileHandler(<path>) # Creates a Handler.
+<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 handlers and parent.
+
+'<parent>.<name=
+>'
.'hand=
+lers.RotatingFileHandler'
creates and deletes log files based=
+ on 'maxBytes' and 'backupCount' arguments.'WARNIN= +G') + logger =3D logging.getLogger(= +'my_module') + handler =3D logging.FileHandl= +er('test.log') + formatter =3D logging.Formatt= +er('%(asctime)s %(levelname)s:%(name)s:%(messag= +e)s') + handler.setFormatter(formatte= +r) + logger.addHandler(handler) + logger.critical('Running out of disk space.') +CRITICAL:my_module:Running out of disk space. + print(open('test.log').read()) +2023-02-07 23:21:01,430 CRITICAL:my_module:Running out of disk space. + logging.basicConfig(level=3D
# $ pip3 install reques=
+ts beautifulsoup4
+import requests, bs4, os, sys
+
+WIKI_URL =3D 'https://en.wikipedia.org/wiki/Pyt=
+hon_(programming_language)'
+try:
+ html =3D requests.get(WIKI_URL).text
+ document =3D bs4.BeautifulSoup(html, 'htm=
+l.parser')
+ table =3D document.find('table'=
+, class_=3D'infobox vevent')
+ python_url =3D table.find('th', text=
+=3D'Website').next_sibling.a['href']
+ version =3D table.find('th', text=
+=3D'Stable release').next_sibling.string=
+s.__next__()
+ logo_url =3D table.find('img')['src']
+ logo =3D requests.get(f'https:{logo_url}').content
+ filename =3D os.path.basename(logo_url)
+ with open(filename, 'wb') as file:
+ file.write(logo)
+ print(f'{python_=
+url}, {version}, file://{os.path.abspath(filename)}')
+except requests.exceptions.ConnectionEr=
+ror:
+ print("You've got problems with connection.=
+", file=3Dsys.stderr)
+
Flask is a micro web framework/ser=
+ver. If you just want to open a html file in a web browser use 'webbrowser.open(<path>)=
+'
instead.
# $ pip3 install flask
+from flask import Flask, send_from_directory, render_template_string, request
+
app =3D Flask(__name__)
+app.run(host=3DNone, debug=3DNone)
+
+'http://localhost:5000'
. Use 'host=3D"0.0.0.0"'
to run =
+externally.def serve_file(filenam=
+e):
+ return send_from_directory('dirname/', filename)
+
+
def serve_html(sport)<=
+/span>:
+ return render_template_string('<h1>{{title}}</h1>', title=3Dspo=
+rt)
+
+
'abort(<int>)'
and to redirect use=
+ 'redirect(<url&=
+gt;)'
.'reques=
+t.args[<str>]'
returns parameter from the query string =
+(URL part after '?').'se=
+ssion[key] =3D value'
to store session data like username, et=
+c.def serve_json(sport)<=
+/span>:
+ team =3D request.form['team']
+ return {'team': team, 'odds': [2.09, 3.74, 3.68]}
+
+
<= +code class=3D"python language-python hljs"># $= + pip3 install requests += +import threading, requests + threading.Thread(target=3Dapp= +.run, daemon=3DTrue).start() + url =3D 'http://localhost:5000/football/odds' + request_data =3D {'team': 'arsenal f.c.'<= +/span>} +'team': 'ar= +senal f.c.', 'odds': [2.09, 3.74,3.68 ]} + response =3D requests.post(ur= +l, data=3Drequest_data) + response.json() +{
from time <=
+span class=3D"hljs-keyword">import perf_counter
+start_time =3D perf_counter()
+...
+duration_in_seconds =3D perf_counter() - start_time
+
from timeit i=
+mport timeit
+ timeit('list(range(10000))', number=3D100=
+0, globals=3Dglobals(), setup=3D'pass'=
+span>)
+0.19373
+
$ pip3 install line_profiler
+$ echo "@profile
+def main():
+ a =3D list(range(10000))
+ b =3D set(range(10000))
+main()" > test.py
+$ kernprof -lv test.py
+Line # Hits Time Per Hit % Time Line Contents
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D
+ 1 @profile
+ 2 def main():
+ 3 1 219.0 219.0 31.1 a =3D list(range(10000))
+ 4 1 487.0 487.0 68.9 b =3D set(range(10000))
+
$ pip3 install gprof2dot snakeviz; apt/brew insta=
+ll graphviz
+$ tail -n 4 test.py > test.py
+$ python3 -m cProfile -o test.prof test.py
+$ gprof2dot -f pstats test.prof | dot -Tpng -o test.png; xdg-open/open test=
+.png
+$ snakeviz test.prof
+
=E2=94=8F=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=93
+=E2=94=83 pip3 install =E2=94=82 How to run =E2=94=82 =
+Target =E2=94=82 Type =E2=94=82 Live =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 py-spy =E2=94=82 py-spy top -- python3 test.py =E2=94=82 =
+ CPU =E2=94=82 Sampling =E2=94=82 Yes =E2=94=83
+=E2=94=83 pyinstrument =E2=94=82 pyinstrument test.py =E2=94=82 =
+ CPU =E2=94=82 Sampling =E2=94=82 No =E2=94=83
+=E2=94=83 scalene =E2=94=82 scalene test.py =E2=94=82 CP=
+U+Memory =E2=94=82 Sampling =E2=94=82 No =E2=94=83
+=E2=94=83 memray =E2=94=82 memray run --live test.py =E2=94=82 =
+Memory =E2=94=82 Tracing =E2=94=82 Yes =E2=94=83
+=E2=94=83 filprofiler =E2=94=82 fil-profile run test.py =E2=94=82 =
+Memory =E2=94=82 Tracing =E2=94=82 No =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=9B
+
Array manipulation mini-la= +nguage. It can run up to one hundred times faster than the equivalent Pytho= +n code. An even faster alternative that runs on a GPU is called CuPy.
# $ pip3 install numpy
+import numpy as np
+
<array> =3D np.array=
+(<list/list_of_lists>) # =
+Returns a 1d/2d NumPy array.
+<array> =3D np.zeros/ones(<shape>) # Also np.full(<shape>, <el>).
+<array> =3D np.arange(from_inc, to_exc, =C2=B1step) # Also np.linspace(start, stop, len).
+<array> =3D np.random.randint(from_inc, to_exc, <shape>) # Also np.random.random(<shape>).
+
+<view> =3D <arra=
+y>.reshape(<shape>) # Also `<array>.shape =3D <shape>`.
+<array> =3D <array>.flatten() # Also `<view> =3D <array>.ravel()`.
+<view> =3D <array>.transpose() # Or: <array>.T
+
+<array> =3D np.copy/=
+abs/sqrt/log/int64(<array>) # =
+Returns new array of the same shape.
+<array> =3D <array>.sum/max/mean/argmax/all(axis) # Passed dimension gets aggregated.
+<array> =3D np.apply_along_axis(<func>, axis, <array>) =
+ # Func can return a scalar or array.
+
+<array> =3D np.conca=
+tenate(<list_of_arrays>, axis=3D0)=
+ # Links arrays along first axis (rows).<=
+/span>
+<array> =3D np.row_stack/column_stack(<list_of_arrays>) # Treats 1d arrays as rows or columns.
+<array> =3D np.tile/repeat(<array>, <int/list>) =
+ # Tiles array or repeats its elements.
+
+<el=
+> =3D <2d_array>[row_index, column_index] # <3d_a>[table_i, row_i, column_i]
+<1d_view> =3D <2d_array>[row_index] # <3d_a>[table_i, row_i]
+<1d_view> =3D <2d_array>[:, column_index] # <3d_a>[table_i, :, column_i]
+<2d_view> =3D <2d_array>[rows_slice, columns_slice] # <3d_a>[table_i, rows_s, columns_s]
+
<2d_array> =3D <2d_array>[row_in=
+dexes] # <3d_a>[table=
+_i/is, row_is]
+<2d_array> =3D <2d_array>[:, column_indexes] # <3d_a>[table_i/is, :, column_is]
+<1d_array> =3D <2d_array>[row_indexes, column_indexes] # <3d_a>[table_i/is, row_is, column_is]
+<1d_array> =3D <2d_array>[row_indexes, column_index] # <3d_a>[table_i/is, row_is, column_i]
+
+<2d_bools> =3D <2d_array> >&l=
+t;=3D=3D <el/1d/2d_array> # 1d=
+_array must have size of a row.
+<1d/2d_a> =3D <2d_array>[<2d/1d_bools>] =
+ # 1d_bools must have size of a column.
+
+'obj[i, j]'
to=
+ 'obj[(i, j)]'
!Set of rules by wh= +ich NumPy functions operate on arrays of different sizes and/or dimensions.= +
left =3D [[<=
+span class=3D"hljs-number">0.1], [0.6], [0.8]] =
+# Shape: (3, 1)
+right =3D [ 0.1 , 0.6 , 0.8 ] =
+ # Shape: (3,)
+
left =3D [[0.1], [0.6], [<=
+span class=3D"hljs-number">0.8]] # Shape: (3, 1)
+right =3D [[0.1 , 0.6 , 0.8]] =
+ # Shape: (1, 3) <- !
+
left =3D [[0.1, 0.1, 0.=
+1], # Shape=
+: (3, 3) <- !
+ [0.6, 0.6, 0.6],
+ [0.8, 0.8, 0.8]]
+
+right =3D [[0.1, 0.6, 0.8], =
+ # Shape: (3, 3) <- !
+ [0.1, 0.6, 0.8],
+ [0.1, 0.6, 0.8]]
+
[0.1, =
+0.6, 0.8] =3D> [1, 2, 1]
):0.1, points =3D np.array([0.6, 0.8= +]) + [ 0.1, 0.6= +, 0.8] + wrapped_points =3D points.res= +hape(3, 1) +[[ 0.1], + [ 0.6], + [ 0.8]] + distances =3D wrapped_points = +- points +[[ 0. , -0.5= +, -0.7], + [ 0.5, 0.<= +/span> , -0.2], + [ 0.7, 0.2= +, 0. ]] + distances =3D np.abs(distance= +s) +[[ 0. , 0.5= +, 0.7], + [ 0.5, 0.<= +/span> , 0.2], + [ 0.7, 0.2= +, 0. ]] + i =3D np.arange(3) +[0, 1= +, 2] + distances[i, i] =3D np.inf +[[ inf, 0.5, 0.7], + [ 0.5, inf, 0.2], + [ 0.7, 0.2= +, inf]] + distances.argmin(1) +[1, 2= +, 1] +
# $ pip3 install pillow
+from PIL i=
+mport Image, ImageDraw
+
<Image> =3D Image.ne=
+w('<mode>', (width, height)) # Also `color=3D<int/tuple/str>`.
+<Image> =3D Image.open(<path>) # Identifies format based on file contents.
+<Image> =3D <Image>.convert('<mo=
+de>') # Converts image t=
+o the new mode.
+<Image>.save(<path>) # Selects format based on the path extension.
+<Image>.show() # Opens image in the default preview app.
+
+<int/tuple> =3D <=
+Image>.getpixel((x, y)) # Returns =
+a pixel.
+<Image>.putpixel((x, y), <int/tuple>) # Writes a pixel to the image.
+<ImagingCore> =3D <Image>.getdata() # Returns a flattened view of the pixels.
+<Image>.putdata(<list/ImagingCore>) # Writes a flattened sequence of pixels.
+<Image>.paste(<Image>, (x, y)) # Writes passed image to the image.
+
+<Image> =3D <Imag=
+e>.filter(<Filter>) # `&=
+lt;Filter> =3D ImageFilter.<name>([<args>])`
+<Image> =3D <Enhance>.enhance(<float>) # `<Enhance> =3D ImageEnhance.<name>(<=
+Image>)`
+
+<array> =3D np.array=
+(<Image>) # Creates =
+NumPy array from the image.
+<Image> =3D Image.fromarray(np.uint8(<array>)) # Use <array>.clip(0, 255) to clip the values.
+
+'1'
- 1-bit pixels, black and white, stored with one pixel per byte.=
+'L'
- 8-bit pixels, greyscale.'RGB'=
+span>
- 3x8-bit pixels, true color.'RGBA'<=
+/span>
- 4x8-bit pixels, true color with transparency mask.=
+'HSV'=
+span>
- 3x8-bit pixels, Hue, Saturation, Value color space.=
+WIDTH, HEIGHT =3D 100, 100 +n_pixels =3D WIDTH * HEIGHT +hues =3D (255 * i/n_pixels for i in range= +(n_pixels)) +img =3D Image.new('HSV', (WIDTH, HEIGHT)= +) +img.putdata([(int(h), 255, 255) for h in hues]) +img.convert('RGB').save('test.png') +
from= + random import randint +add_noise =3D lambda value: max(0, min(255, = +value + randint(-20, 20))) +img =3D Image.open('test.png').convert(<= +span class=3D"hljs-string">'HSV') +img.putdata([(add_noise(h), s, v) for h= +, s, v in img.getdata()]) +img.show() +
<ImageDraw> =3D ImageDraw.Draw(<Image>) =
+ # Object for adding 2D graphics to the image=
+.
+<ImageDraw>.point((x, y)) # Draws a point. Truncates floats into ints.
+<ImageDraw>.line((x1, y1, x2, y2 [, ...])) # To get anti-aliasing use Image's resize().
+<ImageDraw>.arc((x1, y1, x2, y2), deg1, deg2) # Always draws in clockwise direction.
+<ImageDraw>.rectangle((x1, y1, x2, y2)) # To rotate use Image's rotate() and paste().
+<ImageDraw>.polygon((x1, y1, x2, y2, ...)) # Last point gets connected to the first.
+<ImageDraw>.ellipse((x1, y1, x2, y2)) # To rotate use Image's rotate() and paste().
+<ImageDraw>.text((x, y), text, font=3D<Font>) # `<Font> =3D ImageFont.truetype(<path>, size=
+)`
+
'fi=
+ll=3D<color>'
to set the primary color.'wi=
+dth=3D<int>'
to set the width of lines or contours.'ou=
+tline=3D<color>'
to set the color of the contours.'#rrggbb[aa]'
string or a color name.# $ pip3 ins=
+tall imageio
+from PIL i=
+mport Image, ImageDraw
+import imageio
+
+WIDTH, HEIGHT, R =3D 126, 126, 10
+frames =3D []
+for velocity in range(1, 16):
+ y =3D sum(range(velocity))
+ frame =3D Image.new('L', (WIDTH, HEI=
+GHT))
+ draw =3D ImageDraw.Draw(frame)
+ draw.ellipse((WIDTH/2-R, y, WIDTH/2+R, y+R*2), fill=3D'white')
+ frames.append(frame)
+frames +=3D reversed(frames[1:-1])
+imageio.mimsave('test.gif', frames, dura=
+tion=3D0.03)
+
import wave
+
<Wave_read> =3D wav=
+e.open('<path>', 'rb') # Opens the WAV=
+ file.
+framerate =3D <Wave_read>.getframerate() # Number of frames per second.
+nchannels =3D <Wave_read>.getnchannels() # Number of samples per frame.
+sampwidth =3D <Wave_read>.getsampwidth() # Sample size in bytes.
+nframes =3D <Wave_read>.getnframes() # Number of frames.
+<params> =3D <Wave_read>.getparams() # Immutable collection of above.
+<bytes> =3D <Wave_read>.readframes(nframes) # Returns next 'nframes' frames.
+
+<Wave_write> =3D wav=
+e.open('<path>', 'wb') # Truncates exi=
+sting file.
+<Wave_write>.setframerate(<int>) # 44100 for CD, 48000 for video.
+<Wave_write>.setnchannels(<int>) # 1 for mono, 2 for stereo.
+<Wave_write>.setsampwidth(<int>) # 2 for CD quality sound.
+<Wave_write>.setparams(<params>) # Sets all parameters.
+<Wave_write>.writeframes(<bytes>) # Appends frames to the file.
+
+=E2=94=8F=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 sampwidth =E2=94=82 min =E2=94=82 zero =E2=94=82 max =
+=E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=A8
+=E2=94=83 1 =E2=94=82 0 =E2=94=82 1=
+28 =E2=94=82 255 =E2=94=83
+=E2=94=83 2 =E2=94=82 -32768 =E2=94=82 0 =E2=94=82 32767 =E2=94=83
+=E2=94=83 3 =E2=94=82 -8388608 =E2=94=82 0 =E2=94=82 8388607 =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=9B
+
def read_wav_file(filename):
+ def <=
+span class=3D"hljs-title">get_int(bytes_=
+obj):
+ an_int =3D int.from_bytes(bytes_obj, 'l=
+ittle', signed=3D(sampwidth !=3D 1))
+ return an_int - 128 * (sampwidth =3D=3D 1=
+span>)
+ with wave.open(filename, 'rb') as file:
+ sampwidth =3D file.getsampwidth()
+ frames =3D file.readframes(-1)
+ bytes_samples =3D (frames[i : i+sampwidth] for i in range(0, len(frames), sampwidth))
+ return [get_int(b) / pow(2, sampwidth * 8 - 1) for<=
+/span> b in bytes_samples]
+
def =
+write_to_wav_file(filename, float_sample=
+s, nchannels=3D1, sampwidth=3D2, framerate=3D44100=
+span>):
+ def <=
+span class=3D"hljs-title">get_bytes(a_fl=
+oat):
+ a_float =3D max(-1, min(1 - 2e-16, a_=
+float))
+ a_float +=3D sampwidth =3D=3D 1
+ a_float *=3D pow(2, sampwidth * =
+8 - 1=
+)
+ return int(a_float).to_bytes(sa=
+mpwidth, 'little', signed=3D(sampwidth !=
+=3D 1))
+ with wave.open(filename, 'wb') as file:
+ file.setnchannels(nchannels)
+ file.setsampwidth(sampwidth)
+ file.setframerate(framerate)
+ file.writeframes(b''.join(get_by=
+tes(f) for f in float_samples))
+
from math import pi, sin
+samples_f =3D (sin(i * 2 * pi * 440 / 44100) =
+for i in=
+span> range(100_000))
+write_to_wav_file('test.wav', samples_f)
+
from random import random
+add_noise =3D lambda value: value + (ra=
+ndom() - 0.5) * 0.03
+samples_f =3D (add_noise(f) for f in read_wav_file('test.wav'))
+write_to_wav_file('test.wav', samples_f)
+
# $ pip3 install sim=
+pleaudio
+from simpleaudio import play_buffer
+with wave.open('test.wav', 'rb') as file:
+ p =3D file.getparams()
+ frames =3D file.readframes(-1)
+ play_buffer(frames, p.nchannels, p.sampwidth, p.framerate)
+
# $ pip3 install pyttsx3=
+
+import pyttsx3
+engine =3D pyttsx3.init()
+engine.say('Sally sells seashells by the seasho=
+re.')
+engine.runAndWait()
+
# $ pip3 install simpleaudio
+import array, itertools as it, math, simpleaudio
+
+F =3D 44100
+P1 =3D '71=E2=99=A9,69=E2=99=AA,,71=E2=99=A9,66=
+=E2=99=AA,,62=E2=99=A9,66=E2=99=AA,,59=E2=99=A9,,'
+P2 =3D '71=E2=99=A9,73=E2=99=AA,,74=E2=99=A9,73=
+=E2=99=AA,,74=E2=99=AA,,71=E2=99=AA,,73=E2=99=A9,71=E2=99=AA,,73=E2=99=AA,,=
+69=E2=99=AA,,71=E2=99=A9,69=E2=99=AA,,71=E2=99=AA,,67=E2=99=AA,,71=E2=99=A9=
+,,'
+get_pause =3D lambda seconds: it.repe=
+at(0, int(seconds * F))
+sin_f =3D lambda i, hz: math.sin(=
+i * 2 * math.pi * hz / F)
+get_wave =3D lambda hz, seconds: (si=
+n_f(i, hz) for i in range(int(seconds * F)))
+get_hz =3D lambda key: 8.176 * 2 ** (in=
+t(key) / 12)
+parse_note =3D lambda note: (get_hz(no=
+te[:2]), 1=
+span>/4 if<=
+/span> '=E2=99=A9' in note else 1/8)
+get_samples =3D lambda note: get_wave(*=
+parse_note(note)) if note else get_pause(1/8)
+samples_f =3D it.chain.from_iterable(get_samples(n) for n in f'{P1},{P1},{P2}'.split(',' ))
+samples_i =3D array.array('h', (int(f =
+* 30000) fo=
+r f in samples_f))
+simpleaudio.play_buffer(samples_i, 1, 2, F)
+
# $ pip3 install pygame
+import pygame as pg
+
+pg.init()
+screen =3D pg.display.set_mode((500, 500))
+rect =3D pg.Rect(240, 240, 20, 20)
+while not<=
+/span> pg.event.get(pg.QUIT):
+ deltas =3D {pg.K_UP: (0, -20), pg.K_RIGHT: (20=
+span>, 0), pg.K_DOWN: (0, 20), pg.K_LEFT: (-20, 0)=
+}
+ for event in pg.event.get(pg.KEYDOWN):
+ dx, dy =3D deltas.get(event.key, (0 , 0))
+ rect =3D rect.move((dx, dy))
+ screen.fill((0, 0, 0))
+ pg.draw.rect(screen, (255, 255, 255), rec=
+t)
+ pg.display.flip()
+
Object for storing recta= +ngular coordinates.
<Rect> =3D pg.Rect(x, y, width, height) # Floats get truncated into ints.
+<int> =3D <Rect>.x/y/centerx/centery/=E2=80=A6 # Top, right, bottom, left. Allows assignments.
+<tup.> =3D <Rect>.topleft/center/=E2=80=A6 # Topright, bottomright, bottomleft. Same.
+<Rect> =3D <Rect>.move((delta_x, delta_y)) # Use move_ip() to move in-place.
+
<bool> =3D <Rect&=
+gt;.collidepoint((x, y)) # Checks i=
+f rectangle contains the point.
+<bool> =3D <Rect>.colliderect(<Rect>) # Checks if two rectangles overlap.
+<int> =3D <Rect>.collidelist(<list_of_Rect>) # Returns index of first colliding Rect or -1.
+<list> =3D <Rect>.collidelistall(<list_of_Rect>) # Returns indexes of all colliding rectangles.
+
+Object for representing imag= +es.
<Surf&g=
+t; =3D pg.display.set_mode((width, height)) =
+# Opens new window and returns its surface.
+<Surf> =3D pg.Surface((width, height)) # New RGB surface. RGBA if `flags=3Dpg.SRCALPHA`.
+<Surf> =3D pg.image.load(<path/file>) # Loads the image. Format depends on source.
+<Surf> =3D pg.surfarray.make_surface(<np_array>) # Also `<np_arr> =3D surfarray.pixels3d(<Surf>=
+;)`.
+<Surf> =3D <Surf>.subsurface(<Rect>) # Creates a new surface from the cutout.
+
<Surf>.fill(color) =
+ # Tuple, Color('#r=
+rggbb[aa]') or Color(<name>).
+<Surf>.set_at((x, y), color) # Updates pixel. Also <Surf>.get_at((x, y)).
+<Surf>.blit(<Surf>, (x, y)) # Draws passed surface to the surface.
+
+from pygame.transform import =
+scale, ...
+<Surf> =3D scale(<Surf>, (width, height)) # Returns scaled surface.
+<Surf> =3D rotate(<Surf>, anticlock_degrees) # Returns rotated and scaled surface.
+<Surf> =3D flip(<Surf>, x_bool, y_bool) # Returns flipped surface.
+
+from pygame.draw import line,=
+ ...
+line(<Surf>, color, (x1, y1), (x2, y2), width) # Draws a line to the surface.
+arc(<Surf>, color, <Rect>, from_rad, to_rad) # Also ellipse(<Surf>, color, <Rect>, width=3D0).=
+
+rect(<Surf>, color, <Rect>, width=3D0) # Also polygon(<Surf&=
+gt;, color, points, width=3D0).
+
+<Font> =3D pg.font.Font(<path/file>, size) # Loads TTF file. Pass None for default font.
+<Surf> =3D <Font>.render(text, antialias, color) # Background color can be specified at the end.
+
<Sound> =3D pg.mixer.Sound(<path/file/bytes>) # Loads WAV file or array of signed shorts.
+<Sound>.play/stop() # Also <Sound>.set_volume(<float>).
+
import collections, dataclasses, enum, io, itertools as it, pygame as pg, urllib.request
+from random import randint
+
+P =3D collections.namedtuple('P', 'x y') #=
+ Position
+D =3D enum.Enum('D', 'n e s w') #=
+ Direction
+W, H, MAX_S =3D 50, 50, P(5, 10) # Widt=
+h, Height, Max speed
+
+def main():
+ def <=
+span class=3D"hljs-title">get_screen()=
+span>:
+ pg.init()
+ return pg.display.set_mode((W*<=
+span class=3D"hljs-number">16, H*16))
+ def <=
+span class=3D"hljs-title">get_images()=
+span>:
+ url =3D 'https://gto76.github.io/python=
+-cheatsheet/web/mario_bros.png'
+ img =3D pg.image.load(io.BytesIO(urllib.request.urlopen(url).read()=
+))
+ return [img.subsurface(get_rect=
+(x, 0)) for=
+ x in range(img.get_width() // <=
+span class=3D"hljs-number">16)]
+ def <=
+span class=3D"hljs-title">get_mario():
+ Mario =3D dataclasses.make_dataclass('M=
+ario', 'rect spd facing_left frame_cycle=
+'.split())
+ return Mario(get_rect(1, 1), P(0, 0), False , it.cycle(range(3)))
+ def <=
+span class=3D"hljs-title">get_tiles():
+ border =3D [(x, y) for x in range(W) for<=
+/span> y in range(H) if x in [0, W-1] or y in [0, H-1]=
+]
+ platforms =3D [(randint(1, W-2), randint(2=
+span>, H-2)) for _ in range(W*H // 10)]
+ return [get_rect(x, y) for x, y in=
+ border + platforms]
+ def <=
+span class=3D"hljs-title">get_rect(x, y)=
+:
+ return pg.Rect(x*16, y*16, 16, 16)
+ run(get_screen(), get_images(), get_mario(), get_tiles())
+
+def run(screen, images=
+, mario, tiles):
+ clock =3D pg.time.Clock()
+ pressed =3D set()
+ while =
+not pg.event.get(pg.QUIT) and cl=
+ock.tick(28):
+ keys =3D {pg.K_UP: D.n, pg.K_RIGHT: D.e, pg.K_DOWN: D.s, pg.K_LEFT:=
+ D.w}
+ pressed |=3D {keys.get(e.key) for e in pg.event.get(pg.KEYDOWN)}
+ pressed -=3D {keys.get(e.key) for e in pg.event.get(pg.KEYUP)}
+ update_speed(mario, tiles, pressed)
+ update_position(mario, tiles)
+ draw(screen, images, mario, tiles, pressed)
+
+def update_speed(mario=
+, tiles, pressed):
+ x, y =3D mario.spd
+ x +=3D 2 * ((D.e in pressed) - (D.w in =
+pressed))
+ x +=3D (x < 0) - (x > 0)
+ y +=3D 1 if D.s not in get_boundaries(mario.rect, tiles) else (D.n in pressed) * =
+-10
+ mario.spd =3D P(x=3Dmax(-MAX_S.x, min(MAX_S.x, x)), y=3Dmax(-MAX_S.y, m=
+in(MAX_S.y, y)))
+
+def update_position(ma=
+rio, tiles):
+ x, y =3D mario.rect.topleft
+ n_steps =3D max(abs(s) for s in mario.spd)
+ for _ =
+in range(n_steps):
+ mario.spd =3D stop_on_collision(mario.spd, get_boundaries(mario.rec=
+t, tiles))
+ mario.rect.topleft =3D x, y =3D x + (mario.spd.x / n_steps), y + (m=
+ario.spd.y / n_steps)
+
+def get_boundaries(rec=
+t, tiles):
+ deltas =3D {D.n: P(0, -1), D.e: P(1, 0 ), D.s: P(0 , 1), D.w: P(-1, 0)}
+ return {d for d, delta in deltas.items=
+() if rect.move(delta).collidelist(tile=
+s) !=3D -1}
+
+def stop_on_collision(=
+spd, bounds):
+ return P(x=3D0 if (D.w in bounds and spd.x=
+ < 0) or=
+ (D.e in bounds and spd.x > 0) else spd.x,
+ y=3D0 if (D.n in bounds and spd.y < 0<=
+/span>) or (D.s in bounds and spd.y > <=
+span class=3D"hljs-number">0) else spd.y)
+
+def draw(screen, image=
+s, mario, tiles, pressed):
+ def <=
+span class=3D"hljs-title">get_marios_image_index():
+ if D.s not in get_boundaries(mario=
+.rect, tiles):
+ return 4
+ return next(mario.frame_cycle) =
+if {D.w, D.e} & pressed else 6
+ screen.fill((85, 168, 255))
+ mario.facing_left =3D (D.w in press=
+ed) if {D.w, D.e} & pressed else mario.facing_left
+ screen.blit(images[get_marios_image_index() + mario.facing_left * 9], mario.rect)
+ for t =
+in tiles:
+ screen.blit(images[18 if t.x in [0, (W-1=
+)*16] or t.y in [0, (H-1)*16] else 19], t)
+ pg.display.flip()
+
+if __name__ =3D=3D '__main__':
+ main()
+
# $ pip3 install pandas matplo=
+tlib
+import pandas as pd, matplotlib.pyplot as =
+plt
+
Ordered dictionary with a name= +.
1=
+, 2], index=3D['x', 'y'], name=3D'a')
+x 1
+y 2
+Name: a, dtype: int64
+
pd.Series([
<Sr> =3D pd.Series(&=
+lt;list>) # Assigns R=
+angeIndex starting at 0.
+<Sr> =3D pd.Series(<dict>) # Takes dictionary's keys for index.
+<Sr> =3D pd.Series(<dict/Series>, index=3D<list>) # Only keeps items with keys specified in index.
+
+<el> =3D <Sr>.=
+loc[key] # Or: <S=
+r>.iloc[index]
+<Sr> =3D <Sr>.loc[keys] # Or: <Sr>.iloc[indexes]
+<Sr> =3D <Sr>.loc[from_key : to_key_inclusive] # Or: <Sr>.iloc[from_i : to_i_exclusive]
+
+<el> =3D <Sr>[=
+key/index] # Or: <S=
+r>.key
+<Sr> =3D <Sr>[keys/indexes] # Or: <Sr>[<keys_slice/slice>]
+<Sr> =3D <Sr>[bools] # Or: <Sr>.loc/iloc[bools]
+
+<Sr> =3D <Sr> =
+><=3D=3D <el/Sr> # Returns a Series of bools.
+<Sr> =3D <Sr> +-*/ <el/Sr> # Items with non-matching keys get value NaN.
+
+<Sr> =3D pd.concat(&=
+lt;coll_of_Sr>) # Concats m=
+ultiple Series into one long Series.
+<Sr> =3D <Sr>.combine_first(<Sr>) # Adds items that are not yet present.
+<Sr>.update(<Sr>) # Updates items that are already present.
+
+<Sr>.plot.line/area/=
+bar/pie/hist() # Generates a Matpl=
+otlib plot.
+plt.show() # Displays the plot. Also plt.savefig(<path>).
+
+<el>=
+; =3D <Sr>.sum/max/mean/idxmax/all() # Or: <Sr>.agg(lambda <Sr>: <el>)
+<Sr> =3D <Sr>.rank/diff/cumsum/ffill/interpl() # Or: <Sr>.agg/transform(lambda <Sr>: <Sr>=
+)
+<Sr> =3D <Sr>.fillna(<el>) # Or: <Sr>.agg/transform/map(lambda <el>: =
+<el>)
+
1,=
+ 2], index=3D['x', 'y'])
+x 1
+y 2
+
sr =3D pd.Series([
+=E2=94=8F=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 'sum' =E2=94=82 ['sum'] =E2=94=82 {<=
+span class=3D"hljs-string">'s': 'sum'} =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=A8
+=E2=94=83 sr.apply(=E2=80=A6) =E2=94=82 =
+3 =E2=94=82 sum 3 =E2=
+=94=82 s 3 =E2=94=83
+=E2=94=83 sr.agg(=E2=80=A6) =E2=94=82 =E2=94=82 =
+ =E2=94=82 =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=9B
+
+=E2=94=8F=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 'rank' =E2=94=82 ['rank'] =E2=94=82 {<=
+span class=3D"hljs-string">'r': 'rank'=
+span>} =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=A8
+=E2=94=83 sr.apply(=E2=80=A6) =E2=94=82 =E2=94=82 rank =
+ =E2=94=82 =E2=94=83
+=E2=94=83 sr.agg(=E2=80=A6) =E2=94=82 x 1 =E2=94=82 x 1 =E2=
+=94=82 r x 1 =E2=94=83
+=E2=94=83 =E2=94=82 y 2 =E2=94=82 y 2 =E2=94=82 =
+ y 2 =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=9B
+
+
+'obj[x, y]'
is converted =
+to 'obj[(x, y)]'
!'<Sr>[key_1, key_2]'
=
+ to get its values.Table with labeled rows = +and columns.
<=
+span class=3D"hljs-meta">>>> pd.DataFrame([[1, 2], [3, 4]], index=3D=
+['a', 'b'], columns=3D['x', 'y'])
+ x y
+a 1 2
+b 3 4
+
<DF> =3D pd.DataF=
+rame(<list_of_rows>) # Rows can =
+be either lists, dicts or series.
+<DF> =3D pd.DataFrame(<dict_of_columns>) # Columns can be either lists, dicts or series.
+
+<el> =3D <DF&g=
+t;.loc[row_key, column_key] # Or: <D=
+F>.iloc[row_index, column_index]
+<Sr/DF> =3D <DF>.loc[row_key/s] # Or: <DF>.iloc[row_index/es]
+<Sr/DF> =3D <DF>.loc[:, column_key/s] # Or: <DF>.iloc[:, column_index/es]
+<DF> =3D <DF>.loc[row_bools, column_bools] # Or: <DF>.iloc[row_bools, column_bools]
+
+<Sr/DF> =3D <DF&g=
+t;[column_key/s] # Or: <D=
+F>.column_key
+<DF> =3D <DF>[row_bools] # Keeps rows as specified by bools.
+<DF> =3D <DF>[<DF_of_bools>] # Assigns NaN to False values.
+
+<DF> =3D <DF&g=
+t; ><=3D=3D <el/Sr/DF> # Returns DF of bools. Sr is treated as a row.
+<DF> =3D <DF> +-*/ <el/Sr/DF> # Items with non-matching keys get value NaN.
+
+<DF> =3D <DF&g=
+t;.set_index(column_key) # Replaces =
+row keys with values from a column.
+<DF> =3D <DF>.reset_index(drop=3DFalse) # Drops or moves row k=
+eys to column named index.
+<DF> =3D <DF>.sort_index(ascending=3DTrue) # Sorts rows by row ke=
+ys. Use `axis=3D1` for cols.
+<DF> =3D <DF>.sort_values(column_key/s) # Sorts rows by the passed column/s. Same.
+
+>>> l =3D pd.DataFrame([[1, 2], [3, 4]], index=3D['a', 'b'], co=
+lumns=3D['x', 'y'])
+ x y
+a 1 2
+b 3 4
+4, 5], [6, 7]], in=
+dex=3D['b', =
+'c'], columns=3D['y', 'z'])
+ y z
+b 4 5
+c 6 7
+ r =3D pd.DataFrame([[
=E2=94=8F=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 '=
+outer' =E2=94=82 'inner' =
+=E2=94=82 'left' =E2=94=82 Des=
+cription =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 l.merge(r, on=3D'y', =E2=
+=94=82 x y z =E2=94=82 x y z =E2=94=82 x y z =E2=94=82 Me=
+rges on column if 'on' =E2=94=83
+=E2=94=83 how=3D=E2=80=A6) =E2=94=82 0 1 2 . =E2=94=82 3 4 5 =
+=E2=94=82 1 2 . =E2=94=82 or 'left/right_on' are =E2=94=83
+=E2=94=83 =E2=94=82 1 3 4<=
+/span> 5 =E2=94=82 =E2=94=
+=82 3 4 5 =E2=94=82 set, else on shared =
+cols.=E2=94=83
+=E2=94=83 =E2=94=82 2 . 6 7 =E2=94=82 =E2=94=82 =E2=94=82 Uses 'inner' by default. =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 l.join(r, lsuffix=3D'l', =E2=
+=94=82 x yl yr z =E2=94=82 =E2=94=82 x yl yr z =E2=94=82 Me=
+rges on row keys. =E2=94=83
+=E2=94=83 rsuffix=3D'r', =E2=
+=94=82 a 1 2 . . =E2=94=82 x yl yr z =E2=94=82 =
+1 2 . . =E2=94=82 Uses 'left' by default. =E2=94=83
+=E2=94=83 how=3D=E2=80=A6) =E2=94=82 b 3 4 4 5 =E2=94=82 3 4 4 5 =E2=94=
+=82 3 4 4 5 =E2=94=82 If r is a Series, it is =E2=94=83
+=E2=94=83 =E2=94=82 c . . 6 7 =E2=94=82 =
+=E2=94=82 =E2=94=82 treated as a column. =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 pd.concat([l, r], =E2=94=82 x y z =E2=94=82 y =
+ =E2=94=82 =E2=94=82 Adds rows at the bottom. =E2=94=83
+=E2=94=83 axis=3D0, =E2=
+=94=82 a 1 2 . =E2=94=82 2 =E2=
+=94=82 =E2=94=82 Uses 'outer'=
+ by default. =E2=94=83
+=E2=94=83 join=3D=E2=80=A6) =E2=94=82 b 3 4 . =E2=94=82 =
+ 4 =E2=94=82 =E2=94=82 A=
+ Series is treated as a =E2=94=83
+=E2=94=83 =E2=94=82 b . 4 5 =E2=94=82 4 =E2=94=82 =E2=94=82 column. To =
+add a row use =E2=94=83
+=E2=94=83 =E2=94=82 c . 6 7 =E2=94=82 6 =E2=94=82 =E2=94=82 pd.concat([=
+l, DF([sr])]).=E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 pd.concat([l, r], =E2=94=82 x y y z =E2=94=82 =
+ =E2=94=82 =E2=94=82 Adds columns at the =E2=94=83
+=E2=94=83 axis=3D1, =E2=
+=94=82 a 1 2 . . =E2=94=82 x y y z =E2=94=82 =E2=94=82 right e=
+nd. Uses 'outer' =E2=94=83
+=E2=94=83 join=3D=E2=80=A6) =E2=94=82 b 3 4 4 5 =E2=94=82 3 4 4 5 =E2=94=
+=82 =E2=94=82 by default. A Series is =E2=94=83
+=E2=94=83 =E2=94=82 c . . 6 7 =E2=94=82 =
+=E2=94=82 =E2=94=82 treated as a column. =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 l.combine_first(r) =E2=94=82 x y z =E2=94=82 =
+ =E2=94=82 =E2=94=82 Adds missing rows and =E2=94=83
+=E2=94=83 =E2=94=82 a 1=
+ 2 . =E2=94=82 =
+=E2=94=82 =E2=94=82 columns. Also updates =E2=94=83
+=E2=94=83 =E2=94=82 b 3=
+ 4 5 =E2=94=82 =E2=94=82 =E2=94=82 items that =
+contain NaN. =E2=94=83
+=E2=94=83 =E2=94=82 c . 6 7 =E2=94=82 =
+=E2=94=82 =E2=94=82 R must be a DataFrame. =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=9B
+
+<=
+;Sr> =3D <DF>.sum/max/mean/idxmax/all() # Or: <DF>.apply/agg(lambda <Sr>: <el>)
+<DF> =3D <DF>.rank/diff/cumsum/ffill/interpl() # Or: <DF>.apply/agg/transfrm(lambda <Sr>: <S=
+r>)
+<DF> =3D <DF>.fillna(<el>) # Or: <DF>.applymap(lambda <el>: <el>=
+;)
+
'axis=3D1'
to pr=
+ocess the rows instead.1, 2], [3<=
+/span>, 4]], index=3D['a', 'b'], columns=3D[<=
+span class=3D"hljs-string">'x', 'y'])
+ x y
+a 1 2
+b 3 4
+
df =3D pd.DataFrame([[
+=E2=94=8F=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 'sum' =E2=94=82 ['sum'] =E2=94=82 =
+{'x': 'sum'<=
+/span>} =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 df.apply(=E2=80=A6) =E2=94=82 =E2=94=82 x =
+y =E2=94=82 =E2=94=83
+=E2=94=83 df.agg(=E2=80=A6) =E2=94=82 x 4 =E2=94=82 sum 4 6 =E2=94=82 x 4 =E2=94=83
+=E2=94=83 =E2=94=82 y 6 =E2=94=82 =E2=94=82 =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=9B
+
+=E2=94=8F=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 'rank'=
+span> =E2=94=82 ['rank'] =E2=94=82 =
+{'x': 'rank'=
+} =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=A8
+=E2=94=83 df.apply(=E2=80=A6) =E2=94=82 x y =E2=94=82 x =
+ y =E2=94=82 x =E2=94=83
+=E2=94=83 df.agg(=E2=80=A6) =E2=94=82 a 1 1 =E2=94=82 rank rank =
+=E2=94=82 a 1 =E2=94=83
+=E2=94=83 df.transform(=E2=80=A6) =E2=94=82 b 2 2 =E2=94=82 a 1 1 =E2=94=
+=82 b 2 =E2=94=83
+=E2=94=83 =E2=94=82 =E2=94=82 b 2 2 =E2=94=82=
+ =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=9B
+
+
+'&l=
+t;DF>[col_key_1, col_key_2][row_key]'
to get the fifth res=
+ult's values.<DF>.pl=
+ot.line/area/bar/hist/scatter/box() # Also=
+: `x=3Dcolumn_key, y=3Dcolumn_key/s`.
+plt.show() # Displays the plot. Also plt.savefig(<path>).
+
<DF> =3D pd.read_jso=
+n/html('<str/path/url>') # Run `$ pip3 install beautifulsoup4 lxml`.
+<DF> =3D pd.read_csv/pickle/excel('<pa=
+th/url>') # Use `sheet_name=3DNone`=
+ to get all Excel sheets.
+<DF> =3D pd.read_sql('<table/query>=
+', <conn.>) # Accepts SQLite3 o=
+r SQLAlchemy connection.
+<DF> =3D pd.read_clipboard() # Reads a copied table from the clipboard.
+
+<dict> =3D <DF>=
+;.to_dict(['d/l/s/=E2=80=A6']) =
+ # Returns columns as dicts, lists or series=
+.
+<str> =3D <DF>.to_json/html/csv([<path>]) # Also to_markdown/latex([<path>]).
+<DF>.to_pickle/excel(<path>) # Run `$ pip3 install "pandas[excel]" odfpy`.
+<DF>.to_sql('<table_name>', =
+<connection>) # Accepts SQLite3 or =
+SQLAlchemy connection.
+
+Object that groups together = +rows of a dataframe based on the value of the passed column.
1, 2, 3], [4, 5=
+span>, 6], [=
+7, 8, 6]], list('abc'), list('xyz'))
+ df.groupby('z').get_group(6)
+ x y z
+b 4 5 6
+c 7 8 6
+
df =3D pd.DataFrame([[
<GB> =3D <DF>.=
+groupby(column_key/s) # Splits DF=
+ into groups based on passed column.
+<DF> =3D <GB>.apply(<func>) # Maps each group. Func can return DF, Sr or el.
+<GB> =3D <GB>[column_key] # Single column GB. All operations return a Sr.
+
+<DF&=
+gt; =3D <GB>.sum/max/mean/idxmax/all() # Or: <GB>.agg(lambda <Sr>: <el>)
+<DF> =3D <GB>.rank/diff/cumsum/ffill() # Or: <GB>.transform(lambda <Sr>: <Sr>)
+<DF> =3D <GB>.fillna(<el>) # Or: <GB>.transform(lambda <Sr>: <Sr&g=
+t;)
+
'z')
+ x y z
+3: a 1 2 3
+6: b 4 5 6
+ c 7 8=
+span> 6
+
gb =3D df.groupby(
+=E2=94=8F=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=AF=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=AF=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=93
+=E2=94=83 =E2=94=82 'sum' =E2=94=82 'rank' =E2=94=82 =
+ ['rank'] =E2=94=82 {'x': 'rank'} =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=A8
+=E2=94=83 gb.agg(=E2=80=A6) =E2=94=82 x y =E2=94=82 x y=
+ =E2=94=82 x y =E2=94=82 x =E2=94=83
+=E2=94=83 =E2=94=82 z =E2=94=82 a 1 1 =E2=94=82=
+ rank rank =E2=94=82 a 1 =E2=
+=94=83
+=E2=94=83 =E2=94=82 3 =
+ 1 2 =E2=94=82 b 1 1 =E2=94=82 a 1 =
+1 =E2=94=82 b 1 =E2=94=83
+=E2=94=83 =E2=94=82 6 =
+11 13 =E2=94=82 c 2 2 =E2=94=82 b 1 =
+1 =E2=94=82 c 2 =E2=94=83
+=E2=94=83 =E2=94=82 =E2=94=82 =E2=
+=94=82 c 2 2 =E2=94=82 =E2=94=83
+=E2=94=A0=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=
+=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
+=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
+=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
+=E2=94=80=E2=94=A8
+=E2=94=83 gb.transform(=E2=80=A6) =E2=94=82 x y =E2=94=82 x y=
+ =E2=94=82 =E2=94=82 =E2=94=83
+=E2=94=83 =E2=94=82 a 1 2 =E2=94=82 a 1 1 =E2=94=82 =
+ =E2=94=82 =E2=94=83
+=E2=94=83 =E2=94=82 b 11 13 =E2=94=82 b 1 1 =E2=94=82 =
+ =E2=94=82 =E2=94=83
+=E2=94=83 =E2=94=82 c 11 13 =E2=94=82 c 2 2 =E2=94=82 =
+ =E2=94=82 =E2=94=83
+=E2=94=97=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=
+=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
+=94=81=E2=94=81=E2=94=B7=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
+=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=
+=E2=94=81=E2=94=9B
+
+Object for rolling window ca= +lculations.
&l=
+t;RSr/RDF/RGB> =3D <Sr/DF/GB>.rolling(win_size) # Also: `min_periods=3DNone, center=3DFalse`.
+<RSr/RDF/RGB> =3D <RDF/RGB>[column_key/s] # Or: <RDF/RGB>.column_key
+<Sr/DF> =3D <R>.mean/sum/max() # Or: <R>.apply/agg(<agg_func/str>)
+
# $ pip3 install plotly kaleid=
+o
+from plotly.express import line
+<Figure> =3D line(<DF>, x=3D<col_name>, y=3D<col_name&=
+gt;) # Or: line(x=3D<list>, y=
+=3D<list>)
+<Figure>.update_layout(margin=3Ddict(t=3D=
+0, r=3D0, b=3D0, l=3D0), =E2=80=A6) <=
+span class=3D"hljs-comment"># `paper_bgcolor=3D'rgb(0, 0, 0)'`.
+<Figure>.write_html/json/image('<path&=
+gt;') # Also <Fig=
+ure>.show().
+
covid =3D pd.read_csv('h=
+ttps://covid.ourworldindata.org/data/owid-covid-data.csv',
+ usecols=3D['iso_code', 'date', '=
+total_deaths', 'population'])
+continents =3D pd.read_csv('https://gist.github=
+usercontent.com/stevewithington/20a69c0b6d2ff'
+ '846ea5d35e5fc47f26c/r=
+aw/country-and-continent-codes-list-csv.csv',
+ usecols=3D['Three_Lett=
+er_Country_Code', 'Continent_Name'])
+df =3D pd.merge(covid, continents, left_on=3D'i=
+so_code', right_on=3D'Three_Letter_Count=
+ry_Code')
+df =3D df.groupby(['Continent_Name', 'date']).sum().reset_index()
+df['Total Deaths per Million'] =3D df.to=
+tal_deaths * 1e6 / df.population
+df =3D df[df.date > '2020-03-14']
+df =3D df.rename({'date': 'Date', 'Continent_Name'=
+span>: 'Continent'}, axis=3D'columns')
+line(df, x=3D'Date', y=3D'Total Deaths per Million', color=3D'Continent').show()
+
+
+
+
+import pandas as pd, plotly.graph_objects as go
+
+def main():
+ display_data(wrangle_data(*scrape_data()))
+
+def scrape_data():
+ def <=
+span class=3D"hljs-title">scrape_covid()=
+:
+ url =3D 'https://covid.ourworldindata.o=
+rg/data/owid-covid-data.csv'
+ df =3D pd.read_csv(url, usecols=3D['loc=
+ation', 'date', 'total_cases'])
+ return df[df.location =3D=3D 'World'].set_index('date').total_cases
+ def <=
+span class=3D"hljs-title">scrape_yahoo(s=
+lug):
+ url =3D (f'https://query1.finance.yahoo=
+.com/v7/finance/download/{slug}?'
+ 'period1=3D1579651200&period=
+2=3D9999999999&interval=3D1d&events=3Dhistory')
+ df =3D pd.read_csv(url, usecols=3D['Dat=
+e', 'Close'])
+ return df.set_index('Date').Close
+ out =3D scrape_covid(), scrape_yahoo('BTC-U=
+SD'), scrape_yahoo('GC=3DF'), scr=
+ape_yahoo('^DJI')
+ return map(pd.Series.rename, out, [=
+'Total Cases', 'Bitcoin', 'Gold', 'Dow Jones'])
+
+def wrangle_data(covid=
+, bitcoin, gold, dow):
+ df =3D pd.concat([bitcoin, gold, dow], axis=3D1) # Joins columns on dates.
+ df =3D df.sort_index().interpolate() # Sorts by date and interpolates NaN-s.
+ df =3D df.loc['2020-02-23':] =
+ # Discards rows before '2020-02-23=
+'.
+ df =3D (df / df.iloc[0]) * 100 # Calculates percentages relative to day 1.
+ df =3D df.join(covid) # Adds column with covid cases.
+ return df.sort_values(df.index[-1], axis=3D1 ) # Sorts columns by last day's value.=
+span>
+
+def display_data(df)=
+span>:
+ figure =3D go.Figure()
+ for col_name in reversed(df.columns):
+ yaxis =3D 'y1' if col_name =3D=3D 'Total Ca=
+ses' else 'y2'
+ trace =3D go.Scatter(x=3Ddf.index, y=3Ddf[col_name], name=3Dcol_nam=
+e, yaxis=3Dyaxis)
+ figure.add_trace(trace)
+ figure.update_layout(
+ yaxis1=3Ddict(title=3D'Total Cases', rangemode=3D'tozero'),
+ yaxis2=3Ddict(title=3D'%', range=
+mode=3D'tozero', overlaying=3D'y', side=3D'right'),
+ legend=3Ddict(x=3D1.1),
+ height=3D450
+ )
+ figure.show()
+
+if __name__ =3D=3D '__main__':
+ main()
+
# $ pip3 i=
+nstall PySimpleGUI
+import PySimpleGUI as sg
+
+layout =3D [[sg.Text("What's your name?"=
+)], [sg.Input()], [sg.Button('Ok')]]
+window =3D sg.Window('Window Title', lay=
+out)
+event, values =3D window.read()
+print(f'Hello {value=
+s[0]}!' if event =3D=3D 'Ok' <=
+span class=3D"hljs-keyword">else '')
+
Library that compiles Python code into C.
<= +pre># $ pip3 install cython
+import pyximport; pyximport.install()
+import <cython_script>
+<cython_script>.main()
+
'cd=
+ef'
definitions are optional, but they contribute to the spee=
+d-up.'pyx'
extension.cdef <ctype> &l=
+t;var_name> =3D <el>
+cdef <ctype>[n_elements] <var_name> =3D [<el>, <el>=
+, ...]
+cdef <ctype/void> <func_name>(<ctype> <arg_name>): =
+...
+
cdef class <class_name>:
+ cdef public <ctype> <attr_name>
+ def <=
+span class=3D"hljs-title">__init__(self,=
+ <ctype> <arg_name>):
+ self.<attr_name> =3D <arg_name>
+
+cdef enum <enum_name>=
+;: <member_name>, <member_name>, ...
+
+$ pip3 install pyinstaller
+$ pyinstaller script.py # Compiles into './dist/script' directory.
+$ pyinstaller script.py --onefile # Compiles into './dist/script' console app.
+$ pyinstaller script.py --windowed # Compiles into './dist/script' windowed app.
+$ pyinstaller script.py --add-data '<path>:.' # Adds file to the root of the executable.
+
'os.path.join(sys._MEIPASS, <path>)'=
+
.#!/usr/bin=
+/env python3
+#
+# Usage: .py
+#
+
+from sys i=
+mport argv, exit
+from collections import defaultdict, namedtuple
+from dataclasses import make_dataclass
+from enum =
+import Enum
+import functools as ft, itertools as it, o=
+perator as op, re
+
+
+def main():
+ pass
+
+
+###
+## UTIL
+#
+
+def read_file(filename=
+):
+ with open(filename, encoding=3D'utf-8' ) as file:
+ return file.readlines()
+
+
+if __name__ =3D=3D '__main__':
+ main()
+