def get_details_for_ref_students(mat_no, session): """ Gets the details of a student with mat_no `mat_no` as required by the referred students section of the 500 level senate version :param mat_no: mat number of student :param session: session module object for student :return: dict containing the student details """ student = session.PersonalInfo.query.filter_by(mat_no=mat_no).first() name = student.othernames + ' ' + '<b>{}</b>'.format(student.surname) name += ' (Miss)' if student.sex == 'F' else '' level = get_level(mat_no) try: session_failed_courses = get_session_failed_courses( mat_no, level, session) credits_passed_list = list(zip(*gpa_credits_poll(mat_no)[:-1]))[1] total_credits_passed = sum(filter(lambda x: x, credits_passed_list)) total_credits = sum( get_credits(mat_no, session=session.__name__[12:16])) except AttributeError: # Students who didn't register or sit for the exam session_failed_courses = [] total_credits_passed = 0 total_credits = 0 # KeyError for the utils.get_carryovers function carryovers_dict = get_carryovers(mat_no, next_level=True) carryovers_credits = carryovers_dict['first_sem'] + carryovers_dict[ 'second_sem'] overall_carryover_courses = list(map(lambda x: x[0], carryovers_credits)) outstanding_courses = [] for course_code in overall_carryover_courses: if course_code not in session_failed_courses: outstanding_courses.append(course_code) details = { 'mat_no': mat_no, 'name': name, 'session_carryover_courses': ' '.join(session_failed_courses), 'cum_credits_to_date': total_credits_passed, 'outstanding_credits': total_credits - total_credits_passed, 'outstanding_courses': ' '.join(outstanding_courses) } return details
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'
def get_students_details(students, entry_session): students_details_dict = dict.fromkeys(students) for db_name in students: for mat_no in students[db_name]: bio = personal_info.get(mat_no) name = bio['othernames'] + ' ' + bio['surname'] name += ' (Miss)' if bio['sex'] == 'F' else '' *gpa_credits, cgpa = gpa_credits_poll(mat_no) details = { 'mat_no': mat_no, 'name': name, 'gpas': list(zip(*gpa_credits))[0], 'cgpa': float(cgpa) } if students_details_dict.get(db_name): students_details_dict[db_name].append(details) else: students_details_dict[db_name] = [details] ordinary_students = [] spillover_students = [] for db_name in students_details_dict: details = students_details_dict[db_name] if int(db_name[:4]) >= entry_session and details: ordinary_students.extend(details) elif details: spillover_students.extend(details) ordinary_students_details = sorted(ordinary_students, key=lambda x: x['cgpa'], reverse=True) spillover_students_details = sorted(spillover_students, key=lambda x: x['cgpa'], reverse=True) students_details = ordinary_students_details + spillover_students_details return students_details
def get(mat_no, raw_score=False, to_print=False): result_stmt = result_statement.get(mat_no) name = result_stmt["surname"] + " " + result_stmt["othernames"] dept = capwords(result_stmt["dept"]) dob = result_stmt["date_of_birth"] mod = ['PUTME', 'DE(200)', 'DE(300)'][result_stmt['mode_of_entry'] - 1] entry_session = result_stmt['session_admitted'] grad_session = result_stmt['session_grad'] results = res_sort(result_stmt['results']) no_of_pages = len(results) + 1 credits = [list(map(sum, creds)) for creds in result_stmt['credits']] gpas, level_credits = list(zip(*gpa_credits_poll(mat_no)[:-1])) gpas, level_credits = [ list(map(lambda x: x if x else 0, item)) for item in (gpas, level_credits) ] level_weightings = get_level_weightings(result_stmt['mode_of_entry']) weighted_gpas = list( map(lambda x, y: round(x * y, 4), gpas, level_weightings)) owed_courses = get_carryovers(mat_no) owed_courses = owed_courses['first_sem'] + owed_courses['second_sem'] gpa_check = [''] * 5 for course in owed_courses: index = ltoi(course[2]) gpa_check[index] = '*' with current_app.app_context(): html = render_template('result_update_template.htm', uniben_logo_path=UNIBEN_LOGO_PATH, any=any, no_of_pages=no_of_pages, mat_no=mat_no, name=name, dept=dept, dob=dob, mode_of_entry=mod, entry_session=entry_session, grad_session=grad_session, results=results, credits=credits, gpas=gpas, level_weightings=level_weightings, weighted_gpas=weighted_gpas, enumerate=enumerate, raw_score=raw_score, level_credits=level_credits, gpa_check=gpa_check) def generate_img(args): i, page = args img = imgkit.from_string(page, None, options=options) arcname = file_name + '_{}.png'.format(i) with lock: zf.writestr(arcname, data=img) def generate_archive(): with concurrent.futures.ThreadPoolExecutor() as executor: executor.map(generate_img, enumerate(htmls)) if to_print: options = { 'page-size': 'A4', 'disable-smart-shrinking': None, 'print-media-type': None, 'margin-top': '0.6in', 'margin-right': '0.5in', 'margin-bottom': '0.6in', 'margin-left': '0.5in', # 'minimum-font-size': 12, 'encoding': "UTF-8", 'enable-local-file-access': None, 'no-outline': None, 'log-level': 'warn', 'dpi': 100, } file_name = secrets.token_hex(8) + '.pdf' start_time = time.time() pdfkit.from_string(html, os.path.join(CACHE_BASE_DIR, file_name), options=options) print(f'pdf generated in {time.time() - start_time} seconds') resp = send_from_directory(CACHE_BASE_DIR, file_name, as_attachment=True) else: options = { 'format': 'png', 'enable-local-file-access': None, 'log-level': 'warn', 'quality': 50, } file_name = secrets.token_hex(8) file_path = os.path.join(CACHE_BASE_DIR, file_name + '.zip') start_time = time.time() htmls = split_html(html) lock = threading.Lock() with ZipFile(file_path, 'w', ZIP_DEFLATED) as zf: generate_archive() print( f'{len(htmls)} images generated and archived in {time.time() - start_time} seconds' ) resp = send_from_directory(CACHE_BASE_DIR, file_name + '.zip', as_attachment=True) return resp, 200
def get_results_for_acad_session(mat_no, acad_session, include_reg=False): """includes registered but unentered results if "include_reg" is True. Score and grade in such case are empty strings """ res_stmt = result_statement.get(mat_no, sep_carryovers=True) res_idx = [ idx for idx, res in enumerate(res_stmt['results']) if res['session'] == acad_session ] if not res_idx and not include_reg: return 'No result available for entered session', 404 res_idx = res_idx[0] if res_idx else None if include_reg: from sms.src.course_reg import get_existing_course_reg reg, ret_code = get_existing_course_reg(mat_no, acad_session) if ret_code != 200: return reg, ret_code # include courses from course_reg not already in results form = { 'first_sem': [], 'second_sem': [], 'table': int(reg['table_to_populate'][-3:]), 'level': reg['course_reg_level'], 'session': reg['course_reg_session'] } if res_idx is not None: result_dict = { key: res_stmt[key][res_idx] for key in ('results', 'carryovers', 'unregd') } else: result_dict = { key: deepcopy(form) for key in ('results', 'carryovers', 'unregd') } result_dict['regulars'] = result_dict.pop('results') for sem in ('first_sem', 'second_sem'): for key in ('regulars', 'carryovers'): entered_res = list(zip(*result_dict[key][sem]) )[0] if result_dict[key][sem] else [] to_be_entered = list( filter(lambda x: x[0] not in entered_res, reg[key][sem])) [ result_dict[key][sem].append([*crs[:3], '', '', *crs[3:]]) for crs in to_be_entered ] regulars, carryovers, unregd = [ result_dict[key] for key in ('regulars', 'carryovers', 'unregd') ] else: regulars, carryovers, unregd = [ res_stmt[key][res_idx] for key in ('results', 'carryovers', 'unregd') ] gpa_credits = utils.gpa_credits_poll(mat_no) personal_info_keys = ('surname', 'othernames', 'sex', 'grad_status', 'is_symlink', 'mode_of_entry') refine = lambda res: { sem: utils.dictify(utils.multisort(res[sem])) for sem in ('first_sem', 'second_sem') } frame = { 'mat_no': mat_no, 'personal_info': {key: res_stmt[key] for key in personal_info_keys}, 'entry_session': res_stmt["session_admitted"], 'table': 'Result{}'.format(100 * (res_idx + 1)) if res_idx is not None else res_idx, 'level_written': regulars['level'], 'session_written': regulars['session'], 'credits': res_stmt['credits'][res_idx] if res_idx is not None else 0, 'failed_courses': res_stmt['failed_courses'][res_idx] if res_idx is not None else [[], []], 'category': res_stmt["categories"][res_idx] if res_idx is not None else '', 'level_gpa': gpa_credits[utils.ltoi(min(regulars['level'], 500))][0], 'cgpa': gpa_credits[-1], 'regular_courses': refine(regulars), 'carryovers': refine(carryovers), 'unusual_results': refine(unregd) } return frame, 200