namngo commited on
Commit
182504e
·
verified ·
1 Parent(s): 3d6329e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +227 -138
app.py CHANGED
@@ -71,41 +71,30 @@ def save_to_gsheet(name, student_id, major, prediction, semester_data, sheet_nam
71
      # Get all values from the sheet to check if the first row is empty (i.e., headers not created yet)
72
      all_values = sheet.get_all_values()
73
 
74
-     # Define headers based on the model type for clarity in the sheet
75
-     base_headers = ["Họ và tên", "MSV", "Khoa", "Dự báo", "Thời gian"]
76
-     if sheet_name == "Trang tính1": # Full model headers
77
-         semester_headers = []
78
-         for i in range(6):
79
-             semester_headers += [
80
-                 f"Số môn không thi - HK{i+1}",
81
-                 f"Số tín chỉ không thi - HK{i+1}",
82
-                 f"Số tín chỉ nợ - HK{i+1}",
83
-                 f"Số môn không đạt - HK{i+1}",
84
-                 f"Tổng tín chỉ học kỳ - HK{i+1}",
85
-                 f"Số môn học kỳ - HK{i+1}",
86
-                 f"Số môn đạt - HK{i+1}",
87
-                 f"GPA - HK{i+1}",
88
-                 f"Xếp loại - HK{i+1}"
89
-             ]
90
-         # Add nganh header
91
-         headers = base_headers + semester_headers + ["Ngành (0: CNTT, 1: Kinh tế)"]
92
-
93
-     elif sheet_name == "Trang tính2": # Important features model headers
94
-         semester_headers = []
95
-         for i in range(6):
96
-             semester_headers += [
97
-                 f"Số tín chỉ đạt - HK{i+1}",
98
-                 f"Số tín chỉ nợ - HK{i+1}",
99
-                 f"Điểm trung bình - HK{i+1}"
100
-             ]
101
-         headers = base_headers + semester_headers
102
-
103
-
104
-     # If the sheet is empty or if headers are missing or mismatched, insert headers
105
-     if not all_values or len(all_values[0]) != len(headers):
106
-         sheet.clear() # Clear existing content if headers are wrong or missing
107
-         sheet.append_row(headers)  # Create headers
108
-
109
      # Append data to the sheet
110
      sheet.append_row(data_row)
111
 
@@ -114,7 +103,7 @@ def save_to_gsheet(name, student_id, major, prediction, semester_data, sheet_nam
114
  # def list_sheet_names(sheet_id):
115
  #     client = get_gsheet_client()
116
  #     sheet = client.open_by_key(sheet_id)
117
- #    
118
  #     # List all sheet names
119
  #     sheet_names = [worksheet.title for worksheet in sheet.worksheets()]
120
  #     return sheet_names
@@ -140,12 +129,12 @@ sample_cntt_example_full = {
140
      "student_id": "10117367",
141
      "major": "Công nghệ thông tin",
142
      "semester_data": [
143
-         0, 0, 0, 0, 17, 7, 7, 8.73, 0, # HK1
144
-         0, 0, 0, 0, 17, 7, 7, 8.19, 0, # HK2
145
-         0, 0, 0, 0, 17, 7, 7, 7.90, 0, # HK3
146
-         0, 0, 0, 0, 17, 7, 7, 8.19, 0, # HK4
147
-         0, 0, 0, 0, 19, 7, 6, 8.18, 0, # HK5
148
-         0, 0, 5, 2, 19, 7, 5, 7.10, 1 # HK6
149
      ]
150
  }
151
 
@@ -166,6 +155,7 @@ sample_kinhte_example_simple = {
166
  }
167
 
168
 
 
169
  # ===== Ví dụ cho mô hình "Dùng mô hình đơn giản" cho CNTT =====
170
  sample_cntt_example_simple = {
171
      "name": "Nguyễn Văn B",
@@ -187,123 +177,222 @@ sample_kinhte_example_full = {
187
      "student_id": "11418093",
188
      "major": "Kinh tế",
189
      "semester_data": [
190
-         0, 0, 0, 0, 16, 6, 6, 7.00, 1, # HK1
191
-         0, 0, 0, 0, 18, 7, 7, 8.20, 1, # HK2
192
-         0, 0, 0, 0, 17, 7, 7, 7.80, 1, # HK3
193
-         0, 0, 0, 0, 17, 7, 6, 7.90, 1, # HK4
194
-         0, 0, 0, 0, 19, 8, 5, 8.10, 0, # HK5
195
-         0, 0, 8, 2, 19, 7, 6, 7.30, 1 # HK6
196
      ]
197
  }
198
 
199
-
200
  # ===== Thông tin cá nhân =====
201
- # Determine which example data to use based on model type and selected option
202
- if model_type == "Dùng toàn bộ đặc trưng":
203
- if sample_option == "Dùng dụ mẫu ngành Công nghệ thông tin":
204
- selected_example_data = sample_cntt_example_full
205
- default_major_index = 0
206
- elif sample_option == "Dùng ví dụ mẫu ngành Kinh tế":
207
- selected_example_data = sample_kinhte_example_full
208
- default_major_index = 1
209
- else:
210
- selected_example_data = None
211
- default_major_index = 0 # Default to CNTT
212
- else: # Dùng đặc trưng quan trọng
213
- if sample_option == "Dùng ví dụ mẫu ngành Công nghệ thông tin":
214
- selected_example_data = sample_cntt_example_simple
215
- default_major_index = 0
216
- elif sample_option == "Dùng dụ mẫu ngành Kinh tế":
217
- selected_example_data = sample_kinhte_example_simple
218
- default_major_index = 1
219
- else:
220
- selected_example_data = None
221
- default_major_index = 0 # Default to CNTT
222
-
223
-
224
- name_value = selected_example_data["name"] if selected_example_data else ""
225
- student_id_value = selected_example_data["student_id"] if selected_example_data else ""
226
-
227
-
228
- name = st.text_input("👤 Họ và tên", value=name_value)
229
- student_id = st.text_input("🎓 Mã sinh viên", value=student_id_value)
230
- major = st.selectbox("📚 Ngành học", ["Công nghệ thông tin", "Kinh tế"], index=default_major_index)
231
 
232
 
233
  st.write("---")
234
 
235
  # ===== Nhập thông tin học kỳ =====
236
- def input_semester_full(semester_label, default_values=None):
237
      with st.expander(f"📖 {semester_label}", expanded=True):
238
          col1, col2 = st.columns(2)
239
          with col1:
240
-             somon0thi = st.number_input("Số môn không thi", 0, value=default_values[0] if default_values and len(default_values) > 0 else 0, key=f"sm0_{semester_label}")
241
-             sotc0thi = st.number_input("Số tín chỉ không thi", 0, value=default_values[1] if default_values and len(default_values) > 1 else 0, key=f"tc0_{semester_label}")
242
-             sotcno = st.number_input("Số tín chỉ nợ", 0, value=default_values[2] if default_values and len(default_values) > 2 else 0, key=f"tcno_{semester_label}")
243
-             mhno = st.number_input("Số môn không đạt", 0, value=default_values[3] if default_values and len(default_values) > 3 else 0, key=f"mhno_{semester_label}")
244
-             # Calculate default_tc_qua if possible, otherwise default to 0
245
-             default_tc_qua = 0
246
-             if default_values and len(default_values) > 4 and len(default_values) > 2:
247
-                 default_tc_qua = default_values[4] - default_values[2]
248
-             sotc_qua = st.number_input("Số tín chỉ qua môn", 0, value=default_tc_qua, key=f"tcqua_{semester_label}")
249
-
 
 
 
 
 
250
          with col2:
251
-             TCHK = st.number_input("Tổng tín chỉ học kỳ", 0, value=default_values[4] if default_values and len(default_values) > 4 else 0, key=f"tchk_{semester_label}")
252
-             smhk = st.number_input("Số môn học kỳ", 0, value=default_values[5] if default_values and len(default_values) > 5 else 0, key=f"smhk_{semester_label}")
253
-             mhpass = st.number_input("Số môn đạt", 0, value=default_values[6] if default_values and len(default_values) > 6 else 0, key=f"mhpass_{semester_label}")
254
-             TBCHK = st.number_input("GPA", 0.0, 10.0, value=default_values[7] if default_values and len(default_values) > 7 else 0.0, step=0.01, key=f"gpa_{semester_label}")
255
-             xep_loai_selected = st.selectbox("Xếp loại", list(range(7)), index=default_values[8] if default_values and len(default_values) > 8 else 0, key=f"xeploai_{semester_label}")
256
-
257
-     return [somon0thi, sotc0thi, sotcno, mhno, TCHK, smhk, mhpass, TBCHK, xep_loai_selected] # Removed sotc_qua as it's calculated
258
-
 
 
 
 
 
 
 
 
 
 
259
 
260
  # ===== Giao diện theo mô hình =====
261
  data = []
262
  semesters = ["HỌC KỲ I", "HỌC KỲ II", "HỌC KỲ III", "HỌC KỲ IV", "HỌC KỲ V", "HỌC KỲ VI"]
263
 
264
- # Mô hình 1: "Dùng toàn bộ đặc trưng"
265
  if model_type == "Dùng toàn bộ đặc trưng":
266
- st.subheader("🔢 Nhập thông tin học kỳ chi tiết")
267
- for idx, sem in enumerate(semesters):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
  example_data = sample_cntt_example_full if sample_option == "Dùng ví dụ mẫu ngành Công nghệ thông tin" else sample_kinhte_example_full if sample_option == "Dùng ví dụ mẫu ngành Kinh tế" else None
269
- default_values = example_data["semester_data"][idx*9:(idx+1)*9] if example_data else None
270
- data += input_semester_full(sem, default_values)
271
- nganh = 0 if major == "Công nghệ thông tin" else 1
272
- final_features = np.array(data + [nganh]).reshape(1, -1)
273
 
274
- # Mô hình 2: "Dùng đặc trưng quan trọng" (Simplified layout as per image)
275
- else:
 
276
      st.subheader("✨ Nhập thông tin rút gọn")
277
      
278
-     example_data = sample_cntt_example_simple if sample_option == "Dùng ví dụ mẫu ngành Công nghệ thông tin" else sample_kinhte_example_simple if sample_option == "Dùng ví dụ mẫu ngành Kinh tế" else None
279
-     semester_data_example = example_data["semester_data"] if example_data else [0, 0, 0] * 6 # Default to zeros if no example
280
-
281
-     # Row 1: HK I, HK II, HK III
282
-     cols1 = st.columns(3)
283
-     for idx, sem in enumerate(semesters[:3]):
284
-         with cols1[idx]:
285
-             with st.expander(f"📘 {sem}", expanded=True):
286
-                 default_values = semester_data_example[idx*3:(idx+1)*3]
287
-                 sotc_qua = st.number_input("Số tín chỉ đạt", 0, value=default_values[0] if len(default_values) > 0 else 0, key=f"tcqua_imp_{sem}")
288
-                 sotcno = st.number_input("Số tín chỉ nợ", 0, value=default_values[1] if len(default_values) > 1 else 0, key=f"tcno_imp_{sem}")
289
-                 TBCHK = st.number_input("Điểm trung bình", 0.0, 10.0, value=default_values[2] if len(default_values) > 2 else 0.0, step=0.01, key=f"gpa_imp_{sem}")
290
-                 data.extend([sotc_qua, sotcno, TBCHK]) # Collect data
291
-
292
-     # Row 2: HK IV, HK V, HK VI (assuming VI is included based on semesters list)
293
-     cols2 = st.columns(3)
294
-     for idx, sem in enumerate(semesters[3:]):
295
-         with cols2[idx]:
296
-             with st.expander(f"📘 {sem}", expanded=True):
297
-                 # Adjust index for example data: idx here is 0, 1, 2 for HK IV, V, VI
298
-                 example_idx = idx + 3 # Adjust to get correct data from the 6 semesters
299
-                 default_values = semester_data_example[example_idx*3:(example_idx+1)*3]
300
-                 sotc_qua = st.number_input("Số tín chỉ đạt", 0, value=default_values[0] if len(default_values) > 0 else 0, key=f"tcqua_imp_{sem}")
301
-                 sotcno = st.number_input("Số tín chỉ nợ", 0, value=default_values[1] if len(default_values) > 1 else 0, key=f"tcno_imp_{sem}")
302
-                 TBCHK = st.number_input("Điểm trung bình", 0.0, 10.0, value=default_values[2] if len(default_values) > 2 else 0.0, step=0.01, key=f"gpa_imp_{sem}")
303
-                 data.extend([sotc_qua, sotcno, TBCHK]) # Collect data
304
-
305
-     final_features = np.array(data).reshape(1, -1)
306
-
307
 
308
  # ===== Predict =====
309
  if st.button("🎯 DỰ BÁO"):
@@ -311,9 +400,9 @@ if st.button("🎯 DỰ BÁO"):
311
          prediction = model_full.predict(final_features)
312
          sheet_name = "Trang tính1"  # For full data model, save to Trang tính1
313
 
314
-     else:
315
          prediction = model_important.predict(final_features)
316
-         sheet_name = "Trang tính2"  # For full data model, save to Trang tính1
317
 
318
 
319
      if prediction[0] == 1:
 
71
      # Get all values from the sheet to check if the first row is empty (i.e., headers not created yet)
72
      all_values = sheet.get_all_values()
73
 
74
+ # Define headers based on the model type for accurate sheet saving
75
+ if sheet_name == "Trang tính1": # Full features model
76
+ headers = ["Họ và tên", "MSV", "Khoa", "Dự báo", "Thời gian"] + [
77
+ f"Số môn không thi - HK{i+1}" for i in range(6)] + [
78
+ f"Số tín chỉ không thi - HK{i+1}" for i in range(6)] + [
79
+ f"Số tín chỉ nợ - HK{i+1}" for i in range(6)] + [
80
+ f"Số môn không đạt - HK{i+1}" for i in range(6)] + [
81
+ f"Số tín chỉ qua môn - HK{i+1}" for i in range(6)] + [
82
+ f"Tổng tín chỉ học kỳ - HK{i+1}" for i in range(6)] + [
83
+ f"Số môn học kỳ - HK{i+1}" for i in range(6)] + [
84
+ f"Số môn đạt - HK{i+1}" for i in range(6)] + [
85
+ f"GPA - HK{i+1}" for i in range(6)] + [
86
+ f"Xếp loại - HK{i+1}" for i in range(6)]
87
+
88
+ elif sheet_name == "Trang tính2": # Important features model
89
+ headers = ["Họ và tên", "MSV", "Khoa", "Dự báo", "Thời gian"] + [
90
+ f"Số tín chỉ đạt - HK{i+1}" for i in range(6)] + [
91
+ f"Số tín chỉ nợ - HK{i+1}" for i in range(6)] + [
92
+ f"Điểm trung bình - HK{i+1}" for i in range(6)]
93
+
94
+ # If the sheet is empty or if headers are missing, insert headers
95
+     if not all_values or len(all_values[0]) != len(headers):  # Ensure number of columns matches expected headers
96
+         sheet.append_row(headers)  # Create headers if missing
97
+     
 
 
 
 
 
 
 
 
 
 
 
98
      # Append data to the sheet
99
      sheet.append_row(data_row)
100
 
 
103
  # def list_sheet_names(sheet_id):
104
  #     client = get_gsheet_client()
105
  #     sheet = client.open_by_key(sheet_id)
106
+     
107
  #     # List all sheet names
108
  #     sheet_names = [worksheet.title for worksheet in sheet.worksheets()]
109
  #     return sheet_names
 
129
      "student_id": "10117367",
130
      "major": "Công nghệ thông tin",
131
      "semester_data": [
132
+         0, 0, 0, 0, 17, 7, 7, 8.73, 0,
133
+         0, 0, 0, 0, 17, 7, 7, 8.19, 0,
134
+         0, 0, 0, 0, 17, 7, 7, 7.90, 0,
135
+         0, 0, 0, 0, 17, 7, 7, 8.19, 0,
136
+         0, 0, 0, 0, 19, 7, 6, 8.18, 0,
137
+         0, 0, 5, 2, 19, 7, 5, 7.10, 1
138
      ]
139
  }
140
 
 
155
  }
156
 
157
 
158
+ # ===== Ví dụ cho mô hình "Dùng mô hình đơn giản" cho CNTT =====
159
  # ===== Ví dụ cho mô hình "Dùng mô hình đơn giản" cho CNTT =====
160
  sample_cntt_example_simple = {
161
      "name": "Nguyễn Văn B",
 
177
      "student_id": "11418093",
178
      "major": "Kinh tế",
179
      "semester_data": [
180
+         0, 0, 0, 0, 16, 6, 6, 7.00, 1,
181
+         0, 0, 0, 0, 18, 7, 7, 8.20, 1,
182
+         0, 0, 0, 0, 17, 7, 7, 7.80, 1,
183
+         0, 0, 0, 0, 17, 7, 6, 7.90, 1,
184
+         0, 0, 0, 0, 19, 8, 5, 8.10, 0,
185
+         0, 0, 8, 2, 19, 7, 6, 7.30, 1
186
      ]
187
  }
188
 
 
189
  # ===== Thông tin cá nhân =====
190
+ if sample_option == "Dùng dụ mẫu ngành Công nghệ thông tin":
191
+     # Check model type to load appropriate example data
192
+ if model_type == "Dùng toàn bộ đặc trưng":
193
+ sample_data_personal = sample_cntt_example_full
194
+ else: # Dùng đặc trưng quan trọng
195
+ sample_data_personal = sample_cntt_example_simple
196
+ name = st.text_input("👤 Họ và tên", value=sample_data_personal["name"])
197
+     student_id = st.text_input("🎓 Mã sinh viên", value=sample_data_personal["student_id"])
198
+     major = st.selectbox("📚 Ngành học", ["Công nghệ thông tin", "Kinh tế"], index=0)
199
+ elif sample_option == "Dùng ví dụ mẫu ngành Kinh tế":
200
+ # Check model type to load appropriate example data
201
+ if model_type == "Dùng toàn bộ đặc trưng":
202
+ sample_data_personal = sample_kinhte_example_full
203
+ else: # Dùng đặc trưng quan trọng
204
+ sample_data_personal = sample_kinhte_example_simple
205
+     name = st.text_input("👤 Họ tên", value=sample_data_personal["name"])
206
+     student_id = st.text_input("🎓 Mã sinh viên", value=sample_data_personal["student_id"])
207
+     major = st.selectbox("📚 Ngành học", ["Công nghệ thông tin", "Kinh tế"], index=1)
208
+ else:
209
+     name = st.text_input("👤 Họ và tên")
210
+     student_id = st.text_input("🎓 sinh viên")
211
+     major = st.selectbox("📚 Ngành học", ["Công nghệ thông tin", "Kinh tế"])
 
 
 
 
 
 
 
 
212
 
213
 
214
  st.write("---")
215
 
216
  # ===== Nhập thông tin học kỳ =====
217
+ def input_semester(semester_label, default_values=None):
218
      with st.expander(f"📖 {semester_label}", expanded=True):
219
          col1, col2 = st.columns(2)
220
          with col1:
221
+             somon0thi = st.number_input("Số môn không thi", 0, value=default_values[0] if default_values else 0, key=f"sm0_{semester_label}")
222
+             sotc0thi = st.number_input("Số tín chỉ không thi", 0, value=default_values[1] if default_values else 0, key=f"tc0_{semester_label}")
223
+             sotcno = st.number_input("Số tín chỉ nợ", 0, value=default_values[2] if default_values else 0, key=f"tcno_{semester_label}")
224
+             mhno = st.number_input("Số môn không đạt", 0, value=default_values[3] if default_values else 0, key=f"mhno_{semester_label}")
225
+             try:
226
+                 default_tc_qua = default_values[4] - default_values[2] if default_values and len(default_values) >= 5 else 0 # This calculation seems incorrect for "Số tín chỉ qua môn" if default_values[4] is Total Credit
227
+             except:
228
+                 default_tc_qua = 0
229
+ # Correcting default value logic for "Số tín chỉ qua môn" based on sample data structure
230
+ # If default_values has 9 elements (full model data), default_tc_qua is at index 4
231
+ if default_values and len(default_values) == 9:
232
+ default_tc_qua_input = default_values[4]
233
+ else:
234
+ default_tc_qua_input = 0 # Or some default
235
+             sotc_qua = st.number_input("Số tín chỉ qua môn", 0, value=default_tc_qua_input, key=f"tcqua_{semester_label}")
236
          with col2:
237
+             TCHK = st.number_input("Tổng tín chỉ học kỳ", 0, value=default_values[4] if default_values else 0, key=f"tchk_{semester_label}")
238
+             smhk = st.number_input("Số môn học kỳ", 0, value=default_values[5] if default_values else 0, key=f"smhk_{semester_label}")
239
+             mhpass = st.number_input("Số môn đạt", 0, value=default_values[6] if default_values else 0, key=f"mhpass_{semester_label}")
240
+             TBCHK = st.number_input("GPA", 0.0, 10.0, value=default_values[7] if default_values else 0.0, step=0.01, key=f"gpa_{semester_label}")
241
+             xep_loai_selected = st.selectbox("Xếp loại", list(range(7)), index=default_values[8] if default_values else 0, key=f"xeploai_{semester_label}")
242
+     return [somon0thi, sotc0thi, sotcno, mhno, TCHK, smhk, mhpass, TBCHK, xep_loai_selected, sotc_qua]
243
+
244
+ def input_important_features(semester_label, default_values=None):
245
+     with st.expander(f"📘 {semester_label}", expanded=True):
246
+         col1, col2, col3 = st.columns(3) # Use 3 columns for important features layout
247
+         with col1:
248
+             # Use consistent keys for input fields
249
+             sotc_qua = st.number_input("Số tín chỉ đạt", 0, value=default_values[0] if default_values and len(default_values) > 0 else 0, key=f"tcqua_imp_{semester_label}")
250
+         with col2:
251
+             sotcno = st.number_input("Số tín chỉ nợ", 0, value=default_values[1] if default_values and len(default_values) > 1 else 0, key=f"tcno_imp_{semester_label}")
252
+         with col3:
253
+             TBCHK = st.number_input("Điểm trung bình", 0.0, 10.0, value=default_values[2] if default_values and len(default_values) > 2 else 0.0, step=0.01, key=f"gpa_imp_{semester_label}")
254
+     return [sotc_qua, sotcno, TBCHK]
255
 
256
  # ===== Giao diện theo mô hình =====
257
  data = []
258
  semesters = ["HỌC KỲ I", "HỌC KỲ II", "HỌC KỲ III", "HỌC KỲ IV", "HỌC KỲ V", "HỌC KỲ VI"]
259
 
260
+ # Mô hình 1: "Dùng toàn bộ dữ liệu"
261
  if model_type == "Dùng toàn bộ đặc trưng":
262
+     st.subheader("🔢 Nhập thông tin học kỳ chi tiết")
263
+     for idx, sem in enumerate(semesters):
264
+         example_data = sample_cntt_example_full if sample_option == "Dùng ví dụ mẫu ngành Công nghệ thông tin" else sample_kinhte_example_full if sample_option == "Dùng ví dụ mẫu ngành Kinh tế" else None
265
+         # Full model data has 9 features per semester + 1 extra (sotc_qua, which was calculated) = 10 features.
266
+ # Update: based on the data structure, there are 9 features per semester in the full model example.
267
+ # The input_semester function returns 10 values. Let's check the save_to_gsheet function's headers for full model.
268
+ # Headers for full model have 9 semester specific columns per semester.
269
+ # Let's correct input_semester to return 9 values matching the headers/example data.
270
+ # The example data has 9 values per semester for the full model.
271
+ # Let's fix the input_semester function to match the example data and headers (9 features).
272
+ # The example data has [0, 0, 0, 0, 17, 7, 7, 8.73, 0] -> 9 values.
273
+ # The input_semester returns [somon0thi, sotc0thi, sotcno, mhno, TCHK, smhk, mhpass, TBCHK, xep_loai_selected, sotc_qua] -> 10 values.
274
+ # The save_to_gsheet headers for full model list 9 columns per semester.
275
+ # Let's align input_semester to return the 9 values that correspond to the headers.
276
+ # Headers: Số môn không thi, Số tín chỉ không thi, Số tín chỉ nợ, Số môn không đạt, Số tín chỉ qua môn, Tổng tín chỉ học kỳ, Số môn học kỳ, Số môn đạt, GPA, Xếp loại
277
+ # This is 10 headers per semester. The example data has 9. Let's fix the example data structure to match headers or vice versa.
278
+ # Assuming headers are correct: Número môn không thi, Số tín chỉ không thi, Số tín chỉ nợ, Số môn không đạt, Số tín chỉ qua môn, Tổng tín chỉ học kỳ, Số môn học kỳ, Số môn đạt, GPA, Xếp loại (10 features)
279
+ # Let's update the example data for the full model to include all 10 features if possible or remove headers that don't match the example data.
280
+ # Given the original code's save_to_gsheet headers for the full model list 10 items per semester type, and the example data for full model has 9 items per semester type, there's a mismatch.
281
+ # Let's assume the `input_semester` function's return values are correct based on the intended model features, and the `sample_cntt_example_full` and `sample_kinhte_example_full` are slightly off or need adjustment to match the 10 inputs.
282
+ # The `input_semester` returns: somon0thi, sotc0thi, sotcno, mhno, TCHK, smhk, mhpass, TBCHK, xep_loai_selected, sotc_qua. This is 10 values.
283
+ # The `save_to_gsheet` headers for 'Trang tính1' list 10 headers per semester type. This matches.
284
+ # The `sample_cntt_example_full` and `sample_kinhte_example_full` have 9 values per semester. This is where the discrepancy is.
285
+ # To make the examples work correctly with the full model inputs, the example data structure should match the 10 features collected by `input_semester`.
286
+ # The missing feature in the example data seems to be `sotc_qua`.
287
+ # Let's adjust the example data to include a value for `sotc_qua` for each semester, or adjust the `input_semester` default value logic.
288
+ # A simpler fix for now is to adjust the `input_semester` default value logic to handle the case where example data might be shorter.
289
+ # The `default_tc_qua_input` line within `input_semester` was calculating it, let's remove that and rely solely on the example data if available.
290
+ # And if example data for `sotc_qua` is missing, default to 0.
291
+
292
+ # Corrected input_semester default value handling:
293
+ def input_semester_corrected(semester_label, default_values=None):
294
+ with st.expander(f"📖 {semester_label}", expanded=True):
295
+ col1, col2 = st.columns(2)
296
+ with col1:
297
+ somon0thi = st.number_input("Số môn không thi", 0, value=default_values[0] if default_values and len(default_values) > 0 else 0, key=f"sm0_{semester_label}")
298
+ sotc0thi = st.number_input("Số tín chỉ không thi", 0, value=default_values[1] if default_values and len(default_values) > 1 else 0, key=f"tc0_{semester_label}")
299
+ sotcno = st.number_input("Số tín chỉ nợ", 0, value=default_values[2] if default_values and len(default_values) > 2 else 0, key=f"tcno_{semester_label}")
300
+ mhno = st.number_input("Số môn không đạt", 0, value=default_values[3] if default_values and len(default_values) > 3 else 0, key=f"mhno_{semester_label}")
301
+ # Assuming sotc_qua is the 5th value in the example data if 9 values exist
302
+ sotc_qua_default = default_values[4] if default_values and len(default_values) > 4 else 0
303
+ sotc_qua = st.number_input("Số tín chỉ qua môn", 0, value=sotc_qua_default, key=f"tcqua_{semester_label}")
304
+ with col2:
305
+ TCHK = st.number_input("Tổng tín chỉ học kỳ", 0, value=default_values[5] if default_values and len(default_values) > 5 else 0, key=f"tchk_{semester_label}")
306
+ smhk = st.number_input("Số môn học kỳ", 0, value=default_values[6] if default_values and len(default_values) > 6 else 0, key=f"smhk_{semester_label}")
307
+ mhpass = st.number_input("Số môn đạt", 0, value=default_values[7] if default_values and len(default_values) > 7 else 0, key=f"mhpass_{semester_label}")
308
+ TBCHK = st.number_input("GPA", 0.0, 10.0, value=default_values[8] if default_values and len(default_values) > 8 else 0.0, step=0.01, key=f"gpa_{semester_label}")
309
+ xep_loai_selected = st.selectbox("Xếp loại", list(range(7)), index=default_values[9] if default_values and len(default_values) > 9 else 0, key=f"xeploai_{semester_label}") # Assuming Xếp loại is the 10th value
310
+ return [somon0thi, sotc0thi, sotcno, mhno, sotc_qua, TCHK, smhk, mhpass, TBCHK, xep_loai_selected] # Return 10 values
311
+
312
+ # Let's update the example data structure to have 10 values per semester for consistency
313
+ # Based on the headers, the order should be: Số môn không thi, Số tín chỉ không thi, Số tín chỉ nợ, Số môn không đạt, Số tín chỉ qua môn, Tổng tín chỉ học kỳ, Số môn học kỳ, Số môn đạt, GPA, Xếp loại
314
+ # The original example data was [somon0thi, sotc0thi, sotcno, mhno, TCHK, smhk, mhpass, TBCHK, xep_loai_selected] -> 9 values
315
+ # It seems "Số tín chỉ qua môn" was missing or intended to be calculated.
316
+ # Let's assume "Số tín chỉ qua môn" is implicitly TCHK - sotcno.
317
+ # However, the headers list "Số tín chỉ qua môn" as a separate column.
318
+ # Let's assume the headers are correct and the example data needs to match the headers.
319
+ # Let's restructure example data to have 10 values, adding a plausible value for "Số tín chỉ qua môn" (TCHK - sotcno).
320
+
321
+ sample_cntt_example_full = {
322
+ "name": "Nguyễn Văn A",
323
+ "student_id": "10117367",
324
+ "major": "Công nghệ thông tin",
325
+ "semester_data": [
326
+ # HK1: sm0, tc0, tcno, mhno, tc_qua (calculated: TCHK-tcno), TCHK, smhk, mhpass, GPA, xeploai
327
+ 0, 0, 0, 0, 17-0, 17, 7, 7, 8.73, 0,
328
+ # HK2:
329
+ 0, 0, 0, 0, 17-0, 17, 7, 7, 8.19, 0,
330
+ # HK3:
331
+ 0, 0, 0, 0, 17-0, 17, 7, 7, 7.90, 0,
332
+ # HK4:
333
+ 0, 0, 0, 0, 17-0, 17, 7, 7, 8.19, 0,
334
+ # HK5:
335
+ 0, 0, 0, 0, 19-0, 19, 7, 6, 8.18, 0,
336
+ # HK6: tcno=5, mhno=2, TCHK=19, mhpass=6, xeploai=1. Assuming tc_qua = TCHK - tcno = 19-5 = 14
337
+ 0, 0, 5, 2, 19-5, 19, 7, 6, 7.10, 1
338
+ ]
339
+ }
340
+
341
+ sample_kinhte_example_full = {
342
+ "name": "Trần Thị C",
343
+ "student_id": "11418093",
344
+ "major": "Kinh tế",
345
+ "semester_data": [
346
+ # HK1:
347
+ 0, 0, 0, 0, 16-0, 16, 6, 6, 7.00, 1,
348
+ # HK2:
349
+ 0, 0, 0, 0, 18-0, 18, 7, 7, 8.20, 1,
350
+ # HK3:
351
+ 0, 0, 0, 0, 17-0, 17, 7, 7, 7.80, 1,
352
+ # HK4:
353
+ 0, 0, 0, 0, 17-0, 17, 7, 6, 7.90, 1,
354
+ # HK5:
355
+ 0, 0, 0, 0, 19-0, 19, 8, 5, 8.10, 0,
356
+ # HK6: tcno=8, mhno=2, TCHK=19, mhpass=6, xeploai=1. Assuming tc_qua = TCHK - tcno = 19-8 = 11
357
+ 0, 0, 8, 2, 19-8, 19, 7, 6, 7.30, 1
358
+ ]
359
+ }
360
+ # Now the example data for the full model should match the 10 inputs per semester.
361
+
362
  example_data = sample_cntt_example_full if sample_option == "Dùng ví dụ mẫu ngành Công nghệ thông tin" else sample_kinhte_example_full if sample_option == "Dùng ví dụ mẫu ngành Kinh tế" else None
363
+         default_values = example_data["semester_data"][idx*10:(idx+1)*10] if example_data else None # Slice 10 values
364
+         data += input_semester_corrected(sem, default_values) # Use the corrected function
365
+     nganh = 0 if major == "Công nghệ thông tin" else 1
366
+     final_features = np.array(data + [nganh]).reshape(1, -1)
367
 
368
+
369
+ # Mô hình 2: "Dùng đặc trưng quan trọng"
370
+ else: # model_type == "Dùng đặc trưng quan trọng"
371
      st.subheader("✨ Nhập thông tin rút gọn")
372
      
373
+     # Allow selecting an example
374
+     for idx, sem in enumerate(semesters):
375
+         example_data = sample_cntt_example_simple if sample_option == "Dùng ví dụ mẫu ngành Công nghệ thông tin" else sample_kinhte_example_simple if sample_option == "Dùng ví dụ mẫu ngành Kinh tế" else None
376
+         # Slice 3 values per semester for the simple model example data
377
+         default_values = example_data["semester_data"][idx*3:(idx+1)*3] if example_data else None 
378
+
379
+         # Use expander to group each semester's fields
380
+ with st.expander(f"📘 {sem}", expanded=True):
381
+ # Use 3 columns to align with the image layout for all semesters
382
+ col1, col2, col3 = st.columns(3)
383
+ with col1:
384
+ # Use consistent keys for input fields
385
+ sotc_qua = st.number_input("Số tín chỉ đạt", 0, value=default_values[0] if default_values and len(default_values) > 0 else 0, key=f"tcqua_imp_{sem}")
386
+ with col2:
387
+ sotcno = st.number_input("Số tín chỉ nợ", 0, value=default_values[1] if default_values and len(default_values) > 1 else 0, key=f"tcno_imp_{sem}")
388
+ with col3:
389
+ # Adjusted label to match the image: "Điểm trung bình hệ 10"
390
+ TBCHK = st.number_input("Điểm trung bình hệ 10", 0.0, 10.0, value=default_values[2] if default_values and len(default_values) > 2 else 0.0, step=0.01, key=f"gpa_imp_{sem}")
391
+
392
+         # Collect semester data (3 values per semester)
393
+         data += [sotc_qua, sotcno, TBCHK]  
394
+     
395
+     final_features = np.array(data).reshape(1, -1) # Should be 6 semesters * 3 features = 18 features
 
 
 
 
 
 
396
 
397
  # ===== Predict =====
398
  if st.button("🎯 DỰ BÁO"):
 
400
          prediction = model_full.predict(final_features)
401
          sheet_name = "Trang tính1"  # For full data model, save to Trang tính1
402
 
403
+     else: # model_type == "Dùng đặc trưng quan trọng"
404
          prediction = model_important.predict(final_features)
405
+         sheet_name = "Trang tính2"  # For important data model, save to Trang tính2
406
 
407
 
408
      if prediction[0] == 1: