Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 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,
|
| 144 |
-
0, 0, 0, 0, 17, 7, 7, 8.19, 0,
|
| 145 |
-
0, 0, 0, 0, 17, 7, 7, 7.90, 0,
|
| 146 |
-
0, 0, 0, 0, 17, 7, 7, 8.19, 0,
|
| 147 |
-
0, 0, 0, 0, 19, 7, 6, 8.18, 0,
|
| 148 |
-
0, 0, 5, 2, 19, 7, 5, 7.10, 1
|
| 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,
|
| 191 |
-
0, 0, 0, 0, 18, 7, 7, 8.20, 1,
|
| 192 |
-
0, 0, 0, 0, 17, 7, 7, 7.80, 1,
|
| 193 |
-
0, 0, 0, 0, 17, 7, 6, 7.90, 1,
|
| 194 |
-
0, 0, 0, 0, 19, 8, 5, 8.10, 0,
|
| 195 |
-
0, 0, 8, 2, 19, 7, 6, 7.30, 1
|
| 196 |
]
|
| 197 |
}
|
| 198 |
|
| 199 |
-
|
| 200 |
# ===== Thông tin cá nhân =====
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
if
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 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
|
| 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
|
| 241 |
-
sotc0thi = st.number_input("Số tín chỉ không thi", 0, value=default_values[1] if default_values
|
| 242 |
-
sotcno = st.number_input("Số tín chỉ nợ", 0, value=default_values[2] if default_values
|
| 243 |
-
mhno = st.number_input("Số môn không đạt", 0, value=default_values[3] if default_values
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
default_tc_qua =
|
| 248 |
-
|
| 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
|
| 252 |
-
smhk = st.number_input("Số môn học kỳ", 0, value=default_values[5] if default_values
|
| 253 |
-
mhpass = st.number_input("Số môn đạt", 0, value=default_values[6] if default_values
|
| 254 |
-
TBCHK = st.number_input("GPA", 0.0, 10.0, value=default_values[7] if default_values
|
| 255 |
-
xep_loai_selected = st.selectbox("Xếp loại", list(range(7)), index=default_values[8] if default_values
|
| 256 |
-
|
| 257 |
-
|
| 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ộ
|
| 265 |
if model_type == "Dùng toàn bộ đặc trưng":
|
| 266 |
-
|
| 267 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
| 273 |
|
| 274 |
-
|
| 275 |
-
|
|
|
|
| 276 |
st.subheader("✨ Nhập thông tin rút gọn")
|
| 277 |
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
|
| 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
|
| 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 ví 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ọ và 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("🎓 Mã 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:
|