Пример #1
0
def post(data):
    data = data.copy()
    if utils.get_DB(data.get("mat_no")):
        return "Student already exists"
    if not all([data.get(prop)
                for prop in required]) or (data.keys() - all_fields):
        # Empty value supplied or Invalid field supplied or Missing field present
        return "Invalid field supplied or missing a compulsory field"
    if ("grad_status" not in data) or data.get("session_grad") == 0:
        # Check exceptions to non required
        return "Invalid field supplied or missing a compulsory field"

    session_admitted = data['session_admitted']

    master_schema = MasterSchema()
    database = "{}-{}.db".format(session_admitted, session_admitted + 1)
    master_model = master_schema.load({
        'mat_no': data['mat_no'],
        'surname': data['surname'],
        'database': database
    })

    session = utils.load_session(session_admitted)
    personalinfo_schema = session.PersonalInfoSchema()
    data["is_symlink"] = data["mode_of_entry"] - 1
    data["level"] = abs(data["level"]) * [1, -1][data.pop("grad_status")]
    student_model = personalinfo_schema.load(data)

    db.session.add(master_model)
    db.session.commit()

    db_session = personalinfo_schema.Meta.sqla_session

    if data["mode_of_entry"] != 1:
        # Point from Symlink table
        # TODO use util fn to predict class DB for DE students
        session_list = loads(
            Props.query.filter_by(key="SessionList").first().valuestr)
        class_session = session_list[session_list.index(session_admitted) -
                                     data["mode_of_entry"] + 1]
        student_model.database = "{}-{}.db".format(class_session,
                                                   class_session + 1)
        symlink_session = utils.load_session(class_session)
        symlink_schema = symlink_session.SymLinkSchema()
        database = "{}-{}.db".format(session_admitted, session_admitted + 1)
        symlink_model = symlink_schema.load({
            "mat_no": data["mat_no"],
            "database": database
        })
        db_session_2 = symlink_schema.Meta.sqla_session
        db_session_2.add(symlink_model)
        db_session_2.commit()

    db_session.add(student_model)
    db_session.commit()
Пример #2
0
def get_students_details_by_category(level,
                                     entry_session,
                                     category=None,
                                     get_all=False):
    """
    Gets the details for students in `level` level as required by the senate version for
    non-graduating students

    If `get_all` is supplied, `category` is ignored

    :param level: level of students
    :param entry_session: entry session of students
    :param category: (Optional) category to fetch
    :param get_all: (Optional) if true return the details of all categories of students
    :return: list of dicts of the details students with all categories if `get_all` is true else
             list of dicts of the details students with `category` category
    """
    populate_course_list(level)

    students = get_students_by_category(level,
                                        entry_session,
                                        category=category,
                                        get_all=get_all)
    categories = get_categories()
    if get_all:
        students_details = {}
        for db_name in students.keys():
            session = load_session(db_name)
            for category in categories:
                dets = list(
                    map(
                        lambda stud: get_student_details_for_cat(
                            stud, level, session),
                        students[db_name][category]))
                if students_details.get(category):
                    students_details[category].extend(dets)
                else:
                    students_details[category] = dets
    else:
        students_details = []
        for db_name in students:
            session = load_session(db_name)
            dets = list(
                map(
                    lambda stud: get_student_details_for_cat(
                        stud, level, session), students[db_name]))
            students_details.extend(dets)

    return students_details
Пример #3
0
def patch(data, superuser=False):
    data = data.copy()
    session = utils.get_DB(data.get("mat_no"))
    if not session:
        return None, 404
    if not all([data.get(prop)
                for prop in (required & data.keys())]) or (data.keys() -
                                                           all_fields):
        # Empty value supplied or Invalid field supplied
        return "Invalid field supplied or missing a compulsory field", 400
    if data.get("session_grad") == 0:
        return "Invalid field supplied", 400

    session = utils.load_session(session)
    student = session.PersonalInfo.query.filter_by(mat_no=data["mat_no"])

    if superuser:
        level = abs(data.get("level", 0)) or abs(student.first().level)
        if "grad_status" in data:
            data["level"] = level * [1, -1][data.pop("grad_status")]
        elif "level" in data:
            # Preserve grad status
            data["level"] = level * [1, -1][student.first().grad_status]
    else:
        for prop in ("session_admitted", "session_grad", "level",
                     "mode_of_entry", "grad_status"):
            data.pop(prop, None)

    student.update(data)
    db_session = session.PersonalInfoSchema().Meta.sqla_session
    db_session.commit()
    return None, 200
Пример #4
0
def get(mat_no):
    db_name = utils.get_DB(mat_no)
    if not db_name:
        return None
    session = utils.load_session(db_name)
    student_data = session.PersonalInfo.query.filter_by(mat_no=mat_no).first()
    personal_info_obj = session.PersonalInfoSchema().dump(student_data)
    personal_info_obj['level'] = abs(personal_info_obj['level'])
    personal_info_obj.update({'grad_status': student_data.grad_status})
    return personal_info_obj
Пример #5
0
def get_cls_limits(cls, db_name=None, session=None):
    """
    Retrieves the lower and upper limit for `cls` graduating class designation

    :param cls: graduating class designation
    :param db_name: name of the database file of the graduating students
    :param session: session module of the graduating students
    :return: list of the lower and upper limits for the `cls` class designation
    """
    if not session:
        session = load_session(db_name)
    limits = session.DegreeClass.query.filter_by(
        cls=class_mapping[cls]).first().limits
    return list(map(float, limits.split(',')))
Пример #6
0
def rule_2_3():
    bad_mat_1 = set()
    bad_mat_2 = set()
    for session in range(start, stop):
        sess = utils.load_session(session)
        mats = [x.mat_no for x in sess.PersonalInfo.query.all()]
        for mat_no in mats:
            # print(mat_no)
            catg = result_statement.get(mat_no)["categories"]
            if catg.count("C") > 1:
                bad_mat_1.add(mat_no)
            d_idx = (catg + ["D"]).index("D")
            if (catg + ["D"])[d_idx + 1:]:
                bad_mat_2.add(mat_no)
    print("Rule 2 defaulters\n", bad_mat_1)
    print("Rule 3 defaulters\n", bad_mat_2)
Пример #7
0
def delete_course_reg_entry(mat_no, acad_session):
    course_reg = course_reg_utils.course_reg_for_session(mat_no, acad_session)
    if not course_reg:
        return 'Course Registration for session {}/{} does not exist'.format(acad_session, acad_session+1), 404

    session = utils.load_session(utils.get_DB(mat_no))
    courses_reg_schema = getattr(session, course_reg['table'] + 'Schema')
    # TODO reset optional course in personal info if set here

    courses_reg = courses_reg_schema.Meta.model.query.filter_by(mat_no=mat_no).first()
    db_session = courses_reg_schema.Meta.sqla_session
    db_session.delete(courses_reg)
    db_session.commit()
    db_session.close()

    return 'Record Deleted Successfully', 200
Пример #8
0
def update_gpa_credits(mat_no, grade, previous_grade, course_credit,
                       course_level):
    gpa_credits = utils.gpa_credits_poll(mat_no)[:-1]
    index = utils.ltoi(course_level)
    level_gpa = gpa_credits[index][0] if gpa_credits[index][0] else 0
    level_credits_passed = gpa_credits[index][1] if gpa_credits[index][1] else 0

    if grade != previous_grade:
        creds = utils.get_credits(mat_no, lpad=True)
        level_credits = creds[index]
        grading_point_rule = utils.get_grading_point(utils.get_DB(mat_no))
        grading_point = grading_point_rule[grade]
        grading_point_old = grading_point_rule[
            previous_grade] if previous_grade else 0

        diff = grading_point - grading_point_old
        level_gpa = level_gpa + ((course_credit * diff) / level_credits)

        sign_multiplier = diff // abs(diff) if diff != 0 else 0
        level_credits_passed += course_credit * sign_multiplier

    gpa_credits[index] = (round(level_gpa, 4), level_credits_passed)
    cgpa = 0
    mode_of_entry = personal_info.get(mat_no)['mode_of_entry']
    weights = utils.get_level_weightings(mode_of_entry)

    for idx in range(len(weights)):
        cgpa += weights[idx] * gpa_credits[idx][0] if gpa_credits[
            idx] and gpa_credits[idx][0] else 0

    gpa_record = {'mat_no': mat_no, 'cgpa': round(cgpa, 4)}
    for key, idx in [('level{}00'.format(lev + 1), lev) for lev in range(5)]:
        gpa_record.update({
            key:
            ','.join(list(map(str, gpa_credits[idx])))
            if gpa_credits[idx][0] else None
        })

    session = utils.load_session(utils.get_DB(mat_no))
    gpa_record = session.GPACreditsSchema().load(gpa_record)
    db_session = session.GPACreditsSchema().Meta.sqla_session
    db_session.add(gpa_record)
    db_session.commit()
    db_session.close()
    return 'Success'
Пример #9
0
def filter_students_by_category(level, category, db_name, students):
    """
    Strips and returns students with category `category` from a list of students

    :param level: level of the students
    :param category: category to match students against
    :param db_name: name of the database file of the students
    :param students: list of students
    :return: list of students with ctagory `category`
    """
    session = load_session(db_name)
    res_obj = getattr(session, 'Result{}'.format(level))
    studs = []
    for mat_no in students:
        stud = res_obj.query.filter_by(mat_no=mat_no).first()
        if stud:
            if stud.category == category:
                studs.append(mat_no)

    return studs
Пример #10
0
def rule_1_4():
    bad_mat_1 = set()
    bad_mat_2 = set()
    for session in range(start, stop):
        sess = utils.load_session(session)
        mats = [x.mat_no for x in sess.PersonalInfo.query.all()]
        for mat_no in mats:
            person = personal_info.get(mat_no)
            mode_of_entry = person["mode_of_entry"]
            results = result_statement.get(mat_no)["results"]
            for result in results:
                for record in result["first_sem"] + result["second_sem"]:
                    rec_crs_lvl = crs_lvl[mode_of_entry][record[0]]
                    if rec_crs_lvl // 100 < mode_of_entry:
                        bad_mat_1.add(mat_no)
                    if rec_crs_lvl > result["level"]:
                        bad_mat_2.add(mat_no)

    print("Rule 1 defaulters\n", bad_mat_1)
    print("Rule 4 defaulters\n", bad_mat_2)
Пример #11
0
def get_students_by_category(level,
                             entry_session,
                             category=None,
                             get_all=False):
    """
    Gets all students within a category

    If `get_all` is supplied, `category` is ignored

    :param level: level of students
    :param entry_session: entry session of students
    :param category: (Optional) category to fetch
    :param get_all: (Optional) if True return all categories of students
    :return: list of students if not `get_all` else dictionary of all category mapping to list of students
    """
    mat_no_dict = get_students_by_level(entry_session, level, retDB=True)
    acad_session = get_session_from_level(entry_session, level)
    if get_all:
        students = dict.fromkeys(mat_no_dict)
        categories = get_categories(final_year=(level == 500))

        cat_dict = dict(zip(categories, [[]] * len(categories)))
        for db_name in mat_no_dict:
            students[db_name] = cat_dict.copy()
            session = load_session(db_name)
            for mat_no in mat_no_dict[db_name]:
                # level = level if level != 500 else get_level(mat_no)  # Accounts for spillover students
                cat = get_category(mat_no, level, acad_session, session)
                if students[db_name].get(cat):
                    students[db_name][cat].append(mat_no)
                else:
                    students[db_name][cat] = [mat_no]
    else:
        students = dict.fromkeys(mat_no_dict)
        for db_name in mat_no_dict:
            filtered_studs = filter_students_by_category(
                level, category, db_name, mat_no_dict[db_name])
            students[db_name] = filtered_studs

    return students
Пример #12
0
def filter_students_by_degree_class(degree_class, db_name, students):
    """
    Strips and returns the details of students with `degree_class` graduating class
    designation from the list of students

    :param degree_class: graduating class designation
    :param db_name: name of the database file of the graduating students
    :param students: list of graduating students
    :return: list of dicts of graduating students
    """
    session = load_session(db_name)
    limits = get_cls_limits(degree_class, session=session)
    cgpa_obj = getattr(session, 'GPA_Credits')
    studs = []
    for stud in students:
        cgpa = cgpa_obj.query.filter_by(mat_no=stud).first().cgpa
        if limits[0] <= cgpa <= limits[1]:
            details = get_student_details_for_cls(stud, session)
            details['cgpa'] = float(cgpa)
            studs.append(details)
            students.remove(stud)

    return studs
Пример #13
0
def delete(mat_no):
    session = utils.get_DB(mat_no)
    if not session:
        return None, 404
    session = utils.load_session(session)
    entries = []
    db_session = session.PersonalInfoSchema().Meta.sqla_session
    entries.append(session.PersonalInfo.query.filter_by(mat_no=mat_no).first())
    entries.append(session.GPA_Credits.query.filter_by(mat_no=mat_no).first())
    for lvl in range(100, 900, 100):
        entries.append(
            eval("session.CourseReg{}".format(lvl)).query.filter_by(
                mat_no=mat_no).first())
        entries.append(
            eval("session.Result{}".format(lvl)).query.filter_by(
                mat_no=mat_no).first())
    for entry in entries:
        if entry:
            db_session.delete(entry)
    master = Master.query.filter_by(mat_no=mat_no).first()
    db.session.delete(master)
    db_session.commit()
    db.session.commit()
    return None, 200
Пример #14
0
def post_course_reg(data):
    level_options = course_reg_utils.get_optional_courses(data['course_reg_level'])
    level_options = utils.dictify(level_options[0] + level_options[1])
    courses, person_options = [], []
    tcr = [0, 0]
    for idx, sem in enumerate(['first_sem', 'second_sem']):
        for course_obj in data['courses'][sem]:
            courses.append(course_obj[0])
            tcr[idx] += course_obj[2]
            if course_obj[0] in level_options:
                person_options.append('{} {}'.format(idx+1, course_obj[0]))
    courses = sorted(courses)
    mat_no = data['mat_no']
    table_to_populate = data['table_to_populate']
    course_reg_session = data['course_reg_session']

    session = utils.load_session(utils.get_DB(mat_no))
    course_reg_xxx_schema = getattr(session, table_to_populate + 'Schema')()
    table_columns = course_reg_xxx_schema.load_fields.keys()
    registration = {}
    for col in table_columns:
        if col in courses:
            registration[col] = '1'
            courses.remove(col)
        elif col not in ['carryovers', 'mat_no', 'tcr', 'level', 'session', 'probation', 'fees_status', 'others']:
            registration[col] = '0'
    registration.update({
        'carryovers': ','.join(courses),
        'mat_no': mat_no,
        'tcr': sum(tcr),
        'level': data['course_reg_level'],
        'session': course_reg_session,
        'probation': data['probation_status'],
        'fees_status': data['fees_status'],
        'others': data['others']
    })
    course_registration = course_reg_xxx_schema.load(registration)
    db_session = course_reg_xxx_schema.Meta.sqla_session

    if person_options:
        person = session.PersonalInfo.query.filter_by(mat_no=mat_no).first()
        person.option = ','.join(person_options)
        db_session.add(person)

    db_session.add(course_registration)
    db_session.commit()
    db_session.close()

    success_text = 'course registration successful'

    # Here we check if there were any stray results waiting in unusual results for this session
    session_results = [x for x in utils.result_poll(mat_no) if x and (x['session'] == course_reg_session)]
    if session_results and ('unusual_results' in session_results[0]) and session_results[0]['unusual_results']:
        unusual_results = [utils.spc_fn(x) for x in utils.csv_fn(session_results[0]['carryovers'])]
        unusual_results = [[x[0], course_reg_session, mat_no, x[1]] for x in unusual_results]
        log = results.add_result_records(unusual_results)

        if log[0]: success_text += '; results for unregistered courses still remain in database'

    print('\n====>>  ', success_text)
    return success_text, 200
Пример #15
0
def get_final_year_students_by_category(entry_session,
                                        category=None,
                                        get_all=False):
    """
    Gets the details for students required by the senate version for graduating students

    If `get_all` is supplied, `category` is ignored

    :param entry_session: entry session of students
    :param category: (Optional) category to fetch
    :param get_all: (Optional) if true return the details of all categories of students
    :return: list of dicts of the details students with all categories if `get_all` is true else
             list of dicts of the details students with `category` category
    """
    populate_course_list(500)

    students_categories = get_students_by_category(500,
                                                   entry_session,
                                                   category=category,
                                                   get_all=get_all)
    all_students_by_category = group_students_by_category(students_categories)
    if get_all:
        all_students = {}

        # Successful students
        successful_students = all_students_by_category.pop(
            'successful students')
        students = {}
        classes = class_mapping.keys()
        for degree_class in classes:
            studs = []
            for db_name in successful_students:
                studs.extend(
                    filter_students_by_degree_class(
                        degree_class, db_name, successful_students[db_name]))
            students[degree_class] = studs
        all_students['successful students'] = students

        # Referred students
        referred_students = all_students_by_category.pop('carryover students')
        studs = []
        for db_name in referred_students:
            session = load_session(db_name)
            studs.extend(
                list(
                    map(
                        lambda mat_no: get_details_for_ref_students(
                            mat_no, session), referred_students[db_name])))
        all_students['referred students'] = studs

        # Other students
        for group in all_students_by_category:
            studs, other_students = [], all_students_by_category[group]
            for db_name in other_students:
                session = load_session(db_name)
                studs.extend(
                    list(
                        map(
                            lambda mat_no: get_other_students_details(
                                mat_no, session, group),
                            other_students[db_name])))
            all_students[group] = studs

        return all_students
Пример #16
0
def add_single_result_record(index,
                             result_details,
                             result_errors_file,
                             course_details_dict,
                             level=None):
    """
    :param index: position of entry in the larger list --for tracking
    :param result_details: [course_code, session_written, mat_no, score]
    :param result_errors_file: file object in write or append mode for logging important errors
    :param course_details_dict:
    :param level: student's course-adviser assigned level
    """
    error_log = []
    try:
        course_code, session_taken, mat_no, score = result_details
        session_taken, score = map(int, [session_taken, score])
        entry_session = utils.get_DB(mat_no)
    except:
        return handle_errors('Invalid inputs at index {}'.format(index),
                             error_log, result_errors_file, result_details)

    grade = utils.compute_grade(score, entry_session)
    current_level = utils.get_level(mat_no)

    # Error check on level, grade and score
    error_text = ''
    if level:
        levels = [600, 700, 800] if level == 600 else [level]
        if current_level not in levels:
            error_text = "You are not allowed to enter results for {} at index {} whose current level is " \
                         "{}".format(mat_no, index, current_level)
    if not (-1 <= score <= 100) and not error_text:
        error_text = 'Unexpected score for {}, "{}", for {} at index {}; ' \
                     'result not added'.format(course_code, score, mat_no, index)
    if not grade and not error_text:
        error_text = '{0} at index {1} was not found in the database'.format(
            mat_no, index)
    if error_text:
        return handle_errors(error_text, error_log, result_errors_file,
                             result_details)

    # Get course details
    if course_code in course_details_dict and course_details_dict[course_code]:
        course_dets = course_details_dict[course_code]
    else:
        # if there was error in initializing course_details_dict, individual calls would be made
        course_dets = course_details.get(course_code)
        if not course_dets:
            # fail on non-existent course(s)
            error_text = '{} at index {} was not found in the database'.format(
                course_code, index)
            return handle_errors(error_text, error_log, result_errors_file,
                                 result_details)

    course_credit = course_dets['credit']
    course_level = course_dets['level']
    is_unusual = False

    # Get course reg
    course_registration = course_reg_for_session(mat_no, session_taken) or {
        'level': current_level,
        'courses': []
    }
    courses_registered = course_registration['courses']
    level_written = course_registration['level']
    if not courses_registered:
        is_unusual = True
        error_log = handle_errors(
            'No course registration found for {0} at index {1} for the {2}/{3} '
            'session'.format(mat_no, index, session_taken, session_taken + 1),
            error_log)
    elif course_code not in courses_registered:
        is_unusual = True
        error_log = handle_errors(
            '{0} at index {1} did not register {2} in the {3}/{4} session'
            ''.format(mat_no, index, course_code, session_taken,
                      session_taken + 1), error_log)

    # Get the result table for the session
    res_poll = utils.result_poll(mat_no)
    result_record, table_to_populate = res_poll_for_session(
        session_taken, res_poll)
    session = utils.load_session(utils.get_DB(mat_no))
    if not result_record:
        if is_unusual and grade == 'ABS':
            return handle_errors(
                'Unregistered course {} with grade "ABS" cannot be added for '
                '{}'.format(course_code, mat_no), error_log)
        table_to_populate = get_table_to_populate(course_registration,
                                                  res_poll)
        result_xxx_schema = getattr(session, table_to_populate + 'Schema')()
        params = mat_no, session_taken, courses_registered, result_xxx_schema, level_written
        result_record = prepare_new_results_table(params)
    else:
        result_xxx_schema = getattr(session, table_to_populate + 'Schema')()

    # Check if a previous entry for the course exists in the current session and updates the value
    # of "previous_grade" while logging the changes to be made
    previous_grade = get_previous_grade_and_log_changes(
        result_details, result_record, is_unusual)

    # add score to result object
    if is_unusual or result_record['unusual_results']:
        unusual_results = result_record['unusual_results'].split(',')
        index = [
            ind for ind, x in enumerate(unusual_results)
            if x.split(' ')[0] == course_code
        ]
        if index: unusual_results.pop(index[0])
        if is_unusual and grade != "ABS":
            unusual_results.append('{} {} {}'.format(course_code, score,
                                                     grade))
        while '' in unusual_results:
            unusual_results.remove('')
        result_record['unusual_results'] = ','.join(unusual_results)
    if not is_unusual:
        if course_code in result_record:
            result_record[course_code] = '{},{}'.format(score, grade)
        else:
            carryovers = result_record['carryovers'].split(
                ',') if result_record['carryovers'] else ['']
            index = [
                ind for ind, x in enumerate(carryovers)
                if x.split(' ')[0] == course_code
            ]
            if index: carryovers.pop(index[0])
            carryovers.append('{} {} {}'.format(course_code, score, grade))
            while '' in carryovers:
                carryovers.remove('')
            result_record['carryovers'] = ','.join(carryovers)

    # get the session category
    owed_courses_exist = check_owed_courses_exists(
        mat_no, level_written, grade, course_dets) if not is_unusual else True
    if not courses_registered:
        tcr, tcp = 0, 0
    else:
        if grade not in ['F', 'ABS'] and previous_grade in [
                'F', 'ABS', ''
        ] and not is_unusual:
            result_record['tcp'] += course_credit
        elif grade in ['F', 'ABS'] and previous_grade not in [
                'F', 'ABS', ''
        ] and not is_unusual:
            result_record['tcp'] -= course_credit
        tcr, tcp = course_registration['tcr'], result_record['tcp']

    res_record = result_xxx_schema.load(result_record)
    res_record.category = utils.compute_category(tcr, res_record,
                                                 owed_courses_exist)

    db_session = result_xxx_schema.Meta.sqla_session
    db_session.add(res_record)
    if grade == 'ABS':
        delete_if_empty(res_record, result_xxx_schema)
    db_session.commit()
    db_session.close()

    # update GPA - Credits table
    if not is_unusual:
        update_gpa_credits(mat_no, grade, previous_grade, course_credit,
                           course_level)

    return error_log
Пример #17
0
def get_students_by_level(entry_session,
                          level,
                          is_course_adviser=False,
                          retDB=False):
    """
    Gets all the mat numbers of students in a particular db

    This only includes the regular students that entered during the `entry_session` session, DE and probating students
    that somehow have ties to this db.

    :param entry_session: entry session
    :param level: level of students
    :param is_course_adviser: if true returns the students associated with the level course adviser
    :param retDB: if True, returns a dict
    :return: list of mat numbers if not `retDB` else a dictionary of db name being mapped to a list of mat numbers
    """
    entry_session_db_name = '{}_{}'.format(entry_session, entry_session + 1)
    session = load_session(entry_session_db_name)

    # Regular students
    if level > 500 and is_course_adviser:
        students = []
    else:
        students = session.PersonalInfo.query.filter_by(
            is_symlink=0).filter_by(mode_of_entry=1).all()
    if retDB:
        students = {
            entry_session_db_name: list(map(lambda stud: stud.mat_no,
                                            students))
        }
    else:
        students = list(map(lambda stud: stud.mat_no, students))

    level_num = level // 100
    other_students = session.SymLink.query.filter(getattr(session.SymLink, f'database_{level_num}') != None)\
        .order_by(f'DATABASE_{level_num}').all()    # DE and probating students

    # Spillover students
    if level_num == 5 and not is_course_adviser:
        for num in range(6, 9):
            other_students.extend(
                session.SymLink.query.filter(
                    getattr(session.SymLink, f'database_{num}') != None).
                order_by(f'DATABASE_{num}').all())
    elif level_num > 5 and is_course_adviser:
        for num in range(7, 9):
            other_students.extend(
                session.SymLink.query.filter(
                    getattr(session.SymLink, f'database_{num}') != None).
                order_by(f'DATABASE_{num}').all())
    if retDB:
        # groups the students by their database name
        stud_db_map, num = {}, [5, 6][is_course_adviser]
        for stud in other_students:
            if level_num == [5, 6][is_course_adviser]:
                try:
                    db = getattr(stud, f'database_{num}')
                    assert db is not None
                    db_name = db[:-3].replace('-', '_')
                except AssertionError:
                    num += 1
                    db_name = getattr(stud, f'database_{num}')[:-3].replace(
                        '-', '_')
            else:
                db_name = getattr(stud, f'database_{level_num}')[:-3].replace(
                    '-', '_')
            try:
                stud_db_map[db_name].append(stud.mat_no)
            except KeyError:
                stud_db_map[db_name] = [stud.mat_no]
        if entry_session_db_name in stud_db_map:
            de_probating_students = stud_db_map.pop(entry_session_db_name)
            students[entry_session_db_name].extend(de_probating_students)
        students.update(stud_db_map)
    else:
        other_students = list(map(lambda stud: stud.mat_no, other_students))
        students.extend(other_students)

    return students