def execute_trial(train_data, test_users, data_gen, solvers, recorder, trial_name = None, measures_per_user = 1, logger = None): results = [] if trial_name == None: trial_name = '' else: trial_name = ': ' + trial_name logger_f = logger.log if logger != None else lambda x, y: None logger_f = logger.log logger_f('Executing comparison trial' + str(trial_name), 'standard') for (f, solver_name) in solvers: logger_f(" Starting solver: " + solver_name, 'standard') start_time = ut.curr_time() msgs = map(f, test_users) elapsed = ut.curr_time() - start_time resps = [] for i in range(measures_per_user): resps += data_gen.gen_responses(test_users, msgs) correct_frac = float(sum(resps)) / float(measures_per_user * len(resps)) results.append((solver_name, correct_frac, elapsed, resps)) add = lambda att, val: recorder.add(solver_name + '.' + str(att), val) add('correct_frac', correct_frac) add('responses', resps) recorder.add('elapsed_time', elapsed) logger_f(" Results (correct%, elapsed time): " + str((correct_frac, elapsed)), 'standard')
def optimize(self, user): self.log('Beginning GA Optimizer for user: '******'standard') reg_n = int(self.pop_size * (1 - self.elitism)) elite_n = min(1, int(self.pop_size * self.elitism)) pop = sorted(map(lambda x: (x, self.prob_f(user, x)), self.build_random_candidates(self.pop_size)), key = lambda x: x[1]) regulars = pop[:reg_n] elites = pop[reg_n:] best = pop[len(pop) - 1] self.curr_iter = 1 self.start_time = ut.curr_time() self.start_noimprove_time = ut.curr_time() self.noimprove_iterations = 0 while not(self.should_terminate()): self.log(' Iteration ' + str(self.curr_iter) + ', Best so far: ' + str(best), 'debug') regulars = self.build_new_gen(user, regulars + elites, reg_n) pop = sorted(regulars + elites, key=lambda x: x[1]) regulars = pop[:reg_n] elites = pop[reg_n:] if elites[0][1] > best[1]: self.start_noimprove_time = ut.curr_time() self.noimprove_iterations = -1 best = elites[0] self.noimprove_iterations += 1 self.curr_iter += 1 best_inter, best_prob = best elapsed_time = ut.curr_time() - self.start_time msg = 'Best Solution = ' + str(best) + ', Elapsed Time (sec.): ' + str(elapsed_time) self.log(msg, 'standard') return (best_inter, best_prob, elapsed_time)
def optimize(self, user): self.log('Beginning GA Optimizer for user: '******'standard') reg_n = int(self.pop_size * (1 - self.elitism)) elite_n = min(1, int(self.pop_size * self.elitism)) pop = sorted(map(lambda x: (x, self.prob_f(user, x)), self.build_random_candidates(self.pop_size)), key=lambda x: x[1]) regulars = pop[:reg_n] elites = pop[reg_n:] best = pop[len(pop) - 1] self.curr_iter = 1 self.start_time = ut.curr_time() self.start_noimprove_time = ut.curr_time() self.noimprove_iterations = 0 while not (self.should_terminate()): self.log( ' Iteration ' + str(self.curr_iter) + ', Best so far: ' + str(best), 'debug') regulars = self.build_new_gen(user, regulars + elites, reg_n) pop = sorted(regulars + elites, key=lambda x: x[1]) regulars = pop[:reg_n] elites = pop[reg_n:] if elites[0][1] > best[1]: self.start_noimprove_time = ut.curr_time() self.noimprove_iterations = -1 best = elites[0] self.noimprove_iterations += 1 self.curr_iter += 1 best_inter, best_prob = best elapsed_time = ut.curr_time() - self.start_time msg = 'Best Solution = ' + str(best) + ', Elapsed Time (sec.): ' + str( elapsed_time) self.log(msg, 'standard') return (best_inter, best_prob, elapsed_time)
def execute_trial(train_data, test_users, data_gen, solvers, recorder, trial_name=None, measures_per_user=1, logger=None): results = [] if trial_name == None: trial_name = '' else: trial_name = ': ' + trial_name logger_f = logger.log if logger != None else lambda x, y: None logger_f = logger.log logger_f('Executing comparison trial' + str(trial_name), 'standard') for (f, solver_name) in solvers: logger_f(" Starting solver: " + solver_name, 'standard') start_time = ut.curr_time() msgs = map(f, test_users) elapsed = ut.curr_time() - start_time resps = [] for i in range(measures_per_user): resps += data_gen.gen_responses(test_users, msgs) correct_frac = float(sum(resps)) / float( measures_per_user * len(resps)) results.append((solver_name, correct_frac, elapsed, resps)) add = lambda att, val: recorder.add(solver_name + '.' + str(att), val) add('correct_frac', correct_frac) add('responses', resps) recorder.add('elapsed_time', elapsed) logger_f( " Results (correct%, elapsed time): " + str( (correct_frac, elapsed)), 'standard')
def should_terminate(self): if self.curr_iter >= self.max_iterations: return True if self.max_time != None and ut.curr_time() >= self.start_time + self.max_time: return True if self.noimprove_iterations >= self.max_noimprove_iterations: return True if self.max_noimprove_time != None and ut.curr_time() >= self.start_noimprove_time + self.max_noimprove_time: return True return False
def should_terminate(self): if self.curr_iter >= self.max_iterations: return True if self.max_time != None and ut.curr_time( ) >= self.start_time + self.max_time: return True if self.noimprove_iterations >= self.max_noimprove_iterations: return True if self.max_noimprove_time != None and ut.curr_time( ) >= self.start_noimprove_time + self.max_noimprove_time: return True return False
def run_trials(trial_initializer_f, analyzer_f, num_trials, recorder, logger): recorder.set('num_trials', num_trials) main_start_time = ut.curr_time() for t in range(1, num_trials + 1): trial_start = ut.curr_time() logger.log('Starting new trial, initializing...', 'standard') train_data, test_users, data_generator, solvers = trial_initializer_f(recorder, logger) logger.log(' Time initializing: ' + str(ut.curr_time() - trial_start) + ' sec.', 'standard') execute_trial(train_data, test_users, data_generator, solvers, recorder, trial_name = 'Trial ' + str(t), logger = logger) main_elapsed = ut.curr_time() - main_start_time recorder.set('main.elapsed_time', main_elapsed) analyzer_f(recorder, logger, map(lambda (x, y): y, solvers))
def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.LeftButton and self._resize_needed: # scale inline if self._full_size: pixmap = self._pixmap.scaled(self._max_size, self._max_size, QtCore.Qt.KeepAspectRatio) self._image_label.setPixmap(pixmap) self.resize(QtCore.QSize(self._max_size, pixmap.height())) self._image_label.setGeometry(5, 0, pixmap.width(), pixmap.height()) else: self._image_label.setPixmap(self._pixmap) self.resize(QtCore.QSize(self._max_size, self._pixmap.height() + 17)) self._image_label.setGeometry(5, 0, self._pixmap.width(), self._pixmap.height()) self._full_size = not self._full_size self._elem.setSizeHint(QtCore.QSize(self.width(), self.height())) elif event.button() == QtCore.Qt.RightButton: # save inline directory = QtGui.QFileDialog.getExistingDirectory( self, QtGui.QApplication.translate("MainWindow", "Choose folder", None, QtGui.QApplication.UnicodeUTF8), curr_directory(), QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog, ) if directory: fl = QtCore.QFile(directory + "/toxygen_inline_" + curr_time().replace(":", "_") + ".png") self._pixmap.save(fl, "PNG") return False
def get(self): util.check_role(self, "student") sid = self.get_secure_cookie("userid") print("当前学生的id是", sid) cursor = util.con.cursor() sql = "select enroll_year, academyid from student where studentid = %s" cursor.execute(sql, (sid,)) enroll_year, academyid = list(cursor)[0] grade = util.get_grade(enroll_year) print("学生的入学年,学期和学院分别是", enroll_year, grade, academyid) sql = "select * from plan where grade = %s and academyid = %s and public = '1'" cursor.execute(sql, (grade, academyid)) plans = list(cursor) print("该学生能参加的选课计划有", plans) cursor.close() self.render( "chooseClass.html", title="选课页面", plans=plans, role=b"student", studentid=self.get_secure_cookie("userid"), curr_time=util.curr_time(), )
def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.LeftButton and self._resize_needed: # scale inline if self._full_size: pixmap = self._pixmap.scaled(self._max_size, self._max_size, QtCore.Qt.KeepAspectRatio) self._image_label.setPixmap(pixmap) self.resize(QtCore.QSize(self._max_size, pixmap.height())) self._image_label.setGeometry(5, 0, pixmap.width(), pixmap.height()) else: self._image_label.setPixmap(self._pixmap) self.resize(QtCore.QSize(self._max_size, self._pixmap.height() + 17)) self._image_label.setGeometry(5, 0, self._pixmap.width(), self._pixmap.height()) self._full_size = not self._full_size self._elem.setSizeHint(QtCore.QSize(self.width(), self.height())) elif event.button() == QtCore.Qt.RightButton: # save inline directory = QtGui.QFileDialog.getExistingDirectory(self, QtGui.QApplication.translate("MainWindow", 'Choose folder', None, QtGui.QApplication.UnicodeUTF8), curr_directory(), QtGui.QFileDialog.ShowDirsOnly) if directory: fl = QtCore.QFile(directory + '/toxygen_inline_' + curr_time().replace(':', '_') + '.png') self._pixmap.save(fl, 'PNG') return False
def run_trials(trial_initializer_f, analyzer_f, num_trials, recorder, logger): recorder.set('num_trials', num_trials) main_start_time = ut.curr_time() for t in range(1, num_trials + 1): trial_start = ut.curr_time() logger.log('Starting new trial, initializing...', 'standard') train_data, test_users, data_generator, solvers = trial_initializer_f( recorder, logger) logger.log( ' Time initializing: ' + str(ut.curr_time() - trial_start) + ' sec.', 'standard') execute_trial(train_data, test_users, data_generator, solvers, recorder, trial_name='Trial ' + str(t), logger=logger) main_elapsed = ut.curr_time() - main_start_time recorder.set('main.elapsed_time', main_elapsed) analyzer_f(recorder, logger, map(lambda (x, y): y, solvers))
def send_message(self, text): """ Send message to active friend :param text: message text """ if self.is_active_online() and text: if text.startswith('/me '): message_type = TOX_MESSAGE_TYPE['ACTION'] text = text[4:] else: message_type = TOX_MESSAGE_TYPE['NORMAL'] friend = self._friends[self._active_friend] self.split_and_send(friend.number, message_type, text.encode('utf-8')) self.create_message_item(text, curr_time(), self._name, message_type) self._screen.messageEdit.clear() self._messages.scrollToBottom() friend.append_message(TextMessage(text, MESSAGE_OWNER['ME'], time.time(), message_type))
def new_message(self, friend_num, message_type, message): """ Current user gets new message :param friend_num: friend_num of friend who sent message :param message_type: message type - plain text or action message (/me) :param message: text of message """ if friend_num == self.get_active_number(): # add message to list user_name = Profile.get_instance().get_active_name() self.create_message_item(message.decode('utf-8'), curr_time(), user_name, message_type) self._messages.scrollToBottom() self._friends[self._active_friend].append_message( TextMessage(message.decode('utf-8'), MESSAGE_OWNER['FRIEND'], time.time(), message_type)) else: friend = self.get_friend_by_number(friend_num) friend.set_messages(True) friend.append_message( TextMessage(message.decode('utf-8'), MESSAGE_OWNER['FRIEND'], time.time(), message_type))
def send_message(self, text): """ Send message to active friend :param text: message text """ if self.is_active_online() and text: if text.startswith('/me '): message_type = TOX_MESSAGE_TYPE['ACTION'] text = text[4:] else: message_type = TOX_MESSAGE_TYPE['NORMAL'] friend = self._friends[self._active_friend] self.split_and_send(friend.number, message_type, text.encode('utf-8')) self.create_message_item(text, curr_time(), self._name, message_type) self._screen.messageEdit.clear() self._messages.scrollToBottom() friend.append_message( TextMessage(text, MESSAGE_OWNER['ME'], time.time(), message_type))
def end_registration(self): planid = self.get_argument("planid") # 需要删除的课程列表: cls_to_del = set() choicelist = [] registration_temp = {} # 选课情况dict # 检查选课计划是不是已经结束 cursor = con.cursor() sql = "select end_time from plan where planid = %s" cursor.execute(sql, (planid,)) end_time = list(cursor)[0][0].isoformat().replace("T", " ") print("选课计划结束时间", end_time) if util.curr_time() < end_time: dump_err(self, "未到选课结束时间不能结束选课") return # 从choice_temp中选出结束的planid里所有的选课记录 choicequery = "select * from choice_temp where planid = " + planid cursor.execute(choicequery) choicelist = list(cursor) print("1 ", choicelist) if len(choicelist) > 0: # 对所有选课记录进行投票统计,如果一个班级首选加备选人数都不超过3个人,这个教学班删除。写入一个set cls_to_del clsidsquery = "select distinct classid from choice_temp where planid = " + str(planid) cursor.execute(clsidsquery) clsids = list(cursor) print("2 ", clsids) remainnum_per_class = {} # 初始化remainnum_perclass for i in range(0, len(clsids)): remainnum_per_class[clsids[i][0]] = max_student_per_class print("3 ", remainnum_per_class) for eachchoice in choicelist: theclassid = eachchoice[2] if remainnum_per_class[theclassid] > 0: remainnum_per_class[theclassid] += -1 print("4 ", remainnum_per_class) for key in remainnum_per_class.keys(): # key=classid if remainnum_per_class[key] > max_student_per_class - 3: cls_to_del.add(key) print("5 ", cls_to_del) # choicelist按照cls_to_del删除记录 # 第一轮筛选之后的choicelist: index = 0 while index < len(choicelist) and index >= 0: # print(index," " ,choicelist) if choicelist[index][2] in cls_to_del: # print("hhh",choicelist[index][2]) choicelist.remove(choicelist[index]) index -= 1 index += 1 print("6 ", choicelist) if len(choicelist) > 0: # 按照首选给每个人选课,生成一个选课情况dict。 # registration_temp = {} # 选课情况dict # 初始化选课情况字典 for eachchoice in choicelist: registration_temp[eachchoice[1]] = [] print("7 ", registration_temp) # 重新初始化remainnum_per_class (重复) for key in remainnum_per_class.keys(): remainnum_per_class[key] = max_student_per_class # 按照首选课选到选课情况字典registration_temp里 for eachchoice in choicelist: if eachchoice[-1] == 1: # 是首选课 this_stu_id = eachchoice[1] this_cls_id = eachchoice[2] registration_temp[this_stu_id].append(this_cls_id) remainnum_per_class[this_cls_id] += -1 print("8 ", registration_temp) print("9 ", remainnum_per_class) # #在dict中统计所有班级的人数,如果不够3个人这个班级删除,dict中的记录删除 # for key in remainnum_per_class.keys():# key=classid # if remainnum_per_class[key] > max_student_per_class-3: # cls_to_del.add(key) # 增加要删除的课id,更新了cls_to_del!!!!!!!!!!!!!!!! # print("10 ",cls_to_del) # # # 在registration_temp里学生的课程列表中,删掉更新后的cls_to_del里面的课id # for key in registration_temp.keys():# key=studentid # clsids = registration_temp[key] # 每个学生选的一堆课id 的list # index = 0 # while index <len(clsids) and index >= 0 :# 每个学生选的一堆课id中的一个 # if clsids[index] in cls_to_del: # print("clsids[index]:",clsids[index]) # clsids.remove(clsids[index]) # index-=1 # index+=1 # # # 上一步操作后registration_temp里学生的课程列表可能是空的了(学生的至多四个首选课全都没选上),需要删除他 # for key in list(registration_temp.keys()):# key=studentid # if len(registration_temp[key]) == 0: # 这个学生没有选上课,一堆课id删减到为空了(太惨了) # registration_temp.pop(key) # print("11 ",registration_temp) # # # # choicelist按照cls_to_del删除记录 # # 第二轮筛选之后的choicelist: # while index < len(choicelist) and index >= 0: # # print(index," " ,choicelist) # if choicelist[index][2] in cls_to_del: # # print("hhh",choicelist[index][2]) # choicelist.remove(choicelist[index]) # index-=1 # index+=1 # print("12 ",choicelist) # 用第一备选给学生补齐选课 if len(choicelist) > 0: # 找dict中不满4门课的学生。给他选上第一备选。 for key in list(registration_temp.keys()): # key = studentid if len(registration_temp[key]) < 4: # 找到dict中不满4门课的学生id: key for eachchoice in choicelist: if ( eachchoice[1] == key and eachchoice[-3] == 5 ): # 找到这个学生的第一备选课id:eachchoice[2] registration_temp[key].append(eachchoice[2]) # 给他选上第一备选 remainnum_per_class[eachchoice[2]] += -1 print("_+_+_+_+_+_+", eachchoice[2]) print("$$$$$$$$", registration_temp, "$$$$$$$$$$", remainnum_per_class) # 找dict中还是不满4门课的学生。给他选上第二备选。 for key in list(registration_temp.keys()): # key = studentid if len(registration_temp[key]) < 4: # 找到dict中不满4门课的学生id: key for eachchoice in choicelist: if ( eachchoice[1] == key and eachchoice[-3] == 6 ): # 找到这个学生的第二备选课id:eachchoice[2] registration_temp[key].append(eachchoice[2]) # 给他选上第二备选 remainnum_per_class[eachchoice[2]] += -1 # 在dict中统计所有班级的人数,如果不够3个人这个班级删除,dict中的记录删除 for key in remainnum_per_class.keys(): # key=classid if remainnum_per_class[key] > max_student_per_class - 3: cls_to_del.add(key) # 增加要删除的课id,更新了cls_to_del!!!!!!!!!!!!!!!! print("10 ", cls_to_del) # 在registration_temp里学生的课程列表中,删掉更新后的cls_to_del里面的课id for key in registration_temp.keys(): # key=studentid clsids = registration_temp[key] # 每个学生选的一堆课id 的list index = 0 while index < len(clsids) and index >= 0: # 每个学生选的一堆课id中的一个 if clsids[index] in cls_to_del: print("clsids[index]:", clsids[index]) clsids.remove(clsids[index]) index -= 1 index += 1 # 上一步操作后registration_temp里学生的课程列表可能是空的了(学生的至多四个首选课全都没选上),需要删除他 for key in list(registration_temp.keys()): # key=studentid if len(registration_temp[key]) == 0: # 这个学生没有选上课,一堆课id删减到为空了(太惨了) registration_temp.pop(key) print("11 ", registration_temp) # choicelist按照cls_to_del删除记录 # 第三轮筛选之后的choicelist: while index < len(choicelist) and index >= 0: # print(index," " ,choicelist) if choicelist[index][2] in cls_to_del: # print("hhh",choicelist[index][2]) choicelist.remove(choicelist[index]) index -= 1 index += 1 print("12 ", choicelist) # # 用第二备选给学生补齐选课(重复) # if len(choicelist) > 0: # # 找dict中不满4门课的学生。给他选上第二备选。 # for key in list(registration_temp.keys()): # key = studentid # if len(registration_temp[key]) < 4: # 找到dict中不满4门课的学生id: key # for eachchoice in choicelist: # if ( # eachchoice[1] == key and eachchoice[-3] == 6 # ): # 找到这个学生的第二备选课id:eachchoice[2] # registration_temp[key].append(eachchoice[2]) # 给他选上第二备选 # remainnum_per_class[eachchoice[2]] += -1 # # # 在dict中统计所有班级的人数,如果不够3个人这个班级删除,dict中的记录删除 # for key in remainnum_per_class.keys(): # key=classid # if remainnum_per_class[key] > max_student_per_class - 3: # cls_to_del.add(key) # 增加要删除的课id,更新了cls_to_del!!!!!!!!!!!!!!!! # print("13 ", cls_to_del) # # # 在registration_temp里学生的课程列表中,删掉更新后的cls_to_del里面的课id # for key in registration_temp.keys(): # key=studentid # clsids = registration_temp[key] # 每个学生选的一堆课id 的list # index = 0 # while index < len(clsids) and index >= 0: # 每个学生选的一堆课id中的一个 # if clsids[index] in cls_to_del: # print("clsids[index]:", clsids[index]) # clsids.remove(clsids[index]) # index -= 1 # index += 1 # # # 上一步操作后registration_temp里学生的课程列表可能是空的了(学生的至多四个首选课全都没选上),需要删除他 # for key in list(registration_temp.keys()): # key=studentid # if len(registration_temp[key]) == 0: # 这个学生没有选上课,一堆课id删减到为空了(太惨了) # registration_temp.pop(key) # print("14 ", registration_temp) # # # choicelist按照cls_to_del删除记录 # # 第四轮筛选之后的choicelist: # while index < len(choicelist) and index >= 0: # # print(index," " ,choicelist) # if choicelist[index][2] in cls_to_del: # # print("hhh",choicelist[index][2]) # choicelist.remove(choicelist[index]) # index -= 1 # index += 1 # print("15 ", choicelist) # 给主任显示要删除的教学班:需要render现在的cls_to_del print("set", cls_to_del) cursor.close() self.write( json.dumps( { "status": "success", "planid": planid, "cls_to_del": list(cls_to_del), "choicelist": choicelist, "registration_temp": registration_temp, }, ensure_ascii=False, ), )
for temp in uts: user_templates.append((temp, nu)) total_users += nu for temp in its: inter_templates.append(temp) results = [[1, 2, 3]] for rep in range(1, replications + 1): users = b.gen_random_users(n_users, user_templates) test_messages = b.gen_random_inters( n_test_inter_designs, [] ) # TODO: Add specific number of propensity-based interactions if needed. #model.set_data(*b.gen_crossprod_rows(users, test_messages)) all_users, all_inters, all_resps = b.gen_crossprod_rows( users, test_messages) start_time = ut.curr_time() log('Beginning Simulation Interation ' + str(rep), 'standard') best_message, best_count = n_best_inters(all_users, all_inters, all_resps, 1)[0] #ga = GeneticAlgorithm(model.inter_attr_levels(), model.prob_f(), params) f = build_top_n_optimizer(all_users, all_inters, all_resps, 10, model, False) print('ere') optimal_messages = map(lambda u: f(u), users) #optimal_messages = map(lambda u: best_message, users) log( 'Top message: ' + str( (best_message, float(best_count) / float(len(users)))), 'standard') #resps = b.gen_responses(users, map(lambda x: x[0], optimal_messages)) resps = b.gen_responses(users, optimal_messages)
total_users = 0 for (nt, nua, nia, p, nu) in random_propensity_specs: uts, its = b.set_random_propensities(nt, nua, nua, nia, nia, p, p) for temp in uts: user_templates.append((temp, nu)) total_users += nu for temp in its: inter_templates.append(temp) results = [[1,2,3]] for rep in range(1, replications + 1): users = b.gen_random_users(n_users, user_templates) test_messages = b.gen_random_inters(n_test_inter_designs, []) # TODO: Add specific number of propensity-based interactions if needed. #model.set_data(*b.gen_crossprod_rows(users, test_messages)) all_users, all_inters, all_resps = b.gen_crossprod_rows(users, test_messages) start_time = ut.curr_time() log('Beginning Simulation Interation ' + str(rep), 'standard') best_message, best_count = n_best_inters(all_users, all_inters, all_resps, 1)[0] #ga = GeneticAlgorithm(model.inter_attr_levels(), model.prob_f(), params) f = build_top_n_optimizer(all_users, all_inters, all_resps, 10, model, False) print('ere') optimal_messages = map(lambda u: f(u), users) #optimal_messages = map(lambda u: best_message, users) log('Top message: ' + str((best_message, float(best_count)/float(len(users)))), 'standard') #resps = b.gen_responses(users, map(lambda x: x[0], optimal_messages)) resps = b.gen_responses(users, optimal_messages) print(optimal_messages[0]) log('Optimal targeted messages results: ' + str(float(sum(resps)) / float(len(users))), 'standard') write_output_csv(results)
async def post(self, action): if action == "get_class": # 1. 获取所有的课程 classes = self.get_classes() sid = self.get_argument("sid") print("所有的课程为", classes) # 2. 对class按照学生设定的顺序进行排序 cursor = util.con.cursor() sql = "select clsids from student where studentid = %s " cursor.execute(sql, (sid,)) clsids = list(cursor)[0][0] if clsids is not None: # 如果是none是学生没设过排序 # 检查排序的clsid和当前计划的clsid是否完全相同 clsids = json.loads(clsids) curr_plan_clas = set([cls[0] for cls in classes]) print(curr_plan_clas, clsids, set(clsids)) if curr_plan_clas != set(clsids): # 有出入,这个排序无效,清空 sql = "update student set clsids = null where studentid = %s" cursor.execute(sql, (sid,)) util.con.commit() else: # 合法,按照排序修改课程顺序 sorted_class = [] for clsid in clsids: for clas in classes: if clsid == clas[0]: sorted_class.append(clas) break print("sorted_class", sorted_class) classes = sorted_class # 3. 补全class中的老师,课程名称,是否选择信息 for ind in range(len(classes)): classes[ind] = list(classes[ind]) print("curr clas info", classes[ind]) sql = "select name from course where courseid = %s" cursor.execute(sql, (classes[ind][1],)) print(cursor.statement) course_name = list(cursor)[0][0] classes[ind].append(str(course_name)) sql = "select name from teacher where teacherid = %s" cursor.execute(sql, (classes[ind][3],)) print(cursor.statement) teacher_name = list(cursor)[0][0] classes[ind].append(teacher_name) classes[ind].append(util.map_class_time(classes[ind][5])) sql = "select is_1st from choice_temp where studentid = %s and classid = %s" cursor.execute(sql, (sid, classes[ind][0])) print("+_+_+", cursor.statement) is_1st = list(cursor) print("is_1st", is_1st) if len(is_1st) == 0: classes[ind].append(-1) else: classes[ind].append(is_1st[0][0]) print("补全后课程信息", classes[ind]) # 4. 获取选课计划信息 sql = "select * from plan where planid = %s" cursor.execute(sql, (self.get_argument("planid"),)) planinfo = list(list(cursor)[0]) planinfo[5] = planinfo[5].isoformat().replace("T", " ") planinfo[6] = planinfo[6].isoformat().replace("T", " ") print(planinfo) cursor.close() self.write( json.dumps( {"status": "success", "classes": classes, "planinfo": planinfo,}, ensure_ascii=False, ) ) return if action == "set_order": # 设置课程展示顺序, clsids = json.loads(self.get_argument("classids")) sid = self.get_argument("sid") clsids = [int(id) for id in clsids] clsids = json.dumps(clsids) sql = "update student set clsids = %s where studentid = %s " cursor = util.con.cursor() cursor.execute(sql, (clsids, sid)) cursor.close() util.con.commit() planid = self.get_argument("pid") studentid = self.get_argument("sid") order_2nd = self.get_argument("order_2nd") order_2nd = util.purge_list(order_2nd.split(",")) order_2nd = [int(x) for x in order_2nd] unified = [] for id in order_2nd: if id not in unified: unified.append(id) order_2nd = unified order_2nd = [int(x) for x in order_2nd] print("备选的顺序是", order_2nd) cursor = util.con.cursor() sql = "select classid from choice_temp where planid = %s and studentid = %s and is_1st = 0" cursor.execute(sql, (planid, studentid)) sec_ids = list(cursor) sec_ids = [int(x[0]) for x in sec_ids] print("数据库中的备选id", sec_ids) if set(sec_ids) != set(order_2nd): dump_err(self, "保存过程中备选顺序和数据库中备选课程不匹配") cursor.close() return sql = "update choice_temp set priority = %s where classid = %s and planid = %s and studentid = %s" for ind, id in enumerate(sec_ids): cursor.execute(sql, (ind + 5, id, planid, studentid)) print(cursor.statement) util.con.commit() cursor.close() self.write(json.dumps({"status": "success", "message": "选课计划保存成功"})) # 设置备选课程顺序 return if action == "unchoose": planid = self.get_argument("pid") studentid = self.get_argument("sid") classid = self.get_argument("cid") courseid = self.get_argument("courseid") # 1. 获取要退的课的id print(studentid, "正在尝试退", classid) cursor = util.con.cursor() sql = "select choiceid, is_1st from choice_temp where studentid = %s and classid = %s and planid = %s" cursor.execute(sql, (studentid, classid, planid)) print(cursor.statement) choiceid = list(cursor) if len(choiceid) == 0: dump_err(self, "无法退选自己没选的课") cursor.close() return choiceid, is_1st = choiceid[0] print("这个选课记录的id是", choiceid) # 2. 如果是首选要求已经没有备选 if is_1st == 1: print("退的是首选的课程") sql = "select count(choiceid) from choice_temp where studentid = %s and planid = %s and is_1st = 0" cursor.execute(sql, (studentid, planid)) class_count = list(cursor)[0][0] print("备选总数", class_count) if class_count != 0: dump_err(self, "有备选的课程时不能退选首选") cursor.close() return # 3. 解冻账户冻结金额 # # 3.1 看看这门课多少钱 # sql = "select price from course where courseid = %s" # cursor.execute(sql, (courseid,)) # print(cursor.statement) # price = list(cursor)[0][0] # print("课程费用", price) # # # 3.2 解冻金额 # url = util.base_url + "/finance/unfreeze" # body = urllib.parse.urlencode({"studentid": studentid, "amount": price}) # req = tornado.httpclient.HTTPRequest(url, "POST", body=body) # res = await tornado.httpclient.AsyncHTTPClient().fetch(req) # print("freeze", res.body) # 4. 删除课程 sql = "delete from choice_temp where choiceid = %s" cursor.execute(sql, (choiceid,)) util.con.commit() self.write(json.dumps({"status": "success"})) if action == "choose": # 只有学生能访问 util.check_role(self, "student") # 实际进行选课,谁选什么课程 sid = self.get_argument("sid") cid = self.get_argument("cid") is_1st = int(self.get_argument("is_1st")) planid = self.get_argument("pid") courseid = self.get_argument("courseid") print("学生 {} 尝试选 {} 作为 {}".format(sid, cid, is_1st)) """ 所有的这些检查都要分开做,能切换顺序。提升性能的时候把便宜刷的多的放前面 1. 判断选课时间是否合法 2. 检查这个教学班是不是已经选满 3. 检查这个学生这门课是不是选了其他班级 4. 检查是不是选了超过4门首选 5. 检查是不是选了超过2门备选 6. 首选满了才备选 7. 检查是不是选了先修课 扣钱 添加记录 """ """1. 判断选课时间是否合法""" cursor = util.con.cursor() sql = "select start_time, end_time from plan where planid = %s" cursor.execute(sql, (planid,)) time_range = list(cursor) if len(time_range) != 1: print("选课计划不合法", time_range) dump_err(self, "提供的选课计划不合法") cursor.close() return time_range = list(time_range[0]) time_range = [x.isoformat().replace("T", " ") for x in time_range] print("选课计划时间", time_range) curr_time = util.curr_time() print("当前时间", curr_time) if curr_time <= time_range[0]: dump_err(self, "还未到选课开始时间") cursor.close() return if curr_time > time_range[1]: dump_err(self, "选课已经结束") cursor.close() return """2. 检查首选选这个教学班的是不是已经满了""" sql = "select count(choiceid) from choice_temp where is_1st = %s and classid = %s" cursor.execute(sql, (is_1st, cid)) count = list(cursor)[0][0] print("当前首选这门课的人数", count) if count >= 10: dump_err(self, "当前选课人数已经超过10个") cursor.close() return """3. 检查这个学生这门课是不是已经选了这个或者其他班级 """ sql = "select classid from class where planid = %s and courseid = %s" cursor.execute(sql, (planid, courseid)) classes = list(cursor) classes = [x[0] for x in classes] print("这门课的教学班id共有", classes) sql = "select count(choiceid) from choice_temp where classid in (" sql += "%s, " * len(classes) sql = sql[:-2] + ") and planid = %s and studentid = %s" classes.append(planid) classes.append(sid) print(sql) cursor.execute(sql, classes) class_count = list(cursor)[0][0] print("当前学生选了上述班级 {} 次".format(class_count)) if class_count != 0: dump_err(self, "已经选择了这个教学班或者这门课的其他教学班") cursor.close() return """4. 如果首选,检查是不是选了超过4门首选""" sql = "select count(choiceid) from choice_temp where studentid = %s and is_1st = 1" cursor.execute(sql, (sid,)) pri_class_count = list(cursor)[0][0] print("学生当前共选了 {} 门首选".format(pri_class_count)) if is_1st == 1: if pri_class_count >= 4: dump_err(self, "不能选超过4门首选") cursor.close() return """5. 如果备选, 检查是否选了超过2门备选 """ if is_1st == 0: print("choosing 2nd, now chosen", pri_class_count) if pri_class_count != 4: dump_err(self, "首选没选满4门课不能选择备选") cursor.close() return sql = "select count(choiceid) from choice_temp where studentid = %s and is_1st = 0" cursor.execute(sql, (sid,)) class_count = list(cursor)[0][0] print("学生当前共选了 {} 门备选") if class_count >= 2: dump_err(self, "不能选超过2门备选") cursor.close() return """6. 检查是否选了先修课 """ """7. 尝试冻结金额""" # sql = "select price from course where courseid = %s" # cursor.execute(sql, (courseid,)) # print(cursor.statement) # price = list(cursor)[0][0] # print("课程费用", price) # # url = util.base_url + "/finance/freeze" # body = urllib.parse.urlencode({"studentid": sid, "amount": price}) # req = tornado.httpclient.HTTPRequest(url, "POST", body=body) # res = await tornado.httpclient.AsyncHTTPClient().fetch(req) # print("freeze", res.body) """ 在choicetemp表中添加选课记录 """ print("is 1st", is_1st) if is_1st == 1: priority = 1 else: priority = 0 sql = "INSERT INTO `choice_temp`(`studentid`,`classid`,`planid`,`is_1st`, `priority`)VALUES(%s, %s, %s, %s, %s)" cursor.execute(sql, (sid, cid, planid, is_1st, priority)) cursor.close() util.con.commit() self.write(json.dumps({"status": "success", "message": "选课成功"}))
def post(self, action): """删除选课计划""" if action == "delete": planid = self.get_argument("planid") # 1. 如果不存在,不能删除 sql = "select public from plan where planid = %s" cursor = util.con.cursor() cursor.execute(sql, (planid,)) print(cursor.statement) ispublic = list(cursor) print("ispublic", ispublic) if len(ispublic) == 0: dump_err(self, "不能删除不存在的选课计划") cursor.close() return # 2. 如果已公开,不能删除 ispublic = ispublic[0][0] if ispublic == 1: dump_err(self, "不能删除已公开的选课计划") cursor.close() return # 3. 删除教学班 sql = "delete from class where planid = %s" cursor.execute(sql, (planid,)) util.con.commit() # 4. 删除计划记录 sql = "delete from plan where planid = %s" cursor.execute(sql, (planid,)) print("delete plan: ", cursor.statement) util.con.commit() cursor.close() self.write(json.dumps({"status": "success", "message": "选课计划和计划中的教学班删除成功"})) """公开选课计划""" if action == "publish": planid = self.get_argument("planid") cursor = util.con.cursor() # 1. 删除没老师的课程 sql = "select classid from class where planid = %s and teacherid is null " cursor.execute(sql, (planid,)) classes_without_teacher = list(cursor) classes_without_teacher = [x[0] for x in classes_without_teacher] print("没老师的课", classes_without_teacher) if len(classes_without_teacher) != 0: sql = "delete from class where classid in (" + "%s, " * len(classes_without_teacher) sql = sql[:-2] sql = sql + ")" cursor.execute(sql, classes_without_teacher) print(cursor.statement) # 2. 选课计划设置为公开 sql = "update plan set public = 1 where planid = %s" cursor.execute(sql, (planid,)) cursor.close() util.con.commit() msg = "选课计划公开成功" if len(classes_without_teacher) != 0: msg += ",删除了{}".format(classes_without_teacher) self.write(json.dumps({"status": "success", "message": msg,}, ensure_ascii=False,)) return """编辑选课计划""" if action == "save": planid = self.get_argument("planid") curr_time = util.curr_time() start_daytime = ( self.get_argument("start_day") + " " + self.get_argument("start_time") + ":00" ) if start_daytime <= curr_time: dump_err(self, "选课计划开始时间需要晚于当前时间") return if planid == "None": planid = self.insert_plan() else: self.update_plan(planid) # PLAN: 这里判断如果有选课计划(是修改),那么当前选课计划必须还没有发布 self.insert_class(planid) self.update_class(planid) self.del_class(planid) self.write( json.dumps( {"status": "success", "message": "成功添加选课计划", "planid": planid}, ensure_ascii=False, ) )