Upload 43 files
Browse files- .gitattributes +3 -0
- All_major.csv +3 -0
- Columns/column_BA.txt +111 -0
- Columns/column_BE.txt +53 -0
- Columns/column_BT.txt +195 -0
- Columns/column_CE.txt +41 -0
- Columns/column_EE.txt +66 -0
- Columns/column_EN.txt +48 -0
- Columns/column_EV.txt +41 -0
- Columns/column_IE.txt +64 -0
- Columns/column_IT.txt +91 -0
- Columns/column_MA.txt +37 -0
- Columns/column_SE.txt +37 -0
- HCM.png +0 -0
- Logo-iuoss-trans.png +0 -0
- README.md +2 -9
- Student System · Streamlit.pdf +3 -0
- Userscript re-installation.html +14 -0
- __pycache__/function.cpython-311.pyc +0 -0
- app.bat +3 -0
- app.bat - Shortcut.lnk +0 -0
- database.db +3 -0
- function.py +288 -140
- main.py +888 -0
- model/BA_rank.joblib +3 -0
- model/BE_rank.joblib +3 -0
- model/BT_rank.joblib +3 -0
- model/CE_rank.joblib +3 -0
- model/EE_rank.joblib +3 -0
- model/EN_rank.joblib +3 -0
- model/EV_rank.joblib +3 -0
- model/IE_rank.joblib +3 -0
- model/IT_rank.joblib +3 -0
- model/MA_rank.joblib +3 -0
- model/SE_rank.joblib +3 -0
- model/Time/Late.joblib +3 -0
- model/Time/Sem.joblib +3 -0
- requirements.txt +1 -0
.gitattributes
CHANGED
@@ -35,3 +35,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
Analyze-and-predict-student-scores/All_maj.csv filter=lfs diff=lfs merge=lfs -text
|
37 |
All_maj.csv filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
Analyze-and-predict-student-scores/All_maj.csv filter=lfs diff=lfs merge=lfs -text
|
37 |
All_maj.csv filter=lfs diff=lfs merge=lfs -text
|
38 |
+
All_major.csv filter=lfs diff=lfs merge=lfs -text
|
39 |
+
database.db filter=lfs diff=lfs merge=lfs -text
|
40 |
+
Student[[:space:]]System[[:space:]]·[[:space:]]Streamlit.pdf filter=lfs diff=lfs merge=lfs -text
|
All_major.csv
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:00b38ab80266b79882e1dcf3e7a5e0344f75651804c68adee1ae9d93c325d56c
|
3 |
+
size 36064560
|
Columns/column_BA.txt
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
BA0005
|
2 |
+
BA002
|
3 |
+
BA003
|
4 |
+
BA005
|
5 |
+
BA006
|
6 |
+
BA007
|
7 |
+
BA010
|
8 |
+
BA011
|
9 |
+
BA015
|
10 |
+
BA016
|
11 |
+
BA018
|
12 |
+
BA020
|
13 |
+
BA022
|
14 |
+
BA023
|
15 |
+
BA027
|
16 |
+
BA028
|
17 |
+
BA029
|
18 |
+
BA030
|
19 |
+
BA032
|
20 |
+
BA035
|
21 |
+
BA038
|
22 |
+
BA045
|
23 |
+
BA051
|
24 |
+
BA054
|
25 |
+
BA057
|
26 |
+
BA065
|
27 |
+
BA068
|
28 |
+
BA080
|
29 |
+
BA081
|
30 |
+
BA082
|
31 |
+
BA083
|
32 |
+
BA084
|
33 |
+
BA086
|
34 |
+
BA087
|
35 |
+
BA094
|
36 |
+
BA098
|
37 |
+
BA115
|
38 |
+
BA116
|
39 |
+
BA117
|
40 |
+
BA118
|
41 |
+
BA119
|
42 |
+
BA120
|
43 |
+
BA123
|
44 |
+
BA130
|
45 |
+
BA134
|
46 |
+
BA138
|
47 |
+
BA140
|
48 |
+
BA142
|
49 |
+
BA145
|
50 |
+
BA146
|
51 |
+
BA151
|
52 |
+
BA153
|
53 |
+
BA154
|
54 |
+
BA155
|
55 |
+
BA156
|
56 |
+
BA160
|
57 |
+
BA161
|
58 |
+
BA162
|
59 |
+
BA164
|
60 |
+
BA167
|
61 |
+
BA168
|
62 |
+
BA169
|
63 |
+
BA170
|
64 |
+
BA171
|
65 |
+
BA172
|
66 |
+
BA174
|
67 |
+
BA176
|
68 |
+
BA182
|
69 |
+
BA183
|
70 |
+
BA184
|
71 |
+
BA185
|
72 |
+
BA186
|
73 |
+
BA189
|
74 |
+
BA190
|
75 |
+
BA191
|
76 |
+
BA192
|
77 |
+
BA197
|
78 |
+
BA198
|
79 |
+
BA206
|
80 |
+
BA207
|
81 |
+
BA213
|
82 |
+
BA214
|
83 |
+
BA216
|
84 |
+
BA217
|
85 |
+
BA218
|
86 |
+
BA222
|
87 |
+
BA223
|
88 |
+
BA226
|
89 |
+
BA228
|
90 |
+
BA229
|
91 |
+
BA231
|
92 |
+
BA232
|
93 |
+
BA233
|
94 |
+
BA243
|
95 |
+
BA245
|
96 |
+
BA254
|
97 |
+
BA256
|
98 |
+
BA257
|
99 |
+
BA272
|
100 |
+
BA273
|
101 |
+
BA274
|
102 |
+
BA275
|
103 |
+
BA276
|
104 |
+
BA277
|
105 |
+
BA278
|
106 |
+
BA279
|
107 |
+
BA280
|
108 |
+
BA281
|
109 |
+
BA282
|
110 |
+
BA283
|
111 |
+
BA284
|
Columns/column_BE.txt
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
BM003
|
2 |
+
BM004
|
3 |
+
BM005
|
4 |
+
BM007
|
5 |
+
BM008
|
6 |
+
BM009
|
7 |
+
BM010
|
8 |
+
BM011
|
9 |
+
BM012
|
10 |
+
BM013
|
11 |
+
BM017
|
12 |
+
BM020
|
13 |
+
BM030
|
14 |
+
BM033
|
15 |
+
BM050
|
16 |
+
BM052
|
17 |
+
BM058
|
18 |
+
BM060
|
19 |
+
BM061
|
20 |
+
BM062
|
21 |
+
BM063
|
22 |
+
BM064
|
23 |
+
BM067
|
24 |
+
BM068
|
25 |
+
BM069
|
26 |
+
BM070
|
27 |
+
BM073
|
28 |
+
BM074
|
29 |
+
BM075
|
30 |
+
BM076
|
31 |
+
BM077
|
32 |
+
BM078
|
33 |
+
BM079
|
34 |
+
BM080
|
35 |
+
BM082
|
36 |
+
BM083
|
37 |
+
BM084
|
38 |
+
BM085
|
39 |
+
BM086
|
40 |
+
BM089
|
41 |
+
BM090
|
42 |
+
BM091
|
43 |
+
BM092
|
44 |
+
BM094
|
45 |
+
BM095
|
46 |
+
BM096
|
47 |
+
BM098
|
48 |
+
BM099
|
49 |
+
BM100
|
50 |
+
BM101
|
51 |
+
BM102
|
52 |
+
BM103
|
53 |
+
BM104
|
Columns/column_BT.txt
ADDED
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
BT008
|
2 |
+
BT009
|
3 |
+
BT010
|
4 |
+
BT150
|
5 |
+
BT152
|
6 |
+
BT155
|
7 |
+
BT156
|
8 |
+
BT162
|
9 |
+
BT163
|
10 |
+
BT164
|
11 |
+
BT168
|
12 |
+
BT172
|
13 |
+
BT174
|
14 |
+
BT179
|
15 |
+
BT184
|
16 |
+
BT185
|
17 |
+
BT200
|
18 |
+
BT201
|
19 |
+
BT203
|
20 |
+
BT205
|
21 |
+
BT207
|
22 |
+
BT210
|
23 |
+
BT211
|
24 |
+
BT212
|
25 |
+
BT213
|
26 |
+
BT214
|
27 |
+
BT216
|
28 |
+
BT217
|
29 |
+
BT218
|
30 |
+
BT220
|
31 |
+
BT221
|
32 |
+
BT222
|
33 |
+
BT223
|
34 |
+
BT224
|
35 |
+
BT225
|
36 |
+
BT306
|
37 |
+
BT307
|
38 |
+
BT308
|
39 |
+
BT309
|
40 |
+
BT310
|
41 |
+
BT311
|
42 |
+
BT312
|
43 |
+
BT313
|
44 |
+
BT314
|
45 |
+
BT315
|
46 |
+
BT316
|
47 |
+
BT317
|
48 |
+
BT318
|
49 |
+
BT319
|
50 |
+
BT320
|
51 |
+
BT321
|
52 |
+
BT322
|
53 |
+
BT333
|
54 |
+
BT334
|
55 |
+
BT335
|
56 |
+
BT336
|
57 |
+
BT337
|
58 |
+
BT338
|
59 |
+
BT339
|
60 |
+
BT340
|
61 |
+
BT343
|
62 |
+
BT344
|
63 |
+
BT345
|
64 |
+
BT346
|
65 |
+
BT347
|
66 |
+
BT348
|
67 |
+
BT349
|
68 |
+
BT350
|
69 |
+
BT351
|
70 |
+
BT352
|
71 |
+
BT353
|
72 |
+
BT354
|
73 |
+
BT355
|
74 |
+
BT356
|
75 |
+
BT357
|
76 |
+
BT358
|
77 |
+
BT359
|
78 |
+
BT360
|
79 |
+
BT405
|
80 |
+
BT500
|
81 |
+
BTAR101
|
82 |
+
BTAR102
|
83 |
+
BTAR201
|
84 |
+
BTAR202
|
85 |
+
BTAR205
|
86 |
+
BTAR206
|
87 |
+
BTAR207
|
88 |
+
BTAR208
|
89 |
+
BTAR306
|
90 |
+
BTAR308
|
91 |
+
BTAR310
|
92 |
+
BTAR311
|
93 |
+
BTAR312
|
94 |
+
BTAR313
|
95 |
+
BTAR314
|
96 |
+
BTBC101
|
97 |
+
BTBC102
|
98 |
+
BTBC103
|
99 |
+
BTBC104
|
100 |
+
BTBC201
|
101 |
+
BTBC202
|
102 |
+
BTBC203
|
103 |
+
BTBC204
|
104 |
+
BTBC205
|
105 |
+
BTBC206
|
106 |
+
BTBC207
|
107 |
+
BTBC209
|
108 |
+
BTBC210
|
109 |
+
BTBC211
|
110 |
+
BTBC212
|
111 |
+
BTBC213
|
112 |
+
BTBC214
|
113 |
+
BTBC215
|
114 |
+
BTBC216
|
115 |
+
BTBC301
|
116 |
+
BTBC302
|
117 |
+
BTBC304
|
118 |
+
BTBC309
|
119 |
+
BTBC311
|
120 |
+
BTBC312
|
121 |
+
BTBC313
|
122 |
+
BTBC314
|
123 |
+
BTBC315
|
124 |
+
BTBC316
|
125 |
+
BTBC317
|
126 |
+
BTBC318
|
127 |
+
BTBC402
|
128 |
+
BTBC403
|
129 |
+
BTBC405
|
130 |
+
BTBC406
|
131 |
+
BTBC408
|
132 |
+
BTBC409
|
133 |
+
BTBC410
|
134 |
+
BTBC411
|
135 |
+
BTBC412
|
136 |
+
BTBC413
|
137 |
+
BTBC414
|
138 |
+
BTBC415
|
139 |
+
BTBC416
|
140 |
+
BTBC419
|
141 |
+
BTBC420
|
142 |
+
BTBC421
|
143 |
+
BTBC422
|
144 |
+
BTBC500
|
145 |
+
BTFT201
|
146 |
+
BTFT202
|
147 |
+
BTFT203
|
148 |
+
BTFT204
|
149 |
+
BTFT205
|
150 |
+
BTFT206
|
151 |
+
BTFT208
|
152 |
+
BTFT234
|
153 |
+
BTFT236
|
154 |
+
BTFT254
|
155 |
+
BTFT256
|
156 |
+
BTFT301
|
157 |
+
BTFT302
|
158 |
+
BTFT303
|
159 |
+
BTFT304
|
160 |
+
BTFT305
|
161 |
+
BTFT306
|
162 |
+
BTFT309
|
163 |
+
BTFT310
|
164 |
+
BTFT311
|
165 |
+
BTFT316
|
166 |
+
BTFT331
|
167 |
+
BTFT332
|
168 |
+
BTFT334
|
169 |
+
BTFT337
|
170 |
+
BTFT351
|
171 |
+
BTFT352
|
172 |
+
BTFT354
|
173 |
+
BTFT357
|
174 |
+
BTFT401
|
175 |
+
BTFT402
|
176 |
+
BTFT403
|
177 |
+
BTFT405
|
178 |
+
BTFT406
|
179 |
+
BTFT407
|
180 |
+
BTFT408
|
181 |
+
BTFT409
|
182 |
+
BTFT411
|
183 |
+
BTFT431
|
184 |
+
BTFT432
|
185 |
+
BTFT435
|
186 |
+
BTFT436
|
187 |
+
BTFT437
|
188 |
+
BTFT438
|
189 |
+
BTFT451
|
190 |
+
BTFT452
|
191 |
+
BTFT455
|
192 |
+
BTFT456
|
193 |
+
BTFT457
|
194 |
+
BTFT458
|
195 |
+
BTFT500
|
Columns/column_CE.txt
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
CE100
|
2 |
+
CE101
|
3 |
+
CE102
|
4 |
+
CE103
|
5 |
+
CE104
|
6 |
+
CE105
|
7 |
+
CE201
|
8 |
+
CE202
|
9 |
+
CE203
|
10 |
+
CE205
|
11 |
+
CE206
|
12 |
+
CE208
|
13 |
+
CE209
|
14 |
+
CE210
|
15 |
+
CE211
|
16 |
+
CE213
|
17 |
+
CE214
|
18 |
+
CE215
|
19 |
+
CE216
|
20 |
+
CE301
|
21 |
+
CE302
|
22 |
+
CE303
|
23 |
+
CE304
|
24 |
+
CE305
|
25 |
+
CE306
|
26 |
+
CE307
|
27 |
+
CE308
|
28 |
+
CE309
|
29 |
+
CE310
|
30 |
+
CE311
|
31 |
+
CE312
|
32 |
+
CE313
|
33 |
+
CE314
|
34 |
+
CE401
|
35 |
+
CE402
|
36 |
+
CE403
|
37 |
+
CE404
|
38 |
+
CE405
|
39 |
+
CE406
|
40 |
+
CE407
|
41 |
+
CE420
|
Columns/column_EE.txt
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
EE010
|
2 |
+
EE049
|
3 |
+
EE050
|
4 |
+
EE051
|
5 |
+
EE052
|
6 |
+
EE053
|
7 |
+
EE054
|
8 |
+
EE055
|
9 |
+
EE056
|
10 |
+
EE057
|
11 |
+
EE058
|
12 |
+
EE061
|
13 |
+
EE062
|
14 |
+
EE063
|
15 |
+
EE068
|
16 |
+
EE070
|
17 |
+
EE072
|
18 |
+
EE079
|
19 |
+
EE083
|
20 |
+
EE084
|
21 |
+
EE088
|
22 |
+
EE089
|
23 |
+
EE090
|
24 |
+
EE091
|
25 |
+
EE092
|
26 |
+
EE093
|
27 |
+
EE094
|
28 |
+
EE095
|
29 |
+
EE097
|
30 |
+
EE102
|
31 |
+
EE103
|
32 |
+
EE104
|
33 |
+
EE105
|
34 |
+
EE107
|
35 |
+
EE112
|
36 |
+
EE114
|
37 |
+
EE115
|
38 |
+
EE116
|
39 |
+
EE117
|
40 |
+
EE118
|
41 |
+
EE119
|
42 |
+
EE120
|
43 |
+
EE122
|
44 |
+
EE124
|
45 |
+
EE125
|
46 |
+
EE126
|
47 |
+
EE127
|
48 |
+
EE128
|
49 |
+
EE129
|
50 |
+
EE130
|
51 |
+
EE131
|
52 |
+
EE133
|
53 |
+
EEAC001
|
54 |
+
EEAC003
|
55 |
+
EEAC004
|
56 |
+
EEAC005
|
57 |
+
EEAC006
|
58 |
+
EEAC007
|
59 |
+
EEAC008
|
60 |
+
EEAC009
|
61 |
+
EEAC010
|
62 |
+
EEAC014
|
63 |
+
EEAC015
|
64 |
+
EEAC017
|
65 |
+
EEAC020
|
66 |
+
EEAC021
|
Columns/column_EN.txt
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
EL001
|
2 |
+
EL002
|
3 |
+
EL003
|
4 |
+
EL004
|
5 |
+
EL005
|
6 |
+
EL006
|
7 |
+
EL007
|
8 |
+
EL008
|
9 |
+
EL009
|
10 |
+
EL010
|
11 |
+
EL011
|
12 |
+
EL012
|
13 |
+
EL013
|
14 |
+
EL014
|
15 |
+
EL015
|
16 |
+
EL016
|
17 |
+
EL017
|
18 |
+
EL018
|
19 |
+
EL019
|
20 |
+
EL020
|
21 |
+
EL021
|
22 |
+
EL022
|
23 |
+
EL023
|
24 |
+
EL024
|
25 |
+
EL025
|
26 |
+
EL026
|
27 |
+
EL027
|
28 |
+
EL028
|
29 |
+
EL029
|
30 |
+
EL030
|
31 |
+
EL031
|
32 |
+
EL032
|
33 |
+
EL033
|
34 |
+
EL034
|
35 |
+
EL035
|
36 |
+
EL036
|
37 |
+
EL037
|
38 |
+
EL038
|
39 |
+
EL039
|
40 |
+
EL040
|
41 |
+
EL041
|
42 |
+
EL042
|
43 |
+
EL043
|
44 |
+
EL044
|
45 |
+
EL045
|
46 |
+
EL046
|
47 |
+
EL048
|
48 |
+
EL049
|
Columns/column_EV.txt
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
ENEE1001
|
2 |
+
ENEE1002
|
3 |
+
ENEE1003
|
4 |
+
ENEE1004
|
5 |
+
ENEE1005
|
6 |
+
ENEE1006
|
7 |
+
ENEE1007
|
8 |
+
ENEE1010
|
9 |
+
ENEE2001
|
10 |
+
ENEE2002
|
11 |
+
ENEE2003
|
12 |
+
ENEE2004
|
13 |
+
ENEE2005
|
14 |
+
ENEE2006
|
15 |
+
ENEE2007
|
16 |
+
ENEE2008
|
17 |
+
ENEE2009
|
18 |
+
ENEE2010
|
19 |
+
ENEE2011
|
20 |
+
ENEE2013
|
21 |
+
ENEE2014
|
22 |
+
ENEE2015
|
23 |
+
ENEE2016
|
24 |
+
ENEE2017
|
25 |
+
ENEE3101
|
26 |
+
ENEE3102
|
27 |
+
ENEE3103
|
28 |
+
ENEE3104
|
29 |
+
ENEE3106
|
30 |
+
ENEE3108
|
31 |
+
ENEE3109
|
32 |
+
ENEE3110
|
33 |
+
ENEE3111
|
34 |
+
ENEE3202
|
35 |
+
ENEE3208
|
36 |
+
ENEE3301
|
37 |
+
ENEE4002
|
38 |
+
ENEE4013
|
39 |
+
ENEE4016
|
40 |
+
ENEE5001
|
41 |
+
ENEE5002
|
Columns/column_IE.txt
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
IS001
|
2 |
+
IS003
|
3 |
+
IS004
|
4 |
+
IS005
|
5 |
+
IS006
|
6 |
+
IS012
|
7 |
+
IS013
|
8 |
+
IS014
|
9 |
+
IS015
|
10 |
+
IS016
|
11 |
+
IS017
|
12 |
+
IS018
|
13 |
+
IS019
|
14 |
+
IS020
|
15 |
+
IS023
|
16 |
+
IS024
|
17 |
+
IS025
|
18 |
+
IS026
|
19 |
+
IS027
|
20 |
+
IS028
|
21 |
+
IS031
|
22 |
+
IS032
|
23 |
+
IS033
|
24 |
+
IS034
|
25 |
+
IS035
|
26 |
+
IS040
|
27 |
+
IS041
|
28 |
+
IS043
|
29 |
+
IS045
|
30 |
+
IS048
|
31 |
+
IS050
|
32 |
+
IS052
|
33 |
+
IS053
|
34 |
+
IS054
|
35 |
+
IS055
|
36 |
+
IS056
|
37 |
+
IS057
|
38 |
+
IS058
|
39 |
+
IS059
|
40 |
+
IS062
|
41 |
+
IS063
|
42 |
+
IS066
|
43 |
+
IS067
|
44 |
+
IS068
|
45 |
+
IS069
|
46 |
+
IS070
|
47 |
+
IS071
|
48 |
+
IS072
|
49 |
+
IS073
|
50 |
+
IS074
|
51 |
+
IS076
|
52 |
+
IS077
|
53 |
+
IS078
|
54 |
+
IS079
|
55 |
+
IS081
|
56 |
+
IS082
|
57 |
+
IS083
|
58 |
+
IS084
|
59 |
+
IS085
|
60 |
+
IS086
|
61 |
+
IS087
|
62 |
+
IS089
|
63 |
+
IS090
|
64 |
+
IS091
|
Columns/column_IT.txt
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
IT001
|
2 |
+
IT002
|
3 |
+
IT003
|
4 |
+
IT004
|
5 |
+
IT006
|
6 |
+
IT007
|
7 |
+
IT008
|
8 |
+
IT009
|
9 |
+
IT010
|
10 |
+
IT011
|
11 |
+
IT012
|
12 |
+
IT013
|
13 |
+
IT014
|
14 |
+
IT015
|
15 |
+
IT016
|
16 |
+
IT017
|
17 |
+
IT018
|
18 |
+
IT019
|
19 |
+
IT020
|
20 |
+
IT022
|
21 |
+
IT024
|
22 |
+
IT025
|
23 |
+
IT027
|
24 |
+
IT031
|
25 |
+
IT034
|
26 |
+
IT041
|
27 |
+
IT044
|
28 |
+
IT045
|
29 |
+
IT046
|
30 |
+
IT056
|
31 |
+
IT057
|
32 |
+
IT058
|
33 |
+
IT060
|
34 |
+
IT063
|
35 |
+
IT064
|
36 |
+
IT065
|
37 |
+
IT067
|
38 |
+
IT068
|
39 |
+
IT069
|
40 |
+
IT072
|
41 |
+
IT073
|
42 |
+
IT075
|
43 |
+
IT076
|
44 |
+
IT077
|
45 |
+
IT079
|
46 |
+
IT080
|
47 |
+
IT082
|
48 |
+
IT083
|
49 |
+
IT089
|
50 |
+
IT090
|
51 |
+
IT091
|
52 |
+
IT092
|
53 |
+
IT093
|
54 |
+
IT094
|
55 |
+
IT096
|
56 |
+
IT097
|
57 |
+
IT098
|
58 |
+
IT099
|
59 |
+
IT100
|
60 |
+
IT103
|
61 |
+
IT107
|
62 |
+
IT112
|
63 |
+
IT114
|
64 |
+
IT115
|
65 |
+
IT116
|
66 |
+
IT117
|
67 |
+
IT119
|
68 |
+
IT120
|
69 |
+
IT122
|
70 |
+
IT124
|
71 |
+
IT125
|
72 |
+
IT130
|
73 |
+
IT131
|
74 |
+
IT132
|
75 |
+
IT133
|
76 |
+
IT134
|
77 |
+
IT135
|
78 |
+
IT136
|
79 |
+
IT137
|
80 |
+
IT138
|
81 |
+
IT139
|
82 |
+
IT140
|
83 |
+
IT142
|
84 |
+
IT143
|
85 |
+
IT145
|
86 |
+
IT149
|
87 |
+
IT150
|
88 |
+
IT151
|
89 |
+
IT153
|
90 |
+
IT154
|
91 |
+
IT155
|
Columns/column_MA.txt
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
MAFE101
|
2 |
+
MAFE102
|
3 |
+
MAFE103
|
4 |
+
MAFE104
|
5 |
+
MAFE105
|
6 |
+
MAFE109
|
7 |
+
MAFE201
|
8 |
+
MAFE202
|
9 |
+
MAFE203
|
10 |
+
MAFE204
|
11 |
+
MAFE205
|
12 |
+
MAFE206
|
13 |
+
MAFE207
|
14 |
+
MAFE208
|
15 |
+
MAFE209
|
16 |
+
MAFE212
|
17 |
+
MAFE214
|
18 |
+
MAFE215
|
19 |
+
MAFE301
|
20 |
+
MAFE302
|
21 |
+
MAFE303
|
22 |
+
MAFE305
|
23 |
+
MAFE306
|
24 |
+
MAFE307
|
25 |
+
MAFE308
|
26 |
+
MAFE309
|
27 |
+
MAFE311
|
28 |
+
MAFE312
|
29 |
+
MAFE313
|
30 |
+
MAFE314
|
31 |
+
MAFE315
|
32 |
+
MAFE316
|
33 |
+
MAFE401
|
34 |
+
MAFE402
|
35 |
+
MAFE403
|
36 |
+
MAFE404
|
37 |
+
MAFE409
|
Columns/column_SE.txt
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
PH012
|
2 |
+
PH013
|
3 |
+
PH014
|
4 |
+
PH015
|
5 |
+
PH016
|
6 |
+
PH018
|
7 |
+
PH019
|
8 |
+
PH020
|
9 |
+
PH024
|
10 |
+
PH025
|
11 |
+
PH026
|
12 |
+
PH027
|
13 |
+
PH029
|
14 |
+
PH030
|
15 |
+
PH031
|
16 |
+
PH035
|
17 |
+
PH036
|
18 |
+
PH037
|
19 |
+
PH038
|
20 |
+
PH039
|
21 |
+
PH040
|
22 |
+
PH041
|
23 |
+
PH042
|
24 |
+
PH043
|
25 |
+
PH044
|
26 |
+
PH045
|
27 |
+
PH046
|
28 |
+
PH047
|
29 |
+
PH049
|
30 |
+
PH050
|
31 |
+
PH051
|
32 |
+
PH052
|
33 |
+
PH053
|
34 |
+
PH054
|
35 |
+
PH055
|
36 |
+
PH056
|
37 |
+
PH057
|
HCM.png
ADDED
Logo-iuoss-trans.png
ADDED
README.md
CHANGED
@@ -1,9 +1,2 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
license: apache-2.0
|
4 |
-
title: Student System
|
5 |
-
sdk: streamlit
|
6 |
-
emoji: 🚀
|
7 |
-
colorFrom: yellow
|
8 |
-
colorTo: blue
|
9 |
-
---
|
|
|
1 |
+
# Analyze-and-predict-student-performance
|
2 |
+
Link to web-app: https://itdsiu19001-analyze-and-predict-student-performance-main-oiibq6.streamlit.app/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Student System · Streamlit.pdf
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:d1eb029a6a4fa063f49620a31e797b71e23dc329841d6ac712f84f1ac3b0d739
|
3 |
+
size 1963686
|
Userscript re-installation.html
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<!-- saved from url=(0101)chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/ask.html?aid=5b119d14-6ed7-47e6-bf66-89933b7227d2 -->
|
3 |
+
<html class="desktop dark"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
4 |
+
|
5 |
+
<link href="chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/editor.css" rel="stylesheet" type="text/css">
|
6 |
+
<link href="chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/style.css" rel="stylesheet" type="text/css">
|
7 |
+
|
8 |
+
<script src="chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/editor.js"></script>
|
9 |
+
<script src="chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/extension.js"></script><title>Userscript re-installation</title>
|
10 |
+
</head>
|
11 |
+
<body class="main">
|
12 |
+
|
13 |
+
|
14 |
+
<div id="div_Y3RfMA_p" class="curouter hide" style="z-index: 10000"><div id="div_Y3RfMA_d" class="curmiddle_fixed"><table id="table_Y3RfMA_table" class="curtable"><tr id="tr_Y3RfMA_tr2"><td id="td_Y3RfMA_td1" class="curtableoutertd"></td><td id="td_Y3RfMA_td2" class="curtableinner"><div class="curcontainer"><div class="curwaithead"></div><div class="curwaitmsg"><div class="lds-css ng-scope"><div class="lds-dual-ring"><div></div><div></div></div></div><div class="curtext">Please wait...</div></div></div></td><td id="td_Y3RfMA_td3" class="curtableoutertd"></td></tr></table></div><div id="div_Y3RfMA_c" class="curbg"></div></div><div id="div_YXNrX21haW4" class="content_wrapper"><div id="div_YXNrX2hlYWRfY29udGFpbmVy" class="head_container"><a id="a_aGVhZF9saW5rX2Fzaw_head_link" href="https://www.tampermonkey.net/" target="_blank"><div id="div_YXNrX2hlYWQx" class="float"><img id="img_YXNrX3VuZGVmaW5lZA" class="banner" src="data:image/svg+xml,%3C?xml%20version=%271.0%27%20encoding=%27utf-8%27?%3E%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20viewBox=%270%200%20400%20400%27%3E%3Cg%20id=%27XMLID_273_%27%3E%3Cg%20id=%27XMLID_78_%27%3E%3Cpath%20id=%27XMLID_83_%27%20class=%27st0%27%20d=%27M304.8,0H95.2C42.6,0,0,42.6,0,95.2v209.6C0,357.4,42.6,400,95.2,400h209.6%20c52.6,0,95.2-42.6,95.2-95.2V95.2C400,42.6,357.4,0,304.8,0z%20M106.3,375C61.4,375,25,338.6,25,293.8c0-44.9,36.4-81.3,81.3-81.3%20c44.9,0,81.3,36.4,81.3,81.3C187.5,338.6,151.1,375,106.3,375z%20M293.8,375c-44.9,0-81.3-36.4-81.3-81.3%20c0-44.9,36.4-81.3,81.3-81.3c44.9,0,81.3,36.4,81.3,81.3C375,338.6,338.6,375,293.8,375z%27/%3E%3C/g%3E%3Cg%20id=%27XMLID_67_%27%20class=%27st2%27%3E%3Cpath%20id=%27XMLID_74_%27%20class=%27st3%27%20d=%27M304.8,0H95.2C42.6,0,0,42.6,0,95.2v209.6C0,357.4,42.6,400,95.2,400h209.6%20c52.6,0,95.2-42.6,95.2-95.2V95.2C400,42.6,357.4,0,304.8,0z%20M106.3,375C61.4,375,25,338.6,25,293.8c0-44.9,36.4-81.3,81.3-81.3%20c44.9,0,81.3,36.4,81.3,81.3C187.5,338.6,151.1,375,106.3,375z%20M293.8,375c-44.9,0-81.3-36.4-81.3-81.3%20c0-44.9,36.4-81.3,81.3-81.3c44.9,0,81.3,36.4,81.3,81.3C375,338.6,338.6,375,293.8,375z%27/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"></div><div id="div_YXNrX2hlYWQy" class="float head"><div id="div_aGVhZGluZ191bmRlZmluZWQ" class="header_title">Tampermonkey<sup>®</sup></div><div id="div_dmVyc2lvbl92ZXJzaW9u" class="version">v4.18.1</div></div></a><div id="div_c2VhcmNoX2JveA_"></div></div><div id="div_YXNrX3R2X2NvbnRhaW5lcg" class="tv_container_fit"><div id="div_bWFpbm1haW5fdW5kZWZpbmVk" class="tv"><table id="table_bWFpbl90YWJsZW1haW5fdW5kZWZpbmVk" class="tv_table noborder"><tr id="tr_dGFic2Rpdl9ZWE5yWDNSMlgyTnZiblJoYVc1bGNnbWFpbl91bmRlZmluZWQ" class="tr_tabs"><td id="td_cGFnZXNtYWluX3VuZGVmaW5lZA" class="td_tabs"><div id="div_dHZfdGFic19maWxsbWFpbl91bmRlZmluZWQ" class="tv_tabs_fill"><div id="div_dHZfdGFic190YWJsZW1haW5fdW5kZWZpbmVk" class="tv_tabs_table"><div id="div_dHZfdGFic19hbGlnbm1haW5fdW5kZWZpbmVk" class="tv_tabs_align"><div id="div_dGFiX2JXRnBibDl0WVdsdV9jb250ZW50bWFpbg" tvid="bWFpbl9tYWlu" name="tabview_tabmain" class="tv_tab tv_selected" style="undefined" vis="true"><div id="div_bWFpbl9tYWlu_tab_content_h">Install<div id="div_dGFiX2JXRnBibDl0WVdsdV9oZWFkX3RleHRtYWlu"></div></div></div></div></div></div></td></tr><tr id="tr_Y29udGVudGRpdl9ZWE5yWDNSMlgyTnZiblJoYVc1bGNnbWFpbl91bmRlZmluZWQ" class="tr_content"><td id="td_Y29udGVudG1haW5fdW5kZWZpbmVk" class="td_content"><div id="div_dHZfY29udGVudG1haW5fdW5kZWZpbmVk" class="tv_contents"><div id="div_bWFpbl9tYWlu_tab_content" name="tabview_contentmain" class="tv_content" style="undefined" vis="true"><div id="div_Njc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3X2luc3RhbGxfc3Jj" class="section"><div id="div_Njc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3X3VuZGVmaW5lZA" class="viewer_upper"><div id="div_Z2VuZXJhbF82NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDc" class="viewer_info viewer_info_multiple"><h3 id="h3_aW5zdGFsbF9oZWFkaW5n_675d1929-24cc-4b5a-9513-9389e4063d47"><span id="span_bmFtZV9oZWFkaW5n_675d1929-24cc-4b5a-9513-9389e4063d47">Quizlet Editor</span><span id="span_aGVhZGluZ182NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDc" class="view_version">v0.2</span></h3><div id="div_Z2VuZXJhbF9jb250ZW50XzY3NWQxOTI5LTI0Y2MtNGI1YS05NTEzLTkzODllNDA2M2Q0Nw" class="viewer_content"><table id="table_Njc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3X3VuZGVmaW5lZA" class="script_desc"><tr id="tr_YXV0aG9yXzY3NWQxOTI5LTI0Y2MtNGI1YS05NTEzLTkzODllNDA2M2Q0Nw" class="script_desc"><td id="td_YXV0aG9yXzY3NWQxOTI5LTI0Y2MtNGI1YS05NTEzLTkzODllNDA2M2Q0N2R0" class="script_desc">Author</td><td id="td_YXV0aG9yXzY3NWQxOTI5LTI0Y2MtNGI1YS05NTEzLTkzODllNDA2M2Q0N2Rk" class="script_desc">troop129 + josephyooo</td></tr><tr id="tr_ZGVzY3JpcHRpb25fNjc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3" class="script_desc"><td id="td_ZGVzY3JpcHRpb25fNjc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3ZHQ" class="script_desc">Description</td><td id="td_ZGVzY3JpcHRpb25fNjc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3ZGQ" class="script_desc">Remove paywall for Quizlet answers</td></tr><tr id="tr_ZmlsZVVSTF82NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDc" class="script_desc"><td id="td_ZmlsZVVSTF82NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDdkdA" class="script_desc">Source</td><td id="td_ZmlsZVVSTF82NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDdkZA" class="script_desc">https://greasyfork.org/scripts/438663-quizlet-editor/code/Quizlet%20Editor.user.js</td></tr></table></div></div><div id="div_aW5mb182NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDc" class="viewer_info viewer_info_multiple"><div id="div_aW5mb19jb250ZW50XzY3NWQxOTI5LTI0Y2MtNGI1YS05NTEzLTkzODllNDA2M2Q0Nw" class="viewer_content"><h4 id="h4_YWN0aW9uX2hlYWRpbmc_675d1929-24cc-4b5a-9513-9389e4063d47">Userscript re-installation</h4><table id="table_ZXJyb3JzXzY3NWQxOTI5LTI0Y2MtNGI1YS05NTEzLTkzODllNDA2M2Q0NzA"></table><table id="table_d2FybmluZ3NfNjc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3MA"><tr id="tr_d2FybmluZ3NfNjc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3MQ"><td id="td_d2FybmluZ3NfNjc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3ZHQx"><i class="far fa-exclamation-triangle orange"></i> </td><td id="td_d2FybmluZ3NfNjc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3ZGQx">All script settings will be reset!</td></tr></table><table id="table_aW5mb182NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDcx"><tr id="tr_aW5mb182NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDcy"><td id="td_aW5mb182NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDdkdDI">Installed Version</td><td id="td_aW5mb182NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDdkZDI">v0.2</td></tr><tr id="tr_aW5mb182NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDcz"><td id="td_aW5mb182NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDdkdDM">Note</td><td id="td_aW5mb182NzVkMTkyOS0yNGNjLTRiNWEtOTUxMy05Mzg5ZTQwNjNkNDdkZDM">A recheck of the GreaseMonkey/FF compatibility options may be required in order to run this script.</td></tr></table><table id="table_aW5jbHVkZXNfNjc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3"><tr id="tr_aHR0cCo6Ly93d3cucXVpemxldC5jb20vZXhwbGFuYXRpb25zL3RleHRib29rLXNvbHV0aW9ucy8qXzY3NWQxOTI5LTI0Y2MtNGI1YS05NTEzLTkzODllNDA2M2Q0NzA" class="includesdesc"><td id="td_aHR0cCo6Ly93d3cucXVpemxldC5jb20vZXhwbGFuYXRpb25zL3RleHRib29rLXNvbHV0aW9ucy8qXzY3NWQxOTI5LTI0Y2MtNGI1YS05NTEzLTkzODllNDA2M2Q0NzBkdA" class="includesdesc">Include(s)</td><td id="td_aHR0cCo6Ly93d3cucXVpemxldC5jb20vZXhwbGFuYXRpb25zL3RleHRib29rLXNvbHV0aW9ucy8qXzY3NWQxOTI5LTI0Y2MtNGI1YS05NTEzLTkzODllNDA2M2Q0NzBkZA" class="includesdesc">http*://www.quizlet.com/explanations/textbook-solutions/*</td></tr><tr id="tr_aHR0cCo6Ly9xdWl6bGV0LmNvbS9leHBsYW5hdGlvbnMvdGV4dGJvb2stc29sdXRpb25zLypfNjc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3MQ" class="includesdesc"><td id="td_aHR0cCo6Ly9xdWl6bGV0LmNvbS9leHBsYW5hdGlvbnMvdGV4dGJvb2stc29sdXRpb25zLypfNjc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3MWR0" class="includesdesc"> </td><td id="td_aHR0cCo6Ly9xdWl6bGV0LmNvbS9leHBsYW5hdGlvbnMvdGV4dGJvb2stc29sdXRpb25zLypfNjc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3MWRk" class="includesdesc">http*://quizlet.com/explanations/textbook-solutions/*</td></tr></table><table id="table_ZXhjbHVkZXNfNjc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3"></table></div></div></div><div id="div_aW5zdGFsbF91bmRlZmluZWQ" class="viewer_last"><div id="div_aW5zdGFsbF9jb250ZW50X3VuZGVmaW5lZA" class="viewer_content"><div id="div_aW5zdGFsbF9idXR0b25zX3VuZGVmaW5lZA" class="ask_action_buttons"><input id="input_UmVpbnN0YWxsX3VuZGVmaW5lZA_bu" class="button install" name="Reinstall" type="button" value="Reinstall"><input id="input_Q2FuY2VsX3VuZGVmaW5lZA_bu" class="button install" name="Cancel" type="button" value="Cancel"></div></div></div><div id="div_Ym90dG9tXw" class="viewer_bottom_tab"><div id="div_bWFpbnNvdXJjZTY3NWQxOTI5MjRjYzRiNWE5NTEzOTM4OWU0MDYzZDQ3X3VuZGVmaW5lZA" class="tv tv_alt"><table id="table_bWFpbl90YWJsZXNvdXJjZTY3NWQxOTI5MjRjYzRiNWE5NTEzOTM4OWU0MDYzZDQ3X3VuZGVmaW5lZA" class="tv_table tv_table_alt noborder"><tr id="tr_dGFic2Rpdl9ZbTkwZEc5dFh3c291cmNlNjc1ZDE5MjkyNGNjNGI1YTk1MTM5Mzg5ZTQwNjNkNDdfdW5kZWZpbmVk" class="tr_tabs tr_tabs_alt"><td id="td_cGFnZXNzb3VyY2U2NzVkMTkyOTI0Y2M0YjVhOTUxMzkzODllNDA2M2Q0N191bmRlZmluZWQ" class="td_tabs td_tabs_alt"><div id="div_dHZfdGFic19maWxsc291cmNlNjc1ZDE5MjkyNGNjNGI1YTk1MTM5Mzg5ZTQwNjNkNDdfdW5kZWZpbmVk" class="tv_tabs_fill tv_tabs_fill_alt"><div id="div_dHZfdGFic190YWJsZXNvdXJjZTY3NWQxOTI5MjRjYzRiNWE5NTEzOTM4OWU0MDYzZDQ3X3VuZGVmaW5lZA" class="tv_tabs_table tv_tabs_table_alt"><div id="div_dHZfdGFic19hbGlnbnNvdXJjZTY3NWQxOTI5MjRjYzRiNWE5NTEzOTM4OWU0MDYzZDQ3X3VuZGVmaW5lZA" class="tv_tabs_align tv_tabs_align_alt"><div id="div_dGFiX3NvdXJjZV9jb250ZW50c291cmNlNjc1ZDE5MjkyNGNjNGI1YTk1MTM5Mzg5ZTQwNjNkNDc" tvid="source" name="tabview_tabsource675d192924cc4b5a95139389e4063d47" class="tv_tab tv_selected tv_tab_alt tv_selected_alt" style="undefined" vis="true"><div id="div_Njc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3X3NvdXJjZV9o">Source Code<div id="div_dGFiX3NvdXJjZV9oZWFkX3RleHRzb3VyY2U2NzVkMTkyOTI0Y2M0YjVhOTUxMzkzODllNDA2M2Q0Nw"></div></div></div></div></div></div></td></tr><tr id="tr_Y29udGVudGRpdl9ZbTkwZEc5dFh3c291cmNlNjc1ZDE5MjkyNGNjNGI1YTk1MTM5Mzg5ZTQwNjNkNDdfdW5kZWZpbmVk" class="tr_content tr_content_alt"><td id="td_Y29udGVudHNvdXJjZTY3NWQxOTI5MjRjYzRiNWE5NTEzOTM4OWU0MDYzZDQ3X3VuZGVmaW5lZA" class="td_content td_content_alt"><div id="div_dHZfY29udGVudHNvdXJjZTY3NWQxOTI5MjRjYzRiNWE5NTEzOTM4OWU0MDYzZDQ3X3VuZGVmaW5lZA" class="tv_contents tv_contents_alt"><div id="div_Njc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3X3NvdXJjZWNvbnRhaW5lcl9v" class="tv_content tv_content_alt" name="tabview_contentsource675d192924cc4b5a95139389e4063d47" style="undefined" vis="true"><table id="table_Njc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3X3NvdXJjZWNvbnRhaW5lcl9v" class="editor_container_o editor_400p_container_o p100100 noborder"><tr id="tr_Njc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3X3NvdXJjZWNvbnRhaW5lcg" class="editor_container p100100"><td id="td_Njc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3X3NvdXJjZWVkaXQ" class="editor_outer editor_400p_outer"><div id="div_Njc1ZDE5MjktMjRjYy00YjVhLTk1MTMtOTM4OWU0MDYzZDQ3X3NvdXJjZWVkaXQ" class="editor_100 editor_border"><div class="CodeMirror-editor" style="font-size:1.00em;"><div class="CodeMirror cm-s-monokai CodeMirror-focused"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 72.9375px; left: 149.828px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" readonly="" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-vscrollbar" tabindex="-1" cm-not-content="true"><div style="min-width: 1px; height: 0px;"></div></div><div class="CodeMirror-hscrollbar" tabindex="-1" cm-not-content="true"><div style="height: 100%; min-height: 1px; width: 0px;"></div></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; min-width: 867.375px; margin-bottom: -10px; border-right-width: 40px; min-height: 387px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre class="CodeMirror-line-like"><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-cursors" style=""><div class="CodeMirror-cursor" style="left: 149.828px; top: 68.9375px; height: 17.2344px;"> </div></div><div class="CodeMirror-code" role="presentation" style=""><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// ==UserScript==</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// @name Quizlet Editor</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// @match http*://www.quizlet.com/explanations/textbook-solutions/*</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// @match http*://quizlet.com/explanations/textbook-solutions/*</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// @version 0.</span><span class="cm-comment cm-overlay cm-matchhighlight">2</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// @description Remove paywall for Quizlet answers</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// @author troop129 + josephyooo</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// @grant none</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// @run-at document-end</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// @namespace Quizlet Explanations Unlocker</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// ==/UserScript==</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">window</span>.<span class="cm-property">addEventListener</span>(<span class="cm-string">'load'</span>, <span class="cm-keyword">function</span>() {</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-string">'use strict'</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-keyword">var</span> <span class="cm-def">paywall</span> <span class="cm-operator">=</span> <span class="cm-variable">document</span>.<span class="cm-property">getElementsByClassName</span>(<span class="cm-string">'wugyavo'</span>);</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-keyword">if</span>(<span class="cm-variable-2">paywall</span>.<span class="cm-property">length</span> <span class="cm-operator">!=</span> <span class="cm-number">0</span>){</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-variable-2">paywall</span>[<span class="cm-number">0</span>].<span class="cm-property">remove</span>();</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-variable">document</span>.<span class="cm-property">getElementsByClassName</span>(<span class="cm-string">'ExplanationSolutionsContainer hnqbbas s1oluvjw'</span>)[<span class="cm-number">0</span>].<span class="cm-property">style</span>.<span class="cm-property">overflow</span><span class="cm-operator">=</span><span class="cm-string">"visible"</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-keyword">let</span> <span class="cm-def">newHeight</span> <span class="cm-operator">=</span> <span class="cm-variable">document</span>.<span class="cm-property">getElementsByClassName</span>(<span class="cm-string">'ExplanationsSolutionCard c5ngj6s'</span>)[<span class="cm-number">0</span>].<span class="cm-property">offsetHeight</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-variable">document</span>.<span class="cm-property">getElementsByClassName</span>(<span class="cm-string">'mv7e89c'</span>)[<span class="cm-number">0</span>].<span class="cm-property">style</span>.<span class="cm-property">minHeight</span><span class="cm-operator">=</span><span class="cm-variable-2">newHeight</span><span class="cm-operator">+</span><span class="cm-string">"px"</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> }</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}, <span class="cm-atom">false</span>);</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text=""></span></span></pre></div></div></div></div></div><div style="position: absolute; height: 40px; width: 1px; border-bottom: 0px solid transparent; top: 387px;"></div><div class="CodeMirror-gutters" style="display: none; height: 427px;"></div></div><div style="position: absolute; right: 0px; top: 0px; z-index: 7; pointer-events: none;"></div></div></div></div></td></tr></table></div></div></td></tr><tfoot id="tfoot_dHZfZm9vdGVyX3Rzb3VyY2U2NzVkMTkyOTI0Y2M0YjVhOTUxMzkzODllNDA2M2Q0N191bmRlZmluZWQ"><tr id="tr_dHZfZm9vdGVyX3Ryc291cmNlNjc1ZDE5MjkyNGNjNGI1YTk1MTM5Mzg5ZTQwNjNkNDdfdW5kZWZpbmVk"><td id="td_dHZfZm9vdGVyX3Rkc291cmNlNjc1ZDE5MjkyNGNjNGI1YTk1MTM5Mzg5ZTQwNjNkNDdfdW5kZWZpbmVk"></td></tr></tfoot></table></div></div></div></div></div></td></tr><tfoot id="tfoot_dHZfZm9vdGVyX3RtYWluX3VuZGVmaW5lZA"><tr id="tr_dHZfZm9vdGVyX3RybWFpbl91bmRlZmluZWQ"><td id="td_dHZfZm9vdGVyX3RkbWFpbl91bmRlZmluZWQ"></td></tr></tfoot></table></div></div></div><div id="div_YXNrX3N0YXR1cw" class="ask status"></div></body></html>
|
__pycache__/function.cpython-311.pyc
ADDED
Binary file (22.7 kB). View file
|
|
app.bat
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
@echo off
|
2 |
+
cd /d D:\Analyze-and-predict-student-performance
|
3 |
+
start /B cmd /C "python -m streamlit run main.py & timeout /T 1 > nul"
|
app.bat - Shortcut.lnk
ADDED
Binary file (1.24 kB). View file
|
|
database.db
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:0114a7fefb66a7de43db5fa10c330fe7883c4592a23968d4f8fe97d0de6fc9de
|
3 |
+
size 11698176
|
function.py
CHANGED
@@ -4,230 +4,317 @@ import plotly.express as px
|
|
4 |
import plotly.graph_objs as go
|
5 |
import streamlit as st
|
6 |
import joblib
|
|
|
7 |
|
8 |
|
9 |
def get_year(student_id):
|
10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
|
|
|
|
12 |
def process_data(raw_data):
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
pivot_df = pivot_df.reset_index().rename_axis(None, axis=1)
|
16 |
pivot_df.columns.name = None
|
17 |
pivot_df = pivot_df.dropna(thresh=50, axis=1)
|
18 |
pivot_df = pivot_df.rename(columns=lambda x: x.strip())
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
if existing_cols:
|
26 |
-
pivot_df.drop(existing_cols, axis=1, inplace=True)
|
27 |
-
|
28 |
-
# Merge with the XepLoaiNH column
|
29 |
-
df = pd.merge(pivot_df, raw_data[['MaSV', 'XepLoaiNH']], on='MaSV')
|
30 |
-
df.drop_duplicates(subset='MaSV', keep='last', inplace=True)
|
31 |
-
dfid=df['MaSV']
|
32 |
-
df.drop(['MaSV', 'XepLoaiNH'], axis=1, inplace=True)
|
33 |
-
df.replace(['WH', 'VT',"I"], np.nan, inplace=True)
|
34 |
df.iloc[:, :-1] = df.iloc[:, :-1].apply(pd.to_numeric)
|
35 |
-
df = pd.merge(dfid,df,left_index=True, right_index=True)
|
36 |
-
df[
|
37 |
-
df[
|
38 |
df["Year"] = 2000 + df["MaSV"].apply(get_year)
|
39 |
-
df["Year"]=df["Year"].astype(str)
|
40 |
-
df=df.
|
41 |
-
|
|
|
42 |
return df
|
43 |
-
|
|
|
44 |
def process_data_per(raw_data):
|
45 |
-
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
47 |
pivot_df = pivot_df.reset_index().rename_axis(None, axis=1)
|
48 |
pivot_df.columns.name = None
|
49 |
pivot_df = pivot_df.dropna(thresh=50, axis=1)
|
50 |
pivot_df = pivot_df.rename(columns=lambda x: x.strip())
|
51 |
|
52 |
-
|
53 |
-
cols_to_drop = []
|
54 |
-
with open('cols_to_drop.txt', 'r') as f:
|
55 |
-
for line in f:
|
56 |
-
cols_to_drop.append(str(line.strip()))
|
57 |
-
existing_cols = [col for col in cols_to_drop if col in pivot_df.columns]
|
58 |
-
if existing_cols:
|
59 |
-
pivot_df.drop(existing_cols, axis=1, inplace=True)
|
60 |
-
pivot_df.replace('WH', np.nan, inplace=True)
|
61 |
pivot_df.iloc[:, 1:] = pivot_df.iloc[:, 1:].apply(pd.to_numeric)
|
62 |
-
|
63 |
-
|
64 |
-
df.drop_duplicates(subset='MaSV', keep='last', inplace=True)
|
65 |
-
df.drop(['XepLoaiNH'], axis=1, inplace=True)
|
66 |
-
|
67 |
-
return df
|
68 |
|
69 |
|
70 |
def process_predict_data(raw_data):
|
71 |
dtk = raw_data[["MaSV", "DTBTKH4"]].copy()
|
72 |
dtk.drop_duplicates(subset="MaSV", keep="last", inplace=True)
|
73 |
|
74 |
-
count_duplicates =
|
75 |
-
|
76 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
|
78 |
-
# Create two new columns for counting courses that are in the courses_list or not
|
79 |
count_duplicates["fail_courses_list"] = (
|
80 |
(count_duplicates["MaMH"].isin(courses_list)) & (count_duplicates["Times"] >= 2)
|
81 |
).astype(int)
|
82 |
|
83 |
count_duplicates["fail_not_courses_list"] = (
|
84 |
-
(~count_duplicates["MaMH"].isin(courses_list))
|
|
|
85 |
).astype(int)
|
86 |
|
87 |
count_duplicates["pass_courses"] = (
|
88 |
-
(~count_duplicates["MaMH"].isin(courses_list))
|
|
|
89 |
).astype(int)
|
90 |
|
91 |
-
# Group the data by "MaSV" and sum the counts for the two new columns
|
92 |
fail = (
|
93 |
count_duplicates.groupby("MaSV")[["fail_courses_list", "fail_not_courses_list"]]
|
94 |
.sum()
|
95 |
.reset_index()
|
96 |
)
|
97 |
|
98 |
-
# Rename the columns to reflect the split of courses_list and not courses_list
|
99 |
fail.columns = ["MaSV", "fail_courses_list_count", "fail_not_courses_list_count"]
|
100 |
|
101 |
df = pd.merge(dtk, fail, on="MaSV")
|
102 |
df = df.rename(columns={"DTBTKH4": "GPA"})
|
103 |
|
104 |
-
data = raw_data[[
|
105 |
-
data =
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
return df
|
116 |
|
|
|
117 |
def predict_late_student(test_df):
|
118 |
-
|
119 |
-
model=joblib.load("model/
|
120 |
-
model1=joblib.load("model/
|
121 |
-
|
122 |
test_dfed = process_predict_data(test_df)
|
123 |
|
124 |
-
# Save the student ID column
|
125 |
std_id = test_dfed.iloc[:, 0]
|
126 |
|
127 |
-
# Drop the student ID column
|
128 |
test_dfed = test_dfed.drop(test_dfed.columns[0], axis=1)
|
129 |
|
130 |
-
# Make predictions using the pre-trained model
|
131 |
prediction = model.predict(test_dfed)
|
132 |
|
133 |
-
# Add a new column to the student data indicating if the student is late
|
134 |
-
|
135 |
-
|
136 |
prediction1 = model1.predict(test_dfed)
|
137 |
|
138 |
-
|
139 |
-
test_dfed[
|
140 |
-
|
|
|
141 |
|
142 |
-
# Add the student ID column back to the beginning of the DataFrame
|
143 |
-
test_dfed.insert(0, 'MaSV', std_id)
|
144 |
-
|
145 |
for index, row in test_dfed.iterrows():
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
|
152 |
return test_dfed
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
pivot_df = pd.pivot_table(
|
158 |
-
raw_data, values="DiemHP", index="MaSV", columns="
|
159 |
)
|
160 |
pivot_df = pivot_df.reset_index().rename_axis(None, axis=1)
|
161 |
pivot_df.columns.name = None
|
162 |
-
|
163 |
-
pivot_df = pivot_df.rename(columns=lambda x: x.strip())
|
164 |
|
165 |
-
|
|
|
|
|
|
|
166 |
pivot_df.iloc[:, 1:] = pivot_df.iloc[:, 1:].apply(pd.to_numeric)
|
|
|
167 |
|
168 |
-
|
|
|
169 |
df = pd.merge(pivot_df, raw_data[["MaSV", "DTBTK"]], on="MaSV")
|
170 |
df.drop_duplicates(subset="MaSV", keep="last", inplace=True)
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
r=df.drop(columns=['MaSV','DTBTK'])
|
180 |
-
merge=r.columns.tolist()
|
181 |
-
dup=pd.DataFrame(columns=columns_data)
|
182 |
-
df= pd.merge(dup, df, on=merge, how='outer')
|
183 |
for col in df.columns:
|
184 |
-
|
185 |
df[col].fillna(value=df["DTBTK"], inplace=True)
|
186 |
-
|
187 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
df.sort_index(axis=1, inplace=True)
|
189 |
-
model=joblib.load("model/R_rank.joblib")
|
190 |
-
prediction = model.predict(df)
|
191 |
-
df['Pred Rank'] = prediction
|
192 |
-
df.insert(0, 'MaSV', std_id)
|
193 |
-
df=df[['MaSV','Pred Rank']]
|
194 |
return df
|
195 |
|
196 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
def predict_one_student(raw_data, student_id):
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
selected_row = filtered_df.iloc[0, 1:].dropna()
|
203 |
-
colname = filtered_df.dropna().columns.tolist()
|
204 |
values = selected_row.values.tolist()
|
|
|
|
|
|
|
|
|
|
|
205 |
|
206 |
-
# create a line chart using plotly
|
207 |
fig1 = go.Figure()
|
208 |
-
fig1.add_trace(go.Histogram(x=values, nbinsx=40, name=student_id,marker=dict(color='rgba(50, 100, 200, 0.7)')))
|
209 |
|
210 |
-
|
|
|
|
|
|
|
|
|
|
|
211 |
fig1.update_layout(
|
212 |
-
title="
|
213 |
-
xaxis_title="
|
214 |
-
yaxis_title="
|
215 |
-
|
|
|
216 |
)
|
217 |
|
218 |
-
|
219 |
-
data =
|
220 |
-
data[
|
221 |
-
data['NHHK'] = data['NHHK'].apply(lambda x: str(x)[:4] + ' S ' + str(x)[4:])
|
222 |
rows_to_drop = []
|
223 |
-
with open(
|
224 |
for line in f:
|
225 |
rows_to_drop.append(str(line.strip()))
|
226 |
-
data = data[~data[
|
227 |
-
student_data = data[data[
|
228 |
-
student_data[
|
229 |
-
|
230 |
-
fig2 = px.bar(
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
fig2.update_layout(
|
232 |
title="Student Score vs. Course",
|
233 |
xaxis_title=None,
|
@@ -237,17 +324,78 @@ def predict_one_student(raw_data, student_id):
|
|
237 |
type="line",
|
238 |
x0=0,
|
239 |
y0=50,
|
240 |
-
x1=len(student_data[
|
241 |
y1=50,
|
242 |
-
line=dict(color=
|
243 |
)
|
244 |
|
245 |
-
# display the charts using st.column
|
246 |
col1, col2 = st.columns(2)
|
247 |
with col1:
|
248 |
-
st.plotly_chart(fig1)
|
249 |
|
250 |
with col2:
|
251 |
-
st.plotly_chart(fig2)
|
252 |
-
|
253 |
-
st.write("No data found for student {}".format(student_id))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
import plotly.graph_objs as go
|
5 |
import streamlit as st
|
6 |
import joblib
|
7 |
+
import re
|
8 |
|
9 |
|
10 |
def get_year(student_id):
|
11 |
+
year_str = ""
|
12 |
+
for char in student_id:
|
13 |
+
if char.isdigit():
|
14 |
+
year_str += char
|
15 |
+
if len(year_str) == 2:
|
16 |
+
break
|
17 |
+
return int(year_str)
|
18 |
|
19 |
+
|
20 |
+
@st.cache_data()
|
21 |
def process_data(raw_data):
|
22 |
+
|
23 |
+
raw_data = raw_data[
|
24 |
+
~raw_data["TenMH"].str.contains("IE|Intensive English|IE2|IE1|IE3|IE0")
|
25 |
+
]
|
26 |
+
|
27 |
+
pivot_df = pd.pivot_table(
|
28 |
+
raw_data, values="DiemHP", index="MaSV", columns="TenMH", aggfunc="first"
|
29 |
+
)
|
30 |
pivot_df = pivot_df.reset_index().rename_axis(None, axis=1)
|
31 |
pivot_df.columns.name = None
|
32 |
pivot_df = pivot_df.dropna(thresh=50, axis=1)
|
33 |
pivot_df = pivot_df.rename(columns=lambda x: x.strip())
|
34 |
+
|
35 |
+
df = pd.merge(pivot_df, raw_data[["MaSV"]], on="MaSV")
|
36 |
+
df.drop_duplicates(subset="MaSV", keep="last", inplace=True)
|
37 |
+
dfid = df["MaSV"]
|
38 |
+
df.drop(["MaSV"], axis=1, inplace=True)
|
39 |
+
df.replace(["WH", "VT", "I"], np.nan, inplace=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
df.iloc[:, :-1] = df.iloc[:, :-1].apply(pd.to_numeric)
|
41 |
+
df = pd.merge(dfid, df, left_index=True, right_index=True)
|
42 |
+
df["MaSV_school"] = df["MaSV"].str.slice(2, 4)
|
43 |
+
df["Major"] = df["MaSV"].str.slice(0, 2)
|
44 |
df["Year"] = 2000 + df["MaSV"].apply(get_year)
|
45 |
+
df["Year"] = df["Year"].astype(str)
|
46 |
+
df = pd.merge(df, raw_data[["MaSV", "DTBTK"]].drop_duplicates(), on="MaSV")
|
47 |
+
df = df.drop(columns="MaSV")
|
48 |
+
|
49 |
return df
|
50 |
+
|
51 |
+
|
52 |
def process_data_per(raw_data):
|
53 |
+
|
54 |
+
raw_data = raw_data[
|
55 |
+
~raw_data["TenMH"].str.contains("IE|Intensive English|IE2|IE1|IE3|IE0")
|
56 |
+
]
|
57 |
+
pivot_df = pd.pivot_table(
|
58 |
+
raw_data, values="DiemHP", index="MaSV", columns="TenMH", aggfunc="first"
|
59 |
+
)
|
60 |
pivot_df = pivot_df.reset_index().rename_axis(None, axis=1)
|
61 |
pivot_df.columns.name = None
|
62 |
pivot_df = pivot_df.dropna(thresh=50, axis=1)
|
63 |
pivot_df = pivot_df.rename(columns=lambda x: x.strip())
|
64 |
|
65 |
+
pivot_df.replace(["WH", "VT", "I"], np.nan, inplace=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
pivot_df.iloc[:, 1:] = pivot_df.iloc[:, 1:].apply(pd.to_numeric)
|
67 |
+
|
68 |
+
return pivot_df
|
|
|
|
|
|
|
|
|
69 |
|
70 |
|
71 |
def process_predict_data(raw_data):
|
72 |
dtk = raw_data[["MaSV", "DTBTKH4"]].copy()
|
73 |
dtk.drop_duplicates(subset="MaSV", keep="last", inplace=True)
|
74 |
|
75 |
+
count_duplicates = (
|
76 |
+
raw_data.groupby(["MaSV", "MaMH"]).size().reset_index(name="Times")
|
77 |
+
)
|
78 |
+
courses = raw_data[
|
79 |
+
raw_data["MaMH"].str.startswith(
|
80 |
+
("IT", "BA", "BM", "BT", "MA", "CE", "EE", "EL", "ENEE", "IS", "MAFE", "PH")
|
81 |
+
)
|
82 |
+
]
|
83 |
+
|
84 |
+
courses_list = courses["MaMH"].unique().tolist()
|
85 |
|
|
|
86 |
count_duplicates["fail_courses_list"] = (
|
87 |
(count_duplicates["MaMH"].isin(courses_list)) & (count_duplicates["Times"] >= 2)
|
88 |
).astype(int)
|
89 |
|
90 |
count_duplicates["fail_not_courses_list"] = (
|
91 |
+
(~count_duplicates["MaMH"].isin(courses_list))
|
92 |
+
& (count_duplicates["Times"] >= 2)
|
93 |
).astype(int)
|
94 |
|
95 |
count_duplicates["pass_courses"] = (
|
96 |
+
(~count_duplicates["MaMH"].isin(courses_list))
|
97 |
+
& (count_duplicates["Times"] == 1)
|
98 |
).astype(int)
|
99 |
|
|
|
100 |
fail = (
|
101 |
count_duplicates.groupby("MaSV")[["fail_courses_list", "fail_not_courses_list"]]
|
102 |
.sum()
|
103 |
.reset_index()
|
104 |
)
|
105 |
|
|
|
106 |
fail.columns = ["MaSV", "fail_courses_list_count", "fail_not_courses_list_count"]
|
107 |
|
108 |
df = pd.merge(dtk, fail, on="MaSV")
|
109 |
df = df.rename(columns={"DTBTKH4": "GPA"})
|
110 |
|
111 |
+
data = raw_data[["MaSV", "NHHK", "SoTCDat"]]
|
112 |
+
data = (
|
113 |
+
data.groupby(["MaSV"])["SoTCDat"].mean().reset_index(name="Mean_Cre").round(2)
|
114 |
+
)
|
115 |
+
|
116 |
+
df = pd.merge(df, data, on="MaSV")
|
117 |
+
df1 = raw_data[["MaSV", "MaMH", "NHHK"]]
|
118 |
+
courses_list = raw_data[
|
119 |
+
(raw_data["MaMH"].str.startswith("EN"))
|
120 |
+
& ~(raw_data["MaMH"].str.contains("EN007|EN008|EN011|EN012"))
|
121 |
+
].MaMH.tolist()
|
122 |
+
filtered_df = df1[df1["MaMH"].isin(courses_list)]
|
123 |
+
nhhk_counts = (
|
124 |
+
filtered_df.groupby("MaSV")["NHHK"].nunique().reset_index(name="EPeriod")
|
125 |
+
)
|
126 |
+
df = pd.merge(df, nhhk_counts, on="MaSV", how="left").fillna(0)
|
127 |
+
df = df[
|
128 |
+
[
|
129 |
+
"MaSV",
|
130 |
+
"GPA",
|
131 |
+
"Mean_Cre",
|
132 |
+
"fail_courses_list_count",
|
133 |
+
"fail_not_courses_list_count",
|
134 |
+
"EPeriod",
|
135 |
+
]
|
136 |
+
]
|
137 |
return df
|
138 |
|
139 |
+
|
140 |
def predict_late_student(test_df):
|
141 |
+
|
142 |
+
model = joblib.load("model/Time/Late.joblib")
|
143 |
+
model1 = joblib.load("model/Time/Sem.joblib")
|
144 |
+
|
145 |
test_dfed = process_predict_data(test_df)
|
146 |
|
|
|
147 |
std_id = test_dfed.iloc[:, 0]
|
148 |
|
|
|
149 |
test_dfed = test_dfed.drop(test_dfed.columns[0], axis=1)
|
150 |
|
|
|
151 |
prediction = model.predict(test_dfed)
|
152 |
|
|
|
|
|
|
|
153 |
prediction1 = model1.predict(test_dfed)
|
154 |
|
155 |
+
test_dfed["Semeters"] = prediction1
|
156 |
+
test_dfed["Progress"] = ["late" if p == 1 else "not late" for p in prediction]
|
157 |
+
|
158 |
+
test_dfed.insert(0, "MaSV", std_id)
|
159 |
|
|
|
|
|
|
|
160 |
for index, row in test_dfed.iterrows():
|
161 |
+
if row["Semeters"] <= 9 and row["Progress"] == "late":
|
162 |
+
test_dfed.loc[index, "Semeters"] = row["Semeters"] / 2
|
163 |
+
test_dfed.loc[index, "Progress"] = "may late"
|
164 |
+
else:
|
165 |
+
test_dfed.loc[index, "Semeters"] = row["Semeters"] / 2
|
166 |
|
167 |
return test_dfed
|
168 |
+
|
169 |
+
|
170 |
+
def get_major(raw_data):
|
171 |
+
major_mapping = {
|
172 |
+
"BA": "BA",
|
173 |
+
"BE": "BM",
|
174 |
+
"BT": "BT",
|
175 |
+
"CE": "CE",
|
176 |
+
"EE": "EE",
|
177 |
+
"EN": "EL",
|
178 |
+
"EV": "ENEE",
|
179 |
+
"IE": "IS",
|
180 |
+
"IT": "IT",
|
181 |
+
"MA": "MAFE",
|
182 |
+
"SE": "PH",
|
183 |
+
}
|
184 |
+
for major, ma_mh in major_mapping.items():
|
185 |
+
if raw_data["MaSV"].str[:2].str.contains(major).any():
|
186 |
+
return major, ma_mh
|
187 |
+
return None, None
|
188 |
+
|
189 |
+
|
190 |
+
def create_pivot_table(raw_data):
|
191 |
pivot_df = pd.pivot_table(
|
192 |
+
raw_data, values="DiemHP", index="MaSV", columns="MaMH", aggfunc="first"
|
193 |
)
|
194 |
pivot_df = pivot_df.reset_index().rename_axis(None, axis=1)
|
195 |
pivot_df.columns.name = None
|
196 |
+
return pivot_df
|
|
|
197 |
|
198 |
+
|
199 |
+
def drop_nan_columns(pivot_df):
|
200 |
+
pivot_df = pivot_df.rename(columns=lambda x: x.strip())
|
201 |
+
pivot_df.replace(["WH", "VT", "I", "P", "F"], np.nan, inplace=True)
|
202 |
pivot_df.iloc[:, 1:] = pivot_df.iloc[:, 1:].apply(pd.to_numeric)
|
203 |
+
return pivot_df
|
204 |
|
205 |
+
|
206 |
+
def merge_with_xeploainh(pivot_df, raw_data):
|
207 |
df = pd.merge(pivot_df, raw_data[["MaSV", "DTBTK"]], on="MaSV")
|
208 |
df.drop_duplicates(subset="MaSV", keep="last", inplace=True)
|
209 |
+
return df
|
210 |
+
|
211 |
+
|
212 |
+
def fill_missing_values(df):
|
213 |
+
col = df.drop(["MaSV", "DTBTK"], axis=1)
|
214 |
+
columns_data = get_column_data(df)
|
215 |
+
dup = pd.DataFrame(columns=columns_data)
|
216 |
+
df = pd.merge(dup, df, on=col.columns.tolist(), how="outer")
|
|
|
|
|
|
|
|
|
217 |
for col in df.columns:
|
218 |
+
if df[col].isnull().values.any():
|
219 |
df[col].fillna(value=df["DTBTK"], inplace=True)
|
220 |
+
return df
|
221 |
+
|
222 |
+
|
223 |
+
def get_column_data(df):
|
224 |
+
major = df["MaSV"].str[:2].unique()[0]
|
225 |
+
column_file = f"Columns/column_{major}.txt"
|
226 |
+
columns_data = []
|
227 |
+
with open(column_file, "r") as f:
|
228 |
+
for line in f:
|
229 |
+
columns_data.append(str(line.strip()))
|
230 |
+
return columns_data
|
231 |
+
|
232 |
+
|
233 |
+
def prepare_data(df):
|
234 |
+
std_id = df["MaSV"].copy()
|
235 |
+
df = df.drop(["MaSV", "DTBTK"], axis=1)
|
236 |
df.sort_index(axis=1, inplace=True)
|
|
|
|
|
|
|
|
|
|
|
237 |
return df
|
238 |
|
239 |
|
240 |
+
def predict_rank(raw_data):
|
241 |
+
major, ma_mh = get_major(raw_data)
|
242 |
+
if major:
|
243 |
+
raw_data["MaMH"] = raw_data["MaMH"].str[:-2]
|
244 |
+
raw_data = raw_data[raw_data["MaMH"].str.startswith(ma_mh)]
|
245 |
+
|
246 |
+
pivot_df = create_pivot_table(raw_data)
|
247 |
+
pivot_df = drop_nan_columns(pivot_df)
|
248 |
+
|
249 |
+
df = merge_with_xeploainh(pivot_df, raw_data)
|
250 |
+
df = fill_missing_values(df)
|
251 |
+
|
252 |
+
std_id = df["MaSV"].copy()
|
253 |
+
df = prepare_data(df)
|
254 |
+
|
255 |
+
model = joblib.load(f"model/{major}_rank.joblib")
|
256 |
+
prediction = model.predict(df)
|
257 |
+
|
258 |
+
new_columns = pd.concat(
|
259 |
+
[pd.Series(std_id, name="MaSV"), pd.Series(prediction, name="Pred Rank")],
|
260 |
+
axis=1,
|
261 |
+
)
|
262 |
+
df = pd.concat([new_columns, df], axis=1)
|
263 |
+
newframe = df.copy()
|
264 |
+
|
265 |
+
df = newframe[["MaSV", "Pred Rank"]]
|
266 |
+
return df
|
267 |
+
else:
|
268 |
+
return None
|
269 |
+
|
270 |
+
|
271 |
def predict_one_student(raw_data, student_id):
|
272 |
+
|
273 |
+
student = process_data_per(raw_data)
|
274 |
+
filtered_df = student[student["MaSV"] == student_id]
|
275 |
+
if len(filtered_df) > 0:
|
276 |
selected_row = filtered_df.iloc[0, 1:].dropna()
|
|
|
277 |
values = selected_row.values.tolist()
|
278 |
+
course_data_filtered = [x for x in selected_row if not np.isnan(x)]
|
279 |
+
counts, bins = np.histogram(course_data_filtered, bins=np.arange(0, 110, 10))
|
280 |
+
grade_bins = [f"{bins[i]}-{bins[i+1]}" for i in range(len(bins) - 1)]
|
281 |
+
total_count = len(selected_row)
|
282 |
+
frequencies_percentage = (counts / total_count) * 100
|
283 |
|
|
|
284 |
fig1 = go.Figure()
|
|
|
285 |
|
286 |
+
fig1.add_trace(
|
287 |
+
go.Scatter(
|
288 |
+
x=bins[:-1], y=frequencies_percentage, mode="lines", name="Frequency"
|
289 |
+
)
|
290 |
+
)
|
291 |
+
|
292 |
fig1.update_layout(
|
293 |
+
title="Frequency Range for",
|
294 |
+
xaxis_title="Score",
|
295 |
+
yaxis_title="Percentage",
|
296 |
+
height=400,
|
297 |
+
width=400,
|
298 |
)
|
299 |
|
300 |
+
data = raw_data[["MaSV", "NHHK", "TenMH", "DiemHP"]]
|
301 |
+
data["TenMH"] = data["TenMH"].str.lstrip()
|
302 |
+
data["NHHK"] = data["NHHK"].apply(lambda x: str(x)[:4] + " S " + str(x)[4:])
|
|
|
303 |
rows_to_drop = []
|
304 |
+
with open("rows_to_drop.txt", "r") as f:
|
305 |
for line in f:
|
306 |
rows_to_drop.append(str(line.strip()))
|
307 |
+
data = data[~data["TenMH"].isin(rows_to_drop)]
|
308 |
+
student_data = data[data["MaSV"] == student_id][["NHHK", "TenMH", "DiemHP"]]
|
309 |
+
student_data["DiemHP"] = pd.to_numeric(student_data["DiemHP"], errors="coerce")
|
310 |
+
|
311 |
+
fig2 = px.bar(
|
312 |
+
student_data,
|
313 |
+
x="TenMH",
|
314 |
+
y="DiemHP",
|
315 |
+
color="NHHK",
|
316 |
+
title="Student Score vs. Course",
|
317 |
+
)
|
318 |
fig2.update_layout(
|
319 |
title="Student Score vs. Course",
|
320 |
xaxis_title=None,
|
|
|
324 |
type="line",
|
325 |
x0=0,
|
326 |
y0=50,
|
327 |
+
x1=len(student_data["TenMH"]) - 1,
|
328 |
y1=50,
|
329 |
+
line=dict(color="red", width=3),
|
330 |
)
|
331 |
|
|
|
332 |
col1, col2 = st.columns(2)
|
333 |
with col1:
|
334 |
+
st.plotly_chart(fig1, use_container_width=True)
|
335 |
|
336 |
with col2:
|
337 |
+
st.plotly_chart(fig2, use_container_width=True)
|
338 |
+
else:
|
339 |
+
st.write("No data found for student {}".format(student_id))
|
340 |
+
|
341 |
+
|
342 |
+
def show_boxplot1(
|
343 |
+
new1_df, new1_dfa, major, school, year, additional_selection="", year_a=""
|
344 |
+
):
|
345 |
+
if additional_selection != " ":
|
346 |
+
show_boxplot = st.checkbox(
|
347 |
+
"Show Boxplot for student's performance", key="checkbox2"
|
348 |
+
)
|
349 |
+
|
350 |
+
if show_boxplot:
|
351 |
+
fig = px.box(new1_df)
|
352 |
+
fig1 = px.box(new1_dfa)
|
353 |
+
fig.update_layout(
|
354 |
+
title="Boxplot of " + major + school + " student in " + year
|
355 |
+
)
|
356 |
+
fig1.update_layout(
|
357 |
+
title="Boxplot of "
|
358 |
+
+ major
|
359 |
+
+ additional_selection
|
360 |
+
+ " student in "
|
361 |
+
+ year_a
|
362 |
+
)
|
363 |
+
col1, col2 = st.columns(2)
|
364 |
+
|
365 |
+
with col1:
|
366 |
+
st.plotly_chart(fig, use_container_width=True)
|
367 |
+
|
368 |
+
with col2:
|
369 |
+
st.plotly_chart(fig1, use_container_width=True)
|
370 |
+
|
371 |
+
elif additional_selection == " " and year_a != " ":
|
372 |
+
show_boxplot = st.checkbox(
|
373 |
+
"Show Boxplot for student's performance", key="checkbox2"
|
374 |
+
)
|
375 |
+
|
376 |
+
if show_boxplot:
|
377 |
+
fig = px.box(new1_df)
|
378 |
+
fig1 = px.box(new1_dfa)
|
379 |
+
fig.update_layout(
|
380 |
+
title="Boxplot of " + major + school + " student in " + year
|
381 |
+
)
|
382 |
+
fig1.update_layout(
|
383 |
+
title="Boxplot of " + major + school + " student in " + year_a
|
384 |
+
)
|
385 |
+
col1, col2 = st.columns(2)
|
386 |
+
|
387 |
+
with col1:
|
388 |
+
st.plotly_chart(fig, use_container_width=True)
|
389 |
+
|
390 |
+
with col2:
|
391 |
+
st.plotly_chart(fig1, use_container_width=True)
|
392 |
+
|
393 |
+
elif additional_selection == " ":
|
394 |
+
show_boxplot = st.checkbox(
|
395 |
+
"Show Boxplot for student's performance", key="checkbox2"
|
396 |
+
)
|
397 |
+
|
398 |
+
if show_boxplot:
|
399 |
+
fig = px.box(new1_df)
|
400 |
+
fig.update_layout(title="Boxplot of " + major + " student in " + year)
|
401 |
+
st.plotly_chart(fig, use_container_width=True)
|
main.py
ADDED
@@ -0,0 +1,888 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import streamlit as st
|
3 |
+
import plotly.express as px
|
4 |
+
import numpy as np
|
5 |
+
import plotly.graph_objs as go
|
6 |
+
from function import (
|
7 |
+
process_data,
|
8 |
+
predict_late_student,
|
9 |
+
predict_rank,
|
10 |
+
predict_one_student,
|
11 |
+
show_boxplot1,
|
12 |
+
)
|
13 |
+
from datetime import datetime
|
14 |
+
from PIL import Image
|
15 |
+
import base64
|
16 |
+
import re
|
17 |
+
import sqlite3
|
18 |
+
|
19 |
+
df = pd.DataFrame()
|
20 |
+
|
21 |
+
|
22 |
+
def color_cell(val):
|
23 |
+
if val == "not late":
|
24 |
+
color = "green"
|
25 |
+
elif val == "may late":
|
26 |
+
color = "yellow"
|
27 |
+
elif val == "late":
|
28 |
+
color = "red"
|
29 |
+
else:
|
30 |
+
color = "black"
|
31 |
+
|
32 |
+
return f"color: {color};"
|
33 |
+
|
34 |
+
|
35 |
+
def clear_resources():
|
36 |
+
"""Clears all resources from the st.session_state."""
|
37 |
+
for key in list(st.session_state.keys()):
|
38 |
+
if key.startswith("resource"):
|
39 |
+
del st.session_state[key]
|
40 |
+
|
41 |
+
|
42 |
+
def get_year(student_id):
|
43 |
+
year_str = ""
|
44 |
+
for char in student_id:
|
45 |
+
if char.isdigit():
|
46 |
+
year_str += char
|
47 |
+
if len(year_str) == 2:
|
48 |
+
break
|
49 |
+
return int(year_str)
|
50 |
+
|
51 |
+
|
52 |
+
def generate_comment(median):
|
53 |
+
if median < 30:
|
54 |
+
comment = f"The median score for {course} is quite low at {median}. Students may need to work harder to improve their performance."
|
55 |
+
elif median < 50:
|
56 |
+
comment = f"The median score for {course} is below average at {median}. Students should work on improving their understanding of the material."
|
57 |
+
elif median < 80:
|
58 |
+
comment = f"The median score for {course} is solid at {median}. Students are making good progress but could still work on improving their skills."
|
59 |
+
else:
|
60 |
+
comment = f"The median score for {course} is outstanding at {median}. Students are doing an excellent job in this course."
|
61 |
+
return comment
|
62 |
+
|
63 |
+
|
64 |
+
favicon = "R.png"
|
65 |
+
hcm = "HCM.png"
|
66 |
+
intera = "Logo-iuoss-trans.png"
|
67 |
+
st.set_page_config(
|
68 |
+
page_title="Student System",
|
69 |
+
page_icon=favicon,
|
70 |
+
layout="wide",
|
71 |
+
)
|
72 |
+
currentYear = datetime.now().year
|
73 |
+
im1 = Image.open("R.png")
|
74 |
+
im2 = Image.open("HCM.png")
|
75 |
+
im3 = Image.open("Logo-iuoss-trans.png")
|
76 |
+
|
77 |
+
|
78 |
+
col1, col2, col3 = st.columns([1, 3, 1])
|
79 |
+
|
80 |
+
|
81 |
+
with col1:
|
82 |
+
st.image(im1, width=150)
|
83 |
+
|
84 |
+
|
85 |
+
with col2:
|
86 |
+
st.markdown(
|
87 |
+
"<h1 style='text-align: center;'>TRUONG QUOC AN'S THESIS</h1>",
|
88 |
+
unsafe_allow_html=True,
|
89 |
+
)
|
90 |
+
|
91 |
+
|
92 |
+
with col3:
|
93 |
+
st.image(im2, width=250)
|
94 |
+
|
95 |
+
|
96 |
+
@st.cache_data()
|
97 |
+
def score_table():
|
98 |
+
# Establish a connection to the database
|
99 |
+
conn = sqlite3.connect("database.db")
|
100 |
+
cursor = conn.cursor()
|
101 |
+
|
102 |
+
# Fetch data from the tables
|
103 |
+
cursor.execute('''SELECT Students.MaSV, Enrollment.MaMH, Courses.TenMH, Enrollment.NHHK, Enrollment.DiemHP, Students.DTBTK
|
104 |
+
FROM Students
|
105 |
+
INNER JOIN Enrollment ON Students.MaSV = Enrollment.MaSV
|
106 |
+
INNER JOIN Courses ON Enrollment.MaMH = Courses.MaMH''')
|
107 |
+
data = cursor.fetchall()
|
108 |
+
|
109 |
+
# Create a DataFrame
|
110 |
+
df = pd.DataFrame(data, columns=['MaSV', 'MaMH', 'TenMH', 'NHHK', 'DiemHP', 'DTBTK'])
|
111 |
+
df = df.drop_duplicates()
|
112 |
+
|
113 |
+
# Close the database connection
|
114 |
+
conn.close()
|
115 |
+
|
116 |
+
return df
|
117 |
+
|
118 |
+
@st.cache_data()
|
119 |
+
def score_table_for_student():
|
120 |
+
with sqlite3.connect("database.db") as conn:
|
121 |
+
cursor = conn.cursor()
|
122 |
+
|
123 |
+
cursor.execute('''
|
124 |
+
SELECT DISTINCT Students.MaSV, Enrollment.MaMH, Courses.TenMH, Enrollment.NHHK, Enrollment.DiemHP, Students.DTBTK
|
125 |
+
FROM Students
|
126 |
+
INNER JOIN Enrollment ON Students.MaSV = Enrollment.MaSV
|
127 |
+
INNER JOIN Courses ON Enrollment.MaMH = Courses.MaMH
|
128 |
+
''')
|
129 |
+
results = cursor.fetchall()
|
130 |
+
df = pd.DataFrame(results, columns=['MaSV', 'MaMH', 'TenMH', 'NHHK', 'DiemHP', 'DTBTK'])
|
131 |
+
|
132 |
+
cursor.execute('''
|
133 |
+
SELECT MaSV, NHHK, SoTCDat
|
134 |
+
FROM Students
|
135 |
+
''')
|
136 |
+
results = cursor.fetchall()
|
137 |
+
df1 = pd.DataFrame(results, columns=['MaSV', 'NHHK', 'SoTCDat'])
|
138 |
+
merged_df = pd.merge(df, df1, on=['MaSV', 'NHHK'])
|
139 |
+
|
140 |
+
return merged_df
|
141 |
+
|
142 |
+
|
143 |
+
|
144 |
+
|
145 |
+
st.sidebar.image(im3)
|
146 |
+
st.sidebar.title("Student Performance Prediction System")
|
147 |
+
option = ["Dashboard","Prediction Performance", "Grade Distribution Tables"]
|
148 |
+
|
149 |
+
tabs = st.sidebar.selectbox("Select an option", option)
|
150 |
+
|
151 |
+
|
152 |
+
def filter_dataframe(df, column, value):
|
153 |
+
if value == "All":
|
154 |
+
return df
|
155 |
+
else:
|
156 |
+
return df[df[column] == value]
|
157 |
+
|
158 |
+
|
159 |
+
if tabs == "Dashboard":
|
160 |
+
clear_resources()
|
161 |
+
raw_data = score_table()
|
162 |
+
df = process_data(raw_data)
|
163 |
+
additional_selection = " "
|
164 |
+
unique_values_major = df["Major"].unique()
|
165 |
+
unique_values_major = [
|
166 |
+
"BA",
|
167 |
+
"BE",
|
168 |
+
"BT",
|
169 |
+
"CE",
|
170 |
+
"EE",
|
171 |
+
"EN",
|
172 |
+
"EV",
|
173 |
+
"IE",
|
174 |
+
"MA",
|
175 |
+
"SE",
|
176 |
+
"IT",
|
177 |
+
]
|
178 |
+
unique_values_major = sorted(unique_values_major, key=lambda s: s)
|
179 |
+
major = st.selectbox("Select a school:", unique_values_major)
|
180 |
+
df = filter_dataframe(df, "Major", major)
|
181 |
+
dfa = filter_dataframe(df, "Major", major)
|
182 |
+
|
183 |
+
unique_values_school = df["MaSV_school"].unique()
|
184 |
+
all_values_school = np.concatenate([["All"], unique_values_school])
|
185 |
+
no_numbers = [x for x in all_values_school if not re.search(r"\d", str(x))]
|
186 |
+
|
187 |
+
if len(no_numbers) == 2:
|
188 |
+
school = no_numbers[1]
|
189 |
+
else:
|
190 |
+
col1, col2 = st.columns(2)
|
191 |
+
|
192 |
+
with col1:
|
193 |
+
school = st.selectbox("Select a major:", no_numbers)
|
194 |
+
|
195 |
+
if school != "All":
|
196 |
+
values = [x for x in no_numbers if x != "All" and x != school]
|
197 |
+
values = np.concatenate([[" "], values])
|
198 |
+
|
199 |
+
with col2:
|
200 |
+
additional_selection = st.selectbox(
|
201 |
+
"Select another major for comparisons:", values
|
202 |
+
)
|
203 |
+
if additional_selection != " ":
|
204 |
+
dfa = filter_dataframe(dfa, "MaSV_school", additional_selection)
|
205 |
+
|
206 |
+
df = filter_dataframe(df, "MaSV_school", school)
|
207 |
+
|
208 |
+
unique_values_year = df["Year"].unique()
|
209 |
+
all_values_year = np.concatenate([["All"], unique_values_year])
|
210 |
+
|
211 |
+
col1, col2 = st.columns(2)
|
212 |
+
|
213 |
+
with col1:
|
214 |
+
year = st.selectbox("Select a year:", all_values_year)
|
215 |
+
|
216 |
+
with col2:
|
217 |
+
if year != "All" and additional_selection == " ":
|
218 |
+
year_list = [x for x in all_values_year if x != "All" and x != year]
|
219 |
+
year_list = np.concatenate([[" "], year_list])
|
220 |
+
year_a = st.selectbox("Select another year for comparisons:", year_list)
|
221 |
+
elif year == "All":
|
222 |
+
year_a = " "
|
223 |
+
elif year != "All" and additional_selection != " ":
|
224 |
+
year_a = year
|
225 |
+
if year_a != " ":
|
226 |
+
dfa = filter_dataframe(dfa, "Year", year_a)
|
227 |
+
dfa.dropna(axis=1, thresh=1, inplace=True)
|
228 |
+
else:
|
229 |
+
year_a = " "
|
230 |
+
|
231 |
+
df = filter_dataframe(df, "Year", year)
|
232 |
+
new1_df = df.DTBTK
|
233 |
+
new1_dfa = dfa.DTBTK
|
234 |
+
show_boxplot1(
|
235 |
+
new1_df, new1_dfa, major, school, year, additional_selection="", year_a=""
|
236 |
+
)
|
237 |
+
|
238 |
+
df.dropna(axis=1, thresh=1, inplace=True)
|
239 |
+
|
240 |
+
new_df = df.iloc[:, :-4].dropna(axis=1, thresh=10).apply(pd.to_numeric)
|
241 |
+
new_dfa = dfa.iloc[:, :-4].dropna(axis=1, thresh=10).apply(pd.to_numeric)
|
242 |
+
list1 = new_df.columns.tolist()
|
243 |
+
list2 = new_dfa.columns.tolist()
|
244 |
+
if (year != "All" and year_a != " ") or (
|
245 |
+
school != "All" and additional_selection != " "
|
246 |
+
):
|
247 |
+
dfac = new_dfa.columns[:-4].tolist()
|
248 |
+
common_elements = np.intersect1d(list1, list2)
|
249 |
+
|
250 |
+
merged_array = np.concatenate((list1, list2), axis=None)
|
251 |
+
|
252 |
+
list3 = np.intersect1d(merged_array, common_elements)
|
253 |
+
new_df = new_df[list3]
|
254 |
+
new_dfa = new_dfa[list3]
|
255 |
+
if additional_selection != " ":
|
256 |
+
show_boxplot = st.checkbox("Show Boxplot for All Course", key="checkbox1")
|
257 |
+
|
258 |
+
if show_boxplot:
|
259 |
+
fig = px.box(new_df)
|
260 |
+
fig1 = px.box(new_dfa)
|
261 |
+
fig.update_layout(
|
262 |
+
title="Boxplot of " + major + school + " student in " + year
|
263 |
+
)
|
264 |
+
fig1.update_layout(
|
265 |
+
title="Boxplot of "
|
266 |
+
+ major
|
267 |
+
+ additional_selection
|
268 |
+
+ " student in "
|
269 |
+
+ year
|
270 |
+
)
|
271 |
+
|
272 |
+
st.plotly_chart(fig, use_container_width=True)
|
273 |
+
st.plotly_chart(fig1, use_container_width=True)
|
274 |
+
|
275 |
+
elif additional_selection == " " and year_a != " ":
|
276 |
+
show_boxplot = st.checkbox("Show Boxplot for All Course", key="checkbox1")
|
277 |
+
|
278 |
+
if show_boxplot:
|
279 |
+
fig = px.box(new_df)
|
280 |
+
fig1 = px.box(new_dfa)
|
281 |
+
fig.update_layout(
|
282 |
+
title="Boxplot of " + major + school + " student in " + year
|
283 |
+
)
|
284 |
+
fig1.update_layout(
|
285 |
+
title="Boxplot of " + major + school + " student in " + year_a
|
286 |
+
)
|
287 |
+
|
288 |
+
st.plotly_chart(fig, use_container_width=True)
|
289 |
+
st.plotly_chart(fig1, use_container_width=True)
|
290 |
+
|
291 |
+
elif additional_selection == " ":
|
292 |
+
show_boxplot = st.checkbox("Show Boxplot for All Course", key="checkbox1")
|
293 |
+
|
294 |
+
if show_boxplot:
|
295 |
+
fig = px.box(new_df)
|
296 |
+
fig.update_layout(title="Boxplot of " + major + " student in " + year)
|
297 |
+
|
298 |
+
st.plotly_chart(fig, use_container_width=True)
|
299 |
+
|
300 |
+
options = df.columns[:-4]
|
301 |
+
|
302 |
+
course_data_dict = {course: df[course].dropna() for course in options}
|
303 |
+
valid_courses = [
|
304 |
+
course for course, data in course_data_dict.items() if len(data) > 1
|
305 |
+
]
|
306 |
+
|
307 |
+
if (year != "All" and year_a != " ") or (
|
308 |
+
school != "All" and additional_selection != " "
|
309 |
+
):
|
310 |
+
dfac = new_dfa.columns[:-4].tolist()
|
311 |
+
common_elements = np.intersect1d(valid_courses, dfac)
|
312 |
+
|
313 |
+
merged_array = np.concatenate((valid_courses, dfac), axis=None)
|
314 |
+
|
315 |
+
valid_courses = np.intersect1d(merged_array, common_elements)
|
316 |
+
|
317 |
+
if len(valid_courses) > 5:
|
318 |
+
course = st.selectbox("Select a course:", valid_courses)
|
319 |
+
elif len(valid_courses) == 1:
|
320 |
+
course = valid_courses[0]
|
321 |
+
else:
|
322 |
+
st.write("No valid course data found!")
|
323 |
+
st.stop()
|
324 |
+
|
325 |
+
course_data = course_data_dict[course]
|
326 |
+
|
327 |
+
if len(course_data) > 1:
|
328 |
+
if school == "All":
|
329 |
+
st.write("Course:", course, " of ", major, " student")
|
330 |
+
else:
|
331 |
+
st.write("Course:", course, " of ", major + school, " student")
|
332 |
+
st.write(generate_comment(course_data.median()))
|
333 |
+
else:
|
334 |
+
st.write("No data available for the selected course.")
|
335 |
+
|
336 |
+
col1, col2, col3, col4 = st.columns(4)
|
337 |
+
|
338 |
+
with col1:
|
339 |
+
counts, bins = np.histogram(course_data, bins=np.arange(0, 110, 10))
|
340 |
+
total_count = len(course_data)
|
341 |
+
frequencies_percentage = (counts / total_count) * 100
|
342 |
+
grade_bins = [f"{bins[i]}-{bins[i+1]}" for i in range(len(bins) - 1)]
|
343 |
+
|
344 |
+
df = pd.DataFrame(
|
345 |
+
{"Grade": grade_bins, "Grading percentage": frequencies_percentage}
|
346 |
+
)
|
347 |
+
df["Grading percentage"] = df["Grading percentage"].map(
|
348 |
+
lambda x: "{:.2f}".format(x)
|
349 |
+
)
|
350 |
+
|
351 |
+
st.table(df)
|
352 |
+
|
353 |
+
with col2:
|
354 |
+
|
355 |
+
fig = go.Figure()
|
356 |
+
fig.add_trace(
|
357 |
+
go.Scatter(
|
358 |
+
x=bins[:-1], y=frequencies_percentage, mode="lines", name="Frequency"
|
359 |
+
)
|
360 |
+
)
|
361 |
+
|
362 |
+
fig.update_layout(
|
363 |
+
title="Frequency Range for {}".format(course),
|
364 |
+
xaxis_title="Score",
|
365 |
+
yaxis_title="Percentage",
|
366 |
+
height=400,
|
367 |
+
width=400,
|
368 |
+
)
|
369 |
+
st.plotly_chart(fig, use_container_width=True)
|
370 |
+
|
371 |
+
with col3:
|
372 |
+
fig = go.Figure()
|
373 |
+
fig.add_trace(go.Box(y=course_data, name="Box plot"))
|
374 |
+
fig.update_layout(
|
375 |
+
title="Box plot of Scores for {}".format(course),
|
376 |
+
yaxis_title="Score",
|
377 |
+
height=400,
|
378 |
+
width=400,
|
379 |
+
)
|
380 |
+
st.plotly_chart(fig, use_container_width=True)
|
381 |
+
|
382 |
+
with col4:
|
383 |
+
raw_data1 = raw_data.copy()
|
384 |
+
raw_data1["major"] = raw_data1["MaSV"].str.slice(0, 2)
|
385 |
+
raw_data1.replace(["WH", "VT", "I"], np.nan, inplace=True)
|
386 |
+
raw_data1 = raw_data1[~raw_data1["DiemHP"].isin(["P", "F", "PC"])]
|
387 |
+
if major != "All":
|
388 |
+
raw_data1 = raw_data1[raw_data1["major"] == major]
|
389 |
+
|
390 |
+
raw_data1["MaSV_school"] = raw_data1["MaSV"].str.slice(2, 4)
|
391 |
+
if school != "All":
|
392 |
+
raw_data1 = raw_data1[raw_data1["MaSV_school"] == school]
|
393 |
+
|
394 |
+
df1 = raw_data1[["TenMH", "NHHK", "DiemHP"]].copy()
|
395 |
+
|
396 |
+
df1["DiemHP"] = df1["DiemHP"].replace('', pd.NA).dropna().astype(float)
|
397 |
+
df1["NHHK"] = df1["NHHK"].apply(lambda x: str(x)[:4] + " S " + str(x)[4:])
|
398 |
+
|
399 |
+
selected_TenMH = " " + course
|
400 |
+
filtered_df1 = df1[df1["TenMH"] == selected_TenMH]
|
401 |
+
|
402 |
+
mean_DiemHP = (
|
403 |
+
filtered_df1.groupby("NHHK")["DiemHP"]
|
404 |
+
.mean()
|
405 |
+
.round(1)
|
406 |
+
.reset_index(name="Mean")
|
407 |
+
)
|
408 |
+
|
409 |
+
if year != "All":
|
410 |
+
st.write("")
|
411 |
+
else:
|
412 |
+
fig = px.line(
|
413 |
+
mean_DiemHP,
|
414 |
+
x="NHHK",
|
415 |
+
y="Mean",
|
416 |
+
title=f"Mean Course Score for{selected_TenMH} through Semeters",
|
417 |
+
)
|
418 |
+
fig.update_layout(xaxis_title="Semeters",height=400, width=400)
|
419 |
+
st.plotly_chart(fig, use_container_width=True)
|
420 |
+
|
421 |
+
if (year != "All" and year_a != " ") or (
|
422 |
+
school != "All" and additional_selection != " "
|
423 |
+
):
|
424 |
+
course_data_dict = {course: new_dfa[course]}
|
425 |
+
course_data = course_data_dict[course]
|
426 |
+
|
427 |
+
st.write(
|
428 |
+
"Course:",
|
429 |
+
course,
|
430 |
+
" of ",
|
431 |
+
major + additional_selection,
|
432 |
+
" student in ",
|
433 |
+
year_a,
|
434 |
+
)
|
435 |
+
col1, col2, col3, col4 = st.columns(4)
|
436 |
+
|
437 |
+
with col1:
|
438 |
+
course_data_filtered = [x for x in course_data if not np.isnan(x)]
|
439 |
+
counts, bins = np.histogram(
|
440 |
+
course_data_filtered, bins=np.arange(0, 110, 10)
|
441 |
+
)
|
442 |
+
total_count = len(course_data_filtered)
|
443 |
+
frequencies_percentage = (counts / total_count) * 100
|
444 |
+
grade_bins = [f"{bins[i]}-{bins[i+1]}" for i in range(len(bins) - 1)]
|
445 |
+
|
446 |
+
df1 = pd.DataFrame(
|
447 |
+
{"Grade": grade_bins, "Grading percentage": frequencies_percentage}
|
448 |
+
)
|
449 |
+
df1["Grading percentage"] = df1["Grading percentage"].map(
|
450 |
+
lambda x: "{:.2f}".format(x)
|
451 |
+
)
|
452 |
+
|
453 |
+
st.table(df1)
|
454 |
+
|
455 |
+
with col2:
|
456 |
+
|
457 |
+
fig = go.Figure()
|
458 |
+
fig.add_trace(
|
459 |
+
go.Scatter(
|
460 |
+
x=bins[:-1],
|
461 |
+
y=frequencies_percentage,
|
462 |
+
mode="lines",
|
463 |
+
name="Frequency",
|
464 |
+
)
|
465 |
+
)
|
466 |
+
|
467 |
+
fig.update_layout(
|
468 |
+
title="Frequency Range for {}".format(course),
|
469 |
+
xaxis_title="Score",
|
470 |
+
yaxis_title="Percentage",
|
471 |
+
height=400,
|
472 |
+
width=400,
|
473 |
+
)
|
474 |
+
st.plotly_chart(fig, use_container_width=True)
|
475 |
+
|
476 |
+
with col3:
|
477 |
+
fig = go.Figure()
|
478 |
+
fig.add_trace(go.Box(y=course_data, name="Box plot"))
|
479 |
+
fig.update_layout(
|
480 |
+
title="Box plot of Scores for {}".format(course),
|
481 |
+
yaxis_title="Score",
|
482 |
+
height=400,
|
483 |
+
width=400,
|
484 |
+
)
|
485 |
+
st.plotly_chart(fig, use_container_width=True)
|
486 |
+
|
487 |
+
with col4:
|
488 |
+
raw_data["major"] = raw_data["MaSV"].str.slice(0, 2)
|
489 |
+
raw_data.replace(["WH", "VT", "I"], np.nan, inplace=True)
|
490 |
+
raw_data = raw_data[~raw_data["DiemHP"].isin(["P", "F", "PC"])]
|
491 |
+
if major != "All":
|
492 |
+
raw_data = raw_data[raw_data["major"] == major]
|
493 |
+
|
494 |
+
raw_data["MaSV_school"] = raw_data["MaSV"].str.slice(2, 4)
|
495 |
+
raw_data = raw_data[raw_data["MaSV_school"] == additional_selection]
|
496 |
+
|
497 |
+
df1 = raw_data[["TenMH", "NHHK", "DiemHP"]].copy()
|
498 |
+
df1["DiemHP"] = df1["DiemHP"].replace('', pd.NA).dropna().astype(float)
|
499 |
+
df1["NHHK"] = df1["NHHK"].apply(lambda x: str(x)[:4] + " S " + str(x)[4:])
|
500 |
+
|
501 |
+
selected_TenMH = " " + course
|
502 |
+
filtered_df1 = df1[df1["TenMH"] == selected_TenMH]
|
503 |
+
|
504 |
+
mean_DiemHP = (
|
505 |
+
filtered_df1.groupby("NHHK")["DiemHP"]
|
506 |
+
.mean()
|
507 |
+
.round(1)
|
508 |
+
.reset_index(name="Mean")
|
509 |
+
)
|
510 |
+
|
511 |
+
if year != "All":
|
512 |
+
st.write("")
|
513 |
+
else:
|
514 |
+
fig = px.line(
|
515 |
+
mean_DiemHP,
|
516 |
+
x="NHHK",
|
517 |
+
y="Mean",
|
518 |
+
title=f"Mean Course Score for{selected_TenMH} through Semeters",
|
519 |
+
)
|
520 |
+
fig.update_layout(xaxis_title="Semeters",height=400, width=400)
|
521 |
+
st.plotly_chart(fig, use_container_width=True)
|
522 |
+
variables_to_delete = [
|
523 |
+
'raw_data1', 'df1', 'filtered_df1', 'mean_DiemHP', 'counts', 'bins',
|
524 |
+
'total_count', 'frequencies_percentage', 'grade_bins', 'fig1',
|
525 |
+
'common_elements', 'merged_array', 'list3', 'dfac', 'fig', 'new_df',
|
526 |
+
'new_dfa', 'new1_df', 'new1_dfa', 'course_data',
|
527 |
+
'options', 'valid_courses', 'list2', 'list1'
|
528 |
+
]
|
529 |
+
|
530 |
+
for variable in variables_to_delete:
|
531 |
+
if variable in locals():
|
532 |
+
del locals()[variable]
|
533 |
+
|
534 |
+
|
535 |
+
|
536 |
+
elif tabs == "Prediction Performance":
|
537 |
+
|
538 |
+
clear_resources()
|
539 |
+
|
540 |
+
raw_data = score_table_for_student()
|
541 |
+
raw_data["DTBTKH4"] = raw_data["DTBTK"]/25
|
542 |
+
df=raw_data.copy()
|
543 |
+
df["MaSV_school"] = df["MaSV"].str.slice(2, 4)
|
544 |
+
df["Major"] = df["MaSV"].str.slice(0, 2)
|
545 |
+
unique_values_major = df["Major"].unique()
|
546 |
+
unique_values_major = [
|
547 |
+
"BA",
|
548 |
+
"BE",
|
549 |
+
"BT",
|
550 |
+
"CE",
|
551 |
+
"EE",
|
552 |
+
"EN",
|
553 |
+
"EV",
|
554 |
+
"IE",
|
555 |
+
"MA",
|
556 |
+
"SE",
|
557 |
+
"IT",
|
558 |
+
]
|
559 |
+
unique_values_major = sorted(unique_values_major, key=lambda s: s)
|
560 |
+
col1, col2 = st.columns(2)
|
561 |
+
with col1:
|
562 |
+
major = st.selectbox("Select a school:", unique_values_major)
|
563 |
+
df = filter_dataframe(df, "Major", major)
|
564 |
+
|
565 |
+
unique_values_school = df["MaSV_school"].unique()
|
566 |
+
all_values_school = np.concatenate([["All"], unique_values_school])
|
567 |
+
no_numbers = [x for x in all_values_school if not re.search(r"\d", str(x))]
|
568 |
+
|
569 |
+
if len(no_numbers) == 2:
|
570 |
+
school = no_numbers[1]
|
571 |
+
with col2:
|
572 |
+
school = st.selectbox("Select a major:", no_numbers)
|
573 |
+
|
574 |
+
df = filter_dataframe(df, "MaSV_school", school)
|
575 |
+
predict = predict_late_student(df)
|
576 |
+
rank = predict_rank(df)
|
577 |
+
predict = pd.merge(predict, rank, on="MaSV")
|
578 |
+
predict.rename(columns={"Mean_Cre": "Mean Credit"}, inplace=True)
|
579 |
+
|
580 |
+
rank_mapping = {
|
581 |
+
"Khá": "Good",
|
582 |
+
"Trung Bình Khá": "Average good",
|
583 |
+
"Giỏi": "Very good",
|
584 |
+
"Kém": "Very weak",
|
585 |
+
"Trung Bình": "Ordinary",
|
586 |
+
"Yếu": "Weak",
|
587 |
+
"Xuất Sắc": "Excellent",
|
588 |
+
}
|
589 |
+
predict["Pred Rank"].replace(rank_mapping, inplace=True)
|
590 |
+
|
591 |
+
df_late = predict
|
592 |
+
|
593 |
+
MaSV = st.text_input("Enter Student ID:", key="MaSV")
|
594 |
+
|
595 |
+
def clear_form():
|
596 |
+
st.session_state["MaSV"] = ""
|
597 |
+
|
598 |
+
if st.button("Clear", on_click=clear_form):
|
599 |
+
MaSV = ""
|
600 |
+
|
601 |
+
if MaSV:
|
602 |
+
df_filtered = predict[predict["MaSV"] == MaSV]
|
603 |
+
styled_table = (
|
604 |
+
df_filtered[
|
605 |
+
["MaSV", "GPA", "Mean Credit", "Pred Rank", "Progress", "Semeters"]
|
606 |
+
]
|
607 |
+
.style.applymap(color_cell)
|
608 |
+
.format({"GPA": "{:.2f}", "Mean Credit": "{:.1f}", "Semeters": "{:.1f}"})
|
609 |
+
)
|
610 |
+
|
611 |
+
with st.container():
|
612 |
+
st.table(styled_table)
|
613 |
+
predict_one_student(df, MaSV)
|
614 |
+
else:
|
615 |
+
df_late = predict
|
616 |
+
|
617 |
+
df_late["Year"] = 2000 + df_late["MaSV"].apply(get_year)
|
618 |
+
df_late = df_late[
|
619 |
+
(df_late["Year"] != currentYear - 1) & (df_late["Year"] != currentYear - 2)
|
620 |
+
]
|
621 |
+
year = st.selectbox("Select Year", options=df_late["Year"].unique())
|
622 |
+
df_filtered = df_late[df_late["Year"] == year]
|
623 |
+
styled_table = (
|
624 |
+
df_filtered[
|
625 |
+
["MaSV", "GPA", "Mean Credit", "Pred Rank", "Progress", "Semeters"]
|
626 |
+
]
|
627 |
+
.style.applymap(color_cell)
|
628 |
+
.format({"GPA": "{:.2f}", "Mean Credit": "{:.2f}", "Semeters": "{:.2f}"})
|
629 |
+
)
|
630 |
+
csv = df_filtered.to_csv(index=False)
|
631 |
+
b64 = base64.b64encode(csv.encode()).decode()
|
632 |
+
href = f'<a href="data:file/csv;base64,{b64}" download="Preidct data.csv">Download CSV</a>'
|
633 |
+
st.markdown(href, unsafe_allow_html=True)
|
634 |
+
|
635 |
+
legend_order = [
|
636 |
+
"Excellent",
|
637 |
+
"Very good",
|
638 |
+
"Good",
|
639 |
+
"Average good",
|
640 |
+
"Ordinary",
|
641 |
+
"Weak",
|
642 |
+
"Very weak",
|
643 |
+
]
|
644 |
+
|
645 |
+
fig1 = px.pie(
|
646 |
+
df_filtered,
|
647 |
+
names="Pred Rank",
|
648 |
+
title="Pred Rank",
|
649 |
+
color_discrete_sequence=px.colors.sequential.Mint,
|
650 |
+
height=400,
|
651 |
+
width=400,
|
652 |
+
labels=legend_order,
|
653 |
+
)
|
654 |
+
|
655 |
+
fig2 = px.pie(
|
656 |
+
df_filtered,
|
657 |
+
names="Progress",
|
658 |
+
title="Progress",
|
659 |
+
color_discrete_sequence=px.colors.sequential.Peach,
|
660 |
+
height=400,
|
661 |
+
width=400,
|
662 |
+
)
|
663 |
+
|
664 |
+
fig1.update_layout(
|
665 |
+
title={
|
666 |
+
"text": "Pred Rank",
|
667 |
+
"y": 0.95,
|
668 |
+
"x": 0.35,
|
669 |
+
"xanchor": "center",
|
670 |
+
"yanchor": "top",
|
671 |
+
}
|
672 |
+
)
|
673 |
+
fig2.update_layout(
|
674 |
+
title={
|
675 |
+
"text": "Progress",
|
676 |
+
"y": 0.95,
|
677 |
+
"x": 0.35,
|
678 |
+
"xanchor": "center",
|
679 |
+
"yanchor": "top",
|
680 |
+
}
|
681 |
+
)
|
682 |
+
|
683 |
+
col3, col1, col2 = st.columns([2, 1, 1])
|
684 |
+
with col3:
|
685 |
+
st.dataframe(styled_table,use_container_width=True)
|
686 |
+
with col1:
|
687 |
+
st.plotly_chart(fig1, use_container_width=True)
|
688 |
+
with col2:
|
689 |
+
st.plotly_chart(fig2, use_container_width=True)
|
690 |
+
variables_to_delete = [
|
691 |
+
"raw_data",
|
692 |
+
"df",
|
693 |
+
"df_late",
|
694 |
+
"MaSV",
|
695 |
+
"predict",
|
696 |
+
"rank",
|
697 |
+
"rank_mapping",
|
698 |
+
"styled_table",
|
699 |
+
"df_filtered",
|
700 |
+
"csv",
|
701 |
+
"b64",
|
702 |
+
"href",
|
703 |
+
"legend_order",
|
704 |
+
"fig1",
|
705 |
+
"fig2",
|
706 |
+
"col1",
|
707 |
+
"col2",
|
708 |
+
"col3"
|
709 |
+
]
|
710 |
+
|
711 |
+
# Delete the variables after running the code
|
712 |
+
for variable_name in variables_to_delete:
|
713 |
+
if variable_name in locals():
|
714 |
+
del locals()[variable_name]
|
715 |
+
|
716 |
+
elif tabs == "Grade Distribution Tables":
|
717 |
+
clear_resources()
|
718 |
+
raw_data = score_table()
|
719 |
+
df = process_data(raw_data)
|
720 |
+
additional_selection = " "
|
721 |
+
|
722 |
+
unique_values_major = df["Major"].unique()
|
723 |
+
unique_values_major = [
|
724 |
+
"BA",
|
725 |
+
"BE",
|
726 |
+
"BT",
|
727 |
+
"CE",
|
728 |
+
"EE",
|
729 |
+
"EN",
|
730 |
+
"EV",
|
731 |
+
"IE",
|
732 |
+
"MA",
|
733 |
+
"SE",
|
734 |
+
"IT",
|
735 |
+
]
|
736 |
+
unique_values_major = sorted(unique_values_major, key=lambda s: s)
|
737 |
+
col1, col2 = st.columns(2)
|
738 |
+
with col1:
|
739 |
+
major = st.selectbox("Select a school:", unique_values_major)
|
740 |
+
df = filter_dataframe(df, "Major", major)
|
741 |
+
|
742 |
+
unique_values_school = df["MaSV_school"].unique()
|
743 |
+
all_values_school = np.concatenate([["All"], unique_values_school])
|
744 |
+
no_numbers = [x for x in all_values_school if not re.search(r"\d", str(x))]
|
745 |
+
|
746 |
+
if len(no_numbers) == 2:
|
747 |
+
school = no_numbers[1]
|
748 |
+
with col2:
|
749 |
+
school = st.selectbox("Select a major:", no_numbers)
|
750 |
+
|
751 |
+
df = filter_dataframe(df, "MaSV_school", school)
|
752 |
+
|
753 |
+
unique_values_year = df["Year"].unique()
|
754 |
+
all_values_year = np.concatenate([["All"], unique_values_year])
|
755 |
+
|
756 |
+
year = st.selectbox("Select a year:", all_values_year)
|
757 |
+
|
758 |
+
options = df.columns[:-4]
|
759 |
+
|
760 |
+
|
761 |
+
course_data_dict = {course: df[course].dropna() for course in options}
|
762 |
+
|
763 |
+
valid_courses = [
|
764 |
+
course for course, data in course_data_dict.items() if len(data) > 1
|
765 |
+
]
|
766 |
+
|
767 |
+
course = "All"
|
768 |
+
|
769 |
+
if st.button("Generate Chart"):
|
770 |
+
courses_per_row = 4
|
771 |
+
num_courses = len(valid_courses)
|
772 |
+
num_rows = (num_courses + courses_per_row - 1) // courses_per_row
|
773 |
+
|
774 |
+
for row in range(num_rows):
|
775 |
+
start_index = row * courses_per_row
|
776 |
+
end_index = min((row + 1) * courses_per_row, num_courses)
|
777 |
+
courses_in_row = valid_courses[start_index:end_index]
|
778 |
+
|
779 |
+
for course in courses_in_row:
|
780 |
+
course_data = course_data_dict[course]
|
781 |
+
course_data = course_data.astype(float)
|
782 |
+
st.markdown(f"Course: **{course}**")
|
783 |
+
st.write("Number of examinations: ", str(len(course_data)))
|
784 |
+
col1, col2, col3, col4 = st.columns(4)
|
785 |
+
|
786 |
+
with col1:
|
787 |
+
counts, bins = np.histogram(course_data, bins=np.arange(0, 110, 10))
|
788 |
+
total_count = len(course_data)
|
789 |
+
frequencies_percentage = (counts / total_count) * 100
|
790 |
+
grade_bins = [
|
791 |
+
f"{bins[i]}-{bins[i+1]}" for i in range(len(bins) - 1)
|
792 |
+
]
|
793 |
+
result_array = []
|
794 |
+
cumulative_sum = 0
|
795 |
+
|
796 |
+
for element in frequencies_percentage:
|
797 |
+
cumulative_sum += element
|
798 |
+
result_array.append(cumulative_sum)
|
799 |
+
|
800 |
+
df = pd.DataFrame(
|
801 |
+
{
|
802 |
+
"Grade": grade_bins,
|
803 |
+
"Grading percentage": frequencies_percentage,
|
804 |
+
"Cumulative percentage": result_array
|
805 |
+
}
|
806 |
+
)
|
807 |
+
df["Grading percentage"] = df["Grading percentage"].map(
|
808 |
+
lambda x: "{:.2f}".format(x)
|
809 |
+
)
|
810 |
+
df["Cumulative percentage"] = df["Cumulative percentage"].map(
|
811 |
+
lambda x: "{:.2f}".format(x)
|
812 |
+
)
|
813 |
+
|
814 |
+
st.table(df)
|
815 |
+
|
816 |
+
with col2:
|
817 |
+
fig = go.Figure()
|
818 |
+
fig.add_trace(
|
819 |
+
go.Scatter(
|
820 |
+
x=bins[:-1],
|
821 |
+
y=frequencies_percentage,
|
822 |
+
mode="lines",
|
823 |
+
name="Frequency",
|
824 |
+
)
|
825 |
+
)
|
826 |
+
|
827 |
+
fig.update_layout(
|
828 |
+
title="Frequency Range",
|
829 |
+
xaxis_title="Score",
|
830 |
+
yaxis_title="Percentage",
|
831 |
+
height=400,
|
832 |
+
width=400,
|
833 |
+
)
|
834 |
+
st.plotly_chart(fig, use_container_width=True)
|
835 |
+
|
836 |
+
with col3:
|
837 |
+
fig = go.Figure()
|
838 |
+
fig.add_trace(go.Box(y=course_data, name="Box plot"))
|
839 |
+
fig.update_layout(
|
840 |
+
title="Box plot",
|
841 |
+
yaxis_title="Score",
|
842 |
+
height=400,
|
843 |
+
width=400,
|
844 |
+
)
|
845 |
+
st.plotly_chart(fig, use_container_width=True)
|
846 |
+
|
847 |
+
with col4:
|
848 |
+
raw_data1 = raw_data.copy()
|
849 |
+
raw_data1["major"] = raw_data1["MaSV"].str.slice(0, 2)
|
850 |
+
raw_data1.replace(["WH", "VT", "I"], np.nan, inplace=True)
|
851 |
+
raw_data1 = raw_data1[~raw_data1["DiemHP"].isin(["P", "F", "PC"])]
|
852 |
+
if major != "All":
|
853 |
+
raw_data1 = raw_data1[raw_data1["major"] == major]
|
854 |
+
|
855 |
+
raw_data1["MaSV_school"] = raw_data1["MaSV"].str.slice(2, 4)
|
856 |
+
if school != "All":
|
857 |
+
raw_data1 = raw_data1[raw_data1["MaSV_school"] == school]
|
858 |
+
|
859 |
+
df1 = raw_data1[["TenMH", "NHHK", "DiemHP"]].copy()
|
860 |
+
df1["DiemHP"] = df1["DiemHP"].astype(float)
|
861 |
+
df1["NHHK"] = df1["NHHK"].apply(
|
862 |
+
lambda x: str(x)[:4] + " S " + str(x)[4:]
|
863 |
+
)
|
864 |
+
|
865 |
+
selected_TenMH = " " + course
|
866 |
+
filtered_df1 = df1[df1["TenMH"] == selected_TenMH]
|
867 |
+
|
868 |
+
mean_DiemHP = (
|
869 |
+
filtered_df1.groupby("NHHK")["DiemHP"]
|
870 |
+
.mean()
|
871 |
+
.round(1)
|
872 |
+
.reset_index(name="Mean")
|
873 |
+
)
|
874 |
+
|
875 |
+
if year != "All":
|
876 |
+
st.write("")
|
877 |
+
else:
|
878 |
+
fig = px.line(
|
879 |
+
mean_DiemHP,
|
880 |
+
x="NHHK",
|
881 |
+
y="Mean",
|
882 |
+
title=f"Mean DiemHP through Semesters",
|
883 |
+
)
|
884 |
+
fig.update_layout(height=400, width=400)
|
885 |
+
st.plotly_chart(fig, use_container_width=True)
|
886 |
+
del raw_data1, df1, filtered_df1, mean_DiemHP, counts, bins, total_count, frequencies_percentage, grade_bins, fig
|
887 |
+
del course_data, course_data_dict, valid_courses
|
888 |
+
st.stop()
|
model/BA_rank.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:d11d4c28f682d07bda4d4adfe64ef76ac692cc88af9d3a1b2551226cc2e4fa73
|
3 |
+
size 992753
|
model/BE_rank.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:720a598596eeab9ed2f7f4fec18076ec7eed80bde81750e70fd6194194105a36
|
3 |
+
size 956225
|
model/BT_rank.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:f7ebe7baa44bc48cd34bc9d03e29848c77bae585df28ed25f0db57603b0c811b
|
3 |
+
size 970705
|
model/CE_rank.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:1618dfb0ad4439038f7d20267ae871ed01dc2593fa92cfda4a0afbdf76bccd57
|
3 |
+
size 699689
|
model/EE_rank.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:2758fe04674069b630752eedafeebed5873b4cf4ff2760b5985553a71d36c6e5
|
3 |
+
size 937585
|
model/EN_rank.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:667d9d1423ffbdc8992dd4356c4edebb1f19f443ad4726a04dbafa6fc1f4bd29
|
3 |
+
size 801689
|
model/EV_rank.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:8ecf3c8a4e79a4e809cc8eff9bb3448c308020b8253941a4ce449c97b326aceb
|
3 |
+
size 595841
|
model/IE_rank.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:f88caec0a36dd42cbb9a5b721270263b37d64c713e4852c0279924d4c986938f
|
3 |
+
size 997569
|
model/IT_rank.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:1501f7d0d2fa69383152b743d6b64d81d483054ec38ef95bedde9667fff68636
|
3 |
+
size 1041793
|
model/MA_rank.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:1de5f4e973abab2d91c18f88e4cd88ac8d1f3b358b827dec03fb75c5c0f9ef4e
|
3 |
+
size 885313
|
model/SE_rank.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:f6202e55a86124de781d7aa456e995a98f1e2810c5b9dc4c7efa5a61fbf2e396
|
3 |
+
size 556705
|
model/Time/Late.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:bc8a028c74d33d2ee4237cc6e1fc017d51e276bad5ccf752a608e4eab9d5249b
|
3 |
+
size 540660
|
model/Time/Sem.joblib
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:adfbee871506a3a7e6e3ca02d7bd205cceab50fdbec47878d01773ed59dd5e7c
|
3 |
+
size 2638353
|
requirements.txt
CHANGED
@@ -6,3 +6,4 @@ plotly
|
|
6 |
scipy
|
7 |
pyDOE
|
8 |
openpyxl
|
|
|
|
6 |
scipy
|
7 |
pyDOE
|
8 |
openpyxl
|
9 |
+
matplotlib
|