# Data Smoothing and Two-Column Table: Version 4

 WARNING: This example assumes spaces are ignored for the I and F descriptors and the output is sent to a printer.

### Problem Statement

We shall redo a program discussed previously in the data smoothing and two-column table. In fact, we shall take advantage of format scanning and the CHARACTER concatenation operator // discussed in CHARACTER Operator and Substring so that a single format can be used to print the whole table.

Suppose we have an input like the following. The first line gives the number of input values. Each of the input line has five fields with 10 positions each.

```         1    1    2    2    3    3    4    4
....5....0....5....0....5....0....5....0....5
17
13.5      17.23     9.0       20.9      23.0
16.3      15.9      21.5      14.78     18.5
16.54     13.67     10.78     9.5       13.2
19.6      20.0
```
Write a Fortran program that reads in the above input, computes the 2-moving average, and prints the following two-column table:
```         1    1    2    2    3    3    4    4    5
....5....0....5....0....5....0....5....0....5....0
**************************
*  Data Smoothing Table  *
**************************

No       x         y      No       x         y
---  --------  --------   ---  --------  --------
1     13.50        NA     2     17.23     15.36
3      9.00     13.11     4     20.90     14.95
5     23.00     21.95     6     16.30     19.65
7     15.90     16.10     8     21.50     18.70
9     14.78     18.14    10     18.50     16.64
11     16.54     17.52    12     13.67     15.11
13     10.78     12.23    14      9.50     10.14
15     13.20     11.35    16     19.60     16.40
17     20.00     19.80
```
Suppose the input values are x(1), x(2) and so on. The 2-moving average is computed as follows: y(1)=(x(1)+x(2))/2, y(2)=(x(2)+x(3))/2, y(3)=(x(3)+x(4))/2 and so on. In general, y(i)=(x(i)+x(i+1))/2. If x has n entries, y will have n-1 (i.e., y(n) cannot be computed).

Note that the first position is always for printer control.

### Solution

```PROGRAM  Smoothing
IMPLICIT  NONE
INTEGER, PARAMETER           :: MAX_SIZE = 20
REAL, DIMENSION(1:MAX_SIZE)  :: x, y
INTEGER                      :: Number
INTEGER                      :: i
CHARACTER(LEN=*), PARAMETER  :: TitleHeading  = "T14,A/T14,A/T14,A//T2,A,T28,A/T2,A,T28,A/"
CHARACTER(LEN=*), PARAMETER  :: NA_Line       = "T2,I3,F10.2,A10,I6,2F10.2/"
CHARACTER(LEN=*), PARAMETER  :: Data_Line     = "(1X,I3,2F10.2,I6,2F10.2)"
CHARACTER(LEN=100)           :: Format

DO i = 1, Number-1
y(i) = (x(i) + x(i+1)) / 2.0
END DO

Format = "(" // TitleHeading // NA_Line // Data_Line // ")"
WRITE(*,Format)  "**************************",             &
"*  Data Smoothing Table  *",             &
"**************************",             &
(" No       x         y    ", i = 1, 2),  &
("---  --------  --------  ", i = 1, 2),  &
1, x(1), "NA", 2, x(2), y(1),             &
(i, x(i), y(i-1), i = 3, Number)
END PROGRAM  Smoothing

```

### Program Input and Output

The output of the program is:
```         1    1    2    2    3    3    4    4    5
....5....0....5....0....5....0....5....0....5....0
**************************
*  Data Smoothing Table  *
**************************

No       x         y      No       x         y
---  --------  --------   ---  --------  --------
1     13.50        NA     2     17.23     15.36
3      9.00     13.11     4     20.90     14.95
5     23.00     21.95     6     16.30     19.65
7     15.90     16.10     8     21.50     18.70
9     14.78     18.14    10     18.50     16.64
11     16.54     17.52    12     13.67     15.11
13     10.78     12.23    14      9.50     10.14
15     13.20     11.35    16     19.60     16.40
17     20.00     19.80
```

### Discussion

• If you look at the desired output carefully, you will see that it has a title, heading, special line which contains a NA, and a group of unknown number of output lines. Since these output lines are at the end of the output, the format that describes a single line can be repeated. Thus, a possible format should have the following form:
```( descriptors for the title /
descriptors for the NA line /
( descriptors for a normal data line) )
```
If this can be done, a single WRITE and a single format can be used to generate the output.
• To this end, what we have to do is pull all formats used in the previous example together into a single format. First, let us remove the opening and closing parenthesis of each format:
```TitleHeading  = "T14,A/T14,A/T14,A//T2,A,T28,A/T2,A,T28,A/"
NA_Line       = "T2,I3,F10.2,A10,I6,2F10.2/"
Data_Line     = "(1X,I3,2F10.2,I6,2F10.2)"
```
Note that a slash / has been added to formats TitleHeading and NA_Line. This is because we do not have a closing parenthesis for completing the current output line and as a result a / is needed to do the job.
• Finally, we use the concatenation operator to join them together:
```Format = "(" // TitleHeading // NA_Line // Data_Line // ")"
```
Note that an opening and closing parenthesis is added. The concatenated result is the following:
```(