Пример #1
0
 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
Пример #2
0
    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
Пример #4
0
 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)
Пример #7
0
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 [], {}
Пример #8
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)
Пример #9
0
    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)
Пример #10
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
Пример #11
0
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
Пример #14
0
    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  # 正确量
Пример #17
0
    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()
Пример #18
0
    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