Which programming structure repeats an operation until a condition is met?

In order to write useful programs, we almost always need the ability to check conditions and change the behavior of the program accordingly. Conditional statements give us this ability. The simplest form is the if statement, which has the genaral form:

Show

if BOOLEAN EXPRESSION:
    STATEMENTS

A few important things to note about

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
6 statements:

  1. The colon (

    if True:          # This is always true
        pass          # so this is always executed, but it does nothing
    else:
        pass
    
    8) is significant and required. It separates the header of the compound statement from the body.

  2. The line after the colon must be indented. It is standard in Python to use four spaces for indenting.

  3. All lines indented the same amount after the colon will be executed whenever the BOOLEAN_EXPRESSION is true.

Here is an example:

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))

The boolean expression after the

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
6 statement is called the condition. If it is true, then all the indented statements get executed. What happens if the condition is false, and
if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
0 is not equal to
if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
1? In a simple
if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
6 statement like this, nothing happens, and the program continues on to the next statement.

Run this example code and see what happens. Then change the value of

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
0 to something other than
if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
1 and run it again, confirming that you don’t get any output.

Flowchart of an if statement

Which programming structure repeats an operation until a condition is met?

As with the

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
5 statement from the last chapter, the
if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
6 statement is a compound statement. Compound statements consist of a header line and a body. The header line of the
if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
6 statement begins with the keyword
if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
6 followed by a boolean expression and ends with a colon (
if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
8).

The indented statements that follow are called a block. The first unindented statement marks the end of the block. Each statement inside the block must have the same indentation.

Indentation and the PEP 8 Python Style Guide

The Python community has developed a Style Guide for Python Code, usually referred to simply as “PEP 8”. The Python Enhancement Proposals, or PEPs, are part of the process the Python community uses to discuss and adopt changes to the language.

PEP 8 recommends the use of 4 spaces per indentation level. We will follow this (and the other PEP 8 recommendations) in this book.

To help us learn to write well styled Python code, there is a program called pep8 that works as an automatic style guide checker for Python source code.

if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")
0 is installable as a package on Debian based GNU/Linux systems like Ubuntu.

In the section of the appendix, , there is instruction on configuring vim to run

if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")
0 on your source code with the push of a button.

4.1.2. The if choice == 'a': print("You chose 'a'.") elif choice == 'b': print("You chose 'b'.") elif choice == 'c': print("You chose 'c'.") else: print("Invalid choice.") 2 statement

It is frequently the case that you want one thing to happen when a condition it true, and something else to happen when it is false. For that we have the

if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")
2 statement.

if food == 'spam':
    print('Ummmm, my favorite!')
else:
    print("No, I won't have it. I want spam!")

Here, the first print statement will execute if

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
0 is equal to
if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
1, and the print statement indented under the
if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")
6 clause will get executed when it is not.

Flowchart of a if else statement

Which programming structure repeats an operation until a condition is met?

The syntax for an

if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")
2 statement looks like this:

if BOOLEAN EXPRESSION:
    STATEMENTS_1        # executed if condition evaluates to True
else:
    STATEMENTS_2        # executed if condition evaluates to False

Each statement inside the

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
6 block of an
if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")
2 statement is executed in order if the boolean expression evaluates to
if x < y:
    STATEMENTS_A
else:
    if x > y:
        STATEMENTS_B
    else:
        STATEMENTS_C
0. The entire block of statements is skipped if the boolean expression evaluates to
if x < y:
    STATEMENTS_A
else:
    if x > y:
        STATEMENTS_B
    else:
        STATEMENTS_C
1, and instead all the statements under the
if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")
6 clause are executed.

There is no limit on the number of statements that can appear under the two clauses of an

if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")
2 statement, but there has to be at least one statement in each block. Occasionally, it is useful to have a section with no statements (usually as a place keeper, or scaffolding, for code you haven’t written yet). In that case, you can use the
if x < y:
    STATEMENTS_A
else:
    if x > y:
        STATEMENTS_B
    else:
        STATEMENTS_C
4 statement, which does nothing except act as a placeholder.

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass

Python terminology

Python documentation sometimes uses the term suite of statements to mean what we have called a block here. They mean the same thing, and since most other languages and computer scientists use the word block, we’ll stick with that.

Notice too that

if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")
6 is not a statement. The
if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
6 statement has two clauses, one of which is the (optional)
if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")
6 clause. The Python documentation calls both forms, together with the next form we are about to meet, the
if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
6 statement.

4.2. Chained conditionals

Sometimes there are more than two possibilities and we need more than two branches. One way to express a computation like that is a chained conditional:

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C

Flowchart of this chained conditional

Which programming structure repeats an operation until a condition is met?

if x < y:
    STATEMENTS_A
else:
    if x > y:
        STATEMENTS_B
    else:
        STATEMENTS_C
9 is an abbreviation of
if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
0. Again, exactly one branch will be executed. There is no limit of the number of
if x < y:
    STATEMENTS_A
else:
    if x > y:
        STATEMENTS_B
    else:
        STATEMENTS_C
9 statements but only a single (and optional) final
if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")
6 statement is allowed and it must be the last branch in the statement:

if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")

Each condition is checked in order. If the first is false, the next is checked, and so on. If one of them is true, the corresponding branch executes, and the statement ends. Even if more than one condition is true, only the first true branch executes.

4.3. Nested conditionals

One conditional can also be nested within another. (It is the same theme of composibility, again!) We could have written the previous example as follows:

Flowchart of this nested conditional

Which programming structure repeats an operation until a condition is met?

if x < y:
    STATEMENTS_A
else:
    if x > y:
        STATEMENTS_B
    else:
        STATEMENTS_C

The outer conditional contains two branches. The second branch contains another

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
6 statement, which has two branches of its own. Those two branches could contain conditional statements as well.

Although the indentation of the statements makes the structure apparent, nested conditionals very quickly become difficult to read. In general, it is a good idea to avoid them when you can.

Logical operators often provide a way to simplify nested conditional statements. For example, we can rewrite the following code using a single conditional:

if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")

The

if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
4 function is called only if we make it past both the conditionals, so we can use the
if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
5 operator:

if 0 < x and x < 10:
    print("x is a positive single digit.")

Note

Python actually allows a short hand form for this, so the following will also work:

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
0

4.4. Iteration

Computers are often used to automate repetitive tasks. Repeating identical or similar tasks without making errors is something that computers do well and people do poorly.

Repeated execution of a set of statements is called iteration. Python has two statements for iteration – the

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
5 statement, which we met last chapter, and the
if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
7 statement.

Before we look at those, we need to review a few ideas.

4.4.1. Reassignmnent

As we saw back in the section, it is legal to make more than one assignment to the same variable. A new assignment makes an existing variable refer to a new value (and stop referring to the old value).

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
1

The output of this program is

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
2

because the first time

if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
8 is printed, its value is 5, and the second time, its value is 7.

Here is what reassignment looks like in a state snapshot:

Which programming structure repeats an operation until a condition is met?

With reassignment it is especially important to distinguish between an assignment statement and a boolean expression that tests for equality. Because Python uses the equal token (

if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
9) for assignment, it is tempting to interpret a statement like
if 0 < x and x < 10:
    print("x is a positive single digit.")
0 as a boolean test. Unlike mathematics, it is not! Remember that the Python token for the equality operator is
if 0 < x and x < 10:
    print("x is a positive single digit.")
1.

Note too that an equality test is symmetric, but assignment is not. For example, if

if 0 < x and x < 10:
    print("x is a positive single digit.")
2 then
if 0 < x and x < 10:
    print("x is a positive single digit.")
3. But in Python, the statement
if 0 < x and x < 10:
    print("x is a positive single digit.")
4 is legal and
if 0 < x and x < 10:
    print("x is a positive single digit.")
5 is not.

Furthermore, in mathematics, a statement of equality is always true. If

if 0 < x and x < 10:
    print("x is a positive single digit.")
6 now, then
if 0 < x and x < 10:
    print("x is a positive single digit.")
7 will always equal
if 0 < x and x < 10:
    print("x is a positive single digit.")
8. In Python, an assignment statement can make two variables equal, but because of the possibility of reassignment, they don’t have to stay that way:

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
3

The third line changes the value of

if 0 < x and x < 10:
    print("x is a positive single digit.")
7 but does not change the value of
if 0 < x and x < 10:
    print("x is a positive single digit.")
8, so they are no longer equal.

Note

In some programming languages, a different symbol is used for assignment, such as

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
01 or
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
02, to avoid confusion. Python chose to use the tokens
if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
9 for assignment, and
if 0 < x and x < 10:
    print("x is a positive single digit.")
1 for equality. This is a common choice, also found in languages like C, C++, Java, JavaScript, and PHP, though it does make things a bit confusing for new programmers.

4.4.2. Updating variables

When an assignment statement is executed, the right-hand-side expression (i.e. the expression that comes after the assignment token) is evaluated first. Then the result of that evaluation is written into the variable on the left hand side, thereby changing it.

One of the most common forms of reassignment is an update, where the new value of the variable depends on its old value.

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
4

The second line means “get the current value of n, multiply it by three and add one, and put the answer back into n as its new value”. So after executing the two lines above,

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
05 will have the value 16.

If you try to get the value of a variable that doesn’t exist yet, you’ll get an error:

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
5

Before you can update a variable, you have to initialize it, usually with a simple assignment:

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
6

This second statement — updating a variable by adding 1 to it — is very common. It is called an increment of the variable; subtracting 1 is called a decrement.

4.5. The if x < y: STATEMENTS_A elif x > y: STATEMENTS_B else: STATEMENTS_C 5 loop

The

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
5 loop processes each item in a sequence, so it is used with Python’s sequence data types - strings, lists, and tuples.

Each item in turn is (re-)assigned to the loop variable, and the body of the loop is executed.

The general form of a

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
5 loop is:

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
7

This is another example of a compound statement in Python, and like the branching statements, it has a header terminated by a colon (

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
8) and a body consisting of a sequence of one or more statements indented the same amount from the header.

The loop variable is created when the

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
5 statement runs, so you do not need to create the variable before then. Each iteration assigns the the loop variable to the next element in the sequence, and then executes the statements in the body. The statement finishes when the last element in the sequence is reached.

This type of flow is called a loop because it loops back around to the top after each iteration.

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
8

Running through all the items in a sequence is called traversing the sequence, or traversal.

You should run this example to see what it does.

Tip

As with all the examples you see in this book, you should try this code out yourself and see what it does. You should also try to anticipate the results before you do, and create your own related examples and try them out as well.

If you get the results you expected, pat yourself on the back and move on. If you don’t, try to figure out why. This is the essence of the scientific method, and is essential if you want to think like a computer programmer.

Often times you will want a loop that iterates a given number of times, or that iterates over a given sequence of numbers. The

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
11 function come in handy for that.

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
9

4.6. Tables

One of the things loops are good for is generating tables. Before computers were readily available, people had to calculate logarithms, sines and cosines, and other mathematical functions by hand. To make that easier, mathematics books contained long tables listing the values of these functions. Creating the tables was slow and boring, and they tended to be full of errors.

When computers appeared on the scene, one of the initial reactions was, “This is great! We can use the computers to generate the tables, so there will be no errors.” That turned out to be true (mostly) but shortsighted. Soon thereafter, computers and calculators were so pervasive that the tables became obsolete.

Well, almost. For some operations, computers use tables of values to get an approximate answer and then perform computations to improve the approximation. In some cases, there have been errors in the underlying tables, most famously in the table the Intel Pentium processor chip used to perform floating-point division.

Although a log table is not as useful as it once was, it still makes a good example. The following program outputs a sequence of values in the left column and 2 raised to the power of that value in the right column:

if food == 'spam':
    print('Ummmm, my favorite!')
else:
    print("No, I won't have it. I want spam!")
0

Using the tab character (

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
12) makes the output align nicely.

if food == 'spam':
    print('Ummmm, my favorite!')
else:
    print("No, I won't have it. I want spam!")
1

4.7. The if 0 < x: # assume x is an int here if x < 10: print("x is a positive single digit.") 7 statement

The general syntax for the while statement looks like this:

if food == 'spam':
    print('Ummmm, my favorite!')
else:
    print("No, I won't have it. I want spam!")
2

Like the branching statements and the

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
5 loop, the
if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
7 statement is a compound statement consisting of a header and a body. A
if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
7 loop executes an unknown number of times, as long at the BOOLEAN EXPRESSION is true.

Here is a simple example:

if food == 'spam':
    print('Ummmm, my favorite!')
else:
    print("No, I won't have it. I want spam!")
3

Notice that if

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
17 is set to
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
18 on the first line, the body of the
if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
7 statement will not execute at all.

Here is a more elaborate example program demonstrating the use of the

if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
7 statement

if food == 'spam':
    print('Ummmm, my favorite!')
else:
    print("No, I won't have it. I want spam!")
4

The flow of execution for a

if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
7 statement works like this:

  1. Evaluate the condition (

    food = 'spam'
    
    if food == 'spam':
        print('Ummmm, my favorite!')
        print('I feel like saying it 100 times...')
        print(100 * (food + '! '))
    
    22), yielding
    if x < y:
        STATEMENTS_A
    else:
        if x > y:
            STATEMENTS_B
        else:
            STATEMENTS_C
    
    1 or
    if x < y:
        STATEMENTS_A
    else:
        if x > y:
            STATEMENTS_B
        else:
            STATEMENTS_C
    
    0.

  2. If the condition is false, exit the

    if 0 < x:            # assume x is an int here
        if x < 10:
            print("x is a positive single digit.")
    
    7 statement and continue execution at the next statement.

  3. If the condition is true, execute each of the

    food = 'spam'
    
    if food == 'spam':
        print('Ummmm, my favorite!')
        print('I feel like saying it 100 times...')
        print(100 * (food + '! '))
    
    26 in the body and then go back to step 1.

The body consists of all of the statements below the header with the same indentation.

The body of the loop should change the value of one or more variables so that eventually the condition becomes false and the loop terminates. Otherwise the loop will repeat forever, which is called an infinite loop.

An endless source of amusement for computer programmers is the observation that the directions on shampoo, lather, rinse, repeat, are an infinite loop.

In the case here, we can prove that the loop terminates because we know that the value of

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
27 is finite, and we can see that the value of
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
28 increments each time through the loop, so eventually it will have to equal
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
27. In other cases, it is not so easy to tell.

What you will notice here is that the

if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
7 loop is more work for you — the programmer — than the equivalent
if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
5 loop. When using a
if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
7 loop one has to control the loop variable yourself: give it an initial value, test for completion, and then make sure you change something in the body so that the loop terminates.

4.8. Choosing between if x < y: STATEMENTS_A elif x > y: STATEMENTS_B else: STATEMENTS_C 5 and if 0 < x: # assume x is an int here if x < 10: print("x is a positive single digit.") 7

So why have two kinds of loop if

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
5 looks easier? This next example shows a case where we need the extra power that we get from the
if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
7 loop.

Use a

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
5 loop if you know, before you start looping, the maximum number of times that you’ll need to execute the body. For example, if you’re traversing a list of elements, you know that the maximum number of loop iterations you can possibly need is “all the elements in the list”. Or if you need to print the 12 times table, we know right away how many times the loop will need to run.

So any problem like “iterate this weather model for 1000 cycles”, or “search this list of words”, “find all prime numbers up to 10000” suggest that a

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
5 loop is best.

By contrast, if you are required to repeat some computation until some condition is met, and you cannot calculate in advance when this will happen, as we did in the “greatest name” program, you’ll need a

if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
7 loop.

We call the first case definite iteration — we have some definite bounds for what is needed. The latter case is called indefinite iteration — we’re not sure how many iterations we’ll need — we cannot even establish an upper bound!

4.9. Tracing a program

To write effective computer programs a programmer needs to develop the ability to trace the execution of a computer program. Tracing involves “becoming the computer” and following the flow of execution through a sample program run, recording the state of all variables and any output the program generates after each instruction is executed.

To understand this process, let’s trace the execution of the program from section.

At the start of the trace, we have a local variable,

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
40 with an initial value of
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
41. The user will enter a string that is stored in the variable,
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
42. Let’s assume they enter
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
43. The next line creates a variable named
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
28 and gives it an intial value of
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
45.

To keep track of all this as you hand trace a program, make a column heading on a piece of paper for each variable created as the program runs and another one for output. Our trace so far would look something like this:

if food == 'spam':
    print('Ummmm, my favorite!')
else:
    print("No, I won't have it. I want spam!")
5

Since

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
46 evaluates to
if x < y:
    STATEMENTS_A
else:
    if x > y:
        STATEMENTS_B
    else:
        STATEMENTS_C
0 (take a minute to convince yourself of this), the loop body is executed.

The user will now see

if food == 'spam':
    print('Ummmm, my favorite!')
else:
    print("No, I won't have it. I want spam!")
6

Assuming the user enters

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
48 this time,
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
28 will be incremented,
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
46 again evaluates to
if x < y:
    STATEMENTS_A
else:
    if x > y:
        STATEMENTS_B
    else:
        STATEMENTS_C
0, and our trace will now look like this:

if food == 'spam':
    print('Ummmm, my favorite!')
else:
    print("No, I won't have it. I want spam!")
7

A full trace of the program might produce something like this:

if food == 'spam':
    print('Ummmm, my favorite!')
else:
    print("No, I won't have it. I want spam!")
8

Tracing can be a bit tedious and error prone (that’s why we get computers to do this stuff in the first place!), but it is an essential skill for a programmer to have. From a trace we can learn a lot about the way our code works.

4.10. Abbreviated assignment

Incrementing a variable is so common that Python provides an abbreviated syntax for it:

if food == 'spam':
    print('Ummmm, my favorite!')
else:
    print("No, I won't have it. I want spam!")
9

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
52 is an abreviation for
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
53 . We pronouce the operator as “plus-equals”. The increment value does not have to be 1:

if BOOLEAN EXPRESSION:
    STATEMENTS_1        # executed if condition evaluates to True
else:
    STATEMENTS_2        # executed if condition evaluates to False
0

There are similar abbreviations for

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
54,
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
55,
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
56,
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
57 and
food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
58:

if BOOLEAN EXPRESSION:
    STATEMENTS_1        # executed if condition evaluates to True
else:
    STATEMENTS_2        # executed if condition evaluates to False
1

4.11. Another if 0 < x: # assume x is an int here if x < 10: print("x is a positive single digit.") 7 example: Guessing game

The following program implements a simple guessing game:

if BOOLEAN EXPRESSION:
    STATEMENTS_1        # executed if condition evaluates to True
else:
    STATEMENTS_2        # executed if condition evaluates to False
2

This program makes use of the mathematical law of trichotomy (given real numbers a and b, exactly one of these three must be true: a > b, a < b, or a == b).

4.12. The food = 'spam' if food == 'spam': print('Ummmm, my favorite!') print('I feel like saying it 100 times...') print(100 * (food + '! ')) 60 statement

The break statement is used to immediately leave the body of its loop. The next statement to be executed is the first one after the body:

if BOOLEAN EXPRESSION:
    STATEMENTS_1        # executed if condition evaluates to True
else:
    STATEMENTS_2        # executed if condition evaluates to False
3

This prints:

if BOOLEAN EXPRESSION:
    STATEMENTS_1        # executed if condition evaluates to True
else:
    STATEMENTS_2        # executed if condition evaluates to False
4

4.13. The food = 'spam' if food == 'spam': print('Ummmm, my favorite!') print('I feel like saying it 100 times...') print(100 * (food + '! ')) 61 statement

This is a control flow statement that causes the program to immediately skip the processing of the rest of the body of the loop, for the current iteration. But the loop still carries on running for its remaining iterations:

if BOOLEAN EXPRESSION:
    STATEMENTS_1        # executed if condition evaluates to True
else:
    STATEMENTS_2        # executed if condition evaluates to False
5

This prints:

if BOOLEAN EXPRESSION:
    STATEMENTS_1        # executed if condition evaluates to True
else:
    STATEMENTS_2        # executed if condition evaluates to False
6

4.14. Another if x < y: STATEMENTS_A elif x > y: STATEMENTS_B else: STATEMENTS_C 5 example

Here is an example that combines several of the things we have learned:

if BOOLEAN EXPRESSION:
    STATEMENTS_1        # executed if condition evaluates to True
else:
    STATEMENTS_2        # executed if condition evaluates to False
7

Trace this program and make sure you feel confident you understand how it works.

4.15. Nested Loops for Nested Data

Now we’ll come up with an even more adventurous list of structured data. In this case, we have a list of students. Each student has a name which is paired up with another list of subjects that they are enrolled for:

if BOOLEAN EXPRESSION:
    STATEMENTS_1        # executed if condition evaluates to True
else:
    STATEMENTS_2        # executed if condition evaluates to False
8

Here we’ve assigned a list of five elements to the variable

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
63. Let’s print out each student name, and the number of subjects they are enrolled for:

if BOOLEAN EXPRESSION:
    STATEMENTS_1        # executed if condition evaluates to True
else:
    STATEMENTS_2        # executed if condition evaluates to False
9

Python agreeably responds with the following output:

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
0

Now we’d like to ask how many students are taking CompSci. This needs a counter, and for each student we need a second loop that tests each of the subjects in turn:

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
1

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
2

You should set up a list of your own data that interests you — perhaps a list of your CDs, each containing a list of song titles on the CD, or a list of movie titles, each with a list of movie stars who acted in the movie. You could then ask questions like “Which movies starred Angelina Jolie?”

4.16. List comprehensions

A list comprehension is a syntactic construct that enables lists to be created from other lists using a compact, mathematical syntax:

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
3

The general syntax for a list comprehension expression is:

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
4

This list expression has the same effect as:

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
5

As you can see, the list comprehension is much more compact.

4.17. Glossary

append

To add new data to the end of a file or other data object.

block

A group of consecutive statements with the same indentation.

body

The block of statements in a compound statement that follows the header.

branch

One of the possible paths of the flow of execution determined by conditional execution.

chained conditional

A conditional branch with more than two possible flows of execution. In Python chained conditionals are written with

food = 'spam'

if food == 'spam':
    print('Ummmm, my favorite!')
    print('I feel like saying it 100 times...')
    print(100 * (food + '! '))
64 statements.

compound statement

A Python statement that has two parts: a header and a body. The header begins with a keyword and ends with a colon (

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
8). The body contains a series of other Python statements, all indented the same amount.

Note

We will use the Python standard of 4 spaces for each level of indentation.

condition

The boolean expression in a conditional statement that determines which branch is executed.

conditional statement

A statement that controls the flow of execution depending on some condition. In Python the keywords

if True:          # This is always true
    pass          # so this is always executed, but it does nothing
else:
    pass
6,
if x < y:
    STATEMENTS_A
else:
    if x > y:
        STATEMENTS_B
    else:
        STATEMENTS_C
9, and
if choice == 'a':
    print("You chose 'a'.")
elif choice == 'b':
    print("You chose 'b'.")
elif choice == 'c':
    print("You chose 'c'.")
else:
    print("Invalid choice.")
6 are used for conditional statements.

counter

A variable used to count something, usually initialized to zero and incremented in the body of a loop.

cursor

An invisible marker that keeps track of where the next character will be printed.

decrement

Decrease by 1.

definite iteration

A loop where we have an upper bound on the number of times the body will be executed. Definite iteration is usually best coded as a

if x < y:
    STATEMENTS_A
elif x > y:
    STATEMENTS_B
else:
    STATEMENTS_C
5 loop.

delimiter

A sequence of one or more characters used to specify the boundary between separate parts of text.

increment

Both as a noun and as a verb, increment means to increase by 1.

infinite loop

A loop in which the terminating condition is never satisfied.

indefinite iteration

A loop where we just need to keep going until some condition is met. A

if 0 < x:            # assume x is an int here
    if x < 10:
        print("x is a positive single digit.")
7 statement is used for this case.

initialization (of a variable)

To initialize a variable is to give it an initial value. Since in Python variables don’t exist until they are assigned values, they are initialized when they are created. In other programming languages this is not the case, and variables can be created without being initialized, in which case they have either default or garbage values.

iteration

Repeated execution of a set of programming statements.

loop

A statement or group of statements that execute repeatedly until a terminating condition is satisfied.

loop variable

A variable used as part of the terminating condition of a loop.

nested loop

A loop inside the body of another loop.

nesting

One program structure within another, such as a conditional statement inside a branch of another conditional statement.

newline

A special character that causes the cursor to move to the beginning of the next line.

prompt

A visual cue that tells the user to input data.

reassignment

Making more than one assignment to the same variable during the execution of a program.

tab

A special character that causes the cursor to move to the next tab stop on the current line.

trichotomy

Given any real numbers a and b, exactly one of the following relations holds: a < b, a > b, or a == b. Thus when you can establish that two of the relations are false, you can assume the remaining one is true.

trace

To follow the flow of execution of a program by hand, recording the change of state of the variables and any output produced.

What is a repetition structure in programming?

Repetition structures are used to repeat statements or blocks of code. The decision whether to repeat the code is based on the evaluation of a logical expression. If the expression is true, the code is executed.

What structure repeats a statement while the condition is true?

Use a Do... Loop structure when you want to repeat a set of statements an indefinite number of times, until a condition is satisfied. If you want to repeat the statements a set number of times, the For...

What is the process of repeating sections of a program called?

In programming specifically, iterative refers to a sequence of instructions or code being repeated until a specific end result is achieved. Iterative development is sometimes called circular or evolutionary development.

What command instruct you to perform something until the condition is met?

Loops are a sequence of instructions executed until a condition is satisfied.