From fccfc468a4306534b5947224094c82c8d8153dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Thu, 24 Aug 2023 14:15:18 +0200 Subject: [PATCH 001/390] Logging, Web, Image --- README.md | 66 +++++++++++++++++++++++++------------------------- index.html | 70 +++++++++++++++++++++++++++--------------------------- parse.js | 8 ------- 3 files changed, 68 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index ec5b40e6f..1366a6cfa 100644 --- a/README.md +++ b/README.md @@ -1500,7 +1500,7 @@ Exit import sys sys.exit() # Exits with exit code 0 (success). sys.exit() # Prints to stderr and exits with 1. -sys.exit() # Exits with passed exit code. +sys.exit() # Exits with the passed exit code. ``` @@ -2463,7 +2463,7 @@ logging.debug/info/warning/error/critical() # Logs to the root logger. ### Setup ```python 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. @@ -2482,7 +2482,7 @@ logging.basicConfig( * **Formatter also supports: pathname, filename, funcName, lineno, thread and process.** * **A `'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: +#### Creates a logger that writes all messages to a file and sends them to the root logger that prints to stderr: ```python >>> logging.basicConfig(level='WARNING') >>> logger = logging.getLogger('my_module') @@ -2527,11 +2527,11 @@ Web **Flask is a micro web framework/server. If you just want to open a html file in a web browser use `'webbrowser.open()'` instead.** ```python # $ pip3 install flask -from flask import Flask, send_from_directory, render_template_string, request +import flask ``` ```python -app = Flask(__name__) +app = flask.Flask(__name__) app.run(host=None, port=None, debug=None) ``` * **Starts the app at `'http://localhost:5000'`. Use `'host="0.0.0.0"'` to run externally.** @@ -2542,14 +2542,14 @@ app.run(host=None, port=None, debug=None) ```python @app.route('/img/') def serve_file(filename): - return send_from_directory('dirname/', filename) + return flask.send_from_directory('dirname/', filename) ``` ### Dynamic Request ```python @app.route('/') def serve_html(sport): - return render_template_string('

{{title}}

', title=sport) + return flask.render_template_string('

{{title}}

', title=sport) ``` * **To return an error code use `'abort()'` and to redirect use `'redirect()'`.** * **`'request.args[]'` returns parameter from the query string (URL part after '?').** @@ -2559,7 +2559,7 @@ def serve_html(sport): ```python @app.post('//odds') def serve_json(sport): - team = request.form['team'] + team = flask.request.form['team'] return {'team': team, 'odds': [2.09, 3.74, 3.68]} ``` @@ -2749,37 +2749,36 @@ Image ----- ```python # $ pip3 install pillow -from PIL import Image, ImageDraw +from PIL import Image, ImageFilter, ImageEnhance ``` ```python - = Image.new('', (width, height)) # Also `color=`. - = Image.open() # Identifies format based on file contents. - = .convert('') # Converts image to the new mode. -.save() # Selects format based on the path extension. -.show() # Opens image in the default preview app. + = Image.new('', (width, height)) # Also `color=`. + = Image.open() # Identifies format based on file contents. + = .convert('') # Converts image to the new mode. +.save() # Selects format based on the path extension. +.show() # Opens image in the default preview app. ``` ```python - = .getpixel((x, y)) # Returns a pixel. -.putpixel((x, y), ) # Writes a pixel to the image. - = .getdata() # Returns a flattened view of the pixels. -.putdata() # Writes a flattened sequence of pixels. -.paste(, (x, y)) # Writes passed image to the image. + = .getpixel((x, y)) # Returns a pixel. +.putpixel((x, y), ) # Writes a pixel to the image. + = .getdata() # Returns a flattened view of the pixels. +.putdata() # Writes a flattened sequence of pixels. +.paste(, (x, y)) # Writes passed image to the image. ``` ```python - = .filter() # ` = ImageFilter.([])` - = .enhance() # ` = ImageEnhance.()` + = .filter() # ` = ImageFilter.([])` + = .enhance() # ` = ImageEnhance.()` ``` ```python - = np.array() # Creates NumPy array from the image. - = Image.fromarray(np.uint8()) # Use .clip(0, 255) to clip the values. + = np.array() # Creates NumPy array from the image. + = Image.fromarray(np.uint8()) # Use .clip(0, 255) to clip values. ``` ### Modes -* **`'1'` - 1-bit pixels, black and white, stored with one pixel per byte.** * **`'L'` - 8-bit pixels, greyscale.** * **`'RGB'` - 3x8-bit pixels, true color.** * **`'RGBA'` - 4x8-bit pixels, true color with transparency mask.** @@ -2807,14 +2806,15 @@ img.show() ### Image Draw ```python - = ImageDraw.Draw() # Object for adding 2D graphics to the image. -.point((x, y)) # Draws a point. Truncates floats into ints. -.line((x1, y1, x2, y2 [, ...])) # To get anti-aliasing use Image's resize(). -.arc((x1, y1, x2, y2), deg1, deg2) # Always draws in clockwise direction. -.rectangle((x1, y1, x2, y2)) # To rotate use Image's rotate() and paste(). -.polygon((x1, y1, x2, y2, ...)) # Last point gets connected to the first. -.ellipse((x1, y1, x2, y2)) # To rotate use Image's rotate() and paste(). -.text((x, y), text, font=) # ` = ImageFont.truetype(, size)` +from PIL import ImageDraw, ImageFont + = ImageDraw.Draw() # Object for adding 2D graphics to the image. +.point((x, y)) # Draws a point. Truncates floats into ints. +.line((x1, y1, x2, y2 [, ...])) # To get anti-aliasing use Image's resize(). +.arc((x1, y1, x2, y2), deg1, deg2) # Always draws in clockwise direction. +.rectangle((x1, y1, x2, y2)) # To rotate use Image's rotate() and paste(). +.polygon((x1, y1, x2, y2, ...)) # Last point gets connected to the first. +.ellipse((x1, y1, x2, y2)) # To rotate use Image's rotate() and paste(). +.text((x, y), text, font=) # ` = ImageFont.truetype(, size)` ``` * **Use `'fill='` to set the primary color.** * **Use `'width='` to set the width of lines or contours.** @@ -3545,7 +3545,7 @@ $ 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. +$ deactivate # Deactivates the active virtual environment. ``` ### Basic Script Template diff --git a/index.html b/index.html index 9fab83d30..a1e5cb871 100644 --- a/index.html +++ b/index.html @@ -54,7 +54,7 @@
- +
@@ -1278,7 +1278,7 @@

#Exit

Exits the interpreter by raising SystemExit exception.

import sys
 sys.exit()                        # Exits with exit code 0 (success).
 sys.exit(<el>)                    # Prints to stderr and exits with 1.
-sys.exit(<int>)                   # Exits with passed exit code.
+sys.exit(<int>)                   # Exits with the passed exit code.
 
@@ -2021,7 +2021,7 @@

Format

# Calls error() with caught exception.

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 003/390] 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 004/390] 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 005/390] 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 006/390] 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