Subversion Repositories wimsdev

Rev

Rev 12200 | 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
 
7158 bpr 18
/* This is an internal program,
7571 bpr 19
 * used to show statistics of frequentation, module by module.
7158 bpr 20
*/
10 reyssat 21
 
16866 guerimand 22
/* TODO : lorsqu'on selectionne score et noscore il y a une double lecture
23
   des fichiers de log (une premiere lecture pour score et une autre pour noscore
24
   surement qu'une seule lecture serait possible A voir */
25
 
26
 
10 reyssat 27
#include "../Lib/libwims.h"
8254 bpr 28
#include "../wimsdef.h"
10 reyssat 29
 
7158 bpr 30
#define MAX_SCORE      512*1024
10 reyssat 31
 
32
typedef struct {
33
    short int dure,score;
34
    long int next;
8254 bpr 35
} statscoredata;
36
statscoredata scores[MAX_SCORE];
10 reyssat 37
int sccnt=0;
38
 
39
typedef struct {
40
    int newcnt,scorecnt,lasttime,firstscore,lastscore;
41
    char lastnew[12];
8254 bpr 42
} statexodata;
43
statexodata shdata[MAX_SHEETS*MAX_EXOS],examdata[MAX_EXAMS*MAX_EXOS];
10 reyssat 44
 
45
/* cid: combined index of difficulty */
46
double scsum, scavg, scdeviat, scmin, scmax, cid;
47
double dursum, duravg, durdeviat, durmin, durmax;
7609 bpr 48
double best[10];
10 reyssat 49
int filecnt=0, fcind;
7609 bpr 50
char *dirbase, *sdata, user[256];
10 reyssat 51
 
52
int str2time(char *p)
53
{
12200 bpr 54
  int sec,min,hr;
55
  sec=atoi(p+15); p[14]=0;
56
  min=atoi(p+12); p[11]=0;
57
  hr=atoi(p+9);
58
  if(sec<0 || min<0 || hr<0 || sec>59 || min>59 || hr>23) return -1;
59
  return hr*3600+min*60+sec;
10 reyssat 60
}
61
 
16866 guerimand 62
/*  traitement d'une ligne des fichiers score/noscore d'un utilisateur
63
 les donnees des sheet sont stockees dans shdata
64
  les donnees des exam sont stockees dans examdata */
8899 bpr 65
static
7609 bpr 66
void oneline(char *p, char *typ)
10 reyssat 67
{
12200 bpr 68
  int i, j, sh, ex, t;
69
  char *data[64];
70
  statexodata *tab;
71
  char *pp, *pe;
16866 guerimand 72
  char *ltype;
12200 bpr 73
  for(i=0, pp=find_word_start(p); i<9  && *pp; pp=find_word_start(pe),i++) {
74
    pe=find_word_end(pp); if(*pe) *pe++=0;
75
    data[i]=pp;
76
  }
77
  if(i<6) return;
78
  sh=atoi(data[2]); ex=atoi(data[3]);
79
  if(sh<=0 || ex<=0 || ex>MAX_EXOS || strlen(data[1])>10) return;
80
  if(data[0][0]=='E') {
81
    tab=examdata; data[0]++; if(sh>MAX_EXAMS) return;
16866 guerimand 82
    ltype="S";
12200 bpr 83
  }
84
  else {
85
    tab=shdata; if(sh>MAX_SHEETS) return;
16866 guerimand 86
    ltype="noscore";
12200 bpr 87
  }
88
  tab+=(sh-1)*MAX_EXOS+(ex-1);
89
  t=str2time(data[0]); if(t==-1) return;
90
  if(strstr(data[4],"new")!=NULL) {
91
    if(strcmp(typ,"score")==0)
16866 guerimand 92
            for (j = 6; j < i; ++j) if (strcmp(data[j],ltype)==0) return;
93
    if(strcmp(typ,"noscore")==0) {
94
            int test=0;
95
            for (j = 7; j < i; ++j) if (strcmp(data[j],ltype)==0) test=1;
96
            if (test==0) return;
97
    }
12200 bpr 98
    snprintf(tab->lastnew,12,"%s",data[1]);
99
    tab->newcnt++; tab->lasttime=t;
100
    fcind++;
101
    return;
102
  }
103
  if(strcmp(data[4],"score")==0) {
104
    if(strcmp(tab->lastnew,data[1])!=0) return;
105
    if(sccnt>=MAX_SCORE) return;
106
    if(tab->lasttime==-1) return;
16866 guerimand 107
    if(strcmp(typ,"score")==0)
108
            for (j = 6; j < i; ++j) if (strcmp(data[j],ltype)==0) return;
109
    if(strcmp(typ,"noscore")==0) {
110
            int test=0;
111
            for (j = 7; j < i; ++j) if (strcmp(data[j],ltype)==0) test=1;
112
            if (test==0) return;
113
    }
12200 bpr 114
    t-=tab->lasttime; tab->lasttime=-1; if(t<0) t+=24*3600;
115
    if(t<0) t=0;
116
    if(t>5*3600) t=5*3600;
117
    scores[sccnt].dure=t; scores[sccnt].next=-1;
118
    scores[sccnt].score=(double) atof(data[5])*100+0.5;
119
    if(tab->scorecnt>0) scores[tab->lastscore].next=sccnt;
120
    else tab->firstscore=sccnt;
121
    tab->lastscore=sccnt; sccnt++; tab->scorecnt++;
122
  }
10 reyssat 123
}
124
 
16866 guerimand 125
 
126
/* traitement d'un fichier de log particulier
127
 typ prend deux valeurs score ou noscore */
7609 bpr 128
void onefile(char *fname, char *typ)
10 reyssat 129
{
12200 bpr 130
  FILE *f;
131
  char *buf, *pp, *pe;
132
  long int l;
133
  f=fopen(fname,"r"); if(f==NULL) return;
134
  fseek(f,0,SEEK_END); l=ftell(f); fseek(f,0,SEEK_SET);
135
  if(l<=0) {fclose(f); return;}
136
  buf=xmalloc(l+16); (void)fread(buf,1,l,f); fclose(f); buf[l]=0;
137
  fcind=0;
138
  for(pp=buf; pp; pp=pe) {
139
    pe=strchr(pp,'\n'); if(pe!=NULL) *pe++=0;
140
    oneline(pp,typ);
141
  }
142
  free(buf);
143
  if(fcind>0) filecnt++;
10 reyssat 144
}
145
 
16866 guerimand 146
 
147
/* traitement de tous les fichiers d'un repertoire
148
qui est soit /score soit /noscore */
149
 
7609 bpr 150
void onedir_ (char buf[MAX_LINELEN+1], char *typ)
10 reyssat 151
{
7609 bpr 152
  char buf2[MAX_LINELEN+1];
153
  DIR *dir;
154
  struct dirent *ff;
155
  dir=opendir(buf); if(dir==NULL) return;
12200 bpr 156
  while((ff=readdir(dir))!=NULL) {
16866 guerimand 157
    /* les fichiers commençant par . sont ceux des eleves supprimes ; les fichiers avec
158
    une extension .exam .bin ne sont pas des fichiers de scores
159
    le decompte d'activite n'est pas fait sur supervisor */
160
    if(strstr(ff->d_name,".")!=NULL || strcmp(ff->d_name,"supervisor")==0) continue;
12200 bpr 161
    snprintf(buf2,sizeof(buf2),"%s/%s",buf,ff->d_name);
162
    onefile(buf2,typ);
163
  }
164
  closedir(dir);
7609 bpr 165
}
166
 
167
void onedir(char *dirname)
168
{
12200 bpr 169
  char buf[MAX_LINELEN+1];
170
  char *t1, *t2, types[256];
171
  snprintf(types,sizeof(types),"%s",sdata);
172
  for(t1=find_word_start(types); *t1; t1=find_word_start(t2)) {
173
    t2=find_word_end(t1); if(*t2) *t2++=0;
174
    snprintf(buf,sizeof(buf),"%s/%s/score",dirbase,dirname);
175
    onedir_(buf,t1);
176
    snprintf(buf,sizeof(buf),"%s/%s/noscore",dirbase,dirname);
177
    onedir_(buf,t1);
178
  }
10 reyssat 179
}
180
 
16866 guerimand 181
/* traitement des donnees seulement pour un utilisateur
182
  appel de la fonction onefile pour chaque fichier */
183
 
7609 bpr 184
void oneuser(char *dirname, char fname[64])
185
{
12200 bpr 186
  char buf[MAX_LINELEN+1], buf2[MAX_LINELEN+1];
187
  char *t1, *t2, types[256];
188
  snprintf(types,sizeof(types),"%s",sdata);
189
  for(t1=find_word_start(types); *t1; t1=find_word_start(t2)) {
190
    t2=find_word_end(t1); if(*t2) *t2++=0;
191
    snprintf(buf,sizeof(buf),"%s/%s/score/%s",dirbase,dirname,fname);
192
    onefile(buf,t1);
193
    snprintf(buf2,sizeof(buf),"%s/%s/noscore/%s",dirbase,dirname,fname);
194
    onefile(buf2,t1);
195
  }
7609 bpr 196
}
197
 
16866 guerimand 198
/* traitement de plusieurs utilisateurs (appel de oneuser
199
  pour chacun d'entre eux */
7609 bpr 200
void multiuser(char *dirname, char *user)
201
{
12200 bpr 202
  char buf[MAX_LINELEN+1];
203
  char *u1, *u2;
204
  snprintf(buf,sizeof(buf),"%s",user);
205
  for(u1=find_word_start(buf); *u1; u1=find_word_start(u2)) {
206
    u2=find_word_end(u1); if(*u2) *u2++=0;
207
    oneuser(dirname, u1);
7609 bpr 208
  }
209
}
210
 
16866 guerimand 211
/* fonction de generation des statistiques en utilisant les donnees
212
   recoltees dans les fichiers de log avec oneuser onefile etc...
213
   ne realise les statistiques que sur une feuille ou exam
214
   en meme temps */
8254 bpr 215
void stati(statexodata *dat)
10 reyssat 216
{
12200 bpr 217
  int i,j;
218
  double s,d;
219
  scsum=scavg=scdeviat=dursum=duravg=durdeviat=cid=0;
220
  scmin=10; scmax=0; durmin=24*3600; durmax=0;
221
  {int k; for(k=0; k<10; k++) best[k]=0 ;}
222
  for(i=0,j=dat->firstscore; i<dat->scorecnt; i++) {
223
    s=(double) scores[j].score/100; d=(double) scores[j].dure/60;
224
    scsum+=s; dursum+=d;
225
    if(scmin>s) scmin=s;
226
    if(scmax<s) scmax=s;
227
    if(durmin>d) durmin=d;
228
    if(durmax<d) durmax=d;
229
    {
230
     int k, l = 0;
231
     for (k = 0; k < 10; k++) if (best[k] < best[l]) l = k;
232
     if (best[l] < s) best[l] = s;
233
    }
234
    j=scores[j].next;
235
  }
236
  if(i<=0) {scmin=durmin=0; return;}
237
  scavg=scsum/i; duravg=dursum/i;
238
  if(scsum>1) cid=min(4*sqrt(dursum*dat->newcnt)/scsum,99);
239
  else cid=0;
240
  if(i>=2) {
10 reyssat 241
    for(i=0,j=dat->firstscore; i<dat->scorecnt; i++) {
7158 bpr 242
      s=(double) scores[j].score/100; d=(double) scores[j].dure/60;
12200 bpr 243
      scdeviat+=(s-scavg)*(s-scavg); durdeviat+=(d-duravg)*(d-duravg);
7158 bpr 244
      j=scores[j].next;
10 reyssat 245
    }
12200 bpr 246
    scdeviat=sqrt(scdeviat/i); durdeviat=sqrt(durdeviat/i);
247
  }
10 reyssat 248
}
249
 
7571 bpr 250
/* Output line format:
251
 * type sh exo newcnt scorecnt scsum dursum scavg duravg scmin durmin scmax durmax scdeviat durdeviat cid
252
 */
7609 bpr 253
 
254
void  outsheetexo (int i, int flag)
10 reyssat 255
{
7609 bpr 256
  if(shdata[i].newcnt<=0) return;
257
  stati(shdata+i);
258
  switch(flag) {
259
     case 0: printf(":S %2d %2d %4d %4d \
10 reyssat 260
%4.0f %4.0f %5.2f %5.2f \
261
%5.2f %4.1f %5.2f %5.1f \
262
%5.2f %5.2f %4.1f\n",
8254 bpr 263
             i/MAX_EXOS+1,i%MAX_EXOS+1,
7158 bpr 264
             shdata[i].newcnt, shdata[i].scorecnt,
265
             scsum, dursum,
266
             scavg, duravg,
267
             scmin,durmin,scmax,durmax,
268
             scdeviat, durdeviat,
7609 bpr 269
             cid); break;
270
     case 1: printf("%d_%d=%d,%d,\
271
%.0f,%.0f,%.2f,%.2f,\
272
%.2f,%.1f,%.2f,%.1f,\
273
%.2f,%.2f,%.1f;",
8254 bpr 274
             i/MAX_EXOS+1,i%MAX_EXOS+1,
7609 bpr 275
             shdata[i].newcnt, shdata[i].scorecnt,
276
             scsum, dursum,
277
             scavg, duravg,
278
             scmin,durmin,scmax,durmax,
279
             scdeviat, durdeviat,
7158 bpr 280
             cid);
7609 bpr 281
            int k; for (k=0; k<10; k++) printf("%.2f,", best[k]);
282
            printf("\n");
283
            break;
12200 bpr 284
  }
7609 bpr 285
}
286
 
287
void outexamexo (int i)
288
{
12200 bpr 289
  if(examdata[i].newcnt<=0) return;
290
  stati(examdata+i);
291
  printf(":E %2d %2d %4d %4d \
10 reyssat 292
%4.0f %4.0f %5.2f %5.2f \
293
%5.2f %4.1f %5.2f %5.1f \
294
%5.2f %5.2f %4.1f\n",
8254 bpr 295
             i/MAX_EXOS+1,i%MAX_EXOS+1,
7158 bpr 296
             examdata[i].newcnt, examdata[i].scorecnt,
297
             scsum, dursum,
298
             scavg, duravg,
299
             scmin,durmin,scmax,durmax,
300
             scdeviat, durdeviat,
301
             cid);
10 reyssat 302
}
303
 
16866 guerimand 304
 
305
/* ecriture de la sortie */
7609 bpr 306
void output(void)
307
{
12200 bpr 308
  int i;
309
  for(i=0;i<MAX_SHEETS*MAX_EXOS;i++) { outsheetexo(i, 0);}
310
  for(i=0;i<MAX_EXAMS*MAX_EXOS;i++) { outexamexo(i);}
7609 bpr 311
}
312
 
10 reyssat 313
int main()
314
{
12200 bpr 315
  char cla[MAX_LINELEN+1], user[256];
316
  char *c1, *c2;
317
  char *cdata, *udata, *sh;
7158 bpr 318
 
12200 bpr 319
  memset(shdata,0,sizeof(shdata)); memset(examdata,0,sizeof(examdata));
320
  dirbase=getenv("exostat_dirbase");
321
  if(dirbase==NULL || *dirbase==0) dirbase="../log/classes";
322
  sdata=getenv("exostat_types");
323
  if(sdata==NULL || *sdata==0) sdata="score noscore";
324
  cdata=getenv("exostat_classes");
325
  if(cdata==NULL || *cdata==0) cdata=getenv("w_wims_class");
326
  if(cdata==NULL || *cdata==0) return -1;
327
  snprintf(cla,sizeof(cla),"%s",cdata);
328
  udata=getenv("exostat_user");
329
  if(udata==NULL || *udata==0) {
330
    for(c1=cla; *c1; c1++) if(!isalnum(*c1) && *c1!='/') *c1=' ';
331
    for(c1=find_word_start(cla); *c1; c1=find_word_start(c2)) {
332
      c2=find_word_end(c1); if(*c2) *c2++=0;
333
      onedir(c1);
334
    }
335
    output();
336
  } else {
337
    snprintf(user,sizeof(user),"%s",udata);
338
    multiuser(cla, user);
339
    sh=getenv("exostat_sheet");
340
    if( sh==NULL || *sh==0 ) output();
341
    else {
342
      int s=atoi(sh);
343
      s=(s-1)*MAX_EXOS;
344
      int i;
345
      for(i=s;i < s + MAX_EXOS;i++) {
346
        outsheetexo(i, 1);
7609 bpr 347
      }
12200 bpr 348
    };
349
  }
350
  return 0;
10 reyssat 351
}