/*
 * grades_2.c
 * This program reads a series of grades, terminated by (-1), and computes
 * the average and variance.
 * In case the user the code (-2) the program aborts and prints no statistics.
 */

#include <stdio.h>

int main ()
{
  const int min_grade = 0;
  const int max_grade = 100;
  const int stop_code = -1;
  const int abort_code = -2;
  int       curr_grade;            /* The current grade. */
  int       sum_grades = 0;        /* The sum of all grades so far. */
  int       sum_sqr_grades = 0;    /* The sum of their squares. */
  int       n_grades = 0;          /* The number of legal grades so far. */
  float     average;
  float     variance;

  /* Notice that the loop is theoretically infinite. */
  while (1)
  {
    /* Read the current grade. */
    printf ("Please enter the next grade (or: -1 to stop, -2 to abort): ");
    scanf ("%d", &curr_grade);

    /* Stop if necessary. */
    if (curr_grade == stop_code)
      break;

    /* Abort the program if necessary. */
    if (curr_grade == abort_code)
      goto abort;

    /* Ignore illegal values. */
    if (curr_grade < min_grade || curr_grade > max_grade)
    {
      printf ("Ignoring illegal grade (%d).\n", curr_grade);
      continue;
    }

    /* Update our sums. */
    sum_grades += curr_grade;
    sum_sqr_grades += curr_grade * curr_grade;
    n_grades++;
  }

  /* Compute the average and variance. */
  if (n_grades > 0)
  {
    average = (float)sum_grades / (float)n_grades;

    /* Using the equality: Var(X) = E(X^2) - E(X)*E(X) */
    variance = (float)sum_sqr_grades / (float)n_grades - average * average;

    printf ("Average grade is %g (variance = %g).\n", average, variance);
  }

  return (0);

  /* Code executed in case the user requested to abort the program: */
 abort:
  printf ("Program aborted!\n");
  return (1);
}

