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)
예제 #3
0
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)
예제 #4
0
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  # 正确量