From c6ea2d809fb5cce3ce344fb0f65ad9c53563f885 Mon Sep 17 00:00:00 2001 From: Francis Windram Date: Sun, 2 Oct 2022 14:03:12 +0100 Subject: [PATCH 1/3] Move Logging and OOP appendices to main notebook dir --- content/_toc.yml | 5 ++++- ...ging_in_python.ipynb => Appendix_Logging_in_python.ipynb} | 0 ...ng.ipynb => Appendix_Object-oriented-programming-1.ipynb} | 0 ...P2.ipynb => Appendix_Object-oriented-programming-2.ipynb} | 0 4 files changed, 4 insertions(+), 1 deletion(-) rename content/notebooks/{test/Logging_in_python.ipynb => Appendix_Logging_in_python.ipynb} (100%) rename content/notebooks/{test/Object-oriented-programming.ipynb => Appendix_Object-oriented-programming-1.ipynb} (100%) rename content/notebooks/{test/OOP2.ipynb => Appendix_Object-oriented-programming-2.ipynb} (100%) diff --git a/content/_toc.yml b/content/_toc.yml index 9a2d6946..effc4a45 100644 --- a/content/_toc.yml +++ b/content/_toc.yml @@ -30,9 +30,12 @@ parts: - caption: Appendices chapters: - file: notebooks/Appendix-JupyIntro - - file: notebooks/Appendix-Data-Python + - file: notebooks/Appendix-Data-Pytho - file: notebooks/Appendix-Maths - file: notebooks/Appendix-Databases + - file: notebooks/Appendix_Logging_in_python + - file: notebooks/Appendix_Object-oriented-programming-1 + - file: notebooks/Appendix_Object-oriented-programming-2 - file: notebooks/Appendix-NLLS-Python - file: notebooks/Appendix-MiniProj - file: notebooks/Appendix-Assessment diff --git a/content/notebooks/test/Logging_in_python.ipynb b/content/notebooks/Appendix_Logging_in_python.ipynb similarity index 100% rename from content/notebooks/test/Logging_in_python.ipynb rename to content/notebooks/Appendix_Logging_in_python.ipynb diff --git a/content/notebooks/test/Object-oriented-programming.ipynb b/content/notebooks/Appendix_Object-oriented-programming-1.ipynb similarity index 100% rename from content/notebooks/test/Object-oriented-programming.ipynb rename to content/notebooks/Appendix_Object-oriented-programming-1.ipynb diff --git a/content/notebooks/test/OOP2.ipynb b/content/notebooks/Appendix_Object-oriented-programming-2.ipynb similarity index 100% rename from content/notebooks/test/OOP2.ipynb rename to content/notebooks/Appendix_Object-oriented-programming-2.ipynb From 7081a02fadc6c1207643f3e9d0172fe1cc29245a Mon Sep 17 00:00:00 2001 From: Francis Windram Date: Sun, 2 Oct 2022 14:04:46 +0100 Subject: [PATCH 2/3] Fix toc after typo --- content/_toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/_toc.yml b/content/_toc.yml index effc4a45..304a7a5e 100644 --- a/content/_toc.yml +++ b/content/_toc.yml @@ -30,7 +30,7 @@ parts: - caption: Appendices chapters: - file: notebooks/Appendix-JupyIntro - - file: notebooks/Appendix-Data-Pytho + - file: notebooks/Appendix-Data-Python - file: notebooks/Appendix-Maths - file: notebooks/Appendix-Databases - file: notebooks/Appendix_Logging_in_python From 9f907cdd7af9aafc034dd607131d0db855278586 Mon Sep 17 00:00:00 2001 From: Francis Windram Date: Sun, 2 Oct 2022 15:11:06 +0100 Subject: [PATCH 3/3] Update logging tutorial with fixed string formatting as in #22 and #56, and add warning about f-string use in logging. --- .../Appendix_Logging_in_python.ipynb | 180 +++++++++++++----- 1 file changed, 132 insertions(+), 48 deletions(-) diff --git a/content/notebooks/Appendix_Logging_in_python.ipynb b/content/notebooks/Appendix_Logging_in_python.ipynb index bffe8e70..f9cded26 100644 --- a/content/notebooks/Appendix_Logging_in_python.ipynb +++ b/content/notebooks/Appendix_Logging_in_python.ipynb @@ -133,45 +133,46 @@ "text": [ "Training 20 padawan/s\n", "Training padawan 0\n", - "Light = 10, Dark = 3\n", + "Light = 8, Dark = 3\n", "Training padawan 1\n", - "Light = 6, Dark = 1\n", + "Light = 7, Dark = 6\n", "Training padawan 2\n", - "Light = 10, Dark = 6\n", + "Light = 5, Dark = 3\n", "Training padawan 3\n", - "Light = 9, Dark = 0\n", + "Light = 5, Dark = 2\n", "Training padawan 4\n", - "Light = 9, Dark = 2\n", + "Light = 10, Dark = 2\n", "Training padawan 5\n", - "Light = 6, Dark = 4\n", + "Light = 6, Dark = 6\n", "Training padawan 6\n", - "Light = 7, Dark = 5\n", + "Light = 6, Dark = 7\n", + "Padawan has fallen to the dark side.\n", "Training padawan 7\n", - "Light = 10, Dark = 0\n", + "Light = 10, Dark = 7\n", "Training padawan 8\n", - "Light = 5, Dark = 2\n", + "Light = 9, Dark = 2\n", "Training padawan 9\n", - "Light = 9, Dark = 3\n", + "Light = 8, Dark = 6\n", "Training padawan 10\n", - "Light = 7, Dark = 0\n", + "Light = 9, Dark = 2\n", "Training padawan 11\n", - "Light = 5, Dark = 5\n", + "Light = 7, Dark = 2\n", "Training padawan 12\n", - "Light = 6, Dark = 4\n", + "Light = 7, Dark = 6\n", "Training padawan 13\n", - "Light = 10, Dark = 7\n", + "Light = 5, Dark = 2\n", "Training padawan 14\n", - "Light = 6, Dark = 5\n", + "Light = 5, Dark = 2\n", "Training padawan 15\n", - "Light = 9, Dark = 7\n", + "Light = 7, Dark = 2\n", "Training padawan 16\n", - "Light = 10, Dark = 2\n", + "Light = 7, Dark = 0\n", "Training padawan 17\n", - "Light = 5, Dark = 1\n", + "Light = 6, Dark = 4\n", "Training padawan 18\n", - "Light = 6, Dark = 3\n", + "Light = 5, Dark = 1\n", "Training padawan 19\n", - "Light = 5, Dark = 1\n" + "Light = 7, Dark = 1\n" ] } ], @@ -186,11 +187,11 @@ "# Main script\n", "\n", "def train_padawans(n):\n", - " print(\"Training {} padawan/s\".format(n))\n", + " print(f\"Training {n} padawan/s\")\n", " trained_successfully = 0\n", " for i in range(n):\n", " try:\n", - " print(\"Training padawan {}\".format(i))\n", + " print(f\"Training padawan {i}\")\n", " train(i)\n", " trained_successfully += 1\n", " except SithError:\n", @@ -199,7 +200,7 @@ "def train(padawan):\n", " lightpoints = random.randint(5,10)\n", " darkpoints = random.randint(0,7)\n", - " print(\"Light = {}, Dark = {}\".format(lightpoints, darkpoints))\n", + " print(f\"Light = {lightpoints}, Dark = {darkpoints}\")\n", " if darkpoints > lightpoints:\n", " raise SithError\n", " else:\n", @@ -236,7 +237,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now we have done that we can set up the logging format for the messages. These can be formatted like any string, but for now let's get the log messages in the format `2020-09-08 19:16:16,855 - INFO - Log message`" + "Alternatively if we want a logger specific to our script we could initialise one as follows:" ] }, { @@ -244,6 +245,22 @@ "execution_count": 3, "metadata": {}, "outputs": [], + "source": [ + "logger = logging.getLogger(\"MyScript\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we have done that we can set up the logging format for the messages. These can be formatted like any string, but for now let's get the log messages in the format `2020-09-08 19:16:16,855 - INFO - Log message`" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], "source": [ "formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')" ] @@ -259,7 +276,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -275,7 +292,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -292,7 +309,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -308,7 +325,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -327,17 +344,17 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "2020-09-08 21:02:02,428 - INFO - INFO message\n", - "2020-09-08 21:02:02,429 - WARNING - WARNING message\n", - "2020-09-08 21:02:02,429 - ERROR - ERROR message\n", - "2020-09-08 21:02:02,430 - CRITICAL - CRITICAL message\n" + "2022-10-02 15:08:08,988 - INFO - INFO message\n", + "2022-10-02 15:08:08,988 - WARNING - WARNING message\n", + "2022-10-02 15:08:08,989 - ERROR - ERROR message\n", + "2022-10-02 15:08:08,989 - CRITICAL - CRITICAL message\n" ] } ], @@ -360,18 +377,18 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "2020-09-08 21:02:02,435 - DEBUG - DEBUG message\n", - "2020-09-08 21:02:02,436 - INFO - INFO message\n", - "2020-09-08 21:02:02,436 - WARNING - WARNING message\n", - "2020-09-08 21:02:02,437 - ERROR - ERROR message\n", - "2020-09-08 21:02:02,437 - CRITICAL - CRITICAL message\n" + "2022-10-02 15:08:11,254 - DEBUG - DEBUG message\n", + "2022-10-02 15:08:11,255 - INFO - INFO message\n", + "2022-10-02 15:08:11,255 - WARNING - WARNING message\n", + "2022-10-02 15:08:11,255 - ERROR - ERROR message\n", + "2022-10-02 15:08:11,256 - CRITICAL - CRITICAL message\n" ] } ], @@ -397,13 +414,80 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "chandler.setLevel(logging.INFO)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Inserting Variables" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Debug strings are just strings, as such they _can_ be formatted using f-strings as we have done during the course so far." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-10-02 15:08:12,996 - INFO - x = 42\n" + ] + } + ], + "source": [ + "x = 42\n", + "logger.info(f\"{x = }\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However this is actually a bit suboptimal in some cases [see here for more in-depth details](https://blog.pilosus.org/posts/2020/01/24/python-f-strings-in-logging/).\n", + "\n", + "It is therefore best when inputting formatted strings in logging to use the old-style % formatting, and to pass the data to be formatted as an argument to the logger method:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-10-02 15:08:13,537 - INFO - x = 42\n" + ] + } + ], + "source": [ + "logger.info(\"x = %d\", x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This little optimisation makes more difference the more logging calls you make (even ones below the current log level of the handler or logger).\n", + "\n", + "Thus depending on how much you are logging, this little tip could be either a big deal, or a major inconvenience for a minor gain in speed." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -432,14 +516,14 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "2020-09-08 21:02:02,448 - ERROR - An error occurred\n" + "2022-10-02 15:08:15,391 - ERROR - An error occurred\n" ] }, { @@ -475,18 +559,18 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "2020-09-08 21:02:02,455 - ERROR - An error occurred\n", + "2022-10-02 15:08:15,939 - ERROR - An error occurred\n", "Traceback (most recent call last):\n", - " File \"\", line 6, in \n", + " File \"/tmp/ipykernel_16810/2065718702.py\", line 6, in \n", " print(div_by_nsub1(i))\n", - " File \"\", line 2, in div_by_nsub1\n", + " File \"/tmp/ipykernel_16810/2065718702.py\", line 2, in div_by_nsub1\n", " return n/(n-1)\n", "ZeroDivisionError: division by zero\n" ] @@ -670,7 +754,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -684,7 +768,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.2" + "version": "3.10.6" }, "toc": { "base_numbering": 1,