# Print Means

 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 to print the multiplication table in the following form:
```         1    1    2    2    3    3
....5....0....5....0....5....0....5
Input Data

a =       1.0000000
b =       2.0000000
c =       3.0000000

Computed Results

Arithmetic Mean =       2.0000000
Geometric Mean  =       1.8171207
Harmonic Mean   =       1.6363636

```

### Solution

```PROGRAM  Means
IMPLICIT  NONE
REAL                        :: a, b, c
REAL                        :: Am, Gm, Hm
CHARACTER(LEN=*), PARAMETER :: FMT = "(1X, A//3(1X, A, F15.7/))"

Am = (a + b + c)/3.0
Gm = (a * b * c)**(1.0/3.0)
Hm = 3.0 / (1.0/a + 1.0/b + 1.0/c)
WRITE(*,FMT) "Input Data",   &
"a = ", a,      &
"b = ", b,      &
"c = ", c
WRITE(*,FMT) "Computed Results",  &
"Arithmetic Mean = ", Am, &
"Geometric Mean  = ", Gm, &
"Harmonic Mean   = ", Hm

END PROGRAM  Means
```

### Program Input and Output

Suppose we have the following input:
```         1    1    2    2    3
....5....0....5....0....5....0
1.0       2.0       3.0
```
The output of the program is:
```         1    1    2    2    3    3
....5....0....5....0....5....0....5
Input Data

a =       1.0000000
b =       2.0000000
c =       3.0000000

Computed Results

Arithmetic Mean =       2.0000000
Geometric Mean  =       1.8171207
Harmonic Mean   =       1.6363636

```

### Discussion

• If you look at the output carefully, it consists of two parts: the input and the results. Each part has a title (i.e., Input Data and Computed Results), followed by three output lines in a form of a CHARACTER string followed by a REAL. This implies that a single format can cover both parts.
• To print the title, A is sufficient. Since there is a blank line between the title and the next output line, we need two /s. You can use either 2/ or //. So far, we have the following:
```(1X, A//....)
```
Thus, the title is printed with A. Then, we see the first / forces the end of the first output line. The next / forces the end of the second output line.

For each output, since it has a form of character followed by a real. We can use 1X, A, F15.7. Since each of these output is on its own line, we need a / to terminate the current line. As a result, printing one output line requires 1X,A,F15.7/. Since we have three such output lines, we can repeat this group three times 3(1X,A,F15.7/). Appending this part to the format, we have

```(1X, A//3(1X, A, F15.7/))
```
Note that 1X is used to skip the first position for printer control.
• Let us match the edit descriptors and variables. Here is the first WRITE statement of the program:
```CHARACTER(LEN=*), PARAMETER :: FMT = "(1X, A//3(1X, A, F15.7/))"

WRITE(*,FMT) "Input Data",   &
"a = ", a,      &
"b = ", b,      &
"c = ", c
```
Once this WRITE starts, Fortran begins format scanning with 1X which skips the first position of the first output line. Then, Fortran sees A, which requires a value. Thus, scanning stops here (temporarily) and looks for a value. The next value to be printed is the CHARACTER string "Input Data". Therefore, it is printed with A. Then, format scanning continues and sees /, which forces to end the first output line. Format scanning continues and sees the second /, which forces the end of the second output line. Up to now, we have the following output:
```         1    1    2    2    3    3
....5....0....5....0....5....0....5
Input Data                          <----- printed by 1X, A /
<----- printed by the second /
```
• Format scanning continues and sees the 1X in the group and then A. This causes the CHARACTER string "a = " printed. Then, Fortran sees F15.7, which is used to print the value of a. After printing with F15.7, format scanning continues, sees / and terminates this third output line. Then, it is the end of group, which has only been iterated once. Thus, Fortran goes back to use this group the second time. At this moment, we have the following output:
```         1    1    2    2    3    3
....5....0....5....0....5....0....5
Input Data                          <----- printed by 1X, A /
<----- printed by the second /
a =       1.0000000                 <----- printed by 1X,A,F15.7 /
```
• The next two iterations of 1X,A,F15.7 print "b = ", the value of b, "c = ", and the value of c. After the value of c is printed using F15.7, format scanning continues and sees /. This causes advancing to the sixth output line. The output is:
```         1    1    2    2    3    3
....5....0....5....0....5....0....5
Input Data                          <----- printed by 1X, A /
<----- printed by the second /
a =       1.0000000                 <----- printed by 1X,A,F15.7 /
b =       2.0000000                 <----- printed by 1X,A,F15.7 /
c =       3.0000000                 <----- printed by 1X,A,F15.7 /
```
• Are we done? Not yet! After printing 1X,A,F15.7/ three times, we are not at the end of format. In fact, we are only at the end of the group. So, format scanning continues and sees the end of format. This WRITE completes; however, since we did not put anything into the buffer output line (it is all spaces), Fortran prints the current buffer output line which contains all spaces.
```         1    1    2    2    3    3
....5....0....5....0....5....0....5
Input Data                          <----- printed by 1X, A /
<----- printed by the second /
a =       1.0000000                 <----- printed by 1X,A,F15.7 /
b =       2.0000000                 <----- printed by 1X,A,F15.7 /
c =       3.0000000                 <----- printed by 1X,A,F15.7 /
<----- printed by the end of format!
```
This is the reason that there is a blank line between the line containing the value of c and the title line of the second part.
```         1    1    2    2    3    3
....5....0....5....0....5....0....5
Input Data                          <----- printed by 1X, A /
<----- printed by the second /
a =       1.0000000                 <----- printed by 1X,A,F15.7 /
b =       2.0000000                 <----- printed by 1X,A,F15.7 /
c =       3.0000000                 <----- printed by 1X,A,F15.7 /
<----- printed by the end of format!
Computed Results                    <----- printed by 1X, A /
<----- printed by the second /
Arithmetic Mean =       2.0000000   <----- printed by 1X,A,F15.7 /
Geometric Mean  =       1.8171207   <----- printed by 1X,A,F15.7 /
Harmonic Mean   =       1.6363636   <----- printed by 1X,A,F15.7 /
<----- printed by the end of format!
```