From 72ff13968fc20f043fdec657b4cfe385f4666146 Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Thu, 10 Nov 2022 21:32:00 +0100 Subject: Update notebooks/python/python_3_8_to_3_11.ipynb --- notebooks/python/python_3_8_to_3_11.ipynb | 134 ++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 45 deletions(-) diff --git a/notebooks/python/python_3_8_to_3_11.ipynb b/notebooks/python/python_3_8_to_3_11.ipynb index 62fea7d..fd5a3fc 100644 --- a/notebooks/python/python_3_8_to_3_11.ipynb +++ b/notebooks/python/python_3_8_to_3_11.ipynb @@ -17,6 +17,10 @@ "\n", "Released on October 14th, 2019.\n", "\n", + "Latest Python version to support MS Windows <= 7.\n", + "\n", + "By default, the end-of-life is scheduled 5 years after the first release, but can be adjusted by the release manager of each branch.\n", + "\n", "\n", "## Highlights\n", "\n", @@ -31,7 +35,7 @@ }, { "cell_type": "code", - "execution_count": 113, + "execution_count": 1, "id": "a21e461a-8a7c-49d2-8a53-ab63ff2488bb", "metadata": {}, "outputs": [ @@ -47,6 +51,10 @@ "source": [ "# The walrus operator:\n", "\n", + "# \"Guido van Rossum searched through a Dropbox code base and discovered some\n", + "# evidence that programmers value writing fewer lines over shorter lines\" - PEP 572\n", + "\n", + "# example1\n", "my_list = [\"Greham\", \"John\", \"Terry G\", \"Eric\", \"Terry J\", \"Michael\"]\n", "\n", "# Python < 3.8\n", @@ -55,13 +63,25 @@ " print(f\"List is too long ({list_length} elements, expected <= 10)\")\n", "\n", "# while using the walrus operator...\n", - "if (list_length := len(my_list)) > 5:\n", - " print(f\"List is too long ({list_length} elements, expected <= 10)\")" + "if (list_length := len(my_list)) > 5: # fewer but longer lines :)\n", + " print(f\"List is too long ({list_length} elements, expected <= 10)\")\n", + "\n", + "\n", + "# example2\n", + "def expensive_func(x):\n", + " \"\"\"assuming that the function is performing an expensive task\"\"\"\n", + " return x\n", + "\n", + "# reuse the value that's expensive to compute\n", + "[y := expensive_func(8), y**2, y**3]\n", + "\n", + "# share a subexpression between a comprehension filter clause and its output\n", + "filtered_data = [y for x in (2, None, 4) if (y := expensive_func(x)) is not None]" ] }, { "cell_type": "code", - "execution_count": 114, + "execution_count": 2, "id": "99b75989-e991-4f77-a62e-01776f5b606c", "metadata": {}, "outputs": [ @@ -106,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": 115, + "execution_count": 3, "id": "f683072f-c555-404b-b2c9-0d7d3621b118", "metadata": {}, "outputs": [ @@ -165,7 +185,7 @@ }, { "cell_type": "code", - "execution_count": 116, + "execution_count": 4, "id": "a21fdf0a-92d2-4987-93c4-ea68f34f71b3", "metadata": {}, "outputs": [ @@ -175,15 +195,18 @@ "text": [ "2019\n", "('GREHAM', 'John', 'TerryG', 'Eric', 'TerryJ', 'Michael')\n", + "---\n", "Performing a very expensive operation\n", "Performing a very expensive operation\n", - "dataset.string='836278421', id(dataset.string)=36514294704\n", + "dataset.string='836278421', id(dataset.string)=36108881968\n", "Performing a very expensive operation\n", "Performing a very expensive operation\n", - "dataset.string='836278421', id(dataset.string)=36514289520\n", + "dataset.string='836278421', id(dataset.string)=36108885360\n", + "---Doing the same using cached property---\n", "Performing a very expensive operation\n", - "dataset.cached_string='836278421', id(dataset.cached_string)=36514289520\n", - "dataset.cached_string='836278421', id(dataset.cached_string)=36514289520\n", + "dataset.cached_string='836278421', id(dataset.cached_string)=36108885360\n", + "dataset.cached_string='836278421', id(dataset.cached_string)=36108885360\n", + "---\n", "Permutations of 10 things taken 3 at a time: math.perm(10, 3)=720\n", "Combinations of 10 things taken 3 at a time: math.comb(10, 3)=120\n" ] @@ -219,8 +242,6 @@ "\n", "\n", "# new functools.cached_property() decorator, for computed properties cached for the life of the instance\n", - "import statistics\n", - "\n", "class Dataset:\n", " def __init__(self, sequence_of_numbers):\n", " self.data = sequence_of_numbers\n", @@ -237,11 +258,14 @@ " print(\"Performing a very expensive operation\")\n", " return \"\".join(map(str, self.data))\n", "\n", + "print(\"---\")\n", "dataset = Dataset((836, 278, 421))\n", "print(f\"{dataset.string=}, {id(dataset.string)=}\")\n", "print(f\"{dataset.string=}, {id(dataset.string)=}\")\n", + "print(\"---Doing the same using cached property---\")\n", "print(f\"{dataset.cached_string=}, {id(dataset.cached_string)=}\")\n", "print(f\"{dataset.cached_string=}, {id(dataset.cached_string)=}\")\n", + "print(\"---\")\n", "\n", "\n", "# new combinatoric functions math.perm() and math.comb()\n", @@ -260,27 +284,33 @@ "\n", " Released on October 5th, 2020.\n", " \n", + " PEP 602 - CPython adopts an annual release cycle.\n", " \n", - " ## Highlights\n", - " \n", - " - **PEP 584** – Add Union Operators To dict\n", + " Python 3.9 is the last version providing those Python 2 backward compatibility layers,\n", + " to give more time to Python projects maintainers to organize the removal of the Python 2 support and add support for Python 3.9.\n", " \n", - " - **PEP 585** – Type Hinting Generics In Standard Collections - you can now use built-in collection types such as `list` and `dict` as generic types instead of importing the corresponding capitalized types (e.g. `List` or `Dict`) from `typing`\n", + " Python 3.9 uses a new parser, based on PEG (parsing expression gramma) instead of LL (Left to right, performing Leftmost derivation of the sentence). \n", + " The new parser’s performance is roughly comparable to that of the old parser, but the PEG formalism is more flexible than LL when it comes to designing new language features.\n", + "\n", + "COVID-19.\n", + "\n", + "\n", + "## Highlights\n", " \n", - " - **PEP 614** – Relaxing Grammar Restrictions On Decorators\n", + " - **PEP 584** - Add Union Operators To dict\n", " \n", - " - **PEP 616** – String methods to remove prefixes and suffixes\n", + " - **PEP 585** - Type Hinting Generics In Standard Collections - you can now use built-in collection types such as `list` and `dict` as generic types instead of importing the corresponding capitalized types (e.g. `List` or `Dict`) from `typing`\n", " \n", - " - **PEP 593** – Flexible function and variable annotations\n", + " - **PEP 616** - String methods to remove prefixes and suffixes\n", " \n", - " - **PEP 615** – Support for the IANA Time Zone Database in the Standard Library - the new `zoneinfo` module\n", + " - **PEP 615** - Support for the IANA Time Zone Database in the Standard Library - the new `zoneinfo` module\n", " \n", " - Python now gets the absolute path of the script filename specified on the command line (ex: python3 script.py): the `__file__` attribute of the `__main__` module became an absolute path, rather than a relative path. These paths now remain valid after the current directory is changed by `os.chdir()`. As a side effect, the traceback also displays the absolute path for `__main__` module frames in this case." ] }, { "cell_type": "code", - "execution_count": 117, + "execution_count": 5, "id": "1f567f26-3783-4435-bcff-48826ea50404", "metadata": {}, "outputs": [ @@ -310,7 +340,7 @@ }, { "cell_type": "code", - "execution_count": 118, + "execution_count": 6, "id": "3f527469-64c7-4cef-8a4d-ef536c418fa1", "metadata": {}, "outputs": [ @@ -335,6 +365,10 @@ "source": [ "## Other changes\n", "\n", + "- PEP 614 - Relaxing Grammar Restrictions On Decorator\n", + "\n", + "- PEP 593 - Flexible function and variable annotations\n", + "\n", "- The hashlib module can now use *SHA3* hashes and *SHAKE XOF* from *OpenSSL* when available\n", "\n", "- new `math.lcm(*integers)` function while `math.gcd(*integers)` now handles multiple arguments. `fractions.gcd()` is removed\n", @@ -382,7 +416,7 @@ }, { "cell_type": "code", - "execution_count": 119, + "execution_count": 7, "id": "11aaff48-28a3-49f5-86b6-059af6ab534d", "metadata": {}, "outputs": [], @@ -432,7 +466,7 @@ }, { "cell_type": "code", - "execution_count": 120, + "execution_count": 8, "id": "59329225-db92-4eb6-ad1b-b88455e48d50", "metadata": {}, "outputs": [ @@ -442,23 +476,13 @@ "text": [ "Started with: ['the', 'clock']\n" ] - }, - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 120, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ "# PEP 634, PEP 635, PEP 636 - Structural pattern matching\n", "command = \"start the clock\"\n", "# command = input(\"Command: \")\n", - "match command.split():\n", + "match command.split(): # match statement\n", " case [\"start\", *args]:\n", " print(f\"Started with: {args}\")\n", " case [\"stop\"] | [\"quit\"]:\n", @@ -472,7 +496,27 @@ " case _:\n", " print(\"Something completely unexpected happened :)\")\n", "\n", - "\n", + "# __match_args__ can be defined / used in a class in order to select 'matchable' attributes" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "ded7dcfa-24e2-4a1d-8aad-4703a9aa24aa", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ "# PEP 604, PEP 612, PEP 613 - Various typing features\n", "import typing\n", "\n", @@ -497,7 +541,7 @@ "\n", "- the entire `distutils` package is deprecated, to be removed in Python 3.12. Its functionality for specifying package builds has already been completely replaced by third-party packages `setuptools` and `packaging`\n", "\n", - "- new `itertools.pairwise()`\n", + "- new `itertools.pairwise()` (example: `pairwise('ABCDEFG') --> AB BC CD DE EF FG`)\n", "\n", "- `os.path.realpath()` now accepts a strict keyword-only argument. When set to `True`, `OSError` is raised if a path doesn’t exist or a symlink loop is encountered\n", "\n", @@ -517,10 +561,10 @@ "\n", "Released on October 24th, 2022.\n", "\n", + "The first reference implementation (CPython) using C11 instead of C89.\n", "\n", - "## Highlights\n", "\n", - "- The first reference implementation (CPython) using C11 instead of C89\n", + "## Highlights\n", "\n", "- Python 3.11 is between 10-60% faster than Python 3.10. \"On average, we measured a 1.25x speedup on the standard benchmark suite\"\n", "\n", @@ -614,7 +658,7 @@ }, { "cell_type": "code", - "execution_count": 121, + "execution_count": 10, "id": "ef9285ea-2bdb-4fb0-968d-833011fe0724", "metadata": {}, "outputs": [ @@ -658,7 +702,7 @@ }, { "cell_type": "code", - "execution_count": 122, + "execution_count": 11, "id": "c70ce21d-bdf8-4a30-a5a2-c888ab75b92a", "metadata": {}, "outputs": [ @@ -718,7 +762,7 @@ }, { "cell_type": "code", - "execution_count": 123, + "execution_count": 12, "id": "f1f9977c-20f4-4bc1-9fa7-14acd0f16193", "metadata": {}, "outputs": [ @@ -748,7 +792,7 @@ }, { "cell_type": "code", - "execution_count": 124, + "execution_count": 13, "id": "7260ad15-4215-4b48-b6a3-870a14d8079c", "metadata": {}, "outputs": [ @@ -757,7 +801,7 @@ "output_type": "stream", "text": [ "0.0\n", - "+0.0\n" + "0.0\n" ] } ], @@ -770,7 +814,7 @@ "print(f\"{x:z.1f}\")\n", "\n", "x = decimal.Decimal('-.00001')\n", - "print(f\"{x:+z.1f}\")" + "print(f\"{x:-z.1f}\")" ] } ], -- cgit v1.3