File:  [LON-CAPA] / capa / capa51 / Historic / capa_stats.c
Revision 1.3: download - view: text, annotated - select for diffs
Mon Aug 7 20:47:29 2000 UTC (23 years, 9 months ago) by albertel
Branches: MAIN
CVS tags: version_2_9_X, version_2_9_99_0, version_2_9_1, version_2_9_0, version_2_8_X, version_2_8_99_1, version_2_8_99_0, version_2_8_2, version_2_8_1, version_2_8_0, version_2_7_X, version_2_7_99_1, version_2_7_99_0, version_2_7_1, version_2_7_0, version_2_6_X, version_2_6_99_1, version_2_6_99_0, version_2_6_3, version_2_6_2, version_2_6_1, version_2_6_0, version_2_5_X, version_2_5_99_1, version_2_5_99_0, version_2_5_2, version_2_5_1, version_2_5_0, version_2_4_X, version_2_4_99_0, version_2_4_2, version_2_4_1, version_2_4_0, version_2_3_X, version_2_3_99_0, version_2_3_2, version_2_3_1, version_2_3_0, version_2_2_X, version_2_2_99_1, version_2_2_99_0, version_2_2_2, version_2_2_1, version_2_2_0, version_2_1_X, version_2_1_99_3, version_2_1_99_2, version_2_1_99_1, version_2_1_99_0, version_2_1_3, version_2_1_2, version_2_1_1, version_2_1_0, version_2_12_X, version_2_11_X, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, version_2_11_1, version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, version_2_10_X, version_2_10_1, version_2_10_0_RC2, version_2_10_0_RC1, version_2_10_0, version_2_0_X, version_2_0_99_1, version_2_0_2, version_2_0_1, version_2_0_0, version_1_99_3, version_1_99_2, version_1_99_1_tmcc, version_1_99_1, version_1_99_0_tmcc, version_1_99_0, version_1_3_X, version_1_3_3, version_1_3_2, version_1_3_1, version_1_3_0, version_1_2_X, version_1_2_99_1, version_1_2_99_0, version_1_2_1, version_1_2_0, version_1_1_X, version_1_1_99_5, version_1_1_99_4, version_1_1_99_3, version_1_1_99_2, version_1_1_99_1, version_1_1_99_0, version_1_1_3, version_1_1_2, version_1_1_1, version_1_1_0, version_1_0_99_3, version_1_0_99_2, version_1_0_99_1, version_1_0_99, version_1_0_3, version_1_0_2, version_1_0_1, version_1_0_0, version_0_99_5, version_0_99_4, version_0_99_3, version_0_99_2, version_0_99_1, version_0_99_0, version_0_6_2, version_0_6, version_0_5_1, version_0_5, version_0_4, stable_2002_spring, stable_2002_july, stable_2002_april, stable_2001_fall, release_5-1-3, loncapaMITrelate_1, language_hyphenation_merge, language_hyphenation, conference_2003, bz6209-base, bz6209, STABLE, HEAD, GCI_3, GCI_2, GCI_1, CAPA_5-1-6, CAPA_5-1-5, CAPA_5-1-4_RC1, BZ4492-merge, BZ4492-feature_horizontal_radioresponse, BZ4492-feature_Support_horizontal_radioresponse, BZ4492-Support_horizontal_radioresponse
- fixed license notices the reference the GNU GPL rather than the GNU LGPL

    1: /* early version of some statistics for CAPA
    2:    Copyright (C) 1992-2000 Michigan State University
    3: 
    4:    The CAPA system is free software; you can redistribute it and/or
    5:    modify it under the terms of the GNU General Public License as
    6:    published by the Free Software Foundation; either version 2 of the
    7:    License, or (at your option) any later version.
    8: 
    9:    The CAPA system is distributed in the hope that it will be useful,
   10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12:    General Public License for more details.
   13: 
   14:    You should have received a copy of the GNU General Public
   15:    License along with the CAPA system; see the file COPYING.  If not,
   16:    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   17:    Boston, MA 02111-1307, USA.
   18: 
   19:    As a special exception, you have permission to link this program
   20:    with the TtH/TtM library and distribute executables, as long as you
   21:    follow the requirements of the GNU GPL in regard to all of the
   22:    software in the executable aside from TtH/TtM.
   23: */
   24: 
   25: #include <stdio.h>
   26: #include <string.h>
   27: #include <math.h>
   28: #include <ctype.h>
   29: #ifdef __sun
   30: #include <unistd.h>
   31: #endif
   32: #ifdef NeXT
   33: #include <sys/file.h>
   34: #endif
   35: #include <stdlib.h>
   36: 
   37: /*--------------------------------------------------------------*/
   38: /* Constant Values for "hgr*.out".                              */
   39: /*--------------------------------------------------------------*/
   40: #define MAX_SECTION_NUMBER    3  /* maximum number of char for section number */
   41: #define MAX_STUDENT_NUMBER    9  /* maximum number of char for student number */
   42: #define MAX_STUDENT_NAME     30  /* maximum number of char for student name */
   43: #define MAX_PROBLEM_NUMBER  150  /* maximum number of problems in a set */
   44: #define FILE_NAME_LENGTH    256  /* maximum length of file name */
   45: #define MAX_CLASS_SIZE     1024  /* maximum number of students in a class */
   46: 
   47: 
   48: /*--------------------------------------------------------------*/
   49: /* Constant Values for "set*.db".                               */
   50: /*--------------------------------------------------------------*/
   51: #define MAX_TRIES           100  /* tries 0..99 */
   52: 
   53: 
   54: /*--------------------------------------------------------------*/
   55: /* One line of record in "hgr*.out".                            */
   56: /*--------------------------------------------------------------*/
   57: typedef struct{
   58:    char section[MAX_SECTION_NUMBER+1];
   59:    char s_number[MAX_STUDENT_NUMBER+1];
   60:    char s_name[MAX_STUDENT_NAME+1];
   61:    char problem_number[MAX_PROBLEM_NUMBER];
   62:    char problem_score[MAX_PROBLEM_NUMBER];
   63: } HGR_record;
   64: 
   65: int     GradedProblems=0;      /* The number of problems in a HG'd record */
   66: int     NumberOfUpdates=0;     /* The number of records need updated in hgr*.db */
   67: int     NumberOfProblems=0;
   68: char    *progname;
   69: HGR_record hgr_record[MAX_CLASS_SIZE];
   70: 
   71: 
   72: /*--------------------------------------------------------------*/
   73: /* One line of record in "set*.out".                            */
   74: /*--------------------------------------------------------------*/
   75: typedef struct{
   76:    int  valid;                          /* if a registered student */
   77:    char s_number[MAX_STUDENT_NUMBER+1]; /* student number */
   78:    char answer[MAX_PROBLEM_NUMBER];     /* a string of answers */
   79:    char tries[3*MAX_PROBLEM_NUMBER];
   80: } SET_record;
   81: 
   82: char  line1[512],line2[512],line3[512]; /* The first three lines in set*.db */
   83: int   NumberOfStudents=0;               /* Number of students in set*.db */
   84: int   ValidStudents=0;                  /* No. of Valid students in set*.db */
   85: SET_record set_record[MAX_CLASS_SIZE];
   86: 
   87: 
   88: /*--------------------------------------------------------------*/
   89: /*                                                              */
   90: /* Statistics for the number of tries in "set*.db".             */
   91: /*                                                              */
   92: /*--------------------------------------------------------------*/
   93: int   s[MAX_PROBLEM_NUMBER][MAX_TRIES];
   94: int   t[MAX_CLASS_SIZE][MAX_PROBLEM_NUMBER];
   95: int   YesCnt[MAX_PROBLEM_NUMBER];
   96: int   yesCnt[MAX_PROBLEM_NUMBER];
   97: int   correct[MAX_PROBLEM_NUMBER];
   98: int   Weight[MAX_PROBLEM_NUMBER];
   99: int   TotalTries[MAX_PROBLEM_NUMBER];
  100: 
  101: typedef struct{
  102:   int total;
  103:   int score[MAX_PROBLEM_NUMBER];
  104: }Student;
  105: 
  106: int GuyNumberOfStudents;
  107: Student student[MAX_CLASS_SIZE];
  108: #define PARTIAL 0
  109: #define NOPARTIAL 1
  110: /*--------------------------------------------------------------*/
  111: /*                                                              */
  112: /*                                                              */
  113: /*--------------------------------------------------------------*/
  114: void usage()
  115: {
  116:  printf("USAGE: %s [-s set] [-t LargeTry] [-n NumberLargeTry]\n", progname);
  117: }
  118: 
  119: 
  120: 
  121: /*--------------------------------------------------------------*/
  122: /*                                                              */
  123: /* Return the maximum score of a problem.                       */
  124: /*                                                              */
  125: /*--------------------------------------------------------------*/
  126: int Problem_Score(score_ptr,problem_number)
  127: char *score_ptr;
  128: char problem_number;
  129: {
  130:      char *tmp_ptr;
  131:      char score;
  132: 
  133:      tmp_ptr=strchr(score_ptr,problem_number);
  134:      tmp_ptr=tmp_ptr+2;
  135:      sscanf(tmp_ptr, "%c", &score);
  136:      return(score-'0');
  137: }
  138: 
  139: 
  140: /*--------------------------------------------------------------*/
  141: /*                                                              */
  142: /* Check if the list of scores is valid                         */
  143: /*                                                              */
  144: /*--------------------------------------------------------------*/
  145: int Valid_Score(scorelist,score_ptr)
  146: char *scorelist;
  147: char *score_ptr;
  148: {
  149:      char *problem;
  150:      int  score=-1;
  151:      int  value=1;
  152:      
  153:      GradedProblems=0;
  154:      problem = scorelist;
  155:      while (*problem == '('){
  156:          GradedProblems++;
  157:          problem++;
  158:          score=Problem_Score(score_ptr,*problem);
  159:          problem=problem+2;
  160:          if (*problem != '*'&&((*problem-'0')>score)){
  161:             value=0;  
  162:          }
  163:          problem=problem+3;
  164:      }
  165:      return(value);
  166: }
  167: 
  168: /*--------------------------------------------------------------*/
  169: /*                                                              */
  170: /* Open the hand graded file "./record/set`set`.out",           */
  171: /* and return the file pointer.                                 */
  172: /*                                                              */
  173: /*--------------------------------------------------------------*/
  174: FILE *Open_Read(filename)
  175: char  filename[FILE_NAME_LENGTH];
  176: {
  177:     FILE  *fp;
  178:  
  179:    if ((fp=fopen(filename,"r"))==NULL) {
  180:        printf("Error: can't open %s\n",filename);
  181:        exit(1);
  182:     }
  183:     return(fp);
  184: }
  185:  
  186: /*--------------------------------------------------------------*/
  187: /*                                                              */
  188: /* Open the hand graded file "./record/set`set`.out",           */
  189: /* and return the file pointer.                                 */
  190: /*                                                              */
  191: /*--------------------------------------------------------------*/
  192: FILE *Open_Write(filename)
  193: char  filename[FILE_NAME_LENGTH];
  194: {
  195:     FILE  *fp;
  196:  
  197:     if ((fp=fopen(filename,"w"))==NULL) {
  198:        printf("Error: can't open %s\n",filename);
  199:        exit(1);
  200:     }
  201:     return(fp);
  202: }
  203:  
  204: 
  205: int studentCompare(const void *a,const void *b)
  206: {
  207:   Student *voida,*voidb;
  208:   voida=(Student *)a;
  209:   voidb=(Student *)b;
  210:   if (voida->total < voidb->total)
  211:     return 1;
  212:   if (voida->total > voidb->total)
  213:     return -1;
  214:   return 0;
  215: }
  216: 
  217: /*--------------------------------------------------------------*/
  218: /*                                                              */
  219: /*                                                              */
  220: /*--------------------------------------------------------------*/
  221: void Read_Record(fp_set)
  222:      FILE *fp_set;
  223: {
  224:   int   count,i,j;
  225:   int   done,len;
  226:   int   problem;
  227:   int   problem_cnt;
  228:   char  fmtbuf[128];
  229:   char  nextline[512];
  230:   char  temp;
  231:   
  232:   fgets(line1,511,fp_set);  
  233:   sscanf(line1,"%d",&problem_cnt);
  234:   
  235:   fgets(line2,511,fp_set);  
  236:   len=strlen(line2);              /* weight line */
  237:   for(i=0;i<problem_cnt;i++)  {
  238:     Weight[i] = line2[i] - '0';  /* put weight into a global array */
  239:   }
  240:   
  241:   fgets(line3,511,fp_set);        /* get rid of hand grading line */
  242:   /* here problem_cnt should be the same as NumberOfProblems */
  243:   NumberOfProblems=strlen(line2)-1;
  244:   sprintf(fmtbuf,"%%%dc %%%dc%%%dc",
  245: 	  MAX_STUDENT_NUMBER, NumberOfProblems+1, 3*NumberOfProblems);
  246:   
  247:   done=0;
  248:   count=0;
  249:   while (!done){
  250:     done=!fgets(nextline,511,fp_set);
  251:     len=strlen(nextline);
  252:     if (!done){
  253:       count++;
  254:       sscanf(nextline, fmtbuf,
  255: 	     set_record[count].s_number,
  256: 	     set_record[count].answer,
  257: 	     set_record[count].tries);
  258:       /* printf("(%s)  (%s)  (%s)\n",
  259: 	 set_record[count].s_number,
  260: 	 set_record[count].answer,
  261: 	 set_record[count].tries); */
  262:       set_record[count].valid=0;
  263:       for (i=0;i<NumberOfProblems;i++){
  264: 	if (set_record[count].answer[i]!='-')
  265: 	  set_record[count].valid=1;
  266:       }
  267:     }
  268:   }
  269:   NumberOfStudents=count;
  270:   printf("%d",NumberOfStudents);
  271:   fclose(fp_set);
  272:   
  273:   for(j=0,i=0;i<NumberOfStudents;j++,i++)
  274:     {
  275:       for(problem=0;problem<NumberOfProblems;problem++)
  276: 	{
  277: 	  temp=set_record[i].answer[problem];
  278: 	  switch (temp)
  279: 	    {
  280: 	    case 'y': 
  281: 	    case 'Y':
  282: 	      student[j].score[problem]=Weight[problem];
  283: 	      student[j].total+=Weight[problem];
  284: 	      break;
  285: 	    case 'n':
  286: 	    case 'N':
  287: 	      student[j].score[problem]=0;
  288: 	      break;
  289: 	    default:
  290: 	      if (isdigit(temp))
  291: 		{
  292: 		  student[j].score[problem]=temp-'0';
  293: 		  student[j].total+=student[j].score[problem];
  294: 		}
  295: 	      else
  296: 		{
  297: 		  student[j].score[problem]=0;
  298: 		  student[j].total+=student[j].score[problem];
  299: 		  fprintf(stderr,"Invalid score for student ");
  300: 		  fprintf(stderr,"%s, problem",set_record[i].s_number);
  301: 		  fprintf(stderr,"%d, score == ",problem);
  302: 		  fprintf(stderr,"%c skipping them\n",temp);
  303: 		  j--;
  304: 		  goto skip_student;
  305: 		}
  306: 	    }
  307: 	}
  308:     skip_student: j=j;
  309:     }
  310:   GuyNumberOfStudents=j;
  311:   qsort((char *)student,GuyNumberOfStudents,sizeof(Student),studentCompare);
  312: }
  313:  
  314: 
  315: 
  316: /*--------------------------------------------------------------*/
  317: /*                                                              */
  318: /* t[i][j]: the number of tries for the `i`th student, the      */
  319: /*          `j`th problem in set*.db file.                      */
  320: /*          t[i][*]=set_record[i].tries                         */
  321: /* s[i][j]: the number of students who work on the `i`th        */
  322: /*          problem for `j` tries.                              */
  323: /*                                                              */
  324: /*--------------------------------------------------------------*/
  325: void Sort_By_Tries()
  326: {
  327:    int   i,j,try;
  328:    char  *tmp;
  329: 
  330:    /* initialization */
  331:    for (i=0;i<MAX_PROBLEM_NUMBER;i++){
  332:        YesCnt[i] = 0;
  333:        yesCnt[i] = 0;
  334:        correct[i] = 0;
  335:        TotalTries[i]=0;
  336:        for (j=0; j<MAX_TRIES; j++){
  337:            s[i][j]=0;
  338:        }
  339:        for (j=0;j<MAX_CLASS_SIZE;j++){
  340:            t[j][i]=0;
  341:        }
  342:    }
  343: 
  344:    for (i=0;i<NumberOfStudents;i++){
  345:        tmp=set_record[i].tries;
  346:        for (j=0; j<NumberOfProblems; j++){
  347:            sscanf(tmp+3*j,"%d,",&try);
  348:            if ((try>=0) && (try <=99)){
  349:               s[j][try]++;
  350:               t[i][j]=try;
  351:               TotalTries[j]=TotalTries[j]+try;
  352:            }
  353:        }
  354:    }
  355: 
  356: }
  357: 
  358: 
  359: double GetDegreeOfDiscrim(int problem,int mode)
  360: {
  361:   int i,numTopRight=0,numBottomRight=0,twentySevenPercent;
  362:   double dd;
  363: 
  364:   twentySevenPercent=(int)ceil(.27*(double)GuyNumberOfStudents);
  365:   for(i=0;i<twentySevenPercent;i++)
  366:     {
  367:       switch (mode)
  368: 	{
  369: 	case PARTIAL:
  370: 	  if (student[i].score[problem] > 0) { numTopRight++; }
  371: 	  if (student[GuyNumberOfStudents-i].score[problem]>0){numBottomRight++;}
  372: 	  break;
  373: 	case NOPARTIAL:
  374: 	  if (student[i].score[problem] == Weight[problem]) { numTopRight++; }
  375: 	  if (student[GuyNumberOfStudents-i].score[problem] == Weight[problem])
  376:             { numBottomRight++; }
  377: 	  break;
  378: 	}
  379:     }
  380:   dd=(((((double)numTopRight)/((double)twentySevenPercent))-
  381:        (((double)numBottomRight)/((double)twentySevenPercent))));
  382:   return 100.0*dd;
  383: }
  384: 	  
  385: double GetDifficulty(int problem, int mode)
  386: {
  387:   int i,numWrong=0;
  388:   for(i=0;i<GuyNumberOfStudents;i++)
  389:     {
  390:       switch(mode)
  391: 	{
  392: 	case PARTIAL:
  393: 	  if (student[i].score[problem] == 0) { numWrong++; }
  394: 	  break;
  395: 	case NOPARTIAL:
  396: 	  if (student[i].score[problem] < Weight[problem]) { numWrong++; }
  397: 	  break;
  398: 	}
  399:     }
  400:   return (100.0*((double)numWrong/(double)GuyNumberOfStudents));
  401: }
  402: 
  403: #define MAXSCORE 58
  404: void doScoreHistogram(void)
  405: {
  406:   int hist[MAXSCORE],i,numGoneBy=0;
  407:   for(i=0;i<MAXSCORE;i++)
  408:     hist[i]=0;
  409:   for(i=0;i<GuyNumberOfStudents;i++)
  410:     {
  411:       hist[student[i].total]++;
  412:     }
  413:   printf("Scr Num Tot\n");
  414:   for(i=0;i<MAXSCORE;i++)
  415:     {
  416:       numGoneBy+=hist[i];
  417:       printf("%3d %3d %3d\n",i,hist[i],numGoneBy);
  418:     }
  419: }
  420:   
  421: /*--------------------------------------------------------------*/
  422: /*                                                              */
  423: /* This is only used to print out the statistics in s[][],      */
  424: /* which stores the number of occurences in a form of           */
  425: /* s[problem_number-1][tries]. This is not normally used.       */
  426: /* For a  global view only.                                     */ 
  427: /*                                                              */
  428: /*--------------------------------------------------------------*/
  429: void Print_moment(avg,sd,sd3,m,students)
  430: float avg[MAX_PROBLEM_NUMBER];
  431: float sd[MAX_PROBLEM_NUMBER];
  432: float sd3[MAX_PROBLEM_NUMBER];
  433: int   m[MAX_PROBLEM_NUMBER];
  434: int   students[MAX_PROBLEM_NUMBER];
  435: {
  436:    int i;
  437:    float dod,disP,disNP,difP,difNP;
  438: 
  439:    printf("\nThis is the statistics for each problem:\n");
  440:    printf("Prob#   MxTries   avg.     s.d.    s.k.   #Stdnts ");
  441:    printf("  #Yes   #yes   Tries  DoDiff  Dis(P)  Dif(P) Dis(NP) Dif(NP)\n");
  442:    for (i=0;i<NumberOfProblems;i++){
  443:        dod=1.0-((float)(YesCnt[i]+yesCnt[i]+correct[i])/(float)TotalTries[i]);
  444:        disP=GetDegreeOfDiscrim(i,PARTIAL);
  445:        difP=GetDifficulty(i,PARTIAL);
  446:        disNP=GetDegreeOfDiscrim(i,NOPARTIAL);
  447:        difNP=GetDifficulty(i,NOPARTIAL);
  448:        printf("P %2d:",i+1);
  449:        printf("%7d  %8.2f  %7.2f  %6.2f   %5d   %5d  %5d    %5d  %5.2f   %5.2f   %5.2f  %6.2f %6.2f",
  450:               m[i],avg[i],sd[i],sd3[i],students[i],YesCnt[i],yesCnt[i],
  451:               TotalTries[i],dod,disP,difP,disNP,difNP);
  452:        printf("\n");
  453:    }
  454:    doScoreHistogram();
  455: }
  456: 
  457: 
  458: /*--------------------------------------------------------------*/
  459: /*                                                              */
  460: /* This is only used to print out the statistics in s[][],      */
  461: /* which stores the number of occurences in a form of           */
  462: /* s[problem_number-1][tries]. This is not normally used.       */
  463: /* For a  global view only.                                     */ 
  464: /*                                                              */
  465: /*--------------------------------------------------------------*/
  466: void Print_Tries()
  467: {
  468:    int i,j;
  469: 
  470:    printf("\nThis is the sumary of tries:\n");
  471:    for (i=0;i<NumberOfProblems;i++){
  472:        printf("P %d:",i+1);
  473:        for (j=0; j<MAX_TRIES; j++)
  474:            if (s[i][j]!=0)
  475:               printf("%d( %d)  ",j,s[i][j]);
  476:        printf("\n");
  477:    }
  478: }
  479: 
  480: /*--------------------------------------------------------------*/
  481: /*                                                              */
  482: /* This is only used to print out the statistics in s[][],      */
  483: /* which stores the number of occurences in a form of           */
  484: /* s[problem_number-1][tries]. This is not normally used.       */
  485: /* For a  global view only.                                     */
  486: /*                                                              */
  487: /*--------------------------------------------------------------*/
  488: 
  489: void Average_Tries()
  490: {
  491:    float avg[MAX_PROBLEM_NUMBER];
  492:    float sd[MAX_PROBLEM_NUMBER];
  493:    float sd3[MAX_PROBLEM_NUMBER];
  494:    int   students[MAX_PROBLEM_NUMBER];
  495:    int   m[MAX_PROBLEM_NUMBER];
  496:    int   i,j;
  497:    float tmp1,tmp2;
  498:    float sum;
  499: 
  500:    /* max tries for each problem */
  501:    for (i=0;i<NumberOfProblems;i++){
  502:        m[i]=0;
  503:        for (j=0;j<NumberOfStudents;j++){
  504:            if (t[j][i]>m[i]){
  505:               m[i]=t[j][i];
  506:            }
  507:        }
  508:    }
  509:    for (i=0;i<NumberOfStudents;i++){
  510:        if (set_record[j].valid){
  511:           ValidStudents++;
  512:        }
  513:    }
  514: 
  515:    /* first moment */
  516:    for (i=0;i<NumberOfProblems;i++){
  517:        avg[i]=0.0;                       /* initialization */
  518:        students[i]=0;
  519:        for (j=1;j<NumberOfStudents;j++){ 
  520:            if (set_record[j].valid){
  521:               avg[i]=avg[i]+t[j][i];     /* sumation actually */
  522:               students[i]=students[i]+1;
  523:            }
  524:        }
  525:        avg[i]=avg[i]/students[i];        /* real average */
  526:    }
  527: 
  528:    /* second moment */
  529:    for (i=0;i<NumberOfProblems;i++){ 
  530:        sd[i]=0.0;
  531:        sum=0.0;
  532:        for (j=0;j<NumberOfStudents;j++){
  533:            if (set_record[j].valid){                                  
  534:               tmp1=(float)t[j][i];
  535:               tmp2=(tmp1-avg[i])*(tmp1-avg[i]);
  536:               sum=sum+tmp2;
  537:            }
  538:            sd[i]=sum/(float)(students[i]-1);
  539:            sd[i]=sqrt((double) sd[i]); 
  540:        }
  541:    }
  542: 
  543:    /* third moment, skewness */
  544:    for (i=0;i<NumberOfProblems;i++){ 
  545:        sd3[i]=0.0;
  546:        sum=0.0;
  547:        for (j=0;j<NumberOfStudents;j++){
  548:            if (set_record[j].valid){     
  549:               tmp1=(float)t[j][i];
  550:               tmp2=(tmp1-avg[i])*(tmp1-avg[i])*(tmp1-avg[i]);
  551:               sum=sum+tmp2;
  552:            }
  553:            sd3[i]=sum/(float)(students[i]);
  554:            sd3[i]=sd3[i]/(sd[i]*sd[i]*sd[i]); 
  555:        }
  556:    }
  557:    Print_moment(avg,sd,sd3,m,students);     /* print mean, sd, skewness */
  558: }
  559: 
  560: /*--------------------------------------------------------------*/
  561: /*                                                              */
  562: /*                                                              */
  563: /*--------------------------------------------------------------*/
  564: void Percentage_Scores(set)
  565: int set;
  566: {
  567:   int    i,j;
  568:   int    total_weight = 0, 
  569:          total_scores=0;
  570:   float  percentage;
  571:   
  572:   for (i=0;i<NumberOfStudents;i++){
  573:       if (set_record[i].valid){
  574:          for (j=0;j<NumberOfProblems;j++){
  575:              total_weight = total_weight+Weight[j];
  576:              switch (set_record[i].answer[j]){
  577:                 case 'Y': YesCnt[j] = YesCnt[j]+1;
  578:                           total_scores = total_scores + Weight[j];
  579:                           break;
  580:                 case 'y': yesCnt[j] = yesCnt[j]+1;
  581:                           total_scores = total_scores + Weight[j];
  582:                           break;
  583:                 default : if (set_record[i].answer[j] >= '0' && 
  584:                               set_record[i].answer[j] <= '9' ) {
  585:                               correct[i]=correct[i]+1;
  586:                               total_scores=total_scores+(set_record[i].answer[j]-'0');
  587:                           } 
  588:                           break;
  589:              }
  590:          }
  591:       }
  592:   }
  593: 
  594:   percentage = (float)total_scores / (float)total_weight;
  595:   percentage = percentage * 100.0;
  596:   printf("\nThe percentage score for set%d.db is %7.2f%%\n",set,percentage);
  597:   /*printf("Total Number of Students in set%d.db is %d\n",set,ValidStudents);*/
  598: 
  599: }
  600: 
  601: /*--------------------------------------------------------------*/
  602: /*                                                              */
  603: /*                                                              */
  604: /*--------------------------------------------------------------*/
  605: void Large_Tries(LargeTry, NumberLargeTry)
  606: int LargeTry, NumberLargeTry;
  607: {
  608:    int   i,j;
  609:    int   count;
  610:    int   credit;              /* Number of credits should be taken off */
  611: 
  612: 
  613:    printf("\nHere is a list of students who have %d tries more than %d times: \n\n", LargeTry, NumberLargeTry);
  614: 
  615:    for (i=0;i<NumberOfStudents;i++){
  616:        count=0;
  617:        credit=0;
  618:        for (j=0;j<NumberOfProblems;j++){
  619:            if (t[i][j]>=LargeTry){
  620:               count++;
  621:               if (set_record[i].answer[j]=='Y' ||
  622:                   set_record[i].answer[j]=='y')
  623:                   credit ++;
  624:            } 
  625:        }
  626:        if (count >= NumberLargeTry){
  627:           printf("(%d)  %s \n",credit, set_record[i].s_number);
  628:           printf("%s %s \n", set_record[i].answer, set_record[i].tries);
  629:        }
  630:    }
  631: 
  632: }
  633: 
  634: /*--------------------------------------------------------------*/
  635: /*                                                              */
  636: /*                                                              */
  637: /*--------------------------------------------------------------*/
  638: int main(argc,argv)
  639: int argc;
  640: char *argv[];
  641: 
  642: {
  643: 
  644:     int    set=1;
  645:     int    inputNotOK=1;
  646:     int    LargeTry=0,NumberLargeTry=0;
  647:     FILE   *fp_set;
  648:     char   set_file[FILE_NAME_LENGTH];
  649:     char   path[FILE_NAME_LENGTH];
  650:     char   filename[FILE_NAME_LENGTH];
  651:    
  652:     for( progname = *argv++; --argc; argv++) {
  653:       if ( argv[0][0] == '-' ) {
  654:         switch(argv[0][1]) {
  655:            case 's':  set = atoi(argv[1]);            break;
  656:            case 't':  LargeTry = atoi(argv[1]);       break;
  657:            case 'n':  NumberLargeTry = atoi(argv[1]); break; 
  658:            default:   usage();                        break;
  659:         }
  660:       }
  661:     }
  662: 
  663:     while ( inputNotOK ) {
  664:        puts("Enter the ABSOLUTE path of class");
  665:        scanf("%s", path);
  666:        if( access(path, F_OK) == -1 ) {
  667:        } else {
  668:           sprintf(filename,"%s/records",path);
  669:           if( access(filename, F_OK) == -1 ) {
  670:             puts("There isn't a records dir in this CLASS directory");
  671:             puts("Please Specify another calss");
  672:           } else {
  673:             inputNotOK = 0;
  674:           }
  675:        }
  676:     }
  677:     chdir(path);
  678:     sprintf(set_file, "records/set%d.db",set);
  679:     /* sprintf(out_file, "records/set%d.out",set); */
  680:     fp_set=Open_Read(set_file);
  681:     /* fp_out=Open_Write(out_file); */
  682: 
  683:     Read_Record(fp_set);
  684:    
  685:     Sort_By_Tries();   
  686:     /* Print_Tries(); */
  687:     Percentage_Scores(set);
  688:     Average_Tries();
  689:     
  690:     Large_Tries(LargeTry, NumberLargeTry);  
  691:     return 0;
  692: }
  693: 
  694: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>