# Computing and Printing the Input Data and Their Average: Version 2

 WARNING: This example assumes the output is sent to a printer, and as a result, every formatted output contains printer control.

### Problem Statement

Write a program that reads in a set of values into a REAL array, computes the average, and prints a report like the following:
```         1    1    2    2    3
....5....0....5....0....5....0
Average Computation

Input Data

No  Data
=== ======
1 100.00
2 231.00
:
:
:
14 250.00
15 379.00

Average =   1.7860001E+02
```
This problem is identical to the previous one; however, please print all data values using only one WRITE statement and do not use listed-directed WRITE.

### Solution

```PROGRAM  Mean
IMPLICIT  NONE
INTEGER, PARAMETER         :: SIZE = 20
REAL, DIMENSION(1:SIZE)    :: x
INTEGER                    :: ActualSize
INTEGER                    :: i
REAL                       :: Average
CHARACTER(LEN=30)          :: Title = "(A, A)"

READ(*,*)  (x(i), i = 1, ActualSize)

Average = 0.0
DO i = 1, ActualSize
Average = Average + x(i)
END DO
Average = Average / ActualSize

WRITE(*,Title)  " ", "Average Computation"
WRITE(*,Title)  " "
WRITE(*,Title)  " ", "Input Data"
WRITE(*,Title)  " "
WRITE(*,Title)  " ", " No  Data "
WRITE(*,Title)  " ", "=== ======"
WRITE(*,"(I4, F7.2)")  (i, x(i), i = 1, ActualSize)
WRITE(*,Title)  " "
WRITE(*,"(A,A,ES15.7)")  " ", "Average = ", Average
END PROGRAM  Mean
```

### Program Input and Output

If the input data consist of the following:
```15
100.0  231.0   67.0  179.0  315.0
78.0  111.0  410.0   98.0   25.0
245.0   90.0  101.0  250.0  379.0
```
The output of the program is:
``` Average Computation

Input Data

No  Data
=== ======
1 100.00
2 231.00
3  67.00
4 179.00
5 315.00
6  78.00
7 111.00
8 410.00
9  98.00
10  25.00
11 245.00
12  90.00
13 101.00
14 250.00
15 379.00

Average =   1.7860001E+02
```

### Discussion

• Let us replace all listed-directed WRITE statements. Since they are used to generate a blank line and a blank line can always be generated with a space in the first position, we can easily replace a listed-directed WRITE with the following:
```WRITE(*,"(A)")  " "
```
This WRITE prints a space to the first position and causes advancing to the next line.

Is this new format (A) necessary? No. Format Title is defined as follows:

```CHARACTER(LEN=30) :: Title = "(A, A)"
```
Recall that if all variables have been printed and there are unused edit descriptors, these unused edit descriptors are ignored. So, why don't we use the following for advancing lines?
```WRITE(*,Title)  " "
```
In this case, the first A edit descriptor is used to print " " and the second A edit descriptor is ignored.
• It is not difficult to print all data items with one WRITE statement. Here is the solution:
```WRITE(*,*)  (x, x(i), i = 1, ActualSize)
```
But, since this is a listed-directed output, we do not have any control over how the data items are placed on each line. This is a good start, however, as long as we can find a usable format.

The input data are printed two items per line. The first is an INTEGER and the second is a REAL. The edit descriptors used are I4 and F7.2. What if we just use this format as we did in the previous example:

```WRITE(*,"(I4, F7.2)")  (i, x(i), i = 1, ActualSize)
```
The format only prints two items (i.e., the values of i and x(i)). If there are remaining variables, the next pair of data items will be printed on the next line due to the format rescanning rule. More precisely, if all edit descriptors are used and there are unprinted variables, Fortran will print the current line and start rescanning the format. Therefore, it works!
• The way of generating blank lines discussed here is not a good one. We shall discuss a better way later on.