From eb277cad82d317b426a32b309349173fff45ce12 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Mon, 1 Aug 2022 15:33:40 +1000 Subject: [PATCH 01/11] Update Code Explanations --- lectures/python_by_example.md | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/lectures/python_by_example.md b/lectures/python_by_example.md index b0ce5c8a..fc41e145 100644 --- a/lectures/python_by_example.md +++ b/lectures/python_by_example.md @@ -142,14 +142,27 @@ In fact, a package is just a directory containing In fact, you can find and explore the directory for NumPy on your computer easily enough if you look around. -On this machine, it's located in +The directory can be different based on the system of the machine and the version of python. + +You can check the location of your `__init__.py` for NumPy in python by running the code: + +```{code-cell} ipython +:class: no-execute + +import numpy as np + +print(np.__file__) +``` + +For example, on this machine, it's located in ```{code-block} ipython :class: no-execute -anaconda3/lib/python3.7/site-packages/numpy +anaconda3/lib/python3.9/site-packages/numpy/ ``` + #### Subpackages ```{index} single: Python; Subpackages @@ -159,7 +172,7 @@ Consider the line `ϵ_values = np.random.randn(100)`. Here `np` refers to the package NumPy, while `random` is a **subpackage** of NumPy. -Subpackages are just packages that are subdirectories of another package. +Subpackages are just packages that are subdirectories of another package. For instance, you can find folder `random` under the directory of NumPy. ### Importing Names Directly @@ -208,7 +221,7 @@ We can and will look at various ways to configure and improve this plot below. ## Alternative Implementations -Let's try writing some alternative versions of {ref}`our first program `, which plotted IID draws from the normal distribution. +Let's try writing some alternative versions of {ref}`our first program `, which plotted IID draws from the standard normal distribution. The programs below are less efficient than the original one, and hence somewhat artificial. @@ -250,7 +263,7 @@ Let's study some parts of this program in more detail. Consider the statement `ϵ_values = []`, which creates an empty list. -Lists are a *native Python data structure* used to group a collection of objects. +Lists are a *native Python data structure* used to group a collection of objects. Items in lists are ordered, and duplicates are allowed in lists. For example, try @@ -259,7 +272,7 @@ x = [10, 'foo', False] type(x) ``` -The first element of `x` is an [integer](https://en.wikipedia.org/wiki/Integer_%28computer_science%29), the next is a [string](https://en.wikipedia.org/wiki/String_%28computer_science%29), and the third is a [Boolean value](https://en.wikipedia.org/wiki/Boolean_data_type). +The first element of `x` is an [integer](https://en.wikipedia.org/wiki/Integer_(computer_science)), the next is a [string](https://en.wikipedia.org/wiki/String_(computer_science)), and the third is a [Boolean value](https://en.wikipedia.org/wiki/Boolean_data_type). When adding a value to a list, we can use the syntax `list_name.append(some_value)` @@ -274,7 +287,7 @@ x Here `append()` is what's called a *method*, which is a function "attached to" an object---in this case, the list `x`. -We'll learn all about methods later on, but just to give you some idea, +We'll learn all about methods later on in {doc}`Object Oriented Programming `, but just to give you some idea, * Python objects such as lists, strings, etc. all have methods that are used to manipulate the data contained in the object. * String objects have [string methods](https://docs.python.org/3/library/stdtypes.html#string-methods), list objects have [list methods](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists), etc. @@ -332,7 +345,7 @@ for animal in animals: print("The plural of " + animal + " is " + animal + "s") ``` -This example helps to clarify how the `for` loop works: When we execute a +This example helps to clarify how the `for` loop works: When we execute a loop of the form ```{code-block} python3 @@ -397,6 +410,12 @@ plt.plot(ϵ_values) plt.show() ``` +A while loop will keep executing the code block delimited by indentation until the condition (```i < ts_length```) is satisfied. It means that the programme will keep adding values to the list ```ϵ_values``` until ```i``` equals ```ts_length```: + +```{code-cell} python3 +i == ts_length #the ending condition for the while loop +``` + Note that * the code block for the `while` loop is again delimited only by indentation From 4902ef3aa0850196b487f1fabb0d5136f67803b1 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Mon, 1 Aug 2022 15:51:47 +1000 Subject: [PATCH 02/11] add explanantion for f-string --- lectures/python_by_example.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lectures/python_by_example.md b/lectures/python_by_example.md index fc41e145..9631b20f 100644 --- a/lectures/python_by_example.md +++ b/lectures/python_by_example.md @@ -632,6 +632,9 @@ plt.legend() plt.show() ``` +Note: the `f'$\\alpha = {α}$'` is called [f-String](https://docs.python.org/3/tutorial/inputoutput.html#tut-f-strings) in python which allows you to use `{}` to contain expression. The expression will be evaluated, and the result of the evaluation will be placed into the string. + + ```{solution-end} ``` From b083d28f446063be86f378c092113ca3f0ea815c Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Mon, 1 Aug 2022 15:57:42 +1000 Subject: [PATCH 03/11] refine explanation for f-string --- lectures/python_by_example.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lectures/python_by_example.md b/lectures/python_by_example.md index 9631b20f..2e13cf03 100644 --- a/lectures/python_by_example.md +++ b/lectures/python_by_example.md @@ -418,8 +418,8 @@ i == ts_length #the ending condition for the while loop Note that -* the code block for the `while` loop is again delimited only by indentation -* the statement `i = i + 1` can be replaced by `i += 1` +* the code block for the `while` loop is again delimited only by indentation. +* the statement `i = i + 1` can be replaced by `i += 1`. ## Another Application @@ -632,7 +632,7 @@ plt.legend() plt.show() ``` -Note: the `f'$\\alpha = {α}$'` is called [f-String](https://docs.python.org/3/tutorial/inputoutput.html#tut-f-strings) in python which allows you to use `{}` to contain expression. The expression will be evaluated, and the result of the evaluation will be placed into the string. +Note:`f'$\\alpha = {α}$'` in the solution is an application of [f-String](https://docs.python.org/3/tutorial/inputoutput.html#tut-f-strings), which allows you to use `{}` to contain expression. The contained expression will be evaluated, and the result will be placed into the string. ```{solution-end} From e9f87b6ac9451182f01c2d2504ec4cbef291f0a0 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Mon, 1 Aug 2022 16:27:59 +1000 Subject: [PATCH 04/11] Add explanations to Monte Carlo simulation --- lectures/python_by_example.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lectures/python_by_example.md b/lectures/python_by_example.md index 2e13cf03..636abb05 100644 --- a/lectures/python_by_example.md +++ b/lectures/python_by_example.md @@ -632,7 +632,7 @@ plt.legend() plt.show() ``` -Note:`f'$\\alpha = {α}$'` in the solution is an application of [f-String](https://docs.python.org/3/tutorial/inputoutput.html#tut-f-strings), which allows you to use `{}` to contain expression. The contained expression will be evaluated, and the result will be placed into the string. +Note:`f'$\\alpha = {α}$'` in the solution is an application of [f-String](https://docs.python.org/3/tutorial/inputoutput.html#tut-f-strings), which allows you to use `{}` to contain an expression. The contained expression will be evaluated, and the result will be placed into the string. ```{solution-end} @@ -726,12 +726,20 @@ We estimate the area by sampling bivariate uniforms and looking at the fraction that falls into the circle. ```{code-cell} python3 -n = 100000 +n = 100000 # sample size for Monte Carlo simulation count = 0 for i in range(n): + + # drawing random positions on in the square u, v = np.random.uniform(), np.random.uniform() + + # check whether the point falls within + # the estimated boundary of the inscribed semi-circle d = np.sqrt((u - 0.5)**2 + (v - 0.5)**2) + + # if it falls on the inscribed semi-circle, + # add it to the count if d < 0.5: count += 1 From 5a28d48148c268165e690e9f455877703dc2a648 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Mon, 1 Aug 2022 19:22:47 +1000 Subject: [PATCH 05/11] fix typos --- lectures/python_by_example.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lectures/python_by_example.md b/lectures/python_by_example.md index 636abb05..58b09def 100644 --- a/lectures/python_by_example.md +++ b/lectures/python_by_example.md @@ -734,11 +734,11 @@ for i in range(n): # drawing random positions on in the square u, v = np.random.uniform(), np.random.uniform() - # check whether the point falls within - # the estimated boundary of the inscribed semi-circle + # check whether the point falls within the boundary + # of the semi-circle located at (0.5,0.5) d = np.sqrt((u - 0.5)**2 + (v - 0.5)**2) - # if it falls on the inscribed semi-circle, + # if it falls within the inscribed semi-circle, # add it to the count if d < 0.5: count += 1 From 246a7a7f6a1ddcd8e832537638bb3a6bfbce9f05 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 2 Aug 2022 16:44:05 +1000 Subject: [PATCH 06/11] put solutions below exercises --- lectures/python_by_example.md | 191 +++++++++++++++++----------------- 1 file changed, 98 insertions(+), 93 deletions(-) diff --git a/lectures/python_by_example.md b/lectures/python_by_example.md index 58b09def..4be0e7ad 100644 --- a/lectures/python_by_example.md +++ b/lectures/python_by_example.md @@ -497,8 +497,30 @@ Set $T=200$ and $\alpha = 0.9$. ```{exercise-end} ``` +```{solution-start} pbe_ex1 +:class: dropdown +``` + +Here's one solution. + +```{code-cell} python3 +α = 0.9 +T = 200 +x = np.empty(T+1) +x[0] = 0 + +for t in range(T): + x[t+1] = α * x[t] + np.random.randn() + +plt.plot(x) +plt.show() +``` -```{exercise} +```{solution-end} +``` + + +```{exercise-start} :label: pbe_ex2 Starting with your solution to exercise 1, plot three simulated time series, @@ -514,87 +536,61 @@ Hints: * For the legend, noted that the expression `'foo' + str(42)` evaluates to `'foo42'`. ``` -```{exercise} -:label: pbe_ex3 - -Similar to the previous exercises, plot the time series - -$$ -x_{t+1} = \alpha \, |x_t| + \epsilon_{t+1} -\quad \text{where} \quad -x_0 = 0 -\quad \text{and} \quad t = 0,\ldots,T -$$ - -Use $T=200$, $\alpha = 0.9$ and $\{\epsilon_t\}$ as before. - -Search online for a function that can be used to compute the absolute value $|x_t|$. +```{exercise-end} ``` -```{exercise-start} -:label: pbe_ex4 +```{solution-start} pbe_ex2 +:class: dropdown ``` -One important aspect of essentially all programming languages is branching and -conditions. - -In Python, conditions are usually implemented with if--else syntax. - -Here's an example, that prints -1 for each negative number in an array and 1 -for each nonnegative number - ```{code-cell} python3 -numbers = [-9, 2.3, -11, 0] -``` +α_values = [0.0, 0.8, 0.98] +T = 200 +x = np.empty(T+1) -```{code-cell} python3 -for x in numbers: - if x < 0: - print(-1) - else: - print(1) +for α in α_values: + x[0] = 0 + for t in range(T): + x[t+1] = α * x[t] + np.random.randn() + plt.plot(x, label=f'$\\alpha = {α}$') + +plt.legend() +plt.show() ``` -Now, write a new solution to Exercise 3 that does not use an existing function -to compute the absolute value. +Note:`f'$\\alpha = {α}$'` in the solution is an application of [f-String](https://docs.python.org/3/tutorial/inputoutput.html#tut-f-strings), which allows you to use `{}` to contain an expression. The contained expression will be evaluated, and the result will be placed into the string. -Replace this existing function with an if--else condition. -```{exercise-end} +```{solution-end} ``` - ```{exercise-start} -:label: pbe_ex5 -``` +:label: pbe_ex3 -Here's a harder exercise, that takes some thought and planning. +Similar to the previous exercises, plot the time series -The task is to compute an approximation to $\pi$ using [Monte Carlo](https://en.wikipedia.org/wiki/Monte_Carlo_method). +$$ +x_{t+1} = \alpha \, |x_t| + \epsilon_{t+1} +\quad \text{where} \quad +x_0 = 0 +\quad \text{and} \quad t = 0,\ldots,T +$$ -Use no imports besides +Use $T=200$, $\alpha = 0.9$ and $\{\epsilon_t\}$ as before. -```{code-cell} python3 -import numpy as np +Search online for a function that can be used to compute the absolute value $|x_t|$. ``` -Your hints are as follows: - -* If $U$ is a bivariate uniform random variable on the unit square $(0, 1)^2$, then the probability that $U$ lies in a subset $B$ of $(0,1)^2$ is equal to the area of $B$. -* If $U_1,\ldots,U_n$ are IID copies of $U$, then, as $n$ gets large, the fraction that falls in $B$, converges to the probability of landing in $B$. -* For a circle, $area = \pi * radius^2$. - ```{exercise-end} ``` -## Solutions -```{solution-start} pbe_ex1 +```{solution-start} pbe_ex3 :class: dropdown ``` -Here's one solution. +Here's one solution: ```{code-cell} python3 α = 0.9 @@ -603,7 +599,7 @@ x = np.empty(T+1) x[0] = 0 for t in range(T): - x[t+1] = α * x[t] + np.random.randn() + x[t+1] = α * np.abs(x[t]) + np.random.randn() plt.plot(x) plt.show() @@ -613,55 +609,38 @@ plt.show() ``` -```{solution-start} pbe_ex2 -:class: dropdown -``` - -```{code-cell} python3 -α_values = [0.0, 0.8, 0.98] -T = 200 -x = np.empty(T+1) - -for α in α_values: - x[0] = 0 - for t in range(T): - x[t+1] = α * x[t] + np.random.randn() - plt.plot(x, label=f'$\\alpha = {α}$') - -plt.legend() -plt.show() +```{exercise-start} +:label: pbe_ex4 ``` -Note:`f'$\\alpha = {α}$'` in the solution is an application of [f-String](https://docs.python.org/3/tutorial/inputoutput.html#tut-f-strings), which allows you to use `{}` to contain an expression. The contained expression will be evaluated, and the result will be placed into the string. - +One important aspect of essentially all programming languages is branching and +conditions. -```{solution-end} -``` +In Python, conditions are usually implemented with if--else syntax. +Here's an example, that prints -1 for each negative number in an array and 1 +for each nonnegative number -```{solution-start} pbe_ex3 -:class: dropdown +```{code-cell} python3 +numbers = [-9, 2.3, -11, 0] ``` -Here's one solution: - ```{code-cell} python3 -α = 0.9 -T = 200 -x = np.empty(T+1) -x[0] = 0 +for x in numbers: + if x < 0: + print(-1) + else: + print(1) +``` -for t in range(T): - x[t+1] = α * np.abs(x[t]) + np.random.randn() +Now, write a new solution to Exercise 3 that does not use an existing function +to compute the absolute value. -plt.plot(x) -plt.show() -``` +Replace this existing function with an if--else condition. -```{solution-end} +```{exercise-end} ``` - ```{solution-start} pbe_ex4 :class: dropdown ``` @@ -705,6 +684,31 @@ plt.show() ``` + +```{exercise-start} +:label: pbe_ex5 +``` + +Here's a harder exercise, that takes some thought and planning. + +The task is to compute an approximation to $\pi$ using [Monte Carlo](https://en.wikipedia.org/wiki/Monte_Carlo_method). + +Use no imports besides + +```{code-cell} python3 +import numpy as np +``` + +Your hints are as follows: + +* If $U$ is a bivariate uniform random variable on the unit square $(0, 1)^2$, then the probability that $U$ lies in a subset $B$ of $(0,1)^2$ is equal to the area of $B$. +* If $U_1,\ldots,U_n$ are IID copies of $U$, then, as $n$ gets large, the fraction that falls in $B$, converges to the probability of landing in $B$. +* For a circle, $area = \pi * radius^2$. + +```{exercise-end} +``` + + ```{solution-start} pbe_ex5 :class: dropdown ``` @@ -726,7 +730,7 @@ We estimate the area by sampling bivariate uniforms and looking at the fraction that falls into the circle. ```{code-cell} python3 -n = 100000 # sample size for Monte Carlo simulation +n = 1000000 # sample size for Monte Carlo simulation count = 0 for i in range(n): @@ -750,3 +754,4 @@ print(area_estimate * 4) # dividing by radius**2 ```{solution-end} ``` + From 406c0f62c627a62b964ab2b7cdf11d917908be2b Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 2 Aug 2022 17:25:08 +1000 Subject: [PATCH 07/11] Reformat a code block --- lectures/python_by_example.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lectures/python_by_example.md b/lectures/python_by_example.md index 4be0e7ad..3209a16c 100644 --- a/lectures/python_by_example.md +++ b/lectures/python_by_example.md @@ -146,7 +146,7 @@ The directory can be different based on the system of the machine and the versio You can check the location of your `__init__.py` for NumPy in python by running the code: -```{code-cell} ipython +```{code-block} ipython :class: no-execute import numpy as np @@ -735,11 +735,11 @@ n = 1000000 # sample size for Monte Carlo simulation count = 0 for i in range(n): - # drawing random positions on in the square + # drawing random positions on the square u, v = np.random.uniform(), np.random.uniform() # check whether the point falls within the boundary - # of the semi-circle located at (0.5,0.5) + # of the semi-circle centred at (0.5,0.5) d = np.sqrt((u - 0.5)**2 + (v - 0.5)**2) # if it falls within the inscribed semi-circle, From 9796fdb8669bda78c4a6d08dbeccc6f1bbfa5abe Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 2 Aug 2022 17:27:37 +1000 Subject: [PATCH 08/11] update title --- lectures/python_by_example.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/python_by_example.md b/lectures/python_by_example.md index 3209a16c..ac5156a3 100644 --- a/lectures/python_by_example.md +++ b/lectures/python_by_example.md @@ -465,7 +465,7 @@ operating system. Notice that we added a legend to the plot --- a feature you will be asked to use in the exercises. -## Exercises +## Exercises and Solutions Now we turn to exercises. It is important that you complete them before continuing, since they present new concepts we will need. From 6e23e4976c74d35e8ba0479d8950d265180fd4ee Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 3 Aug 2022 11:37:35 +1000 Subject: [PATCH 09/11] Simplify sentence and correct annotations --- lectures/python_by_example.md | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/lectures/python_by_example.md b/lectures/python_by_example.md index ac5156a3..f15e05a1 100644 --- a/lectures/python_by_example.md +++ b/lectures/python_by_example.md @@ -142,8 +142,6 @@ In fact, a package is just a directory containing In fact, you can find and explore the directory for NumPy on your computer easily enough if you look around. -The directory can be different based on the system of the machine and the version of python. - You can check the location of your `__init__.py` for NumPy in python by running the code: ```{code-block} ipython @@ -154,15 +152,6 @@ import numpy as np print(np.__file__) ``` -For example, on this machine, it's located in - -```{code-block} ipython -:class: no-execute - -anaconda3/lib/python3.9/site-packages/numpy/ -``` - - #### Subpackages ```{index} single: Python; Subpackages @@ -172,7 +161,9 @@ Consider the line `ϵ_values = np.random.randn(100)`. Here `np` refers to the package NumPy, while `random` is a **subpackage** of NumPy. -Subpackages are just packages that are subdirectories of another package. For instance, you can find folder `random` under the directory of NumPy. +Subpackages are just packages that are subdirectories of another package. + +For instance, you can find folder `random` under the directory of NumPy. ### Importing Names Directly @@ -263,7 +254,9 @@ Let's study some parts of this program in more detail. Consider the statement `ϵ_values = []`, which creates an empty list. -Lists are a *native Python data structure* used to group a collection of objects. Items in lists are ordered, and duplicates are allowed in lists. +Lists are a *native Python data structure* used to group a collection of objects. + +Items in lists are ordered, and duplicates are allowed in lists. For example, try @@ -410,7 +403,9 @@ plt.plot(ϵ_values) plt.show() ``` -A while loop will keep executing the code block delimited by indentation until the condition (```i < ts_length```) is satisfied. It means that the programme will keep adding values to the list ```ϵ_values``` until ```i``` equals ```ts_length```: +A while loop will keep executing the code block delimited by indentation until the condition (```i < ts_length```) is satisfied. + +In this case, the program will keep adding values to the list ```ϵ_values``` until ```i``` equals ```ts_length```: ```{code-cell} python3 i == ts_length #the ending condition for the while loop @@ -465,7 +460,7 @@ operating system. Notice that we added a legend to the plot --- a feature you will be asked to use in the exercises. -## Exercises and Solutions +## Exercises Now we turn to exercises. It is important that you complete them before continuing, since they present new concepts we will need. @@ -559,7 +554,9 @@ plt.legend() plt.show() ``` -Note:`f'$\\alpha = {α}$'` in the solution is an application of [f-String](https://docs.python.org/3/tutorial/inputoutput.html#tut-f-strings), which allows you to use `{}` to contain an expression. The contained expression will be evaluated, and the result will be placed into the string. +Note: `f'$\\alpha = {α}$'` in the solution is an application of [f-String](https://docs.python.org/3/tutorial/inputoutput.html#tut-f-strings), which allows you to use `{}` to contain an expression. + +The contained expression will be evaluated, and the result will be placed into the string. ```{solution-end} @@ -739,10 +736,10 @@ for i in range(n): u, v = np.random.uniform(), np.random.uniform() # check whether the point falls within the boundary - # of the semi-circle centred at (0.5,0.5) + # of the unit circle centred at (0.5,0.5) d = np.sqrt((u - 0.5)**2 + (v - 0.5)**2) - # if it falls within the inscribed semi-circle, + # if it falls within the inscribed circle, # add it to the count if d < 0.5: count += 1 From 42e12f668c75dc2d1dc029738fcab3b44d60f04a Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 3 Aug 2022 13:33:30 +1000 Subject: [PATCH 10/11] changes based on comments --- lectures/python_by_example.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lectures/python_by_example.md b/lectures/python_by_example.md index f15e05a1..533248ca 100644 --- a/lectures/python_by_example.md +++ b/lectures/python_by_example.md @@ -139,9 +139,6 @@ In fact, a package is just a directory containing 1. possibly some compiled code that can be accessed by Python (e.g., functions compiled from C or FORTRAN code) 1. a file called `__init__.py` that specifies what will be executed when we type `import package_name` -In fact, you can find and explore the directory for NumPy on your computer -easily enough if you look around. - You can check the location of your `__init__.py` for NumPy in python by running the code: ```{code-block} ipython @@ -280,7 +277,7 @@ x Here `append()` is what's called a *method*, which is a function "attached to" an object---in this case, the list `x`. -We'll learn all about methods later on in {doc}`Object Oriented Programming `, but just to give you some idea, +We'll learn all about methods {doc}`later on `, but just to give you some idea, * Python objects such as lists, strings, etc. all have methods that are used to manipulate the data contained in the object. * String objects have [string methods](https://docs.python.org/3/library/stdtypes.html#string-methods), list objects have [list methods](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists), etc. From e8c672e4b604532104c9d9c54593827a43a4b859 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 3 Aug 2022 14:41:22 +1000 Subject: [PATCH 11/11] trivial change --- lectures/python_by_example.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/python_by_example.md b/lectures/python_by_example.md index 533248ca..299fd379 100644 --- a/lectures/python_by_example.md +++ b/lectures/python_by_example.md @@ -277,7 +277,7 @@ x Here `append()` is what's called a *method*, which is a function "attached to" an object---in this case, the list `x`. -We'll learn all about methods {doc}`later on `, but just to give you some idea, +We'll learn all about methods {doc}`later on `, but just to give you some idea, * Python objects such as lists, strings, etc. all have methods that are used to manipulate the data contained in the object. * String objects have [string methods](https://docs.python.org/3/library/stdtypes.html#string-methods), list objects have [list methods](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists), etc.