Logo Search packages:      
Sourcecode: wims version File versions  Download package

score.c

/*    Copyright (C) 1998 XIAO, Gang of Universite de Nice - Sophia Antipolis
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

      /* Routines treating user scores. */

double scorerequire[64][64];
double scoreweight[64][64];
double scoreuser[64][64];
double scoremean[64][64];
int    scorenew[64][64];
int    scorehint[64][64];
int    scoretry[64][64];
double scoresum[64];
int gotrequire=0, gotweight=0, gotscore=0, totsheets=0, totexos[64];
int score_ispublic=0;
char gotuser[256];
int score_status=-1;          /* save of score status */
int score_statussheet=-1;
int score_statusisexam=-1;

int getscorestatus(int classe, int sheet);

      /* Internal routine. */
int _getscoredata(int classe, char *dataf, double buf[64][64],int *tag)
{
    int  i,j,positive=0;
    char *c, *p1, *p2;
    double d;
    char fname[1024], linebuf[1024];
    WORKING_FILE da;

    if(classe==0) {
      c=getvar("wims_class");
      if(c==NULL) return -1;
      classe=atoi(c); if(classe<=0) return -1;
    }
    if(*tag==classe) return 0;
    memset(buf,0,sizeof(buf));
    snprintf(fname,sizeof(fname),"%s/classes/%u/sheets/%s",log_dir,classe,dataf);
    if(open_working_file(&da,fname)!=0) return -1;
    i=0; while(i<64 && wgetline(linebuf,sizeof(linebuf)-1,&da)!=EOF) {
      for(j=0,p1=find_word_start(linebuf);
          j<64 && *p1!=0; p1=find_word_start(p2),j++) {
          p2=find_word_end(p1); 
          if(*p2!=0) *(p2++)=0;
          d=atof(p1); if(d>0) {
            buf[i][j]=d; positive++;
          }
      }
      totexos[i]=j;
      i++;
    }
    close_working_file(&da);
    totsheets=i;
    *tag=classe; return positive;
}

      /* read require file. returns -1 if error, 0 otherwise. */
int getscorerequire(int classe)
{
    return _getscoredata(classe,".require",scorerequire,&gotrequire);
}

      /* read score weight file. returns -1 if error, 0 otherwise. */
int getscoreweight(int classe)
{
    return _getscoredata(classe,".weight",scoreweight,&gotweight);
}

      /* sum score requirements and weights. Calls the above
       * two routines getscorerequire() and getscoreweight(). */
int getscoresum(int classe)
{
    int i,j;
    if(getscorerequire(classe)<0 || getscoreweight(classe)<0) 
      return -1;
    for(i=0;i<totsheets;i++) {
      scoresum[i]=0;
      for(j=0;j<totexos[i];j++)
        scoresum[i]+=scorerequire[i][j]*scoreweight[i][j];
    }
    return 0;
}

      /* gather user score, core routine. */
int getscoreuser(int classe, char *user)
{
    int i,j,sheet,exo;
    char *pm[16], *pp;
    char *nowuser, *nowsheet, *nowexo, *nowscore;
    int nsheet,nexo; double nscore;
    char namebuf[1024], linebuf[1024];
    char oldsession[256];
    int oldsheet, oldexo;
    double score;
    WORKING_FILE logf;
    
    if(*user==0) {
      user=getvar("wims_user");
      if(user==NULL || *user==0) return -1;
    }
    if(getscoresum(classe)<0) return -1;
    gotuser[sizeof(gotuser)-1]=0;
    if(gotscore==classe && strcmp(user,gotuser)==0) return 0;
    snprintf(namebuf,sizeof(namebuf),"%s/classes/%u/score/%s",log_dir,classe,user);
    if(open_working_file(&logf,namebuf)!=0) return -1;
    memset(scoreuser,0,sizeof(scoreuser));
    memset(scorenew,0,sizeof(scorenew));
    memset(scorehint,0,sizeof(scorehint));
    memset(scoretry,0,sizeof(scoretry));
    oldsession[0]=oldsheet=oldexo=0;
    while(wgetline(linebuf,sizeof(linebuf)-1,&logf)!=EOF) {
      if(linebuf[0]=='E') continue;
      for(i=0,pm[0]=pp=find_word_start(linebuf);i<10 && *pp!=0;i++) {
          pp=find_word_end(pm[i]); 
          if(*pp!=0) *pp++=0;
          pp=find_word_start(pp); pm[i+1]=pp;
      }
      if(strcmp(pm[i-1],"noscore")==0 || strcmp(pm[i-1],"erased")==0)
        continue;
      sheet=atoi(pm[2]); exo=atoi(pm[3]);
      if(sheet<=0 || sheet>64 || exo<=0 || exo>64) continue;
      if(strcmp(pm[4],"score")==0) {
          score=atof(pm[5]);
            /* measure to prohibit simultaneous scoring. */
          if(strcmp(pm[1],oldsession)==0 &&
             sheet==oldsheet && exo==oldexo) {
            scoreuser[sheet-1][exo-1]+=score;
            scoretry[sheet-1][exo-1]++;
            oldsheet=oldexo=0;
          }
      }
      else {
          if(strcmp(pm[4],"resume")!=0) {
            if(strcmp(pm[4],"hint")==0) scorehint[sheet-1][exo-1]++;
            else scorenew[sheet-1][exo-1]++;
          }
          snprintf(oldsession,sizeof(oldsession),"%s",pm[1]);
          oldsheet=sheet; oldexo=exo;
      }
    }
    close_working_file(&logf);
    nowuser=getvar("wims_user"); if(nowuser==NULL || *nowuser==0) goto added;
    nowscore=getvar("module_score"); if(nowscore==NULL || *nowscore==0) goto added;
    nowsheet=getvar("wims_sheet");if(nowsheet==NULL || *nowsheet==0) goto added;
    nowexo=getvar("wims_exo"); if(nowexo==NULL || *nowexo==0) goto added;
    nsheet=atof(nowsheet); nexo=atof(nowexo);
    if(getscorestatus(classe,nsheet)==0) goto added;
    nscore=atof(nowscore);
    if(nsheet<1 || nexo<1 || nscore<0 || nscore>10 || nsheet>64 || nexo>64)
      goto added;
    scoreuser[nsheet-1][nexo-1]+=nscore;
    scoretry[nsheet-1][nexo-1]++;
    added:
    for(i=0;i<totsheets;i++) for(j=0;j<totexos[i];j++) {
      if(scorenew[i][j]>0 && scoretry[i][j]>0) {
          /* At most one hint is counted as new. */
          if(scorehint[i][j]>=1) scorenew[i][j]++;
          /* here we give up to 1 time unsuccessful tries.
           * Together with a premium of 5 uncounted tries. */
          if(scorenew[i][j]<scoretry[i][j]*2+5)
            scorenew[i][j]=scoretry[i][j];
          else scorenew[i][j]=(scorenew[i][j]-4)/2;
          scoremean[i][j]=scoreuser[i][j]/scorenew[i][j];
          if(scoreuser[i][j]>scorerequire[i][j])
            scoreuser[i][j]=scorerequire[i][j];
      }
      else scoremean[i][j]=scoreuser[i][j]=0;
    }
    gotscore=classe;
    snprintf(gotuser,sizeof(gotuser),"%s",user);
    return 0;
}

char *scorepname[]={
     "class","user","sheet","work","exam"
};
#define scorepname_no (sizeof(scorepname)/sizeof(scorepname[0]))
int score_class,score_sheet,score_exo,score_isexam;
char score_user[256];

      /* Uniformed treatment of score command parameters
       * format: class=? user=? sheet=? work=?
       * all are optional. */
void _scoreparm(char *p)
{
    int i;
    char *pn, *pe, *pd, *pf;
    char sav;
    
    score_class=score_sheet=score_exo=score_isexam=score_ispublic=0;
    score_user[0]=0;
    for(i=0;i<scorepname_no;i++) {
      pf=p;
      ahead:
      pn=strstr(pf,scorepname[i]); pf=pn+1;
      if(pn==NULL) continue;
      if(pn>p && !isspace(*(pn-1))) goto ahead;
      pe=find_word_start(pn+strlen(scorepname[i]));
      if(*pe!='=') goto ahead;
      pd=find_word_start(pe+1);
      pf=find_word_end(pd);
      if(pf<=pd) continue;
      sav=*pf; *pf=0;
      switch(i) {
          case 0: /* class */
            score_class=atoi(pd); break;
          case 1: /* user */
            snprintf(score_user,sizeof(score_user),"%s",pd); break;
          case 2: { /* sheet */
            if(*pd=='P') {pd++; score_ispublic=1;}
            score_sheet=atoi(pd);
            break;
          }
          case 3: /* work */
            score_exo=atoi(pd); break;
          case 4: /* exam */
            score_isexam=1; break;
      }
      *pf=sav; strcpy(pn, pf);
    }
    *p=0;
    if((score_class!=0 || score_user[0]!=0) && !trusted_module()) {
      module_error("not_trusted"); return;
    }
    if(score_class==0) {
      char *classe;
      classe=getvar("wims_class");
      if(classe==NULL || *classe==0) return;
      else score_class=atoi(classe);
    }
    if(score_user[0]==0) {
      char *user;
      user=getvar("wims_user");
      if(user!=NULL) snprintf(score_user,sizeof(score_user),"%s",user);
    }
}

      /* gather user score. */
void calc_getscore(char *p)
{
    int i,j;

    _scoreparm(p);
    if(score_class==0 || *score_user==0) return;
    if(getscoreuser(score_class,score_user)<0) return;
    for(*p=0,i=0;i<totsheets;i++) {
      if(score_sheet!=0 && i!=score_sheet-1) continue;
      for(j=0;j<totexos[i];j++) {
          if(score_exo!=0 && j!=score_exo-1) continue;
          sprintf(p+strlen(p),"%.2f ",scoreuser[i][j]);
      }
      strcat(p,"\n");
    }
}

      /* gather user score average. */
void calc_getscoremean(char *p)
{
    int i,j;

    _scoreparm(p);
    if(score_class==0 || *score_user==0) return;
    if(getscoreuser(score_class,score_user)<0) return;
    for(*p=0,i=0;i<totsheets;i++) {
      if(score_sheet!=0 && i!=score_sheet-1) continue;
      for(j=0;j<totexos[i];j++) {
          if(score_exo!=0 && j!=score_exo-1) continue;
          sprintf(p+strlen(p),"%.2f ",scoremean[i][j]);
      }
      strcat(p,"\n");
    }
}

      /* gather remaining of score to get for user. */
void calc_getscoreremain(char *p)
{
    int i,j;

    _scoreparm(p);
    if(score_class==0 || *score_user==0) return;
    if(getscoreuser(score_class,score_user)<0) return;
    for(*p=0,i=0;i<totsheets;i++) {
      if(score_sheet!=0 && i!=score_sheet-1) continue;
      for(j=0;j<totexos[i];j++) {
          if(score_exo!=0 && j!=score_exo-1) continue;
          sprintf(p+strlen(p),"%.2f ",scorerequire[i][j]-scoreuser[i][j]);
      }
      strcat(p,"\n");
    }
}

      /* Require score table. */
void calc_getscorerequire(char *p)
{
    int i,j;

    _scoreparm(p);
    if(score_class==0 || getscorerequire(score_class)<0) return;
    for(*p=0,i=0;i<totsheets;i++) {
      if(score_sheet!=0 && i!=score_sheet-1) continue;
      for(j=0;j<totexos[i];j++) {
          if(score_exo!=0 && j!=score_exo-1) continue;
          sprintf(p+strlen(p),"%.2f ",scorerequire[i][j]);
      }
      strcat(p,"\n");
    }
}

      /* Score weight table. */
void calc_getscoreweight(char *p)
{
    int i,j;

    _scoreparm(p);
    if(score_class==0 || getscoreweight(score_class)<0) return;
    for(*p=0,i=0;i<totsheets;i++) {
      if(score_sheet!=0 && i!=score_sheet-1) continue;
      for(j=0;j<totexos[i];j++) {
          if(score_exo!=0 && j!=score_exo-1) continue;
          sprintf(p+strlen(p),"%.2f ",scoreweight[i][j]);
      }
      strcat(p,"\n");
    }
}

      /* percentage of work done for each sheet. */
void calc_getscorepercent(char *p)
{
    int i,j;
    double tot, mean, d;

    _scoreparm(p);
    if(score_class==0 || *score_user==0) return;
    if(getscoreuser(score_class,score_user)<0) return;
    for(*p=0,i=0;i<totsheets;i++) {
      if(scoresum[i]==0) {
          strcat(p,"0 0.00\n"); continue;
      }
      if(score_sheet!=0 && i!=score_sheet-1) continue;
      if(scoresum[i]<=0) strcat(p,"\n");
      tot=mean=0;
      for(j=0;j<totexos[i];j++) {
            /* if scoremean[i][j]<1 then ignore scoreuser[i][j].
             * if scoremean[i][j]<2 then half scoreuser[i][j]. */
          if(scoremean[i][j]>=1) {
            double dt=scoreuser[i][j];
            if(scoremean[i][j]<2) dt=dt/2;
            d=dt*scoreweight[i][j];
            mean+=scoremean[i][j]*d; tot+=d;
          }
      }
      if(tot>0) d=mean/tot; else d=0;
      sprintf(p+strlen(p), "%d %.2f\n",
            (int) rint(100*tot/scoresum[i]), d);
    }
}

      /* Returns the status of a sheet, or -1 if error */
int getsheetstatus(int classe, int sheet)
{
    char *p, *st, *buf, namebuf[1024];
    FILE *sf;
    long int l;
    int i;

    if(isexam || score_isexam) st="exam"; else st="sheet";
    snprintf(namebuf,sizeof(namebuf),"%s/classes/%u/%ss/.%ss",log_dir,classe,st,st);
    sf=fopen(namebuf,"r"); if(sf==NULL) return -1;
    fseek(sf,0,SEEK_END); l=ftell(sf); fseek(sf,0,SEEK_SET);
    buf=xmalloc(l+1); fread(buf,1,l,sf); *(buf+l)=0; fclose(sf); _tolinux(buf);
    for(i=1, p=strchr(buf,':');p!=NULL;i++,p=strchr(p+1,':')) {
      if(p>buf && *(p-1)!='\n') i--;
      if(i>=sheet) break;
    }
    if(p==NULL) return -1;
    i=*(p+1)-'0'; if(i>5 || i<0) i=-1;
    free(buf); return i;
}

      /* return 1 if a word of bf2 is a substring of host.
       * Content of bf2 is destroyed. */
int _subword(char bf2[])
{
    char *p1, *p2;
    for(p1=strchr(bf2,'\\'); p1!=NULL; p1=strchr(p1+1,'\\')) {
      char buf[MAX_LINELEN+1], buf2[MAX_LINELEN+1], fbuf[MAX_LINELEN+1];
      char *classp, *userp;
      classp=getvar("wims_class"); userp=getvar("wims_user");
      if(classp==NULL || userp==NULL || *classp==0 || *userp==0) break;
      if(p1>bf2 && !isspace(*(p1-1))) continue;
      if(!isalnum(*(p1+1))) continue;
      p2=find_word_end(p1); if(p2>=p1+MAX_NAMELEN) continue;
      memmove(buf2, p1+1, p2-p1-1); buf2[p2-p1-1]=0;
      snprintf(buf,sizeof(buf),"user__%s",buf2);
      if(strcmp(userp,"supervisor")==0)
        snprintf(fbuf,sizeof(fbuf),"../log/classes/%s/supervisor",classp);
      else
        snprintf(fbuf,sizeof(fbuf),"../log/classes/%s/.users/%s",classp,userp);
      getdef(fbuf,buf,buf2); string_modify(bf2,p1,p2,buf2);
      p1+=strlen(buf2);
    }
    if(wordchr(bf2,"none")!=NULL) return 0;
    if((isexam || score_isexam) && bf2[0]=='#') return 1;
    if(wordchr(bf2,"all")!=NULL) return 1;
      /* compare with starting time */
    for(p1=strchr(bf2,'>'); p1!=NULL; p1=strchr(p1+1,'>')) {
      if(p1>bf2 && !isspace(*(p1-1))) continue;
      p1++; p2=find_word_end(p1);
      if(p2-p1!=14) continue;
      p1[8]='.'; p1[11]=':'; if(*p2) *p2++=0;
      if(strcmp(nowstr,p1)<0) return 0;
      strcpy(p1-1,p2); p1-=2;
    }
      /* compare with ending time */
    for(p1=strchr(bf2,'<'); p1!=NULL; p1=strchr(p1+1,'<')) {
      if(p1>bf2 && !isspace(*(p1-1))) continue;
      p1++; p2=find_word_end(p1);
      if(p2-p1!=14) continue;
      p1[8]='.'; p1[11]=':'; if(*p2) *p2++=0;
      if(strcmp(nowstr,p1)>0) return 0;
      strcpy(p1-1,p2); p1-=2;
    }
    p1=find_word_start(bf2); if(*p1==0) return 1;
    return checkhost(p1);
}

      /* Returns 1 if score registration is open, 0 otherwise. */
int _getscorestatus(int classe, int sheet)
{
    char nbuf[MAX_LINELEN+1], gbuf[MAX_LINELEN+1];
    char *es;

    if(classe<0 || sheet<=0) return 1;
    if(getsheetstatus(classe,sheet)!=1) return 0;
    if(*remote_addr==0) return 0;
    if(isexam || score_isexam) {    /* exam simulation */
      accessfile(nbuf,"r","%s/classes/%u/.E%d",log_dir,classe,sheet);
      if(nbuf[0]=='#') return 1;
    }
      /* Global restriction data */
    accessfile(nbuf,"r","%s/classes/%u/.security",log_dir,classe);
    if(nbuf[0]) {
      _getdef(nbuf,"allow",gbuf);
      if(*find_word_start(gbuf)!=0 && _subword(gbuf)==0)
        return 0;
      _getdef(nbuf,"except",gbuf);
      if(*find_word_start(gbuf)!=0 && _subword(gbuf)==1)
        return 0;
    }

      /* Sheet restriction data */
    if(isexam || score_isexam) es="E"; else es="";
    accessfile(nbuf,"r","%s/classes/%u/.%s%d",log_dir,classe,es,sheet);
    if(*find_word_start(nbuf)==0) return 1;
    return _subword(nbuf);
}

      /* Returns 1 if score registration is open, 0 otherwise. */
int getscorestatus(int classe, int sheet)
{
    if(score_status<0 || score_statussheet!=sheet
       || score_statusisexam!=isexam) {
      score_statussheet=sheet; score_statusisexam=isexam;
      score_status=_getscorestatus(classe,sheet); score_isexam=0;
      if(score_status==1 && (cmd_type==cmd_new || cmd_type==cmd_renew
                         || isexam)) {
          char *p;
          p=getvar("wims_scorereg");
          if(p==NULL || strcmp(p,"suspend")!=0)
            setvar("wims_scoring","pending");
          else setvar("wims_scoring","");
      }
    }
    if(isexam && score_status==0) {
      char *p;
      p=getvar("wims_user"); if(p==NULL || strcmp(p,"supervisor")!=0)
        user_error("exam_closed");
    }
    return score_status;
}

      /* Whether score registering is open */
void calc_getscorestatus(char *p)
{
    _scoreparm(p);
    if(score_class==0 || score_sheet==0 || *score_user==0) {
        *p=0; return;
    }
    if(getscorestatus(score_class, score_sheet))
      strcpy(p,"yes");
    else strcpy(p,"no");
}

double exam_scoredata[64];

      /* get current exam score */
void exam_currscore(int esh)
{
    FILE *df;
    char *p, *bf, pb[64], dbuf[256];
    char *s, *p1, *p2, *e1, *e2;
    int i, l;
    
    for(i=0;i<64;i++) exam_scoredata[i]=-1;
    s=getvar("wims_session"); if(s==NULL || *s==0) return;
    snprintf(pb,sizeof(pb),"%s",s);
    p=strchr(pb,'_'); if(p!=NULL) *p=0;
    snprintf(dbuf,sizeof(dbuf),"%s/%s/examscore.%d",session_dir,pb,esh);
    df=fopen(dbuf,"r"); if(df!=NULL) {
      fseek(df,0,SEEK_END); l=ftell(df);
      if(l<=0 || l>1000000) {fclose(df); return;}
      fseek(df,0,SEEK_SET); bf=xmalloc(l+16);
      l=fread(bf,1,l,df); fclose(df);
      if(l<=0 || l>1000000) {free(bf); return;}
      bf[l]=0;
      for(p1=bf;*p1;p1=p2) {
          p2=strchr(p1,'\n'); if(*p2) *p2++=0;
          else p2=p1+strlen(p1);
          p1=find_word_start(find_word_end(find_word_start(p1)));
          e1=find_word_end(p1); if(*e1) *e1++=0;
          e1=find_word_start(e1); e2=find_word_start(find_word_end(e1));
          *find_word_end(e1)=0;
          i=atoi(p1);
          if(i>=1 && i<=64 && 
             exam_scoredata[i-1]<0 && strcmp(e1,"score")==0) {
            *find_word_end(e2)=0;
            exam_scoredata[i-1]=atof(e2);
          }
      }
      free(bf);
    }
}

      /* Gather exam score. */
void calc_examscore(char *p)
{
    char nbuf[1024], sbuf[MAX_LINELEN+1];
    char *rbuf, *p1, *p2, *p3, *p4, *p5;
    int i, k, ecnt;
    double ss, sc[64];
    unsigned int tr[64], all[64], ver[64], start[64], dure[64];
    char *ip[64], *ses[64];
    char *ip1, *ses1;
    unsigned int start1, dure1;
    FILE *rec;
    long int l;
    
    _scoreparm(p); *p=0;
    if(score_class==0 || *score_user==0) return;
    snprintf(nbuf,sizeof(nbuf),"%s/classes/%u/exams/.exams",log_dir,score_class);
    direct_datafile=1; ecnt=datafile_recordnum(nbuf); direct_datafile=0;
    if(ecnt<=0) return; if(ecnt>64) ecnt=64;
    memset(all,0,sizeof(all)); memset(ver,0,sizeof(ver));
    direct_datafile=1;
    for(i=1;i<=ecnt;i++) {
      sbuf[0]=0; datafile_fnd_record(nbuf,i,sbuf);
      p1=find_word_start(sbuf); p2=strchr(p1,'\n')+1; if(p2-1==NULL) continue;
      *find_word_end(p1)=0;
      k=atoi(p1); if(k<1) continue;
      p1=strchr(p2,'\n')+1; if(p1-1==NULL) continue;
      p1=find_word_start(p1); p1=find_word_end(p1);
      p1=find_word_start(p1); *find_word_end(p1)=0;
      k=atoi(p1); if(k<0) k=0; if(k>1024) k=1024; all[i-1]=k;
    }
    direct_datafile=0;
    memset(sc,0,sizeof(sc)); memset(tr,0,sizeof(tr));
    memset(dure,0,sizeof(dure)); memset(start,0,sizeof(start));
    memset(ip,0,sizeof(ip)); memset(ses,0,sizeof(ses));
    snprintf(sbuf,sizeof(sbuf),"%s/classes/%u/score/%s.exam",
             log_dir,score_class,score_user);
    rec=fopen(sbuf,"r"); if(rec==NULL) goto end;
    fseek(rec,0,SEEK_END); l=ftell(rec); fseek(rec,0,SEEK_SET);
    if(l<=0) {fclose(rec); goto end;}
    if(l>4*1024*1024) l=4*1024*1024;
    rbuf=xmalloc(l+16); fread(rbuf,1,l,rec); fclose(rec); rbuf[l]=0;
    for(p1=rbuf; p1!=NULL && *p1; p1=p2) {
      p2=strchr(p1,'\n'); if(p2!=NULL) *p2++=0;
      p1=find_word_start(p1); p3=find_word_end(p1);
      *p3++=0; p3=find_word_start(p3); 
      p4=find_word_end(p3); if(*p4==0) continue; else *p4++=0;
      i=atoi(p1)-1; if(i<0 || i>=ecnt) continue;
      p4=find_word_start(p4); p5=find_word_end(p4);
      if(*p5) *p5++=0; dure1=atoi(p4);
      p4=find_word_start(p5); p5=find_word_end(p4);
      if(*p5) *p5++=0; start1=atoi(p4);
      p4=find_word_start(p5); p5=find_word_end(p4);
      if(*p5) *p5++=0; ip1=p4;
      p4=find_word_start(p5); p5=find_word_end(p4);
      if(*p5) *p5++=0; ses1=p4;
      if(strcmp(p3,"--")==0) {      /* session closure */
          start[i]=dure[i]=0; ip[i]=ses[i]="";
          continue;
      }
      if(strcmp(p3,"00")==0) {
          ver[i]=1; tr[i]++; start[i]=start1; dure[i]=dure1;
          ip[i]=ip1; ses[i]=ses1;
      }
      else if(ver[i]==0) tr[i]++;
      if(tr[i]>all[i]) continue;
      ss=atof(p3); if(ss<=0) continue; if(ss>10) ss=10;
      if(ss>sc[i] && (dure1>=0 ||   /* checking conditions */
                  (start1-start[i]<dure[i]*60 &&
                   dure[i]>0 && dure[i]<4096 &&
                   *ses[i]!=0 && *ip[i]!=0 &&
                   start[i]!=0 && start1>start[i] &&
                   strcmp(ip[i],ip1)==0 &&
                   strcmp(ses[i],ses1)==0)))
        sc[i]=ss;
    }
    free(rbuf);
    end:
    for(i=0; i<ecnt; i++) sprintf(p+strlen(p),"%.2f ",sc[i]);
    sprintf(p+strlen(p),"\n");
    for(i=0; i<ecnt; i++) sprintf(p+strlen(p),"%d, %d,\n",all[i], tr[i]);
}

      /* check score dependency.
       * returns 1 if requirements are met. */
int _depcheck(char *ds, double got[], double mean[], double tot[])
{
    char *p1, *p2, *p3, *p4, *pp;
    int perc, t, sum;
    double tgot, ttot, tmean;
    
    for(p1=ds; *p1; p1=p3) {
      p2=strchr(p1,':'); if(p2==NULL) break;
      *p2++=0; p2=find_word_start(p2);
      for(p3=p2; isdigit(*p3); p3++);
      if(p3<=p2) break;
      *p3++=0; perc=atoi(p2);
      if(perc<=0 || perc>100) break;
      for(pp=p1; *pp; pp++) if(!isdigit(*pp)) *pp=' ';
      tgot=ttot=tmean=0; sum=0;
      for(pp=find_word_start(p1); *pp; pp=find_word_start(p4)) {
          p4=find_word_end(pp); if(*p4) *p4++=0;
          t=atoi(pp); if(t<=0 || t>64) goto lend;
          t--;
          ttot+=tot[t]; tgot+=got[t]; tmean+=mean[t];
          sum++;
      }
      if(ttot<10) continue;
      if(tgot/ttot*sqrt(tmean/(sum*10))*100<perc) {
          for(pp=p1;pp<p2-1;pp++) if(!*pp) *pp=',';
          *pp=0; setvar("dep_list",p1);
          return 0;
      }
      lend: ;
    }
    return 1;
}

int depcheck(char *sh, int exo, char *deps)
{
    char buf[MAX_LINELEN+1];
    char *s, sbuf[64];
    int i, is, cl;
    
    s=getvar("wims_session");
    if(s==NULL || *s==0 || strstr(s,"robot")!=NULL) return 0;
    snprintf(sbuf,sizeof(sbuf),"%s",s);
    s=strchr(sbuf,'_'); if(s) *s=0;
    accessfile(buf,"r","../sessions/%s/exodep.%s",sbuf,sh);
    if(buf[0]==0) {     /* no dep file found */
      is=atoi(sh); if(is<=0 || is>64) return 0;
      s=getvar("wims_class"); if(s==NULL || *s==0) return 0;
      cl=atoi(s); if(cl<=0) return 0;
      getscorerequire(cl); getscoreuser(cl,"");
      return _depcheck(deps,
                   scoreuser[is-1],scoremean[is-1],
                   scorerequire[is-1]);
    }
    for(i=1,s=strchr(buf,':'); s && i<exo; i++, s=strchr(s+1,':'));
    if(s==NULL) return 0;     /* bad file or exo number */
    if(isdigit(*++s)) return 0; else return 1;
}

int exam_depcheck(char *deps, int exam)
{
    double tot[64];
    int i;
    for(i=0;i<64;i++) tot[i]=10;
    exam_currscore(exam);
    for(i=0;i<64;i++) if(exam_scoredata[i]<0) exam_scoredata[i]=0;
    return _depcheck(deps,exam_scoredata,tot,tot);
}


Generated by  Doxygen 1.6.0   Back to index