async def post(self): r_dict = {'code': 0} try: query_timestamp = self.i_args.get('query_timestamp', None) query_all = self.i_args.get('query_all', None) data_list = [] if query_all: subject_cursor = Subject.find(dict(record_flag=1)) else: if query_timestamp: query_timestamp = int(query_timestamp) else: query_timestamp = self.client_timestamp query_time = timestamp2datetime(query_timestamp) subject_cursor = Subject.find({ '$and': [ {"record_flag": 1}, {"updated_dt": {'$gte': query_time}}, ] }) while await subject_cursor.fetch_next: subject = subject_cursor.next_object() if subject: data = self.subject_2_dict(subject) if data: data_list.append(data) r_dict['code'] = 1000 r_dict['data_list'] = data_list except RuntimeError: r_dict['code'] = -1 logger.error(traceback.format_exc()) return r_dict
async def post(self, *args, **kwargs): """ 注册科目 :param args: :param kwargs: :return: """ r_dict = {'respBody': '', 'errorCode': 200, 'errorMessage': 'success'} issuer = self.get_i_argument('issuer') category = int(self.get_i_argument('category')) title = self.get_i_argument('title') max_score = int(self.get_i_argument('maxscore')) id_number = self.get_i_argument('idNumber') try: res, tx_hash = fisco_client.fisco_add_data( 'createSubject', [id_number, issuer, category, max_score]) print('tx_hash:', tx_hash) subject = Subject() subject.title = title subject.issuer = issuer subject.category = category subject.max_score = max_score subject.id_number = id_number subject.tx_hash = tx_hash await subject.save() r_dict['respBody'] = res except Exception as e: print(e) return r_dict
def get_dimension_detail(result_list: list): """ :param result_list: :return: """ dimension_detail = {} for result in result_list: for answer in result: subject = Subject.sync_get_by_cid(answer.get('subject_cid')) for fst_dimen, sec_dimen in subject.dimension_dict.items(): if fst_dimen not in dimension_detail: dimension_detail[fst_dimen] = {'total': 0, 'correct': 0} if sec_dimen not in dimension_detail[fst_dimen]: dimension_detail[fst_dimen][sec_dimen] = { 'total': 0, 'correct': 0 } dimension_detail[fst_dimen]['total'] += 1 dimension_detail[fst_dimen][sec_dimen]['total'] += 1 if answer.get('true_answer'): dimension_detail[fst_dimen]['correct'] += 1 dimension_detail[fst_dimen][sec_dimen]['correct'] += 1 return dimension_detail
async def post(self): race_cid = self.get_argument('race_cid', '') r_dict = {'code': 0} try: if race_cid: refer_subject_list = [] exist_refer_subject_list = await RaceSubjectRefer.distinct('subject_cid', filtered={'race_cid': race_cid}) kw_name = self.get_argument('kw_name', '') kw_difficulty = self.get_argument('kw_difficulty', '') category_use = self.get_argument('category_use', '') query_params = {'status': STATUS_SUBJECT_ACTIVE, 'cid': {'$nin': exist_refer_subject_list}} subject_cursor = await Subject.find(filtered=query_params).to_list(None) if kw_name: query_params['$or'] = [ {"custom_code": {'$regex': kw_name, '$options': 'i'}}, {"title": {'$regex': kw_name, '$options': 'i'}}, {"code": {'$regex': kw_name, '$options': 'i'}} ] if kw_difficulty: query_params['difficulty'] = int(kw_difficulty) if category_use: query_params['category'] = int(category_use) subject_cursor = Subject.find(filtered=query_params) while await subject_cursor.fetch_next: subject = subject_cursor.next_object() if not subject: break refer_subject_list.append( RaceSubjectRefer( race_cid=race_cid, subject_cid=subject.cid, title=subject.title, status=subject.status, dimension_dict=subject.dimension_dict, created_dt=datetime.datetime.now(), created_id=self.current_user.oid ) ) if refer_subject_list: await RaceSubjectRefer.insert_many(refer_subject_list) r_dict['code'] = 1 else: r_dict['code'] = -1 except Exception: logger.error(traceback.format_exc()) return r_dict
def _do_get_subjects_detail(history): """ 题目详情 :param history: 会员游戏历史Model :return: """ if history: answer_list = history.result if answer_list: subject_cid_list, subject_answer_dict = [], {} for answer in answer_list: if answer and answer.get('selected_option_cid') and answer.get( 'subject_cid'): subject_cid_list.append(answer.get('subject_cid')) subject_answer_dict[answer.get('subject_cid')] = answer if subject_cid_list: subject_list = Subject.sync_find( dict(cid={'$in': subject_cid_list})).to_list(None) return subject_list, subject_answer_dict return [], {}
def member_daily_dimension_statistics(history, member: Member): result = {'code': 0} try: daily_code, result_list = _get_daily_code(history.fight_datetime), history.result if history.result else [] insert_mdds_list = [] for result in result_list: if result: subject_cid = result.get('subject_cid') if subject_cid: subject = Subject.sync_get_by_cid(subject_cid) if subject and subject.dimension_dict: query = {'daily_code': daily_code, 'member_cid': member.cid} query.update({'dimension.%s' % k: v for k, v in subject.dimension_dict.items()}) mdds = MemberDailyDimensionStatistics.sync_find_one(query) if not mdds: mdds = MemberDailyDimensionStatistics( id=ObjectId(), daily_code=daily_code, member_cid=member.cid, dimension=subject.dimension_dict) insert_mdds_list.append(mdds) if mdds: mdds.province_code = member.province_code mdds.city_code = complete_member_city_code(member.province_code, member.city_code) mdds.district_code = member.district_code mdds.gender = member.sex mdds.age_group = member.age_group mdds.education = member.education mdds.category = member.category mdds.subject_total_quantity += 1 if result.get('true_answer'): mdds.subject_correct_quantity += 1 mdds.created_dt = history.created_dt mdds.updated_dt = history.updated_dt if mdds not in insert_mdds_list: mdds.sync_save() if insert_mdds_list: MemberDailyDimensionStatistics.sync_insert_many(insert_mdds_list) except ValueError: trace_i = traceback.format_exc() result['msg'] = trace_i print(trace_i)
def _do_count_subjects_detail(ds: DockingStatistics, history_model): """ 统计题目详情 :param ds: 统计数据Model :param history_model: 会员游戏历史Model :return: """ if ds and history_model: answer_list = history_model.result if answer_list: subject_cid_list, subject_answer_dict = [], {} for answer in answer_list: if answer and answer.get('selected_option_cid') and answer.get( 'subject_cid'): subject_cid_list.append(answer.get('subject_cid')) subject_answer_dict[answer.get('subject_cid')] = answer if subject_cid_list: subject_list = Subject.sync_find( dict(cid={'$in': subject_cid_list})).to_list(None) if subject_list: for subject in subject_list: answer = subject_answer_dict.get(subject.cid) if answer: if ds.subjects_detail is None: ds.subjects_detail = {} if ds.subjects_detail.get(subject.code) is None: ds.subjects_detail[subject.code] = {} if not ds.subjects_detail[subject.code].get( 'total'): ds.subjects_detail[subject.code]['total'] = 0 if not ds.subjects_detail[subject.code].get( 'correct'): ds.subjects_detail[subject.code]['correct'] = 0 ds.subjects_detail[subject.code]['total'] += 1 if answer.get('true_answer'): ds.subjects_detail[ subject.code]['correct'] += 1 return subject_list, subject_answer_dict return [], {}
def member_learning_day_dimension_statistics(history, member: Member): try: learning_code, result_list = _sync_get_learning_code(history), history.result if history.result else [] insert_mldds_list = [] for result in result_list: if result: subject_cid = result.get('subject_cid') if subject_cid: subject = Subject.sync_get_by_cid(subject_cid) if subject and subject.dimension_dict: query = {'learning_code': learning_code, 'member_cid': member.cid} query.update({'dimension.%s' % k: v for k, v in subject.dimension_dict.items()}) mldds = MemberLearningDayDimensionStatistics.sync_find_one(query, read_preference=ReadPreference.PRIMARY) if not mldds: mldds = MemberLearningDayDimensionStatistics( id=ObjectId(), learning_code=learning_code, member_cid=member.cid, dimension=subject.dimension_dict) insert_mldds_list.append(mldds) if mldds: mldds.province_code = member.province_code mldds.city_code = complete_member_city_code(member.province_code, member.city_code) mldds.district_code = member.district_code mldds.gender = member.sex mldds.age_group = member.age_group mldds.education = member.education mldds.category = member.category mldds.subject_total_quantity += 1 if result.get('true_answer'): mldds.subject_correct_quantity += 1 mldds.created_dt = history.created_dt mldds.updated_dt = history.updated_dt if mldds not in insert_mldds_list: mldds.sync_save() if insert_mldds_list: MemberLearningDayDimensionStatistics.sync_insert_many(insert_mldds_list) except ValueError: trace_i = traceback.format_exc() print(trace_i)
def __query(self, dimension_cid_pair_list: list = None, length=6): query_params = { 'status': STATUS_SUBJECT_ACTIVE, 'category_use': { '$nin': [CATEGORY_SUBJECT_BENCHMARK, CATEGORY_SUBJECT_GRADUATION] } } if self.__option_condition_list: for option_condition in self.__option_condition_list: query_params['dimension_dict.%s' % option_condition[0]] = { '$in': option_condition[1] } if dimension_cid_pair_list: for dimension_cid_pair in dimension_cid_pair_list: query_params['dimension_dict.%s' % dimension_cid_pair[0]] = dimension_cid_pair[1] match_stage = MatchStage(query_params) sample_stage = SampleStage(length) return Subject.sync_aggregate([match_stage, sample_stage]).to_list(None)
def do_init_member_stat(pre_match: dict = {}, skip_num=0, limit_num=0, just_return_count=False): """ :param pre_match: :param skip_num: :param limit_num: :param just_return_count: :return: """ if not isinstance(just_return_count, bool): raise Exception('check params(just_return_count)') stage_list = [] if pre_match: stage_list.append(MatchStage(pre_match)) stage_list.extend([ UnwindStage("result"), LookupStage(Member, 'member_cid', 'cid', 'member_list'), MatchStage({'member_list': { '$ne': list() }}), ProjectStage( **{ 'subject_cid': '$result.subject_cid', 'province_code': { '$arrayElemAt': ['$member_list.province_code', 0] }, 'city_code': { '$arrayElemAt': ['$member_list.city_code', 0] }, 'district_code': { '$arrayElemAt': ['$member_list.district_code', 0] }, 'sex': { '$arrayElemAt': ['$member_list.sex', 0] }, 'age_group': { '$arrayElemAt': ['$member_list.age_group', 0] }, 'category': { '$arrayElemAt': ['$member_list.category', 0] }, 'education': { '$arrayElemAt': ['$member_list.education', 0] }, 'true_answer': { '$cond': { 'if': { '$eq': ['$result.true_answer', True] }, 'then': True, 'else': False } }, 'created_dt': '$created_dt' }), GroupStage( { 'subject_cid': '$subject_cid', 'province_code': '$province_code', 'city_code': '$city_code', 'district_code': '$district_code', 'sex': '$sex', 'age_group': '$age_group', 'category': '$category', 'education': '$education', }, answers_list={'$push': '$true_answer'}, created_dt={'$first': '$created_dt'}), ]) if just_return_count: stage_list.append(CountStage()) data = MemberGameHistory.sync_aggregate( stage_list, read_preference=ReadPreference.PRIMARY, allowDiskUse=True).to_list(1) return data[0].count stage_list.append(SortStage([('created_dt', ASC)])) if skip_num: stage_list.append(SkipStage(skip_num)) if limit_num: stage_list.append(LimitStage(limit_num)) cursor = MemberGameHistory.sync_aggregate( stage_list, read_preference=ReadPreference.PRIMARY, allowDiskUse=True).batch_size(256) index = 0 _subject_map = {} while True: try: data = cursor.next() subject_cid = data.id.get('subject_cid') subject = _subject_map.get(subject_cid) if not subject: subject = Subject.sync_get_by_cid(subject_cid) _subject_map[subject_cid] = subject write_member_subject_stat(data, subject) index += 1 print('has exec %s' % index) except StopIteration: break except Exception: print(traceback.format_exc()) continue
def get_stages(group_dict=None, skip_num=None): """ :param group_dict: :param skip_num: :return: """ if not group_dict or skip_num is None: logger.error('there is not group_dict(%s) or skip_num(%s)' % (group_dict, skip_num)) raise ValueError() inactive_subject_cids = Subject.sync_distinct( 'cid', { '$or': [{ 'status': STATUS_SUBJECT_INACTIVE }, { 'category_use': { '$in': [CATEGORY_SUBJECT_BENCHMARK, CATEGORY_SUBJECT_GRADUATION] } }] }) inactive_sbj = MatchStage({'subject_cid': {'$nin': inactive_subject_cids}}) group_stage = GroupStage(group_dict, t_total={'$sum': '$total'}, t_correct={'$sum': '$correct'}, created_dt={'$max': '$created_dt'}) sort_stage = SortStage([('t_total', DESC), ('t_correct', DESC), ('created_dt', ASC)]) project_stage = ProjectStage(total='$t_total', correct='$t_correct', percent={ '$cond': { 'if': { '$eq': ['$t_total', 0] }, 'then': 0, 'else': { '$divide': ['$t_correct', '$t_total'] } } }) s_lookup_stage = LookupStage(Subject, as_list_name='subject_list', let={'subject_id': "$_id.subject_cid"}, pipeline=[{ '$match': { '$expr': { '$and': [{ '$eq': ['$cid', '$$subject_id'] }] } } }]) so_lookup_stage = LookupStage( SubjectOption, as_list_name='subject_option_list', let={'subject_id': "$_id.subject_cid"}, pipeline=[{ '$match': { '$expr': { '$and': [{ '$eq': ['$subject_cid', '$$subject_id'] }] } } }, { '$sort': { 'code': ASC } }]) match_stage = MatchStage({ 'subject_list': { '$ne': [] }, 'subject_option_list': { '$ne': [] } }) project_stage2 = ProjectStage( **{ 'custom_code': { '$arrayElemAt': ['$subject_list.custom_code', 0] }, 'code': { '$arrayElemAt': ['$subject_list.code', 0] }, 'title': { '$arrayElemAt': ['$subject_list.title', 0] }, 'option_list': '$subject_option_list', 'dimension': { '$arrayElemAt': ['$subject_list.dimension_dict', 0] }, 'total': '$total', 'correct': '$correct' }) skip_stage = SkipStage(skip_num) limit_stage = LimitStage(10000) return [ inactive_sbj, group_stage, sort_stage, skip_stage, limit_stage, project_stage, s_lookup_stage, so_lookup_stage, match_stage, project_stage2 ]
def member_learning_day_dimension_statistics(self, history, member: Member): result = {'code': 0} if history and member and allowed_process( KEY_ALLOW_TASK_MEMBER_LEARNING_DAY_DIMENSION_STATISTICS): try: logger.info( 'START MEMBER_LEARNING_DAY_DIMENSION_STATISTICS(%s): history_cid=%s' % (self.request.id if self.request.id else '-', history.cid)) learning_code, result_list = _sync_get_learning_code( history), history.result if history.result else [] insert_mldds_list = [] for result in result_list: if result: subject_cid = result.get('subject_cid') if subject_cid: subject = Subject.sync_get_by_cid(subject_cid) if subject and subject.dimension_dict: query = { 'learning_code': learning_code, 'member_cid': member.cid } query.update({ 'dimension.%s' % k: v for k, v in subject.dimension_dict.items() }) mldds = MemberLearningDayDimensionStatistics.sync_find_one( query, read_preference=ReadPreference.PRIMARY) if not mldds: mldds = MemberLearningDayDimensionStatistics( id=ObjectId(), learning_code=learning_code, member_cid=member.cid, dimension=subject.dimension_dict) insert_mldds_list.append(mldds) if mldds: mldds.province_code = member.province_code mldds.city_code = complete_member_city_code( member.province_code, member.city_code) mldds.district_code = member.district_code mldds.gender = member.sex mldds.age_group = member.age_group mldds.education = member.education mldds.category = member.category mldds.subject_total_quantity += 1 if result.get('true_answer'): mldds.subject_correct_quantity += 1 mldds.created_dt = history.fight_datetime mldds.updated_dt = history.fight_datetime if mldds not in insert_mldds_list: mldds.sync_save() if insert_mldds_list: MemberLearningDayDimensionStatistics.sync_insert_many( insert_mldds_list) logger.info( 'END MEMBER_LEARNING_DAY_DIMENSION_STATISTICS(%s): result_code=%s' % (self.request.id if self.request.id else '-', result.get('code'))) except ValueError: trace_i = traceback.format_exc() result['msg'] = trace_i logger.error(trace_i) finally: release_process( KEY_ALLOW_TASK_MEMBER_LEARNING_DAY_DIMENSION_STATISTICS) return result
def member_subject_statistics(self, history, answer: dict, member: Member): """ 会员题目统计分析 :param self: 任务对象 :param history: 历史 :param answer: 答案 :param member: 会员 :return: """ result = {'code': 0} if history and answer and member and allowed_process( KEY_ALLOW_TASK_MEMBER_SUBJECT_STATISTICS): try: logger.info( 'START MEMBER_SUBJECT_STATISTICS(%s): history_cid=%s' % (self.request.id if self.request.id else '-', history.cid)) mds = MemberSubjectStatistics.sync_find_one( dict(province_code=member.province_code, city_code=member.city_code, district_code=member.district_code, gender=member.sex, age_group=member.age_group, education=member.education, category=member.category, subject_cid=answer.get('subject_cid'))) if not mds: mds = MemberSubjectStatistics( province_code=member.province_code, city_code=member.city_code, district_code=member.district_code, gender=member.sex, age_group=member.age_group, education=member.education, category=member.category, subject_cid=answer.get('subject_cid')) subject = Subject.sync_get_by_cid(mds.subject_cid) mds.dimension = subject.dimension_dict mds.province_code = member.province_code mds.city_code = member.city_code mds.district_code = member.district_code mds.gender = member.sex mds.age_group = member.age_group mds.education = member.education mds.category = member.category # 统计题目正确率 _do_member_subject_accuracy(answer, mds) # 保存结果 mds.created_dt = history.fight_datetime mds.updated_dt = history.fight_datetime mds.sync_save() logger.info('END MEMBER_SUBJECT_STATISTICS(%s): result_code=%s' % (self.request.id if self.request.id else '-', result.get('code'))) except ValueError: trace_i = traceback.format_exc() result['msg'] = trace_i logger.error(trace_i) finally: release_process(KEY_ALLOW_TASK_MEMBER_SUBJECT_STATISTICS) return result
async def __subject_import_excel(self, excel_file_content): result_code = 1 custom_code_list = await Subject.distinct('custom_code', {'record_flag': 1}) book = xlrd.open_workbook(file_contents=excel_file_content) sheet = book.sheet_by_index(0) subject_list = [] subject_option_list = [] row_list = [] k_first_dict = dict(zip(KNOWLEDGE_FIRST_LEVEL_DICT.values(), KNOWLEDGE_FIRST_LEVEL_DICT.keys())) k_second_dict = dict(zip(KNOWLEDGE_SECOND_LEVEL_DICT.values(), KNOWLEDGE_SECOND_LEVEL_DICT.keys())) # 维度信息 field_dict = {'record_flag': 1, 'status': STATUS_SUBJECT_DIMENSION_ACTIVE, 'parent_cid': {'$in': ['', None]}} all_dimension_list = await SubjectDimension.find(field_dict).to_list(None) sub_dict = dict(record_flag=1, status=STATUS_SUBJECT_DIMENSION_ACTIVE) subject_dimension_dict = {} for subject_dimension in all_dimension_list: sub_dict['parent_cid'] = subject_dimension.cid sub_dimension_list = await SubjectDimension.find(sub_dict).to_list(None) if sub_dimension_list: subject_dimension_dict[subject_dimension.cid] = sub_dimension_list # 按顺序得到表头对应的维度cid(如果题目表头除维度之外有增减,3就随之改变) cid_list = [] title_list = [] is_empty = 0 for ind, col in enumerate(sheet.row_values(0)): if col: title_list.append(col) if 3 < ind < (len(all_dimension_list) + 4): if not col: is_empty = 1 flag = 1 for dimension in all_dimension_list: if dimension.title == str(self.__get_replace_data(col, 2)): flag = 2 cid_list.append(dimension.cid) break if flag == 1: continue if (ind < len(cid_list) + 8) and not col: is_empty = 1 # 判断表头是否正确(如果题目表头除维度之外有增减,8就随之改变) if not (len(cid_list) + 8) == len(title_list) or len(cid_list) < 1 or is_empty: result_code = 2 return result_code for rownum in range(1, sheet.nrows): row_list.append([col for col in sheet.row_values(rownum)]) if row_list: for i, row_data in enumerate(row_list): is_exist = 0 # 题目ID custom_code = str(self.__get_replace_data(row_data[1], 2)) if not custom_code or len(custom_code) > 20 or len(custom_code) < 5: continue else: reg = re.compile(r'^[a-zA-Z0-9]*$') if not bool(reg.match(custom_code)): continue if custom_code not in custom_code_list: subject = Subject() subject_code = str(get_increase_code(KEY_INCREASE_SUBJECT_CODE)) subject.code = subject_code subject.custom_code = custom_code subject.status = STATUS_SUBJECT_ACTIVE custom_code_list.append(custom_code) else: subject = await Subject.find_one(dict(custom_code=custom_code)) # await SubjectOption.delete_many({'subject_cid': subject.cid}) subject.updated_dt = datetime.datetime.now() is_exist = 1 # 一级知识点 subject.knowledge_first = self.__get_replace_data(row_data[2], 1, data_dict=k_first_dict) # 二级知识点 subject.knowledge_second = self.__get_replace_data(row_data[3], 1, data_dict=k_second_dict) # 知识维度 dimension_dict = {} is_wrong = 0 end_dimension_len = 4 + len(cid_list) for index in range(4, end_dimension_len): c_code = self.__get_replace_data(row_data[index], 2) cid = cid_list[index - 4] if cid and c_code: sub_list = subject_dimension_dict.get(cid) if sub_list: is_wrong = 0 for sub_dimension in sub_list: if sub_dimension.code == c_code: is_wrong = 1 dimension_dict[cid] = sub_dimension.cid break if not is_wrong: result_code = 3 is_wrong = 0 break if dimension_dict and is_wrong: subject.dimension_dict = dimension_dict else: continue # 答案解析 resolving = self.__get_replace_data(row_data[end_dimension_len], 2) if not resolving: continue else: subject.resolving = resolving # 题目 title = self.__get_replace_data(row_data[end_dimension_len + 1], 2) if not title: continue else: subject.title = title # 答案 count = 0 if not row_data[end_dimension_len + 2]: continue else: if not row_data[end_dimension_len + 2].strip().isalpha() or len( row_data[end_dimension_len + 2].strip()) > 1: continue count = ord(row_data[end_dimension_len + 2].strip().upper()) - 64 if (count + end_dimension_len + 2) > len(row_data): continue else: if not row_data[count + end_dimension_len + 2]: continue # 选项 num = 0 tmp_option_list = await SubjectOption.find({'subject_cid': subject.cid}).sort([('sort', ASC)]).to_list( None) for index in range(end_dimension_len + 3, len(row_data)): if row_data[index]: option_title = self.__get_replace_data(row_data[index], 2) if not option_title: continue else: sort = index - (end_dimension_len + 2) a_index = sort - 1 update, subject_option = False, None if tmp_option_list: if len(tmp_option_list) > a_index: subject_option = tmp_option_list[a_index] update = True if subject_option is None: subject_option = SubjectOption( code=str(get_increase_code(KEY_INCREASE_SUBJECT_OPTION_CODE))) if isinstance(option_title, (float, int)): option_title = str(option_title) subject_option.title = option_title subject_option.sort = sort if sort == count: subject_option.correct = True else: subject_option.correct = False subject_option.subject_code = subject.code subject_option.subject_cid = subject.cid if update: subject_option.updated_dt = datetime.datetime.now() subject_option.updated_id = self.current_user.oid subject_option.needless = {} await subject_option.save() else: subject_option_list.append(subject_option) num += 1 subject.needless = {'option_quantity': num} if is_exist: await subject.save() else: subject_list.append(subject) if len(subject_list) == 500: await Subject.insert_many(subject_list) subject_list = [] if len(subject_option_list) == 500: await SubjectOption.insert_many(subject_option_list) subject_option_list = [] if subject_list: await Subject.insert_many(subject_list) if subject_option_list: await SubjectOption.insert_many(subject_option_list) return result_code
def do_count_member_subject_accuracy(accuracy_stat: MemberAccuracyStatistics, history_model, member: Member): """ 统计会员答题正确率 :param accuracy_stat: 统计结果Model :param history_model: 游戏历史Model :param member: 会员Model :return: """ if accuracy_stat and history_model and member: answer_results = history_model.result if answer_results: for answer in answer_results: if answer: selected_option_cid = answer.get('selected_option_cid') if selected_option_cid: subject_cid = answer.get('subject_cid') correct = answer.get('true_answer') if subject_cid: accuracy_stat.total_quantity += 1 if correct: accuracy_stat.correct_quantity += 1 subject = Subject.sync_get_by_cid(subject_cid) if subject: dimension_dict = subject.dimension_dict if dimension_dict: for p_dimension_cid, dimension_cid in dimension_dict.items(): dimension = accuracy_stat.dimension if dimension is None: accuracy_stat.dimension = {} # 冗余根维度信息 if dimension.get(p_dimension_cid) is None: dimension[p_dimension_cid] = {} p_dimension: SubjectDimension = SubjectDimension.sync_get_by_cid( p_dimension_cid) if p_dimension: if p_dimension.code: dimension[p_dimension_cid]['code'] = p_dimension.code if p_dimension.title: dimension[p_dimension_cid]['title'] = p_dimension.title if p_dimension.ordered: dimension[p_dimension_cid]['ordered'] = p_dimension.ordered dimension[p_dimension_cid]['children'] = {} # 根维度统计 if dimension[p_dimension_cid].get('total') is None: dimension[p_dimension_cid]['total'] = 0 if dimension[p_dimension_cid].get('correct') is None: dimension[p_dimension_cid]['correct'] = 0 dimension[p_dimension_cid]['total'] += 1 # 总量 if correct: dimension[p_dimension_cid]['correct'] += 1 # 正确量 children = dimension[p_dimension_cid]['children'] # 冗余子维度信息 if children.get(dimension_cid) is None: children[dimension_cid] = {} c_dimension: SubjectDimension = SubjectDimension.sync_get_by_cid(dimension_cid) if c_dimension: if c_dimension.code: children[dimension_cid]['code'] = c_dimension.code if c_dimension.title: children[dimension_cid]['title'] = c_dimension.title if c_dimension.ordered: children[dimension_cid]['ordered'] = c_dimension.ordered # 子维度统计 if children[dimension_cid].get('total') is None: children[dimension_cid]['total'] = 0 if children[dimension_cid].get('correct') is None: children[dimension_cid]['correct'] = 0 children[dimension_cid]['total'] += 1 # 总量 if correct: children[dimension_cid]['correct'] += 1 # 正确量
def do_count_dimension_accuracy(answer: dict, accuracy_stat: SubjectAccuracyStatistics): """ 计算维度正确率 :param answer: 答案 :param accuracy_stat: 统计Model :return: """ if answer and accuracy_stat: selected_option_cid = answer.get('selected_option_cid') if selected_option_cid: correct = answer.get('true_answer') subject_cid = answer.get('subject_cid') # 统计维度 if subject_cid: subject = Subject.sync_get_by_cid(subject_cid) if subject: dimension_dict = subject.dimension_dict if dimension_dict: for p_dimension_cid, dimension_cid in dimension_dict.items(): dimension = accuracy_stat.dimension if dimension is None: accuracy_stat.dimension = {} # 冗余根维度信息 if dimension.get(p_dimension_cid) is None: dimension[p_dimension_cid] = {} p_dimension: SubjectDimension = SubjectDimension.sync_get_by_cid(p_dimension_cid) if p_dimension: if p_dimension.code: dimension[p_dimension_cid]['code'] = p_dimension.code if p_dimension.title: dimension[p_dimension_cid]['title'] = p_dimension.title if p_dimension.ordered: dimension[p_dimension_cid]['ordered'] = p_dimension.ordered dimension[p_dimension_cid]['children'] = {} # 根维度统计 if dimension[p_dimension_cid].get('total') is None: dimension[p_dimension_cid]['total'] = 0 if dimension[p_dimension_cid].get('correct') is None: dimension[p_dimension_cid]['correct'] = 0 dimension[p_dimension_cid]['total'] += 1 # 总量 if correct: dimension[p_dimension_cid]['correct'] += 1 # 正确量 children = dimension[p_dimension_cid]['children'] # 冗余子维度信息 if children.get(dimension_cid) is None: children[dimension_cid] = {} c_dimension: SubjectDimension = SubjectDimension.sync_get_by_cid(dimension_cid) if c_dimension: if c_dimension.code: children[dimension_cid]['code'] = c_dimension.code if c_dimension.title: children[dimension_cid]['title'] = c_dimension.title if c_dimension.ordered: children[dimension_cid]['ordered'] = c_dimension.ordered # 子维度统计 if children[dimension_cid].get('total') is None: children[dimension_cid]['total'] = 0 if children[dimension_cid].get('correct') is None: children[dimension_cid]['correct'] = 0 children[dimension_cid]['total'] += 1 # 总量 if correct: children[dimension_cid]['correct'] += 1 # 正确量
async def get(self): dark_skin = self.get_argument('dark_skin') dark_skin = True if dark_skin == 'True' else False category_cid, difficulty_cid, knowledge_cid = None, None, None subject_dimension_list = await SubjectDimension.find( dict(parent_cid=None, status=STATUS_SUBJECT_DIMENSION_ACTIVE)).to_list(None) for subject_dimension in subject_dimension_list: if subject_dimension: if subject_dimension.code == 'CSK001': category_cid = subject_dimension.cid if subject_dimension.code == 'CSD001': difficulty_cid = subject_dimension.cid if subject_dimension.code == 'CDS001': knowledge_cid = subject_dimension.cid knowledge_dimension_list = await SubjectDimension.find( dict(parent_cid=knowledge_cid)).sort([('ordered', ASC)] ).to_list(None) category_dimension_list = await SubjectDimension.find( dict(parent_cid=category_cid)).sort([('ordered', ASC)] ).to_list(None) second_dimension_list = await SubjectDimension.find( dict(parent_cid={'$ne': None})).sort([('ordered', ASC)] ).to_list(None) dimension_mapping = json.dumps({ second_dimension.cid: second_dimension.parent_cid for second_dimension in second_dimension_list }) match_stage = MatchStage( dict(status=STATUS_SUBJECT_ACTIVE, category_use={ '$nin': [CATEGORY_SUBJECT_BENCHMARK, CATEGORY_SUBJECT_GRADUATION] })) group_stage = GroupStage( dict(category='$dimension_dict.%s' % category_cid, difficulty='$dimension_dict.%s' % difficulty_cid, knowledge='$dimension_dict.%s' % knowledge_cid)) sort_stage = SortStage([('_id.difficulty', ASC), ('_id.knowledge', ASC), ('_id.category', ASC)]) subject_lookup_stage = LookupStage( foreign=Subject, let={ 'difficulty': '$_id.difficulty', 'knowledge': '$_id.knowledge', 'category': '$_id.category' }, pipeline=[{ '$match': { '$expr': { '$and': [{ '$eq': ['$status', STATUS_SUBJECT_ACTIVE] }, { '$in': [ '$category_use', [CATEGORY_SUBJECT_GENERAL, None] ] }, { '$eq': [ '$dimension_dict.%s' % difficulty_cid, '$$difficulty' ] }, { '$eq': [ '$dimension_dict.%s' % knowledge_cid, '$$knowledge' ] }, { '$eq': [ '$dimension_dict.%s' % category_cid, '$$category' ] }] } } }, { '$group': { '_id': None, 'count': { '$sum': 1 } } }], as_list_name='quantity_list', ) difficulty_lookup_stage = LookupStage(SubjectDimension, '_id.difficulty', 'cid', 'difficulty_list') knowledge_lookup_stage = LookupStage(SubjectDimension, '_id.knowledge', 'cid', 'knowledge_list') category_lookup_stage = LookupStage(SubjectDimension, '_id.category', 'cid', 'category_list') project_stage = ProjectStage( **{ '_id': False, 'm_difficulty': { 'cid': '$_id.difficulty', 'code': '$difficulty_list.code', 'title': '$difficulty_list.title', 'ordered': '$difficulty_list.ordered' }, 'm_knowledge': { 'cid': '$_id.knowledge', 'code': '$knowledge_list.code', 'title': '$knowledge_list.title', 'ordered': '$knowledge_list.ordered' }, 'm_category': { 'cid': '$_id.category', 'code': '$category_list.code', 'title': '$category_list.title', 'ordered': '$category_list.ordered' }, 'count': '$quantity_list.count' }) subject_cursor = Subject.aggregate([ match_stage, group_stage, sort_stage, subject_lookup_stage, difficulty_lookup_stage, knowledge_lookup_stage, category_lookup_stage, project_stage ]) data: dict = await self.do_generate_data_structs(subject_cursor) return locals()
async def post(self): r_dict = {'code': 0} subject_id = None try: title = self.get_argument('title', None) option_str = self.get_argument('option_list', None) option_list = json.loads(option_str) if option_str else [] # difficulty = self.get_argument('difficulty', None) # category = self.get_argument('category', None) content = self.get_argument('content', None) status = self.get_argument('status', None) # 状态 knowledge_first = self.get_argument('knowledge_first', None) knowledge_second = self.get_argument('knowledge_second', None) category_use = self.get_argument('category_use', None) resolving = self.get_argument('resolving', None) subject_dimension_list = self.get_arguments('subject_dimension') custom_code = self.get_argument('custom_code', None) if title and len(option_list) >= 2 and resolving and custom_code: c_count = await Subject.count(dict(custom_code=custom_code)) if c_count > 0: r_dict['code'] = -10 else: if status == 'on': status = STATUS_SUBJECT_ACTIVE else: status = STATUS_SUBJECT_INACTIVE image_cid = None image_cid_list = await save_upload_file(self, 'image', category=CATEGORY_UPLOAD_FILE_IMG_SUBJECT) if image_cid_list: image_cid = image_cid_list[0] code = get_increase_code(KEY_INCREASE_SUBJECT_CODE) # subject = Subject(code=code, title=title, difficulty=int(difficulty), category=int(category)) subject = Subject(code=code, title=title) subject.custom_code = custom_code subject.image_cid = image_cid subject.status = status subject.content = content subject.created_id = self.current_user.oid subject.updated_id = self.current_user.oid subject.resolving = resolving knowledge_first = int(knowledge_first) if knowledge_first else None knowledge_second = int(knowledge_second) if knowledge_second else None subject.knowledge_first = knowledge_first subject.knowledge_second = knowledge_second subject.category_use = int(category_use) if category_use else None subject_dimension_dict = {} if subject_dimension_list: for subject_dimension in subject_dimension_list: try: subject_dimension_cid, sub_subject_dimension_cid = subject_dimension.split('_') subject_dimension_dict[subject_dimension_cid] = sub_subject_dimension_cid except ValueError as e: if subject_dimension != 'DFKX': raise e subject.dimension_dict = subject_dimension_dict # 冗余信息 if not isinstance(subject.needless, dict): subject.needless = {} subject.needless['option_quantity'] = len(option_list) if option_list: subject_id = await subject.save() for index, option_dict in enumerate(option_list): if option_dict: so = SubjectOption(subject_cid=subject.cid, code=str(index + 1), title=option_dict.get('content'), correct=option_dict.get('is_correct')) so.sort = str(index + 1) so.created_id = self.current_user.oid so.updated_id = self.current_user.oid await so.save() await set_subject_choice_rules_redis_value(1) r_dict['code'] = 1 else: if not title: r_dict['code'] = -1 # if not difficulty: # r_dict['code'] = -4 # if not category: # r_dict['code'] = -5 if not resolving: r_dict['code'] = -8 if not option_list and len(option_list) < 2: r_dict['code'] = -6 if not custom_code: r_dict['code'] = -9 if not category_use: r_dict['code'] = -11 except Exception as e: if subject_id: subject = await Subject.get_by_id(subject_id) if subject: await Subject.delete_by_ids([subject.oid]) await Subject.delete_many({'code': subject.code}) logger.error(traceback.format_exc()) return r_dict