\chapter{Iteration: part 2}
\section{Two-dimensional tables}
A two-dimensional table is a table where you read the value at the
intersection of a row and a column. A multiplication table is a good
example. Let's say you want to print a multiplication table for the
values from 1 to 6.
A good way to start is to write a loop that prints the multiples of 2,
all on one line:
\begin{python}
i = 1
while i <= 6:
    print 2*i, '   ',
    i += 1
print
\end{python}
The first line initializes a variable named \pythoninline{i}, which
acts as a counter or \myidx{loop variable} . As the loop executes, the
value of \pythoninline{i} increases from 1 to 6. When \pythoninline{i}
is 7, the loop terminates. Each time through the loop, it displays the
value of \pythoninline{2*i}, followed by three spaces.
Again, the comma in the print statement suppresses the newline. After
the loop completes, the second print statement starts a new line.
The output of the program is:
\begin{pythonOutput}
2      4      6      8      10     12
\end{pythonOutput}

So far, so good. The next step is to \myidx{encapsulate} and
\myidx{generalize} .

\section{Encapsulation and generalization}
Encapsulation is the process of wrapping a piece of code in a
function, allowing you to take advantage of all the things functions
are good for. You have already seen two examples of encapsulation:
\pythoninline{print\_parity} in lecture \ref{lecture-conditionals}; and
\pythoninline{is\_divisible} in chapter \ref{lecture-fruity}.
Generalization means taking something specific, such as printing the
multiples of 2, and making it more general, such as printing the
multiples of any integer.
This function encapsulates the previous loop and generalizes it to
print multiples of \pythoninline{n}:

\noindent
\begin{minipage}{\textwidth}
\begin{python}
def print_multiples(n):
    i = 1
    while i <= 6:
        print n*i, '\t',
        i += 1
    print
\end{python}
\end{minipage}

To encapsulate, all we had to do was add the first line, which
declares the name of the function and the parameter list. To
generalize, all we had to do was replace the value 2 with the
parameter \pythoninline{n}.
If we call this function with the argument \pythoninline{2}, we get
the same output 
as before. With the argument \pythoninline{3}, the output is:
\begin{pythonOutput}
3      6      9      12     15     18
\end{pythonOutput}
With the argument \pythoninline{4}, the output is:
\begin{pythonOutput}
4      8      12     16     20     24
\end{pythonOutput}
By now you can probably guess how to print a multiplication table---by
calling \pythoninline{print\_multiples} repeatedly with different
arguments. In fact, 
we can use another loop:
\begin{python}
i = 1
while i <= 6:
    print_multiples(i)
    i += 1
\end{python}
Notice how similar this loop is to the one inside
\pythoninline{print\_multiples}. All we did was replace the print
statement with a function call.
The output of this program is a multiplication table:
\begin{pythonOutput}
1      2      3      4      5      6
2      4      6      8      10     12
3      6      9      12     15     18
4      8      12     16     20     24
5      10     15     20     25     30
6      12     18     24     30     36
\end{pythonOutput}

\section{More encapsulation}
To demonstrate encapsulation again, let's take the code from the last
section and wrap it up in a function:
\begin{python}
def print_mult_table():
    i = 1
    while i <= 6:
        print_multiples(i)
        i += 1
\end{python}
This process is a common \myidx{development plan}. We develop code by
writing lines of code outside any function, or typing them in to the
interpreter. When we get the code working, we extract it and wrap it
up in a function. This development plan is particularly useful if you
don't know how to divide the program into functions when you start
writing. This approach lets you design as you go along.

\section{Local variables}
You might be wondering how we can use the same variable,
\pythoninline{i}, in both \pythoninline{print\_multiples} and
\pythoninline{print\_mult\_table}.  Doesn't it cause problems when one
of the functions changes the value of the variable? The answer is no,
because the \pythoninline{i} in \pythoninline{print\_multiples} and
the \pythoninline{i} in \pythoninline{print\_mult\_table} are
\emph{not} the same variable.  Variables created inside a function
definition are \myidx{local}; you can't access a local variable from
outside its home function. That means you are free to have multiple
variables with the same name as long as they are not in the same
function.

The stack diagram for this program shows that the two variables named
\pythoninline{i} are not the same variable. They can refer to
different values, and changing one does not affect the other.

\includegraphics[scale=1]{illustrations/stack4.png}

The value of \pythoninline{i} in \pythoninline{print\_mult\_table}
goes from 1 to 6. In the diagram it happens to be 3. The next time
through the loop it will be 4. Each time through the loop,
\pythoninline{print\_mult\_table} calls
\pythoninline{print\_multiples} with the current value of
\pythoninline{i} as an argument. That value gets assigned to the
parameter \pythoninline{n}. 
Inside \pythoninline{print\_multiples}, the value of \pythoninline{i}
goes from 1 to 6. In the 
diagram, it happens to be 2. Changing this variable has no effect on
the value of \pythoninline{i} in \pythoninline{print\_mult\_table}.

It is common and perfectly legal to have different local variables
with the same name. In particular, names like \pythoninline{i} and
\pythoninline{j} are used 
frequently as loop variables. If you avoid using them in one function
just because you used them somewhere else, you will probably make the
program harder to read.

\section{More generalization}
As another example of generalization, imagine you wanted a program
that would print a multiplication table of any size, not just the
six-by-six table. You could add a parameter to
\pythoninline{print\_mult\_table}:
\begin{python}
def print_mult_table(high):
    i = 1
    while i <= high:
        print_multiples(i)
        i += 1
\end{python}
We replaced the value \pythoninline{6} with the parameter
\pythoninline{high}. If we call 
\pythoninline{print\_mult\_table} with the argument \pythoninline{7},
it displays: 
\begin{pythonOutput}
1      2      3      4      5      6
2      4      6      8      10     12
3      6      9      12     15     18
4      8      12     16     20     24
5      10     15     20     25     30
6      12     18     24     30     36
7      14     21     28     35     42
\end{pythonOutput}
This is fine, except that we probably want the table to be
square---with the same number of rows and columns. To do that, we add
another parameter to \pythoninline{print\_multiples} to specify how
many columns the table should have.
Just to be annoying, we call this parameter high, demonstrating that
different functions can have parameters with the same name (just like
local variables). Here's the whole program:
\begin{python}
def print_multiples(n, high):
    i = 1
    while i <= high:
        print n*i, '\t',
        i += 1
    print
   

def print_mult_table(high):
    i = 1
    while i <= high:
        print_multiples(i, high)
        i += 1
\end{python}

Notice that when we added a new parameter, we had to change the first
line of the function (the function heading), and we also had to change
the place where the function is called in
\pythoninline{print\_mult\_table}.
As expected, this program generates a square seven-by-seven table:
\begin{pythonOutput}
1      2      3      4      5      6      7
2      4      6      8      10     12     14
3      6      9      12     15     18     21
4      8      12     16     20     24     28
5      10     15     20     25     30     35
6      12     18     24     30     36     42
7      14     21     28     35     42     49
\end{pythonOutput}

When you generalize a function appropriately, you often get a program
with capabilities you didn't plan. For example, you might notice that,
because $ab = ba$, all the entries in the table appear twice. You could
save ink by printing only half the table. To do that, you only have to
change one line of \pythoninline{print\_mult\_table}. Change
\begin{python}
print_multiples(i, high)
\end{python}
to
\begin{python}
print_multiples(i, i)
\end{python}
and you get
\begin{pythonOutput}
1
2      4
3      6      9
4      8      12     16
5      10     15     20     25
6      12     18     24     30     36
7      14     21     28     35     42     49
\end{pythonOutput}

\section{Functions}
A few times now, we have mentioned all the things functions are good
for. By now, you might be wondering what exactly those things
are. Here are some of them:
\begin{enumerate}
\item Giving a name to a sequence of statements makes your program
easier to read and debug.
\item Dividing a long program into functions allows you to separate
parts of the program, debug them in isolation, and then compose them
into a whole.
\item Facilitating the use of iteration.
\item Producing reusable code; as well defined functions are often useful
in many different situations. 
\end{enumerate}

\section{Newton's method}
\label{sec-iteration-newton}
Loops are often used in programs that compute numerical results by
starting with an approximate answer and iteratively improving it.
For example, one way of computing square roots is Newton's
method. Suppose that you want to know the square root of $n$. If you
start with almost any approximation, you can compute a better
approximation with the following formula\footnote{If $s$ is the
square root of $n$, then $s$ and $n/s$ are the same, so even for a number $x$
which isn't the square root, the average of $x$ and $n/x$ might well be a
better approximation.}:
\begin{python}
better = (approx + n/approx)/2
\end{python}
By repeatedly applying this formula until the better approximation is
equal to the previous one, we can write a function for computing the
square root:
\begin{python}
def sqrt_newton(n):
    eps = 1e-8
    approx = n/2.0
    better = (approx + n/approx)/2.0
    while abs(better-approx) > eps:
        approx = better
        better = (approx + n/approx)/2.0
    return approx
\end{python}
Try calling this function with 25 as an argument to confirm that it
returns 5.0.

\section{Algorithms}
Newton's method is an example of an \myidx{algorithm} : it is a
mechanical process for solving a category of problems (in this case,
computing square roots). It is not easy to define an algorithm. It
might help to start with something that is not an algorithm. When you
learned to multiply single-digit numbers, you probably memorized the
multiplication table. In effect, you memorized 100 specific solutions. 
That kind of knowledge is not algorithmic.
But if you were lazy, you probably cheated by learning a few
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!
Similarly, the techniques you learned for addition with carrying,
subtraction with borrowing, and long division are all algorithms. One
of the characteristics of algorithms is that they do not require any
intelligence to carry out. They are mechanical processes in which each
step follows from the last according to a simple set of rules.

In our opinion, it is embarrassing that humans spend so much time in
school learning to execute algorithms that, quite literally, require
no intelligence. On the other hand, the process of designing
algorithms is interesting, intellectually challenging, and a central
part of what we call programming. Some of the things that people do
naturally, without difficulty or conscious thought, are the hardest to
express algorithmically. Understanding natural language is a good
example. We all do it, but so far no one has been able to explain
\emph{how} we do it, at least not in the form of an algorithm.

\section{Glossary}
\begin{description}
\item[tab:]A special character that causes the cursor to move to the
next tab stop on the current line.
\item[newline:]A special character that causes the cursor to move to
the beginning of the next line.
\item[cursor:]An invisible marker that keeps track of where the next
character will be printed.
\item[escape sequence:]An escape character, $\backslash$, followed by
one or more printable characters used to designate a non-printable
character.
\item[encapsulate:]To divide a large complex program into components
(like functions) and isolate the components from each other (by
using local variables, for example).
\item[generalize:]To replace something unnecessarily specific (like a
constant value) with something appropriately general (like a
variable or parameter). Generalization makes code more versatile,
more likely to be reused, and sometimes even easier to write.
\item[development plan:]A process for developing a program. In this
chapter, we demonstrated a style of development based on developing
code to do simple, specific things and then encapsulating and
generalizing.
\item[algorithm:]A step-by-step process for solving a category of
problems.
\end{description}

\section{Laboratory exercises}
\begin{enumerate}
\item Write a single Python statement that
\begin{pythonOutput}
   produces
   this
   output.
\end{pythonOutput}

\item Write a script that allows users to choose from a number of menu
  options.
\begin{pythonOutput}
--- Menu ---
1 = Option 1
2 = Option 2
3 = Option 3
0 = Quit

Enter your choice :
\end{pythonOutput}

To start with just have an option print out its name when it is
selected and then return to the menu. For example:

\begin{pythonOutput}
--- Menu ---
1 = Option 1
2 = Option 2
3 = Option 3
0 = Quit

Enter your choice : 1

Option 1 selected.

--- Menu ---
1 = Option 1
2 = Option 2
3 = Option 3
0 = Quit

Enter your choice : 

\end{pythonOutput}

Entering 0 (zero) should exit the script with a suitable quit message.

\item Add a print statement to the \pythoninline{sqrt} function
defined in section \ref{sec-iteration-newton} that prints out
\pythoninline{better} each time it is calculated. Call your modified
function with \pythoninline{25} as an argument and record the results.
\begin{answerspace}




zend
\end{answerspace}


\item Modify your menu script so that the \pythoninline{sqrt} function
  is Option 1.

\item Trace the execution of the last version of
\pythoninline{print\_mult\_table} and figure out how it works.

\begin{answerspace}








zend
\end{answerspace}

\item Write a function \pythoninline{count\_apluses(filename)} which
  reads lines from a file of numbers and returns how many were in the
  range 90 to 100.  You can use the provided files
  \pythoninline{marks.txt} and \pythoninline{big-marks.txt} to test
  your function.

\item Modify your menu script so that the
  \pythoninline{count\_apluses(filename)} function is Option 2.

% \item Write a function \pythoninline{print\_triangular\_numbers(n)}
%   that prints out the first \pythoninline{n} triangular numbers. A
%   call to \pythoninline{print\_triangular\_numbers(5)} would produce
%   the following output:
% \begin{pythonOutput}
% 1       1
% 2       3
% 3       6
% 4       10
% 5       15
% \end{pythonOutput}
% (\emph{hint: use a web search to find out what a triangular number is.})
% 
% \item Modify your menu script so that the
%   \pythoninline{print\_triangular\_numbers(n)} function is Option 2.

\item \emph{Extension Exercise:} Write a function
\pythoninline{sum\_of\_squares\_of\_digits} 
that computes the sum of the squares of the digits of an integer
passed to it. For example,
\pythoninline{sum\_of\_squares\_of\_digits(987)} should return
\pythoninline{194}, since
\pythoninline{9**2~+~8**2~+~7**2~==~81~+~64~+~49~==~194}. 
\begin{python}
def sum_of_squares_of_digits(n):
    """
      >>> sum_of_squares_of_digits(1)
      1
      >>> sum_of_squares_of_digits(9)
      81
      >>> sum_of_squares_of_digits(11)
      2
      >>> sum_of_squares_of_digits(121)
      6
      >>> sum_of_squares_of_digits(987)
      194
    """
\end{python}
Check your solution against the doctests above.

\item Modify your menu script so that
the \pythoninline{sum\_of\_squares\_of\_digits} function is Option 3.
\end{enumerate}

\submitreminder
