# 3.11 Program Development: Sentinel-Controlled Iteration¶

- Generalized class-average problem requirements statement:

  > Develop a class-averaging program that processes an arbitrary number of grades each time the program executes.

- Does not state what the grades are or how many there are.
- The program processes an arbitrary number of grades.
- Use a sentinel value (also called a signal value, a dummy value or a flag value) to indicate “end of data entry.”
- Sentinel-controlled iteration is often called indefinite iteration because the number of iterations is not known before the loop begins executing.
- A sentinel value must not be confused with any acceptable input value.

### Developing the Pseudocode Algorithm with Top-Down, Stepwise Refinement¶

- Begin with a pseudocode representation of the top:

  > Determine the class average for the quiz

- Single statement that conveys the program’s overall function.
- Rarely conveys enough detail from which to write a program.
- Specifies what should be done, but not how to implement it.
- Begin the refinement process by decomposing the top into a sequence of smaller tasks—divide and conquer.

### First refinement:¶

> Initialize variables
> Input, sum and count the quiz grades
> Calculate and display the class average

- Each refinement represents the complete algorithm.
- These pseudocode statements correspond to the three execution phases described in the preceding section.

### Second Refinement¶

- Commit to specific variables.
  - a grade variable in which each successive user input will be stored,
  - a running total of the grades,
  - a count of how many grades have been processed and
  - a variable that contains the calculated average.

"Initialize variables" can be refined as follows:

> Initialize total to zero
> Initialize grade counter to zero

- Other variables created when they’re needed.

"Input, sum and count the quiz grades" can be refined as follows:

> Input the first grade (possibly the sentinel)
> While the user has not entered the sentinel

> > Add this grade into the running total
> > Add one to the grade counter
> > Input the next grade (possibly the sentinel)

"Calculate and display the class average" can be refined as follows:

> If the counter is not equal to zero

> > Set the average to the total divided by the grade counter
> > Display the average

> Else

> > Display “No grades were entered”

Complete second refinement:

> Initialize total to zero
> Initialize grade counter to zero
> Input the first grade (possibly the sentinel)
> While the user has not entered the sentinel

> > Add this grade into the running total
> > Add one to the grade counter
> > Input the next grade (possibly the sentinel)
> > If the counter is not equal to zero
> > Set the average to the total divided by the counter
> > Display the average

> Else

> > Display “No grades were entered”

- Sometimes more than two refinements are necessary.
- Dtop refining when there is enough detail to convert the pseudocode to Python.
- Blank lines for readability.

### Implementing Sentinel-Controlled Iteration¶

    # fig03_02.py
    """Class average program with sentinel-controlled iteration."""

    # initialization phase
    total = 0  # sum of grades
    grade_counter = 0  # number of grades entered

    # processing phase
    grade = int(input('Enter grade, -1 to end: '))  # get one grade

    while grade != -1:
        total += grade
        grade_counter += 1
        grade = int(input('Enter grade, -1 to end: '))

    # termination phase
    if grade_counter != 0:
        average = total / grade_counter
        print(f'Class average is {average:.2f}')
    else:
        print('No grades were entered')

In [1]:

    run fig03_02.py

    Class average is 85.67

### Program Logic for Sentinel-Controlled Iteration¶

- Read the first value before reaching the `while` statement.
- The value input determines whether the program’s flow of control should enter the `while`’s suite.
- If the condition is `False`, the user entered `-1`, so the suite does not execute.
- If the condition is `True`, the suite executes, adding the `grade` value to the `total` and incrementing the `grade_counter`.
- Then we input another grade from the user and the `while`’s condition is tested again.
- `grade` is always input immediately before the program tests the `while` condition.
- When the sentinel value is input, the loop terminates, and the program does not add `–1` to the `total`.
- After the loop terminates, the `if`…`else` statement executes.

### Formatting the Class Average with Two Decimal Places¶

- We formatted the class average with two digits to the right of the decimal point.
- In an f-string, you can optionally follow a replacement-text expression with a colon (`:`) and a format specifier that describes how to format the replacement text.
- The format specifier `.2f` formats the average as a floating-point number (`f`) with two digits to the right of the decimal point (`.2`).
- Rounds to the hundredths position

### Control-Statement Stacking¶

- In this example, notice that control statements are stacked in sequence.
- The `while` statement is followed immediately by an `if`…`else` statement.

©1992–2020 by Pearson Education, Inc. All Rights Reserved. This content is based on Chapter 3 of the book Intro to Python for Computer Science and Data Science: Learning to Program with AI, Big Data and the Cloud.

DISCLAIMER: The authors and publisher of this book have used their best efforts in preparing the book. These efforts include the development, research, and testing of the theories and programs to determine their effectiveness. The authors and publisher make no warranty of any kind, expressed or implied, with regard to these programs or to the documentation contained in these books. The authors and publisher shall not be liable in any event for incidental or consequential damages in connection with, or arising out of, the furnishing, performance, or use of these programs.