From 367c06c45ed8d8dcc5e21a6f81cc7b39b2e0ae7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Thu, 7 Nov 2024 13:42:53 +0100 Subject: [PATCH 01/34] OS Commands, big changes to Pandas --- README.md | 189 +++++++++++++++++++++++++-------------------------- index.html | 195 ++++++++++++++++++++++++++--------------------------- parse.js | 41 +++++------ 3 files changed, 208 insertions(+), 217 deletions(-) diff --git a/README.md b/README.md index e905c08c2..070fda5c9 100644 --- a/README.md +++ b/README.md @@ -1740,9 +1740,9 @@ shutil.rmtree() # Deletes the directory. ### Shell Commands ```python - = os.popen('') # Executes command in sh/cmd. Returns its stdout pipe. + = os.popen('') # Executes commands in sh/cmd. Returns combined stdout. = .read(size=-1) # Reads 'size' chars or until EOF. Also readline/s(). - = .close() # Closes the pipe. Returns None on success (returncode 0). + = .close() # Returns None if last command exited with returncode 0. ``` #### Sends '1 + 1' to the basic calculator and captures its output: @@ -3146,6 +3146,8 @@ if __name__ == '__main__': Pandas ------ +**Data analysis library. For examples see [Plotly](#displaysalinechartoftotalcoronavirusdeathspermilliongroupedbycontinent).** + ```python # $ pip3 install pandas matplotlib import pandas as pd, matplotlib.pyplot as plt @@ -3155,65 +3157,61 @@ import pandas as pd, matplotlib.pyplot as plt **Ordered dictionary with a name.** ```python ->>> sr = pd.Series([1, 2], index=['x', 'y'], name='a'); sr +>>> s = pd.Series([1, 2], index=['x', 'y'], name='a'); s x 1 y 2 Name: a, dtype: int64 ``` ```python - = pd.Series() # Assigns RangeIndex starting at 0. - = pd.Series() # Takes dictionary's keys for index. - = pd.Series(, index=) # Only keeps items with keys specified in index. + = pd.Series() # Assigns RangeIndex starting at 0. + = pd.Series() # Takes dictionary's keys for index. + = pd.Series(, index=) # Only keeps items with keys specified in index. ``` ```python - = .loc[key] # Or: .iloc[i] - = .loc[coll_of_keys] # Or: .iloc[coll_of_i] - = .loc[from_key : to_key_inc] # Or: .iloc[from_i : to_i_exc] + = .loc[key] # Or: .iloc[i] + = .loc[coll_of_keys] # Or: .iloc[coll_of_i] + = .loc[from_key : to_key_inc] # Or: .iloc[from_i : to_i_exc] ``` ```python - = [key/i] # Or: . - = [coll_of_keys/coll_of_i] # Or: [key/i : key/i] - = [bools] # Or: .loc/iloc[bools] + = [key/i] # Or: . + = [coll_of_keys/coll_of_i] # Or: [key/i : key/i] + = [bools] # Or: .loc/iloc[bools] ``` ```python - = > # Returns a Series of bools. - = + # Items with non-matching keys get value NaN. + = > # Returns a Series of bools. + = + # Items with non-matching keys get value NaN. ``` ```python - = pd.concat() # Concats multiple series into one long Series. - = .combine_first() # Adds items that are not yet present. -.update() # Updates items that are already present. + = pd.concat() # Concats multiple series into one long Series. + = .combine_first() # Adds items that are not yet present. +.update() # Updates items that are already present. ``` ```python -.plot.line/area/bar/pie/hist() # Generates a Matplotlib plot. +.plot.line/area/bar/pie/hist() # Generates a Matplotlib plot. plt.show() # Displays the plot. Also plt.savefig(). ``` +* **Indexing objects can't be tuples because `'obj[x, y]'` is converted to `'obj[(x, y)]'`!** +* **Pandas uses NumPy types like `'np.int64'`. Series is converted to `'float64'` if we assign np.nan to any item. Use `'.astype()'` to get converted Series.** #### Series — Aggregate, Transform, Map: ```python - = .sum/max/mean/idxmax/all() # Or: .agg(lambda : ) - = .rank/diff/cumsum/ffill/interpo…() # Or: .agg/transform(lambda : ) - = .fillna() # Or: .agg/transform/map(lambda : ) -``` - -```python ->>> sr = pd.Series([2, 3], index=['x', 'y']); sr -x 2 -y 3 + = .sum/max/mean/idxmax/all() # Or: .agg(lambda : ) + = .rank/diff/cumsum/ffill/interpol…() # Or: .agg/transform(lambda : ) + = .isna/fillna/isin([]) # Or: .agg/transform/map(lambda : ) ``` ```text +---------------+-------------+-------------+---------------+ | | 'sum' | ['sum'] | {'s': 'sum'} | +---------------+-------------+-------------+---------------+ -| sr.apply(…) | 5 | sum 5 | s 5 | -| sr.agg(…) | | | | +| s.apply(…) | 3 | sum 3 | s 3 | +| s.agg(…) | | | | +---------------+-------------+-------------+---------------+ ``` @@ -3221,14 +3219,13 @@ y 3 +---------------+-------------+-------------+---------------+ | | 'rank' | ['rank'] | {'r': 'rank'} | +---------------+-------------+-------------+---------------+ -| sr.apply(…) | | rank | | -| sr.agg(…) | x 1 | x 1 | r x 1 | -| | y 2 | y 2 | y 2 | +| s.apply(…) | | rank | | +| s.agg(…) | x 1.0 | x 1.0 | r x 1.0 | +| | y 2.0 | y 2.0 | y 2.0 | +---------------+-------------+-------------+---------------+ ``` -* **Indexing objects can't be tuples because `'obj[x, y]'` is converted to `'obj[(x, y)]'`!** * **Methods ffill(), interpolate(), fillna() and dropna() accept `'inplace=True'`.** -* **Last result has a hierarchical index. Use `'[key_1, key_2]'` to get its values.** +* **Last result has a multi-index. Use `'[key_1, key_2]'` to get its values.** ### DataFrame **Table with labeled rows and columns.** @@ -3241,33 +3238,39 @@ b 3 4 ``` ```python - = pd.DataFrame() # Rows can be either lists, dicts or series. - = pd.DataFrame() # Columns can be either lists, dicts or series. + = pd.DataFrame() # Rows can be either lists, dicts or series. + = pd.DataFrame() # Columns can be either lists, dicts or series. ``` ```python - = .loc[row_key, col_key] # Or: .iloc[row_i, col_i] - = .loc[row_key/s] # Or: .iloc[row_i/s] - = .loc[:, col_key/s] # Or: .iloc[:, col_i/s] - = .loc[row_bools, col_bools] # Or: .iloc[row_bools, col_bools] + = .loc[row_key, col_key] # Or: .iloc[row_i, col_i] + = .loc[row_key/s] # Or: .iloc[row_i/s] + = .loc[:, col_key/s] # Or: .iloc[:, col_i/s] + = .loc[row_bools, col_bools] # Or: .iloc[row_bools, col_bools] ``` ```python - = [col_key/s] # Or: . - = [row_bools] # Keeps rows as specified by bools. - = [] # Assigns NaN to items that are False in bools. + = [col_key/s] # Or: . + = [row_bools] # Keeps rows as specified by bools. + = [] # Assigns NaN to items that are False in bools. ``` ```python - = > # Returns DF of bools. Sr is treated as a row. - = + # Items with non-matching keys get value NaN. + = > # Returns DF of bools. S is treated as a row. + = + # Items with non-matching keys get value NaN. ``` ```python - = .set_index(col_key) # Replaces row keys with column's values. - = .reset_index(drop=False) # Drops or moves row keys to column named index. - = .sort_index(ascending=True) # Sorts rows by row keys. Use `axis=1` for cols. - = .sort_values(col_key/s) # Sorts rows by passed column/s. Also `axis=1`. + = .set_index(col_key) # Replaces row keys with column's values. + = .reset_index(drop=False) # Drops or moves row keys to column named index. + = .sort_index(ascending=True) # Sorts rows by row keys. Use `axis=1` for cols. + = .sort_values(col_key/s) # Sorts rows by passed column/s. Also `axis=1`. +``` + +```python + = .head/tail/sample() # Returns first, last, or random n elements. + = .describe() # Describes columns. Also shape, info(), corr(). + = .query('') # Filters rows with e.g. 'col_1 == val_1 and …'. ``` ```python @@ -3301,41 +3304,28 @@ c 6 7 | axis=0, | a 1 2 . | 2 | | Uses 'outer' by default. | | join=…) | b 3 4 . | 4 | | A Series is treated as a | | | b . 4 5 | 4 | | column. To add a row use | -| | c . 6 7 | 6 | | pd.concat([l, DF([sr])]).| +| | c . 6 7 | 6 | | pd.concat([l, DF([s])]). | +------------------------+---------------+------------+------------+--------------------------+ | pd.concat([l, r], | x y y z | | | Adds columns at the | | axis=1, | a 1 2 . . | x y y z | | right end. Uses 'outer' | | join=…) | b 3 4 4 5 | 3 4 4 5 | | by default. A Series is | | | c . . 6 7 | | | treated as a column. | +------------------------+---------------+------------+------------+--------------------------+ -| l.combine_first(r) | x y z | | | Adds missing rows and | -| | a 1 2 . | | | columns. Also updates | -| | b 3 4 5 | | | items that contain NaN. | -| | c . 6 7 | | | Argument r must be a DF. | -+------------------------+---------------+------------+------------+--------------------------+ ``` #### DataFrame — Aggregate, Transform, Map: ```python - = .sum/max/mean/idxmax/all() # Or: .apply/agg(lambda : ) - = .rank/diff/cumsum/ffill/interpo…() # Or: .apply/agg/transfo…(lambda : ) - = .fillna() # Or: .applymap(lambda : ) -``` -* **All operations operate on columns by default. Pass `'axis=1'` to process the rows instead.** - -```python ->>> df = pd.DataFrame([[1, 2], [3, 4]], index=['a', 'b'], columns=['x', 'y']); df - x y -a 1 2 -b 3 4 + = .sum/max/mean/idxmax/all() # Or: .apply/agg(lambda : ) + = .rank/diff/cumsum/ffill/interpo…() # Or: .apply/agg/transform(lambda : ) + = .isna/fillna/isin([]) # Or: .agg/transform/map(lambda : ) ``` ```text +-----------------+-------------+-------------+---------------+ | | 'sum' | ['sum'] | {'x': 'sum'} | +-----------------+-------------+-------------+---------------+ -| df.apply(…) | x 4 | x y | x 4 | -| df.agg(…) | y 6 | sum 4 6 | | +| l.apply(…) | x 4 | x y | x 4 | +| l.agg(…) | y 6 | sum 4 6 | | +-----------------+-------------+-------------+---------------+ ``` @@ -3343,16 +3333,25 @@ b 3 4 +-----------------+-------------+-------------+---------------+ | | 'rank' | ['rank'] | {'x': 'rank'} | +-----------------+-------------+-------------+---------------+ -| df.apply(…) | | x y | | -| df.agg(…) | x y | rank rank | x | -| df.transform(…) | a 1 1 | a 1 1 | a 1 | -| | b 2 2 | b 2 2 | b 2 | +| l.apply(…) | | x y | | +| l.agg(…) | x y | rank rank | x | +| l.transform(…) | a 1.0 1.0 | a 1.0 1.0 | a 1.0 | +| | b 2.0 2.0 | b 2.0 2.0 | b 2.0 | +-----------------+-------------+-------------+---------------+ ``` -* **Use `'[col_key_1, col_key_2][row_key]'` to get the fifth result's values.** +* **All methods operate on columns by default. Pass `'axis=1'` to process the rows instead.** +* **Fifth result's columns are indexed with a multi-index. This means we need a tuple of column keys to specify a single column: `'.loc[row_k, (col_k_1, col_k_2)]'`.** -#### DataFrame — Encode, Decode: +#### DataFrame — Multi-Index: +```python + = .xs(row_key, level=) # Rows with key on passed level of multi-index. + = .xs(row_keys, level=) # Rows that have first key on first level, etc. + = .set_index(col_keys) # Combines multiple columns into a multi-index. + = .stack/unstack(level=-1) # Combines col keys with row keys or vice versa. + = .pivot_table(index=col_key/s, …) # `columns=col_key/s, values=col_key/s`. +``` +#### DataFrame — Encode, Decode: ```python = pd.read_json/html('') # Run `$ pip3 install beautifulsoup4 lxml`. = pd.read_csv('') # `header/index_col/dtype/usecols/…=`. @@ -3367,53 +3366,49 @@ b 3 4 .to_sql('', ) # Also `if_exists='fail/replace/append'`. ``` * **Read\_csv() only parses dates of columns that were specified by 'parse\_dates' argument. It automatically tries to detect the format, but it can be helped with 'date\_format' or 'datefirst' arguments. Both dates and datetimes get stored as pd.Timestamp objects.** -* **If there's a single invalid date then it returns the whole column as a series of strings, unlike `' = pd.to_datetime(, errors="coerce")'`, which uses pd.NaT.** -* **To get specific attributes from a series of Timestamps use `'.dt.year/date/…'`.** +* **If there's a single invalid date then it returns the whole column as a series of strings, unlike `' = pd.to_datetime(, errors="coerce")'`, which uses pd.NaT.** +* **To get specific attributes from a series of Timestamps use `'.dt.year/date/…'`.** ### GroupBy **Object that groups together rows of a dataframe based on the value of the passed column.** -```python ->>> df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 6]], list('abc'), list('xyz')) ->>> gb = df.groupby('z'); gb.apply(print) - x y z -a 1 2 3 - x y z -b 4 5 6 -c 7 8 6 -``` - ```python = .groupby(col_key/s) # Splits DF into groups based on passed column. - = .apply() # Maps each group. Func can return DF, Sr or el. + = .apply() # Maps each group. Func can return DF, S or el. = .get_group() # Selects a group by grouping column's value. - = .size() # A Sr of group sizes. Same keys as get_group(). - = [col_key] # Single column GB. All operations return a Sr. + = .size() # S of group sizes. Same keys as get_group(). + = [col_key] # Single column GB. All operations return S. ``` -#### GroupBy — Aggregate, Transform, Map: ```python - = .sum/max/mean/idxmax/all() # Or: .agg(lambda : ) - = .rank/diff/cumsum/ffill() # Or: .transform(lambda : ) - = .fillna() # Or: .transform(lambda : ) + = .sum/max/mean/idxmax/all() # Or: .agg(lambda : ) + = .rank/diff/cumsum/ffill() # Or: .transform(lambda : ) + = .fillna() # Or: .transform(lambda : ) ``` +#### Divides rows into groups and sums their columns. Result has a named index that creates column `'z'` on reset_index(): ```python +>>> df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 6]], list('abc'), list('xyz')) +>>> gb = df.groupby('z'); gb.apply(print) + x y z +a 1 2 3 + x y z +b 4 5 6 +c 7 8 6 >>> gb.sum() x y z 3 1 2 6 11 13 ``` -* **Result has a named index that creates column `'z'` instead of `'index'` on reset_index().** ### Rolling **Object for rolling window calculations.** ```python - = .rolling(win_size) # Also: `min_periods=None, center=False`. - = [col_key/s] # Or: .col_key - = .mean/sum/max() # Or: .apply/agg() + = .rolling(win_size) # Also: `min_periods=None, center=False`. + = [col_key/s] # Or: .col_key + = .mean/sum/max() # Or: .apply/agg() ``` diff --git a/index.html b/index.html index a297efed2..a584141f1 100644 --- a/index.html +++ b/index.html @@ -55,7 +55,7 @@
- +
@@ -1452,9 +1452,9 @@
  • Paths can be either strings, Paths, or DirEntry objects.
  • Functions report OS related errors by raising either OSError or one of its subclasses.
  • -

    Shell Commands

    <pipe> = os.popen('<command>')      # Executes command in sh/cmd. Returns its stdout pipe.
    +

    Shell Commands

    <pipe> = os.popen('<commands>')     # Executes commands in sh/cmd. Returns combined stdout.
     <str>  = <pipe>.read(size=-1)       # Reads 'size' chars or until EOF. Also readline/s().
    -<int>  = <pipe>.close()             # Closes the pipe. Returns None on success (returncode 0).
    +<int>  = <pipe>.close()             # Returns None if last command exited with returncode 0.
     

    Sends '1 + 1' to the basic calculator and captures its output:

    >>> subprocess.run('bc', input='1 + 1\n', capture_output=True, text=True)
    @@ -2568,68 +2568,68 @@ 

    Format

    #Pandas

    # $ pip3 install pandas matplotlib
    +

    #Pandas

    Data analysis library. For examples see Plotly.

    # $ pip3 install pandas matplotlib
     import pandas as pd, matplotlib.pyplot as plt
     
    -

    Series

    Ordered dictionary with a name.

    >>> sr = pd.Series([1, 2], index=['x', 'y'], name='a'); sr
    +
    +

    Series

    Ordered dictionary with a name.

    >>> s = pd.Series([1, 2], index=['x', 'y'], name='a'); s
     x    1
     y    2
     Name: a, dtype: int64
     
    -
    <Sr> = pd.Series(<list>)                       # Assigns RangeIndex starting at 0.
    -<Sr> = pd.Series(<dict>)                       # Takes dictionary's keys for index.
    -<Sr> = pd.Series(<dict/Series>, index=<list>)  # Only keeps items with keys specified in index.
    +
    <S>  = pd.Series(<list>)                       # Assigns RangeIndex starting at 0.
    +<S>  = pd.Series(<dict>)                       # Takes dictionary's keys for index.
    +<S>  = pd.Series(<dict/Series>, index=<list>)  # Only keeps items with keys specified in index.
     
    -
    <el> = <Sr>.loc[key]                           # Or: <Sr>.iloc[i]
    -<Sr> = <Sr>.loc[coll_of_keys]                  # Or: <Sr>.iloc[coll_of_i]
    -<Sr> = <Sr>.loc[from_key : to_key_inc]         # Or: <Sr>.iloc[from_i : to_i_exc]
    +
    <el> = <S>.loc[key]                            # Or: <S>.iloc[i]
    +<S>  = <S>.loc[coll_of_keys]                   # Or: <S>.iloc[coll_of_i]
    +<S>  = <S>.loc[from_key : to_key_inc]          # Or: <S>.iloc[from_i : to_i_exc]
     
    -
    <el> = <Sr>[key/i]                             # Or: <Sr>.<key>
    -<Sr> = <Sr>[coll_of_keys/coll_of_i]            # Or: <Sr>[key/i : key/i]
    -<Sr> = <Sr>[bools]                             # Or: <Sr>.loc/iloc[bools]
    +
    <el> = <S>[key/i]                              # Or: <S>.<key>
    +<S>  = <S>[coll_of_keys/coll_of_i]             # Or: <S>[key/i : key/i]
    +<S>  = <S>[bools]                              # Or: <S>.loc/iloc[bools]
     
    -
    <Sr> = <Sr> > <el/Sr>                          # Returns a Series of bools.
    -<Sr> = <Sr> + <el/Sr>                          # Items with non-matching keys get value NaN.
    +
    <S>  = <S> > <el/S>                            # Returns a Series of bools.
    +<S>  = <S> + <el/S>                            # Items with non-matching keys get value NaN.
     
    -
    <Sr> = pd.concat(<coll_of_Sr>)                 # Concats multiple series into one long Series.
    -<Sr> = <Sr>.combine_first(<Sr>)                # Adds items that are not yet present.
    -<Sr>.update(<Sr>)                              # Updates items that are already present.
    +
    <S> = pd.concat(<coll_of_S>)                   # Concats multiple series into one long Series.
    +<S> = <S>.combine_first(<S>)                   # Adds items that are not yet present.
    +<S>.update(<S>)                                # Updates items that are already present.
     
    -
    <Sr>.plot.line/area/bar/pie/hist()             # Generates a Matplotlib plot.
    +
    <S>.plot.line/area/bar/pie/hist()              # Generates a Matplotlib plot.
     plt.show()                                     # Displays the plot. Also plt.savefig(<path>).
     
    -

    Series — Aggregate, Transform, Map:

    <el> = <Sr>.sum/max/mean/idxmax/all()          # Or: <Sr>.agg(lambda <Sr>: <el>)
    -<Sr> = <Sr>.rank/diff/cumsum/ffill/interpo…()  # Or: <Sr>.agg/transform(lambda <Sr>: <Sr>)
    -<Sr> = <Sr>.fillna(<el>)                       # Or: <Sr>.agg/transform/map(lambda <el>: <el>)
    +
      +
    • Indexing objects can't be tuples because 'obj[x, y]' is converted to 'obj[(x, y)]'!
    • +
    • Pandas uses NumPy types like 'np.int64'. Series is converted to 'float64' if we assign np.nan to any item. Use '<S>.astype(<str/type>)' to get converted Series.
    • +
    +

    Series — Aggregate, Transform, Map:

    <el> = <S>.sum/max/mean/idxmax/all()           # Or: <S>.agg(lambda <S>: <el>)
    +<S>  = <S>.rank/diff/cumsum/ffill/interpol…()  # Or: <S>.agg/transform(lambda <S>: <S>)
    +<S>  = <S>.isna/fillna/isin([<el/coll>])       # Or: <S>.agg/transform/map(lambda <el>: <el>)
     
    -
    >>> sr = pd.Series([2, 3], index=['x', 'y']); sr
    -x    2
    -y    3
    -
    ┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
     ┃               │    'sum'    │   ['sum']   │ {'s': 'sum'}  ┃
     ┠───────────────┼─────────────┼─────────────┼───────────────┨
    -┃ sr.apply(…)   │      5      │    sum  5   │     s  5      ┃
    -┃ sr.agg(…)     │             │             │               ┃
    +┃ s.apply(…)    │      3      │    sum  3   │     s  3      ┃
    +┃ s.agg(…)      │             │             │               ┃
     ┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛
     
     ┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
     ┃               │    'rank'   │   ['rank']  │ {'r': 'rank'} ┃
     ┠───────────────┼─────────────┼─────────────┼───────────────┨
    -┃ sr.apply(…)   │             │      rank   │               ┃
    -┃ sr.agg(…)     │     x  1    │   x     1   │    r  x  1    ┃
    -┃               │     y  2    │   y     2   │       y  2    ┃
    +┃ s.apply(…)    │             │      rank   │               ┃
    +┃ s.agg(…)      │    x  1.0   │   x   1.0   │   r  x  1.0   ┃
    +┃               │    y  2.0   │   y   2.0   │      y  2.0   ┃
     ┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛
     
      -
    • Indexing objects can't be tuples because 'obj[x, y]' is converted to 'obj[(x, y)]'!
    • Methods ffill(), interpolate(), fillna() and dropna() accept 'inplace=True'.
    • -
    • Last result has a hierarchical index. Use '<Sr>[key_1, key_2]' to get its values.
    • +
    • Last result has a multi-index. Use '<S>[key_1, key_2]' to get its values.

    DataFrame

    Table with labeled rows and columns.

    >>> l = pd.DataFrame([[1, 2], [3, 4]], index=['a', 'b'], columns=['x', 'y']); l
        x  y
    @@ -2638,25 +2638,29 @@ 

    Format

    <DF> = pd.DataFrame(<list_of_rows>) # Rows can be either lists, dicts or series. -<DF> = pd.DataFrame(<dict_of_columns>) # Columns can be either lists, dicts or series. +
    <DF>   = pd.DataFrame(<list_of_rows>)          # Rows can be either lists, dicts or series.
    +<DF>   = pd.DataFrame(<dict_of_columns>)       # Columns can be either lists, dicts or series.
     
    -
    <el>    = <DF>.loc[row_key, col_key]           # Or: <DF>.iloc[row_i, col_i]
    -<Sr/DF> = <DF>.loc[row_key/s]                  # Or: <DF>.iloc[row_i/s]
    -<Sr/DF> = <DF>.loc[:, col_key/s]               # Or: <DF>.iloc[:, col_i/s]
    -<DF>    = <DF>.loc[row_bools, col_bools]       # Or: <DF>.iloc[row_bools, col_bools]
    +
    <el>   = <DF>.loc[row_key, col_key]            # Or: <DF>.iloc[row_i, col_i]
    +<S/DF> = <DF>.loc[row_key/s]                   # Or: <DF>.iloc[row_i/s]
    +<S/DF> = <DF>.loc[:, col_key/s]                # Or: <DF>.iloc[:, col_i/s]
    +<DF>   = <DF>.loc[row_bools, col_bools]        # Or: <DF>.iloc[row_bools, col_bools]
     
    -
    <Sr/DF> = <DF>[col_key/s]                      # Or: <DF>.<col_key>
    -<DF>    = <DF>[row_bools]                      # Keeps rows as specified by bools.
    -<DF>    = <DF>[<DF_of_bools>]                  # Assigns NaN to items that are False in bools.
    +
    <S/DF> = <DF>[col_key/s]                       # Or: <DF>.<col_key>
    +<DF>   = <DF>[row_bools]                       # Keeps rows as specified by bools.
    +<DF>   = <DF>[<DF_of_bools>]                   # Assigns NaN to items that are False in bools.
     
    -
    <DF>    = <DF> > <el/Sr/DF>                    # Returns DF of bools. Sr is treated as a row.
    -<DF>    = <DF> + <el/Sr/DF>                    # Items with non-matching keys get value NaN.
    +
    <DF>   = <DF> > <el/S/DF>                      # Returns DF of bools. S is treated as a row.
    +<DF>   = <DF> + <el/S/DF>                      # Items with non-matching keys get value NaN.
     
    -
    <DF>    = <DF>.set_index(col_key)              # Replaces row keys with column's values.
    -<DF>    = <DF>.reset_index(drop=False)         # Drops or moves row keys to column named index.
    -<DF>    = <DF>.sort_index(ascending=True)      # Sorts rows by row keys. Use `axis=1` for cols.
    -<DF>    = <DF>.sort_values(col_key/s)          # Sorts rows by passed column/s. Also `axis=1`.
    +
    <DF>   = <DF>.set_index(col_key)               # Replaces row keys with column's values.
    +<DF>   = <DF>.reset_index(drop=False)          # Drops or moves row keys to column named index.
    +<DF>   = <DF>.sort_index(ascending=True)       # Sorts rows by row keys. Use `axis=1` for cols.
    +<DF>   = <DF>.sort_values(col_key/s)           # Sorts rows by passed column/s. Also `axis=1`.
    +
    +
    <DF>   = <DF>.head/tail/sample(<int>)          # Returns first, last, or random n elements.
    +<DF>   = <DF>.describe()                       # Describes columns. Also shape, info(), corr().
    +<DF>   = <DF>.query('<query>')                 # Filters rows with e.g. 'col_1 == val_1 and …'.
     
    <DF>.plot.line/area/bar/scatter(x=col_key, …)  # `y=col_key/s`. Also hist/box(by=col_key).
     plt.show()                                     # Displays the plot. Also plt.savefig(<path>).
    @@ -2684,52 +2688,47 @@ 

    Format

    0, │ a 1 2 . │ 2 │ │ Uses 'outer' by default. ┃ ┃ join=…) │ b 3 4 . │ 4 │ │ A Series is treated as a ┃ ┃ │ b . 4 54 │ │ column. To add a row use ┃ -┃ │ c . 6 76 │ │ pd.concat([l, DF([sr])]).┃ +┃ │ c . 6 76 │ │ pd.concat([l, DF([s])]). ┃ ┠────────────────────────┼───────────────┼────────────┼────────────┼──────────────────────────┨ ┃ pd.concat([l, r], │ x y y z │ │ │ Adds columns at the ┃ ┃ axis=1, │ a 1 2 . . │ x y y z │ │ right end. Uses 'outer' ┃ ┃ join=…) │ b 3 4 4 53 4 4 5 │ │ by default. A Series is ┃ ┃ │ c . . 6 7 │ │ │ treated as a column. ┃ -┠────────────────────────┼───────────────┼────────────┼────────────┼──────────────────────────┨ -┃ l.combine_first(r) │ x y z │ │ │ Adds missing rows and ┃ -┃ │ a 1 2 . │ │ │ columns. Also updates ┃ -┃ │ b 3 4 5 │ │ │ items that contain NaN. ┃ -┃ │ c . 6 7 │ │ │ Argument r must be a DF. ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━┛

    -

    DataFrame — Aggregate, Transform, Map:

    <Sr> = <DF>.sum/max/mean/idxmax/all()          # Or: <DF>.apply/agg(lambda <Sr>: <el>)
    -<DF> = <DF>.rank/diff/cumsum/ffill/interpo…()  # Or: <DF>.apply/agg/transfo…(lambda <Sr>: <Sr>)
    -<DF> = <DF>.fillna(<el>)                       # Or: <DF>.applymap(lambda <el>: <el>)
    +

    DataFrame — Aggregate, Transform, Map:

    <S>  = <DF>.sum/max/mean/idxmax/all()          # Or: <DF>.apply/agg(lambda <S>: <el>)
    +<DF> = <DF>.rank/diff/cumsum/ffill/interpo…()  # Or: <DF>.apply/agg/transform(lambda <S>: <S>)
    +<DF> = <DF>.isna/fillna/isin([<el/coll>])      # Or: <S>.agg/transform/map(lambda <el>: <el>)
     
    -
      -
    • All operations operate on columns by default. Pass 'axis=1' to process the rows instead.
    • -
    -
    >>> df = pd.DataFrame([[1, 2], [3, 4]], index=['a', 'b'], columns=['x', 'y']); df
    -   x  y
    -a  1  2
    -b  3  4
    -
    ┏━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
     ┃                 │    'sum'    │   ['sum']   │ {'x': 'sum'}  ┃
     ┠─────────────────┼─────────────┼─────────────┼───────────────┨
    -┃ df.apply(…)     │     x  4    │       x  y  │     x  4      ┃
    -┃ df.agg(…)       │     y  6    │  sum  4  6  │               ┃
    +┃ l.apply(…)      │     x  4    │       x  y  │     x  4      ┃
    +┃ l.agg(…)        │     y  6    │  sum  4  6  │               ┃
     ┗━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛
     
     ┏━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
     ┃                 │    'rank'   │   ['rank']  │ {'x': 'rank'} ┃
     ┠─────────────────┼─────────────┼─────────────┼───────────────┨
    -┃ df.apply(…)     │             │      x    y │               ┃
    -┃ df.agg(…)       │      x  y   │   rank rank │        x      ┃
    -┃ df.transform(…) │   a  1  1   │ a    1    1 │     a  1      ┃
    -┃                 │   b  2  2   │ b    2    2 │     b  2      ┃
    +┃ l.apply(…)      │             │      x    y │               ┃
    +┃ l.agg(…)        │      x    y │   rank rank │         x     ┃
    +┃ l.transform(…)  │ a  1.0  1.0 │ a  1.0  1.0 │    a  1.0     ┃
    +┃                 │ b  2.0  2.0 │ b  2.0  2.0 │    b  2.0     ┃
     ┗━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛
     
      -
    • Use '<DF>[col_key_1, col_key_2][row_key]' to get the fifth result's values.
    • +
    • All methods operate on columns by default. Pass 'axis=1' to process the rows instead.
    • +
    • Fifth result's columns are indexed with a multi-index. This means we need a tuple of column keys to specify a single column: '<DF>.loc[row_k, (col_k_1, col_k_2)]'.
    +

    DataFrame — Multi-Index:

    <DF>   = <DF>.xs(row_key, level=<int>)         # Rows with key on passed level of multi-index.
    +<DF>   = <DF>.xs(row_keys, level=<ints>)       # Rows that have first key on first level, etc.
    +<DF>   = <DF>.set_index(col_keys)              # Combines multiple columns into a multi-index.
    +<S/DF> = <DF>.stack/unstack(level=-1)          # Combines col keys with row keys or vice versa.
    +<DF>   = <DF>.pivot_table(index=col_key/s, …)  # `columns=col_key/s, values=col_key/s`.
    +
    +

    DataFrame — Encode, Decode:

    <DF> = pd.read_json/html('<str/path/url>')     # Run `$ pip3 install beautifulsoup4 lxml`.
     <DF> = pd.read_csv('<path/url>')               # `header/index_col/dtype/usecols/…=<obj>`.
     <DF> = pd.read_pickle/excel('<path/url>')      # Use `sheet_name=None` to get all Excel sheets.
    @@ -2743,41 +2742,37 @@ 

    Format

    '<Sr> = pd.to_datetime(<Sr>, errors="coerce")', which uses pd.NaT. -
  • To get specific attributes from a series of Timestamps use '<Sr>.dt.year/date/…'.
  • +
  • If there's a single invalid date then it returns the whole column as a series of strings, unlike '<S> = pd.to_datetime(<S>, errors="coerce")', which uses pd.NaT.
  • +
  • To get specific attributes from a series of Timestamps use '<S>.dt.year/date/…'.
  • -

    GroupBy

    Object that groups together rows of a dataframe based on the value of the passed column.

    >>> df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 6]], list('abc'), list('xyz'))
    +

    GroupBy

    Object that groups together rows of a dataframe based on the value of the passed column.

    <GB> = <DF>.groupby(col_key/s)                 # Splits DF into groups based on passed column.
    +<DF> = <GB>.apply(<func>)                      # Maps each group. Func can return DF, S or el.
    +<DF> = <GB>.get_group(<el>)                    # Selects a group by grouping column's value.
    +<S>  = <GB>.size()                             # S of group sizes. Same keys as get_group().
    +<GB> = <GB>[col_key]                           # Single column GB. All operations return S.
    +
    + + +
    <DF> = <GB>.sum/max/mean/idxmax/all()          # Or: <GB>.agg(lambda <S>: <el>)
    +<DF> = <GB>.rank/diff/cumsum/ffill()           # Or: <GB>.transform(lambda <S>: <S>)
    +<DF> = <GB>.fillna(<el>)                       # Or: <GB>.transform(lambda <S>: <S>)
    +
    +

    Divides rows into groups and sums their columns. Result has a named index that creates column 'z' on reset_index():

    >>> df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 6]], list('abc'), list('xyz'))
     >>> gb = df.groupby('z'); gb.apply(print)
        x  y  z
     a  1  2  3
        x  y  z
     b  4  5  6
    -c  7  8  6
    - - -
    <GB> = <DF>.groupby(col_key/s)                 # Splits DF into groups based on passed column.
    -<DF> = <GB>.apply(<func>)                      # Maps each group. Func can return DF, Sr or el.
    -<DF> = <GB>.get_group(<el>)                    # Selects a group by grouping column's value.
    -<Sr> = <GB>.size()                             # A Sr of group sizes. Same keys as get_group().
    -<GB> = <GB>[col_key]                           # Single column GB. All operations return a Sr.
    -
    -

    GroupBy — Aggregate, Transform, Map:

    <DF> = <GB>.sum/max/mean/idxmax/all()          # Or: <GB>.agg(lambda <Sr>: <el>)
    -<DF> = <GB>.rank/diff/cumsum/ffill()           # Or: <GB>.transform(lambda <Sr>: <Sr>)
    -<DF> = <GB>.fillna(<el>)                       # Or: <GB>.transform(lambda <Sr>: <Sr>)
    -
    - -
    >>> gb.sum()
    +c  7  8  6
    +>>> gb.sum()
         x   y
     z
     3   1   2
    -6  11  13
    -
    -
      -
    • Result has a named index that creates column 'z' instead of 'index' on reset_index().
    • -
    -

    Rolling

    Object for rolling window calculations.

    <RSr/RDF/RGB> = <Sr/DF/GB>.rolling(win_size)   # Also: `min_periods=None, center=False`.
    -<RSr/RDF/RGB> = <RDF/RGB>[col_key/s]           # Or: <RDF/RGB>.col_key
    -<Sr/DF>       = <R>.mean/sum/max()             # Or: <R>.apply/agg(<agg_func/str>)
    +6  11  13
    + +

    Rolling

    Object for rolling window calculations.

    <RS/RDF/RGB> = <S/DF/GB>.rolling(win_size)     # Also: `min_periods=None, center=False`.
    +<RS/RDF/RGB> = <RDF/RGB>[col_key/s]            # Or: <RDF/RGB>.col_key
    +<S/DF>       = <R>.mean/sum/max()              # Or: <R>.apply/agg(<agg_func/str>)
     
    @@ -2928,7 +2923,7 @@

    Format

    -
    ┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
    -┃               │    'sum'    │   ['sum']   │ {'s': 'sum'}  ┃
    -┠───────────────┼─────────────┼─────────────┼───────────────┨
    -┃ s.apply(…)    │      3      │    sum  3   │     s  3      ┃
    -┃ s.agg(…)      │             │             │               ┃
    -┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛
    -
    -┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
    -┃               │    'rank'   │   ['rank']  │ {'r': 'rank'} ┃
    -┠───────────────┼─────────────┼─────────────┼───────────────┨
    -┃ s.apply(…)    │             │      rank   │               ┃
    -┃ s.agg(…)      │    x  1.0   │   x   1.0   │   r  x  1.0   ┃
    -┃               │    y  2.0   │   y   2.0   │      y  2.0   ┃
    -┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛
    +
    ┏━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
    +┃              │    'sum'    │   ['sum']   │ {'s': 'sum'}  ┃
    +┠──────────────┼─────────────┼─────────────┼───────────────┨
    +┃ s.apply(…)   │      3      │    sum  3   │     s  3      ┃
    +┃ s.agg(…)     │             │             │               ┃
    +┗━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛
    +
    +┏━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓
    +┃              │    'rank'   │   ['rank']  │ {'r': 'rank'} ┃
    +┠──────────────┼─────────────┼─────────────┼───────────────┨
    +┃ s.apply(…)   │             │      rank   │               ┃
    +┃ s.agg(…)     │    x  1.0   │   x   1.0   │   r  x  1.0   ┃
    +┃              │    y  2.0   │   y   2.0   │      y  2.0   ┃
    +┗━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛
     
      diff --git a/parse.js b/parse.js index 91281068d..50c4790cb 100755 --- a/parse.js +++ b/parse.js @@ -582,26 +582,26 @@ const DIAGRAM_12_B = '┗━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━━┛\n'; const DIAGRAM_13_A = - '| s.apply(…) | 3 | sum 3 | s 3 |'; + '| s.apply(…) | 3 | sum 3 | s 3 |'; const DIAGRAM_13_B = - "┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓\n" + - "┃ │ 'sum' │ ['sum'] │ {'s': 'sum'} ┃\n" + - "┠───────────────┼─────────────┼─────────────┼───────────────┨\n" + - "┃ s.apply(…) │ 3 │ sum 3 │ s 3 ┃\n" + - "┃ s.agg(…) │ │ │ ┃\n" + - "┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛\n" + + "┏━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓\n" + + "┃ │ 'sum' │ ['sum'] │ {'s': 'sum'} ┃\n" + + "┠──────────────┼─────────────┼─────────────┼───────────────┨\n" + + "┃ s.apply(…) │ 3 │ sum 3 │ s 3 ┃\n" + + "┃ s.agg(…) │ │ │ ┃\n" + + "┗━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛\n" + "\n" + - "┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓\n" + - "┃ │ 'rank' │ ['rank'] │ {'r': 'rank'} ┃\n" + - "┠───────────────┼─────────────┼─────────────┼───────────────┨\n" + - "┃ s.apply(…) │ │ rank │ ┃\n" + - "┃ s.agg(…) │ x 1.0 │ x 1.0 │ r x 1.0 ┃\n" + - "┃ │ y 2.0 │ y 2.0 │ y 2.0 ┃\n" + - "┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛\n"; + "┏━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓\n" + + "┃ │ 'rank' │ ['rank'] │ {'r': 'rank'} ┃\n" + + "┠──────────────┼─────────────┼─────────────┼───────────────┨\n" + + "┃ s.apply(…) │ │ rank │ ┃\n" + + "┃ s.agg(…) │ x 1.0 │ x 1.0 │ r x 1.0 ┃\n" + + "┃ │ y 2.0 │ y 2.0 │ y 2.0 ┃\n" + + "┗━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛\n"; const DIAGRAM_14_A = - "| | 'rank' | ['rank'] | {'r': 'rank'} |"; + "| | 'rank' | ['rank'] | {'r': 'rank'} |"; const DIAGRAM_15_A = '+------------------------+---------------+------------+------------+--------------------------+'; From 86e97e638cc9beb5df42ce3ed2585961c5b37586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Wed, 13 Nov 2024 14:54:58 +0100 Subject: [PATCH 06/34] Numbers, Decorator, Class, Duck types --- README.md | 12 ++++++------ index.html | 17 +++++++++-------- parse.js | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index eaf4779ab..d61ef649d 100644 --- a/README.md +++ b/README.md @@ -493,7 +493,7 @@ Format Numbers ------- ```python - = int() # Or: math.floor() + = int() # Or: math.trunc() = float() # Or: = complex(real=0, imag=0) # Or: ± j = fractions.Fraction(0, 1) # Or: Fraction(numerator=0, denominator=1) @@ -931,7 +931,7 @@ from functools import cache def fib(n): return n if n < 2 else fib(n-2) + fib(n-1) ``` -* **Potential problem with cache is that it can grow indefinitely. To clear its stored values run `'fib.cache_clear()'`, or use `'@lru_cache(maxsize=)'` decorator instead.** +* **Potential problem with cache is that it can grow indefinitely. To clear stored return values run `'fib.cache_clear()'`, or use `'@lru_cache(maxsize=)'` decorator instead.** * **CPython interpreter limits recursion depth to 3000 by default. To increase it run `'sys.setrecursionlimit()'`.** ### Parametrized Decorator @@ -1055,9 +1055,9 @@ class : * **For attributes of arbitrary type use `'typing.Any'`.** ```python - = make_dataclass('', ) - = make_dataclass('', ) - = ('', [, ]) +Point = make_dataclass('Point', ['x', 'y']) +Point = make_dataclass('Point', [('x', float), ('y', float)]) +Point = make_dataclass('Point', [('x', float, 0), ('y', float, 0)]) ``` ### Property @@ -1293,7 +1293,7 @@ class MySequence: ``` #### Discrepancies between glossary definitions and abstract base classes: -* **Glossary on Python's website defines iterable as any object with iter() or getitem() and sequence as any object with getitem() and len(). It does not define collection.** +* **Python's glossary defines iterable as any object with iter() or getitem() and sequence as any object with getitem() and len(). It does not define collection.** * **Passing ABC Iterable to isinstance() or issubclass() checks whether object/class has method iter(), while ABC Collection checks for iter(), contains() and len().** ### ABC Sequence diff --git a/index.html b/index.html index 53210903f..21d034499 100644 --- a/index.html +++ b/index.html @@ -55,7 +55,7 @@
      - +
      @@ -444,7 +444,7 @@ {90:X} # '5A'. Number 90 in uppercase hexadecimal.
    -

    #Numbers

    <int>      = int(<float/str/bool>)                # Or: math.floor(<float>)
    +

    #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)
    @@ -778,7 +778,7 @@
     
     
     
      -
    • Potential problem with cache is that it can grow indefinitely. To clear its stored values run 'fib.cache_clear()', or use '@lru_cache(maxsize=<int>)' decorator instead.
    • +
    • Potential problem with cache is that it can grow indefinitely. To clear stored return values run 'fib.cache_clear()', or use '@lru_cache(maxsize=<int>)' decorator instead.
    • CPython interpreter limits recursion depth to 3000 by default. To increase it run 'sys.setrecursionlimit(<int>)'.

    Parametrized Decorator

    A decorator that accepts arguments and returns a normal decorator that accepts a function.

    from functools import wraps
    @@ -886,9 +886,10 @@
     
  • Function field() is needed because '<attr_name>: list = []' would make a list that is shared among all instances. Its 'default_factory' argument can be any callable.
  • For attributes of arbitrary type use 'typing.Any'.
  • -
    <class> = make_dataclass('<class_name>', <coll_of_attribute_names>)
    -<class> = make_dataclass('<class_name>', <coll_of_tuples>)
    -<tuple> = ('<attr_name>', <type> [, <default_value>])
    +
    Point = make_dataclass('Point', ['x', 'y'])
    +Point = make_dataclass('Point', [('x', float), ('y', float)])
    +Point = make_dataclass('Point', [('x', float, 0), ('y', float, 0)])
    +

    Property

    Pythonic way of implementing getters and setters.

    class Person:
         @property
         def name(self):
    @@ -1098,7 +1099,7 @@
     
     
     

    Discrepancies between glossary definitions and abstract base classes:

      -
    • Glossary on Python's website defines iterable as any object with iter() or getitem() and sequence as any object with getitem() and len(). It does not define collection.
    • +
    • Python's glossary defines iterable as any object with iter() or getitem() and sequence as any object with getitem() and len(). It does not define collection.
    • Passing ABC Iterable to isinstance() or issubclass() checks whether object/class has method iter(), while ABC Collection checks for iter(), contains() and len().
    @@ -2923,7 +2924,7 @@

    Format

    -
    sum_of_elements  = sum(<collection>)
    -elementwise_sum  = [sum(pair) for pair in zip(list_a, list_b)]
    +
    <el>  = max(<collection>)       # Returns largest element. Also max(<el_1>, ...).
    +<num> = sum(<collection>)       # Returns sum of elements. Also math.prod(<coll>).
    +
    +
    elementwise_sum  = [sum(pair) for pair in zip(list_a, list_b)]
     sorted_by_second = sorted(<collection>, key=lambda el: el[1])
     sorted_by_both   = sorted(<collection>, key=lambda el: (el[1], el[0]))
     flatter_list     = list(itertools.chain.from_iterable(<list>))
    -product_of_elems = functools.reduce(lambda out, el: out * el, <collection>)
    -list_of_chars    = list(<str>)
     
      -
    • For details about sorted(), min() and max() see sortable.
    • +
    • For details about sort(), sorted(), max() and min() see sortable.
    • Module operator provides functions itemgetter() and mul() that offer the same functionality as lambda expressions above.
    <int> = len(<list>)             # Returns number of items. Also works on other collections.
    @@ -527,7 +527,7 @@
     <TD> = timedelta(weeks=0, days=0, hours=0)  # Also: `minutes=0, seconds=0, microseconds=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!
    • +
    • Aware times and datetimes have defined timezone, while naive 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). Its str() method returns '[±D, ]H:MM:SS[.…]' and total_seconds() a float of all seconds.
    • Use '<D/DT>.weekday()' to get the day of the week as an int, with Monday being 0.
    • @@ -1789,9 +1789,8 @@

      Format

      # [index/key], .name, .name([…])

    elementwise_sum  = map(op.add, list_a, list_b)
    -sorted_by_second = sorted(<coll.>, key=op.itemgetter(1))
    -sorted_by_both   = sorted(<coll.>, key=op.itemgetter(1, 0))
    -product_of_elems = functools.reduce(op.mul, <collection>)
    +sorted_by_second = sorted(<coll>, key=op.itemgetter(1))
    +sorted_by_both   = sorted(<coll>, key=op.itemgetter(1, 0))
     first_element    = op.methodcaller('pop', 0)(<list>)
     
      @@ -2924,7 +2923,7 @@

      Format

      -
    • For details about sort(), sorted(), max() and min() see sortable.
    • +
    • For details about sort(), sorted(), min() and max() see sortable.
    • Module operator provides functions itemgetter() and mul() that offer the same functionality as lambda expressions above.
    <int> = len(<list>)             # Returns number of items. Also works on other collections.
    diff --git a/pdf/remove_links.py b/pdf/remove_links.py
    index 747ffb34d..984c53a7e 100755
    --- a/pdf/remove_links.py
    +++ b/pdf/remove_links.py
    @@ -7,7 +7,7 @@
     
     
     MATCHES = {
    -    'For details about sort(), sorted(), max() and min() see sortable.': 'For details about sort(), sorted(), max() and min() see sortable (p. 16).',
    +    'For details about sort(), sorted(), min() and max() see sortable.': 'For details about sort(), sorted(), min() and max() see sortable (p. 16).',
         'Module operator provides functions itemgetter() and mul() that offer the same functionality as lambda expressions above.': 'Module \'operator\' (p. 31) provides functions itemgetter() and mul() that offer the same functionality as lambda expressions (p. 11) above.',
         'Adding \'!r\' to the expression converts object to string by calling its repr() method.': 'Adding \'!r\' to the expression converts object to string by calling its repr() method.',
         'It can be any callable, but is usually implemented as a function that returns a closure.': 'It can be any callable, but is usually implemented as a function that returns a closure.',
    
    From 8292bc981e723bc1322312031c51aee0f9df2c64 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jure=20=C5=A0orn?= 
    Date: Sun, 17 Nov 2024 04:22:48 +0100
    Subject: [PATCH 10/34] List
    
    ---
     README.md           |  7 ++++---
     index.html          | 11 ++++++-----
     pdf/remove_links.py |  3 ++-
     3 files changed, 12 insertions(+), 9 deletions(-)
    
    diff --git a/README.md b/README.md
    index e252bd4ac..561a24163 100644
    --- a/README.md
    +++ b/README.md
    @@ -50,7 +50,7 @@ List
     ```
     
     ```python
    -  = max()       # Returns largest element. Also max(, ...).
    +  = max()       # Returns largest element. Also min(, ...).
      = sum()       # Returns sum of elements. Also math.prod().
     ```
     
    @@ -61,10 +61,11 @@ sorted_by_both   = sorted(, key=lambda el: (el[1], el[0]))
     flatter_list     = list(itertools.chain.from_iterable())
     ```
     * **For details about sort(), sorted(), min() and max() see [sortable](#sortable).**
    -* **Module [operator](#operator) provides functions itemgetter() and mul() that offer the same functionality as [lambda](#lambda) expressions above.**
    +* **Module [operator](#operator) has function itemgetter() that can replace listed [lambdas](#lambda).**
    +* **This text uses the term 'collection' instead of 'iterable'. For rationale see [collection](#collection).**
     
     ```python
    - = len()             # Returns number of items. Also works on other collections.
    + = len()             # Returns number of items. Also works on dict, set and string.
      = .count()      # Returns number of occurrences. Also `if  in : ...`.
      = .index()      # Returns index of the first occurrence or raises ValueError.
       = .pop()            # Removes and returns item from the end or at index if passed.
    diff --git a/index.html b/index.html
    index 916bc4dea..d086a8113 100644
    --- a/index.html
    +++ b/index.html
    @@ -55,7 +55,7 @@
     
     
       
    - +
    @@ -114,7 +114,7 @@ <list> = sorted(<collection>) # Returns new list with sorted elements. <iter> = reversed(<list>) # Returns reversed iterator of elements.
    -
    <el>  = max(<collection>)       # Returns largest element. Also max(<el_1>, ...).
    +
    <el>  = max(<collection>)       # Returns largest element. Also min(<el_1>, ...).
     <num> = sum(<collection>)       # Returns sum of elements. Also math.prod(<coll>).
     
    elementwise_sum  = [sum(pair) for pair in zip(list_a, list_b)]
    @@ -124,9 +124,10 @@
     
    • For details about sort(), sorted(), min() and max() see sortable.
    • -
    • Module operator provides functions itemgetter() and mul() that offer the same functionality as lambda expressions above.
    • +
    • Module operator has function itemgetter() that can replace listed lambdas.
    • +
    • This text uses the term 'collection' instead of 'iterable'. For rationale see collection.
    -
    <int> = len(<list>)             # Returns number of items. Also works on other collections.
    +
    <int> = len(<list>)             # Returns number of items. Also works on dict, set and string.
     <int> = <list>.count(<el>)      # Returns number of occurrences. Also `if <el> in <coll>: ...`.
     <int> = <list>.index(<el>)      # Returns index of the first occurrence or raises ValueError.
     <el>  = <list>.pop()            # Removes and returns item from the end or at index if passed.
    @@ -2923,7 +2924,7 @@ 

    Format

      -
    • By default, decimal characters, alphanumerics and whitespaces from all alphabets are matched unless 'flags=re.ASCII' argument is used.
    • -
    • It restricts special sequence matches to '[\x00-\x7f]' (the first 128 characters) and also prevents '\s' from accepting '[\x1c-\x1f]' (file, table, row, and field separators).
    • +
    • By default, decimal characters and alphanumerics from all alphabets are matched unless 'flags=re.ASCII' is used. It restricts special sequence matches to the first 128 Unicode characters and also prevents '\s' from accepting '\x1c', '\x1d', '\x1e' and '\x1f' (the so-called information separators that divide text into files, tables, rows and fields).
    • Use a capital letter for negation (all non-ASCII characters will be matched when used in combination with ASCII flag).

    #Format

    <str> = f'{<el_1>}, {<el_2>}'            # Curly brackets can also contain expressions.
    @@ -2924,7 +2923,7 @@ 

    Format

    @@ -1340,7 +1340,7 @@
  • 'w+' - Read and write. Deletes existing contents.
  • 'r+' - Read and write from the start.
  • 'a+' - Read and write from the end.
  • -
  • 'b' - Binary mode ('rb', 'wb', 'xb', …)
  • +
  • 'b' - Binary mode ('rb', 'wb', 'xb', …).
  • Exceptions

    • 'FileNotFoundError' can be raised when reading with 'r' or 'r+'.
    • 'FileExistsError' can be raised when writing with 'x'.
    • @@ -1399,7 +1399,7 @@ <bool> = os.path.isdir(<path>) # Or: <DirEntry/Path>.is_dir()
    <stat> = os.stat(<path>)            # Or: <DirEntry/Path>.stat()
    -<num>  = <stat>.st_mtime/st_size/…  # Modification time, size in bytes, ...
    +<num>  = <stat>.st_mtime/st_size/…  # Modification time, size in bytes, etc.
     

    DirEntry

    Unlike listdir(), scandir() returns DirEntry objects that cache isfile, isdir, and on Windows also stat information, thus significantly increasing the performance of code that requires it.

    <iter> = os.scandir(path='.')       # Returns DirEntry objects located at the path.
     <str>  = <DirEntry>.path            # Returns the whole path as a string.
    @@ -2568,7 +2568,7 @@ 

    Format

    #Pandas

    Data analysis library. For examples see Plotly.

    # $ pip3 install pandas matplotlib
    +

    #Pandas

    Data analysis library. For examples see Plotly.

    # $ pip3 install pandas matplotlib
     import pandas as pd, matplotlib.pyplot as plt
     
    @@ -2923,7 +2923,7 @@

    Format

    \n'; @@ -716,6 +716,7 @@ function getMd() { var readme = readme.replace("#semaphore-event-barrier", "#semaphoreeventbarrier"); var readme = readme.replace("#semaphore-event-barrier", "#semaphoreeventbarrier"); var readme = readme.replace("#dataframe-plot-encode-decode", "#dataframeplotencodedecode"); + var readme = readme.replace("#displays-a-line-chart-of-total-coronavirus-deaths-per-million-grouped-by-continent", "#displaysalinechartoftotalcoronavirusdeathspermilliongroupedbycontinent"); const converter = new showdown.Converter(); return converter.makeHtml(readme); } diff --git a/web/script_2.js b/web/script_2.js index 7484625a2..be1c1c7bf 100644 --- a/web/script_2.js +++ b/web/script_2.js @@ -6,7 +6,7 @@ const TOC = ' \'4. System\': [Exit, Print, Input, Command_Line_Arguments, Open, Path, OS_Commands],\n' + ' \'5. Data\': [JSON, Pickle, CSV, SQLite, Bytes, Struct, Array, Memory_View, Deque],\n' + ' \'6. Advanced\': [Threading, Operator, Match_Stmt, Logging, Introspection, Coroutines],\n' + - ' \'7. Libraries\': [Progress_Bar, Plot, Table, Console_App, GUI, Scraping, Web, Profile],\n' + + ' \'7. Libraries\': [Progress_Bar, Plot, Table, Console_App, GUI, Scraping, Web, Profile],\n' + ' \'8. Multimedia\': [NumPy, Image, Animation, Audio, Synthesizer, Pygame, Pandas, Plotly]\n' + '}\n'; @@ -32,7 +32,7 @@ const TOC_MOBILE = ' Introspection, Coroutines],\n' + ' \'7. Libraries\': [Progress_Bar, Plot, Table,\n' + ' Console_App, GUI_App,\n' + - ' Scraping, Web, Profiling],\n' + + ' Scraping, Web, Profiling],\n' + ' \'8. Multimedia\': [NumPy, Image, Animation,\n' + ' Audio, Synthesizer,\n' + ' Pygame, Pandas, Plotly]\n' + From 4214842fe7aa9d1fcaaf70f20320c556a9cbe4cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Sat, 23 Nov 2024 18:37:26 +0100 Subject: [PATCH 13/34] Class, Json, SQLite, Image, Pandas --- README.md | 64 ++++++++++++++++++++++++------------------------- index.html | 70 +++++++++++++++++++++++++++--------------------------- 2 files changed, 67 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 14617837f..003051944 100644 --- a/README.md +++ b/README.md @@ -975,15 +975,15 @@ class MyClass: def get_class_name(cls): return cls.__name__ ``` -* **Return value of str() should be readable and of repr() unambiguous.** -* **If only repr() is defined, it will also be used for str().** -* **Methods decorated with `'@staticmethod'` do not receive 'self' nor 'cls' as their first arg.** ```python >>> obj = MyClass(1) >>> obj.a, str(obj), repr(obj) (1, '1', 'MyClass(1)') ``` +* **Return value of str() should be readable and of repr() unambiguous.** +* **If only repr() is defined, it will also be used for str().** +* **Methods decorated with `'@staticmethod'` do not receive 'self' nor 'cls' as their first argument.** #### Expressions that call the str() method: ```python @@ -1769,22 +1769,22 @@ JSON ```python import json - = json.dumps() # Converts object to JSON string. - = json.loads() # Converts JSON string to object. + = json.dumps() # Converts collection to JSON string. + = json.loads() # Converts JSON string to collection. ``` -### Read Object from JSON File +### Read Collection from JSON File ```python def read_json_file(filename): with open(filename, encoding='utf-8') as file: return json.load(file) ``` -### Write Object to JSON File +### Write Collection to JSON File ```python -def write_to_json_file(filename, an_object): +def write_to_json_file(filename, list_or_dict): with open(filename, 'w', encoding='utf-8') as file: - json.dump(an_object, file, ensure_ascii=False, indent=2) + json.dump(list_or_dict, file, ensure_ascii=False, indent=2) ``` @@ -1884,41 +1884,41 @@ def write_to_csv_file(filename, rows, mode='w', **csv_params): SQLite ------ -**A server-less database engine that stores each database into a separate file.** +**A server-less database engine that stores each database into its own file.** ```python import sqlite3 - = sqlite3.connect() # Opens existing or new file. Also ':memory:'. -.close() # Closes connection. Discards uncommitted data. + = sqlite3.connect() # Opens existing or new file. Also ':memory:'. +.close() # Closes connection. Discards uncommitted data. ``` ### Read ```python - = .execute('') # Can raise a subclass of sqlite3.Error. - = .fetchone() # Returns next row. Also next(). - = .fetchall() # Returns remaining rows. Also list(). + = .execute('') # Can raise a subclass of sqlite3.Error. + = .fetchone() # Returns next row. Also next(). + = .fetchall() # Returns remaining rows. Also list(). ``` ### Write ```python -.execute('') # Can raise a subclass of sqlite3.Error. -.commit() # Saves all changes since the last commit. -.rollback() # Discards all changes since the last commit. +.execute('') # Can raise a subclass of sqlite3.Error. +.commit() # Saves all changes since the last commit. +.rollback() # Discards all changes since the last commit. ``` #### Or: ```python -with : # Exits the block with commit() or rollback(), - .execute('') # depending on whether any exception occurred. +with : # Exits the block with commit() or rollback(), + .execute('') # depending on whether any exception occurred. ``` ### Placeholders ```python -.execute('', ) # Replaces '?'s in query with values. -.execute('', ) # Replaces ':'s with values. -.executemany('', ) # Runs execute() multiple times. +.execute('', ) # Replaces '?'s in query with values. +.execute('', ) # Replaces ':'s with values. +.executemany('', ) # Runs execute() multiple times. ``` -* **Passed values can be of type str, int, float, bytes, None or bool (stored as 1 or 0).** +* **Passed values can be of type str, int, float, bytes, None, or bool (stored as 1 or 0).** ### Example **Values are not actually saved in this example because `'conn.commit()'` is omitted!** @@ -1936,10 +1936,10 @@ with : # Exits the block with commit() ```python # $ pip3 install sqlalchemy from sqlalchemy import create_engine, text - = create_engine('') # Url: 'dialect://user:password@host/dbname'. - = .connect() # Creates a connection. Also .close(). - = .execute(text(''), …) # Replaces ':'s with keyword arguments. -with .begin(): ... # Exits the block with commit or rollback. + = create_engine('') # Url: 'dialect://user:password@host/dbname'. + = .connect() # Creates a connection. Also .close(). + = .execute(text(''), …) # Replaces ':'s with keyword arguments. +with .begin(): ... # Exits the block with commit or rollback. ``` ```text @@ -2832,9 +2832,9 @@ from PIL import ImageDraw .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) # Draws in clockwise dir. Also pieslice(). -.rectangle((x1, y1, x2, y2)) # To rotate use Image's rotate() and paste(). +.rectangle((x1, y1, x2, y2)) # Also rounded_rectangle(), regular_polygon(). .polygon((x1, y1, x2, y2, ...)) # Last point gets connected to the first. -.ellipse((x1, y1, x2, y2)) # Also rounded_rectangle(), regular_polygon(). +.ellipse((x1, y1, x2, y2)) # To rotate use Image's rotate() and paste(). .text((x, y), , font=) # ` = ImageFont.truetype(, size)` ``` * **Use `'fill='` to set the primary color.** @@ -3340,7 +3340,7 @@ c 6 7 +----------------+---------------+---------------+---------------+ ``` * **All methods operate on columns by default. Pass `'axis=1'` to process the rows instead.** -* **Fifth result's columns are indexed with a multi-index. This means we need a tuple of column keys to specify a single column: `'.loc[row_k, (col_k_1, col_k_2)]'`.** +* **Fifth result's columns are indexed with a multi-index. This means we need a tuple of column keys to specify a column: `'.loc[row_key, (col_key_1, col_key_2)]'`.** #### DataFrame — Multi-Index: ```python @@ -3348,7 +3348,7 @@ c 6 7 = .xs(row_keys, level=) # Rows that have first key on first level, etc. = .set_index(col_keys) # Combines multiple columns into a multi-index. = .stack/unstack(level=-1) # Combines col keys with row keys or vice versa. - = .pivot_table(index=col_key/s, …) # `columns=col_key/s, values=col_key/s`. + = .pivot_table(index=col_key/s, …) # `columns=key/s, values=key/s, aggfunc='mean'`. ``` #### DataFrame — Encode, Decode: diff --git a/index.html b/index.html index bf6a0745f..dd5177179 100644 --- a/index.html +++ b/index.html @@ -55,7 +55,7 @@
    - +
    @@ -817,15 +817,15 @@ -
      -
    • Return value of str() should be readable and of repr() unambiguous.
    • -
    • If only repr() is defined, it will also be used for str().
    • -
    • Methods decorated with '@staticmethod' do not receive 'self' nor 'cls' as their first arg.
    • -
    >>> obj = MyClass(1)
     >>> obj.a, str(obj), repr(obj)
     (1, '1', 'MyClass(1)')
     
    +
      +
    • Return value of str() should be readable and of repr() unambiguous.
    • +
    • If only repr() is defined, it will also be used for str().
    • +
    • Methods decorated with '@staticmethod' do not receive 'self' nor 'cls' as their first argument.
    • +

    Expressions that call the str() method:

    print(<obj>)
     f'{<obj>}'
     logging.warning(<obj>)
    @@ -1471,19 +1471,19 @@
     

    #JSON

    Text file format for storing collections of strings and numbers.

    import json
    -<str>    = json.dumps(<object>)     # Converts object to JSON string.
    -<object> = json.loads(<str>)        # Converts JSON string to object.
    +<str>  = json.dumps(<list/dict>)    # Converts collection to JSON string.
    +<coll> = json.loads(<str>)          # Converts JSON string to collection.
     
    -

    Read Object from JSON File

    def read_json_file(filename):
    +

    Read Collection from JSON File

    def read_json_file(filename):
         with open(filename, encoding='utf-8') as file:
             return json.load(file)
     
    -

    Write Object to JSON File

    def write_to_json_file(filename, an_object):
    +

    Write Collection to JSON File

    def write_to_json_file(filename, list_or_dict):
         with open(filename, 'w', encoding='utf-8') as file:
    -        json.dump(an_object, file, ensure_ascii=False, indent=2)
    +        json.dump(list_or_dict, file, ensure_ascii=False, indent=2)
     

    #Pickle

    Binary file format for storing Python objects.

    import pickle
    @@ -1561,33 +1561,33 @@
             writer.writerows(rows)
     
    -

    #SQLite

    A server-less database engine that stores each database into a separate file.

    import sqlite3
    -<conn> = sqlite3.connect(<path>)                # Opens existing or new file. Also ':memory:'.
    -<conn>.close()                                  # Closes connection. Discards uncommitted data.
    +

    #SQLite

    A server-less database engine that stores each database into its own file.

    import sqlite3
    +<conn> = sqlite3.connect(<path>)               # Opens existing or new file. Also ':memory:'.
    +<conn>.close()                                 # Closes connection. Discards uncommitted data.
     
    -

    Read

    <cursor> = <conn>.execute('<query>')            # Can raise a subclass of sqlite3.Error.
    -<tuple>  = <cursor>.fetchone()                  # Returns next row. Also next(<cursor>).
    -<list>   = <cursor>.fetchall()                  # Returns remaining rows. Also list(<cursor>).
    +

    Read

    <cursor> = <conn>.execute('<query>')           # Can raise a subclass of sqlite3.Error.
    +<tuple>  = <cursor>.fetchone()                 # Returns next row. Also next(<cursor>).
    +<list>   = <cursor>.fetchall()                 # Returns remaining rows. Also list(<cursor>).
     
    -

    Write

    <conn>.execute('<query>')                       # Can raise a subclass of sqlite3.Error.
    -<conn>.commit()                                 # Saves all changes since the last commit.
    -<conn>.rollback()                               # Discards all changes since the last commit.
    +

    Write

    <conn>.execute('<query>')                      # Can raise a subclass of sqlite3.Error.
    +<conn>.commit()                                # Saves all changes since the last commit.
    +<conn>.rollback()                              # Discards all changes since the last commit.
     
    -

    Or:

    with <conn>:                                    # Exits the block with commit() or rollback(),
    -    <conn>.execute('<query>')                   # depending on whether any exception occurred.
    +

    Or:

    with <conn>:                                   # Exits the block with commit() or rollback(),
    +    <conn>.execute('<query>')                  # depending on whether any exception occurred.
     
    -

    Placeholders

    <conn>.execute('<query>', <list/tuple>)         # Replaces '?'s in query with values.
    -<conn>.execute('<query>', <dict/namedtuple>)    # Replaces ':<key>'s with values.
    -<conn>.executemany('<query>', <coll_of_above>)  # Runs execute() multiple times.
    +

    Placeholders

    <conn>.execute('<query>', <list/tuple>)        # Replaces '?'s in query with values.
    +<conn>.execute('<query>', <dict/namedtuple>)   # Replaces ':<key>'s with values.
    +<conn>.executemany('<query>', <coll_of_coll>)  # Runs execute() multiple times.
     
      -
    • Passed values can be of type str, int, float, bytes, None or bool (stored as 1 or 0).
    • +
    • Passed values can be of type str, int, float, bytes, None, or bool (stored as 1 or 0).

    Example

    Values are not actually saved in this example because 'conn.commit()' is omitted!

    >>> conn = sqlite3.connect('test.db')
     >>> conn.execute('CREATE TABLE person (person_id INTEGER PRIMARY KEY, name, height)')
    @@ -1600,10 +1600,10 @@
     
     

    SQLAlchemy

    Library for interacting with various DB systems via SQL, method chaining, or ORM.

    # $ pip3 install sqlalchemy
     from sqlalchemy import create_engine, text
    -<engine> = create_engine('<url>')               # Url: 'dialect://user:password@host/dbname'.
    -<conn>   = <engine>.connect()                   # Creates a connection. Also <conn>.close().
    -<cursor> = <conn>.execute(text('<query>'), …)   # Replaces ':<key>'s with keyword arguments.
    -with <conn>.begin(): ...                        # Exits the block with commit or rollback.
    +<engine> = create_engine('<url>')              # Url: 'dialect://user:password@host/dbname'.
    +<conn>   = <engine>.connect()                  # Creates a connection. Also <conn>.close().
    +<cursor> = <conn>.execute(text('<query>'), …)  # Replaces ':<key>'s with keyword arguments.
    +with <conn>.begin(): ...                       # Exits the block with commit or rollback.
     
    @@ -2305,9 +2305,9 @@

    Format

    # Draws a point. Truncates floats into ints. <Draw>.line((x1, y1, x2, y2 [, ...])) # To get anti-aliasing use Image's resize(). <Draw>.arc((x1, y1, x2, y2), deg1, deg2) # Draws in clockwise dir. Also pieslice(). -<Draw>.rectangle((x1, y1, x2, y2)) # To rotate use Image's rotate() and paste(). +<Draw>.rectangle((x1, y1, x2, y2)) # Also rounded_rectangle(), regular_polygon(). <Draw>.polygon((x1, y1, x2, y2, ...)) # Last point gets connected to the first. -<Draw>.ellipse((x1, y1, x2, y2)) # Also rounded_rectangle(), regular_polygon(). +<Draw>.ellipse((x1, y1, x2, y2)) # To rotate use Image's rotate() and paste(). <Draw>.text((x, y), <str>, font=<Font>) # `<Font> = ImageFont.truetype(<path>, size)`

    @@ -2720,13 +2720,13 @@

    Format

    'axis=1' to process the rows instead. -
  • Fifth result's columns are indexed with a multi-index. This means we need a tuple of column keys to specify a single column: '<DF>.loc[row_k, (col_k_1, col_k_2)]'.
  • +
  • Fifth result's columns are indexed with a multi-index. This means we need a tuple of column keys to specify a column: '<DF>.loc[row_key, (col_key_1, col_key_2)]'.
  • DataFrame — Multi-Index:

    <DF>   = <DF>.xs(row_key, level=<int>)         # Rows with key on passed level of multi-index.
     <DF>   = <DF>.xs(row_keys, level=<ints>)       # Rows that have first key on first level, etc.
     <DF>   = <DF>.set_index(col_keys)              # Combines multiple columns into a multi-index.
     <S/DF> = <DF>.stack/unstack(level=-1)          # Combines col keys with row keys or vice versa.
    -<DF>   = <DF>.pivot_table(index=col_key/s, …)  # `columns=col_key/s, values=col_key/s`.
    +<DF>   = <DF>.pivot_table(index=col_key/s, …)  # `columns=key/s, values=key/s, aggfunc='mean'`.
     

    DataFrame — Encode, Decode:

    <DF> = pd.read_json/html('<str/path/url>')     # Run `$ pip3 install beautifulsoup4 lxml`.
    @@ -2923,7 +2923,7 @@ 

    Format

    DataFrame — Encode, Decode:

    <DF> = pd.read_json/html('<str/path/url>')     # Run `$ pip3 install beautifulsoup4 lxml`.
    
    From 04e5b869bad49f5f7a877bd1b158af0d5ac65c47 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jure=20=C5=A0orn?= 
    Date: Tue, 26 Nov 2024 16:48:25 +0100
    Subject: [PATCH 16/34] Introspection
    
    ---
     README.md  | 4 ++--
     index.html | 4 ++--
     2 files changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/README.md b/README.md
    index 32661666f..926e2c42a 100644
    --- a/README.md
    +++ b/README.md
    @@ -2294,7 +2294,7 @@ CRITICAL:my_module:Running out of disk space.
     Introspection
     -------------
     ```python
    - = dir()                      # List of of local names (including functions and classes).
    + = dir()                      # List of local names (variables, funcs, classes, modules).
      = vars()                     # Dict of local names and their objects. Also locals().
      = globals()                  # Dict of global names (for instance '__builtin__' module).
     ```
    @@ -2304,7 +2304,7 @@ Introspection
      = vars()                # Returns dict of writable attributes. Also .__dict__.
      = hasattr(, '')   # Checks if object possesses attribute with passed name.
     value  = getattr(, '')   # Returns object's attribute or raises AttributeError.
    -setattr(, '', value)     # Sets attribute. Only works on objects with __dict__.
    +setattr(, '', value)     # Sets attribute. Only works on objects with __dict__ attr.
     delattr(, '')            # Deletes attribute from __dict__. Also `del .`.
     ```
     
    diff --git a/index.html b/index.html
    index f206fa810..56e24fc4a 100644
    --- a/index.html
    +++ b/index.html
    @@ -1877,7 +1877,7 @@ 

    Format

    #Introspection

    <list> = dir()                      # List of of local names (including functions and classes).
    +

    #Introspection

    <list> = dir()                      # List of local names (variables, funcs, classes, modules).
     <dict> = vars()                     # Dict of local names and their objects. Also locals().
     <dict> = globals()                  # Dict of global names (for instance '__builtin__' module).
     
    @@ -1886,7 +1886,7 @@

    Format

    # Returns dict of writable attributes. Also <obj>.__dict__. <bool> = hasattr(<obj>, '<name>') # Checks if object possesses attribute with passed name. value = getattr(<obj>, '<name>') # Returns object's attribute or raises AttributeError. -setattr(<obj>, '<name>', value) # Sets attribute. Only works on objects with __dict__. +setattr(<obj>, '<name>', value) # Sets attribute. Only works on objects with __dict__ attr. delattr(<obj>, '<name>') # Deletes attribute from __dict__. Also `del <obj>.<name>`.

    <Sig>  = inspect.signature(<func>)  # Returns function's Signature object. Can accept a class.
    
    From 37d367ce4e316176c3b5ab644490e5c1d5bfcbb0 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jure=20=C5=A0orn?= 
    Date: Wed, 27 Nov 2024 02:27:50 +0100
    Subject: [PATCH 17/34] Introspection
    
    ---
     README.md  | 4 ++--
     index.html | 8 ++++----
     2 files changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/README.md b/README.md
    index 926e2c42a..460fce69f 100644
    --- a/README.md
    +++ b/README.md
    @@ -2296,7 +2296,7 @@ Introspection
     ```python
      = dir()                      # List of local names (variables, funcs, classes, modules).
      = vars()                     # Dict of local names and their objects. Also locals().
    - = globals()                  # Dict of global names (for instance '__builtin__' module).
    + = globals()                  # Dict of global names and their objects, e.g. __builtin__.
     ```
     
     ```python
    @@ -2309,7 +2309,7 @@ delattr(, '')            # Deletes attribute from __dict__. Also `del
     ```
     
     ```python
    -  = inspect.signature()  # Returns function's Signature object. Can accept a class.
    +  = inspect.signature()  # Returns a Signature object of the passed function.
      = .parameters           # Returns dict of Parameters. Also .return_annotation.
      = .kind               # Returns ParameterKind member (Parameter.KEYWORD_ONLY, …).
      = .annotation         # Returns Parameter.empty if missing. Also .default.
    diff --git a/index.html b/index.html
    index 56e24fc4a..47e63ce1b 100644
    --- a/index.html
    +++ b/index.html
    @@ -55,7 +55,7 @@
     
     
       
    - +
    @@ -1879,7 +1879,7 @@

    Format

    #Introspection

    <list> = dir()                      # List of local names (variables, funcs, classes, modules).
     <dict> = vars()                     # Dict of local names and their objects. Also locals().
    -<dict> = globals()                  # Dict of global names (for instance '__builtin__' module).
    +<dict> = globals()                  # Dict of global names and their objects, e.g. __builtin__.
     
    <list> = dir(<obj>)                 # Returns names of all object's attributes (incl. methods).
    @@ -1889,7 +1889,7 @@ 

    Format

    '<name>', value) # Sets attribute. Only works on objects with __dict__ attr. delattr(<obj>, '<name>') # Deletes attribute from __dict__. Also `del <obj>.<name>`.

    -
    <Sig>  = inspect.signature(<func>)  # Returns function's Signature object. Can accept a class.
    +
    <Sig>  = inspect.signature(<func>)  # Returns a Signature object of the passed function.
     <dict> = <Sig>.parameters           # Returns dict of Parameters. Also <Sig>.return_annotation.
     <memb> = <Param>.kind               # Returns ParameterKind member (Parameter.KEYWORD_ONLY, …).
     <type> = <Param>.annotation         # Returns Parameter.empty if missing. Also <Param>.default.
    @@ -2923,7 +2923,7 @@ 

    Format

    <int/tup> = <Image>.getpixel((x, y))            # Returns pixel's value (its color).
     <ImgCore> = <Image>.getdata()                   # Returns a flattened view of pixel values.
    @@ -2275,7 +2275,7 @@ 

    Format

    # Use ImageEnhance.<name>(<Image>) for Enhance.

    <array> = np.array(<Image>)                     # Creates a 2d/3d NumPy array from the image.
    -<Image> = Image.fromarray(np.uint8(<array>))    # Use `<array>.clip(0, 255)` to clip values.
    +<Image> = Image.fromarray(np.uint8(<array>))    # Use <array>.clip(0, 255) to clip the values.
     

    Modes

    • 'L' - Lightness (greyscale image). Each pixel is an int between 0 and 255.
    • @@ -2782,7 +2782,7 @@

      Format

      <Fig> = px.line(<DF>, x=col_key, y=col_key) # Or: px.line(x=<list>, y=<list>) <Fig>.update_layout(margin=dict(t=0, r=0, b=0, l=0)) # Also `paper_bgcolor='rgb(0, 0, 0)'`. -<Fig>.write_html/json/image('<path>') # Also <Fig>.show(). +<Fig>.write_html/json/image('<path>') # <Fig>.show() displays the plot.

    <Fig> = px.area/bar/box(<DF>, x=col_key, y=col_key)    # Also `color=col_key`.
     <Fig> = px.scatter(<DF>, x=col_key, y=col_key)         # Also `color/size/symbol=col_key`.
    
    From bfb81f191a62a96d0333c02ecd477835f846bfac Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jure=20=C5=A0orn?= 
    Date: Wed, 27 Nov 2024 16:10:47 +0100
    Subject: [PATCH 19/34] Dictionary
    
    ---
     README.md  | 4 ++--
     index.html | 4 ++--
     2 files changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/README.md b/README.md
    index ddb7db00f..e3e7817f5 100644
    --- a/README.md
    +++ b/README.md
    @@ -82,8 +82,8 @@ Dictionary
     ```
     
     ```python
    - = .keys()                          # Coll. of keys that reflects changes.
    - = .values()                        # Coll. of values that reflects changes.
    + = .keys()                          # Collection of keys that reflects changes.
    + = .values()                        # Collection of values that reflects changes.
      = .items()                         # Coll. of key-value tuples that reflects chgs.
     ```
     
    diff --git a/index.html b/index.html
    index 40a99063a..fd0294084 100644
    --- a/index.html
    +++ b/index.html
    @@ -138,8 +138,8 @@
     

    #Dictionary

    <dict> = {key_1: val_1, key_2: val_2, ...}      # Use `<dict>[key]` to get or set the value.
     
    -
    <view> = <dict>.keys()                          # Coll. of keys that reflects changes.
    -<view> = <dict>.values()                        # Coll. of values that reflects changes.
    +
    <view> = <dict>.keys()                          # Collection of keys that reflects changes.
    +<view> = <dict>.values()                        # Collection of values that reflects changes.
     <view> = <dict>.items()                         # Coll. of key-value tuples that reflects chgs.
     
    value  = <dict>.get(key, default=None)          # Returns default if key is missing.
    
    From 5b21977ac1032d918d5ab76eed3d2f58c9b8b3af Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jure=20=C5=A0orn?= 
    Date: Wed, 27 Nov 2024 17:55:32 +0100
    Subject: [PATCH 20/34] Operator, Plot, Audio
    
    ---
     README.md  | 14 +++++++-------
     index.html | 14 +++++++-------
     parse.js   |  8 +-------
     3 files changed, 15 insertions(+), 21 deletions(-)
    
    diff --git a/README.md b/README.md
    index e3e7817f5..f5dc7ee1c 100644
    --- a/README.md
    +++ b/README.md
    @@ -2168,7 +2168,7 @@ with :                                   # Enters the block by calling acq
     
     Operator
     --------
    -**Module of functions that provide the functionality of operators. Functions are ordered by operator precedence, starting with least binding.**
    +**Module of functions that provide the functionality of operators. Functions are ordered and grouped by operator precedence from least to most binding. Logical and arithmetic operators in rows 1, 3 and 5 are also ordered by precedence within a group.**
     ```python
     import operator as op
     ```
    @@ -2419,9 +2419,9 @@ import matplotlib.pyplot as plt
     plt.plot/bar/scatter(x_data, y_data [, label=])  # Also plt.plot(y_data).
     plt.legend()                                          # Adds a legend.
     plt.title/xlabel/ylabel()                        # Adds a title or label.
    -plt.savefig()                                   # Saves the figure.
    -plt.show()                                            # Displays the figure.
    -plt.clf()                                             # Clears the figure.
    +plt.savefig()                                   # Saves the plot.
    +plt.show()                                            # Displays the plot.
    +plt.clf()                                             # Clears the plot.
     ```
     
     
    @@ -2876,7 +2876,7 @@ import wave
        = .getnchannels()       # Returns number of samples per frame.
        = .getsampwidth()       # Returns number of bytes per sample.
      = .getparams()          # Returns namedtuple of all parameters.
    - = .readframes(nframes)  # Returns next n frames. All if -1.
    + = .readframes(nframes)  # Returns next n frames (-1 returns all).
     ```
     
     ```python
    @@ -2913,7 +2913,7 @@ def read_wav_file(filename):
             p = file.getparams()
             frames = file.readframes(-1)
         bytes_samples = (frames[i : i + p.sampwidth] for i in range(0, len(frames), p.sampwidth))
    -    return [get_int(b) / pow(2, p.sampwidth * 8 - 1) for b in bytes_samples], p
    +    return [get_int(b) / pow(2, (p.sampwidth * 8) - 1) for b in bytes_samples], p
     ```
     
     ### Write Float Samples to WAV File
    @@ -2922,7 +2922,7 @@ def write_to_wav_file(filename, samples_f, p=None, nchannels=1, sampwidth=2, fra
         def get_bytes(a_float):
             a_float = max(-1, min(1 - 2e-16, a_float))
             a_float += p.sampwidth == 1
    -        a_float *= pow(2, p.sampwidth * 8 - 1)
    +        a_float *= pow(2, (p.sampwidth * 8) - 1)
             return int(a_float).to_bytes(p.sampwidth, 'little', signed=(p.sampwidth != 1))
         if p is None:
             p = wave._wave_params(nchannels, sampwidth, framerate, 0, 'NONE', 'not compressed')
    diff --git a/index.html b/index.html
    index fd0294084..307c470b7 100644
    --- a/index.html
    +++ b/index.html
    @@ -1775,7 +1775,7 @@ 

    Format

    pickable, queues must be sent using executor's 'initargs' and 'initializer' parameters, and executor should only be reachable via 'if __name__ == "__main__": ...'. -

    #Operator

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

    import operator as op
    +

    #Operator

    Module of functions that provide the functionality of operators. Functions are ordered and grouped by operator precedence from least to most binding. Logical and arithmetic operators in rows 1, 3 and 5 are also ordered by precedence within a group.

    import operator as op
     
    @@ -1979,9 +1979,9 @@

    Format

    # Also plt.plot(y_data). plt.legend() # Adds a legend. plt.title/xlabel/ylabel(<str>) # Adds a title or label. -plt.savefig(<path>) # Saves the figure. -plt.show() # Displays the figure. -plt.clf() # Clears the figure. +plt.savefig(<path>) # Saves the plot. +plt.show() # Displays the plot. +plt.clf() # Clears the plot.

    #Table

    Prints a CSV spreadsheet to the console:

    # $ pip3 install tabulate
    @@ -2342,7 +2342,7 @@ 

    Format

    # Returns number of samples per frame. <int> = <Wave>.getsampwidth() # Returns number of bytes per sample. <tuple> = <Wave>.getparams() # Returns namedtuple of all parameters. -<bytes> = <Wave>.readframes(nframes) # Returns next n frames. All if -1. +<bytes> = <Wave>.readframes(nframes) # Returns next n frames (-1 returns all).

    <Wave> = wave.open('<path>', 'wb')    # Creates/truncates a file for writing.
     <Wave>.setframerate(<int>)            # Pass 44100 for CD, 48000 for video.
    @@ -2374,14 +2374,14 @@ 

    Format

    -1) bytes_samples = (frames[i : i + p.sampwidth] for i in range(0, len(frames), p.sampwidth)) - return [get_int(b) / pow(2, p.sampwidth * 8 - 1) for b in bytes_samples], p + return [get_int(b) / pow(2, (p.sampwidth * 8) - 1) for b in bytes_samples], p

    Write Float Samples to WAV File

    def write_to_wav_file(filename, samples_f, p=None, nchannels=1, sampwidth=2, framerate=44100):
         def get_bytes(a_float):
             a_float = max(-1, min(1 - 2e-16, a_float))
             a_float += p.sampwidth == 1
    -        a_float *= pow(2, p.sampwidth * 8 - 1)
    +        a_float *= pow(2, (p.sampwidth * 8) - 1)
             return int(a_float).to_bytes(p.sampwidth, 'little', signed=(p.sampwidth != 1))
         if p is None:
             p = wave._wave_params(nchannels, sampwidth, framerate, 0, 'NONE', 'not compressed')
    diff --git a/parse.js b/parse.js
    index 2cd9e96e8..cc1725ef6 100755
    --- a/parse.js
    +++ b/parse.js
    @@ -84,11 +84,6 @@ const CONSTRUCTOR_OVERLOADING =
       '    def __init__(self, a=None):\n' +
       '        self.a = a\n';
     
    -const DATACLASS =
    -  '<class> = make_dataclass(\'<class_name>\', <coll_of_attribute_names>)\n' +
    -  '<class> = make_dataclass(\'<class_name>\', <coll_of_tuples>)\n' +
    -  '<tuple> = (\'<attr_name>\', <type> [, <default_value>])';
    -
     const SHUTIL_COPY =
       'shutil.copy(from, to)               # Copies the file. \'to\' can exist or be a dir.\n' +
       'shutil.copy2(from, to)              # Also copies creation and modification time.\n' +
    @@ -221,7 +216,7 @@ const AUDIO_1 =
       '    def get_bytes(a_float):\n' +
       '        a_float = max(-1, min(1 - 2e-16, a_float))\n' +
       '        a_float += p.sampwidth == 1\n' +
    -  '        a_float *= pow(2, p.sampwidth * 8 - 1)\n' +
    +  '        a_float *= pow(2, (p.sampwidth * 8) - 1)\n' +
       '        return int(a_float).to_bytes(p.sampwidth, \'little\', signed=(p.sampwidth != 1))\n' +
       '    if p is None:\n' +
       '        p = wave._wave_params(nchannels, sampwidth, framerate, 0, \'NONE\', \'not compressed\')\n' +
    @@ -843,7 +838,6 @@ function fixHighlights() {
       $(`code:contains(@debug(print_result=True))`).html(PARAMETRIZED_DECORATOR);
       $(`code:contains(print/str/repr([]))`).html(REPR_USE_CASES);
       $(`code:contains((self, a=None):)`).html(CONSTRUCTOR_OVERLOADING);
    -  //$(`code:contains(make_dataclass(\'\')`).html(DATACLASS);
       $(`code:contains(shutil.copy)`).html(SHUTIL_COPY);
       $(`code:contains(os.rename)`).html(OS_RENAME);
       $(`code:contains(\'s\')`).html(STRUCT_FORMAT);
    
    From 3d9699ce336f0e8e3dc75d192a2d3faab777f4e5 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jure=20=C5=A0orn?= 
    Date: Wed, 27 Nov 2024 19:54:47 +0100
    Subject: [PATCH 21/34] Moved Threading in front of Coroutines
    
    ---
     README.md                    | 138 +++++++++++++++++------------------
     index.html                   | 110 ++++++++++++++--------------
     parse.js                     |   3 +-
     pdf/index_for_pdf.html       |  26 +++----
     pdf/index_for_pdf_print.html |  26 +++----
     pdf/remove_links.py          |   5 +-
     web/script_2.js              |   8 +-
     7 files changed, 157 insertions(+), 159 deletions(-)
    
    diff --git a/README.md b/README.md
    index f5dc7ee1c..81a9f2d06 100644
    --- a/README.md
    +++ b/README.md
    @@ -13,7 +13,7 @@ Contents
     **   ** **3. Syntax:** **         **  **[`Args`](#arguments)**__,__ **[`Inline`](#inline)**__,__ **[`Import`](#imports)**__,__ **[`Decorator`](#decorator)**__,__ **[`Class`](#class)**__,__ **[`Duck_Types`](#duck-types)**__,__ **[`Enum`](#enum)**__,__ **[`Exception`](#exceptions)**__.__  
     **   ** **4. System:** **        **  **[`Exit`](#exit)**__,__ **[`Print`](#print)**__,__ **[`Input`](#input)**__,__ **[`Command_Line_Arguments`](#command-line-arguments)**__,__ **[`Open`](#open)**__,__ **[`Path`](#paths)**__,__ **[`OS_Commands`](#os-commands)**__.__  
     **   ** **5. Data:** **             **  **[`JSON`](#json)**__,__ **[`Pickle`](#pickle)**__,__ **[`CSV`](#csv)**__,__ **[`SQLite`](#sqlite)**__,__ **[`Bytes`](#bytes)**__,__ **[`Struct`](#struct)**__,__ **[`Array`](#array)**__,__ **[`Memory_View`](#memory-view)**__,__ **[`Deque`](#deque)**__.__  
    -**   ** **6. Advanced:** **   **  **[`Threading`](#threading)**__,__ **[`Operator`](#operator)**__,__ **[`Match_Stmt`](#match-statement)**__,__ **[`Logging`](#logging)**__,__ **[`Introspection`](#introspection)**__,__ **[`Coroutines`](#coroutines)**__.__  
    +**   ** **6. Advanced:** **   **  **[`Operator`](#operator)**__,__ **[`Match_Stmt`](#match-statement)**__,__ **[`Logging`](#logging)**__,__ **[`Introspection`](#introspection)**__,__ **[`Threading`](#threading)**__,__ **[`Coroutines`](#coroutines)**__.__  
     **   ** **7. Libraries:** **      **  **[`Progress_Bar`](#progress-bar)**__,__ **[`Plot`](#plot)**__,__ **[`Table`](#table)**__,__ **[`Console_App`](#console-app)**__,__ **[`GUI`](#gui-app)**__,__ **[`Scraping`](#scraping)**__,__ **[`Web`](#web-app)**__,__ **[`Profile`](#profiling)**__.__  
     **   ** **8. Multimedia:** **  **  **[`NumPy`](#numpy)**__,__ **[`Image`](#image)**__,__ **[`Animation`](#animation)**__,__ **[`Audio`](#audio)**__,__ **[`Synthesizer`](#synthesizer)**__,__ **[`Pygame`](#pygame)**__,__ **[`Pandas`](#pandas)**__,__ **[`Plotly`](#plotly)**__.__
     
    @@ -2086,7 +2086,7 @@ Memory View
     
     Deque
     -----
    -**A thread-safe list with efficient appends and pops from either side. Pronounced "deck".**
    +**List with efficient appends and pops from either side. Pronounced "deck".**
     
     ```python
     from collections import deque
    @@ -2101,71 +2101,6 @@ 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.**
    -```python
    -from threading import Thread, Lock, RLock, Semaphore, Event, Barrier
    -from concurrent.futures import ThreadPoolExecutor, as_completed
    -```
    -
    -### Thread
    -```python
    - = Thread(target=)           # Use `args=` to set the arguments.
    -.start()                               # Starts the thread. Also .is_alive().
    -.join()                                # Waits for the thread to finish.
    -```
    -* **Use `'kwargs='` to pass keyword arguments to the function.**
    -* **Use `'daemon=True'`, or the program will not be able to exit while the thread is alive.**
    -
    -### Lock
    -```python
    - = Lock/RLock()                          # RLock can only be released by acquirer.
    -.acquire()                               # Waits for the lock to be available.
    -.release()                               # Makes the lock available again.
    -```
    -
    -#### Or:
    -```python
    -with :                                   # Enters the block by calling acquire() and
    -    ...                                        # exits it with release(), even on error.
    -```
    -
    -### Semaphore, Event, Barrier
    -```python
    - = Semaphore(value=1)               # Lock that can be acquired by 'value' threads.
    -     = Event()                          # Method wait() blocks until set() is called.
    -   = Barrier(n_times)                 # Wait() blocks until it's called n_times.
    -```
    -
    -### Queue
    -```python
    - = queue.Queue(maxsize=0)               # A thread-safe first-in-first-out queue.
    -.put()                              # Blocks until queue stops being full.
    -.put_nowait()                       # Raises queue.Full exception if full.
    - = .get()                           # Blocks until queue stops being empty.
    - = .get_nowait()                    # Raises queue.Empty exception if empty.
    -```
    -
    -### Thread Pool Executor
    -```python
    - = ThreadPoolExecutor(max_workers=None)  # Or: `with ThreadPoolExecutor() as : ...`
    - = .map(, , ...)     # Multithreaded and non-lazy map(). Keeps order.
    - = .submit(, , ...)   # Creates a thread and returns its Future obj.
    -.shutdown()                              # Blocks until all threads finish executing.
    -```
    -
    -```python
    - = .done()                       # Checks if the thread has finished executing.
    -  = .result(timeout=None)         # Waits for thread to finish and returns result.
    - = .cancel()                     # Cancels or returns False if running/finished.
    - = as_completed()       # `next()` returns next completed Future.
    -```
    -* **Map() and as\_completed() also accept 'timeout'. It causes futures.TimeoutError when next() is called/blocking. Map() times from original call and as_completed() from first call to next(). As\_completed() fails if next() is called too late, even if all threads are done.**
    -* **Exceptions that happen inside threads are raised when map iterator's next() or Future's result() are called. Future's exception() method returns exception object or None.**
    -* **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, and executor should only be reachable via `'if __name__ == "__main__": ...'`.**
    -
    -
     Operator
     --------
     **Module of functions that provide the functionality of operators. Functions are ordered and grouped by operator precedence from least to most binding. Logical and arithmetic operators in rows 1, 3 and 5 are also ordered by precedence within a group.**
    @@ -2316,6 +2251,71 @@ delattr(, '')            # Deletes attribute from __dict__. Also `del
     ```
     
     
    +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.**
    +```python
    +from threading import Thread, Lock, RLock, Semaphore, Event, Barrier
    +from concurrent.futures import ThreadPoolExecutor, as_completed
    +```
    +
    +### Thread
    +```python
    + = Thread(target=)           # Use `args=` to set the arguments.
    +.start()                               # Starts the thread. Also .is_alive().
    +.join()                                # Waits for the thread to finish.
    +```
    +* **Use `'kwargs='` to pass keyword arguments to the function.**
    +* **Use `'daemon=True'`, or the program will not be able to exit while the thread is alive.**
    +
    +### Lock
    +```python
    + = Lock/RLock()                          # RLock can only be released by acquirer.
    +.acquire()                               # Waits for the lock to be available.
    +.release()                               # Makes the lock available again.
    +```
    +
    +#### Or:
    +```python
    +with :                                   # Enters the block by calling acquire() and
    +    ...                                        # exits it with release(), even on error.
    +```
    +
    +### Semaphore, Event, Barrier
    +```python
    + = Semaphore(value=1)               # Lock that can be acquired by 'value' threads.
    +     = Event()                          # Method wait() blocks until set() is called.
    +   = Barrier(n_times)                 # Wait() blocks until it's called n_times.
    +```
    +
    +### Queue
    +```python
    + = queue.Queue(maxsize=0)               # A thread-safe first-in-first-out queue.
    +.put()                              # Blocks until queue stops being full.
    +.put_nowait()                       # Raises queue.Full exception if full.
    + = .get()                           # Blocks until queue stops being empty.
    + = .get_nowait()                    # Raises queue.Empty exception if empty.
    +```
    +
    +### Thread Pool Executor
    +```python
    + = ThreadPoolExecutor(max_workers=None)  # Or: `with ThreadPoolExecutor() as : ...`
    + = .map(, , ...)     # Multithreaded and non-lazy map(). Keeps order.
    + = .submit(, , ...)   # Creates a thread and returns its Future obj.
    +.shutdown()                              # Blocks until all threads finish executing.
    +```
    +
    +```python
    + = .done()                       # Checks if the thread has finished executing.
    +  = .result(timeout=None)         # Waits for thread to finish and returns result.
    + = .cancel()                     # Cancels or returns False if running/finished.
    + = as_completed()       # `next()` returns next completed Future.
    +```
    +* **Map() and as\_completed() also accept 'timeout'. It causes futures.TimeoutError when next() is called/blocking. Map() times from original call and as_completed() from first call to next(). As\_completed() fails if next() is called too late, even if all threads are done.**
    +* **Exceptions that happen inside threads are raised when map iterator's next() or Future's result() are called. Future's exception() method returns exception object or None.**
    +* **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, and executor should only be reachable via `'if __name__ == "__main__": ...'`.**
    +
    +
     Coroutines
     ----------
     * **Coroutines have a lot in common with threads, but unlike threads, they only give up control when they call another coroutine and they don’t use as much memory.**
    @@ -2553,7 +2553,7 @@ import flask as fl
     
     ```python
     app = fl.Flask(__name__)                   # Returns the app object. Put at the top.
    -app.run(host=None, port=None, debug=None)  # Or: $ flask --app FILE run [--ARG[=VAL] …]
    +app.run(host=None, port=None, debug=None)  # Or: $ flask --app FILE run [--ARG[=VAL]]…
     ```
     * **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.**
    @@ -3146,7 +3146,7 @@ if __name__ == '__main__':
     
     Pandas
     ------
    -**Data analysis library. For examples see [Plotly](#displays-a-line-chart-of-total-coronavirus-deaths-per-million-grouped-by-continent).**
    +**Data analysis library. For examples see [Plotly](#plotly).**
     
     ```python
     # $ pip3 install pandas matplotlib
    diff --git a/index.html b/index.html
    index 307c470b7..75852dcb6 100644
    --- a/index.html
    +++ b/index.html
    @@ -86,7 +86,7 @@
         '3. Syntax':      [Args, Inline, Import, Decorator, Class, Duck_Types, Enum, Exception],
         '4. System':      [Exit, Print, Input, Command_Line_Arguments, Open, Path, OS_Commands],
         '5. Data':        [JSON, Pickle, CSV, SQLite, Bytes, Struct, Array, Memory_View, Deque],
    -    '6. Advanced':    [Threading, Operator, Match_Stmt, Logging, Introspection, Coroutines],
    +    '6. Advanced':    [Operator, Match_Stmt, Logging, Introspection, Threading, Coroutines],
         '7. Libraries':   [Progress_Bar, Plot, Table, Console_App, GUI, Scraping, Web, Profile],
         '8. Multimedia':  [NumPy, Image, Animation, Audio, Synthesizer, Pygame, Pandas, Plotly]
     }
    @@ -1714,7 +1714,7 @@ 

    Format

    'utf-8') # Treats memoryview as a bytes object. <str> = <mview>.hex() # Returns hex pairs. Accepts `sep=<str>`.

    -

    #Deque

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

    from collections import deque
    +

    #Deque

    List with efficient appends and pops from either side. Pronounced "deck".

    from collections import deque
     
    @@ -1724,57 +1724,6 @@

    Format

    1) # Last element becomes first. <el> = <deque>.popleft() # Raises IndexError if deque is empty.

    -

    #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, Lock, RLock, Semaphore, Event, Barrier
    -from concurrent.futures import ThreadPoolExecutor, as_completed
    -
    - - -

    Thread

    <Thread> = Thread(target=<function>)           # Use `args=<collection>` to set the arguments.
    -<Thread>.start()                               # Starts the thread. Also <Thread>.is_alive().
    -<Thread>.join()                                # Waits for the thread to finish.
    -
    - -
      -
    • Use '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.
    • -
    -

    Lock

    <lock> = Lock/RLock()                          # RLock can only be released by acquirer.
    -<lock>.acquire()                               # Waits for the lock to be available.
    -<lock>.release()                               # Makes the lock available again.
    -
    - -

    Or:

    with <lock>:                                   # Enters the block by calling acquire() and
    -    ...                                        # exits it with release(), even on error.
    -
    - -

    Semaphore, Event, Barrier

    <Semaphore> = Semaphore(value=1)               # Lock that can be acquired by 'value' threads.
    -<Event>     = Event()                          # Method wait() blocks until set() is called.
    -<Barrier>   = Barrier(n_times)                 # Wait() blocks until it's called n_times.
    -
    - -

    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.
    -<el> = <Queue>.get_nowait()                    # Raises queue.Empty exception if empty.
    -
    - -

    Thread Pool Executor

    <Exec> = ThreadPoolExecutor(max_workers=None)  # Or: `with ThreadPoolExecutor() as <name>: ...`
    -<iter> = <Exec>.map(<func>, <args_1>, ...)     # Multithreaded and non-lazy map(). Keeps order.
    -<Futr> = <Exec>.submit(<func>, <arg_1>, ...)   # Creates a thread and returns its Future obj.
    -<Exec>.shutdown()                              # Blocks until all threads finish executing.
    -
    - -
    <bool> = <Future>.done()                       # Checks if the thread has finished executing.
    -<obj>  = <Future>.result(timeout=None)         # Waits for thread to finish and returns result.
    -<bool> = <Future>.cancel()                     # Cancels or returns False if running/finished.
    -<iter> = as_completed(<coll_of_Futures>)       # `next(<iter>)` returns next completed Future.
    -
    -
      -
    • Map() and as_completed() also accept 'timeout'. It causes futures.TimeoutError when next() is called/blocking. Map() times from original call and as_completed() from first call to next(). As_completed() fails if next() is called too late, even if all threads are done.
    • -
    • Exceptions that happen inside threads are raised when map iterator's next() or Future's result() are called. Future's exception() method returns exception object or None.
    • -
    • ProcessPoolExecutor provides true parallelism but: everything sent to/from workers must be pickable, queues must be sent using executor's 'initargs' and 'initializer' parameters, and executor should only be reachable via 'if __name__ == "__main__": ...'.
    • -

    #Operator

    Module of functions that provide the functionality of operators. Functions are ordered and grouped by operator precedence from least to most binding. Logical and arithmetic operators in rows 1, 3 and 5 are also ordered by precedence within a group.

    import operator as op
     
    @@ -1894,6 +1843,57 @@

    Format

    # Returns ParameterKind member (Parameter.KEYWORD_ONLY, …). <type> = <Param>.annotation # Returns Parameter.empty if missing. Also <Param>.default.

    +

    #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, Lock, RLock, Semaphore, Event, Barrier
    +from concurrent.futures import ThreadPoolExecutor, as_completed
    +
    + + +

    Thread

    <Thread> = Thread(target=<function>)           # Use `args=<collection>` to set the arguments.
    +<Thread>.start()                               # Starts the thread. Also <Thread>.is_alive().
    +<Thread>.join()                                # Waits for the thread to finish.
    +
    + +
      +
    • Use '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.
    • +
    +

    Lock

    <lock> = Lock/RLock()                          # RLock can only be released by acquirer.
    +<lock>.acquire()                               # Waits for the lock to be available.
    +<lock>.release()                               # Makes the lock available again.
    +
    + +

    Or:

    with <lock>:                                   # Enters the block by calling acquire() and
    +    ...                                        # exits it with release(), even on error.
    +
    + +

    Semaphore, Event, Barrier

    <Semaphore> = Semaphore(value=1)               # Lock that can be acquired by 'value' threads.
    +<Event>     = Event()                          # Method wait() blocks until set() is called.
    +<Barrier>   = Barrier(n_times)                 # Wait() blocks until it's called n_times.
    +
    + +

    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.
    +<el> = <Queue>.get_nowait()                    # Raises queue.Empty exception if empty.
    +
    + +

    Thread Pool Executor

    <Exec> = ThreadPoolExecutor(max_workers=None)  # Or: `with ThreadPoolExecutor() as <name>: ...`
    +<iter> = <Exec>.map(<func>, <args_1>, ...)     # Multithreaded and non-lazy map(). Keeps order.
    +<Futr> = <Exec>.submit(<func>, <arg_1>, ...)   # Creates a thread and returns its Future obj.
    +<Exec>.shutdown()                              # Blocks until all threads finish executing.
    +
    + +
    <bool> = <Future>.done()                       # Checks if the thread has finished executing.
    +<obj>  = <Future>.result(timeout=None)         # Waits for thread to finish and returns result.
    +<bool> = <Future>.cancel()                     # Cancels or returns False if running/finished.
    +<iter> = as_completed(<coll_of_Futures>)       # `next(<iter>)` returns next completed Future.
    +
    +
      +
    • Map() and as_completed() also accept 'timeout'. It causes futures.TimeoutError when next() is called/blocking. Map() times from original call and as_completed() from first call to next(). As_completed() fails if next() is called too late, even if all threads are done.
    • +
    • Exceptions that happen inside threads are raised when map iterator's next() or Future's result() are called. Future's exception() method returns exception object or None.
    • +
    • ProcessPoolExecutor provides true parallelism but: everything sent to/from workers must be pickable, queues must be sent using executor's 'initargs' and 'initializer' parameters, and executor should only be reachable via 'if __name__ == "__main__": ...'.
    • +

    #Coroutines

    • Coroutines have a lot in common with threads, but unlike threads, they only give up control when they call another coroutine and they don’t use as much memory.
    • Coroutine definition starts with 'async' and its call with 'await'.
    • @@ -2087,7 +2087,7 @@

      Format

      app = fl.Flask(__name__) # Returns the app object. Put at the top. -app.run(host=None, port=None, debug=None) # Or: $ flask --app FILE run [--ARG[=VAL] …] +app.run(host=None, port=None, debug=None) # Or: $ flask --app FILE run [--ARG[=VAL]]…

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

      Format

      #Pandas

      Data analysis library. For examples see Plotly.

      # $ pip3 install pandas matplotlib
      +

      #Pandas

      Data analysis library. For examples see Plotly.

      # $ pip3 install pandas matplotlib
       import pandas as pd, matplotlib.pyplot as plt
       
      diff --git a/parse.js b/parse.js index cc1725ef6..3f8261722 100755 --- a/parse.js +++ b/parse.js @@ -36,7 +36,7 @@ const TOC = ' \'3. Syntax\': [Args, Inline, Import, Decorator, Class, Duck_Types, Enum, Exception],\n' + ' \'4. System\': [Exit, Print, Input, Command_Line_Arguments, Open, Path, OS_Commands],\n' + ' \'5. Data\': [JSON, Pickle, CSV, SQLite, Bytes, Struct, Array, Memory_View, Deque],\n' + - ' \'6. Advanced\': [Threading, Operator, Match_Stmt, Logging, Introspection, Coroutines],\n' + + ' \'6. Advanced\': [Operator, Match_Stmt, Logging, Introspection, Threading, Coroutines],\n' + ' \'7. Libraries\': [Progress_Bar, Plot, Table, Console_App, GUI, Scraping, Web, Profile],\n' + ' \'8. Multimedia\': [NumPy, Image, Animation, Audio, Synthesizer, Pygame, Pandas, Plotly]\n' + '}\n' + @@ -711,7 +711,6 @@ function getMd() { var readme = readme.replace("#semaphore-event-barrier", "#semaphoreeventbarrier"); var readme = readme.replace("#semaphore-event-barrier", "#semaphoreeventbarrier"); var readme = readme.replace("#dataframe-plot-encode-decode", "#dataframeplotencodedecode"); - var readme = readme.replace("#displays-a-line-chart-of-total-coronavirus-deaths-per-million-grouped-by-continent", "#displaysalinechartoftotalcoronavirusdeathspermilliongroupedbycontinent"); const converter = new showdown.Converter(); return converter.makeHtml(readme); } diff --git a/pdf/index_for_pdf.html b/pdf/index_for_pdf.html index 54f6747f0..44050adcc 100644 --- a/pdf/index_for_pdf.html +++ b/pdf/index_for_pdf.html @@ -14,7 +14,7 @@

      A

      B

      beautifulsoup library, 35
      binary representation, 7, 8
      -bitwise operators, 8, 31
      +bitwise operators, 8, 30
      bytes, 22-23, 25, 28-29

      C

      cache, 13
      @@ -26,7 +26,7 @@

      C

      combinatorics, 8
      command line arguments, 22
      comprehensions, 11
      -context manager, 17, 23, 27, 30
      +context manager, 17, 23, 27, 32
      copy function, 15
      coroutine, 33
      counter, 2, 4, 12, 17
      @@ -44,7 +44,7 @@

      E

      enum module, 19-20
      enumerate function, 3
      excel, 46
      -exceptions, 20-21, 23, 32
      +exceptions, 20-21, 23, 31
      exit function, 21

      F

      files, 22-29, 34, 46
      @@ -66,9 +66,9 @@

      I

      imports, 12
      inline, 11, 15, 20
      input function, 22
      -introspection, 21, 32
      +introspection, 21, 31
      ints, 4, 7, 8, 28
      -is operator, 16, 31
      +is operator, 16, 30
      iterable, 4, 18, 19
      iterator, 3-4, 11, 17
      itertools module, 3, 8

      @@ -78,12 +78,12 @@

      L

      lambda, 11
      lists, 1-2, 4, 11, 18-19, 21
      locale module, 16
      -logging, 32

      +logging, 31

      M

      main function, 1, 49
      -match statement, 31
      +match statement, 30
      matplotlib library, 34, 44, 46
      -map function, 11, 31
      +map function, 11, 30
      math module, 7
      memoryviews, 29
      module, 12

      @@ -94,7 +94,7 @@

      N

      numpy library, 37-38

      O

      open function, 17, 22-23, 25, 26, 28
      -operator module, 31
      +operator module, 30
      os commands, 23-25, 34

      P

      pandas library, 44-48
      @@ -109,12 +109,12 @@

      P

      property decorator, 15
      pygame library, 42-43

      Q

      -

      queues, 29, 30, 33

      +

      queues, 29, 32, 33

      R

      random module, 8
      ranges, 3, 4
      recursion, 13, 21
      -reduce function, 11, 31
      +reduce function, 11
      regular expressions, 5-6
      requests library, 35, 36

      S

      @@ -136,11 +136,11 @@

      S

      T

      table, 26, 27, 34, 37-38, 45-46
      template, 6, 36
      -threading module, 30, 36
      +threading module, 32, 36
      time module, 34, 36
      tuples, 3, 4, 11, 18-19
      type, 4
      -type annotations, 15, 32

      +type annotations, 15, 31

      W

      wave module, 40-41
      web, 36

      diff --git a/pdf/index_for_pdf_print.html b/pdf/index_for_pdf_print.html index e7bdcfeb7..126dbf0ec 100644 --- a/pdf/index_for_pdf_print.html +++ b/pdf/index_for_pdf_print.html @@ -14,7 +14,7 @@

      A

      B

      beautifulsoup library, 35
      binary representation, 7, 8
      -bitwise operators, 8, 31
      +bitwise operators, 8, 30
      bytes, 22-23, 25, 28-29

      C

      cache, 13
      @@ -26,7 +26,7 @@

      C

      combinatorics, 8
      command line arguments, 22
      comprehensions, 11
      -context manager, 17, 23, 27, 30
      +context manager, 17, 23, 27, 32
      copy function, 15
      coroutine, 33
      counter, 2, 4, 12, 17
      @@ -44,7 +44,7 @@

      E

      enum module, 19-20
      enumerate function, 3
      excel, 46
      -exceptions, 20-21, 23, 32
      +exceptions, 20-21, 23, 31
      exit function, 21

      F

      files, 22-29, 34, 46
      @@ -66,9 +66,9 @@

      I

      imports, 12
      inline, 11, 15, 20
      input function, 22
      -introspection, 21, 32
      +introspection, 21, 31
      ints, 4, 7, 8, 28
      -is operator, 16, 31
      +is operator, 16, 30
      iterable, 4, 18, 19
      iterator, 3-4, 11, 17
      itertools module, 3, 8

      @@ -78,12 +78,12 @@

      L

      lambda, 11
      lists, 1-2, 4, 11, 18-19, 21
      locale module, 16
      -logging, 32

      +logging, 31

      M

      main function, 1, 49
      -match statement, 31
      +match statement, 30
      matplotlib library, 34, 44, 46
      -map function, 11, 31
      +map function, 11, 30
      math module, 7
      memoryviews, 29
      module, 12

      @@ -94,7 +94,7 @@

      N

      numpy library, 37-38

      O

      open function, 17, 22-23, 25, 26, 28
      -operator module, 31
      +operator module, 30
      os commands, 23-25, 34

      P

      pandas library, 44-48
      @@ -109,12 +109,12 @@

      P

      property decorator, 15
      pygame library, 42-43

      Q

      -

      queues, 29, 30, 33

      +

      queues, 29, 32, 33

      R

      random module, 8
      ranges, 3, 4
      recursion, 13, 21
      -reduce function, 11, 31
      +reduce function, 11
      regular expressions, 5-6
      requests library, 35, 36

      S

      @@ -136,11 +136,11 @@

      S

      T

      table, 26, 27, 34, 37-38, 45-46
      template, 6, 36
      -threading module, 30, 36
      +threading module, 32, 36
      time module, 34, 36
      tuples, 3, 4, 11, 18-19
      type, 4
      -type annotations, 15, 32

      +type annotations, 15, 31

      W

      wave module, 40-41
      web, 36

      diff --git a/pdf/remove_links.py b/pdf/remove_links.py index e31507ed8..329238d38 100755 --- a/pdf/remove_links.py +++ b/pdf/remove_links.py @@ -20,15 +20,14 @@ 'Objects returned by the itertools module, such as count, repeat and cycle.': 'Objects returned by the itertools module, such as count, repeat and cycle (p. 3).', 'Generators returned by the generator functions and generator expressions.': 'Generators returned by the generator functions (p. 4) and generator expressions (p. 11).', 'File objects returned by the open() function, etc.': 'File objects returned by the open() function (p. 22), etc.', - 'Use \'logging.exception(<str>)\' to log the passed message, followed by the full error message of the caught exception. For details see logging.': 'Use \'logging.exception(<str>)\' to log the passed message, followed by the full error message of the caught exception. For details see logging (p. 32).', + 'Use \'logging.exception(<str>)\' to log the passed message, followed by the full error message of the caught exception. For details see logging.': 'Use \'logging.exception(<str>)\' to log the passed message, followed by the full error message of the caught exception. For details see logging (p. 31).', 'Functions report OS related errors by raising either OSError or one of its subclasses.': 'Functions report OS related errors by raising OSError or one of its subclasses (p. 23).', 'To print the spreadsheet to the console use Tabulate library.': 'To print the spreadsheet to the console use Tabulate library (p. 34).', 'For XML and binary Excel files (xlsx, xlsm and xlsb) use Pandas library.': 'For XML and binary Excel files (xlsx, xlsm and xlsb) use Pandas library (p. 46).', 'Bools will be stored and returned as ints and dates as ISO formatted strings.': 'Bools will be stored and returned as ints and dates as ISO formatted strings (p. 9).', 'ProcessPoolExecutor provides true parallelism but: everything sent to/from workers must be pickable, queues must be sent using executor\'s \'initargs\' and \'initializer\' parameters, and executor should only be reachable via \'if __name__ == "__main__": ...\'.': 'ProcessPoolExecutor provides true parallelism but: everything sent to/from workers must be pickable, queues must be sent using executor\'s \'initargs\' and \'initializer\' parameters, and executor should only be reachable via \'if __name__ == "__main__": ...\'.', - 'Asyncio module also provides its own Queue, Event, Lock and Semaphore classes.': 'Asyncio module also provides its own Queue, Event, Lock and Semaphore classes (p. 30).', 'Install a WSGI server like Waitress and a HTTP server such as Nginx for better security.': 'Install a WSGI server like Waitress and a HTTP server such as Nginx for better security.', - 'Data analysis library. For examples see Plotly.': 'Data analysis library. For examples see Plotly (p. 47).', + 'Data analysis library. For examples see Plotly.': 'Data analysis library. For examples see Plotly (p. 47).', } diff --git a/web/script_2.js b/web/script_2.js index be1c1c7bf..673fc18ed 100644 --- a/web/script_2.js +++ b/web/script_2.js @@ -5,7 +5,7 @@ const TOC = ' \'3. Syntax\': [Args, Inline, Import, Decorator, Class, Duck_Types, Enum, Exception],\n' + ' \'4. System\': [Exit, Print, Input, Command_Line_Arguments, Open, Path, OS_Commands],\n' + ' \'5. Data\': [JSON, Pickle, CSV, SQLite, Bytes, Struct, Array, Memory_View, Deque],\n' + - ' \'6. Advanced\': [Threading, Operator, Match_Stmt, Logging, Introspection, Coroutines],\n' + + ' \'6. Advanced\': [Operator, Match_Stmt, Logging, Introspection, Threading, Coroutines],\n' + ' \'7. Libraries\': [Progress_Bar, Plot, Table, Console_App, GUI, Scraping, Web, Profile],\n' + ' \'8. Multimedia\': [NumPy, Image, Animation, Audio, Synthesizer, Pygame, Pandas, Plotly]\n' + '}\n'; @@ -27,9 +27,9 @@ const TOC_MOBILE = ' \'5. Data\': [JSON, Pickle, CSV, SQLite,\n' + ' Bytes, Struct, Array,\n' + ' Memory_View, Deque],\n' + - ' \'6. Advanced\': [Threading, Operator,\n' + - ' Match_Stmt, Logging, \n' + - ' Introspection, Coroutines],\n' + + ' \'6. Advanced\': [, Operator, Match_Stmt,\n' + + ' Logging, Introspection,\n' + + ' Threading, Coroutines],\n' + ' \'7. Libraries\': [Progress_Bar, Plot, Table,\n' + ' Console_App, GUI_App,\n' + ' Scraping, Web, Profiling],\n' + From ca862f4441f9cc23363da4a7c5d452189d87b1fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Wed, 27 Nov 2024 19:57:56 +0100 Subject: [PATCH 22/34] Fixed script_2.js --- web/script_2.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/script_2.js b/web/script_2.js index 673fc18ed..8cb4f55ab 100644 --- a/web/script_2.js +++ b/web/script_2.js @@ -27,7 +27,7 @@ const TOC_MOBILE = ' \'5. Data\': [JSON, Pickle, CSV, SQLite,\n' + ' Bytes, Struct, Array,\n' + ' Memory_View, Deque],\n' + - ' \'6. Advanced\': [, Operator, Match_Stmt,\n' + + ' \'6. Advanced\': [Operator, Match_Stmt,\n' + ' Logging, Introspection,\n' + ' Threading, Coroutines],\n' + ' \'7. Libraries\': [Progress_Bar, Plot, Table,\n' + From e5a7c71bf10f42b893cc6897eb03c4fbdb83978c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Wed, 27 Nov 2024 20:00:08 +0100 Subject: [PATCH 23/34] Updated mobile TOC --- web/script_2.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/script_2.js b/web/script_2.js index 8cb4f55ab..12ff725a2 100644 --- a/web/script_2.js +++ b/web/script_2.js @@ -27,7 +27,7 @@ const TOC_MOBILE = ' \'5. Data\': [JSON, Pickle, CSV, SQLite,\n' + ' Bytes, Struct, Array,\n' + ' Memory_View, Deque],\n' + - ' \'6. Advanced\': [Operator, Match_Stmt,\n' + + ' \'6. Advanced\': [Operator, Match_Statement,\n' + ' Logging, Introspection,\n' + ' Threading, Coroutines],\n' + ' \'7. Libraries\': [Progress_Bar, Plot, Table,\n' + From e78d26fef1b7dde2bb7c682af3ae9edd4a25cdf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= Date: Thu, 28 Nov 2024 00:19:44 +0100 Subject: [PATCH 24/34] Index --- README.md | 2 +- index.html | 6 +++--- parse.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 81a9f2d06..24c40b1aa 100644 --- a/README.md +++ b/README.md @@ -3585,4 +3585,4 @@ Index * **Only available in the [PDF](https://transactions.sendowl.com/products/78175486/4422834F/view).** * **Ctrl+F / ⌘F is usually sufficient.** * **Searching `'#'` on the [webpage](https://gto76.github.io/python-cheatsheet/) will limit the search to the titles.** -* **Click on the `'🔗'` symbol to get a link to specific section.** +* **Click on the title's `'🔗'` symbol to get a link to specific section.** diff --git a/index.html b/index.html index 75852dcb6..3516f5316 100644 --- a/index.html +++ b/index.html @@ -55,7 +55,7 @@ <body> <header> - <aside>November 27, 2024</aside> + <aside>November 28, 2024</aside> <a href="https://gto76.github.io" rel="author">Jure Šorn</a> </header> @@ -2918,12 +2918,12 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment <div><h2 id="index"><a href="#index" name="index">#</a>Index</h2><ul><li><strong>Only available in the <a href="https://transactions.sendowl.com/products/78175486/4422834F/view">PDF</a>.</strong></li> <li><strong>Ctrl+F / ⌘F is usually sufficient.</strong></li> <li><strong>Searching <code class="python hljs"><span class="hljs-string">'#<title>'</span></code> will limit the search to the titles.</strong></li> -<li><strong>Click on the <code class="python hljs"><span class="hljs-string">'#'</span></code> symbol to get a link to specific section.</strong></li> +<li><strong>Click on the title's <code class="python hljs"><span class="hljs-string">'#'</span></code> symbol to get a link to specific section.</strong></li> </ul></div> <footer> - <aside>November 27, 2024</aside> + <aside>November 28, 2024</aside> <a href="https://gto76.github.io" rel="author">Jure Šorn</a> </footer> diff --git a/parse.js b/parse.js index 3f8261722..dc4a9acc8 100755 --- a/parse.js +++ b/parse.js @@ -337,7 +337,7 @@ const INDEX = '<li><strong>Only available in the <a href="https://transactions.sendowl.com/products/78175486/4422834F/view">PDF</a>.</strong></li>\n' + '<li><strong>Ctrl+F / ⌘F is usually sufficient.</strong></li>\n' + '<li><strong>Searching <code class="python hljs"><span class="hljs-string">\'#<title>\'</span></code> will limit the search to the titles.</strong></li>\n' + - '<li><strong>Click on the <code class="python hljs"><span class="hljs-string">\'#\'</span></code> symbol to get a link to specific section.</strong></li>\n'; + '<li><strong>Click on the title\'s <code class="python hljs"><span class="hljs-string">\'#\'</span></code> symbol to get a link to specific section.</strong></li>\n'; const DIAGRAM_1_A = From 730877a7b3ce5ac73dc1eb53142d9a1d57544f4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= <sornjure@gmail.com> Date: Thu, 28 Nov 2024 14:47:20 +0100 Subject: [PATCH 25/34] SQLite, Pandas --- README.md | 4 ++-- index.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 24c40b1aa..551573254 100644 --- a/README.md +++ b/README.md @@ -1918,7 +1918,7 @@ with <conn>: # Exits the block with commit() o <conn>.execute('<query>', <dict/namedtuple>) # Replaces ':<key>'s with values. <conn>.executemany('<query>', <coll_of_coll>) # Runs execute() multiple times. ``` -* **Passed values can be of type str, int, float, bytes, None, or bool (stored as 0 or 1).** +* **Passed values can be of type str, int, float, bytes, None, or bool (stored as 1 or 0).** ### Example **Values are not actually saved in this example because `'conn.commit()'` is omitted!** @@ -3182,7 +3182,7 @@ Name: a, dtype: int64 ``` ```python -<S> = <S> > <el/S> # Returns a Series of bools. +<S> = <S> > <el/S> # Returns S of bools. Pairs items by keys. <S> = <S> + <el/S> # Items with non-matching keys get value NaN. ``` diff --git a/index.html b/index.html index 3516f5316..a1d6d8cfd 100644 --- a/index.html +++ b/index.html @@ -1587,7 +1587,7 @@ </code></pre></div> <ul> -<li><strong>Passed values can be of type str, int, float, bytes, None, or bool (stored as 0 or 1).</strong></li> +<li><strong>Passed values can be of type str, int, float, bytes, None, or bool (stored as 1 or 0).</strong></li> </ul> <div><h3 id="example-1">Example</h3><p><strong>Values are not actually saved in this example because <code class="python hljs"><span class="hljs-string">'conn.commit()'</span></code> is omitted!</strong></p><pre><code class="python language-python hljs"><span class="hljs-meta">>>> </span>conn = sqlite3.connect(<span class="hljs-string">'test.db'</span>) <span class="hljs-meta">>>> </span>conn.execute(<span class="hljs-string">'CREATE TABLE person (person_id INTEGER PRIMARY KEY, name, height)'</span>) @@ -2592,7 +2592,7 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment <S> = <S>[coll_of_keys/coll_of_i] <span class="hljs-comment"># Or: <S>[key/i : key/i]</span> <S> = <S>[bools] <span class="hljs-comment"># Or: <S>.loc/iloc[bools]</span> </code></pre> -<pre><code class="python language-python hljs"><S> = <S> > <el/S> <span class="hljs-comment"># Returns a Series of bools.</span> +<pre><code class="python language-python hljs"><S> = <S> > <el/S> <span class="hljs-comment"># Returns S of bools. Pairs items by keys.</span> <S> = <S> + <el/S> <span class="hljs-comment"># Items with non-matching keys get value NaN.</span> </code></pre> <pre><code class="python language-python hljs"><S> = pd.concat(<coll_of_S>) <span class="hljs-comment"># Concats multiple series into one long Series.</span> From 724b2edf0b26a7e6be0adc0f40b917e28932b383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= <sornjure@gmail.com> Date: Thu, 28 Nov 2024 14:54:28 +0100 Subject: [PATCH 26/34] Pandas --- README.md | 2 +- index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 551573254..28f50eb3d 100644 --- a/README.md +++ b/README.md @@ -3268,7 +3268,7 @@ b 3 4 ``` ```python -<DF> = <DF>.head/tail/sample(<int>) # Returns first, last, or random n elements. +<DF> = <DF>.head/tail/sample(<int>) # Returns first, last, or random n rows. <DF> = <DF>.describe() # Describes columns. Also shape, info(), corr(). <DF> = <DF>.query('<query>') # Filters rows with e.g. 'col_1 == val_1 and …'. ``` diff --git a/index.html b/index.html index a1d6d8cfd..e332aa241 100644 --- a/index.html +++ b/index.html @@ -2658,7 +2658,7 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment <DF> = <DF>.sort_index(ascending=<span class="hljs-keyword">True</span>) <span class="hljs-comment"># Sorts rows by row keys. Use `axis=1` for cols.</span> <DF> = <DF>.sort_values(col_key/s) <span class="hljs-comment"># Sorts rows by passed column/s. Also `axis=1`.</span> </code></pre> -<pre><code class="python language-python hljs"><DF> = <DF>.head/tail/sample(<int>) <span class="hljs-comment"># Returns first, last, or random n elements.</span> +<pre><code class="python language-python hljs"><DF> = <DF>.head/tail/sample(<int>) <span class="hljs-comment"># Returns first, last, or random n rows.</span> <DF> = <DF>.describe() <span class="hljs-comment"># Describes columns. Also shape, info(), corr().</span> <DF> = <DF>.query(<span class="hljs-string">'<query>'</span>) <span class="hljs-comment"># Filters rows with e.g. 'col_1 == val_1 and …'.</span> </code></pre> From 381dc91c9c9fcbcb84d49034dacdc47500f81b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= <sornjure@gmail.com> Date: Thu, 28 Nov 2024 15:38:01 +0100 Subject: [PATCH 27/34] Introspection --- README.md | 2 +- index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 28f50eb3d..804ed1921 100644 --- a/README.md +++ b/README.md @@ -2235,7 +2235,7 @@ Introspection ``` ```python -<list> = dir(<obj>) # Returns names of all object's attributes (incl. methods). +<list> = dir(<obj>) # Returns names of object's attributes (including methods). <dict> = vars(<obj>) # Returns dict of writable attributes. Also <obj>.__dict__. <bool> = hasattr(<obj>, '<name>') # Checks if object possesses attribute with passed name. value = getattr(<obj>, '<name>') # Returns object's attribute or raises AttributeError. diff --git a/index.html b/index.html index e332aa241..c2f9bfa5d 100644 --- a/index.html +++ b/index.html @@ -1831,7 +1831,7 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment <dict> = globals() <span class="hljs-comment"># Dict of global names and their objects, e.g. __builtin__.</span> </code></pre></div> -<pre><code class="python language-python hljs"><list> = dir(<obj>) <span class="hljs-comment"># Returns names of all object's attributes (incl. methods).</span> +<pre><code class="python language-python hljs"><list> = dir(<obj>) <span class="hljs-comment"># Returns names of object's attributes (including methods).</span> <dict> = vars(<obj>) <span class="hljs-comment"># Returns dict of writable attributes. Also <obj>.__dict__.</span> <bool> = hasattr(<obj>, <span class="hljs-string">'<name>'</span>) <span class="hljs-comment"># Checks if object possesses attribute with passed name.</span> value = getattr(<obj>, <span class="hljs-string">'<name>'</span>) <span class="hljs-comment"># Returns object's attribute or raises AttributeError.</span> From 12fe5a0de6dc0ef23ec21c60e6a63cfc1f10c9ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= <sornjure@gmail.com> Date: Thu, 28 Nov 2024 17:01:48 +0100 Subject: [PATCH 28/34] Pandas --- README.md | 8 ++++---- index.html | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 804ed1921..55517d811 100644 --- a/README.md +++ b/README.md @@ -3164,8 +3164,8 @@ Name: a, dtype: int64 ``` ```python -<S> = pd.Series(<list>) # Assigns RangeIndex starting at 0. -<S> = pd.Series(<dict>) # Takes dictionary's keys for index. +<S> = pd.Series(<list>) # Creates index from list's indices. +<S> = pd.Series(<dict>) # Creates index from dictionary's keys. <S> = pd.Series(<dict/Series>, index=<list>) # Only keeps items with keys specified in index. ``` @@ -3193,7 +3193,7 @@ Name: a, dtype: int64 ``` ```python -<S>.plot.line/area/bar/pie/hist() # Generates a Matplotlib plot. +<S>.plot.line/area/bar/pie/hist() # Generates a plot. Accepts `title=<str>`. plt.show() # Displays the plot. Also plt.savefig(<path>). ``` * **Indexing objects can't be tuples because `'obj[x, y]'` is converted to `'obj[(x, y)]'`!** @@ -3269,7 +3269,7 @@ b 3 4 ```python <DF> = <DF>.head/tail/sample(<int>) # Returns first, last, or random n rows. -<DF> = <DF>.describe() # Describes columns. Also shape, info(), corr(). +<DF> = <DF>.describe() # Describes columns. Also info(), corr(), shape. <DF> = <DF>.query('<query>') # Filters rows with e.g. 'col_1 == val_1 and …'. ``` diff --git a/index.html b/index.html index c2f9bfa5d..53ccff7d7 100644 --- a/index.html +++ b/index.html @@ -2580,8 +2580,8 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment </code></pre></div> -<pre><code class="python language-python hljs"><S> = pd.Series(<list>) <span class="hljs-comment"># Assigns RangeIndex starting at 0.</span> -<S> = pd.Series(<dict>) <span class="hljs-comment"># Takes dictionary's keys for index.</span> +<pre><code class="python language-python hljs"><S> = pd.Series(<list>) <span class="hljs-comment"># Creates index from list's indices.</span> +<S> = pd.Series(<dict>) <span class="hljs-comment"># Creates index from dictionary's keys.</span> <S> = pd.Series(<dict/Series>, index=<list>) <span class="hljs-comment"># Only keeps items with keys specified in index.</span> </code></pre> <pre><code class="python language-python hljs"><el> = <S>.loc[key] <span class="hljs-comment"># Or: <S>.iloc[i]</span> @@ -2599,7 +2599,7 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment <S> = <S>.combine_first(<S>) <span class="hljs-comment"># Adds items that are not yet present.</span> <S>.update(<S>) <span class="hljs-comment"># Updates items that are already present.</span> </code></pre> -<pre><code class="python language-python hljs"><S>.plot.line/area/bar/pie/hist() <span class="hljs-comment"># Generates a Matplotlib plot.</span> +<pre><code class="python language-python hljs"><S>.plot.line/area/bar/pie/hist() <span class="hljs-comment"># Generates a plot. Accepts `title=<str>`.</span> plt.show() <span class="hljs-comment"># Displays the plot. Also plt.savefig(<path>).</span> </code></pre> <ul> @@ -2659,7 +2659,7 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment <DF> = <DF>.sort_values(col_key/s) <span class="hljs-comment"># Sorts rows by passed column/s. Also `axis=1`.</span> </code></pre> <pre><code class="python language-python hljs"><DF> = <DF>.head/tail/sample(<int>) <span class="hljs-comment"># Returns first, last, or random n rows.</span> -<DF> = <DF>.describe() <span class="hljs-comment"># Describes columns. Also shape, info(), corr().</span> +<DF> = <DF>.describe() <span class="hljs-comment"># Describes columns. Also info(), corr(), shape.</span> <DF> = <DF>.query(<span class="hljs-string">'<query>'</span>) <span class="hljs-comment"># Filters rows with e.g. 'col_1 == val_1 and …'.</span> </code></pre> <pre><code class="python language-python hljs"><DF>.plot.line/area/bar/scatter(x=col_key, …) <span class="hljs-comment"># `y=col_key/s`. Also hist/box(by=col_key).</span> From a2b9ed50c6e390ac0c202c00fb9f08b89174b3d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= <sornjure@gmail.com> Date: Thu, 28 Nov 2024 17:09:03 +0100 Subject: [PATCH 29/34] Regex --- README.md | 2 +- index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 55517d811..6fb8f028b 100644 --- a/README.md +++ b/README.md @@ -391,7 +391,7 @@ import re '\w' == '[a-zA-Z0-9_]' # Also [ª²³…]. Matches an alphanumeric or _. '\s' == '[ \t\n\r\f\v]' # Also [\x1c-\x1f…]. Matches a whitespace. ``` -* **By default, decimal characters and alphanumerics from all alphabets are matched unless `'flags=re.ASCII'` is used. It restricts special sequence matches to the first 128 Unicode characters and also prevents `'\s'` from accepting `'\x1c'`, `'\x1d'`, `'\x1e'` and `'\x1f'` (the so-called information separators that divide text into files, tables, rows and fields).** +* **By default, decimal characters and alphanumerics from all alphabets are matched unless `'flags=re.ASCII'` is used. It restricts special sequence matches to the first 128 Unicode characters and also prevents `'\s'` from accepting `'\x1c'`, `'\x1d'`, `'\x1e'` and `'\x1f'` (non-printable characters that divide text into files, tables, rows and fields, respectively).** * **Use a capital letter for negation (all non-ASCII characters will be matched when used in combination with ASCII flag).** diff --git a/index.html b/index.html index 53ccff7d7..4b5fd7066 100644 --- a/index.html +++ b/index.html @@ -360,7 +360,7 @@ </code></pre></div> <ul> -<li><strong>By default, decimal characters and alphanumerics from all alphabets are matched unless <code class="python hljs"><span class="hljs-string">'flags=re.ASCII'</span></code> is used. It restricts special sequence matches to the first 128 Unicode characters and also prevents <code class="python hljs"><span class="hljs-string">'\s'</span></code> from accepting <code class="python hljs"><span class="hljs-string">'\x1c'</span></code>, <code class="python hljs"><span class="hljs-string">'\x1d'</span></code>, <code class="python hljs"><span class="hljs-string">'\x1e'</span></code> and <code class="python hljs"><span class="hljs-string">'\x1f'</span></code> (the so-called information separators that divide text into files, tables, rows and fields).</strong></li> +<li><strong>By default, decimal characters and alphanumerics from all alphabets are matched unless <code class="python hljs"><span class="hljs-string">'flags=re.ASCII'</span></code> is used. It restricts special sequence matches to the first 128 Unicode characters and also prevents <code class="python hljs"><span class="hljs-string">'\s'</span></code> from accepting <code class="python hljs"><span class="hljs-string">'\x1c'</span></code>, <code class="python hljs"><span class="hljs-string">'\x1d'</span></code>, <code class="python hljs"><span class="hljs-string">'\x1e'</span></code> and <code class="python hljs"><span class="hljs-string">'\x1f'</span></code> (non-printable characters that divide text into files, tables, rows and fields, respectively).</strong></li> <li><strong>Use a capital letter for negation (all non-ASCII characters will be matched when used in combination with ASCII flag).</strong></li> </ul> <div><h2 id="format"><a href="#format" name="format">#</a>Format</h2><pre><code class="python hljs"><str> = <span class="hljs-string">f'<span class="hljs-subst">{<el_1>}</span>, <span class="hljs-subst">{<el_2>}</span>'</span> <span class="hljs-comment"># Curly brackets can also contain expressions.</span> From 519ac14ecb28477e0b16769a03d9939d92725efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= <sornjure@gmail.com> Date: Thu, 28 Nov 2024 23:46:43 +0100 Subject: [PATCH 30/34] Decorator --- README.md | 2 +- index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6fb8f028b..084082ce8 100644 --- a/README.md +++ b/README.md @@ -932,7 +932,7 @@ from functools import cache def fib(n): return n if n < 2 else fib(n-2) + fib(n-1) ``` -* **Potential problem with cache is that it can grow indefinitely. To clear stored return values run `'fib.cache_clear()'`, or use `'@lru_cache(maxsize=<int>)'` decorator instead.** +* **Potential problem with cache is that it can grow indefinitely. To clear stored values run `'fib.cache_clear()'`, or use `'@lru_cache(maxsize=<int>)'` decorator instead.** * **CPython interpreter limits recursion depth to 3000 by default. To increase it run `'sys.setrecursionlimit(<int>)'`.** ### Parametrized Decorator diff --git a/index.html b/index.html index 4b5fd7066..263d07d81 100644 --- a/index.html +++ b/index.html @@ -778,7 +778,7 @@ <ul> -<li><strong>Potential problem with cache is that it can grow indefinitely. To clear stored return values run <code class="python hljs"><span class="hljs-string">'fib.cache_clear()'</span></code>, or use <code class="python hljs"><span class="hljs-string">'@lru_cache(maxsize=<int>)'</span></code> decorator instead.</strong></li> +<li><strong>Potential problem with cache is that it can grow indefinitely. To clear stored values run <code class="python hljs"><span class="hljs-string">'fib.cache_clear()'</span></code>, or use <code class="python hljs"><span class="hljs-string">'@lru_cache(maxsize=<int>)'</span></code> decorator instead.</strong></li> <li><strong>CPython interpreter limits recursion depth to 3000 by default. To increase it run <code class="python hljs"><span class="hljs-string">'sys.setrecursionlimit(<int>)'</span></code>.</strong></li> </ul> <div><h3 id="parametrizeddecorator">Parametrized Decorator</h3><p><strong>A decorator that accepts arguments and returns a normal decorator that accepts a function.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> wraps From 0ff16b3ccdceedbd3bc4c7863b038647cf6c5ea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= <sornjure@gmail.com> Date: Fri, 29 Nov 2024 13:37:32 +0100 Subject: [PATCH 31/34] Pandas --- README.md | 1 + index.html | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 084082ce8..390241278 100644 --- a/README.md +++ b/README.md @@ -3375,6 +3375,7 @@ c 6 7 ```python <GB> = <DF>.groupby(col_key/s) # Splits DF into groups based on passed column. <DF> = <GB>.apply(<func>) # Maps each group. Func can return DF, S or el. +<DF> = <GB>.filter(<func>) # Drops a group if function returns False. <DF> = <GB>.get_group(<el>) # Selects a group by grouping column's value. <S> = <GB>.size() # S of group sizes. Same keys as get_group(). <GB> = <GB>[col_key] # Single column GB. All operations return S. diff --git a/index.html b/index.html index 263d07d81..bf3ec8ca6 100644 --- a/index.html +++ b/index.html @@ -55,7 +55,7 @@ <body> <header> - <aside>November 28, 2024</aside> + <aside>November 29, 2024</aside> <a href="https://gto76.github.io" rel="author">Jure Šorn</a> </header> @@ -2747,6 +2747,7 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment </ul> <div><h3 id="groupby">GroupBy</h3><p><strong>Object that groups together rows of a dataframe based on the value of the passed column.</strong></p><pre><code class="python language-python hljs"><GB> = <DF>.groupby(col_key/s) <span class="hljs-comment"># Splits DF into groups based on passed column.</span> <DF> = <GB>.apply(<func>) <span class="hljs-comment"># Maps each group. Func can return DF, S or el.</span> +<DF> = <GB>.filter(<func>) <span class="hljs-comment"># Drops a group if function returns False.</span> <DF> = <GB>.get_group(<el>) <span class="hljs-comment"># Selects a group by grouping column's value.</span> <S> = <GB>.size() <span class="hljs-comment"># S of group sizes. Same keys as get_group().</span> <GB> = <GB>[col_key] <span class="hljs-comment"># Single column GB. All operations return S.</span> @@ -2923,7 +2924,7 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment <footer> - <aside>November 28, 2024</aside> + <aside>November 29, 2024</aside> <a href="https://gto76.github.io" rel="author">Jure Šorn</a> </footer> From 767c4ed87abda73f8f70222a2ac6b39a9b71a6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= <sornjure@gmail.com> Date: Fri, 29 Nov 2024 16:15:07 +0100 Subject: [PATCH 32/34] Operator --- README.md | 2 +- index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 390241278..dd5ea9d2f 100644 --- a/README.md +++ b/README.md @@ -2103,7 +2103,7 @@ from collections import deque Operator -------- -**Module of functions that provide the functionality of operators. Functions are ordered and grouped by operator precedence from least to most binding. Logical and arithmetic operators in rows 1, 3 and 5 are also ordered by precedence within a group.** +**Module of functions that provide the functionality of operators. Functions are ordered and grouped by operator precedence—from least to most binding. Logical and arithmetic operators in rows 1, 3 and 5 are also ordered by precedence within a group.** ```python import operator as op ``` diff --git a/index.html b/index.html index bf3ec8ca6..0af9b79c7 100644 --- a/index.html +++ b/index.html @@ -1724,7 +1724,7 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment <deque>.rotate(n=<span class="hljs-number">1</span>) <span class="hljs-comment"># Last element becomes first.</span> <el> = <deque>.popleft() <span class="hljs-comment"># Raises IndexError if deque is empty.</span> </code></pre> -<div><h2 id="operator"><a href="#operator" name="operator">#</a>Operator</h2><p><strong>Module of functions that provide the functionality of operators. Functions are ordered and grouped by operator precedence from least to most binding. Logical and arithmetic operators in rows 1, 3 and 5 are also ordered by precedence within a group.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> operator <span class="hljs-keyword">as</span> op +<div><h2 id="operator"><a href="#operator" name="operator">#</a>Operator</h2><p><strong>Module of functions that provide the functionality of operators. Functions are ordered and grouped by operator precedence—from least to most binding. Logical and arithmetic operators in rows 1, 3 and 5 are also ordered by precedence within a group.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> operator <span class="hljs-keyword">as</span> op </code></pre></div> From ce7e1049605ba4888afe9f9e0c3507ca37848704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= <sornjure@gmail.com> Date: Fri, 29 Nov 2024 18:12:44 +0100 Subject: [PATCH 33/34] Index --- README.md | 2 +- index.html | 2 +- parse.js | 2 +- pdf/remove_links.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dd5ea9d2f..3f6f13bb7 100644 --- a/README.md +++ b/README.md @@ -3586,4 +3586,4 @@ Index * **Only available in the [PDF](https://transactions.sendowl.com/products/78175486/4422834F/view).** * **Ctrl+F / ⌘F is usually sufficient.** * **Searching `'#<title>'` on the [webpage](https://gto76.github.io/python-cheatsheet/) will limit the search to the titles.** -* **Click on the title's `'🔗'` symbol to get a link to specific section.** +* **Click on the title's `'🔗'` to get a link to its section.** diff --git a/index.html b/index.html index 0af9b79c7..cc20b6047 100644 --- a/index.html +++ b/index.html @@ -2919,7 +2919,7 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment <div><h2 id="index"><a href="#index" name="index">#</a>Index</h2><ul><li><strong>Only available in the <a href="https://transactions.sendowl.com/products/78175486/4422834F/view">PDF</a>.</strong></li> <li><strong>Ctrl+F / ⌘F is usually sufficient.</strong></li> <li><strong>Searching <code class="python hljs"><span class="hljs-string">'#<title>'</span></code> will limit the search to the titles.</strong></li> -<li><strong>Click on the title's <code class="python hljs"><span class="hljs-string">'#'</span></code> symbol to get a link to specific section.</strong></li> +<li><strong>Click on the title's <code class="python hljs"><span class="hljs-string">'#'</span></code> to get a link to its section.</strong></li> </ul></div> diff --git a/parse.js b/parse.js index dc4a9acc8..16488b508 100755 --- a/parse.js +++ b/parse.js @@ -337,7 +337,7 @@ const INDEX = '<li><strong>Only available in the <a href="https://transactions.sendowl.com/products/78175486/4422834F/view">PDF</a>.</strong></li>\n' + '<li><strong>Ctrl+F / ⌘F is usually sufficient.</strong></li>\n' + '<li><strong>Searching <code class="python hljs"><span class="hljs-string">\'#<title>\'</span></code> will limit the search to the titles.</strong></li>\n' + - '<li><strong>Click on the title\'s <code class="python hljs"><span class="hljs-string">\'#\'</span></code> symbol to get a link to specific section.</strong></li>\n'; + '<li><strong>Click on the title\'s <code class="python hljs"><span class="hljs-string">\'#\'</span></code> to get a link to its section.</strong></li>\n'; const DIAGRAM_1_A = diff --git a/pdf/remove_links.py b/pdf/remove_links.py index 329238d38..65fec859b 100755 --- a/pdf/remove_links.py +++ b/pdf/remove_links.py @@ -8,7 +8,7 @@ MATCHES = { '<strong>For details about sort(), sorted(), min() and max() see <a href="#sortable">sortable</a>.</strong>': '<strong>For details about sort(), sorted(), min() and max() see sortable (p. 16).</strong>', - '<strong>Module <a href="#operator">operator</a> has function itemgetter() that can replace listed <a href="#lambda">lambdas</a>.</strong>': '<strong>Module \'operator\' has function itemgetter() that can replace listed lambdas (p. 11, 31).</strong>', + '<strong>Module <a href="#operator">operator</a> has function itemgetter() that can replace listed <a href="#lambda">lambdas</a>.</strong>': '<strong>Module \'operator\' (p. 31) has function itemgetter() that can replace listed lambdas (p. 11).</strong>', '<strong>This text uses the term \'collection\' instead of \'iterable\'. For rationale see <a href="#collection">collection</a>.</strong>': '<strong>This text uses the term \'collection\' instead of \'iterable\'. For rationale see collection (p. 18).</strong>', '<strong>Adding <code class="python hljs"><span class="hljs-string">\'!r\'</span></code> to the expression converts object to string by calling its <a href="#class">repr()</a> method.</strong>': '<strong>Adding <code class="python hljs"><span class="hljs-string">\'!r\'</span></code> to the expression converts object to string by calling its repr() method.</strong>', '<strong>It can be any <a href="#callable">callable</a>, but is usually implemented as a function that returns a <a href="#closure">closure</a>.</strong>': '<strong>It can be any callable, but is usually implemented as a function that returns a closure.</strong>', From 7daf56e3fdfccc9b1aff43a004bed0e3356e0a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jure=20=C5=A0orn?= <sornjure@gmail.com> Date: Fri, 29 Nov 2024 22:23:25 +0100 Subject: [PATCH 34/34] Updated index --- pdf/index_for_pdf.html | 26 +++++++++++++------------- pdf/index_for_pdf_print.html | 16 ++++++++-------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/pdf/index_for_pdf.html b/pdf/index_for_pdf.html index 44050adcc..86a2722bb 100644 --- a/pdf/index_for_pdf.html +++ b/pdf/index_for_pdf.html @@ -57,7 +57,7 @@ <h3 id="g">G</h3> <p><strong>games, <a href="#runsaterminalgamewhereyoucontrolanasteriskthatmustavoidnumbers">33</a>, <a href="#pygame">42</a>-<a href="#basicmariobrothersexample">43</a></strong><br> <strong>generators, <a href="#generator">4</a>, <a href="#comprehensions">11</a>, <a href="#iterator-1">17</a></strong><br> <strong>global keyword, <a href="#nonlocal">12</a></strong><br> -<strong>gui, <a href="#guiapp">35</a></strong> </p> +<strong>gui app, <a href="#guiapp">35</a></strong> </p> <h3 id="h">H</h3> <p><strong>hashable, <a href="#dataclass">15</a>, <a href="#hashable">16</a></strong><br> <strong>hexadecimal representation, <a href="#ints">7</a>, <a href="#binhex">8</a>, <a href="#encode-1">28</a></strong> </p> @@ -67,7 +67,7 @@ <h3 id="i">I</h3> <strong>inline, <a href="#otheruses">11</a>, <a href="#dataclass">15</a>, <a href="#inline-1">20</a></strong><br> <strong>input function, <a href="#input">22</a></strong><br> <strong>introspection, <a href="#exceptionobject">21</a>, <a href="#introspection">31</a></strong><br> -<strong>ints, <a href="#abstractbaseclasses">4</a>, <a href="#ints">7</a>, <a href="#random">8</a>, <a href="#encode-1">28</a></strong><br> +<strong>ints, <a href="#abstractbaseclasses">4</a>, <a href="#ints">7</a>-<a href="#random">8</a>, <a href="#encode-1">28</a></strong><br> <strong>is operator, <a href="#comparable">16</a>, <a href="#operator">30</a></strong><br> <strong>iterable, <a href="#abstractbaseclasses">4</a>, <a href="#iterable">18</a>, <a href="#tableofrequiredandautomaticallyavailablespecialmethods">19</a></strong><br> <strong>iterator, <a href="#enumerate">3</a>-<a href="#generator">4</a>, <a href="#comprehensions">11</a>, <a href="#iterator-1">17</a></strong><br> @@ -76,24 +76,24 @@ <h3 id="j">J</h3> <p><strong>json, <a href="#json">25</a>, <a href="#restrequest">36</a>, <a href="#dataframeencodedecode">46</a></strong> </p> <h3 id="l">L</h3> <p><strong>lambda, <a href="#lambda">11</a></strong><br> -<strong>lists, <a href="#list">1</a>-<a href="#list">2</a>, <a href="#abstractbaseclasses">4</a>, <a href="#otheruses">11</a>, <a href="#sequence">18</a>-<a href="#tableofrequiredandautomaticallyavailablespecialmethods">19</a>, <a href="#collectionsandtheirexceptions">21</a></strong><br> +<strong>lists, <a href="#list">1</a>-<a href="#list">2</a>, <a href="#abstractbaseclasses">4</a>, <a href="#otheruses">11</a>, <a href="#sequence">18</a>-<a href="#abcsequence">19</a>, <a href="#collectionsandtheirexceptions">21</a></strong><br> <strong>locale module, <a href="#sortable">16</a></strong><br> <strong>logging, <a href="#logging">31</a></strong> </p> <h3 id="m">M</h3> <p><strong>main function, <a href="#main">1</a>, <a href="#basicscripttemplate">49</a></strong><br> <strong>match statement, <a href="#matchstatement">30</a></strong><br> -<strong>matplotlib library, <a href="#plot">34</a>, <a href="#series">44</a>, <a href="#dataframeencodedecode">46</a></strong><br> +<strong>matplotlib library, <a href="#plot">34</a>, <a href="#pandas">44</a>, <a href="#dataframe">45</a></strong><br> <strong>map function, <a href="#mapfilterreduce">11</a>, <a href="#operator">30</a></strong><br> <strong>math module, <a href="#numbers">7</a></strong><br> <strong>memoryviews, <a href="#memoryview">29</a></strong><br> <strong>module, <a href="#imports">12</a></strong> </p> <h3 id="n">N</h3> -<p><strong>namedtuples, <a href="#namedtuple">3</a></strong><br> +<p><strong>namedtuples, <a href="#namedtuple">3</a>, <a href="#example">6</a></strong><br> <strong>nonlocal keyword, <a href="#nonlocal">12</a></strong><br> <strong>numbers, <a href="#abstractbaseclasses">4</a>, <a href="#numbers-1">6</a>-<a href="#random">8</a></strong><br> -<strong>numpy library, <a href="#numpy">37</a>-<a href="#indexing">38</a></strong> </p> +<strong>numpy library, <a href="#numpy">37</a>-<a href="#indexing">38</a>, <a href="#image">39</a>, <a href="#series">44</a></strong> </p> <h3 id="o">O</h3> -<p><strong>open function, <a href="#contextmanager">17</a>, <a href="#open">22</a>-<a href="#modes">23</a>, <a href="#readobjectfromjsonfile">25</a>, <a href="#readrowsfromcsvfile">26</a>, <a href="#readbytesfromfile">28</a></strong><br> +<p><strong>open function, <a href="#contextmanager">17</a>, <a href="#open">22</a>-<a href="#modes">23</a>, <a href="#readcollectionfromjsonfile">25</a>, <a href="#readrowsfromcsvfile">26</a>, <a href="#readbytesfromfile">28</a></strong><br> <strong>operator module, <a href="#operator">30</a></strong><br> <strong>os commands, <a href="#paths">23</a>-<a href="#shellcommands">25</a>, <a href="#runsabasicfileexplorerintheconsole">34</a></strong> </p> <h3 id="p">P</h3> @@ -102,16 +102,16 @@ <h3 id="p">P</h3> <strong>paths, <a href="#paths">23</a>-<a href="#oscommands">24</a>, <a href="#runsabasicfileexplorerintheconsole">34</a></strong><br> <strong>pickle module, <a href="#pickle">25</a></strong><br> <strong>pillow library, <a href="#image">39</a>-<a href="#animation">40</a></strong><br> -<strong>plotting, <a href="#plot">34</a>, <a href="#series">44</a>, <a href="#dataframeencodedecode">46</a>, <a href="#plotly">47</a>-<a href="#displaysamultiaxislinechartoftotalcoronaviruscasesandchangesinpricesofbitcoindowjonesandgold">48</a></strong><br> +<strong>plotting, <a href="#plot">34</a>, <a href="#pandas">44</a>, <a href="#dataframe">45</a>, <a href="#plotly">47</a>-<a href="#displaysamultiaxislinechartoftotalcoronaviruscasesandchangesinpricesofbitcoindowjonesandgold">48</a></strong><br> <strong>print function, <a href="#class">14</a>, <a href="#print">22</a></strong><br> <strong>profiling, <a href="#profiling">36</a>-<a href="#profilingbyline">37</a></strong><br> <strong>progress bar, <a href="#progressbar">34</a></strong><br> -<strong>property decorator, <a href="#property">15</a></strong><br> +<strong>property decorator, <a href="#property">15</a>, <a href="#hashable">16</a></strong><br> <strong>pygame library, <a href="#pygame">42</a>-<a href="#basicmariobrothersexample">43</a></strong> </p> <h3 id="q">Q</h3> <p><strong>queues, <a href="#deque">29</a>, <a href="#queue">32</a>, <a href="#runsaterminalgamewhereyoucontrolanasteriskthatmustavoidnumbers">33</a></strong> </p> <h3 id="r">R</h3> -<p><strong>random module, <a href="#random">8</a></strong><br> +<p><strong>random module, <a href="#random">8</a>, <a href="#runsaterminalgamewhereyoucontrolanasteriskthatmustavoidnumbers">33</a>, <a href="#addsnoisetothewavfile">41</a></strong><br> <strong>ranges, <a href="#range">3</a>, <a href="#abstractbaseclasses">4</a></strong><br> <strong>recursion, <a href="#cache">13</a>, <a href="#builtinexceptions">21</a></strong><br> <strong>reduce function, <a href="#mapfilterreduce">11</a></strong><br> @@ -138,10 +138,10 @@ <h3 id="t">T</h3> <strong>template, <a href="#format">6</a>, <a href="#dynamicrequest">36</a></strong><br> <strong>threading module, <a href="#threading">32</a>, <a href="#startstheappinitsownthreadandqueriesitsrestapi">36</a></strong><br> <strong>time module, <a href="#progressbar">34</a>, <a href="#profiling">36</a></strong><br> -<strong>tuples, <a href="#tuple">3</a>, <a href="#abstractbaseclasses">4</a>, <a href="#otheruses">11</a>, <a href="#sequence">18</a>-<a href="#tableofrequiredandautomaticallyavailablespecialmethods">19</a></strong><br> -<strong>type, <a href="#type">4</a></strong><br> +<strong>tuples, <a href="#tuple">3</a>, <a href="#abstractbaseclasses">4</a>, <a href="#otheruses">11</a>, <a href="#sequence">18</a>-<a href="#abcsequence">19</a></strong><br> +<strong>type, <a href="#type">4</a>, <a href="#ducktypes">16</a>, <a href="#matchstatement">30</a></strong><br> <strong>type annotations, <a href="#typeannotations">15</a>, <a href="#introspection">31</a></strong> </p> <h3 id="w">W</h3> <p><strong>wave module, <a href="#audio">40</a>-<a href="#writefloatsamplestowavfile">41</a></strong><br> -<strong>web, <a href="#webapp">36</a></strong> </p> +<strong>web app, <a href="#webapp">36</a></strong> </p> </div> \ No newline at end of file diff --git a/pdf/index_for_pdf_print.html b/pdf/index_for_pdf_print.html index 126dbf0ec..41ecf8940 100644 --- a/pdf/index_for_pdf_print.html +++ b/pdf/index_for_pdf_print.html @@ -67,7 +67,7 @@ <h3 id="i">I</h3> <strong>inline, 11, 15, 20</strong><br> <strong>input function, 22</strong><br> <strong>introspection, 21, 31</strong><br> -<strong>ints, 4, 7, 8, 28</strong><br> +<strong>ints, 4, 7-8, 28</strong><br> <strong>is operator, 16, 30</strong><br> <strong>iterable, 4, 18, 19</strong><br> <strong>iterator, 3-4, 11, 17</strong><br> @@ -82,16 +82,16 @@ <h3 id="l">L</h3> <h3 id="m">M</h3> <p><strong>main function, 1, 49</strong><br> <strong>match statement, 30</strong><br> -<strong>matplotlib library, 34, 44, 46</strong><br> +<strong>matplotlib library, 34, 44, 45</strong><br> <strong>map function, 11, 30</strong><br> <strong>math module, 7</strong><br> <strong>memoryviews, 29</strong><br> <strong>module, 12</strong> </p> <h3 id="n">N</h3> -<p><strong>namedtuples, 3</strong><br> +<p><strong>namedtuples, 3, 6</strong><br> <strong>nonlocal keyword, 12</strong><br> <strong>numbers, 4, 6-8</strong><br> -<strong>numpy library, 37-38</strong> </p> +<strong>numpy library, 37-38, 39, 44</strong> </p> <h3 id="o">O</h3> <p><strong>open function, 17, 22-23, 25, 26, 28</strong><br> <strong>operator module, 30</strong><br> @@ -102,16 +102,16 @@ <h3 id="p">P</h3> <strong>paths, 23-24, 34</strong><br> <strong>pickle module, 25</strong><br> <strong>pillow library, 39-40</strong><br> -<strong>plotting, 34, 44, 46, 47-48</strong><br> +<strong>plotting, 34, 44, 45, 47-48</strong><br> <strong>print function, 14, 22</strong><br> <strong>profiling, 36-37</strong><br> <strong>progress bar, 34</strong><br> -<strong>property decorator, 15</strong><br> +<strong>property decorator, 15, 16</strong><br> <strong>pygame library, 42-43</strong> </p> <h3 id="q">Q</h3> <p><strong>queues, 29, 32, 33</strong> </p> <h3 id="r">R</h3> -<p><strong>random module, 8</strong><br> +<p><strong>random module, 8, 33, 41</strong><br> <strong>ranges, 3, 4</strong><br> <strong>recursion, 13, 21</strong><br> <strong>reduce function, 11</strong><br> @@ -139,7 +139,7 @@ <h3 id="t">T</h3> <strong>threading module, 32, 36</strong><br> <strong>time module, 34, 36</strong><br> <strong>tuples, 3, 4, 11, 18-19</strong><br> -<strong>type, 4</strong><br> +<strong>type, 4, 16, 30</strong><br> <strong>type annotations, 15, 31</strong> </p> <h3 id="w">W</h3> <p><strong>wave module, 40-41</strong><br>