%{
#include <stdio.h>
#include "lib.c"

int regno, t1, line=0;
float t2, csav;
char school[10];
int max=0, course;
enum {matsize=1000};
char courses[matsize][10];
struct stat2 *stats[matsize];
struct stat *diffs[matsize];
struct stat *allmarks, *csavmarks;

int lookup (char course[])
{
  int i;
  for (i=0; i<max; i++)
    if (!strcmp(courses[i], course))
      return i;
  strcpy(courses[max], course);
  stats[max]= structstat2();
  diffs[max]= structstat();
  return max++;
}

/* inputs look like:	9612346 EXT     CS1511  75.0	but CSAV must come first for each student! */

%}

%x two three four

%%

^[0-9]+			{t1=atoi(yytext); line++; BEGIN two;}
<two>[A-Za-z]+[0-9]?	{strcpy(school, yytext); BEGIN three;}
<three>[_A-Za-z0-9]+	{course= lookup(yytext); BEGIN four;}
<four>[-0-9.]+		{t2=atof(yytext);
			if(regno!=t1) { /*next student */
			  if (course!=0) {
			    printf("oops - CSAV should be first for each student (line %d)\n", line);
			    printf("regno=%d t1=%d\n", regno, t1);
			    exit(1);
			  }
			  regno= t1;
			  csav= t2;
			  acc(csavmarks, t2);
			} else {
			  acc(allmarks, t2);
			  acc(diffs[course], t2-csav);
			  acc(diffs[0], t2-csav);
			  acc2(stats[course], csav, t2);
			  acc2(stats[0], csav, t2);
			}
			BEGIN 0;
			}

[ \t\n]+		/*ECHO*/;
<two>[ \t\n]+		/*ECHO*/;
<three>[ \t\n]+		/*ECHO*/;
<four>[ \t\n]+		/*ECHO*/;
.			{printf("ERROR:%c", yytext[0]);}

%%

int yywrap (void)
{
  return 1;
}

/*extern int yy_flex_debug;*/

int main (int argc, char *argv[])
{
  int i, result, n;
  float t, xbar[matsize], s[matsize];
  FILE *course;
  char name[100];
  struct stat *examav= structstat();
  struct stat *examav2= structstat();

  yy_flex_debug= 0;

  regno= 0;
  lookup("_CSAV"); /* -> index 0 */
  if (argc<2) {
    printf("error - course list file name expected\n");
    exit(1);
  }
  course= fopen(argv[1],"r");  
  if (course==NULL) {
    printf("error - unable to open course list file %s\n", argv[1]);
    exit(1);
  }
  while (fgets(name, 100, course)!=NULL) {
    i= strlen(name);
    name[i-1]=0;
    lookup(name);
  }
  fclose(course);

  allmarks= structstat();
  csavmarks= structstat();
  //csavmarks->trace= 1;

  result= yylex();

  done(allmarks);
  done(csavmarks);

  printf("\t--------- differences from CSAV -------------");
  //printf("\t\t");
  printf("\t    exam\t    CSAV");
  //printf("\t\t");
  printf("\t\t\tsigma/sigma");
  printf("\t\tlinear regression");
  printf("\n");

  printf("course\t    n\t  mean\t stdev\t  skew\t  kurt");
  printf("\te(mean)"); /* error in mean, in sigmas of ALL */
  //printf("\tt-mean\tx2-var");
  printf("\t mean\t stdev");
  printf("\t mean\t stdev");
  printf("\t  corr explains");
  //printf("\t t z\t error");
  printf("\tex=a +AV*slope +-error");
  printf("\tex=a +AV*slope +-error");
  printf("\n");

  printf("CSAV");
  printf("\t%6d", csavmarks->n);
  printf("\t%6.2f", csavmarks->mean);
  printf("\t%6.2f", csavmarks->sigma);
  printf("\t%6.2f", csavmarks->skew);
  printf("\t%6.2f", csavmarks->kurtosis);
  //printf("\t%6.2f", csavmarks->var);
  printf("\n");

  printf("ALL");
  printf("\t%6d", allmarks->n);
  printf("\t%6.2f", allmarks->mean);
  printf("\t%6.2f", allmarks->sigma);
  printf("\t%6.2f", allmarks->skew);
  printf("\t%6.2f", allmarks->kurtosis);
  //printf("\t%6.2f", allmarks->var);
  printf("\n");

  for (i=0; i<max; i++) {
    printf("%s", courses[i]);
    done(diffs[i]);
    done2(stats[i]);
    printf("\t%6d", diffs[i]->n);
    printf("\t%6.2f", diffs[i]->mean);
    printf("\t%6.2f", diffs[i]->sigma);
    printf("\t%6.2f", diffs[i]->skew);
    printf("\t%6.2f", diffs[i]->kurtosis);

    //if (i==0) {
    //  printf("\t%6.2f", diffs[i]->var);
    //} else {

      // t-test for mean v. overall mean for these students
      printf("\t%6.2f", diffs[i]->mean*sqrt(diffs[i]->n)/allmarks->sigma);

      // t-test for mean v. overall mean for all students
      //printf("\t%6.2f", (stats[i]->y.mean-allmarks->mean)*sqrt(diffs[i]->n)
	//		/allmarks->sigma);

      // chi-sq-test for var v. overall var for all students, d.f. = n
      //printf("\t%6.2f",stats[i]->y.var*sqrt(diffs[i]->n)/allmarks->var);

      /* means, sigmas, corr */
      printf("\t%6.2f\t%6.2f", stats[i]->y.mean, stats[i]->y.sigma);
      if (i!=0) {
        acc(examav, stats[i]->y.mean);
        acc(examav2, diffs[i]->mean);
      }
      printf("\t%6.2f\t%6.2f", stats[i]->x.mean, stats[i]->x.sigma);
      printf("\t%6.2f\t%6.0f%%", stats[i]->corr, stats[i]->explains);

      //printf("\t%6.2f\t%6.2f", stats[i]->tz, stats[i]->tzerror);

      /* line-fitting */
      fit_sigma(stats[i]);
      printf("\t%6.2f\t%6.2f\t%6.2f", stats[i]->c, stats[i]->a, stats[i]->e);
      fit_xy(stats[i]);
      printf("\t%6.2f\t%6.2f\t%6.2f", stats[i]->c, stats[i]->a, stats[i]->e);
    //}
    printf("\n");
  }

  done(examav);
  printf("exam avs: mean= %6.2f, sigma= %6.2f, var=%6.2f\n",
	 examav->mean, examav->sigma, examav->var);
  variances(allmarks->var, examav->var, csavmarks->var,
	    examav->n-1, csavmarks->n-1);
  printf("\n");
  done(examav2);
  printf("exam diffs: mean= %6.2f, sigma= %6.2f, var=%6.2f\n",
	 examav2->mean, examav2->sigma, examav2->var);
  variances(allmarks->var, examav2->var, csavmarks->var,
	    examav2->n-1, csavmarks->n-1);

  return result;
}
