So, we have made it to Chapter 7.
In case you have not noticed, I have not worked on the exercises from chapter 5 to chapter 7 yet. My goal is to speed up with the theory and then practice for a week. I will organize a session of “Code til you drop” with exercises from Chapter 5 to 8. I hope you can join. This will help us consolidate our knowledge before we tackle Chapter 9’s case study.
The title of chapter 7 is Iteration.
Here is a quick definition in order for us to start:
Iteration is the act of repeating a process with the aim of approaching a desired goal, target or result. Each repetition of the process is also called an “iteration”, and the results of one iteration are used as the starting point for the next iteration.
7.1 Multiple assignment
Let us recall the notion of assignment from Chapter 3 – Functions (Part II):
>>> x = 3 # Read, variable x gets the value of 3.
>>> x = x + 1 # Read, variable x gets the value of itself plus 1.
In addition, we were introduced to Boolean expressions on Chapter 5 / Section 5.1.
>>> 5 == 5 # Read, verify if 5 equals 5.
[…] With multiple assignment it is especially important to distinguish between an assignment operation [ “=” ] and a statement of equality [ “==” ].
Here is the definition that Professor Downey provides for multiple assignment.
Multiple assignment : Making more than one assignment to the same variable during the execution of a program [or code block]
7.2 Updating variables
Do you remember when we first saw this assignment statement “x = x + 1″ in Chapter 3? Today we learn that it is called an assignment update, since the new value of the variable x depends on the old value of x.
>>> x = x + 1 # Read, “get the current value of x, add one (1), and then update x with the new value”.
In order to update a variable, you must initialize the variable first. Otherwise, Python will not recognize the variable.
Python evaluates the right side before it assigns a value to x.
>>> x = 0 # Read, variable x gets the value of zero (0). This assignments is also considered as the initialization of variable x.
>>> x = x + 1 #”Updating a variable by adding one (1) is called an increment“.
>>> x = x 1 1 #”Updating a variable by subtracting one (1) is called an decrement“.
7.3 The while statement
Iteration : Repeated execution of a set of statements using either a recursive function call or a loop.
Python statements that make recursion easier are:
- for statement : ” for i in range ( n ): “
- while statement : ” while Boolean expression : “
Recursion versus For Loop versus While Loop
NOTE: I was looking for a way to improve the “countdown” function with a for loop, and I found inspiration in PythonicProse and Docs/Python.
Here is the flow of execution for the while loop:
- Evaluate the condition, yielding True or False.
- If the condition is false, exit the while statement and continue execution at the next statement.
- If the condition is true, execute the body and loop back to step 1.
The loop’s body should aim to prove the condition false, so that the loop terminates. The body may do so by changing the value of one or more variables.
The objective is to avoid infinite loops.
Infinite loop : A loop in which terminating condition is never satisfied.
>>> def sequence (n):
… while n != 1:
… print n,
… if n%2 == 0: # n is even
… n = n/2
… else: #n is odd
… n = n * 3 + 1
>>> sequence (16)
16, 8, 4, 2
>>> sequence (3)
3, 10, 5, 16, 8, 4, 2
The break statement can be used to exit a loop. To illustrate this notion, Professor Downey provides this example:
>>> while True:
… line = raw_input (‘> ‘)
… if line == ‘done’:
… break # The condition (if line == ‘done’) allows us to stop the condition affirmatively (“stop when this happens”).
… print line
> Hi there!
The loop condition is True, which is always true, so the loop runs until it hits the break statement.
Each time through, it prompts the user with an angle bracket. If the user types done, the break statement exits the loop.
Re-write the function print_n from Section 5.8 using iteration instead of recursion.
Exercise 7.1) Print_n using a while statement
I tried a couple of times to re-write the print_n function using a while statement. This helped me get it right :
- First, it is useful to remind ourselves that the while statement will execute as long as the conditional is True.
- So, we can include in the while-block whatever we want to do or display while the function is True.
- In the print_n function from exercise 7.1, we want to print the variable s as long that the conditional ” n > 0 ” is True.
- Second, a great quality of the while statement is that whenever the conditional is False it ends. Isn’t this great?
7.5 Square roots
Not long ago, I began reviewing some mathematical concepts in order to better tutor mathematics.
So, as we progress in learning the theory and logic behind Python, it amazes me to realize the closeness of mathematics and programming.
For instance, if we were to write a program that computes numerical results, we could use loops in order to start with approximate answers and iteratively improving it.
The book (Think Python) demonstrates this by working with the Newton’s method for computing a square root.
y = ( x + a/x )/2
Professor Downey points out that we must be cautious to test float equality since “floating-point values are only approximately right”.
For instance, irrational numbers such as ∏ (pi) and √2, cannot be represented exactly with a float.
Rather than checking whether x and y are exactly equal, it is safer to use the built-in function abs to compute the absolute value, or magnitude, of the difference between them:
if abs (y – x) < epsilon:
Where epsilon has a value like 0.0000001 that determines how close is close enough.
Exercise 7.2) Encapsulate this loop in a function called square_root that takes a as a parameter, chooses a reasonable value of x, and returns an estimate of the square root of a.
In interactive mode (using Python in the Terminal), I wrote:
>>> a = 4.0
>>> x = 3.0
>>> while True:
… print x
… y = (x + a/x)/2
… if abs (y-x) < epsilon:
… x = y
NOTE: I had the following error when I wrote the code block:
Traceback (most recent call last):
File “<stdin>”, line 4, in <module>
NameError: name ‘epsilon’ is not defined
So, I tried to write it in script mode (using Sublime Text and then executing it with the Terminal) and importing the math module.
Also, I looked for more information and I found an interesting/useful links:
Here is the code block in script mode (using Sublime Text):
from math import *
EPSILON = 0.0000001
a = 4.0
x = 3.0
y = (x + a/x)/2
if abs (y-x) < EPSILON:
x = y
To verify the answer, I executed the file (sqroot_epsilon.py) via the Terminal. Here is the outcome!
MacBook-Air-xxxx:Desktop xxxx$ python sqroot_epsilon.py
Later, I realized that the variable named epsilon had to be set before hand. So, the code block can perfectly work in script or interactive mode.
So, here we are on the verge of understanding the algorithm notion. I asked countless times what was an algorithm. The best answer I got was that it was like a recipe. Fair enough. However, I could not understand why a simple recipe was so fascinating in the programming world.
Again, Professor Downey has done a tremendous work explaining the coveted notion. He starts his explanation by explaining what an algorithm is not. He provides the memorization of the multiplication tables as an example.
However, he points out an interesting fact. As kids, we developed shortcuts or tricks.
For example, to find the product of n and 9, you can write n – 1 as the first digit and 10 – n as the second digit. This trick is a general solution for multiplying any single-digit number by 9. That’s an algorithm!
We can link this explanation with the recipe one. However, the later is crystal clear.
The bigger the program is, the greater the possibility of making errors. Thus, we can say that a program’s length and the possibility of making an error are positively correlated.
Nevertheless, we can save time and many hair pulled by “debugging by bisection”. We can roughly cut the program in two and test one part and then the other. We can use the incremental development
technique we learned in Chapter 6 and use the print
statements to verify line by line (or small code blocks) if we want.
These notes represent my understanding from the book Think Python: How to Think Like a Computer Scientist written by Allen B. Downey.
Part of the chapter is transcribed and all the quotes unless specified otherwise come directly from his book.
Thank you Professor Downey for making this knowledge available.
Also, I would like to thank the open source community for their valuable contribution in making resources on programming available.