Subversion Repositories wimsdev

Rev

Rev 10 | Rev 7158 | 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
 
18
        /* This is an internal program,
19
         * used to show statistics of frequentation, module by module. */
20
 
21
#include "../Lib/libwims.h"
22
 
23
#define MAX_EXO         64
24
#define MAX_SHEET       64
25
#define MAX_EXAM        32
26
#define MAX_SCORE       512*1024
27
 
28
typedef struct {
29
    short int dure,score;
30
    long int next;
31
} scoredata;
32
scoredata scores[MAX_SCORE];
33
int sccnt=0;
34
 
35
typedef struct {
36
    int newcnt,scorecnt,lasttime,firstscore,lastscore;
37
    char lastnew[12];
38
} exodata;
39
exodata shdata[MAX_SHEET*MAX_EXO],examdata[MAX_EXAM*MAX_EXO];
40
 
41
/* cid: combined index of difficulty */
42
double scsum, scavg, scdeviat, scmin, scmax, cid;
43
double dursum, duravg, durdeviat, durmin, durmax;
44
 
45
int filecnt=0, fcind;
46
char *dirbase, types[256];
47
 
48
int str2time(char *p)
49
{
50
    int sec,min,hr;
51
    sec=atoi(p+15); p[14]=0;
52
    min=atoi(p+12); p[11]=0;
53
    hr=atoi(p+9);
54
    if(sec<0 || min<0 || hr<0 || sec>59 || min>59 || hr>23) return -1;
55
    return hr*3600+min*60+sec;
56
}
57
 
58
void oneline(char *p)
59
{
60
    int i, sh, ex, t;
61
    char *data[64];
62
    exodata *tab;
63
    char *pp, *pe;
64
 
65
    for(i=0, pp=find_word_start(p); i<8 && *pp; pp=find_word_start(pe),i++) {
66
        pe=find_word_end(pp); if(*pe) *pe++=0;
67
        data[i]=pp;
68
    }
69
    if(i<6) return;
70
    sh=atoi(data[2]); ex=atoi(data[3]);
71
    if(sh<=0 || ex<=0 || ex>MAX_EXO || strlen(data[1])>10) return;
72
    if(data[0][0]=='E') {
73
        tab=examdata; data[0]++; if(sh>MAX_EXAM) return;
74
    }
75
    else {
76
        tab=shdata; if(sh>MAX_SHEET) return;
77
    }
78
    tab+=(sh-1)*MAX_EXO+(ex-1);
79
    t=str2time(data[0]); if(t==-1) return;
80
    if(strstr(data[4],"new")!=NULL) {
81
        snprintf(tab->lastnew,12,"%s",data[1]);
82
        tab->newcnt++; tab->lasttime=t;
83
        fcind++;
84
        return;
85
    }
86
    if(strcmp(data[4],"score")==0) {
87
        if(strcmp(tab->lastnew,data[1])!=0) return;
88
        if(sccnt>=MAX_SCORE) return;
89
        if(tab->lasttime==-1) return;
90
        t-=tab->lasttime; tab->lasttime=-1; if(t<0) t+=24*3600;
91
        if(t<0) t=0; if(t>5*3600) t=5*3600;
92
        scores[sccnt].dure=t; scores[sccnt].next=-1;
93
        scores[sccnt].score=(double) atof(data[5])*100+0.5;
94
        if(tab->scorecnt>0) scores[tab->lastscore].next=sccnt;
95
        else tab->firstscore=sccnt;
96
        tab->lastscore=sccnt; sccnt++; tab->scorecnt++;
97
    }
98
}
99
 
100
void onefile(char *fname)
101
{
102
    FILE *f;
103
    char *buf, *pp, *pe;
104
    long int l;
105
    f=fopen(fname,"r"); if(f==NULL) return;
106
    fseek(f,0,SEEK_END); l=ftell(f); fseek(f,0,SEEK_SET);
107
    if(l<=0) {fclose(f); return;}
3840 kbelabas 108
    buf=xmalloc(l+16); (void)fread(buf,1,l,f); fclose(f); buf[l]=0;
10 reyssat 109
    fcind=0;
110
    for(pp=buf; pp; pp=pe) {
111
        pe=strchr(pp,'\n'); if(pe!=NULL) *pe++=0;
112
        oneline(pp);
113
    }
114
    free(buf);
115
    if(fcind>0) filecnt++;
116
}
117
 
118
void onedir(char *dirname)
119
{
120
    char buf[MAX_LINELEN+1], buf2[MAX_LINELEN+1];
121
    DIR *dir;
122
    struct dirent *ff;
123
    char *t1, *t2;
124
 
125
    for(t1=find_word_start(types); *t1; t1=find_word_start(t2)) {
126
        t2=find_word_end(t1); if(*t2) *t2++=0;
127
        snprintf(buf,sizeof(buf),"%s/%s/%s",dirbase,dirname,t1);
128
        dir=opendir(buf); if(dir==NULL) return;
129
        while((ff=readdir(dir))!=NULL) {
130
            if(!isalnum(ff->d_name[0]) ||
131
               strcmp(ff->d_name,"supervisor")==0) continue;
132
            snprintf(buf2,sizeof(buf2),"%s/%s",buf,ff->d_name);
133
            onefile(buf2);
134
        }
135
        closedir(dir);
136
    }
137
}
138
 
139
void stati(exodata *dat)
140
{
141
    int i,j;
142
    double s,d;
143
 
144
    scsum=scavg=scdeviat=dursum=duravg=durdeviat=cid=0;
145
    scmin=10; scmax=0; durmin=24*3600; durmax=0;
146
    for(i=0,j=dat->firstscore; i<dat->scorecnt; i++) {
147
        s=(double) scores[j].score/100; d=(double) scores[j].dure/60;
148
        scsum+=s; dursum+=d;
149
        if(scmin>s) scmin=s; if(scmax<s) scmax=s;
150
        if(durmin>d) durmin=d; if(durmax<d) durmax=d;
151
        j=scores[j].next;
152
    }
153
    if(i<=0) {scmin=durmin=0; return;}
154
    scavg=scsum/i; duravg=dursum/i;
155
    if(scsum>1) cid=min(4*sqrt(dursum*dat->newcnt)/scsum,99);
156
    else cid=0;
157
    if(i>=2) {
158
        for(i=0,j=dat->firstscore; i<dat->scorecnt; i++) {
159
            s=(double) scores[j].score/100; d=(double) scores[j].dure/60;
160
            scdeviat+=(s-scavg)*(s-scavg); durdeviat+=(d-duravg)*(d-duravg);
161
            j=scores[j].next;
162
        }
163
        scdeviat=sqrt(scdeviat/i); durdeviat=sqrt(durdeviat/i);
164
    }
165
}
166
 
167
        /* Output line format:
168
         * type sh exo newcnt scorecnt scsum dursum scavg duravg scmin durmin scmax durmax scdeviat durdeviat cid*/
169
void output(void)
170
{
171
    int i;
172
    for(i=0;i<MAX_SHEET*MAX_EXO;i++) {
173
        if(shdata[i].newcnt<=0) continue;
174
        stati(shdata+i);
175
        printf(":S %2d %2d %4d %4d \
176
%4.0f %4.0f %5.2f %5.2f \
177
%5.2f %4.1f %5.2f %5.1f \
178
%5.2f %5.2f %4.1f\n",
179
               i/MAX_EXO+1,i%MAX_EXO+1,
180
               shdata[i].newcnt, shdata[i].scorecnt,
181
               scsum, dursum,
182
               scavg, duravg,
183
               scmin,durmin,scmax,durmax,
184
               scdeviat, durdeviat,
185
               cid);
186
    }
187
    for(i=0;i<MAX_EXAM*MAX_EXO;i++) {
188
        if(examdata[i].newcnt<=0) continue;
189
        stati(examdata+i);
190
        printf(":E %2d %2d %4d %4d \
191
%4.0f %4.0f %5.2f %5.2f \
192
%5.2f %4.1f %5.2f %5.1f \
193
%5.2f %5.2f %4.1f\n",
194
               i/MAX_EXO+1,i%MAX_EXO+1,
195
               examdata[i].newcnt, examdata[i].scorecnt,
196
               scsum, dursum,
197
               scavg, duravg,
198
               scmin,durmin,scmax,durmax,
199
               scdeviat, durdeviat,
200
               cid);
201
    }
202
}
203
 
204
int main()
205
{
206
    char cla[MAX_LINELEN+1];
207
    char *c1, *c2;
208
    char *sdata, *cdata;
209
 
210
    memset(shdata,0,sizeof(shdata)); memset(examdata,0,sizeof(examdata));
211
    dirbase=getenv("exostat_dirbase");
212
    if(dirbase==NULL || *dirbase==0) dirbase="../log/classes";
213
    sdata=getenv("exostat_types");
214
    if(sdata==NULL || *sdata==0) sdata="score noscore";
215
    cdata=getenv("exostat_classes");
216
    if(cdata==NULL || *cdata==0) cdata=getenv("w_wims_class");
217
    if(cdata==NULL || *cdata==0) return -1;
218
    snprintf(types,sizeof(types),"%s",sdata);
219
    snprintf(cla,sizeof(cla),"%s",cdata);
220
    for(c1=cla; *c1; c1++) if(!isalnum(*c1) && *c1!='/') *c1=' ';
221
    for(c1=find_word_start(cla); *c1; c1=find_word_start(c2)) {
222
        c2=find_word_end(c1); if(*c2) *c2++=0;
223
        onedir(c1);
224
    }
225
    output();
226
    return 0;
227
}
228