Subversion Repositories wimsdev

Rev

Rev 13557 | Rev 14134 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
10 reyssat 1
/*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
2
 *
3
 *  This program is free software; you can redistribute it and/or modify
4
 *  it under the terms of the GNU General Public License as published by
5
 *  the Free Software Foundation; either version 2 of the License, or
6
 *  (at your option) any later version.
7
 *
8
 *  This program is distributed in the hope that it will be useful,
9
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 *  GNU General Public License for more details.
12
 *
13
 *  You should have received a copy of the GNU General Public License
14
 *  along with this program; if not, write to the Free Software
15
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
 */
17
 
8155 bpr 18
/* Routines treating user scores. */
8185 bpr 19
#include "wims.h"
10 reyssat 20
 
7149 bpr 21
double oldfactor=0.85;     /* quality factor, should remain stable. */
10 reyssat 22
 
12222 bpr 23
enum {sr_require, sr_weight, sr_score, sr_mean, sr_remain,
12273 bpr 24
  sr_last, sr_try, sr_best, sr_level, sr_new, sr_seedlast, sr_seedscorelast,
12295 bpr 25
  sr_seedscores, sr_seedlastcnt};
10 reyssat 26
char scorebuf[MAX_CLASSEXOS*sizeof(scoreresult)+32];
27
struct scoreresult *rscore;
28
int scorecnt;
29
double scoresum[MAX_SHEETS];
30
int sheetstart[MAX_SHEETS], shexocnt[MAX_SHEETS];
31
int examstart, examcnt;
32
char rscore_class[MAX_CLASSLEN+1];
33
char rscore_user[MAX_NAMELEN+1];
34
 
35
int totsheets=0;
36
int score_ispublic=0;
7149 bpr 37
int score_status=-1;          /* save of score status */
10 reyssat 38
int score_statussheet=-1;
39
int score_statusisexam=-1;
40
double scorerecfactor=0.9;
41
 
12197 bpr 42
/* gather user score, core routine.
43
  rscore data is created (table of structures).
44
  according to the value of wims_sheet or wims_exo
45
*/
10 reyssat 46
int getscoreuser(char *classe, char *user)
47
{
7407 bpr 48
  int i, j, osh, sh;
49
  double s;
50
  char *nowuser, *nowsheet, *nowexo, *nowscore;
51
  char *pp;
12196 bpr 52
  if(user==NULL || *user==0) {
7407 bpr 53
    user=getvar("wims_user");
54
    if(user==NULL || *user==0) return -1;
55
  }
56
  if(strcmp(classe,rscore_class)==0 && strcmp(user,rscore_user)==0) return 0;
57
  nowsheet=nowexo=nowscore="";
12495 bpr 58
  nowuser=getvar("wims_user");
59
  if(nowuser!=NULL && strcmp(user,nowuser)==0) {
12196 bpr 60
    nowscore=getvar("module_score");
61
    if(nowscore!=NULL && *nowscore!=0) {
62
      nowsheet=getvar("wims_sheet");
63
      if(nowsheet==NULL) nowsheet="";
64
      nowexo=getvar("wims_exo");
65
      if(nowexo==NULL) nowexo="";
10 reyssat 66
    }
7407 bpr 67
    else nowscore="";
68
  }
69
  snprintf(scorebuf+sizeof(int),sizeof(scorebuf)-sizeof(int),
7646 bpr 70
       "-c%s -u%s getscore %s %s %s",
71
       classe,user,nowsheet,nowexo,nowscore);
72
  i=kerneld(scorebuf,sizeof(scorebuf));
73
  if(i<0)  internal_error("getscoreuser(): daemon failure.");
7407 bpr 74
  if(memcmp(scorebuf+sizeof(int),"OK",2)!=0) {
75
    if(memcmp(scorebuf+sizeof(int),"ERROR",5)==0) {
76
      module_error(find_word_start(scorebuf+sizeof(int)+8));
10 reyssat 77
    }
7407 bpr 78
    else internal_error("getscoreuser(): communication error with wimslogd.");
79
  }
8340 bpr 80
/* 3 is here the length of "OK " */
7407 bpr 81
  pp=scorebuf+sizeof(int)+3; rscore=(struct scoreresult *) pp;
82
  scorecnt=(i-sizeof(int)-3)/sizeof(scoreresult);
83
  if(scorecnt>MAX_CLASSEXOS) module_error("too_many_exercises");
84
  s=0; for(i=osh=0;i<scorecnt;i++) {
85
    sh=(rscore[i].num>>8)+1;
86
    if(sh<1 || sh>MAX_SHEETS) break;
87
    if(osh>0 && osh<sh) {scoresum[osh-1]=s; s=0;}
88
    for(;osh<sh && osh<MAX_SHEETS;osh++) sheetstart[osh]=i;
89
    s+=rscore[i].require*rscore[i].weight;
90
  }
8338 bpr 91
  if(osh>0) scoresum[osh-1]=s;
92
  totsheets=osh;
7407 bpr 93
  for(j=0;j<totsheets-1;j++) shexocnt[j]=sheetstart[j+1]-sheetstart[j];
94
  shexocnt[totsheets-1]=i-sheetstart[totsheets-1];
95
  examstart=i; examcnt=scorecnt-examstart;
96
  mystrncpy(rscore_class,classe,sizeof(rscore_class));
97
  mystrncpy(rscore_user,user,sizeof(rscore_user));
98
  return 0;
10 reyssat 99
}
7602 bpr 100
/* work : exo */
10 reyssat 101
char *scorepname[]={
12222 bpr 102
  "class","user","sheet","work","exam"
10 reyssat 103
};
104
#define scorepname_no (sizeof(scorepname)/sizeof(scorepname[0]))
105
char score_class[MAX_CLASSLEN+1];
106
int score_sheet,score_exo,score_isexam;
107
char score_user[256];
108
 
7407 bpr 109
/* Uniformed treatment of score command parameters
110
 * format: class=? user=? sheet=? work=?
8155 bpr 111
 * all are optional.
112
 */
10 reyssat 113
void _scoreparm(char *p)
114
{
115
    int i;
116
    char *pn, *pe, *pd, *pf;
117
    char sav;
7407 bpr 118
 
10 reyssat 119
    score_sheet=score_exo=score_isexam=score_ispublic=0; *score_class=0;
120
    score_user[0]=0;
121
    for(i=0;i<scorepname_no;i++) {
7149 bpr 122
     pf=p;
123
     ahead:
124
     pn=strstr(pf,scorepname[i]); pf=pn+1;
125
     if(pn==NULL) continue;
126
     if(pn>p && !isspace(*(pn-1))) goto ahead;
127
     pe=find_word_start(pn+strlen(scorepname[i]));
128
     if(*pe!='=') goto ahead;
129
     pd=find_word_start(pe+1);
130
     pf=find_word_end(pd);
131
     if(pf<=pd) continue;
132
     sav=*pf; *pf=0;
133
     switch(i) {
134
         case 0: /* class */
135
           mystrncpy(score_class,pd,sizeof(score_class)); break;
136
         case 1: /* user */
137
           mystrncpy(score_user,pd,sizeof(score_user)); break;
138
         case 2: { /* sheet */
139
          if(*pd=='P') {pd++; score_ispublic=1;}
140
          score_sheet=atoi(pd);
141
          break;
142
         }
7363 bpr 143
         case 3: /* work=exo */
7149 bpr 144
           score_exo=atoi(pd); break;
145
         case 4: /* exam */
146
           score_isexam=1; break;
147
     }
148
     *pf=sav; ovlstrcpy(pn, pf);
10 reyssat 149
    }
150
    *p=0;
12381 bpr 151
  /* the commands are OK from a non trusted module if the user and the
12369 bpr 152
  class are not precised, so it can be only the user in his class */
10 reyssat 153
    if((*score_class!=0 || score_user[0]!=0) && !trusted_module()) {
7149 bpr 154
     module_error("not_trusted"); return;
10 reyssat 155
    }
156
    if(*score_class==0) {
7149 bpr 157
     char *classe;
158
     classe=getvar("wims_class");
159
     if(classe==NULL || *classe==0) return;
160
     else mystrncpy(score_class,classe,sizeof(score_class));
10 reyssat 161
    }
162
    if(score_user[0]==0) {
7149 bpr 163
     char *user;
164
     user=getvar("wims_user");
165
     if(user!=NULL) mystrncpy(score_user,user,sizeof(score_user));
10 reyssat 166
    }
167
}
168
 
7407 bpr 169
/* gather score: relatif to some of the
170
 *  user class work sheet exam
8155 bpr 171
 *  dtype can be require weight score mean remain best last level try
7407 bpr 172
 */
173
 
10 reyssat 174
void _getscore(char *p,int dtype)
175
{
12222 bpr 176
  int i,sh,ex,osh;
177
  float d;
12273 bpr 178
  char dc[SEEDSIZE];
179
  char ds[SEEDSCORES];
12222 bpr 180
  char *p1;
10 reyssat 181
 
12222 bpr 182
  _scoreparm(p);
183
  if(*score_class==0 || *score_user==0) return;
184
  if(getscoreuser(score_class,score_user)<0) return;
8155 bpr 185
/*  2^8 no_sheet + no_exo_in_the_sheet so limit no_exo to 2^8 */
12222 bpr 186
  for(i=osh=0,p1=p;i<scorecnt && p1-p<MAX_LINELEN-32;i++) {
187
    sh=(rscore[i].num>>8)+1; if(sh<1 || sh>MAX_SHEETS) break;
188
    if(score_sheet!=0) {
189
      if(sh<score_sheet) continue;
190
      if(sh>score_sheet || sh>MAX_SHEETS) break;
191
    }
192
    ex=((rscore[i].num)&255)+1;
193
    if(score_exo!=0 && ex!=score_exo) continue;
194
    if(osh!=0 && sh!=osh) *p1++='\n';
195
    switch(dtype) {
196
      case sr_require: {d=rscore[i].require; break;}
197
      case sr_weight: {d=rscore[i].weight; break;}
198
      case sr_score: {d=rscore[i].score; break;}
199
      case sr_mean: {d=rscore[i].mean; break;}
200
      case sr_remain: {d=rscore[i].require-rscore[i].score; break;}
201
      case sr_last: {d=rscore[i].last; break;}
202
      case sr_try: {d=rscore[i].try; break;}
12230 bpr 203
      case sr_new: {d=rscore[i].new; break;}
12222 bpr 204
      case sr_best: {d=rscore[i].best; break;}
12273 bpr 205
      case sr_level: {d=rscore[i].level; break;}
206
      case sr_seedscorelast: {d=rscore[i].seedscorelast; break;}
12295 bpr 207
      case sr_seedlastcnt: {d=rscore[i].seedlastcnt; break;}
12273 bpr 208
      case sr_seedlast: { mystrncpy(dc,rscore[i].seedlast,SEEDSIZE);
209
        break;
210
      }
211
      case sr_seedscores: {
212
        mystrncpy(ds,rscore[i].seedscores,SEEDSCORES); break;
213
      }
12222 bpr 214
      default: {d=0; break;}
215
    }
12273 bpr 216
    switch(dtype) {
217
      case sr_seedlast:
218
        { snprintf(p1,SEEDSIZE, "%s", dc); p1+=strlen(p1); break; }
219
       case sr_seedscores:
220
        { snprintf(p1,SEEDSCORES, "%s", ds); p1+=strlen(p1); break; }
221
      default:
222
        { p1=moneyprint(p1,d); }
223
    }
224
    *p1++=' ';
12222 bpr 225
    osh=sh;
226
  }
227
  *p1++='\n'; *p1=0;
10 reyssat 228
}
229
 
7407 bpr 230
/* gather user score. */
10 reyssat 231
void calc_getscore(char *p)
232
{
7407 bpr 233
  _getscore(p,sr_score);
10 reyssat 234
}
235
 
7407 bpr 236
/* gather user score average. */
10 reyssat 237
void calc_getscoremean(char *p)
238
{
7407 bpr 239
  _getscore(p,sr_mean);
10 reyssat 240
}
241
 
7407 bpr 242
/* gather remaining of score to get for user. */
10 reyssat 243
void calc_getscoreremain(char *p)
244
{
7407 bpr 245
  _getscore(p,sr_remain);
10 reyssat 246
}
247
 
7407 bpr 248
/* Require score table. */
10 reyssat 249
void calc_getscorerequire(char *p)
250
{
7407 bpr 251
  _getscore(p,sr_require);
10 reyssat 252
}
253
 
7407 bpr 254
/* Score weight table. */
10 reyssat 255
void calc_getscoreweight(char *p)
256
{
7407 bpr 257
  _getscore(p,sr_weight);
10 reyssat 258
}
14126 obado 259
/* user last score */
7602 bpr 260
void calc_getscorelast(char *p)
261
{
262
  _getscore(p,sr_last);
263
}
12196 bpr 264
/* gather user score try numbers with score activated. */
7602 bpr 265
void calc_getscoretry(char *p)
266
{
267
  _getscore(p,sr_try);
268
}
12220 bpr 269
/* gather all user try numbers (terminated or not, but with notation activated)*/
12197 bpr 270
void calc_getscorealltries(char *p)
12196 bpr 271
{
12230 bpr 272
  _getscore(p,sr_new);
12196 bpr 273
}
7602 bpr 274
 
7657 bpr 275
/* if the required points are 10* N, gather N user best scores */
7638 bpr 276
void calc_getscorebest(char *p)
277
{
278
  _getscore(p,sr_best);
279
}
280
 
7657 bpr 281
/* gather user score average. */
282
void calc_getscorelevel(char *p)
283
{
284
  _getscore(p,sr_level);
285
}
286
 
7638 bpr 287
/* percentage of work done for each sheet:
7657 bpr 288
 * score mean best level
289
 * as follows
14126 obado 290
 * score=100*cumulative_points/required_points (< 100)
7665 bpr 291
 * mean=quality (<10)
292
 * best=10*(required/10 best_scores)/required_points (< 100)
293
 * level=minimum of the required/10 best_scores (< 10)
7638 bpr 294
 */
7657 bpr 295
 
296
 void calc_getscorepercent(char *p)
10 reyssat 297
{
7407 bpr 298
  int i,j,jend;
7657 bpr 299
  double tot, mean, totb, totl, totw, d;
7407 bpr 300
  char *p1;
10 reyssat 301
 
7407 bpr 302
  _scoreparm(p);
303
  if(*score_class==0 || *score_user==0) return;
304
  if(getscoreuser(score_class,score_user)<0) return;
305
  for(p1=p,i=0;i<totsheets && p1-p<MAX_LINELEN-32;i++) {
306
    if(scoresum[i]==0) {
7657 bpr 307
      ovlstrcpy(p1,"0 0 0 0\n"); p1+=strlen(p1); continue;
10 reyssat 308
    }
7407 bpr 309
    if(score_sheet!=0 && i!=score_sheet-1) continue;
310
    if(scoresum[i]<=0) *p1++='\n';
7657 bpr 311
    tot=mean=totb=totl=totw=0; jend=sheetstart[i]+shexocnt[i];
7407 bpr 312
    for(j=sheetstart[i];j<jend;j++) {
12495 bpr 313
      /* if mean<1 then ignore score.
314
      * if mean<2 then half score.
315
      */
7407 bpr 316
      if(rscore[j].mean>=1) {
7646 bpr 317
        double dt=rscore[j].score;
318
        float db=rscore[j].best;
7657 bpr 319
        float dl=rscore[j].level;
320
        if(rscore[j].mean<2) {dt=dt/2; db=db/2; dl=dl/2;}
7646 bpr 321
        d=dt*rscore[j].weight;
12495 bpr 322
        /* quality */
7646 bpr 323
        mean+=rscore[j].mean*d;
12495 bpr 324
        /* cumulative score */
7646 bpr 325
        tot+=d;
12495 bpr 326
        /* best */
7646 bpr 327
        totb+=db*rscore[j].weight;
12495 bpr 328
        /* level */
7657 bpr 329
        totl+=dl*rscore[j].weight;
330
        totw+=rscore[j].weight;
7407 bpr 331
      }
332
    }
7638 bpr 333
    if(tot>0) {d=mean/tot;} else d=0;
12495 bpr 334
    /* cumulative score */
7407 bpr 335
    p1=moneyprint(p1,rint(100*tot/scoresum[i])); *p1++=' ';
12495 bpr 336
    /* quality */
7638 bpr 337
    p1=moneyprint(p1,d); *p1++=' ';
12495 bpr 338
    /* best */
7657 bpr 339
    p1=moneyprint(p1,rint(100*totb/scoresum[i])); *p1++=' ';
12495 bpr 340
    /* level */
7657 bpr 341
    p1=moneyprint(p1,rint(10*totl/totw));
342
 
343
   *p1++='\n';
7407 bpr 344
  }
345
  *p1=0;
10 reyssat 346
}
12273 bpr 347
/* [seed1,score1;seed2,score2;...] at most MAX_SCORESEED */
348
void calc_getseedscores(char *p)
349
{
350
  _getscore(p,sr_seedscores);
351
}
352
/* last seed (0 if there is no seed)*/
353
void calc_getseedlast(char *p)
354
{
355
  _getscore(p,sr_seedlast);
356
}
357
/* last score (-1 if does not exist) */
358
void calc_getseedscorelast(char *p)
359
{
360
  _getscore(p,sr_seedscorelast);
361
}
10 reyssat 362
 
12295 bpr 363
/* number of occurences of the last seed */
364
void calc_getseedlastcnt(char *p)
365
{
366
  _getscore(p,sr_seedlastcnt);
367
}
368
 
7407 bpr 369
/* Returns the status of a sheet, or -1 if error */
10 reyssat 370
int getsheetstatus(char *classe, int sheet)
371
{
7407 bpr 372
  char *p, *st, buf[MAX_LINELEN+1], namebuf[MAX_FNAME+1];
373
  int i;
10 reyssat 374
 
7407 bpr 375
  if(isexam || score_isexam) st="exam"; else st="sheet";
376
  mkfname(namebuf,"%s/%s/%ss/.%ss",class_base,classe,st,st);
377
  direct_datafile=1;datafile_fnd_record(namebuf,sheet,buf);direct_datafile=0;
378
  p=find_word_start(buf); if(*p==0) return -1;
379
  i=*p-'0'; if(i>5 || i<0) i=-1;
380
  if((isexam || score_isexam) && i==0) {
381
    p=getvar("wims_user"); if(p!=NULL && strcmp(p,"supervisor")==0) i=1;
382
  }
383
  return i;
10 reyssat 384
}
385
 
13011 bpr 386
/* return 1 if a word of bf2 is a substring of host
387
  and if time restrictions are verified for wims_user
8155 bpr 388
 * Content of bf2 is destroyed.
389
 */
10303 guerimand 390
int _subword(char bf2[],char *ftbuf)
10 reyssat 391
{
7407 bpr 392
  char *p1, *p2;
393
  for(p1=strchr(bf2,'\\'); p1!=NULL; p1=strchr(p1+1,'\\')) {
394
    char buf[MAX_LINELEN+1], buf2[MAX_LINELEN+1], fbuf[MAX_FNAME+1];
395
    char *classp, *classp2, *userp, *scp;
396
    classp=getvar("wims_class"); userp=getvar("wims_user");
397
    if(classp==NULL || userp==NULL || *classp==0 || *userp==0) break;
398
    scp=getvar("wims_superclass");
399
    if(scp!=NULL && *scp!=0) classp2=scp; else classp2=classp;
400
    if(p1>bf2 && !isspace(*(p1-1))) continue;
401
    if(!isalnum(*(p1+1))) continue;
402
    p2=find_word_end(p1); if(p2>=p1+MAX_NAMELEN) continue;
403
    memmove(buf2, p1+1, p2-p1-1); buf2[p2-p1-1]=0;
10303 guerimand 404
    /* get value of technical variable */
405
    snprintf(buf,sizeof(buf),"user_techvar_%s",buf2);
7407 bpr 406
    if(strcmp(userp,"supervisor")==0)
407
      mkfname(fbuf,"%s/%s/supervisor",class_base,classp);
408
    else
409
      mkfname(fbuf,"%s/%s/.users/%s",class_base,classp2,userp);
10303 guerimand 410
    getdef(fbuf,buf,buf2);
10365 bpr 411
    if(buf2[0]==0) ovlstrcpy(buf2,"EMPTY"); /* in case of no value defined for the user*/
10303 guerimand 412
    /* get time restriction for this value */
413
    snprintf(buf,sizeof(buf),"techvar_%s",buf2);
13011 bpr 414
    /* mkfname(fbuf,"%s/%s/.E%s",class_base,classp,sheet);
415
     * read time restriction corresponding to the value of
416
     * technical variable in the file of the sheet or exam
417
    */
10379 bpr 418
    getdef(ftbuf,buf,buf2);
10303 guerimand 419
    if(buf2[0]==0) ovlstrcpy(buf2,"none");
420
    /*string_modify(bf2,p1,p2,buf2);*/
421
    bf2=buf2;
7407 bpr 422
    p1+=strlen(buf2);
423
  }
424
  if((isexam || score_isexam) && bf2[0]=='#') return 1;
425
  if(wordchr(bf2,"none")!=NULL) return 0;
426
  if(wordchr(bf2,"all")!=NULL) return 1;
427
  p1=find_word_start(bf2); if(*p1==0) return 1;
13011 bpr 428
  /* check host and time */
7407 bpr 429
  return checkhostt(p1);
10 reyssat 430
}
431
 
13011 bpr 432
/* Returns 1 if score registration is open for the user
433
 * in variable wims_user, 0 otherwise.
434
 */
10 reyssat 435
int _getscorestatus(char *classe, int sheet)
436
{
7407 bpr 437
  char nbuf[MAX_LINELEN+1], gbuf[MAX_LINELEN+1];
10303 guerimand 438
  char ftbuf[MAX_FNAME+1]="";
7407 bpr 439
  char *es;
10 reyssat 440
 
7407 bpr 441
  if(classe==NULL || *classe==0 || sheet<=0) return 1;
442
  if(getsheetstatus(classe,sheet)!=1) return 0;
443
  if(*remote_addr==0) return 0;
444
  if(isexam || score_isexam) {     /* exam simulation */
445
    accessfile(nbuf,"r","%s/%s/.E%d",class_base,classe,sheet);
446
    if(nbuf[0]=='#') return 1;
447
  }
12814 bpr 448
  /* Global restriction data */
7407 bpr 449
  accessfile(nbuf,"r","%s/%s/.security",class_base,classe);
450
  if(nbuf[0]) {
451
    _getdef(nbuf,"allow",gbuf);
10303 guerimand 452
    if(*find_word_start(gbuf)!=0 && _subword(gbuf,ftbuf)==0)
7407 bpr 453
      return 0;
454
    _getdef(nbuf,"except",gbuf);
10303 guerimand 455
    if(*find_word_start(gbuf)!=0 && _subword(gbuf,ftbuf)==1)
7407 bpr 456
      return 0;
457
  }
13011 bpr 458
  /* Sheet restriction data; take in account the technical variables */
7407 bpr 459
  if(isexam || score_isexam) es="E"; else es="";
460
  accessfile(nbuf,"r","%s/%s/.%s%d",class_base,classe,es,sheet);
461
  if(*find_word_start(nbuf)==0) return 1;
12814 bpr 462
  /* preparing score restriction file name :*/
10303 guerimand 463
  mkfname(ftbuf,"%s/%s/.%s%d",class_base,classe,es,sheet);
464
  return _subword(nbuf,ftbuf);
10 reyssat 465
}
466
 
13011 bpr 467
/* Returns 1 if score registration is open for wims_user, 0 otherwise.*/
10 reyssat 468
int getscorestatus(char *classe, int sheet)
469
{
7407 bpr 470
  if(score_status<0 || score_statussheet!=sheet
471
     || score_statusisexam!=isexam) {
472
    score_statussheet=sheet; score_statusisexam=isexam;
473
    score_status=_getscorestatus(classe,sheet); score_isexam=0;
474
    if(score_status==1 && (cmd_type==cmd_new || cmd_type==cmd_renew
7646 bpr 475
               || isexam)) {
7407 bpr 476
      char *p;
477
      p=getvar("wims_scorereg");
478
      if(p==NULL || strcmp(p,"suspend")!=0)
7646 bpr 479
         setvar("wims_scoring","pending");
7407 bpr 480
      else setvar("wims_scoring","");
10 reyssat 481
    }
7407 bpr 482
  }
483
  if(isexam && score_status==0) {
484
    char *p;
13557 obado 485
    p=getvar("wims_user");
486
    if(p==NULL || strcmp(p,"supervisor")!=0)
487
      user_error("exam_closed");
7407 bpr 488
  }
489
  return score_status;
10 reyssat 490
}
491
 
7407 bpr 492
/* Whether score registering is open */
10 reyssat 493
void calc_getscorestatus(char *p)
494
{
7407 bpr 495
  _scoreparm(p);
496
  if(*score_class==0 || score_sheet==0 || *score_user==0) {
497
    *p=0; return;
498
  }
499
  if(getscorestatus(score_class, score_sheet))
500
    ovlstrcpy(p,"yes");
501
  else ovlstrcpy(p,"no");
10 reyssat 502
}
503
 
13011 bpr 504
/* whether there are too much tries for the exo return yes or no */
12213 bpr 505
void calc_getscoremaxexotry(char *p)
506
{
507
  _scoreparm(p);
508
  if(*score_class==0 || *score_user==0 || score_sheet==0 || score_exo==0) return;
509
  if(gettrycheck(score_class, score_user, score_sheet, score_exo)==1)
510
    ovlstrcpy(p,"yes");
511
  else ovlstrcpy(p,"no");
512
}
513
 
3603 reyssat 514
double exam_scoredata[MAX_EXOS];
10 reyssat 515
 
7407 bpr 516
/* get current exam score */
10 reyssat 517
void exam_currscore(int esh)
518
{
7407 bpr 519
  char *p, *bf, pb[MAX_FNAME+1];
520
  char *s, *p1, *p2, *e1, *e2;
521
  int i;
522
  for(i=0;i<MAX_EXOS;i++) exam_scoredata[i]=-1000;
12814 bpr 523
  /* session_prefix is not yet defined here */
7407 bpr 524
  s=getvar("wims_session"); if(s==NULL || *s==0) return;
525
  mystrncpy(pb,s,sizeof(pb));
526
  p=strchr(pb,'_'); if(p!=NULL) *p=0;
527
  bf=readfile(mkfname(NULL,"%s/%s/examscore.%d",session_dir,pb,esh),NULL,WORKFILE_LIMIT);
528
  if(bf==NULL) return;
529
  for(p1=bf;*p1;p1=p2) {
530
    p2=strchr(p1,'\n'); if(*p2) *p2++=0;
531
    else p2=p1+strlen(p1);
532
    p1=find_word_start(find_word_end(find_word_start(p1)));
533
    e1=find_word_end(p1); if(*e1) *e1++=0;
534
    e1=find_word_start(e1); e2=find_word_start(find_word_end(e1));
535
    *find_word_end(e1)=0;
536
    i=atoi(p1);
537
    if(i>=1 && i<=MAX_EXOS &&
538
       exam_scoredata[i-1]==-1000 && strcmp(e1,"score")==0) {
539
      *find_word_end(e2)=0;
540
      exam_scoredata[i-1]=atof(e2);
10 reyssat 541
    }
7407 bpr 542
  }
543
  free(bf);
10 reyssat 544
}
545
 
7407 bpr 546
/* Gather exam score. */
10 reyssat 547
void calc_examscore(char *p)
548
{
7407 bpr 549
  char *p1;
550
  int i;
9692 bpr 551
  char *withoutip;
7407 bpr 552
 
553
  _scoreparm(p); *p=0;
9692 bpr 554
  withoutip=getvar("wims_examscore_withoutip");
555
 
7407 bpr 556
  if(*score_class==0 || *score_user==0) return;
557
  if(getscoreuser(score_class,score_user)<0) return;
558
  p1=p;
9692 bpr 559
  if(withoutip!=NULL && strcmp(withoutip,"yes")==0) {
560
    for(i=0; i<examcnt && p1-p<MAX_LINELEN-32; i++) {
561
    p1=moneyprint(p1,rscore[examstart+i].best); *p1++=' ';
562
    }
563
  } else {
564
    for(i=0; i<examcnt && p1-p<MAX_LINELEN-32; i++) {
565
      p1=moneyprint(p1,rscore[examstart+i].score); *p1++=' ';
566
    }
7407 bpr 567
  }
568
  *p1++='\n';
569
  for(i=0; i<examcnt && p1-p<MAX_LINELEN-32; i++) {
570
    p1=moneyprint(p1,rscore[examstart+i].require); *p1++=' ';
571
    p1=moneyprint(p1,floor(rscore[examstart+i].mean/2)); *p1++=' ';
572
    p1=moneyprint(p1,(int) rscore[examstart+i].mean%2); *p1++='\n';
573
  }
574
  *p1=0;
10 reyssat 575
}
576
 
7407 bpr 577
/* check score dependency.
8155 bpr 578
 * returns 1 if requirements are met.
579
 */
10 reyssat 580
int _depcheck(char *ds, struct scoreresult *rs, int ecnt)
581
{
7407 bpr 582
  char *p1, *p2, *p3, *p4, *pp;
583
  int perc, t, sum;
584
  double tgot, ttot, tmean;
585
 
586
  for(p1=ds; *p1; p1=p3) {
587
    p2=strchr(p1,':'); if(p2==NULL) break;
588
    *p2++=0; p2=find_word_start(p2);
589
    for(p3=p2; myisdigit(*p3); p3++);
590
    if(p3<=p2) break;
591
    *p3++=0; perc=atoi(p2);
592
    if(perc<=0 || perc>100) break;
593
    for(pp=p1; *pp; pp++) if(!myisdigit(*pp)) *pp=' ';
594
    tgot=ttot=tmean=0; sum=0;
595
    for(pp=find_word_start(p1); *pp; pp=find_word_start(p4)) {
596
      p4=find_word_end(pp); if(*p4) *p4++=0;
597
      t=atoi(pp); if(t<=0 || t>ecnt) goto lend;
598
      t--;
599
      ttot+=rs[t].require; tgot+=rs[t].score; tmean+=rs[t].mean;
600
      sum++;
10 reyssat 601
    }
7407 bpr 602
    if(ttot<10) continue;
603
    if(tgot/ttot*sqrt(tmean/(sum*10))*100<perc) {
604
      for(pp=p1;pp<p2-1;pp++) if(!*pp) *pp=',';
605
      *pp=0; setvar("dep_list",p1);
606
      return 0;
607
    }
608
  lend: ;
609
  }
610
  return 1;
10 reyssat 611
}
612
 
613
int depcheck(char *sh, int exo, char *deps)
614
{
7407 bpr 615
  char buf[MAX_LINELEN+1];
616
  char *s, sbuf[64];
617
  int i, is;
618
 
619
  s=getvar("wims_session");
620
  if(s==NULL || *s==0 || strstr(s,"robot")!=NULL) return 0;
621
  mystrncpy(sbuf,s,sizeof(sbuf));
622
  s=strchr(sbuf,'_'); if(s) *s=0;
623
  accessfile(buf,"r","../sessions/%s/exodep.%s",sbuf,sh);
624
  if(buf[0]==0) {     /* no dep file found */
625
    is=atoi(sh); if(is<=0 || is>totsheets) return 0;
626
    s=getvar("wims_class"); if(s==NULL || *s==0) return 0;
627
    getscoreuser(s,"");
628
    return _depcheck(deps,rscore+sheetstart[is-1],shexocnt[is-1]);
629
  }
630
  for(i=1,s=strchr(buf,':'); s && i<exo; i++, s=strchr(s+1,':'));
631
  if(s==NULL) return 0;     /* bad file or exo number */
632
  if(myisdigit(*++s)) return 0; else return 1;
10 reyssat 633
}
634
 
635
int exam_depcheck(char *deps, int exam)
636
{
12409 bpr 637
  static struct scoreresult esc[MAX_EXOS];
7407 bpr 638
  int i;
639
  exam_currscore(exam);
640
  for(i=0;i<MAX_EXOS;i++) {
641
    esc[i].require=esc[i].mean=10;
642
    if(exam_scoredata[i]==-1000) esc[i].score=0;
643
    else esc[i].score=exam_scoredata[i];
644
  }
645
  return _depcheck(deps,esc,MAX_EXOS);
10 reyssat 646
}
12213 bpr 647
 
12276 bpr 648
/* public sheet gives she=0 */
12495 bpr 649
/* return 1 if score is no more taken in account because of exotrymax */
12213 bpr 650
int gettrycheck(char *classe, char *user, int she, int exo) {
651
  char *s;
652
  int sh, ex, i;
13232 bpr 653
  if(classe==NULL || *classe==0 || user==NULL || *user==0) return 0;
12276 bpr 654
  if (she<=0) return 0;
13232 bpr 655
    if(strcmp(user,"supervisor")==0) return 0;
12213 bpr 656
  s=getvar("exotrymax");
12527 bpr 657
  if(s==NULL || *s==0) return 0;
12213 bpr 658
  getscoreuser(classe,user);
12527 bpr 659
  char *p=getvar("wims_scorereg");
12213 bpr 660
  for(i=0;i<scorecnt;i++) {
661
    sh=(rscore[i].num>>8)+1;
662
    if (she!=sh) continue;
663
    ex=((rscore[i].num)&255)+1;
664
    if(exo!=ex) continue;
12381 bpr 665
    if(cmd_type==cmd_new || cmd_type==cmd_renew)
12527 bpr 666
      if(rscore[i].new >= atoi(s)) {
667
        if(strcmp(p,"suspend")!=0) setvar("wims_scorereg","exotrymax");
668
        return 1;
669
    }
670
    if(rscore[i].new > atoi(s)){
671
      if(strcmp(p,"suspend")!=0) setvar("wims_scorereg","exotrymax");
13015 bpr 672
      return 1;
12527 bpr 673
    }
12508 bpr 674
  }
12213 bpr 675
  return 0;
676
}
12273 bpr 677
 
678
/* return seed if the seed should be kept and NULL if not */
12369 bpr 679
char *getseedscore(char *classe, char *user, int she, int exo) {
12273 bpr 680
  char *s;
681
  int sh, ex, i;
12276 bpr 682
  if (she<=0) return NULL;
12273 bpr 683
  if(strcmp(user,"supervisor")==0) return NULL;
684
  s=getvar("seedrepeat");
12990 bpr 685
  if(s==NULL || *s==0 || atoi(s)<=0) return NULL;
12273 bpr 686
  getscoreuser(classe,user);
687
  for(i=0;i<scorecnt;i++) {
688
    sh=(rscore[i].num>>8)+1;
689
    if (she!=sh) continue;
690
    ex=((rscore[i].num)&255)+1;
691
    if(exo!=ex) continue;
12432 bpr 692
    if(atoi(rscore[i].seedlast)==0) {
693
      char *seed=getvar("wims_seed");
694
      return seed;
695
    }
12390 bpr 696
    if(rscore[i].seedlastcnt > MAX_SEEDSCORE) return NULL;
12445 bpr 697
    if(atoi(s)>0 && rscore[i].seedlastcnt >= atoi(s) && cmd_type!=cmd_next) return NULL;
12432 bpr 698
    if(rscore[i].seedscorelast < 10) return rscore[i].seedlast;
12273 bpr 699
  };
700
  return NULL;
701
}