Пример #1
0
def user_training_model_sync(user_id):
    app.logger.info(f'user_training_model_sync service called for user: {user_id}')
    for count in range(0, 3):
        sync_category_score_for_user(user_id)
    # FIXITLATER:
    # NEED TO FIX THIS LATER, MIGHT NEED TO APPLY RECURSION IN A DAG.
    # THE CATEGORY DEPENDENCY LIST MUST FORM A DAG. NEED TO WRITE SCRIPT TO VERIFY.

    app.logger.info('sync_category_score_for_user done')

    skill_value = sync_root_category_score_for_user(user_id)
    app.logger.info('sync_root_category_score_for_user done')

    app.logger.info('sync_overall_stat_for_user done')
    sync_overall_stat_for_user(user_id, skill_value)

    skill = Skill()
    user_skill_level = skill.get_skill_level_from_skill(skill_value)
    sync_problem_score_for_user(user_id, user_skill_level)
    app.logger.info('sync_problem_score_for_user done')

    notification_data = {
        'user_id': user_id,
        'sender_id': 'System',
        'notification_type': 'System Notification',
        'redirect_url': '',
        'notification_text': 'Your training model has been synced by',
        'status': 'UNREAD',
    }
    add_notification(notification_data)
def sync_overall_stat_for_team(team_id, skill_value=None):
    try:
        team_details = get_team_details(team_id)
        mark_problem = {}
        solve_count = 0
        for member in team_details['member_list']:
            user_details = get_user_details_by_handle_name(
                member['user_handle'])
            if user_details is None:
                continue
            user_id = user_details['id']
            problem_list = find_problems_for_user_by_status_filtered(
                ['SOLVED'], user_id)
            for problem in problem_list:
                if problem not in mark_problem:
                    mark_problem[problem] = 1
                    solve_count += 1

        if skill_value is None:
            skill_value = generate_skill_value_for_user(team_id)
        skill_obj = Skill()
        skill_title = skill_obj.get_skill_title(skill_value)
        skill_data = {
            'skill_value': int(skill_value),
            'solve_count': int(solve_count),
            'skill_title': skill_title,
        }
        app.logger.info('Team final stat to update: ' + json.dumps(skill_data))
        update_team_details(team_id, skill_data)
    except Exception as e:
        raise e
Пример #3
0
def team_list_sync():
    team_list = search_teams({}, 0, _es_size)
    for team in team_list:
        id = team['id']
        team_training_model_sync(id)
        details_info = get_team_details(id)
        member_id_list = []
        for member in details_info['member_list']:
            member_id_list.append(member['user_id'])

        skill_value = details_info.get('skill_value', 0)
        solve_count = details_info.get('solve_count', 0)
        previous_problem_score = details_info['total_score']
        current_problem_score = get_total_problem_score_for_user(
            member_id_list)
        updated_data = {'total_score': current_problem_score}
        decrease_factor = 0
        if current_problem_score < previous_problem_score + details_info[
                'target_score']:
            decrease_amount = previous_problem_score + details_info[
                'target_score'] - current_problem_score
            decrease_factor = math.sqrt(decrease_amount)

        skill = Skill()
        updated_data['decreased_skill_value'] = details_info[
            'decreased_skill_value'] + decrease_factor
        current_skill = skill_value - updated_data['decreased_skill_value']
        current_skill_level = skill.get_skill_level_from_skill(current_skill)
        updated_data['target_score'] = skill.generate_next_week_prediction(
            current_skill_level)
        add_user_ratings(id, current_skill, solve_count)
        update_team_details(id, updated_data)
    app.logger.info(f'team_list_sync completed')
Пример #4
0
def team_training_model_sync(team_id):
    app.logger.info(f'team_training_model_sync service called for team: {team_id}')
    app.logger.info('sync sync_category_score_for_team')
    sync_category_score_for_team(team_id)
    app.logger.info('sync sync_root_category_score_for_team')
    skill_value = sync_root_category_score_for_team(team_id)
    app.logger.info('sync sync_overall_stat_for_team')
    sync_overall_stat_for_team(team_id, skill_value)
    skill = Skill()
    user_skill_level = skill.get_skill_level_from_skill(skill_value)
    app.logger.info('sync get_skill_level_from_skill done')
    sync_problem_score_for_team(team_id, user_skill_level)
    app.logger.info('sync sync_problem_score_for_team done')

    team_details = get_team_details(team_id)
    app.logger.info(f' end team_details{team_details}')
    member_list = team_details.get('member_list', [])
    for member in member_list:
        member_details = get_user_details_by_handle_name(member['user_handle'])
        app.logger.info(f' member_details {member_details}')
        notification_data = {
            'user_id': member_details['id'],
            'sender_id': 'System',
            'notification_type': 'System Notification',
            'redirect_url': '',
            'notification_text': 'Training model for your team ' + team_details['team_name'] + ' has been synced by',
            'status': 'UNREAD',
        }
        app.logger.info(f' add_notification {notification_data}')
        add_notification(notification_data)
    app.logger.info(f'team_training_model_sync service completed')
Пример #5
0
def reformat_user_data(data, rank=1):
    skill = Skill()
    data['skill_value'] = data.get('skill_value', 0) - data.get(
        'decreased_skill_value', 0)
    data['skill_value'] = float("{:.2f}".format(data['skill_value']))
    data['skill_color'] = skill.get_color_from_skill_title(
        data.get('skill_title', 'NA'))
    data['decreased_skill_value'] = float("{:.2f}".format(
        data.get('decreased_skill_value', 0)))
    data['total_score'] = float("{:.2f}".format(data.get('total_score', 0)))
    data['target_score'] = float("{:.2f}".format(data.get('target_score', 0)))
    data['next_week_target'] = float("{:.2f}".format(data['total_score'] +
                                                     data['target_score']))
    data['solve_count'] = data.get('solve_count', 0)
    data['contribution'] = data.get('contribution', 0)
    if 'last_synced_time' in data and data['last_synced_time'] != "NA":
        data['last_synced_time'] = time.strftime(
            '%Y-%m-%d %H:%M:%S', time.localtime(data['last_synced_time']))
    if 'created_at' in data:
        data['created_at'] = time.strftime('%Y-%m-%d %H:%M:%S',
                                           time.localtime(data['created_at']))
    if 'updated_at' in data:
        data['updated_at'] = time.strftime('%Y-%m-%d %H:%M:%S',
                                           time.localtime(data['updated_at']))
    return data
    def post(self, encrypted_token):
        app.logger.info('Activate user API called')
        rs = requests.session()
        try:
            app.logger.info(f'encrypted_token: {encrypted_token}')
            encrypted_token_encoded =  encrypted_token.encode()
            token_data = flask_crypto.decrypt_json(encrypted_token_encoded)
            redis_key = app.config['REDIS_PREFIX_USER_ACTIVATE'] + ':' + encrypted_token

            if redis_store.connection.exists(redis_key):
                user_data = redis_store.connection.get(redis_key)
                user_data = user_data.replace("\'", "\"")
                user_data = json.loads(user_data)
                if user_data['email'] != token_data['email']:
                    return { 'message': 'Invalid token' }, 409
            else:
                return { 'message': 'Invalid token' }, 409

            search_url = 'http://{}/{}/{}/_search'.format(app.config['ES_HOST'], _es_index, _es_type)
            should = [
                {'match': {'username': user_data['username']}},
                {'term': {'email': user_data['email']}}
            ]
            query_params = {'query': {'bool': {'should': should}}}

            response = rs.post(url=search_url, json=query_params, headers=_http_headers).json()

            if 'hits' in response:
                if response['hits']['total']['value'] == 1:
                    app.logger.info('Username already exists')
                    return 'Username or email already exists', 200

            skill = Skill()
            user_data['created_at'] = int(time.time())
            user_data['updated_at'] = int(time.time())
            user_data['skill_value'] = 0
            user_data['skill_title'] = skill.get_skill_title(0)
            user_data['decreased_skill_value'] = 0
            user_data['total_score'] = 0
            user_data['target_score'] = 0
            user_data['solve_count'] = 0
            user_data['contribution'] = 0
            post_url = 'http://{}/{}/{}'.format(app.config['ES_HOST'], _es_index, _es_type)
            response = rs.post(url=post_url, json=user_data, headers=_http_headers).json()

            if 'result' in response:
                if response['result'] == 'created':
                    app.logger.info('Create user API completed')
                    add_user_ratings(response['_id'], 0, 0)
                    return response['_id'], 201
            return response, 500

        except Exception as e:
            return { 'message': 'Invalid token' }, 409
def search_top_skilled_categoires_for_user(user_id,
                                           category_root,
                                           sort_field,
                                           size,
                                           heavy=False):
    try:
        skill = Skill()
        rs = requests.session()
        must = [{'term': {'user_id': user_id}}]

        if category_root == 'root':
            must.append({'term': {'category_root': 'root'}})
        else:
            must.append(
                {'bool': {
                    'must_not': [{
                        'term': {
                            'category_root': 'root'
                        }
                    }]
                }})

        query_json = {'query': {'bool': {'must': must}}}

        query_json['from'] = 0
        query_json['size'] = size
        query_json['sort'] = [{sort_field: {'order': 'desc'}}]
        search_url = 'http://{}/{}/{}/_search'.format(app.config['ES_HOST'],
                                                      _es_index_user_category,
                                                      _es_type)
        response = rs.post(url=search_url,
                           json=query_json,
                           headers=_http_headers).json()
        item_list = []
        if 'hits' in response:
            rank = 1
            for hit in response['hits']['hits']:
                item = hit['_source']
                item['relevant_score'] = "{:.2f}".format(
                    item['relevant_score'])
                skill_value = float(item.get('skill_value', 0))
                item['skill_value'] = "{:.2f}".format(skill_value)
                item['skill_title'] = skill.get_skill_title(skill_value)
                if heavy:
                    item['category_info'] = get_category_details(
                        item['category_id'])
                item['rank'] = rank
                item_list.append(item)
                rank += 1
        return item_list
    except Exception as e:
        raise e
def generate_sync_data_for_root_category(user_id, category, root_solved_count):
    try:
        rs = requests.session()
        skill_obj = Skill()
        must = [{
            'term': {
                'category_root': category['category_name']
            }
        }, {
            'term': {
                'user_id': user_id
            }
        }]
        query_json = {'query': {'bool': {'must': must}}}
        aggregate = {
            "skill_value_by_percentage": {
                "sum": {
                    "field": "skill_value_by_percentage"
                }
            }
        }
        query_json['aggs'] = aggregate
        query_json['size'] = 0

        search_url = 'http://{}/{}/{}/_search'.format(app.config['ES_HOST'],
                                                      _es_index_user_category,
                                                      _es_type)
        response = rs.post(url=search_url,
                           json=query_json,
                           headers=_http_headers).json()

        if 'aggregations' not in response:
            raise Exception('Internal server error')

        skill_value = response['aggregations']['skill_value_by_percentage'][
            'value']
        root_category_percentage = float(category.get('score_percentage', 100))
        skill_value_by_percentage_sum = skill_value * root_category_percentage / 100
        skill_level = skill_obj.get_skill_level_from_skill(skill_value)

        data = {
            'relevant_score': -1,
            'skill_value': skill_value,
            'skill_value_by_percentage': skill_value_by_percentage_sum,
            'skill_level': skill_level,
            'skill_title': skill_obj.get_skill_title(skill_level),
            'solve_count': root_solved_count.get(category['category_name'], 0),
            'category_root': 'root',
        }
        return data
    except Exception as e:
        raise e
    def post(self):
        app.logger.info('Create user API called')
        rs = requests.session()
        data = request.get_json()

        try:
            user_data = self.__validate_json(data)
            user_data['password'] = md5(user_data['password'].encode(encoding='utf-8')).hexdigest()
        except (IOError, KeyError):
            app.logger.warning('Bad request')
            return 'bad request', 400

        try:
            search_url = 'http://{}/{}/{}/_search'.format(app.config['ES_HOST'], _es_index, _es_type)
            should = [
                {'match': {'username': data['username']}},
                {'term': {'email': data['email']}}
            ]
            query_params = {'query': {'bool': {'should': should}}}

            response = rs.post(url=search_url, json=query_params, headers=_http_headers).json()

            if 'hits' in response:
                if response['hits']['total']['value'] == 1:
                    app.logger.info('Username already exists')
                    return 'Username already exists', 200

            skill = Skill()
            user_data['created_at'] = int(time.time())
            user_data['updated_at'] = int(time.time())
            user_data['skill_value'] = 0
            user_data['skill_title'] = skill.get_skill_title(0)
            user_data['decreased_skill_value'] = 0
            user_data['total_score'] = 0
            user_data['target_score'] = 0
            user_data['solve_count'] = 0
            user_data['contribution'] = 0
            post_url = 'http://{}/{}/{}'.format(app.config['ES_HOST'], _es_index, _es_type)
            response = rs.post(url=post_url, json=user_data, headers=_http_headers).json()

            if 'result' in response:
                if response['result'] == 'created':
                    app.logger.info('Create user API completed')
                    # add_user_ratings(response['_id'], 0, 0)
                    return response['_id'], 201
            return response, 500

        except Exception as e:
            return {'message': str(e)}, 500
def sync_overall_stat_for_user(user_id, skill_value=None):
    try:
        solve_count = get_solved_problem_count_for_user(user_id)
        if skill_value is None:
            skill_value = generate_skill_value_for_user(user_id)
        skill_obj = Skill()
        skill_title = skill_obj.get_skill_title(skill_value)
        user_data = {
            'skill_value': skill_value,
            'solve_count': solve_count,
            'skill_title': skill_title,
        }
        update_user_details(user_id, user_data)
    except Exception as e:
        raise e
def generate_sync_data_for_category(user_id, category):
    try:
        category_skill_generator = CategorySkillGenerator()
        factor = float(category.get('factor', 1))
        skill_stat = category_skill_generator.generate_skill(
            category['solved_stat']['difficulty_wise_count'], factor)

        dependent_skill_level = []
        dependent_categories = find_category_dependency_list(
            category['category_id'])
        for dcat in dependent_categories:
            category_details = get_user_category_data(user_id,
                                                      dcat['category_id'])
            category_level = 0
            if category_details:
                category_level = category_details.get('skill_level', 0)
            dependent_skill_level.append(category_level)

        category_score_generator = CategoryScoreGenerator()
        cat_score = category_score_generator.generate_score(
            dependent_skill_level, skill_stat['level'])
        skill_obj = Skill()

        category_percentage = float(category.get('score_percentage', 100))

        data = {
            'relevant_score':
            cat_score['score'],
            'skill_value':
            skill_stat['skill'],
            'skill_value_by_percentage':
            float(skill_stat['skill']) * category_percentage / 100.0,
            'skill_level':
            skill_stat['level'],
            'skill_title':
            skill_obj.get_skill_title(skill_stat['skill']),
            'solve_count':
            category['solved_stat']['total_count'],
            'category_root':
            category['category_root'],
        }

        return data
    except Exception as e:
        raise e
Пример #12
0
def get_user_details(user_id):
    try:
        rs = requests.session()
        search_url = 'http://{}/{}/{}/{}'.format(app.config['ES_HOST'],
                                                 _es_index_user, _es_type,
                                                 user_id)
        response = rs.get(url=search_url, headers=_http_headers).json()
        print('response: ', response)
        if 'found' in response:
            if response['found']:
                data = response['_source']
                skill = Skill()
                data['skill_color'] = skill.get_color_from_skill_title(
                    data.get('skill_title', 'NA'))
                return data
        raise Exception('User not found')
    except Exception as e:
        raise e
Пример #13
0
def get_category_details(cat_id, user_id=None):
    app.logger.info(
        f'get_category_details function called for cat_id: {cat_id}, user_id: {user_id}'
    )
    try:
        rs = requests.session()
        search_url = 'http://{}/{}/{}/{}'.format(app.config['ES_HOST'],
                                                 _es_index_category, _es_type,
                                                 cat_id)
        response = rs.get(url=search_url, headers=_http_headers).json()
        if 'found' in response:
            if response['found']:
                data = response['_source']
                data['category_id'] = response['_id']
                data['comment_list'] = get_comment_list(response['_id'])
                data['vote_count'] = get_vote_count_list(response['_id'])
                data['comment_count'] = get_comment_count(response['_id'])
                data['resource_list'] = search_resource(
                    {'resource_ref_id': response['_id']}, 0, _es_size)
                data['problem_count'] = 0
                if data['category_root'] == 'root':
                    data['problem_count'] = get_problem_count_for_category(
                        {'category_root': data['category_name']})
                else:
                    data['problem_count'] = get_problem_count_for_category(
                        {'category_name': data['category_name']})

                if user_id:
                    cat_info = get_user_category_data(user_id,
                                                      data['category_id'])
                    if cat_info:
                        skill_value = float(cat_info.get('skill_value', 0))
                        data['skill_value'] = "{:.2f}".format(skill_value)
                        skill = Skill()
                        data['skill_title'] = skill.get_skill_title(
                            skill_value)
                    else:
                        data['skill_value'] = 0
                        data['skill_title'] = "NA"
                app.logger.info('get_category_details completed')
                return data
        return None
    except Exception as e:
        raise e
Пример #14
0
def user_list_sync():
    app.logger.info(f'user_list_sync called')
    user_list = search_user({}, 0, _es_size)
    for user in user_list:
        id = user['id']
        user_problem_data_sync(id)
        app.logger.info(f'user_problem_data_sync done')

        # user_training_model_sync(id)
        # app.logger.info(f'user_training_model_sync done')

        details_info = get_user_details(id)
        skill_value = details_info.get('skill_value', 0)
        solve_count = details_info.get('solve_count', 0)
        app.logger.info(
            f'skill_value: {skill_value}, solve_count: {solve_count}')
        previous_problem_score = details_info['total_score']
        app.logger.info(f'previous_problem_score: {previous_problem_score}')
        current_problem_score = get_total_problem_score_for_user([id])
        app.logger.info(f'current_problem_score: {current_problem_score}')

        updated_data = {'total_score': current_problem_score}
        decrease_factor = 0
        if current_problem_score < previous_problem_score + details_info[
                'target_score']:
            decrease_amount = previous_problem_score + details_info[
                'target_score'] - current_problem_score
            app.logger.info(f'decrease_amount: {decrease_amount}')
            decrease_factor = math.sqrt(decrease_amount)

        skill = Skill()
        updated_data['decreased_skill_value'] = details_info[
            'decreased_skill_value'] + decrease_factor
        current_skill = skill_value - updated_data['decreased_skill_value']
        app.logger.info(f'current_skill: {current_skill}')
        current_skill_level = skill.get_skill_level_from_skill(current_skill)
        app.logger.info(f'decrease_amount: {current_skill_level}')
        updated_data['target_score'] = skill.generate_next_week_prediction(
            current_skill_level)
        app.logger.info(f'updated_data: {updated_data}')
        add_user_ratings(id, current_skill, solve_count)
        update_user_details(id, updated_data)
    app.logger.info(f'user_list_sync completed')
Пример #15
0
def get_total_problem_score_for_user(user_list):
    try:
        rs = requests.session()
        score_sum = 0
        marked_problem = {}
        for user_id in user_list:
            app.logger.info(f'check for user: {user_id}')
            must = [{
                'term': {
                    'user_id': user_id
                }
            }, {
                'term': {
                    'status': SOLVED
                }
            }]
            query_json = {'query': {'bool': {'must': must}}}
            query_json['size'] = _es_size
            search_url = 'http://{}/{}/{}/_search'.format(
                app.config['ES_HOST'], _es_index_problem_user, _es_type)
            response = rs.post(url=search_url,
                               json=query_json,
                               headers=_http_headers).json()
            if 'hits' in response:
                for hit in response['hits']['hits']:
                    edge = hit['_source']
                    problem_id = edge['problem_id']
                    if problem_id not in marked_problem:
                        marked_problem[problem_id] = 1
                        url = 'http://{}/{}/{}/{}'.format(
                            app.config['ES_HOST'], _es_index_problem, _es_type,
                            problem_id)
                        presponse = rs.get(url=url,
                                           headers=_http_headers).json()
                        if 'found' in presponse and presponse['found']:
                            problem_details = presponse['_source']
                            skill = Skill()
                            score_sum += skill.get_problem_score(
                                problem_details['problem_difficulty'])
        return score_sum
    except Exception as e:
        raise e
Пример #16
0
def get_team_details(team_id):
    try:
        rs = requests.session()
        search_url = 'http://{}/{}/{}/{}'.format(app.config['ES_HOST'],
                                                 _es_index_team, _es_type,
                                                 team_id)
        response = rs.get(url=search_url, headers=_http_headers).json()

        if 'found' in response:
            if response['found']:
                data = response['_source']
                skill = Skill()
                data['skill_color'] = skill.get_color_from_skill_title(
                    data.get('skill_title'))
                return data
            raise Exception('Team not found')
        app.logger.error('Elasticsearch down, response: ' + str(response))
        raise Exception('Internal server error')

    except Exception as e:
        raise e
Пример #17
0
    def post(self):
        try:
            app.logger.info('Create team method called')
            current_user = get_jwt_identity().get('id')
            print('current_user: '******'created_at'] = int(time.time())
            data['updated_at'] = int(time.time())
            data['skill_value'] = 0
            data['skill_title'] = skill.get_skill_title(0)
            data['decreased_skill_value'] = 0
            data['total_score'] = 0
            data['target_score'] = 0
            data['solve_count'] = 0

            member_list = []
            if 'member_list' in data:
                member_list = data['member_list']
                data.pop('member_list', None)

            data['team_leader_id'] = current_user

            post_url = 'http://{}/{}/{}'.format(app.config['ES_HOST'],
                                                _es_index, _es_type)
            response = rs.post(url=post_url, json=data,
                               headers=_http_headers).json()

            if 'result' in response and response['result'] == 'created':
                add_team_members_bulk(member_list, response['_id'],
                                      data['team_type'], current_user)
                app.logger.info('Create team method completed')
                return response['_id'], 201
            app.logger.error('Elasticsearch down, response: ' + str(response))
            return response, 500

        except Exception as e:
            return {'message': str(e)}, 500
Пример #18
0
    def calculate(self, problem_diff, category_level):
        up = category_level + 1
        down = category_level - 0.5
        level_dx = []
        level_dx.append([category_level + eps, up])
        level_dx.append([down, category_level])

        while up + 1.5 <= 10 or down - 1 >= 0:
            if up + 1.5 <= 10:
                level_dx.append([up + eps, up + 1.5])
                up += 1.5
            elif up < 10:
                level_dx.append([up + eps, 10])
            if down - 1 >= 0:
                level_dx.append([down - 1, down - eps])
                down -= 1

        if down > 0.0:
            level_dx.append([0, down - eps])

        level_idx = 0
        for idx, level in enumerate(level_dx):
            if problem_diff >= level[0] and problem_diff <= level[1]:
                level_idx = idx
                break

        score_range = Skill.get_problem_relevent_score_from_level(level_idx)
        score_dif = score_range[1] - score_range[0]
        level_range_val = level_dx[level_idx][1] - level_dx[level_idx][0]
        if problem_diff > category_level:
            dx_end = level_dx[level_idx][1] - problem_diff
            score_add = score_dif * dx_end / level_range_val
            score = score_range[0] + score_add
            score = min(score, 100)
            score = max(score, 0)
            return score
        else:
            dx_end = problem_diff - level_dx[level_idx][0]
            score_add = score_dif * dx_end / level_range_val
            score = score_range[0] + score_add
            score = min(score, 100)
            score = max(score, 0)
            return score
def sync_problems(user_id, oj_problem_set):
    app.logger.info(f'sync_problems called for {user_id}')
    try:
        category_score_generator = CategoryScoreGenerator()
        updated_categories = {}
        root_category_solve_count = {}

        for problem_set in oj_problem_set:
            # Change here
            for problem in problem_set['problem_list']:
                problem_stat = problem_set['problem_list'][problem]
                submission_list = problem_stat['submission_list']
                problem_db = search_problems({'problem_id': problem, 'oj_name': problem_set['oj_name'], 'active_status': approved}, 0, 1)
                if len(problem_db) == 0:
                    continue
                problem_id = problem_db[0]['id']
                if len(problem_db) > 1:
                    app.logger.error('Multiple problem with same id found')
                apply_solved_problem_for_user(user_id, problem_id, problem_db[0], submission_list, updated_categories, root_category_solve_count)

        app.logger.info('apply_solved_problem_for_user completed for all problems')
        marked_categories = dict(updated_categories)

        for category_id in marked_categories:
            app.logger.info(f'category id inside marked_categories: {category_id}')
            uc_edge = marked_categories[category_id]
            app.logger.info(f'uc_edge 1: {uc_edge}')
            # UPDATE OWN CONTRIBUTION
            old_cont = category_score_generator.get_own_difficulty_based_score(uc_edge['old_skill_level'])
            new_cont = category_score_generator.get_own_difficulty_based_score(uc_edge['skill_level'])
            cont_dx = new_cont - old_cont
            uc_edge['relevant_score'] += cont_dx
            app.logger.info(f'uc_edge 2: {uc_edge}')
            updated_categories[category_id] = uc_edge
            # UPDATE DEPENDENT CATEGORY CONTRIBUTION
            dependent_cat_list = find_dependent_category_list(category_id)
            app.logger.info(f'dependent_cat_list: {dependent_cat_list}')
            for dcat in dependent_cat_list:
                dcat_id = dcat['category_id']
                dcat_category_root = dcat['category_info']['category_root']
                app.logger.info(f'dcat_category_root: {dcat_category_root}')
                if dcat_id in updated_categories:
                    dcat_uc_edge = updated_categories[dcat_id]
                else:
                    dcat_uc_edge = get_user_category_data(user_id, dcat_id)

                if dcat_uc_edge is None:
                    dcat_uc_edge = {
                        "category_id": dcat_id,
                        "category_root": dcat_category_root,
                        "user_id": user_id,
                        "skill_value": 0,
                        "skill_level": 0,
                        "old_skill_level": 0,
                        "relevant_score": 0,
                        "solve_count": 0,
                        "skill_value_by_percentage": 0,
                    }
                    for d in range(1, 11):
                        key = 'scd_' + str(d)
                        dcat_uc_edge[key] = 0

                dependency_percentage = float(dcat['dependency_percentage'])
                old_cont = category_score_generator.get_dependent_score(uc_edge['old_skill_level'], dependency_percentage)
                new_cont = category_score_generator.get_dependent_score(uc_edge['skill_level'], dependency_percentage)
                cont_dx = new_cont - old_cont
                dcat_uc_edge['relevant_score'] += cont_dx

                app.logger.info(f'dcat_uc_edge: {dcat_uc_edge}')
                updated_categories[dcat_id] = dcat_uc_edge

        app.logger.info('process of mark categories completed')

        for category_id in updated_categories:
            uc_edge = updated_categories[category_id]
            uc_edge.pop('old_skill_level', None)
            uc_edge.pop('id', None)
            add_user_category_data(user_id, category_id, uc_edge)

        app.logger.info('updated root categories')
        root_category_list = search_categories({"category_root": "root"}, 0, _es_size)
        skill = Skill()
        user_skill = update_root_category_skill_for_user(user_id, root_category_list, root_category_solve_count)
        user_skill_level = skill.get_skill_level_from_skill(user_skill)
        app.logger.info(f'Final user_skill: {user_skill}, user_skill_level: {user_skill_level}')
        sync_overall_stat_for_user(user_id, user_skill)
        app.logger.info('sync_overall_stat_for_user completed')
        if len(updated_categories) > 0:
            update_problem_score(user_id, user_skill_level, updated_categories)
        app.logger.info(f'sync_problems completed for {user_id}')
    except Exception as e:
        raise e
Пример #20
0
def update_root_category_skill_for_user(user_id, root_category_list,
                                        root_category_solve_count):
    app.logger.info(
        f'update_root_category_skill_for_user called for: {user_id}')
    rs = requests.session()
    user_skill_sum = 0
    for cat in root_category_list:
        must = [{
            "term": {
                "category_root": cat["category_name"]
            }
        }, {
            "term": {
                "user_id": user_id
            }
        }]
        aggs = {
            "skill_value_by_percentage": {
                "sum": {
                    "field": "skill_value_by_percentage"
                }
            }
        }
        query_json = {
            "size": 0,
            "query": {
                "bool": {
                    "must": must
                }
            },
            "aggs": aggs
        }
        search_url = 'http://{}/{}/{}/_search'.format(app.config['ES_HOST'],
                                                      _es_index_user_category,
                                                      _es_type)
        response = rs.post(url=search_url,
                           json=query_json,
                           headers=_http_headers).json()
        if 'aggregations' in response:
            skill_value = response['aggregations'][
                'skill_value_by_percentage']['value']
            category_id = cat['category_id']
            category_name = cat['category_name']
            new_solve_count = root_category_solve_count.get(category_name, 0)
            uc_edge = get_user_category_data(user_id, category_id)
            app.logger.info(f'uc_edge from es: {uc_edge}')
            if uc_edge is None:
                uc_edge = {
                    "category_id": category_id,
                    "category_root": 'root',
                    "user_id": user_id,
                    "skill_value": 0,
                    "skill_level": 0,
                    "relevant_score": 0,
                    "solve_count": 0,
                    "skill_value_by_percentage": 0,
                }
            uc_edge['skill_value'] = skill_value
            uc_edge['solve_count'] = int(uc_edge.get('solve_count',
                                                     0)) + new_solve_count
            skill_info = Skill()
            uc_edge['skill_title'] = skill_info.get_skill_title(
                uc_edge['skill_value'])
            uc_edge['skill_level'] = skill_info.get_skill_level_from_skill(
                uc_edge['skill_value'])
            score_percentage = float(cat['score_percentage'])
            uc_edge['skill_value_by_percentage'] = uc_edge[
                'skill_value'] * score_percentage / 100
            user_skill_sum += uc_edge['skill_value_by_percentage']
            app.logger.info(f'add uc_edge: {uc_edge}')
            uc_edge.pop('id', None)
            add_user_category_data(user_id, category_id, uc_edge)
    return user_skill_sum
Пример #21
0
def apply_solved_problem_for_user(user_id, problem_id, problem_details,
                                  submission_list, updated_categories,
                                  root_category_solve_count):
    app.logger.info(
        f'apply_solved_problem_for_user for user_id: {user_id}, problem_id: {problem_id}'
    )
    app.logger.info('current updated_categories: ' +
                    json.dumps(updated_categories))
    try:
        skill_info = Skill()
        up_edge = get_user_problem_status(user_id, problem_id)
        if up_edge is not None and up_edge['status'] == SOLVED:
            return
        rs = requests.session()
        data = {
            'user_id': user_id,
            'problem_id': problem_id,
            'submission_list': submission_list,
            'status': SOLVED
        }
        # Insert User Problem Solved Status Here
        post_url = 'http://{}/{}/{}'.format(app.config['ES_HOST'],
                                            _es_index_problem_user, _es_type)
        response = rs.post(url=post_url, json=data,
                           headers=_http_headers).json()

        if 'result' not in response:
            raise Exception('Internal server error')

        # Update dependent category skill
        problem_difficulty = problem_details['problem_difficulty']
        app.logger.info(f'problem_difficulty: {problem_difficulty}')
        dep_cat_list = problem_details.get('categories', [])
        cat_skill_model = CategorySkillGenerator()
        marked_roots = {}
        for cat in dep_cat_list:
            app.logger.info(f'dept cat: {cat}')
            category_id = cat['category_id']
            category_details = get_category_details(category_id)
            category_root = category_details['category_root']
            app.logger.info(f'category_root: {category_root}')
            if category_root not in marked_roots:
                if category_root not in root_category_solve_count:
                    root_category_solve_count[category_root] = 0
                root_category_solve_count[category_root] += 1
                marked_roots[category_root] = 1
            if category_id in updated_categories:
                uc_edge = updated_categories[category_id]
            else:
                uc_edge = get_user_category_data(user_id, category_id)
                if uc_edge:
                    uc_edge['old_skill_level'] = uc_edge['skill_level']
                    uc_edge.pop('id', None)
            app.logger.info(f'uc_edge from es: {uc_edge}')
            if uc_edge is None:
                uc_edge = {
                    "category_id": category_id,
                    "category_root": category_root,
                    "user_id": user_id,
                    "skill_value": 0,
                    "skill_level": 0,
                    "old_skill_level": 0,
                    "relevant_score": 0,
                    "solve_count": 0,
                    "skill_value_by_percentage": 0,
                }
                for d in range(1, 11):
                    key = 'scd_' + str(d)
                    uc_edge[key] = 0

            app.logger.info(f'current uc_edge: {uc_edge}')
            dif_key = 'scd_' + str(int(problem_difficulty))
            uc_edge[dif_key] += 1
            problem_factor = category_details.get('factor', 1)
            added_skill = cat_skill_model.get_score_for_latest_solved_problem(
                problem_difficulty, uc_edge[dif_key], problem_factor)
            uc_edge['skill_value'] += added_skill
            uc_edge['solve_count'] += 1
            uc_edge['skill_title'] = skill_info.get_skill_title(
                uc_edge['skill_value'])
            uc_edge['skill_level'] = skill_info.get_skill_level_from_skill(
                uc_edge['skill_value'])
            score_percentage = float(category_details['score_percentage'])
            uc_edge['skill_value_by_percentage'] = uc_edge[
                'skill_value'] * score_percentage / 100
            app.logger.info(f'add uc_edge: {uc_edge}')
            updated_categories[category_id] = uc_edge
            app.logger.info(f'saved at category_id: {category_id}')
    except Exception as e:
        app.logger.error(f'Exception occurred: {e}')
        raise Exception('Internal server error')