From 42f2e689796ce7de090f77bcd53a30288ae31df9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Tue, 22 Apr 2025 04:07:10 +0200 Subject: [PATCH] Numbers big changes, Combinatorics, Console app, GUI, Web --- README.md | 115 ++++++++++++++++++++--------------------- index.html | 115 +++++++++++++++++++++-------------------- parse.js | 12 ++--- pdf/index_for_pdf.html | 4 +- 4 files changed, 123 insertions(+), 123 deletions(-) diff --git a/README.md b/README.md index a43225b..eac1b55 100644 --- a/README.md +++ b/README.md @@ -494,64 +494,69 @@ Format Numbers ------- ```python - = int() # Or: math.trunc() - = float() # Or: - = complex(real=0, imag=0) # Or: ± j - = fractions.Fraction(0, 1) # Or: Fraction(numerator=0, denominator=1) - = decimal.Decimal() # Or: Decimal((sign, digits, exponent)) + = int() # Or: math.trunc() + = float() # Or: + = complex(real=0, imag=0) # Or: ± j + = fractions.Fraction(0, 1) # Or: Fraction(numerator=0, denominator=1) + = decimal.Decimal() # Or: Decimal((sign, digits, exponent)) ``` +* **`'int()'` and `'float()'` raise ValueError on malformed strings.** * **Decimal numbers are stored exactly, unlike most floats where `'1.1 + 2.2 != 3.3'`.** * **Floats can be compared with: `'math.isclose(, )'`.** * **Precision of decimal operations is set with: `'decimal.getcontext().prec = '`.** * **Bools can be used anywhere ints can, because bool is a subclass of int: `'True + 1 == 2'`.** -### Basic Functions +### Built-in Functions ```python - = pow(, ) # Or: ** - = abs() # = abs() - = round( [, ±ndigits]) # `round(126, -1) == 130` + = pow(, ) # Or: ** + = abs() # = abs() + = round( [, ±ndigits]) # Also math.floor/ceil(). + = min() # Also max(, [, ...]). + = sum() # Also math.prod(). ``` ### Math ```python -from math import e, pi, inf, nan, isinf, isnan # ` == 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 math import e, pi, inf, nan, isnan # `inf*0` and `nan+1` return nan. +from math import sqrt, factorial # `sqrt(-1)` raises ValueError. +from math import sin, cos, tan # Also: asin, degrees, radians. +from math import log, log10, log2 # Log accepts base as second arg. ``` ### Statistics ```python -from statistics import mean, median, variance # Also: stdev, quantiles, groupby. +from statistics import mean, median, mode # Mode returns the most common value. +from statistics import variance, stdev # Also: pvariance, pstdev, quantiles. ``` ### Random ```python -from random import random, randint, uniform # Also: gauss, choice, shuffle, seed. +from random import random, randint, uniform # Also: gauss, choice, shuffle, seed. ``` ```python - = random() # Returns a float inside [0, 1). - = randint/uniform(a, b) # Returns an int/float inside [a, b]. - = gauss(mean, stdev) # Also triangular(low, high, mode). - = choice() # Keeps it intact. Also sample(pop, k). -shuffle() # Shuffles the list in place. + = random() # Returns a float inside [0, 1). + = randint/uniform(a, b) # Returns an int/float inside [a, b]. + = gauss(mean, stdev) # Also triangular(low, high, mode). + = choice() # Keeps it intact. Also sample(pop, k). +shuffle() # Shuffles the list in place. ``` ### Hexadecimal Numbers ```python - = ±0x # Or: ±0b - = int('±', 16) # Or: int('±', 2) - = int('±0x', 0) # Or: int('±0b', 0) - = hex() # Returns '[-]0x'. Also bin(). + = ±0x # Or: ±0b + = int('±', 16) # Or: int('±', 2) + = int('±0x', 0) # Or: int('±0b', 0) + = hex() # Returns '[-]0x'. Also bin(). ``` ### Bitwise Operators ```python - = & # And (0b1100 & 0b1010 == 0b1000). - = | # Or (0b1100 | 0b1010 == 0b1110). - = ^ # Xor (0b1100 ^ 0b1010 == 0b0110). - = << n_bits # Left shift. Use >> for right. - = ~ # Not. Also - - 1. + = & # And (0b1100 & 0b1010 == 0b1000). + = | # Or (0b1100 | 0b1010 == 0b1110). + = ^ # Xor (0b1100 ^ 0b1010 == 0b0110). + = << n_bits # Left shift. Use >> for right. + = ~ # Not. Also - - 1. ``` @@ -562,30 +567,24 @@ import itertools as it ``` ```python ->>> 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)] +>>> list(it.product('abc', repeat=2)) # 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 ``` ```python ->>> 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 +>>> 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 . ``` ```python ->>> 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 . -``` - -```python ->>> list(it.combinations('abc', 2)) # a b c -[('a', 'b'), ('a', 'c'), # a . x x - ('b', 'c'), # b . . x -] # c . . . +>>> list(it.combinations('abc', 2)) # a b c +[('a', 'b'), ('a', 'c'), # a . x x + ('b', 'c'), # b . . x +] # c . . . ``` @@ -1183,7 +1182,7 @@ class Counter: ### Callable * **All functions and classes have a call() method, hence are callable.** -* **Use `'callable()'` or `'isinstance(, collections.abc.Callable)'` to check if object is callable.** +* **Use `'callable()'` or `'isinstance(, collections.abc.Callable)'` to check if object is callable. Calling an uncallable object raises `'TypeError'`.** * **When this cheatsheet uses `''` as an argument, it means `''`.** ```python class Counter: @@ -2435,7 +2434,7 @@ Console App ```python # $ pip3 install windows-curses import curses, os -from curses import A_REVERSE, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ENTER +from curses import A_REVERSE, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT def main(screen): ch, first, selected, paths = 0, 0, 0, os.listdir() @@ -2450,7 +2449,7 @@ def main(screen): selected += (ch == KEY_DOWN) and (selected < len(paths)-1) first -= (first > selected) first += (first < selected-(height-1)) - if ch in [KEY_LEFT, KEY_RIGHT, KEY_ENTER, ord('\n'), ord('\r')]: + if ch in [KEY_LEFT, KEY_RIGHT, ord('\n')]: new_dir = '..' if ch == KEY_LEFT else paths[selected] if os.path.isdir(new_dir): os.chdir(new_dir) @@ -2469,9 +2468,9 @@ GUI App # $ pip3 install PySimpleGUI import PySimpleGUI as sg -text_box = sg.Input(default_text='100', enable_events=True, key='-QUANTITY-') -dropdown = sg.InputCombo(['g', 'kg', 't'], 'kg', readonly=True, enable_events=True, k='-UNIT-') -label = sg.Text('100 kg is 220.462 lbs.', key='-OUTPUT-') +text_box = sg.Input(default_text='100', enable_events=True, key='QUANTITY') +dropdown = sg.InputCombo(['g', 'kg', 't'], 'kg', readonly=True, enable_events=True, k='UNIT') +label = sg.Text('100 kg is 220.462 lbs.', key='OUTPUT') button = sg.Button('Close') window = sg.Window('Weight Converter', [[text_box, dropdown], [label], [button]]) @@ -2480,13 +2479,13 @@ while True: if event in [sg.WIN_CLOSED, 'Close']: break try: - quantity = float(values['-QUANTITY-']) + quantity = float(values['QUANTITY']) except ValueError: continue - unit = values['-UNIT-'] + unit = values['UNIT'] factors = {'g': 0.001, 'kg': 1, 't': 1000} lbs = quantity * factors[unit] / 0.45359237 - window['-OUTPUT-'].update(value=f'{quantity} {unit} is {lbs:g} lbs.') + window['OUTPUT'].update(value=f'{quantity} {unit} is {lbs:g} lbs.') window.close() ``` @@ -2552,14 +2551,14 @@ app.run(host=None, port=None, debug=None) # Or: $ flask --app FILE run [--ARG[= * **Install a WSGI server like [Waitress](https://flask.palletsprojects.com/en/latest/deploying/waitress/) and a HTTP server such as [Nginx](https://flask.palletsprojects.com/en/latest/deploying/nginx/) for better security.** * **Debug mode restarts the app whenever script changes and displays errors in the browser.** -### Static Request +### Serving Files ```python @app.route('/img/') def serve_file(filename): return fl.send_from_directory('DIRNAME', filename) ``` -### Dynamic Request +### Serving HTML ```python @app.route('/') def serve_html(sport): @@ -2570,7 +2569,7 @@ def serve_html(sport): * **`'fl.request.args[]'` returns parameter from query string (URL part right of '?').** * **`'fl.session[] = '` stores session data. It requires secret key to be set at the startup with `'app.secret_key = '`.** -### REST Request +### Serving JSON ```python @app.post('//odds') def serve_json(sport): diff --git a/index.html b/index.html index 89dbbe4..7e80673 100644 --- a/index.html +++ b/index.html @@ -56,7 +56,7 @@
- +
@@ -455,75 +455,76 @@ Point(x=1, y=2 {90:X} # '5A'. Hexadecimal with upper-case letters. -

#Numbers

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

#Numbers

<int>      = int(<float/str/bool>)           # Or: math.trunc(<float>)
+<float>    = float(<int/str/bool>)           # Or: <int/float>e±<int>
+<complex>  = complex(real=0, imag=0)         # Or: <int/float> ± <int/float>j
+<Fraction> = fractions.Fraction(0, 1)        # Or: Fraction(numerator=0, denominator=1)
+<Decimal>  = decimal.Decimal(<str/int>)      # Or: Decimal((sign, digits, exponent))
 
    +
  • 'int(<str>)' and 'float(<str>)' raise ValueError on malformed strings.
  • Decimal numbers are stored exactly, unlike most floats where '1.1 + 2.2 != 3.3'.
  • Floats can be compared with: 'math.isclose(<float>, <float>)'.
  • Precision of decimal operations is set with: 'decimal.getcontext().prec = <int>'.
  • Bools can be used anywhere ints can, because bool is a subclass of int: 'True + 1 == 2'.
-

Basic Functions

<num> = pow(<num>, <num>)                         # Or: <number> ** <number>
-<num> = abs(<num>)                                # <float> = abs(<complex>)
-<num> = round(<num> [, ±ndigits])                 # `round(126, -1) == 130`
+

Built-in Functions

<num> = pow(<num>, <num>)                    # Or: <number> ** <number>
+<num> = abs(<num>)                           # <float> = abs(<complex>)
+<num> = round(<num> [, ±ndigits])            # Also math.floor/ceil(<number>).
+<num> = min(<collection>)                    # Also max(<num>, <num> [, ...]).
+<num> = sum(<collection>)                    # Also math.prod(<collection>).
 
-

Math

from math import e, pi, inf, nan, isinf, isnan    # `<el> == 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.
+

Math

from math import e, pi, inf, nan, isnan      # `inf*0` and `nan+1` return nan.
+from math import sqrt, factorial             # `sqrt(-1)` raises ValueError.
+from math import sin, cos, tan               # Also: asin, degrees, radians.
+from math import log, log10, log2            # Log accepts base as second arg.
 
-

Statistics

from statistics import mean, median, variance     # Also: stdev, quantiles, groupby.
+

Statistics

from statistics import mean, median, mode    # Mode returns the most common value.
+from statistics import variance, stdev       # Also: pvariance, pstdev, quantiles.
 
-

Random

from random import random, randint, uniform       # Also: gauss, choice, shuffle, seed.
+

Random

from random import random, randint, uniform  # Also: gauss, choice, shuffle, seed.
 
-
<float> = random()                                # Returns a float inside [0, 1).
-<num>   = randint/uniform(a, b)                   # Returns an int/float inside [a, b].
-<float> = gauss(mean, stdev)                      # Also triangular(low, high, mode).
-<el>    = choice(<sequence>)                      # Keeps it intact. Also sample(pop, k).
-shuffle(<list>)                                   # Shuffles the list in place.
+
<float> = random()                           # Returns a float inside [0, 1).
+<num>   = randint/uniform(a, b)              # Returns an int/float inside [a, b].
+<float> = gauss(mean, stdev)                 # Also triangular(low, high, mode).
+<el>    = choice(<sequence>)                 # Keeps it intact. Also sample(pop, k).
+shuffle(<list>)                              # Shuffles the list in place.
 
-

Hexadecimal Numbers

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

Hexadecimal Numbers

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

Bitwise Operators

<int> = <int> & <int>                             # And (0b1100 & 0b1010 == 0b1000).
-<int> = <int> | <int>                             # Or  (0b1100 | 0b1010 == 0b1110).
-<int> = <int> ^ <int>                             # Xor (0b1100 ^ 0b1010 == 0b0110).
-<int> = <int> << n_bits                           # Left shift. Use >> for right.
-<int> = ~<int>                                    # Not. Also -<int> - 1.
+

Bitwise Operators

<int> = <int> & <int>                        # And (0b1100 & 0b1010 == 0b1000).
+<int> = <int> | <int>                        # Or  (0b1100 | 0b1010 == 0b1110).
+<int> = <int> ^ <int>                        # Xor (0b1100 ^ 0b1010 == 0b0110).
+<int> = <int> << n_bits                      # Left shift. Use >> for right.
+<int> = ~<int>                               # Not. Also -<int> - 1.
 

#Combinatorics

import itertools as it
 
-
>>> 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)]
+
>>> list(it.product('abc', repeat=2))        #   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
+
>>> 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  .
 
-
>>> 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  .
-
-
>>> list(it.combinations('abc', 2))               #   a  b  c
-[('a', 'b'), ('a', 'c'),                          # a .  x  x
- ('b', 'c'),                                      # b .  .  x
-]                                                 # c .  .  .
+
>>> list(it.combinations('abc', 2))          #   a  b  c
+[('a', 'b'), ('a', 'c'),                     # a .  x  x
+ ('b', 'c'),                                 # b .  .  x
+]                                            # c .  .  .
 

#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
@@ -1012,7 +1013,7 @@ P = make_dataclass('P', [(open() function, etc.
 

Callable

  • All functions and classes have a call() method, hence are callable.
  • -
  • Use 'callable(<obj>)' or 'isinstance(<obj>, collections.abc.Callable)' to check if object is callable.
  • +
  • Use 'callable(<obj>)' or 'isinstance(<obj>, collections.abc.Callable)' to check if object is callable. Calling an uncallable object raises 'TypeError'.
  • When this cheatsheet uses '<function>' as an argument, it means '<callable>'.
class Counter:
     def __init__(self):
@@ -2004,7 +2005,7 @@ print(tabulate.tabulate(rows, headers='firstrow'

#Console App

Runs a basic file explorer in the console:

# $ pip3 install windows-curses
 import curses, os
-from curses import A_REVERSE, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ENTER
+from curses import A_REVERSE, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT
 
 def main(screen):
     ch, first, selected, paths = 0, 0, 0, os.listdir()
@@ -2019,7 +2020,7 @@ print(tabulate.tabulate(rows, headers='firstrow'and (selected < len(paths)-1)
         first -= (first > selected)
         first += (first < selected-(height-1))
-        if ch in [KEY_LEFT, KEY_RIGHT, KEY_ENTER, ord('\n'), ord('\r')]:
+        if ch in [KEY_LEFT, KEY_RIGHT, ord('\n')]:
             new_dir = '..' if ch == KEY_LEFT else paths[selected]
             if os.path.isdir(new_dir):
                 os.chdir(new_dir)
@@ -2033,9 +2034,9 @@ print(tabulate.tabulate(rows, headers='firstrow'

#GUI App

A weight converter GUI application:

# $ pip3 install PySimpleGUI
 import PySimpleGUI as sg
 
-text_box = sg.Input(default_text='100', enable_events=True, key='-QUANTITY-')
-dropdown = sg.InputCombo(['g', 'kg', 't'], 'kg', readonly=True, enable_events=True, k='-UNIT-')
-label    = sg.Text('100 kg is 220.462 lbs.', key='-OUTPUT-')
+text_box = sg.Input(default_text='100', enable_events=True, key='QUANTITY')
+dropdown = sg.InputCombo(['g', 'kg', 't'], 'kg', readonly=True, enable_events=True, k='UNIT')
+label    = sg.Text('100 kg is 220.462 lbs.', key='OUTPUT')
 button   = sg.Button('Close')
 window   = sg.Window('Weight Converter', [[text_box, dropdown], [label], [button]])
 
@@ -2044,13 +2045,13 @@ window   = sg.Window('Weight Converter', [[text
     if event in [sg.WIN_CLOSED, 'Close']:
         break
     try:
-        quantity = float(values['-QUANTITY-'])
+        quantity = float(values['QUANTITY'])
     except ValueError:
         continue
-    unit = values['-UNIT-']
+    unit = values['UNIT']
     factors = {'g': 0.001, 'kg': 1, 't': 1000}
     lbs = quantity * factors[unit] / 0.45359237
-    window['-OUTPUT-'].update(value=f'{quantity} {unit} is {lbs:g} lbs.')
+    window['OUTPUT'].update(value=f'{quantity} {unit} is {lbs:g} lbs.')
 window.close()
 
@@ -2105,12 +2106,12 @@ app.run(host=None, port=