#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define DATA_FILE "stats.dat"  /* File we are reading from */

/* Program to read a data file and calculate mean, var and s.d. */


const int MAX_LEN= 256;   /* Used in getting input from user */
const int NO_DATA= 100    /* No. of data items to read */

double calc_mean (double [], int);
/* Calculate the mean of an array of doubles */
double calc_var(double [], int, double);
/* Calculate the variance of an array of doubles */

int main()
{
    int i;
    double data[NO_DATA];    /* Data to read from file */
    double mean, variance;   /* Mean and variance of data */
    char string [MAX_LEN];  /* String for user inputs */
    FILE *fptr;  
    
    fptr= fopen (DATA_FILE, "r");
    if (fptr == NULL) {
        fprintf (stderr, "Unable to open file for reading\n");
        return -1;
    }
    for (i= 0; i < NO_DATA; i++) {
        if (fgets (string, MAX_LEN, fptr) == NULL) {
            printf ("Unexpected end to data \n");
            fclose (fptr);
            return 0;
        }
        data[i]= atof(string);
        mean= calc_mean(data, i+1);
        variance= calc_var(data, i+1, mean);
        printf ("Read %f.  Mean %f.  Variance %f  \n", data[i],
           mean, variance);
    } 
    fclose (fptr);
    return 0;
}

double calc_mean (double data[], int no_data)
/* Calculate the mean of no_data points of data */
{
    double sum;  /* Total of all data points */
    
    int i;
    sum= 0;
    for (i= 0; i < no_data; i++)
        sum+= data[i];
    return sum/no_data;
}

double calc_var (double data [], int no_data, double mean)
/* Calculate the variance of a data set as with calc_mean given that
we know the mean - note that we _could_ use calc_mean within this
function but that would be inefficient since in main we calculated
mean before hand*/

{
    double variance;
    int i;
    
    if (no_data <= 1)
        return 0;
    variance= 0;
    for (i= 0; i < no_data; i++) {
        variance+= (data[i] - mean) * (data[i] - mean);
    }
    variance= variance/ (no_data - 1);
    /* Note also that some definitions of sample variance divide by n-1 here */
    return variance;

}


