def calculate_student_gpa(student, method='update'): """ :param student: :param method: ['update', 'reevaluation'] :return: """ update = 0 create = 0 student_grade = mainModel.Transcript.objects.filter(student=student).values_list('semester_id', 'course_id', 'course__credit', 'grade') if len(student_grade) <= 0: return update, create if method in ['update', 'reevaluation']: student_grade = np.array([list(grade) for grade in student_grade]) student_grade = student_grade[student_grade[:, 0].argsort()] sem_list = np.unique(student_grade[:, 0]) if method == 'update': exist_gpa = mainModel.GPA.objects.filter(student=student) exist_sem = exist_gpa.values_list('semester', flat=True) sem_list = [sem for sem in sem_list if sem not in exist_sem] del exist_gpa, exist_sem if len(sem_list) > 0: begin_semester_id = mainModel.Semesters.objects.filter(year_id=student.group.generation.beginningYear_id).first().pk for sem in sem_list: # calculate semesterGpa, GPA in one semester sem_data = student_grade[student_grade[:, 0] == sem] sem_grade = sem_data[:, 3] sem_credit = sem_data[:, 2] sem_gpa = round(np.sum(sem_grade * sem_credit) / sum(sem_credit), 2) # calculate currentGpa, GPA from fist semester to this semester course_set = set([]) gpa = 0 total_credit = 0 for sem_id, cou, credit, grade in student_grade[::-1]: if sem_id <= sem and cou not in course_set: gpa += grade*credit total_credit += credit course_set.add(cou) current_gpa = round(gpa / total_credit, 2) semesterRank = mainModel.semester_rank(current_semester_id=sem, semester_id=begin_semester_id) obj, created = mainModel.GPA.objects.update_or_create(student=student, semester_id=sem, defaults={"semesterRank": semesterRank, "semesterGpa": sem_gpa, "currentGpa": current_gpa}) if created: create += 1 else: update += 1 return update, create
def course_recommend(request, profile_id, method='greatest', k=5): """Gợi ý các môn học cho sinh viên trong kỳ học tới :param request: :param profile_id: :param method: greatest | similar :param k: :return: """ global MODEL # todo: đề xuất các môn học mặc định try: student = mainModel.Profiles.objects.get(pk=profile_id) except Exception: return Response({"error": "course_id don't exist"}) # Lấy các môn học có thể học trong kỳ này current_semester = mainModel.get_current_semester() semester_rank = mainModel.semester_rank( group_id=student.group_id, current_semester_id=current_semester.pk) course_can_learn = mainModel.Major_Course.objects.filter( major_id=student.major_id, semesterRecommended=semester_rank + 1) course_can_learn = course_can_learn.values_list('course_id', flat=True) if method == 'greatest': recommend_course_id = greatest_scoreCR(student, course_can_learn, k) else: recommend_course_id = similar_neighborCR(student, course_can_learn, k, 'pearson') recommended_course = mainModel.Courses.objects.filter( courseID__in=recommend_course_id) try: recommend_semester = mainModel.Semesters.objects.get( pk=current_semester.pk + 1).semesterName except Exception as e: recommend_semester = "" result = { "student_id": profile_id, "recommend_semester_id": recommend_semester, "course_recommend": {course: {} for course in recommend_course_id} } for course in recommended_course: result["course_recommend"][course.pk] = { "course_code": course.courseCode, "course_name": course.courseName, "credit": course.credit } return Response(result)
def extract_transcript_file(request): """ Extract file điểm csv """ if checkInUrl(request, 'learningoutcome') is False: listFunction = request.user.list_function() return HttpResponseRedirect(reverse(listFunction[0])) file_id = request.POST['file_id'] transcript_file = DBModel.TranscriptFiles.objects.get(pk=file_id) extraction = DataExtraction() try: extraction.loadData(settings.MEDIA_ROOT + '/' + transcript_file.transcript.name) except Exception as e: print("error: learningoutcome.py line 40: ", e) return False # format student info DataFrame studentInfo = extraction.getStudentInfo() studentInfo['birth'] = pd.to_datetime(studentInfo['birth']) # studentInfo = studentInfo.loc[:, ['gender', 'birth']].reset_index() # studentInfo['group'] = stg # studentInfo.columns = ['MSSV', 'gender', 'birthday', 'group'] # DBModel.create_from_DF(studentInfo, DBModel.Profiles, searching_cols=['MSSV', 'group']) # format course info DataFrame courseInfo = extraction.getCourse() courseInfo.columns = ['courseCode', 'courseName', 'credit'] courseInfo['unit_id'] = transcript_file.group.generation.unit_id # check and create course try: course_obj_list = DBModel.create_from_DF( courseInfo, DBModel.Courses, searching_cols=['courseCode', 'unit_id']) recommend_semester = DBModel.semester_rank( group_id=transcript_file.group_id, current_semester_id=transcript_file.semester_id) + 1 for cou in course_obj_list: DBModel.Major_Course.objects.get_or_create( course_id=cou.pk, major_id=transcript_file.major_id, defaults={"semesterRecommended": recommend_semester}) del recommend_semester except Exception as e: print(e) return False course_dict = {cou.courseCode: cou.pk for cou in course_obj_list} stu_grade = extraction.getTranscript() try: for i, row in stu_grade.iterrows(): # check and create student name_arr = studentInfo.loc[i, 'name'].strip().split(' ') first_name = name_arr[-1] last_name = ' '.join(name_arr[:-1]) stu, created = DBModel.Profiles.objects.get_or_create( MSSV=i, group_id=transcript_file.group_id, defaults={ 'gender': studentInfo.loc[i, 'gender'], 'firstName': first_name, 'lastName': last_name, 'birthday': studentInfo.loc[i, 'birth'], 'major_id': transcript_file.major_id }) del name_arr, first_name, last_name # check and create grade in transcript for course_code, grade in row.items(): if ~np.isnan(grade): # print("not nan", grade) DBModel.Transcript.objects.update_or_create( course_id=course_dict[course_code], student=stu, semester_id=transcript_file.semester_id, defaults={'grade': round(grade, 2)}) # update gpa calculate_student_gpa(stu, 'update') except Exception as e: print("ERROR ", e.__dir__(), "\n", e) return False transcript_file.extracted = True transcript_file.save() return True
def predict_grade_generation(request, major_id): """Predict grade for all students in a generation with a specify major, base on student grade and recommend semester of course Dự đoán điểm cho tất cẩ sinh viên thuộc cùng một khóa trong cùng chuyên ngành, dự đoán dựa vào điểm đã có của sinh viên và kỳ học được đề xuất của các môn học POST: Dự đoán điểm theo khóa học và trả về số lượng điểm đã dự đoán POST url: /model_data/<int:major_id>/ Media type: application/x-www-form-urlencoded POST body: generation_id: lặp lại, ứng với khóa học sẽ được sử dụng dữ liệu điểm làm dữ liệu huấn luyện e.g: generation_id=2;generation_id=3; :param request: :param major_id: int type, là id chuyên ngành của các sinh viên :return: """ current_semester = mainModel.get_current_semester() # current_semester = mainModel.Semesters.objects.get(pk=3) list_generation_id = list(map(int, request.POST.getlist('generation_id'))) generations = [] for generation_id in list_generation_id: semester_rank = mainModel.semester_rank( generation_id=generation_id, current_semester_id=current_semester.pk) if semester_rank is None: # go to next generation continue course_id_list = mainModel.Major_Course.objects.filter( major_id=major_id, semesterRecommended=semester_rank).values_list('course_id', flat=True) student_list = mainModel.Profiles.objects.filter( major_id=major_id, group__generation_id=generation_id) try: fit_model(major_id=major_id) except Exception as e: Response({"error": e}) total_delete = 0 total_predict = 0 for student in student_list: delete_num, model = mainModel.GradePredicted.objects.filter( student=student).delete() total_delete += delete_num # not need predict_list = predict_grade(student, current_semester, course_id_list, fitting=False, save_history=True) total_predict += len(predict_list) generations.append({ "id": generation_id, "deleted": total_delete, "predicted": total_predict, }) result = {"major_id": major_id, "generations": generations} print('oke', list_generation_id) return Response(result)
def predict_grade(student, semester=None, course_id_list: list = None, fitting: bool = True, save_history: bool = True): """ :param student: Profile Model, một đối tượng Profile :param semester: Semester Model, một đối tượng Semester :param course_id_list: a list or a query set of Courses Model, một danh sách đối tượng Courses :param fitting: bool type, decide to fit MODEL with new major train data or not, biến quyết định xem có đổi train data của MODEL hay giữ nguyên train data của lần dự trước. Cần fitting lại khi thay đổi chuyên ngành so với lần dự đoán trước :param save_history: bool type, decide to save the predict result to PredictHistory table or not, biến quyết định xem có lưu lại kết quả dự đoán vào PredictHistory hay không :return: """ global MODEL global MAJOR_ID # checking and fit MODEL if fitting or MAJOR_ID is None or MAJOR_ID != student.major_id: try: fit_model(major_id=student.major_id) except Exception as e: Response({"error": e}) # kiểm tra course_id_list if course_id_list is None or len(course_id_list) < 1: if semester is None: semester = mainModel.get_current_semester() semester_rank = mainModel.semester_rank( group_id=student.group_id, current_semester_id=semester.pk) course_id_list = mainModel.Major_Course.objects.filter( major_id=student.major_id, semesterRecommended=semester_rank).values_list('course_id', flat=True) del semester_rank student_grade = student_grade_to_DF(student_id=student.pk) course_id_list = list(set(course_id_list) - set(student_grade.columns)) if len(course_id_list) < 1: return [] # Dự đoán điểm predict_df = MODEL.predict(student_grade, course_id_list) predict_df = predict_df.iloc[0, :].dropna() # lưu điểm dự đoán vào DB grade_predicted_list = [] for course_id, grade in predict_df.items(): grade_predicted, created = mainModel.GradePredicted.objects.update_or_create( student=student, course_id=course_id, defaults={'grade': round(grade, 2)}) grade_predicted_list.append(grade_predicted) if save_history: if semester is None: semester = mainModel.get_current_semester() for course_id, grade in predict_df.items(): mainModel.PredictHistory.objects.create(student=student, course_id=course_id, grade=round(grade, 2), semester=semester) return grade_predicted_list