Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #4
0
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)
Beispiel #5
0
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