Penguni commited on
Commit
cc42642
1 Parent(s): 56b76fb

Upload 43 files

Browse files
.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
- app_file: app.py
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>&nbsp;</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">&nbsp;</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;">&nbsp;</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
- return int(student_id[6:8])
 
 
 
 
 
 
11
 
 
 
12
  def process_data(raw_data):
13
- # Pivot the DataFrame
14
- pivot_df = pd.pivot_table(raw_data, values='DiemHP', index='MaSV', columns='TenMH', aggfunc='first')
 
 
 
 
 
 
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
- # Drop unnecessary columns
20
- cols_to_drop = []
21
- with open('cols_to_drop.txt', 'r') as f:
22
- for line in f:
23
- cols_to_drop.append(str(line.strip()))
24
- existing_cols = [col for col in cols_to_drop if col in pivot_df.columns]
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['MaSV_school'] = df['MaSV'].str.slice(2, 4)
37
- df['Major'] = df['MaSV'].str.slice(0, 2)
38
  df["Year"] = 2000 + df["MaSV"].apply(get_year)
39
- df["Year"]=df["Year"].astype(str)
40
- df=df.drop(columns='MaSV')
41
-
 
42
  return df
43
-
 
44
  def process_data_per(raw_data):
45
- # Pivot the DataFrame
46
- pivot_df = pd.pivot_table(raw_data, values='DiemHP', index='MaSV', columns='TenMH', aggfunc='first')
 
 
 
 
 
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
- # Drop unnecessary columns
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
- # Merge with the XepLoaiNH column
63
- df = pd.merge(pivot_df, raw_data[['MaSV', 'XepLoaiNH']], on='MaSV')
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 = raw_data.groupby(["MaSV", "MaMH"]).size().reset_index(name="Times")
75
- courses = raw_data[raw_data['MaMH'].str.startswith('IT')]
76
- courses_list=courses['MaMH'].unique().tolist()
 
 
 
 
 
 
 
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)) & (count_duplicates["Times"] >= 2)
 
85
  ).astype(int)
86
 
87
  count_duplicates["pass_courses"] = (
88
- (~count_duplicates["MaMH"].isin(courses_list)) & (count_duplicates["Times"] == 1)
 
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[['MaSV','NHHK','SoTCDat']]
105
- data = data.drop_duplicates()
106
- data = data.groupby(['MaSV'])['SoTCDat'].median().reset_index(name='Mean_Cre').round(2)
107
-
108
- df = pd.merge(df, data, on='MaSV')
109
- df1=raw_data[['MaSV','MaMH','NHHK']]
110
- courses_list = raw_data[(raw_data['MaMH'].str.startswith('EN')) & ~(raw_data['MaMH'].str.contains('EN007|EN008|EN011|EN012'))].MaMH.tolist()
111
- filtered_df = df1[df1['MaMH'].isin(courses_list)]
112
- nhhk_counts = filtered_df.groupby('MaSV')['NHHK'].nunique().reset_index(name='EPeriod')
113
- df = pd.merge(df, nhhk_counts, on='MaSV', how='left').fillna(0)
114
- df=df[['MaSV','GPA' ,'Mean_Cre', 'fail_courses_list_count' ,'fail_not_courses_list_count' ,'EPeriod']]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  return df
116
 
 
117
  def predict_late_student(test_df):
118
- # Load the pre-trained model
119
- model=joblib.load("model/R_Late.joblib")
120
- model1=joblib.load("model/R_Sem.joblib")
121
- # Process the student data
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
- # Add a new column to the student data indicating if the student is late
139
- test_dfed['Period'] = prediction1
140
- test_dfed['Result'] = ['late' if p == 1 else 'not late' for p in prediction]
 
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
- if row['Period'] <= 9 and row['Result'] == 'late':
147
- test_dfed.loc[index, 'Period'] = row['Period'] / 2
148
- test_dfed.loc[index, 'Result'] = 'may late'
149
- else:
150
- test_dfed.loc[index, 'Period'] = row['Period'] / 2
151
 
152
  return test_dfed
153
- def predict_rank(raw_data):
154
- # Pivot the DataFrame
155
- raw_data = raw_data[raw_data["MaSV"].str.startswith("IT")]
156
- raw_data = raw_data[raw_data['MaMH'].str.startswith('IT')]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  pivot_df = pd.pivot_table(
158
- raw_data, values="DiemHP", index="MaSV", columns="TenMH", aggfunc="first"
159
  )
160
  pivot_df = pivot_df.reset_index().rename_axis(None, axis=1)
161
  pivot_df.columns.name = None
162
- pivot_df = pivot_df.dropna(thresh=50, axis=1)
163
- pivot_df = pivot_df.rename(columns=lambda x: x.strip())
164
 
165
- pivot_df.replace("WH", np.nan, inplace=True)
 
 
 
166
  pivot_df.iloc[:, 1:] = pivot_df.iloc[:, 1:].apply(pd.to_numeric)
 
167
 
168
- # Merge with the XepLoaiNH column
 
169
  df = pd.merge(pivot_df, raw_data[["MaSV", "DTBTK"]], on="MaSV")
170
  df.drop_duplicates(subset="MaSV", keep="last", inplace=True)
171
- col=df.drop(['MaSV', 'DTBTK'], axis=1)
172
-
173
- columns_data = []
174
- with open('column_all.txt', 'r') as f:
175
- for line in f:
176
- columns_data.append(str(line.strip()))
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
- if df[col].isnull().values.any():
185
  df[col].fillna(value=df["DTBTK"], inplace=True)
186
- std_id = df['MaSV'].copy()
187
- df=df.drop(['MaSV', 'DTBTK'], axis=1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- # Subset the DataFrame to relevant columns and rows
199
- student = process_data_per(raw_data)
200
- filtered_df = student[student["MaSV"] == student_id]
201
- if len(filtered_df) > 0:
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
- # set the chart title and axis labels
 
 
 
 
 
211
  fig1.update_layout(
212
- title="Histogram for student {}".format(student_id),
213
- xaxis_title="Value",
214
- yaxis_title="Frequency",
215
- width=500
 
216
  )
217
 
218
- # create a bar chart using plotly express
219
- data = raw_data[['MaSV', 'NHHK', 'TenMH', 'DiemHP']]
220
- data['TenMH'] = data['TenMH'].str.lstrip()
221
- data['NHHK'] = data['NHHK'].apply(lambda x: str(x)[:4] + ' S ' + str(x)[4:])
222
  rows_to_drop = []
223
- with open('rows_to_drop.txt', 'r') as f:
224
  for line in f:
225
  rows_to_drop.append(str(line.strip()))
226
- data = data[~data['TenMH'].isin(rows_to_drop)]
227
- student_data = data[data['MaSV'] == student_id][['NHHK', 'TenMH', 'DiemHP']]
228
- student_data['DiemHP'] = pd.to_numeric(student_data['DiemHP'], errors='coerce')
229
-
230
- fig2 = px.bar(student_data, x='TenMH', y='DiemHP', color='NHHK', title='Student Score vs. Course')
 
 
 
 
 
 
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['TenMH'])-1,
241
  y1=50,
242
- line=dict(color='red', width=3)
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
- else:
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