From 9c81a492b576d6074f6e052e85ea7b71916d9ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Sat, 22 Jul 2023 17:06:00 +0200 Subject: [PATCH 001/418] Class, Duck types, Open, Memory view, Operator, Metaprogramming, Web, Profile --- README.md | 18 +++++++++--------- index.html | 22 +++++++++++----------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index de2cc7aca..85ab581ca 100644 --- a/README.md +++ b/README.md @@ -1068,7 +1068,7 @@ from dataclasses import make_dataclass #### Rest of type annotations (CPython interpreter ignores them all): ```python -import typing as tp, collections.abc as abc +import collections.abc as abc, typing as tp : list/set/abc.Iterable/abc.Sequence/tp.Optional[] [= ] : dict/tuple/tp.Union[, ...] [= ] def func(: [= ]) -> : ... @@ -1252,7 +1252,7 @@ True ### Collection * **Only required methods are iter() and len(). Len() should return the number of items.** * **This cheatsheet actually means `''` when it uses `''`.** -* **I chose not to use the name 'iterable' because it sounds scarier and more vague than 'collection'. The only drawback of this decision is that a reader could think a certain function doesn't accept iterators when it does, since iterators are the only built-in objects that are iterable but are not collections.** +* **I chose not to use the name 'iterable' because it sounds scarier and more vague than 'collection'. The only drawback of this decision is that the reader could think a certain function doesn't accept iterators when it does, since iterators are the only built-in objects that are iterable but are not collections.** ```python class MyCollection: def __init__(self, a): @@ -1606,7 +1606,7 @@ Open .writelines() # Writes a coll. of strings or bytes objects. .flush() # Flushes write buffer. Runs every 4096/8192 B. ``` -* **Methods do not add or strip trailing newlines, even writelines().** +* **Methods do not add or strip trailing newlines, not even writelines().** ### Read Text from File ```python @@ -2045,7 +2045,7 @@ from array import array Memory View ----------- -* **A sequence object that points to the memory of another object.** +* **A sequence object that points to the memory of another bytes-like object.** * **Each element can reference a single or multiple consecutive bytes, depending on format.** * **Order and number of elements can be changed with slicing.** * **Casting only works between char and other types and uses system's sizes.** @@ -2177,7 +2177,7 @@ product_of_elems = functools.reduce(op.mul, ) union_of_sets = functools.reduce(op.or_, ) first_element = op.methodcaller('pop', 0)() ``` -* **Binary operators require objects to have and(), or(), xor() and invert() special methods, unlike logical operators that work on all types of objects.** +* **Bitwise operators require objects to have and(), or(), xor() and invert() special methods, unlike logical operators that work on all types of objects.** * **Also: `' = &|^ '` and `' = &|^ '`.** @@ -2250,7 +2250,7 @@ class MyMetaClass(type): * **The only difference between the examples above is that my\_meta\_class() returns a class of type type, while MyMetaClass() returns a class of type MyMetaClass.** ### Metaclass Attribute -**Right before a class is created it checks if it has the 'metaclass' attribute defined. If not, it recursively checks if any of his parents has it defined and eventually comes to type().** +**Right before a class is created it checks if it has the 'metaclass' attribute defined. If not, it recursively checks if any of its parents has it defined and eventually comes to type().** ```python class MyClass(metaclass=MyMetaClass): @@ -2535,7 +2535,7 @@ from flask import Flask, send_from_directory, render_template_string, request ```python app = Flask(__name__) -app.run(host=None, debug=None) +app.run(host=None, port=None, debug=None) ``` * **Starts the app at `'http://localhost:5000/'`. Use `'host="0.0.0.0"'` to run externally.** * **Install a WSGI server like [Waitress](https://flask.palletsprojects.com/en/latest/deploying/waitress/) and a HTTP server such as [Nginx](https://flask.palletsprojects.com/en/latest/deploying/nginx/) for better security.** @@ -2599,11 +2599,11 @@ duration_in_seconds = perf_counter() - start_time ### Profiling by Line ```text $ pip3 install line_profiler -$ echo "@profile +$ echo '@profile def main(): a = list(range(10000)) b = set(range(10000)) -main()" > test.py +main()' > test.py $ kernprof -lv test.py Line # Hits Time Per Hit % Time Line Contents ======================================================= diff --git a/index.html b/index.html index 0f35e4af7..c425e235c 100644 --- a/index.html +++ b/index.html @@ -54,7 +54,7 @@
- +
@@ -903,7 +903,7 @@ <class> = make_dataclass('<class_name>', <coll_of_tuples>) <tuple> = ('<attr_name>', <type> [, <default_value>]) -

Rest of type annotations (CPython interpreter ignores them all):

import typing as tp, collections.abc as abc
+

Rest of type annotations (CPython interpreter ignores them all):

import collections.abc as abc, typing as tp
 <var_name>: list/set/abc.Iterable/abc.Sequence/tp.Optional[<type>] [= <obj>]
 <var_name>: dict/tuple/tp.Union[<type>, ...] [= <obj>]
 def func(<arg_name>: <type> [= <obj>]) -> <type>: ...
@@ -1067,7 +1067,7 @@
 

Collection

  • Only required methods are iter() and len(). Len() should return the number of items.
  • This cheatsheet actually means '<iterable>' when it uses '<collection>'.
  • -
  • I chose not to use the name 'iterable' because it sounds scarier and more vague than 'collection'. The only drawback of this decision is that a reader could think a certain function doesn't accept iterators when it does, since iterators are the only built-in objects that are iterable but are not collections.
  • +
  • I chose not to use the name 'iterable' because it sounds scarier and more vague than 'collection'. The only drawback of this decision is that the reader could think a certain function doesn't accept iterators when it does, since iterators are the only built-in objects that are iterable but are not collections.
class MyCollection:
     def __init__(self, a):
         self.a = a
@@ -1371,7 +1371,7 @@
 <file>.flush()                      # Flushes write buffer. Runs every 4096/8192 B.
 
    -
  • Methods do not add or strip trailing newlines, even writelines().
  • +
  • Methods do not add or strip trailing newlines, not even writelines().

Read Text from File

def read_file(filename):
     with open(filename, encoding='utf-8') as file:
@@ -1697,7 +1697,7 @@ 

Format

#Memory View

    -
  • A sequence object that points to the memory of another object.
  • +
  • A sequence object that points to the memory of another bytes-like object.
  • Each element can reference a single or multiple consecutive bytes, depending on format.
  • Order and number of elements can be changed with slicing.
  • Casting only works between char and other types and uses system's sizes.
  • @@ -1801,7 +1801,7 @@

    Format

    'pop', 0)(<list>)

    -
  • Binary operators require objects to have and(), or(), xor() and invert() special methods, unlike logical operators that work on all types of objects.
  • +
  • Bitwise operators require objects to have and(), or(), xor() and invert() special methods, unlike logical operators that work on all types of objects.
  • Also: '<bool> = <bool> &|^ <bool>' and '<int> = <bool> &|^ <int>'.

#Introspection

Inspecting code at runtime.

Variables

<list> = dir()                             # Names of local variables (incl. functions).
@@ -1852,7 +1852,7 @@ 

Format

def __new__(cls): return super().__new__(cls)).
  • The only difference between the examples above is that my_meta_class() returns a class of type type, while MyMetaClass() returns a class of type MyMetaClass.
  • -

    Metaclass Attribute

    Right before a class is created it checks if it has the 'metaclass' attribute defined. If not, it recursively checks if any of his parents has it defined and eventually comes to type().

    class MyClass(metaclass=MyMetaClass):
    +

    Metaclass Attribute

    Right before a class is created it checks if it has the 'metaclass' attribute defined. If not, it recursively checks if any of its parents has it defined and eventually comes to type().

    class MyClass(metaclass=MyMetaClass):
         b = 12345
     
    @@ -2080,7 +2080,7 @@

    Format

    app = Flask(__name__) -app.run(host=None, debug=None) +app.run(host=None, port=None, debug=None)

    • Starts the app at 'http://localhost:5000/'. Use 'host="0.0.0.0"' to run externally.
    • @@ -2130,11 +2130,11 @@

      Format

      Profiling by Line

      $ pip3 install line_profiler
      -$ echo "@profile
      +$ echo '@profile
       def main():
           a = list(range(10000))
           b = set(range(10000))
      -main()" > test.py
      +main()' > test.py
       $ kernprof -lv test.py
       Line #   Hits     Time  Per Hit   % Time  Line Contents
       =======================================================
      @@ -2933,7 +2933,7 @@ 

      Format

      Built-in Exceptions

      BaseException
      @@ -1414,7 +1414,7 @@
       
       

      Path Object

      <Path> = Path(<path> [, ...])       # Accepts strings, Paths and DirEntry objects.
       <Path> = <path> / <path> [/ ...]    # First or second path must be a Path object.
      -<Path> = <Path>.resolve()           # Resolves symlinks and calls <Path>.absolute().
      +<Path> = <Path>.resolve()           # Returns absolute path with resolved symlinks.
       
      <Path> = Path()                     # Returns relative cwd. Also Path('.').
      @@ -2288,7 +2288,7 @@ 

      Format

      Adds noise to a PNG image:

      from random import randint
      +

      Adds noise to a PNG image and displays it:

      from random import randint
       add_noise = lambda value: max(0, min(255, value + randint(-20, 20)))
       img = Image.open('test.png').convert('HSV')
       img.putdata([(add_noise(h), s, v) for h, s, v in img.getdata()])
      @@ -2933,7 +2933,7 @@ 

      Format

      #Numbers

      <int>      = int(<float/str/bool>)                # Or: math.floor(<float>)
      -<float>    = float(<int/str/bool>)                # Or: <real>e±<int>
      -<complex>  = complex(real=0, imag=0)              # Or: <real> ± <real>j
      +<float>    = float(<int/str/bool>)                # Or: <int/float>e±<int>
      +<complex>  = complex(real=0, imag=0)              # Or: <int/float/Fraction> ± <int/float>j
       <Fraction> = fractions.Fraction(0, 1)             # Or: Fraction(numerator=0, denominator=1)
       <Decimal>  = decimal.Decimal(<str/int>)           # Or: Decimal((sign, digits, exponent))
       
      @@ -1669,16 +1669,16 @@

      Format

      Besides numbers, pack() and unpack() also support bytes objects as part of the sequence:

      • 'c' - A bytes object with a single element. For pad byte use 'x'.
      • '<n>s' - A bytes object with n elements.
      • -

      Integer types. Use a capital letter for unsigned type. Minimum and standard sizes are in brackets:

        +

      Integer types. Use a capital letter for unsigned type. Minimum and standard sizes are in brackets:

      • 'b' - char (1/1)
      • 'h' - short (2/2)
      • 'i' - int (2/4)
      • 'l' - long (4/4)
      • 'q' - long long (8/8)
      • -

      Floating point types:

        +

      Floating point types (struct always uses standard sizes):

      • 'f' - float (4/4)
      • 'd' - double (8/8)
      • -
      +

    @@ -2167,8 +2167,8 @@

    Format

    <array> = np.array(<list/list_of_lists>) # Returns a 1d/2d NumPy array. -<array> = np.zeros/ones(<shape>) # Also np.full(<shape>, <el>). +
    <array> = np.array(<list/list_of_lists/…>)              # Returns a 1d/2d/… NumPy array.
    +<array> = np.zeros/ones/empty(<shape>)                  # Also np.full(<shape>, <el>).
     <array> = np.arange(from_inc, to_exc, ±step)            # Also np.linspace(start, stop, len).
     <array> = np.random.randint(from_inc, to_exc, <shape>)  # Also np.random.random(<shape>).
     
    From 4f55bc6cdbdcc79115a4858a828e8a599093c5df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Thu, 27 Jul 2023 19:44:26 +0200 Subject: [PATCH 004/418] CSV, Threading, Curses --- README.md | 16 ++++++++-------- index.html | 20 ++++++++++---------- parse.js | 8 ++++---- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 08f195cf1..fe89ad9d4 100644 --- a/README.md +++ b/README.md @@ -1861,16 +1861,16 @@ import csv ### Read Rows from CSV File ```python -def read_csv_file(filename, dialect='excel'): +def read_csv_file(filename, dialect='excel', **params): with open(filename, encoding='utf-8', newline='') as file: - return list(csv.reader(file, dialect)) + return list(csv.reader(file, dialect, **params)) ``` ### Write Rows to CSV File ```python -def write_to_csv_file(filename, rows, dialect='excel'): +def write_to_csv_file(filename, rows, dialect='excel', **params): with open(filename, 'w', encoding='utf-8', newline='') as file: - writer = csv.writer(file, dialect) + writer = csv.writer(file, dialect, **params) writer.writerows(rows) ``` @@ -2155,7 +2155,7 @@ with : # Enters the block by calling acq ``` * **Map() and as_completed() also accept 'timeout' argument that causes TimeoutError if result isn't available in 'timeout' seconds after next() is called.** * **Exceptions that happen inside threads are raised when next() is called on map's iterator or when result() is called on a Future. Its exception() method returns exception or None.** -* **An object with the same interface called ProcessPoolExecutor provides true parallelism by running a separate interpreter in each process. Arguments/results must be [pickable](#pickle).** +* **ProcessPoolExecutor provides true parallelism, but everything sent to/from workers must be [pickable](#pickle). Queues must be sent using executor's 'initargs' and 'initializer' parameters.** Operator @@ -2423,17 +2423,17 @@ Curses ------ #### Runs a basic file explorer in the terminal: ```python -import curses, curses.ascii, os +import curses, os from curses import A_REVERSE, KEY_DOWN, KEY_UP, KEY_LEFT, KEY_RIGHT, KEY_ENTER def main(screen): ch, first, selected, paths = 0, 0, 0, os.listdir() - while ch != curses.ascii.ESC: + while ch != ord('q'): height, width = screen.getmaxyx() screen.erase() for y, filename in enumerate(paths[first : first+height]): color = A_REVERSE if filename == paths[selected] else 0 - screen.addstr(y, 0, filename[:width-1], color) + screen.addnstr(y, 0, filename, width-1, color) ch = screen.getch() selected += (ch == KEY_DOWN) - (ch == KEY_UP) selected = max(0, min(len(paths)-1, selected)) diff --git a/index.html b/index.html index 8ccaab3d2..d1b993d19 100644 --- a/index.html +++ b/index.html @@ -54,7 +54,7 @@
    - +
    @@ -1553,14 +1553,14 @@ -

    Read Rows from CSV File

    def read_csv_file(filename, dialect='excel'):
    +

    Read Rows from CSV File

    def read_csv_file(filename, dialect='excel', **params):
         with open(filename, encoding='utf-8', newline='') as file:
    -        return list(csv.reader(file, dialect))
    +        return list(csv.reader(file, dialect, **params))
     
    -

    Write Rows to CSV File

    def write_to_csv_file(filename, rows, dialect='excel'):
    +

    Write Rows to CSV File

    def write_to_csv_file(filename, rows, dialect='excel', **params):
         with open(filename, 'w', encoding='utf-8', newline='') as file:
    -        writer = csv.writer(file, dialect)
    +        writer = csv.writer(file, dialect, **params)
             writer.writerows(rows)
     
    @@ -1783,7 +1783,7 @@

    Format

    pickable. +
  • ProcessPoolExecutor provides true parallelism, but everything sent to/from workers must be pickable. Queues must be sent using executor's 'initargs' and 'initializer' parameters.
  • #Operator

    Module of functions that provide the functionality of operators.

    import operator as op
     <obj>     = op.add/sub/mul/truediv/floordiv/mod(<obj>, <obj>)     # +, -, *, /, //, %
    @@ -1986,17 +1986,17 @@ 

    Format

    #Curses

    Runs a basic file explorer in the terminal:

    import curses, curses.ascii, os
    +

    #Curses

    Runs a basic file explorer in the terminal:

    import curses, os
     from curses import A_REVERSE, KEY_DOWN, KEY_UP, KEY_LEFT, KEY_RIGHT, KEY_ENTER
     
     def main(screen):
         ch, first, selected, paths = 0, 0, 0, os.listdir()
    -    while ch != curses.ascii.ESC:
    +    while ch != ord('q'):
             height, width = screen.getmaxyx()
             screen.erase()
             for y, filename in enumerate(paths[first : first+height]):
                 color = A_REVERSE if filename == paths[selected] else 0
    -            screen.addstr(y, 0, filename[:width-1], color)
    +            screen.addnstr(y, 0, filename, width-1, color)
             ch = screen.getch()
             selected += (ch == KEY_DOWN) - (ch == KEY_UP)
             selected = max(0, min(len(paths)-1, selected))
    @@ -2933,7 +2933,7 @@ 

    Format

    @@ -1721,15 +1721,14 @@

    Format

    '<hex>' = <mview>.hex() # Treats mview as a bytes object.

    #Deque

    A thread-safe list with efficient appends and pops from either side. Pronounced "deck".

    from collections import deque
    -<deque> = deque(<collection>, maxlen=None)
    -
    - - -
    <deque>.appendleft(<el>)                       # Opposite element is dropped if full.
    +<deque> = deque(<collection>)                  # Also `maxlen=None`.
    +<deque>.appendleft(<el>)                       # Opposite element is dropped if full.
     <deque>.extendleft(<collection>)               # Collection gets reversed.
     <el> = <deque>.popleft()                       # Raises IndexError if empty.
     <deque>.rotate(n=1)                            # Rotates elements to the right.
    -
    +
    + +

    #Threading

    • CPython interpreter can only run a single thread at a time.
    • That is why using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.
    • @@ -1785,11 +1784,14 @@

      Format

      pickable. Queues must be sent using executor's 'initargs' and 'initializer' parameters.

    -

    #Operator

    Module of functions that provide the functionality of operators.

    import operator as op
    -<obj>     = op.add/sub/mul/truediv/floordiv/mod(<obj>, <obj>)     # +, -, *, /, //, %
    -<int/set> = op.and_/or_/xor(<int/set>, <int/set>)                 # &, |, ^
    -<bool>    = op.eq/ne/lt/le/gt/ge(<sortable>, <sortable>)          # ==, !=, <, <=, >, >=
    -<func>    = op.itemgetter/attrgetter/methodcaller(<obj> [, ...])  # [index/key], .name, .name()
    +

    #Operator

    Module of functions that provide the functionality of operators. Functions are ordered by operator precedence, starting with least binding.

    import operator as op
    +<bool> = op.not_(<obj>)                                        # not (or/and are not provided)
    +<bool> = op.eq/ne/lt/le/gt/ge/contains(<obj>, <obj>)           # ==, !=, <, <=, >, >=, in
    +<obj>  = op.or_/xor/and_(<int/set>, <int/set>)                 # |, ^, &
    +<obj>  = op.add/sub/mul/truediv/floordiv/mod(<obj>, <obj>)     # +, -, *, /, //, %
    +<num>  = op.neg/invert(<num>)                                  # -, ~
    +<num>  = op.pow(<num>, <num>)                                  # **
    +<func> = op.itemgetter/attrgetter/methodcaller(<obj> [, ...])  # [index/key], .name, .name()
     
    @@ -1801,15 +1803,13 @@

    Format

    'pop', 0)(<list>)

      -
    • Bitwise operators require objects to have and(), or(), xor() and invert() special methods, unlike logical operators that work on all types of objects.
    • +
    • Bitwise operators require objects to have and(), or() and xor() special methods, unlike logical operators that work on all types of objects.
    • Also: '<bool> = <bool> &|^ <bool>' and '<int> = <bool> &|^ <int>'.
    -

    #Introspection

    Inspecting code at runtime.

    Variables

    <list> = dir()                             # Names of local variables (incl. functions).
    +

    #Introspection

    <list> = dir()                             # Names of local variables (incl. functions).
     <dict> = vars()                            # Dict of local variables. Also locals().
     <dict> = globals()                         # Dict of global variables.
    -
    - - +

    Attributes

    <list> = dir(<object>)                     # Names of object's attributes (incl. methods).
     <dict> = vars(<object>)                    # Dict of writable attributes. Also <obj>.__dict__.
    @@ -2933,7 +2933,7 @@ 

    Format

    -

    #Combinatorics

      -
    • Every function returns an iterator.
    • -
    • If you want to print the iterator, you need to pass it to the list() function first!
    • -
    import itertools as it
    +

    #Combinatorics

    import itertools as it
     
    - -
    >>> it.product([0, 1], repeat=3)
    +
    >>> list(it.product([0, 1], repeat=3))
     [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1),
      (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]
     
    -
    >>> it.product('abc', 'abc')                     #   a  b  c
    -[('a', 'a'), ('a', 'b'), ('a', 'c'),             # a x  x  x
    - ('b', 'a'), ('b', 'b'), ('b', 'c'),             # b x  x  x
    - ('c', 'a'), ('c', 'b'), ('c', 'c')]             # c x  x  x
    +
    >>> list(it.product('abc', 'abc'))                    #   a  b  c
    +[('a', 'a'), ('a', 'b'), ('a', 'c'),                  # a x  x  x
    + ('b', 'a'), ('b', 'b'), ('b', 'c'),                  # b x  x  x
    + ('c', 'a'), ('c', 'b'), ('c', 'c')]                  # c x  x  x
     
    -
    >>> it.combinations('abc', 2)                    #   a  b  c
    -[('a', 'b'), ('a', 'c'),                         # a .  x  x
    - ('b', 'c')]                                     # b .  .  x
    +
    >>> list(it.combinations('abc', 2))                   #   a  b  c
    +[('a', 'b'), ('a', 'c'),                              # a .  x  x
    + ('b', 'c')]                                          # b .  .  x
     
    -
    >>> it.combinations_with_replacement('abc', 2)   #   a  b  c
    -[('a', 'a'), ('a', 'b'), ('a', 'c'),             # a x  x  x
    - ('b', 'b'), ('b', 'c'),                         # b .  x  x
    - ('c', 'c')]                                     # c .  .  x
    +
    >>> list(it.combinations_with_replacement('abc', 2))  #   a  b  c
    +[('a', 'a'), ('a', 'b'), ('a', 'c'),                  # a x  x  x
    + ('b', 'b'), ('b', 'c'),                              # b .  x  x
    + ('c', 'c')]                                          # c .  .  x
     
    -
    >>> it.permutations('abc', 2)                    #   a  b  c
    -[('a', 'b'), ('a', 'c'),                         # a .  x  x
    - ('b', 'a'), ('b', 'c'),                         # b x  .  x
    - ('c', 'a'), ('c', 'b')]                         # c x  x  .
    +
    >>> list(it.permutations('abc', 2))                   #   a  b  c
    +[('a', 'b'), ('a', 'c'),                              # a .  x  x
    + ('b', 'a'), ('b', 'c'),                              # b x  .  x
    + ('c', 'a'), ('c', 'b')]                              # c x  x  .
     
    -

    #Datetime

      -
    • Module 'datetime' provides 'date' <D>, 'time' <T>, 'datetime' <DT> and 'timedelta' <TD> classes. All are immutable and hashable.
    • -
    • Time and datetime objects can be 'aware' <a>, meaning they have defined timezone, or 'naive' <n>, meaning they don't.
    • -
    • If object is naive, it is presumed to be in the system's timezone.
    • -
    from datetime import date, time, datetime, timedelta
    -from dateutil.tz import UTC, tzlocal, gettz, datetime_exists, resolve_imaginary
    +

    #Datetime

    Provides 'date', 'time', 'datetime' and 'timedelta' classes. All are immutable and hashable.

    # pip3 install python-dateutil
    +from datetime import date, time, datetime, timedelta, timezone
    +from dateutil.tz import tzlocal, gettz, datetime_exists, resolve_imaginary
     
    -

    Constructors

    <D>  = date(year, month, day)               # Only accepts valid dates from 1 to 9999 AD.
    +
    <D>  = date(year, month, day)               # Only accepts valid dates from 1 to 9999 AD.
     <T>  = time(hour=0, minute=0, second=0)     # Also: `microsecond=0, tzinfo=None, fold=0`.
     <DT> = datetime(year, month, day, hour=0)   # Also: `minute=0, second=0, microsecond=0, …`.
     <TD> = timedelta(weeks=0, days=0, hours=0)  # Also: `minutes=0, seconds=0, microseconds=0`.
    -
    - +
      -
    • Use '<D/DT>.weekday()' to get the day of the week as an int, with Monday being 0.
    • +
    • Aware <a> time and datetime objects have defined timezone, while naive <n> don't.
    • +
    • If object is naive, it is presumed to be in the system's timezone.
    • 'fold=1' means the second pass in case of time jumping back for one hour.
    • Timedelta normalizes arguments to ±days, seconds (< 86 400) and microseconds (< 1M).
    • +
    • Use '<D/DT>.weekday()' to get the day of the week as an int, with Monday being 0.
    • '<DTa> = resolve_imaginary(<DTa>)' fixes DTs that fall into the missing hour.

    Now

    <D/DTn>  = D/DT.today()                     # Current local date or naive datetime.
    @@ -548,13 +542,17 @@
     
    • To extract time use '<DTn>.time()', '<DTa>.time()' or '<DTa>.timetz()'.
    -

    Timezone

    <tzinfo> = UTC                              # UTC timezone. London without DST.
    +

    Timezone

    <tzinfo> = timezone.utc                     # London without daylight saving time.
    +<tzinfo> = timezone(<timedelta>)            # Timezone with fixed offset from UTC.
     <tzinfo> = tzlocal()                        # Local timezone. Also gettz().
     <tzinfo> = gettz('<Continent>/<City>')      # 'Continent/City_Name' timezone or None.
     <DTa>    = <DT>.astimezone(<tzinfo>)        # Datetime, converted to the passed timezone.
     <Ta/DTa> = <T/DT>.replace(tzinfo=<tzinfo>)  # Unconverted object with a new timezone.
     
    +
      +
    • Standard library's zoneinfo.ZoneInfo() can be used instead of gettz() on Python 3.9 and later. It requires 'tzdata' package on Windows.
    • +

    Encode

    <D/T/DT> = D/T/DT.fromisoformat('<iso>')    # Object from ISO string. Raises ValueError.
     <DT>     = DT.strptime(<str>, '<format>')   # Datetime from str, according to format.
     <D/DTn>  = D/DT.fromordinal(<int>)          # D/DTn from days since the Gregorian NYE 1.
    @@ -579,13 +577,14 @@
     
      -
    • Format code '%z' accepts '±HH[:]MM' and returns '±HHMM' (or '' if datetime is naive).
    • +
    • '%z' accepts '±HH[:]MM' and returns '±HHMM' or empty string if datetime is naive.
    • +
    • '%Z' accepts 'UTC/GMT' and local timezone's code and returns timezone's name, 'UTC[±HH:MM]' if timezone is nameless, or an empty string if datetime is naive.
    • For abbreviated weekday and month use '%a' and '%b'.

    Arithmetics

    <D/DT>   = <D/DT>  ± <TD>                   # Returned datetime can fall into missing hour.
     <TD>     = <D/DTn> - <D/DTn>                # Returns the difference. Ignores time jumps.
     <TD>     = <DTa>   - <DTa>                  # Ignores time jumps if they share tzinfo object.
    -<TD>     = <TD>    * <real>                 # Also: <TD> = abs(<TD>) and <TD> = <TD> ±% <TD>.
    +<TD>     = <TD>    * <int/float>            # Also: <TD> = abs(<TD>) and <TD> = <TD> ±% <TD>.
     <float>  = <TD>    / <TD>                   # How many weeks/years there are in TD. Also //.
     
    @@ -2933,7 +2932,7 @@

    Format

      From dbf5fdb9052416a7bb9b9626c8c9e5868f0a4eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Tue, 1 Aug 2023 15:16:13 +0200 Subject: [PATCH 009/418] Introspection, Virtual environments --- README.md | 21 +++++++++++---------- index.html | 24 +++++++++++------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index b17260085..55af7e423 100644 --- a/README.md +++ b/README.md @@ -2184,9 +2184,9 @@ first_element = op.methodcaller('pop', 0)() Introspection ------------- ```python - = dir() # Names of local variables (incl. functions). - = vars() # Dict of local variables. Also locals(). - = globals() # Dict of global variables. + = dir() # Names of local variables, functions, classes, etc. + = vars() # Dict of local variables, etc. Also locals(). + = globals() # Dict of global vars, etc. (incl. '__builtins__'). ``` ### Attributes @@ -3537,15 +3537,16 @@ cdef class : cdef enum : , , ... ``` -### PyInstaller +### Virtual Environments +**System for installing libraries directly into project's directory.** + ```bash -$ 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 ':.' # Adds file to the root of the executable. +$ python3 -m venv # Creates virtual environment in current directory. +$ source /bin/activate # Activates venv. On Windows run `\Scripts\activate`. +$ pip3 install # Installs the library into active environment. +$ python3 # Runs the script in active environment. Also `./`. +$ deactivate # Deactivates virtual environment. ``` -* **File paths need to be updated to `'os.path.join(sys._MEIPASS, )'`.** ### Basic Script Template ```python diff --git a/index.html b/index.html index 63913340f..6324e2e08 100644 --- a/index.html +++ b/index.html @@ -54,7 +54,7 @@
      - +
      @@ -1805,9 +1805,9 @@

      Format

      '<bool> = <bool> &|^ <bool>' and '<int> = <bool> &|^ <int>'.

    -

    #Introspection

    <list> = dir()                             # Names of local variables (incl. functions).
    -<dict> = vars()                            # Dict of local variables. Also locals().
    -<dict> = globals()                         # Dict of global variables.
    +

    #Introspection

    <list> = dir()                             # Names of local variables, functions, classes, etc.
    +<dict> = vars()                            # Dict of local variables, etc. Also locals().
    +<dict> = globals()                         # Dict of global vars, etc. (incl. '__builtins__').
     

    Attributes

    <list> = dir(<object>)                     # Names of object's attributes (incl. methods).
    @@ -2886,16 +2886,14 @@ 

    Format

    cdef enum <enum_name>: <member_name>, <member_name>, ...

    -

    PyInstaller

    $ 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.
    +

    Virtual Environments

    System for installing libraries directly into project's directory.

    $ python3 -m venv <name>      # Creates virtual environment in current directory.
    +$ source <name>/bin/activate  # Activates venv. On Windows run `<name>\Scripts\activate`.
    +$ pip3 install <library>      # Installs the library into active environment.
    +$ python3 <path>              # Runs the script in active environment. Also `./<path>`.
    +$ deactivate                  # Deactivates virtual environment.
     
    -
      -
    • File paths need to be updated to 'os.path.join(sys._MEIPASS, <path>)'.
    • -
    +

    Basic Script Template

    #!/usr/bin/env python3
     #
     # Usage: .py
    @@ -2932,7 +2930,7 @@ 

    Format

    -

    Bin, Hex

    <int> = ±0b<bin>                                  # Or: ±0x<hex>
    +

    Bin, Hex

    <int> = ±0b<bin>                                  # Or: ±0x<hex>
     <int> = int('±<bin>', 2)                          # Or: int('±<hex>', 16)
     <int> = int('±0b<bin>', 0)                        # Or: int('±0x<hex>', 0)
     <str> = bin(<int>)                                # Returns '[-]0b<bin>'.
    @@ -2930,7 +2930,7 @@ 

    Format

    \n'; +const BIN_HEX = + '<int> = ±0b<bin> # Or: ±0x<hex>\n' + + '<int> = int(\'±<bin>\', 2) # Or: int(\'±<hex>\', 16)\n' + + '<int> = int(\'±0b<bin>\', 0) # Or: int(\'±0x<hex>\', 0)\n' + + '<str> = bin(<int>) # Returns \'[-]0b<bin>\'.\n'; + const LRU_CACHE = 'from functools import lru_cache\n' + '\n' + @@ -800,6 +806,7 @@ function fixClasses() { } function fixHighlights() { + $(`code:contains( = ±0b)`).html(BIN_HEX); $(`code:contains(@lru_cache(maxsize=None))`).html(LRU_CACHE); $(`code:contains(@debug(print_result=True))`).html(PARAMETRIZED_DECORATOR); $(`code:contains(print/str/repr([]))`).html(REPR_USE_CASES); From 2f6477aa20ff30c448733b9543a9cd119cf99654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Thu, 3 Aug 2023 09:55:33 +0200 Subject: [PATCH 011/418] Comment indentation fixes --- README.md | 62 +++++++++++++++++++++++++------------------------- index.html | 66 +++++++++++++++++++++++++++--------------------------- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 55af7e423..ec5b40e6f 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Contents Main ---- ```python -if __name__ == '__main__': # Runs main() if file wasn't imported. +if __name__ == '__main__': # Runs main() if file wasn't imported. main() ``` @@ -29,19 +29,19 @@ if __name__ == '__main__': # Runs main() if file wasn't imported. List ---- ```python - = [] # Or: [from_inclusive : to_exclusive : ±step] + = [] # Or: [from_inclusive : to_exclusive : ±step] ``` ```python -.append() # Or: += [] -.extend() # Or: += +.append() # Or: += [] +.extend() # Or: += ``` ```python -.sort() # Sorts in ascending order. -.reverse() # Reverses the list in-place. - = sorted() # Returns a new sorted list. - = reversed() # Returns reversed iterator. +.sort() # Sorts in ascending order. +.reverse() # Reverses the list in-place. + = sorted() # Returns a new sorted list. + = reversed() # Returns reversed iterator. ``` ```python @@ -57,12 +57,12 @@ list_of_chars = list() * **Module [operator](#operator) provides functions itemgetter() and mul() that offer the same functionality as [lambda](#lambda) expressions above.** ```python -.insert(, ) # Inserts item at index and moves the rest to the right. - = .pop([]) # Removes and returns item at index or from the end. - = .count() # Returns number of occurrences. Also works on strings. - = .index() # Returns index of the first occurrence or raises ValueError. -.remove() # Removes first occurrence of the item or raises ValueError. -.clear() # Removes all items. Also works on dictionary and set. +.insert(, ) # Inserts item at index and moves the rest to the right. + = .pop([]) # Removes and returns item at index or from the end. + = .count() # Returns number of occurrences. Also works on strings. + = .index() # Returns index of the first occurrence or raises ValueError. +.remove() # Removes first occurrence of the item or raises ValueError. +.clear() # Removes all items. Also works on dictionary and set. ``` @@ -144,9 +144,9 @@ Tuple ----- **Tuple is an immutable and hashable list.** ```python - = () # Empty tuple. - = (,) # Or: , - = (, [, ...]) # Or: , [, ...] + = () # Empty tuple. + = (,) # Or: , + = (, [, ...]) # Or: , [, ...] ``` ### Named Tuple @@ -170,9 +170,9 @@ Range ----- **Immutable and hashable sequence of integers.** ```python - = range(stop) # range(to_exclusive) - = range(start, stop) # range(from_inclusive, to_exclusive) - = range(start, stop, ±step) # range(from_inclusive, to_exclusive, ±step_size) + = range(stop) # range(to_exclusive) + = range(start, stop) # range(from_inclusive, to_exclusive) + = range(start, stop, ±step) # range(from_inclusive, to_exclusive, ±step_size) ``` ```python @@ -192,10 +192,10 @@ for i, el in enumerate( [, i_start]): Iterator -------- ```python - = iter() # `iter()` returns unmodified iterator. - = iter(, to_exclusive) # A sequence of return values until 'to_exclusive'. - = next( [, default]) # Raises StopIteration or returns 'default' on end. - = list() # Returns a list of iterator's remaining elements. + = iter() # `iter()` returns unmodified iterator. + = iter(, to_exclusive) # A sequence of return values until 'to_exclusive'. + = next( [, default]) # Raises StopIteration or returns 'default' on end. + = list() # Returns a list of iterator's remaining elements. ``` ### Itertools @@ -204,19 +204,19 @@ import itertools as it ``` ```python - = it.count(start=0, step=1) # Returns updated value endlessly. Accepts floats. - = it.repeat( [, times]) # Returns element endlessly or 'times' times. - = it.cycle() # Repeats the sequence endlessly. + = it.count(start=0, step=1) # Returns updated value endlessly. Accepts floats. + = it.repeat( [, times]) # Returns element endlessly or 'times' times. + = it.cycle() # Repeats the sequence endlessly. ``` ```python - = it.chain(, [, ...]) # Empties collections in order (figuratively). - = it.chain.from_iterable() # Empties collections inside a collection in order. + = it.chain(, [, ...]) # Empties collections in order (figuratively). + = it.chain.from_iterable() # Empties collections inside a collection in order. ``` ```python - = it.islice(, to_exclusive) # Only returns first 'to_exclusive' elements. - = it.islice(, from_inc, …) # `to_exclusive, +step_size`. Indices can be None. + = it.islice(, to_exclusive) # Only returns first 'to_exclusive' elements. + = it.islice(, from_inc, …) # `to_exclusive, +step_size`. Indices can be None. ``` diff --git a/index.html b/index.html index 93a228b01..ce9631287 100644 --- a/index.html +++ b/index.html @@ -54,7 +54,7 @@
    - +
    @@ -96,20 +96,20 @@ -

    #Main

    if __name__ == '__main__':     # Runs main() if file wasn't imported.
    +

    #Main

    if __name__ == '__main__':      # Runs main() if file wasn't imported.
         main()
     
    -

    #List

    <list> = <list>[<slice>]       # Or: <list>[from_inclusive : to_exclusive : ±step]
    +

    #List

    <list> = <list>[<slice>]        # Or: <list>[from_inclusive : to_exclusive : ±step]
     
    -
    <list>.append(<el>)            # Or: <list> += [<el>]
    -<list>.extend(<collection>)    # Or: <list> += <collection>
    +
    <list>.append(<el>)             # Or: <list> += [<el>]
    +<list>.extend(<collection>)     # Or: <list> += <collection>
     
    -
    <list>.sort()                  # Sorts in ascending order.
    -<list>.reverse()               # Reverses the list in-place.
    -<list> = sorted(<collection>)  # Returns a new sorted list.
    -<iter> = reversed(<list>)      # Returns reversed iterator.
    +
    <list>.sort()                   # Sorts in ascending order.
    +<list>.reverse()                # Reverses the list in-place.
    +<list> = sorted(<collection>)   # Returns a new sorted list.
    +<iter> = reversed(<list>)       # Returns reversed iterator.
     
    sum_of_elements  = sum(<collection>)
     elementwise_sum  = [sum(pair) for pair in zip(list_a, list_b)]
    @@ -123,12 +123,12 @@
     
  • For details about sorted(), min() and max() see sortable.
  • Module operator provides functions itemgetter() and mul() that offer the same functionality as lambda expressions above.
  • -
    <list>.insert(<int>, <el>)     # Inserts item at index and moves the rest to the right.
    -<el>  = <list>.pop([<int>])    # Removes and returns item at index or from the end.
    -<int> = <list>.count(<el>)     # Returns number of occurrences. Also works on strings.
    -<int> = <list>.index(<el>)     # Returns index of the first occurrence or raises ValueError.
    -<list>.remove(<el>)            # Removes first occurrence of the item or raises ValueError.
    -<list>.clear()                 # Removes all items. Also works on dictionary and set.
    +
    <list>.insert(<int>, <el>)      # Inserts item at index and moves the rest to the right.
    +<el>  = <list>.pop([<int>])     # Removes and returns item at index or from the end.
    +<int> = <list>.count(<el>)      # Returns number of occurrences. Also works on strings.
    +<int> = <list>.index(<el>)      # Returns index of the first occurrence or raises ValueError.
    +<list>.remove(<el>)             # Removes first occurrence of the item or raises ValueError.
    +<list>.clear()                  # Removes all items. Also works on dictionary and set.
     

    #Dictionary

    <view> = <dict>.keys()                          # Coll. of keys that reflects changes.
     <view> = <dict>.values()                        # Coll. of values that reflects changes.
    @@ -182,9 +182,9 @@
     
    -

    #Tuple

    Tuple is an immutable and hashable list.

    <tuple> = ()                                # Empty tuple.
    -<tuple> = (<el>,)                           # Or: <el>,
    -<tuple> = (<el_1>, <el_2> [, ...])          # Or: <el_1>, <el_2> [, ...]
    +

    #Tuple

    Tuple is an immutable and hashable list.

    <tuple> = ()                               # Empty tuple.
    +<tuple> = (<el>,)                          # Or: <el>,
    +<tuple> = (<el_1>, <el_2> [, ...])         # Or: <el_1>, <el_2> [, ...]
     
    @@ -201,9 +201,9 @@
    -

    #Range

    Immutable and hashable sequence of integers.

    <range> = range(stop)                       # range(to_exclusive)
    -<range> = range(start, stop)                # range(from_inclusive, to_exclusive)
    -<range> = range(start, stop, ±step)         # range(from_inclusive, to_exclusive, ±step_size)
    +

    #Range

    Immutable and hashable sequence of integers.

    <range> = range(stop)                      # range(to_exclusive)
    +<range> = range(start, stop)               # range(from_inclusive, to_exclusive)
    +<range> = range(start, stop, ±step)        # range(from_inclusive, to_exclusive, ±step_size)
     
    @@ -214,24 +214,24 @@ ...
    -

    #Iterator

    <iter> = iter(<collection>)                 # `iter(<iter>)` returns unmodified iterator.
    -<iter> = iter(<function>, to_exclusive)     # A sequence of return values until 'to_exclusive'.
    -<el>   = next(<iter> [, default])           # Raises StopIteration or returns 'default' on end.
    -<list> = list(<iter>)                       # Returns a list of iterator's remaining elements.
    +

    #Iterator

    <iter> = iter(<collection>)                # `iter(<iter>)` returns unmodified iterator.
    +<iter> = iter(<function>, to_exclusive)    # A sequence of return values until 'to_exclusive'.
    +<el>   = next(<iter> [, default])          # Raises StopIteration or returns 'default' on end.
    +<list> = list(<iter>)                      # Returns a list of iterator's remaining elements.
     

    Itertools

    import itertools as it
     
    -
    <iter> = it.count(start=0, step=1)          # Returns updated value endlessly. Accepts floats.
    -<iter> = it.repeat(<el> [, times])          # Returns element endlessly or 'times' times.
    -<iter> = it.cycle(<collection>)             # Repeats the sequence endlessly.
    +
    <iter> = it.count(start=0, step=1)         # Returns updated value endlessly. Accepts floats.
    +<iter> = it.repeat(<el> [, times])         # Returns element endlessly or 'times' times.
    +<iter> = it.cycle(<collection>)            # Repeats the sequence endlessly.
     
    -
    <iter> = it.chain(<coll>, <coll> [, ...])   # Empties collections in order (figuratively).
    -<iter> = it.chain.from_iterable(<coll>)     # Empties collections inside a collection in order.
    +
    <iter> = it.chain(<coll>, <coll> [, ...])  # Empties collections in order (figuratively).
    +<iter> = it.chain.from_iterable(<coll>)    # Empties collections inside a collection in order.
     
    -
    <iter> = it.islice(<coll>, to_exclusive)    # Only returns first 'to_exclusive' elements.
    -<iter> = it.islice(<coll>, from_inc, …)     # `to_exclusive, +step_size`. Indices can be None.
    +
    <iter> = it.islice(<coll>, to_exclusive)   # Only returns first 'to_exclusive' elements.
    +<iter> = it.islice(<coll>, from_inc, …)    # `to_exclusive, +step_size`. Indices can be None.
     

    #Generator

    • Any function that contains a yield statement returns a generator.
    • @@ -2930,7 +2930,7 @@

      Format

    Setup

    logging.basicConfig(
    -    filename=None,                                # Logs to console by default.
    +    filename=None,                                # Logs to console (stderr) by default.
         format='%(levelname)s:%(name)s:%(message)s',  # Add `%(asctime)s` for datetime.
         level=logging.WARNING,                        # Drops messages with lower priority.
         handlers=[logging.StreamHandler()]            # Uses FileHandler if filename is set.
    @@ -2040,7 +2040,7 @@ 

    Format

    'handlers.RotatingFileHandler' creates and deletes log files based on 'maxBytes' and 'backupCount' arguments. -

    Creates a logger that writes all messages to a file and sends them to the root logger that prints to stdout:

    >>> logging.basicConfig(level='WARNING')
    +

    Creates a logger that writes all messages to a file and sends them to the root logger that prints to stderr:

    >>> logging.basicConfig(level='WARNING')
     >>> logger = logging.getLogger('my_module')
     >>> handler = logging.FileHandler('test.log')
     >>> formatter = logging.Formatter('%(asctime)s %(levelname)s:%(name)s:%(message)s')
    @@ -2074,11 +2074,11 @@ 

    Format

    #Web

    Flask is a micro web framework/server. 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
    +import flask
     
    -
    app = Flask(__name__)
    +
    app = flask.Flask(__name__)
     app.run(host=None, port=None, debug=None)
     
    @@ -1745,6 +1743,7 @@

    Format

    'kwargs=<dict>' to pass keyword arguments to the function.
  • Use 'daemon=True', or the program will not be able to exit while the thread is alive.
  • +
  • To delay thread execution use 'Timer(<float>, <func>)' instead of Thread().
  • Lock

    <lock> = RLock()                               # Lock that can only be released by acquirer.
     <lock>.acquire()                               # Waits for the lock to be available.
    @@ -1760,7 +1759,7 @@ 

    Format

    # Wait() blocks until it's called n_times.

    -

    Queue

    <Queue> = queue.Queue(maxsize=0)               # A thread-safe FIFO queue. Also LifoQueue.
    +

    Queue

    <Queue> = queue.Queue(maxsize=0)               # A thread-safe first-in-first-out queue.
     <Queue>.put(<el>)                              # Blocks until queue stops being full.
     <Queue>.put_nowait(<el>)                       # Raises queue.Full exception if full.
     <el> = <Queue>.get()                           # Blocks until queue stops being empty.
    @@ -1784,8 +1783,8 @@ 

    Format

    pickable. Queues must be sent using executor's 'initargs' and 'initializer' parameters.

    #Operator

    Module of functions that provide the functionality of operators. Functions are ordered by operator precedence, starting with least binding.

    import operator as op
    -<bool> = op.not_(<obj>)                                        # not (or/and are not provided)
    -<bool> = op.eq/ne/lt/le/gt/ge/contains(<obj>, <obj>)           # ==, !=, <, <=, >, >=, in
    +<bool> = op.not_(<obj>)                                        # or, and (both missing), not
    +<bool> = op.eq/ne/lt/le/gt/ge/contains/is_(<obj>, <obj>)       # ==, !=, <, <=, >, >=, in, is
     <obj>  = op.or_/xor/and_(<int/set>, <int/set>)                 # |, ^, &
     <obj>  = op.add/sub/mul/truediv/floordiv/mod(<obj>, <obj>)     # +, -, *, /, //, %
     <num>  = op.neg/invert(<num>)                                  # -, ~
    
    From f31a8382d612fd971412ae4c3f27b193443d8525 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jure=20=C5=A0orn?= 
    Date: Thu, 24 Aug 2023 14:39:26 +0200
    Subject: [PATCH 017/418] Web
    
    ---
     README.md  | 1 +
     index.html | 1 +
     2 files changed, 2 insertions(+)
    
    diff --git a/README.md b/README.md
    index 413140f80..51107b730 100644
    --- a/README.md
    +++ b/README.md
    @@ -2550,6 +2550,7 @@ def serve_file(filename):
     def serve_html(sport):
         return flask.render_template_string('

    {{title}}

    ', title=sport) ``` +* **Use `'render_template(filename, )'` to render template file.** * **To return an error code use `'abort()'` and to redirect use `'redirect()'`.** * **`'request.args[]'` returns parameter from the query string (URL part after '?').** * **Use `'session[key] = value'` to store session data like username, etc.** diff --git a/index.html b/index.html index 89db64e1b..a17a97fa1 100644 --- a/index.html +++ b/index.html @@ -2096,6 +2096,7 @@

    Format

    'render_template(filename, <kwargs>)' to render template file.
  • To return an error code use 'abort(<int>)' and to redirect use 'redirect(<url>)'.
  • 'request.args[<str>]' returns parameter from the query string (URL part after '?').
  • Use 'session[key] = value' to store session data like username, etc.
  • From 8634b822a51dcb345c2584a9510402bc4be8c0a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Thu, 24 Aug 2023 14:41:30 +0200 Subject: [PATCH 018/418] Threading --- README.md | 2 +- index.html | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 51107b730..4bd1e4d32 100644 --- a/README.md +++ b/README.md @@ -2089,7 +2089,7 @@ from collections import deque Threading --------- -* **CPython interpreter can only run a single thread at a time. Using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.** +**CPython interpreter can only run a single thread at a time. Using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.** ```python from threading import Thread, Timer, RLock, Semaphore, Event, Barrier from concurrent.futures import ThreadPoolExecutor, as_completed diff --git a/index.html b/index.html index a17a97fa1..61dac04fe 100644 --- a/index.html +++ b/index.html @@ -1727,9 +1727,7 @@

    Format

    #Threading

      -
    • CPython interpreter can only run a single thread at a time. Using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.
    • -
    from threading import Thread, Timer, RLock, Semaphore, Event, Barrier
    +

    #Threading

    CPython interpreter can only run a single thread at a time. Using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.

    from threading import Thread, Timer, RLock, Semaphore, Event, Barrier
     from concurrent.futures import ThreadPoolExecutor, as_completed
     
    From e13394874ecb624598703aae64a6daa67bdc7af6 Mon Sep 17 00:00:00 2001 From: Dmitri Mi Date: Wed, 30 Aug 2023 11:07:00 -0400 Subject: [PATCH 019/418] Fix simpleaudio synthesizer --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4bd1e4d32..8e46d52da 100644 --- a/README.md +++ b/README.md @@ -2966,7 +2966,8 @@ parse_note = lambda note: (get_hz(note[:2]), 1/4 if '♩' in note else 1/8) get_samples = lambda note: get_wave(*parse_note(note)) if note else get_pause(1/8) samples_f = it.chain.from_iterable(get_samples(n) for n in f'{P1},{P1},{P2}'.split(',')) samples_i = array.array('h', (int(f * 30000) for f in samples_f)) -simpleaudio.play_buffer(samples_i, 1, 2, F) +player = simpleaudio.play_buffer(samples_i, 1, 2, F) +player.wait_done() ``` From 622e6ab0ae75f4ea7e2fd0f95119e4d75606d908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Thu, 31 Aug 2023 23:51:52 +0200 Subject: [PATCH 020/418] Synthesizer --- README.md | 3 +-- index.html | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8e46d52da..cb224c8aa 100644 --- a/README.md +++ b/README.md @@ -2966,8 +2966,7 @@ parse_note = lambda note: (get_hz(note[:2]), 1/4 if '♩' in note else 1/8) get_samples = lambda note: get_wave(*parse_note(note)) if note else get_pause(1/8) samples_f = it.chain.from_iterable(get_samples(n) for n in f'{P1},{P1},{P2}'.split(',')) samples_i = array.array('h', (int(f * 30000) for f in samples_f)) -player = simpleaudio.play_buffer(samples_i, 1, 2, F) -player.wait_done() +simpleaudio.play_buffer(samples_i, 1, 2, F).wait_done() ``` diff --git a/index.html b/index.html index 61dac04fe..7cf85dd27 100644 --- a/index.html +++ b/index.html @@ -54,7 +54,7 @@
    - +
    @@ -2424,7 +2424,7 @@

    Format

    lambda note: get_wave(*parse_note(note)) if note else get_pause(1/8) samples_f = it.chain.from_iterable(get_samples(n) for n in f'{P1},{P1},{P2}'.split(',')) samples_i = array.array('h', (int(f * 30000) for f in samples_f)) -simpleaudio.play_buffer(samples_i, 1, 2, F) +simpleaudio.play_buffer(samples_i, 1, 2, F).wait_done()

    @@ -2928,7 +2928,7 @@

    Format

    #Datetime

    Provides 'date', 'time', 'datetime' and 'timedelta' classes. All are immutable and hashable.

    # pip3 install python-dateutil
     from datetime import date, time, datetime, timedelta, timezone
    -from dateutil.tz import tzlocal, gettz, datetime_exists, resolve_imaginary
    +from dateutil.tz import tzlocal, gettz
     
    @@ -531,25 +531,24 @@
  • 'fold=1' means the second pass in case of time jumping back for one hour.
  • Timedelta normalizes arguments to ±days, seconds (< 86 400) and microseconds (< 1M).
  • Use '<D/DT>.weekday()' to get the day of the week as an int, with Monday being 0.
  • -
  • '<DTa> = resolve_imaginary(<DTa>)' fixes DTs that fall into the missing hour.
  • -

    Now

    <D/DTn>  = D/DT.today()                     # Current local date or naive datetime.
    -<DTn>    = DT.utcnow()                      # Naive datetime from current UTC time.
    -<DTa>    = DT.now(<tzinfo>)                 # Aware datetime from current tz time.
    +

    Now

    <D/DTn>  = D/DT.today()                     # Current local date or naive DT. Also DT.now().
    +<DTa>    = DT.now(<tzinfo>)                 # Aware DT from current time in passed timezone.
     
    • To extract time use '<DTn>.time()', '<DTa>.time()' or '<DTa>.timetz()'.
    -

    Timezone

    <tzinfo> = timezone.utc                     # London without daylight saving time.
    +

    Timezone

    <tzinfo> = timezone.utc                     # London without daylight saving time (DST).
     <tzinfo> = timezone(<timedelta>)            # Timezone with fixed offset from UTC.
     <tzinfo> = tzlocal()                        # Local timezone. Also gettz().
     <tzinfo> = gettz('<Continent>/<City>')      # 'Continent/City_Name' timezone or None.
    -<DTa>    = <DT>.astimezone([<tzinfo>])      # Converts DT to the passed or local timezone.
    +<DTa>    = <DT>.astimezone([<tzinfo>])      # Converts DT to the passed or local fixed zone.
     <Ta/DTa> = <T/DT>.replace(tzinfo=<tzinfo>)  # Changes object's timezone without conversion.
     
      +
    • Timezones returned by gettz(), tzlocal(), and implicit local timezone of naive objects have offsets that vary through time due to DST and historical changes of the zone's base offset.
    • Standard library's zoneinfo.ZoneInfo() can be used instead of gettz() on Python 3.9 and later. It requires 'tzdata' package on Windows.

    Encode

    <D/T/DT> = D/T/DT.fromisoformat('<iso>')    # Object from ISO string. Raises ValueError.
    @@ -564,27 +563,28 @@
     
  • Python uses the Unix Epoch: '1970-01-01 00:00 UTC', '1970-01-01 01:00 CET', …
  • Decode

    <str>    = <D/T/DT>.isoformat(sep='T')      # Also `timespec='auto/hours/minutes/seconds/…'`.
    -<str>    = <D/T/DT>.strftime('<format>')    # Custom string representation.
    +<str>    = <D/T/DT>.strftime('<format>')    # Custom string representation of the object.
     <int>    = <D/DT>.toordinal()               # Days since Gregorian NYE 1, ignoring time and tz.
     <float>  = <DTn>.timestamp()                # Seconds since the Epoch, from DTn in local tz.
     <float>  = <DTa>.timestamp()                # Seconds since the Epoch, from aware datetime.
     
    -

    Format

    >>> dt = datetime.strptime('2015-05-14 23:39:00.00 +0200', '%Y-%m-%d %H:%M:%S.%f %z')
    ->>> dt.strftime("%A, %dth of %B '%y, %I:%M%p %Z")
    -"Thursday, 14th of May '15, 11:39PM UTC+02:00"
    +

    Format

    >>> dt = datetime.strptime('2025-08-14 23:39:00.00 +0200', '%Y-%m-%d %H:%M:%S.%f %z')
    +>>> dt.strftime("%dth of %B '%y (%a), %I:%M%p %Z")
    +"14th of August '25 (Thu), 11:39PM UTC+02:00"
     
    • '%z' accepts '±HH[:]MM' and returns '±HHMM' or empty string if datetime is naive.
    • '%Z' accepts 'UTC/GMT' and local timezone's code and returns timezone's name, 'UTC[±HH:MM]' if timezone is nameless, or an empty string if datetime is naive.
    • -
    • For abbreviated weekday and month use '%a' and '%b'.
    -

    Arithmetics

    <D/DT>   = <D/DT>  ± <TD>                   # Returned datetime can fall into missing hour.
    -<TD>     = <D/DTn> - <D/DTn>                # Returns the difference. Ignores time jumps.
    -<TD>     = <DTa>   - <DTa>                  # Ignores time jumps if they share tzinfo object.
    -<TD>     = <TD>    * <int/float>            # Also: <TD> = abs(<TD>) and <TD> = <TD> ±% <TD>.
    -<float>  = <TD>    / <TD>                   # How many weeks/years there are in TD. Also //.
    +

    Arithmetics

    <bool>   = <D/T/DTn> > <D/T/DTn>            # Ignores time jumps (fold attribute). Also ==.
    +<bool>   = <DTa>     > <DTa>                # Ignores time jumps if they share tzinfo object.
    +<TD>     = <D/DTn>   - <D/DTn>              # Returns the difference. Ignores time jumps.
    +<TD>     = <DTa>     - <DTa>                # Ignores time jumps if they share tzinfo object.
    +<D/DT>   = <D/DT>    ± <TD>                 # Returned datetime can fall into missing hour.
    +<TD>     = <TD>      * <int/float>          # Also: <TD> = abs(<TD>) and <TD> = <TD> ±% <TD>.
    +<float>  = <TD>      / <TD>                 # How many weeks/years there are in TD. Also //.
     

    #Arguments

    Inside Function Call

    func(<positional_args>)                           # func(0, 0)
    @@ -2928,7 +2928,7 @@ 

    Format