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
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 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 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 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
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 # 正确量