From 0c88c4110db47849e80be1ecc2c9c2b0b9bd2a9c Mon Sep 17 00:00:00 2001 From: SandraVerhagen Date: Fri, 3 Oct 2025 13:33:26 +0200 Subject: [PATCH 1/9] merge updates chpt 3 and 4 in main --- book/.DS_Store | Bin 6148 -> 6148 bytes .../exercise_notebook_4_debugging.ipynb | 42 +++++--------- .../PythonNotebook3_loops.ipynb | 54 ++++++++++++++++-- .../PythonNotebook4_debugging.ipynb | 20 +++---- .../PythonNotebook4_first_page copy.ipynb | 7 ++- 5 files changed, 77 insertions(+), 46 deletions(-) diff --git a/book/.DS_Store b/book/.DS_Store index 92fabb46a95e75cabd07975fea25c1c2fb47fa47..09b04c53217951c9d327c661323158012ca9d88b 100644 GIT binary patch delta 98 zcmZoMXffDe&m_D%sURn_xWvHV8Y2@k3o9Et2gl?frf5A*&UgXo>S|p>Gjl^71zj`q zS{;RILlYAN9R&*`!`fO-4pC)&>!A4ToZP(p-pSXP_mScXxvYDOZFFyeA Cy&7l$ delta 96 zcmZoMXffDe&m_DpsURn_xWvHV8Y2@k3o9Et2m9n8rf5wL&UgW_>S_ZW1#`n%9ffK` y6B7{Iz_PZMlS5Ql-#REhJ0~|Uzhm-kCV9rr$vjLNo0XZLuuN=V-OSGMmmdJo%Nle5 diff --git a/book/exercise_notebooks/exercise_notebook_4_debugging.ipynb b/book/exercise_notebooks/exercise_notebook_4_debugging.ipynb index 7bec943..82510a4 100644 --- a/book/exercise_notebooks/exercise_notebook_4_debugging.ipynb +++ b/book/exercise_notebooks/exercise_notebook_4_debugging.ipynb @@ -42,7 +42,11 @@ "outputs": [], "source": [ "def is_prime(n):\n", - " return True # or False" + " \"\"\" \n", + " Check if a number is prime. The input argument n must be a positive integer.\n", + " The function returns True if n is prime, and False otherwise.\n", + " \"\"\"\n", + " ...\n" ] }, { @@ -54,7 +58,7 @@ "\n", "Use your is_prime() function to create a list of all primes $< 1000$. What is the sum of all primes $< 1000$?\n", "\n", - "Hint: is there a nice way to calculate the sum of the elements in a list?\n", + "Hint: you will need a for loop to fill the list.\n", "\n" ] }, @@ -67,8 +71,8 @@ "prime_list = ...\n", "prime_sum = ...\n", "\n", - "print(prime_list)\n", - "print(prime_sum)" + "print(f'List of primes: {prime_list}\\n')\n", + "print(f'Sum of primes: {prime_sum}')" ] }, { @@ -81,7 +85,7 @@ } }, "source": [ - "
(Fixing) Exercise 4.3

Fix the syntax errors so it prints \"AES\" without removing the variable that holds it. You'll need to fix 2 errors.
" + "
(Fixing) Exercise 4.3

Fix the syntax errors so it prints \"EC&T\" without removing the variable that holds it. You'll need to fix 2 errors.
" ] }, { @@ -91,7 +95,7 @@ "outputs": [], "source": [ "def get_abbreviation():\n", - " my abbreviation = \"AES\"\n", + " my abbreviation = \"EC&T\"\n", " return my_abbreviation\n", " \n", "print(get_abbreviation())" @@ -111,25 +115,14 @@ "\n", "The factorial n! is defined as n! = n * (n - 1) * (n - 2) * ... * 2 * 1. The function uses the fact that if n > 0, n! = n * (n - 1)!. This is an example of a _recursive_ function, a function that calls itself.\n", "\n", - "The code below calls the function \"factorial\" with the number 4 as input. The factorial of 4 is 4 * 3 * 2 * 1, which is 24, but the code below prints 262144. Find and fix the semantic error in this function." + "The code below calls the function factorial with the number 4 as input. The factorial of 4 is $4 \\cdot 3 \\cdot 2 \\cdot 1 = 24$, but the code below prints 262144. Find and fix the error in this function. What kind of error is this (syntax, runtime, semantic)?" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "262144" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "def factorial(x):\n", " \"returns the factorial of x\"\n", @@ -140,13 +133,6 @@ "\n", "factorial(4)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -165,7 +151,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.7" + "version": "3.13.2" }, "latex_envs": { "LaTeX_envs_menu_present": true, diff --git a/book/notebook_3_structures_loops/PythonNotebook3_loops.ipynb b/book/notebook_3_structures_loops/PythonNotebook3_loops.ipynb index b004e1a..b28bdfc 100644 --- a/book/notebook_3_structures_loops/PythonNotebook3_loops.ipynb +++ b/book/notebook_3_structures_loops/PythonNotebook3_loops.ipynb @@ -278,25 +278,57 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "f = [-2, 4, 16, 40, 82, 148]\n" + ] + } + ], "source": [ "x = [0, 1, 2, 3, 4, 5]\n", "f = [x[0] ** 3 + 5*x[0] - 2, x[1] ** 3 + 5*x[1] - 2, x[2] ** 3 + 5*x[2] - 2, x[3] ** 3 + 5*x[3] - 2, x[4] ** 3 + 5*x[4] - 2, x[5] ** 3 + 5*x[5] - 2]\n", "print(f'f = {f }')" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can see above, that a list was created by using the equation for every item in $x$. A more convenient way is to use a for loop, as shown below. This is especially important if you need to cycle over a large number of items/values.\n", + "\n", + "You can see that we first create an empty list $f$; in each cycle of the loop, we will then add a new item to $f$. In order to do so, we use .append (see Section 3.1)." + ] + }, { "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "In this cycle we added f(0) = -2\n", + "In this cycle we added f(1) = 4\n", + "In this cycle we added f(2) = 16\n", + "In this cycle we added f(3) = 40\n", + "In this cycle we added f(4) = 82\n", + "In this cycle we added f(5) = 148\n", + "f(x) = [-2, 4, 16, 40, 82, 148]\n" + ] + } + ], "source": [ "x = [0, 1, 2, 3, 4, 5]\n", "f = []\n", "for i in x:\n", " f.append(x[i] ** 3 + 5*x[i] - 2)\n", + " print(f'In this cycle we added f({x[i]}) = {f[i]}')\n", "print(f'f = {f }')" ] }, @@ -651,7 +683,7 @@ } }, "source": [ - "As you can see, with the help of the continue keyword we managed to skip some of the iterations. Also worth noting that $0$ is divisible by any number, for that reason the calculate_cool_function(i) at i = 0 didn't run." + "As you can see, with the help of the continue keyword we skipped the execution of calculate_cool_function(i)< for all even $i$. Also worth noting that $0$ is divisible by any number, for that reason the calculate_cool_function(i) at i = 0 didn't run." ] }, { @@ -705,6 +737,20 @@ "for i in range(3, 17, 2):\n", " print(f'i is {i}')" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### After this Chapter you should be able to:\n", + "\n", + "- understand the differences between **`list`**, **`tuple`**, and **`dict`**\n", + "- slice lists and tuples\n", + "- use for loops\n", + "- use while loops\n", + "- use break and continue in loops\n", + "- understand range()" + ] } ], "metadata": { diff --git a/book/notebook_4_debugging/PythonNotebook4_debugging.ipynb b/book/notebook_4_debugging/PythonNotebook4_debugging.ipynb index b805833..02b56fe 100644 --- a/book/notebook_4_debugging/PythonNotebook4_debugging.ipynb +++ b/book/notebook_4_debugging/PythonNotebook4_debugging.ipynb @@ -296,20 +296,19 @@ "source": [ "#### After this Chapter you should be able to:\n", "\n", - "- understand the differences between **`list`**, **`tuple`**, and **`dict`**\n", - "- slice lists and tuples\n", - "- use for loops\n", - "- use while loops\n", - "- use break and continue in loops\n", - "- understand range()\n", "- know different types of errors\n", "- have a plan when debugging your code" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "base", "language": "python", "name": "python3" }, @@ -323,7 +322,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.0" + "version": "3.13.2" }, "latex_envs": { "LaTeX_envs_menu_present": true, @@ -342,11 +341,6 @@ "latex_user_defs": false, "report_style_numbering": false, "user_envs_cfg": false - }, - "vscode": { - "interpreter": { - "hash": "1fe2f2b718b1108b9c4176932db8a0ead471245140baaa21ea96a4066683e6b2" - } } }, "nbformat": 4, diff --git a/book/notebook_4_debugging/PythonNotebook4_first_page copy.ipynb b/book/notebook_4_debugging/PythonNotebook4_first_page copy.ipynb index 9a24edb..2a22138 100644 --- a/book/notebook_4_debugging/PythonNotebook4_first_page copy.ipynb +++ b/book/notebook_4_debugging/PythonNotebook4_first_page copy.ipynb @@ -17,7 +17,7 @@ "# 4: Debugging\n", "
\n", "\n", - "In this chapter, we introduce debugging. We cover the three main types of errors—syntax, runtime, and logical—and strategies for identifying and resolving issues in your code. Mastering these topics will refine your problem-solving expertise, laying a strong foundation for tackling complex Python projects. \n", + "In this chapter, we introduce debugging. We cover the three main types of errors—syntax, runtime, and semantic—and strategies for identifying and resolving issues in your code. Mastering these topics will refine your problem-solving expertise, laying a strong foundation for tackling complex Python projects. \n", "\n", "```{admonition} Attention\n", ":class: danger\n", @@ -27,6 +27,11 @@ "+++\n", "```" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] } ], "metadata": { From 7559ea04b426327c74d5ffd988c285f1fdda4b56 Mon Sep 17 00:00:00 2001 From: SandraVerhagen Date: Fri, 3 Oct 2025 13:46:38 +0200 Subject: [PATCH 2/9] updates chpt 3 and 4 (toc file, zip files) --- book/_toc.yml | 8 ++++---- .../exercise_notebook_3_structures_loops.zip | Bin 3740 -> 3733 bytes .../exercise_notebook_4_debugging.zip | Bin 0 -> 1977 bytes 3 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 book/exercise_notebooks/exercise_notebook_4_debugging.zip diff --git a/book/_toc.yml b/book/_toc.yml index 0f6967c..24cc574 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -42,10 +42,10 @@ parts: - file: exercise_notebooks/exercise_notebook_3_structures_loops.ipynb # - file: exercise_notebooks/exercise_notebook_3_loops_debugging.ipynb - # - file: notebook_4_debugging/PythonNotebook4_first_page.ipynb - # sections: - # - file: notebook_4_debugging/PythonNotebook4_debugging.ipynb - # - file: exercise_notebooks/exercise_notebook_4_debugging.ipynb + - file: notebook_4_debugging/PythonNotebook4_first_page.ipynb + sections: + - file: notebook_4_debugging/PythonNotebook4_debugging.ipynb + - file: exercise_notebooks/exercise_notebook_4_debugging.ipynb # - file: notebook_5_figures/PythonNotebook5_first_page.ipynb # sections: diff --git a/book/exercise_notebooks/exercise_notebook_3_structures_loops.zip b/book/exercise_notebooks/exercise_notebook_3_structures_loops.zip index 842f169c5e7ba6b3472aab0eeb2d89129d1f11ea..81cb97a10025ab8800a5d387b04fbefdd20ddcd3 100644 GIT binary patch delta 3157 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 delta 3164 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 CiV2zk diff --git a/book/exercise_notebooks/exercise_notebook_4_debugging.zip b/book/exercise_notebooks/exercise_notebook_4_debugging.zip new file mode 100644 index 0000000000000000000000000000000000000000..a269e98dda5f74b16c497484e9444cbc92105018 GIT binary patch literal 1977 zcmbW2YdjN*8^jdZKkpu`F>3XoWC*WTN2K)x_ zkMa*iVhH{|IDDADA0ChOG4i?Q?-w2rfWZamVnU*Ee&JCd0FWoZeEbB@(AO+KR~Hcg zKdX_6hBYzKzxOH)+!<#^>3@co|rq4$N59->)E*=Og;Yxblwr*>~LQL2POsn>zd z26aVj+nl1??WyJ_$V^`?fy<@q&Ax`XMlJF!UZP%p{eGJlxy5~5*6qQQrZl&AlY-Am zL)_!mDUKPImDtOxA1#R#vY)qnoMEs+=`D2VUd0Og^_kArVl@!UEn<2_ek<=olILi2 zaI;2zD5AN3(6#gJL}>qj(k`(*ds4q*K&_`wDDH9eR*LmR;M@t1A6h5{NbD6lP1{TD z2ckmDn4-4H-kNGvs=nRXT6QLm#yJ2B%NzL6FvDxuVbc76Z0m=l zJ&;;2B7?1zQmzhhvZ17hyfMyc&?Giyot{VcC5&HGzve|&DN;qvhx4vVP`lCoHc3Aj zt{)s?w2^o=KXA57#*Sb7B!ysIu`sHH7qwn_QYtT3#D}QAaY3*P>w8YO+4kgR`4>|6 zqxK#sk{0rx&6*ZVI@28DqeOpRcVVUzt@unY30clTd>nUY_1IEky@kWU6U!RA1vb;S z9V>DxSl27-+E}PM1;_IHun2qsodl91l_d#&M(`+e=ZwDfy~1$r5IE&!zUpvwhLV{m zq@G;!m%vW`LPjgmHooz&gwq=d5~ZE8ta4a23DB516@RvCUQ{eqliF`9S37uuy!I0L zXgGG@VDm&ka_gizyo1(e++a*l1gw49FvXO;x8Ry)8_>7MhDSjhD2VWLq1(dEm6T8| z(v}vIc4z6F`|?xw%f6Rsu;@w_BGn?LFPDits=N9T8CB#2f2*npP-<%7Tj#ur4)y8B-wE5g&6XLM3JOFGw+N%9-8J`-o;( zE=ay(VAFV^asWITiT%=tM)n7W=?WP%>Szz`GdWwh0-K=SYJhuux+X`QRltwp*=SSr zm_7SWwuK58B#acMY{avSMLaz_b-O8q+~*dMeJlN%y~TUmTAPdyFntB?I=!)Mqp#bW z3IfqkSo|hI>_F+dMT}17-Jy%@3#iKdjrCco+60=~~nMvuirc9M1JKKiS!wh|}TtxLM~KRlIM=-U>5D||0l z`%yv=mc2hg{fjzr6hQ;kUJTkbPHeFa|wFF;Ys&YrgSL!nS#W*H;8R%wY{dhWnfleYx^Y@2lBsBlZ)gU8rgE zC?2h$l|~W0b|VXPQV=-oW9_7wthkNLUF{kf#k5b5PE$q@II=MghUhy+S4fVEyTnQOn&GROEk4!arv2^*`ktvgQ=}?~Vvj-Vsvg%#oK3$8c(pd@F z`L#41-09w@;>$%7GPwTHHq=J#^gft6lk#HVi|g^aCd;g7w~2yP*{WN%Hg4=cBCYA{?rRyIi4*eO$%Y5SHV?zrkwF55{WAR>2uVxt@w4ZQpio zF)m3vPjQL|wXt-E%$0r?ty6F*QR0PkNBPeYsQYJJ(Kq?d*KSw8``hd04ZMutOYlt6 z61#s-wmy7ohnriL$i*TGhatD^*Xi!D5$KYcZ2Y2b>po#%GA^f$aNe6JEg?+NTr*_i zrqv!;!10qPdnu5DaAfJ=tIX?)>fq=NF*a2cGWd0|2xo0RSgBkV}&Lf9(AC4h)d_FG Date: Fri, 3 Oct 2025 14:01:04 +0200 Subject: [PATCH 3/9] toc and zip updates --- ...ok4_first_page copy.ipynb => PythonNotebook4_first_page.ipynb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename book/notebook_4_debugging/{PythonNotebook4_first_page copy.ipynb => PythonNotebook4_first_page.ipynb} (100%) diff --git a/book/notebook_4_debugging/PythonNotebook4_first_page copy.ipynb b/book/notebook_4_debugging/PythonNotebook4_first_page.ipynb similarity index 100% rename from book/notebook_4_debugging/PythonNotebook4_first_page copy.ipynb rename to book/notebook_4_debugging/PythonNotebook4_first_page.ipynb From 2058790e9e54e7742b87e8e9f5989121a785b211 Mon Sep 17 00:00:00 2001 From: Simon van Diepen Date: Mon, 6 Oct 2025 09:26:18 +0200 Subject: [PATCH 4/9] Review numpy lesson --- .../exercise_notebook_6_numpy.ipynb | 2 +- .../PythonNotebook6_first_page.ipynb | 2 +- .../PythonNotebook6_loading_data.ipynb | 19 +++++--- ...ook6_vectors_and_plotting_with_numpy.ipynb | 43 +++++++++++++++---- 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/book/exercise_notebooks/exercise_notebook_6_numpy.ipynb b/book/exercise_notebooks/exercise_notebook_6_numpy.ipynb index 12d7512..200cceb 100644 --- a/book/exercise_notebooks/exercise_notebook_6_numpy.ipynb +++ b/book/exercise_notebooks/exercise_notebook_6_numpy.ipynb @@ -184,7 +184,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.5" + "version": "3.10.0" }, "latex_envs": { "LaTeX_envs_menu_present": true, diff --git a/book/notebook_6_numpy/PythonNotebook6_first_page.ipynb b/book/notebook_6_numpy/PythonNotebook6_first_page.ipynb index 92059b6..ac1f5f7 100644 --- a/book/notebook_6_numpy/PythonNotebook6_first_page.ipynb +++ b/book/notebook_6_numpy/PythonNotebook6_first_page.ipynb @@ -46,7 +46,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.12" + "version": "3.10.0" }, "latex_envs": { "LaTeX_envs_menu_present": true, diff --git a/book/notebook_6_numpy/PythonNotebook6_loading_data.ipynb b/book/notebook_6_numpy/PythonNotebook6_loading_data.ipynb index 87f8e62..51812ee 100644 --- a/book/notebook_6_numpy/PythonNotebook6_loading_data.ipynb +++ b/book/notebook_6_numpy/PythonNotebook6_loading_data.ipynb @@ -33,7 +33,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "tags": [ "theme-remove-input-init" @@ -124,11 +124,18 @@ "2 qt specific humidity (kg/kg) - amount of water, kg of water per kg of total air \n", "3 u wind speed (m/s) in the eastward direction\n", "4 v wind speed (m/s) in the northward direction\n", - "5 TKE_init turblent kinetic energy (m/s) - a measure of the amount of turbulence\n", + "5 TKE_init turbulent kinetic energy (m/s) - a measure of the amount of turbulence\n", "```\n", "\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will revisit this file in one of the exercises, and have a look at working with its contents there. " + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -222,7 +229,9 @@ "plt.gca().set_aspect('equal') # gca() stands for get current axis\n", "\n", "plt.pcolormesh(X,Y,Z) # plot Z as function of X and Y, using colors\n", - "plt.colorbar() # shows the color bar\n", + "cbar = plt.colorbar() # shows the color bar\n", + "\n", + "cbar.set_label(\"Value of Z\") # put a label on the colourbar so it is understandable\n", "\n", "plt.show()" ] @@ -242,7 +251,7 @@ ], "metadata": { "kernelspec": { - "display_name": "base", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -256,7 +265,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.2" + "version": "3.10.0" }, "latex_envs": { "LaTeX_envs_menu_present": true, diff --git a/book/notebook_6_numpy/PythonNotebook6_vectors_and_plotting_with_numpy.ipynb b/book/notebook_6_numpy/PythonNotebook6_vectors_and_plotting_with_numpy.ipynb index 5364a66..4623c25 100644 --- a/book/notebook_6_numpy/PythonNotebook6_vectors_and_plotting_with_numpy.ipynb +++ b/book/notebook_6_numpy/PythonNotebook6_vectors_and_plotting_with_numpy.ipynb @@ -29,7 +29,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -42,7 +42,7 @@ "source": [ "Now functions in numpy are accessible as `np.array()` for example.\n", "\n", - "The part `as np` is not necessary, but commonly done for slightly shorter code than typing `numpy.array()` every time.\n" + "The part `as np` is not necessary, but commonly done for slightly shorter code than typing `numpy.array()` every time (just like we imported `matplotlib.pyplot` as `plt` last week).\n" ] }, { @@ -75,7 +75,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -93,7 +93,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -216,12 +216,24 @@ "This creates an array of `N` equally spaced numbers where both start and end are included.\n", "**Use whichever is more convenient.**\n", "\n", + "```{admonition} Attention\n", + ":class: danger\n", + "\n", + "Choose `N` carefully. `np.arange(0, 1, 0.1)` yields an array with 10 numbers: `[0, 0.1, 0.2, ..., 0.9]`. `np.linspace(0, 1, 10)` also yields an array with 10 numbers, but different ones: `[0, 0.1111111, 0.22222222, ..., 0.88888889, 1]`. This is the difference between including and excluding the end point. \n", + "+++\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ "Let's now create an array `x` with equally spaced points, and evaluate a function on it." ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -234,6 +246,19 @@ "metadata": {}, "source": [ "Note we used `np.cos()`, which is similar to `math.cos()` but can work on numpy arrays.\n", + "\n", + "```{admonition} Attention\n", + ":class: danger\n", + "\n", + "Functions from the `math` module do not work on numpy arrays as they expect single numbers. Always use their `numpy` equivalents.\n", + "+++\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ "Now each element of `y1` equals the cosine of the corresponding element in `x`. \n", "\n", "Use the cell below to print `y1` to check." @@ -241,7 +266,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -257,7 +282,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -300,7 +325,7 @@ ], "metadata": { "kernelspec": { - "display_name": "base", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -314,7 +339,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.2" + "version": "3.10.0" }, "latex_envs": { "LaTeX_envs_menu_present": true, From 6707429ba0a047966931492bd4ae2b0b38222edc Mon Sep 17 00:00:00 2001 From: Simon van Diepen Date: Mon, 6 Oct 2025 09:35:21 +0200 Subject: [PATCH 5/9] Split out unnecessary comments in code --- .../PythonNotebook6_loading_data.ipynb | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/book/notebook_6_numpy/PythonNotebook6_loading_data.ipynb b/book/notebook_6_numpy/PythonNotebook6_loading_data.ipynb index 51812ee..60d87a2 100644 --- a/book/notebook_6_numpy/PythonNotebook6_loading_data.ipynb +++ b/book/notebook_6_numpy/PythonNotebook6_loading_data.ipynb @@ -193,10 +193,22 @@ "X,Y = np.meshgrid(x,y)\n", "\n", "# a function to plot\n", - "Z = X**2 + Y**2\n", - "# Z has the same shape as X and Y\n", - "# each element of Z is computed from the corresponding elements of X and Y\n", - "\n", + "Z = X**2 + Y**2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`Z` has the same shape as `X` and `Y`, and each element of `Z` is computed from the corresponding elements of `X` and `Y`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "ax = plt.axes(projection='3d')\n", "\n", "ax.plot_surface(X,Y,Z)\n", From 4c6268483c11f6cc7b3d1bf71a9e149c32002dd4 Mon Sep 17 00:00:00 2001 From: SandraVerhagen <120573543+SandraVerhagen@users.noreply.github.com> Date: Thu, 9 Oct 2025 18:17:10 +0200 Subject: [PATCH 6/9] Uncomment sections for notebooks 4 and 5 in _toc.yml --- book/_toc.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/book/_toc.yml b/book/_toc.yml index 0f6967c..3010f86 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -42,15 +42,15 @@ parts: - file: exercise_notebooks/exercise_notebook_3_structures_loops.ipynb # - file: exercise_notebooks/exercise_notebook_3_loops_debugging.ipynb - # - file: notebook_4_debugging/PythonNotebook4_first_page.ipynb - # sections: - # - file: notebook_4_debugging/PythonNotebook4_debugging.ipynb - # - file: exercise_notebooks/exercise_notebook_4_debugging.ipynb + - file: notebook_4_debugging/PythonNotebook4_first_page.ipynb + sections: + - file: notebook_4_debugging/PythonNotebook4_debugging.ipynb + - file: exercise_notebooks/exercise_notebook_4_debugging.ipynb - # - file: notebook_5_figures/PythonNotebook5_first_page.ipynb - # sections: - # - file: notebook_5_figures/PythonNotebook5_matplotlib.ipynb - # - file: exercise_notebooks/exercise_notebook_5_figures.ipynb + - file: notebook_5_figures/PythonNotebook5_first_page.ipynb + sections: + - file: notebook_5_figures/PythonNotebook5_matplotlib.ipynb + - file: exercise_notebooks/exercise_notebook_5_figures.ipynb # - file: notebook_6_numpy/PythonNotebook6_first_page.ipynb # sections: From e33f130f817f48b55359b9d9894a76bae66b9ba5 Mon Sep 17 00:00:00 2001 From: SandraVerhagen <120573543+SandraVerhagen@users.noreply.github.com> Date: Thu, 9 Oct 2025 18:23:04 +0200 Subject: [PATCH 7/9] Fix indentation in _toc.yml for notebook sections --- book/_toc.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/book/_toc.yml b/book/_toc.yml index 3010f86..fff9995 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -42,15 +42,15 @@ parts: - file: exercise_notebooks/exercise_notebook_3_structures_loops.ipynb # - file: exercise_notebooks/exercise_notebook_3_loops_debugging.ipynb - - file: notebook_4_debugging/PythonNotebook4_first_page.ipynb - sections: - - file: notebook_4_debugging/PythonNotebook4_debugging.ipynb - - file: exercise_notebooks/exercise_notebook_4_debugging.ipynb + - file: notebook_4_debugging/PythonNotebook4_first_page.ipynb + sections: + - file: notebook_4_debugging/PythonNotebook4_debugging.ipynb + - file: exercise_notebooks/exercise_notebook_4_debugging.ipynb - - file: notebook_5_figures/PythonNotebook5_first_page.ipynb - sections: - - file: notebook_5_figures/PythonNotebook5_matplotlib.ipynb - - file: exercise_notebooks/exercise_notebook_5_figures.ipynb + - file: notebook_5_figures/PythonNotebook5_first_page.ipynb + sections: + - file: notebook_5_figures/PythonNotebook5_matplotlib.ipynb + - file: exercise_notebooks/exercise_notebook_5_figures.ipynb # - file: notebook_6_numpy/PythonNotebook6_first_page.ipynb # sections: From 9e5b84782618f8bf0c36da535964db4d4b8032c0 Mon Sep 17 00:00:00 2001 From: SandraVerhagen <120573543+SandraVerhagen@users.noreply.github.com> Date: Thu, 9 Oct 2025 18:25:39 +0200 Subject: [PATCH 8/9] Comment out notebook 4 debugging entries Comment out the first page and sections for notebook 4 debugging. --- book/_toc.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/book/_toc.yml b/book/_toc.yml index fff9995..5de4551 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -42,10 +42,10 @@ parts: - file: exercise_notebooks/exercise_notebook_3_structures_loops.ipynb # - file: exercise_notebooks/exercise_notebook_3_loops_debugging.ipynb - - file: notebook_4_debugging/PythonNotebook4_first_page.ipynb - sections: - - file: notebook_4_debugging/PythonNotebook4_debugging.ipynb - - file: exercise_notebooks/exercise_notebook_4_debugging.ipynb + # - file: notebook_4_debugging/PythonNotebook4_first_page.ipynb + # sections: + # - file: notebook_4_debugging/PythonNotebook4_debugging.ipynb + # - file: exercise_notebooks/exercise_notebook_4_debugging.ipynb - file: notebook_5_figures/PythonNotebook5_first_page.ipynb sections: From f38999db12dcc409e39a4b80226890c214601a4f Mon Sep 17 00:00:00 2001 From: SandraVerhagen Date: Mon, 13 Oct 2025 15:39:44 +0200 Subject: [PATCH 9/9] Corrept file added in zip, removed obsolete section (was same as exercise notebook) --- book/_toc.yml | 2 +- .../exercise_notebook_5_figures.ipynb | 2 +- .../exercise_notebook_5_figures.zip | Bin 4276 -> 4246 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/book/_toc.yml b/book/_toc.yml index fff9995..ea6fe03 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -49,7 +49,7 @@ parts: - file: notebook_5_figures/PythonNotebook5_first_page.ipynb sections: - - file: notebook_5_figures/PythonNotebook5_matplotlib.ipynb + # - file: notebook_5_figures/PythonNotebook5_matplotlib.ipynb - file: exercise_notebooks/exercise_notebook_5_figures.ipynb # - file: notebook_6_numpy/PythonNotebook6_first_page.ipynb diff --git a/book/exercise_notebooks/exercise_notebook_5_figures.ipynb b/book/exercise_notebooks/exercise_notebook_5_figures.ipynb index 9652116..0b07c50 100644 --- a/book/exercise_notebooks/exercise_notebook_5_figures.ipynb +++ b/book/exercise_notebooks/exercise_notebook_5_figures.ipynb @@ -261,7 +261,7 @@ "**Label hint:** unfortunately there is no function `plot.zlabel()`.\n", "Instead you have to use `ax.set_zlabel('...')`. You can use `ax.set_xlabel()` and `ax.set_ylabel()` too. Your script looks nicer if you handle all axes in the same way.\n", " \n", - "**Note:** the z-label doesn't necessary show up anyway, perhaps it's hidden behind the plot. If you could rotate the plot it might show up. For now let's choose our battles and not worry about this.\n", + "**Note:** the z-label doesn't necessarily show up anyway, perhaps it's hidden behind the plot. If you could rotate the plot it might show up. For now let's choose our battles and not worry about this.\n", "" ] }, diff --git a/book/exercise_notebooks/exercise_notebook_5_figures.zip b/book/exercise_notebooks/exercise_notebook_5_figures.zip index df6fdd37aba4265a8ec19e158cb55f8d136cac28..506f0ebbea482ef7e254361558d3801f9b57598f 100644 GIT binary patch delta 4202 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