def setUp(self): ''' Add dummy modules and mountings into database ''' self.module_overview_handler = ViewMod() self.mounting_view_handler = IndividualModule() self.current_ay = model.get_current_ay() self.next_ay = self.get_next_ay(self.current_ay) # Dummy modules model.add_module('BB1001', 'Dummy Module 1', 'This module is mounted in both sems in both AYs.', 1, 'Active') model.add_module('BB1002', 'Dummy Module 2', 'This module is mounted in sem 1 only, in both AYs.', 2, 'Active') model.add_module('BB1003', 'Dummy Module 3', 'This module is mounted in sem 2 only, in both AYs.', 3, 'Active') model.add_module( 'BB1004', 'Dummy Module 4', 'This module is not mounted in any sem, in both AYs.', 4, 'Active') # Dummy fixed mountings model.add_fixed_mounting('BB1001', self.current_ay + ' Sem 1', 10) model.add_fixed_mounting('BB1001', self.current_ay + ' Sem 2', 20) model.add_fixed_mounting('BB1002', self.current_ay + ' Sem 1', 30) model.add_fixed_mounting('BB1003', self.current_ay + ' Sem 2', 40) # Dummy tentative mountings model.add_tenta_mounting('BB1001', self.next_ay + ' Sem 1', 10) model.add_tenta_mounting('BB1001', self.next_ay + ' Sem 2', 20) model.add_tenta_mounting('BB1002', self.next_ay + ' Sem 1', 30) model.add_tenta_mounting('BB1003', self.next_ay + ' Sem 2', 40)
def setUp(self): ''' Add dummy modules and mountings into database, Then retrieve all fixed module mountings from database ''' self.fixed_mounting_handler = Fixed() self.current_ay = model.get_current_ay() model.add_module('BB1001', 'Dummy Module 1', 'This module is mounted in both semesters.', 1, 'Active') model.add_module('BB1002', 'Dummy Module 2', 'This module is mounted in semester 1 only.', 2, 'Active') model.add_module('BB1003', 'Dummy Module 3', 'This module is mounted in semester 2 only.', 3, 'Active') model.add_module( 'BB1004', 'Dummy Module 4', 'This module is mounted in not mounted in any semester.', 4, 'Active') model.add_fixed_mounting('BB1001', self.current_ay + ' Sem 1', 10) model.add_fixed_mounting('BB1001', self.current_ay + ' Sem 2', 20) model.add_fixed_mounting('BB1002', self.current_ay + ' Sem 1', 30) model.add_fixed_mounting('BB1003', self.current_ay + ' Sem 2', 40) self.fixed_mounting_handler.populate_module_code_and_name() self.fixed_mounting_handler.populate_module_ay_sem_data() assert_true(len(self.fixed_mounting_handler.full_mounting_plan) > 0)
def __init__(self): self.current_ay = model.get_current_ay() self.next_ay = self.get_next_ay(self.current_ay) self.next_next_ay = self.get_next_ay(self.next_ay) self.modified_modules_handler = Modified() self.module_edit_handler = EditModuleInfo() self.module_restore_handler = RestoreModule()
def load_mounting_info(self, module_code, ay_sem): ''' Load the mounting status and quota of the target module and AY/Sem ''' fixed_mounting_status = -1 fixed_quota = None is_current_ay = False # Get mounting status and quota in current AY target_ay = ay_sem[0:8] current_ay = model.get_current_ay() if target_ay == current_ay: is_current_ay = True fixed_mounting_status = model.get_mounting_of_target_fixed_ay_sem( module_code, ay_sem) fixed_quota = model.get_quota_of_target_fixed_ay_sem( module_code, ay_sem) else: target_sem = ay_sem[9:14] fixed_mounting_status = model.get_mounting_of_target_fixed_ay_sem( module_code, current_ay + " " + target_sem) fixed_quota = model.get_quota_of_target_fixed_ay_sem( module_code, current_ay + " " + target_sem) if fixed_quota is False: fixed_quota = '-' if is_current_ay: if fixed_mounting_status is True: self.mounting_status = 1 else: self.mounting_status = -1 self.quota = fixed_quota else: # Get mounting status and quota in target (future) AY tenta_mounting_status = model.get_mounting_of_target_tenta_ay_sem( module_code, ay_sem) tenta_quota = model.get_quota_of_target_tenta_ay_sem( module_code, ay_sem) if tenta_quota is False: tenta_quota = '-' self.quota = tenta_quota if tenta_mounting_status is True: self.mounting_status = 1 else: if fixed_mounting_status is True: self.mounting_status = 0 else: self.mounting_status = -1 self.is_current_ay = is_current_ay
def __init__(self): ''' Define the AY-Sems that are in the system By right, these settings hould be set by the superadmin ''' self.number_of_future_ays = 1 self.current_ay = model.get_current_ay() self.list_of_future_ay_sems = [] ay = self.current_ay for i in range(self.number_of_future_ays): ay = model.get_next_ay(ay) self.list_of_future_ay_sems.append(ay+" Sem 1") self.list_of_future_ay_sems.append(ay+" Sem 2")
def populate_module_ay_sem_data(self): ''' Populate each subplan with sem 1 and sem 2 mounting values, quotas, and numbers of students taking ''' full_mounting_plan = self.full_mounting_plan mounted_module_infos = model.get_all_fixed_mounted_modules() subplan_index = 0 curr_subplan = full_mounting_plan[subplan_index] for info in mounted_module_infos: code = info[0] curr_module_code = curr_subplan[0] while code != curr_module_code: subplan_index += 1 curr_subplan = full_mounting_plan[subplan_index] curr_module_code = curr_subplan[0] ay_sem = info[2] sem = ay_sem[9:14] quota = info[3] if sem == "Sem 1": curr_subplan[2] = 1 curr_subplan[4] = quota elif sem == "Sem 2": curr_subplan[3] = 1 curr_subplan[5] = quota student_stats = model.get_student_stats_for_all_mods() subplan_index = 0 curr_subplan = full_mounting_plan[subplan_index] current_ay = model.get_current_ay() for stat in student_stats: code = stat[1] curr_module_code = curr_subplan[0] while code != curr_module_code: subplan_index += 1 curr_subplan = full_mounting_plan[subplan_index] curr_module_code = curr_subplan[0] ay_sem = stat[2] number_of_students = stat[0] if ay_sem == current_ay + " Sem 1": curr_subplan[6] = number_of_students elif ay_sem == current_ay + " Sem 2": curr_subplan[7] = number_of_students self.full_mounting_plan = full_mounting_plan
def GET(self): ''' Renders the 'Edit All Mountings and Quotas' page if users requested for the page through the GET method. ''' if not session.validate_session(): raise web.seeother('/login') # Currently, tentative mounting will be shown for the next AY selected_ay = model.get_next_ay(model.get_current_ay()) tenta_mounting_handler = Tentative() tenta_mounting_handler.populate_module_code_and_name() tenta_mounting_handler.populate_module_ay_sem_data(selected_ay) full_mounting_plan = tenta_mounting_handler.full_mounting_plan full_mounting_plan = model.replace_empty_quota_with_symbols(full_mounting_plan) return RENDER.editAll(selected_ay, full_mounting_plan)
def GET(self): ''' This function is called when the '/' page (index.html) is loaded If user is not logged in, they are redirected to the login page. ''' if not session.validate_session(): raise web.seeother('/login') else: current_ay_with_current_date = model.get_current_ay_sem()[0:8] current_database_ay = model.get_current_ay() to_migrate_db = False if current_ay_with_current_date != current_database_ay: to_migrate_db = True # [NOTE] for debugging purposes, comment out this line when done. # to_migrate_db = True return RENDER.index(need_migration=to_migrate_db)
def load_tenta_mounting_plan(self, module_code): ''' Loads the tentative mounting plan of the single module ''' tenta_mounting_and_quota = model.get_tenta_mounting_and_quota( module_code) tenta_ay_sems = [] ay = model.get_current_ay() for i in range(self.number_of_future_ays): ay = model.get_next_ay(ay) tenta_ay_sems.append(ay + " Sem 1") tenta_ay_sems.append(ay + " Sem 2") tenta_mounting_plan = [] for ay_sem in tenta_ay_sems: # AY/Sem is marked as 'not mounted' by default ay_sem_plan = [ay_sem, -1, "-"] # Mark AY/Sems that module is mounted in for mounting in tenta_mounting_and_quota: mounted_ay_sem = mounting[0] quota = mounting[1] if ay_sem == mounted_ay_sem: ay_sem_plan[1] = 1 ay_sem_plan[2] = quota break # Mark AY/Sems that module is unmounted from # (i.e. mounted in fixed AY, but will no longer be mounted in tentative AY) fixed_sem_1_mounting_value = self.fixed_mounting_plan[0][1] fixed_sem_2_mounting_value = self.fixed_mounting_plan[1][1] tenta_mounting_value = ay_sem_plan[1] if ay_sem[9:14] == "Sem 1": if fixed_sem_1_mounting_value == 1 and tenta_mounting_value == -1: ay_sem_plan[1] = 0 elif ay_sem[9:14] == "Sem 2": if fixed_sem_2_mounting_value == 1 and tenta_mounting_value == -1: ay_sem_plan[1] = 0 tenta_mounting_plan.append(ay_sem_plan) self.tenta_mounting_plan = tenta_mounting_plan
def GET(self): ''' This function is called when the database migration page is loaded If user is not logged in, they are redirected to the login page. ''' if not session.validate_session(): raise web.seeother('/login') else: current_ay_with_current_date = model.get_current_ay_sem()[0:8] current_database_ay = model.get_current_ay() if current_ay_with_current_date == current_database_ay: # pass # [NOTE] uncomment out this line for debugging purposes raise web.seeother( "/") # [NOTE] comment out this line for debugging purposes next_ay = model.get_next_ay(current_database_ay) future_ay = model.get_next_ay(next_ay) return RENDER.databaseMigrate(current_database_ay, next_ay, future_ay)
def setUp(self): ''' Add dummy modules and mountings into database ''' self.fixed_mounting_handler = Fixed() self.current_ay = model.get_current_ay() self.tentative_mounting_handler = Tentative() self.next_ay = self.get_next_ay(self.current_ay) self.selected_tenta_mountings = \ model.get_all_tenta_mounted_modules_of_selected_ay(self.next_ay) # Dummy modules model.add_module('BB1001', 'Dummy Module 1', 'This module is mounted in both sems in both AYs.', 1, 'Active') model.add_module('BB1002', 'Dummy Module 2', 'This module is mounted in sem 1 only, in both AYs.', 2, 'Active') model.add_module('BB1003', 'Dummy Module 3', 'This module is mounted in sem 2 only, in both AYs.', 3, 'Active') model.add_module('BB1004', 'Dummy Module 4', 'This module is not mounted in any sem, in both AYs.', 4, 'Active') model.add_module('BB9999', 'Dummy Module X', 'This module is mounted 20 years in the future!', 0, 'Active') # Dummy fixed mountings model.add_fixed_mounting('BB1001', self.current_ay+' Sem 1', 10) model.add_fixed_mounting('BB1001', self.current_ay+' Sem 2', 20) model.add_fixed_mounting('BB1002', self.current_ay+' Sem 1', 30) model.add_fixed_mounting('BB1003', self.current_ay+' Sem 2', 40) self.load_fixed_full_mounting_plan() # Dummy tentative mountings model.add_tenta_mounting('BB1001', self.next_ay+' Sem 1', 10) model.add_tenta_mounting('BB1001', self.next_ay+' Sem 2', 20) model.add_tenta_mounting('BB1002', self.next_ay+' Sem 1', 30) model.add_tenta_mounting('BB1003', self.next_ay+' Sem 2', 40) model.add_tenta_mounting('BB9999', 'AY 36/37 Sem 1', 999) self.load_tenta_full_mounting_plan()
def GET(self, to_render=True, logged_in=False): ''' Renders the tentative mounting page if users requested for the page through the GET method. ''' if not session.validate_session() and not logged_in: raise web.seeother('/login') # Currently, tentative mounting will be shown for the next AY selected_ay = model.get_next_ay(model.get_current_ay()) self.populate_module_code_and_name() self.populate_module_ay_sem_data(selected_ay) full_mounting_plan = model.replace_empty_quota_with_symbols( self.full_mounting_plan) if to_render: return RENDER.moduleMountingTentative(selected_ay, full_mounting_plan) else: self.full_mounting_plan = full_mounting_plan
def GET(self, to_render=True, logged_in=False): ''' Renders the fixed mounting page if users requested for the page through the GET method. ''' if not session.validate_session() and not logged_in: raise web.seeother('/login') self.populate_module_code_and_name() self.populate_module_ay_sem_data() current_ay = model.get_current_ay() full_mounting_plan = self.full_mounting_plan # New modules will not be displayed in fixed mounting full_mounting_plan = [ subplan for subplan in full_mounting_plan if subplan[8].rstrip() == "Active" ] full_mounting_plan = model.replace_empty_quota_with_symbols( full_mounting_plan) if to_render: return RENDER.moduleMountingFixed(current_ay, full_mounting_plan) else: self.full_mounting_plan = full_mounting_plan
def get_modules_with_modified_mounting(self): ''' Get all modules whose mounting has been modified in a future AY. Return the module code, current AY-Sem, target AY-Sem, and mounting change ''' # Generate fixed mounting plan fixed_mounting_handler = Fixed() current_ay = model.get_current_ay() fixed_mounting_handler.populate_module_code_and_name() fixed_mounting_handler.populate_module_ay_sem_data() fixed_full_mounting_plan = fixed_mounting_handler.full_mounting_plan modified_modules = [] target_ay = current_ay # Loop through each future AY for i in range(model.get_number_of_ay_in_system() - 1): target_ay = model.get_next_ay(target_ay) # Generate tentative mounting plan tenta_mounting_handler = Tentative() tenta_mounting_handler.populate_module_code_and_name() tenta_mounting_handler.populate_module_ay_sem_data(target_ay) tenta_full_mounting_plan = tenta_mounting_handler.full_mounting_plan # Compare the fixed and tentative mounting of each module for each semester # to see if there is any difference (if there is, means it's modified) for i in range(len(fixed_full_mounting_plan)): fixed_subplan = fixed_full_mounting_plan[i] tenta_subplan = tenta_full_mounting_plan[i] module_code = fixed_subplan[0] module_name = fixed_subplan[1] fixed_sem_1_mounting = fixed_subplan[2] tenta_sem_1_mounting = tenta_subplan[2] fixed_sem_2_mounting = fixed_subplan[3] tenta_sem_2_mounting = tenta_subplan[3] if tenta_sem_1_mounting == 0: modified_modules.append([ module_code, module_name, current_ay + " Sem 1", target_ay + " Sem 1", 0 ]) # Mounted --> Unmounted elif tenta_sem_1_mounting == 1 and fixed_sem_1_mounting == -1: modified_modules.append([ module_code, module_name, current_ay + " Sem 1", target_ay + " Sem 1", 1 ]) # Unmounted --> Mounted if tenta_sem_2_mounting == 0: modified_modules.append([ module_code, module_name, current_ay + " Sem 2", target_ay + " Sem 2", 0 ]) # Mounted --> Unmounted elif tenta_sem_2_mounting == 1 and fixed_sem_2_mounting == -1: modified_modules.append([ module_code, module_name, current_ay + " Sem 2", target_ay + " Sem 2", 1 ]) # Unmounted --> Mounted return modified_modules
def populate_module_ay_sem_data(self, selected_ay): ''' Populate each subplan with sem 1 and sem 2 mounting values ''' tenta_full_mounting_plan = self.full_mounting_plan mounted_module_infos = model.get_all_tenta_mounted_modules_of_selected_ay( selected_ay) subplan_index = 0 curr_subplan = tenta_full_mounting_plan[subplan_index] # Mark module that are mounted for info in mounted_module_infos: code = info[0] curr_module_code = curr_subplan[0] while code != curr_module_code: subplan_index += 1 curr_subplan = tenta_full_mounting_plan[subplan_index] curr_module_code = curr_subplan[0] ay_sem = info[2] sem = ay_sem[9:14] quota = info[3] if sem == "Sem 1": curr_subplan[2] = 1 curr_subplan[4] = quota elif sem == "Sem 2": curr_subplan[3] = 1 curr_subplan[5] = quota # Generate full mounting plan for fixed mountings fixed_mounting_handler = Fixed() fixed_mounting_handler.populate_module_code_and_name() fixed_mounting_handler.populate_module_ay_sem_data() fixed_full_mounting_plan = fixed_mounting_handler.full_mounting_plan # Mark module that are unmounted # (i.e. mounted in current AY, but will no longer be mounted in future AY) for i in range(len(fixed_full_mounting_plan)): fixed_subplan = fixed_full_mounting_plan[i] tenta_subplan = tenta_full_mounting_plan[i] fixed_sem_1_mounting = fixed_subplan[2] tenta_sem_1_mounting = tenta_subplan[2] fixed_sem_2_mounting = fixed_subplan[3] tenta_sem_2_mounting = tenta_subplan[3] if fixed_sem_1_mounting == 1 and tenta_sem_1_mounting == -1: tenta_full_mounting_plan[i][2] = 0 if fixed_sem_2_mounting == 1 and tenta_sem_2_mounting == -1: tenta_full_mounting_plan[i][3] = 0 student_stats = model.get_student_stats_for_all_mods() subplan_index = 0 curr_subplan = tenta_full_mounting_plan[subplan_index] selected_ay = model.get_next_ay(model.get_current_ay()) for stat in student_stats: code = stat[1] curr_module_code = curr_subplan[0] while code != curr_module_code: subplan_index += 1 curr_subplan = tenta_full_mounting_plan[subplan_index] curr_module_code = curr_subplan[0] ay_sem = stat[2] number_of_students = stat[0] if ay_sem == selected_ay + " Sem 1": curr_subplan[6] = number_of_students elif ay_sem == selected_ay + " Sem 2": curr_subplan[7] = number_of_students self.full_mounting_plan = tenta_full_mounting_plan
def __init__(self): self.current_ay = model.get_current_ay() self.next_ay = self.get_next_ay(self.current_ay) self.taken_prior_handler = TakePriorTo()
def POST(self, *test_data): ''' Handles the editing operations for all mountings and quotas ''' if test_data: input_data = test_data[0] else: input_data = web.input() all_modules = model.get_all_modules() target_ay = model.get_next_ay(model.get_current_ay()) for module in all_modules: module_code = module[0] try: is_module_edited = input_data[module_code+"_isEdited"] except KeyError: is_module_edited = "False" if is_module_edited == "True": try: sem1_mounting = input_data[module_code+"_Sem1Mounting"] sem1_mounting = True except KeyError: sem1_mounting = False try: sem2_mounting = input_data[module_code+"_Sem2Mounting"] sem2_mounting = True except KeyError: sem2_mounting = False try: sem1_quota = input_data[module_code+"_Sem1Quota"] if sem1_quota == "": # quota = '?' sem1_quota = None except KeyError: # quota = '-' sem1_quota = None if sem1_quota is not None: try: sem1_quota = int(sem1_quota) if sem1_quota < 0 or sem1_quota > 999: if test_data: return False else: return Outcome().POST("edit_all_mountings_and_quotas", False, None) except ValueError: # quota is not an integer if test_data: return False else: return Outcome().POST("edit_all_mountings_and_quotas", False, None) try: sem2_quota = input_data[module_code+"_Sem2Quota"] if sem2_quota == "": # quota = '?' sem2_quota = None except KeyError: # quota = '-' sem2_quota = None if sem2_quota is not None: try: sem2_quota = int(sem2_quota) if sem2_quota < 0 or sem2_quota > 999: if test_data: return False else: return Outcome().POST("edit_all_mountings_and_quotas", False, None) except ValueError: # quota is not an integer if test_data: return False else: return Outcome().POST("edit_all_mountings_and_quotas", False, None) target_aysem = target_ay+" Sem 1" outcome = None if sem1_mounting is True: old_mounting = model.get_mounting_of_target_tenta_ay_sem(module_code, target_aysem) if old_mounting is True: outcome = model.update_quota(module_code, target_aysem, sem1_quota) else: outcome = model.add_tenta_mounting(module_code, target_aysem, sem1_quota) else: outcome = model.delete_tenta_mounting(module_code, target_aysem) if outcome is False: return Outcome().POST("edit_all_mountings_and_quotas", False, None) target_aysem = target_ay+" Sem 2" outcome = None if sem2_mounting is True: old_mounting = model.get_mounting_of_target_tenta_ay_sem(module_code, target_aysem) if old_mounting is True: outcome = model.update_quota(module_code, target_aysem, sem2_quota) else: outcome = model.add_tenta_mounting(module_code, target_aysem, sem2_quota) else: outcome = model.delete_tenta_mounting(module_code, target_aysem) if outcome is False: return Outcome().POST("edit_all_mountings_and_quotas", False, None) if not test_data: return Outcome().POST("edit_all_mountings_and_quotas", True, None)
def __init__(self): self.edit_all_handler = EditAll() self.current_ay = model.get_current_ay() self.next_ay = model.get_next_ay(self.current_ay)
def GET(self, *test_data): ''' Renders the oversubscribed modules page if users requested for the page through the GET method. ''' if test_data: target_ay_sem = test_data[0] else: if not session.validate_session(): raise web.seeother('/login') input_data = model.validate_input(web.input(), ["aysem"], aysem_specific=False, attr_required=False) try: target_ay_sem = input_data.aysem except AttributeError: target_ay_sem = model.get_current_ay_sem() all_ay_sems = model.get_all_ay_sems() #list_of_oversub_mod = model.get_oversub_mod() list_of_oversub_mod = [] current_ay = model.get_current_ay() if target_ay_sem[0:8] == current_ay: fixed_mounting_handler = Fixed() fixed_mounting_handler.GET(to_render=False, logged_in=True) full_mounting_plan = fixed_mounting_handler.full_mounting_plan if target_ay_sem[9:15] == "Sem 1": for subplan in full_mounting_plan: module_code = subplan[0] module_name = subplan[1] sem1_quota = subplan[4] sem1_num_students = subplan[6] if ((sem1_quota != '?' and sem1_quota != '-') \ and sem1_num_students > sem1_quota) \ or ((sem1_quota == '?' or sem1_quota == '-') and sem1_num_students > 0): if sem1_quota == '?' or sem1_quota == '-': oversub_amount = sem1_num_students else: oversub_amount = sem1_num_students - sem1_quota list_of_oversub_mod.append( (module_code, module_name, target_ay_sem, sem1_quota, sem1_num_students, oversub_amount)) else: for subplan in full_mounting_plan: module_code = subplan[0] module_name = subplan[1] sem2_quota = subplan[5] sem2_num_students = subplan[7] if ((sem2_quota != '?' and sem2_quota != '-') \ and sem2_num_students > sem2_quota) \ or ((sem2_quota == '?' or sem2_quota == '-') and sem2_num_students > 0): if sem2_quota == '?' or sem2_quota == '-': oversub_amount = sem2_num_students else: oversub_amount = sem2_num_students - sem2_quota list_of_oversub_mod.append( (module_code, module_name, target_ay_sem, sem2_quota, sem2_num_students, oversub_amount)) else: tenta_mounting_handler = Tentative() tenta_mounting_handler.GET(to_render=False, logged_in=True) full_mounting_plan = tenta_mounting_handler.full_mounting_plan if target_ay_sem[9:15] == "Sem 1": for subplan in full_mounting_plan: module_code = subplan[0] module_name = subplan[1] sem1_quota = subplan[4] sem1_num_students = subplan[6] if ((sem1_quota != '?' and sem1_quota != '-') \ and sem1_num_students > sem1_quota) \ or ((sem1_quota == '?' or sem1_quota == '-') and sem1_num_students > 0): if sem1_quota == '?' or sem1_quota == '-': oversub_amount = sem1_num_students else: oversub_amount = sem1_num_students - sem1_quota list_of_oversub_mod.append( (module_code, module_name, target_ay_sem, sem1_quota, sem1_num_students, oversub_amount)) else: for subplan in full_mounting_plan: module_code = subplan[0] module_name = subplan[1] sem2_quota = subplan[5] sem2_num_students = subplan[7] if ((sem2_quota != '?' and sem2_quota != '-') \ and sem2_num_students > sem2_quota) \ or ((sem2_quota == '?' or sem2_quota == '-') and sem2_num_students > 0): if sem2_quota == '?' or sem2_quota == '-': oversub_amount = sem2_num_students else: oversub_amount = sem2_num_students - sem2_quota list_of_oversub_mod.append( (module_code, module_name, target_ay_sem, sem2_quota, sem2_num_students, oversub_amount)) if not test_data: return RENDER.oversubscribedModules(list_of_oversub_mod, all_ay_sems, target_ay_sem) else: return list_of_oversub_mod