Пример #1
0
 def handle_gc(self, options):
     timer('recompute_gc')
     print(' -- collecting garbage')
     to_gc = [
         str(x.id) for x in EnvironmentInfo.objects.filter(
             status=EnvironmentInfo.STATUS_DISABLED).all()
     ]
     if not to_gc:
         print(' -- no environment info to collect')
         return
     to_gc_str = ','.join(to_gc)
     with closing(connection.cursor()) as cursor:
         cursor.execute(
             'DELETE FROM proso_models_variable WHERE info_id IN (%s)' %
             to_gc_str)
         variables = cursor.rowcount
         cursor.execute(
             'DELETE FROM proso_models_audit WHERE info_id IN (%s)' %
             to_gc_str)
         audits = cursor.rowcount
         cursor.execute(
             'DELETE FROM proso_models_environmentinfo WHERE id IN (%s)' %
             to_gc_str)
         infos = cursor.rowcount
     print(' -- collecting garbage, time:', timer('recompute_gc'),
           'seconds, deleted', variables, 'variables,', audits,
           'audit records,', infos, 'environment info records')
Пример #2
0
def _save_answers(request, practice_context):
    timer('_save_answers')
    json_objects = _get_answers(request)
    answers = []
    for json_object in json_objects:
        if 'answer_class' not in json_object:
            raise BadRequestException('The answer does not contain key "answer_class".')
        answer_class = Answer.objects.answer_class(json_object['answer_class'])
        answers.append(answer_class.objects.from_json(json_object, practice_context, request.user.id))
    LOGGER.debug("saving of %s answers took %s seconds", len(answers), timer('_save_answers'))
    return answers
Пример #3
0
 def handle_recompute(self, options):
     timer('recompute_all')
     info = self.load_environment_info(options['initial'], options['config_name'])
     if options['finish']:
         with transaction.atomic():
             to_process = self.number_of_answers_to_process(info)
             if self.number_of_answers_to_process(info) >= options['batch_size']:
                 raise CommandError("There is more then allowed number of answers (%s) to process." % to_process)
             self.recompute(info, options)
     else:
         self.recompute(info, options)
     print(' -- total time:', timer('recompute_all'), 'seconds')
Пример #4
0
def _save_answers(request, practice_context):
    timer('_save_answers')
    json_objects = _get_answers(request)
    answers = []
    for json_object in json_objects:
        if 'answer_class' not in json_object:
            raise BadRequestException(
                'The answer does not contain key "answer_class".')
        answer_class = Answer.objects.answer_class(json_object['answer_class'])
        answers.append(
            answer_class.objects.from_json(json_object, practice_context,
                                           request.user.id))
    LOGGER.debug("saving of %s answers took %s seconds", len(answers),
                 timer('_save_answers'))
    return answers
Пример #5
0
 def handle_recompute(self, options):
     timer('recompute_all')
     info = self.load_environment_info(options['initial'],
                                       options['config_name'])
     if options['finish']:
         with transaction.atomic():
             to_process = self.number_of_answers_to_process(info)
             if self.number_of_answers_to_process(
                     info) >= options['batch_size']:
                 raise CommandError(
                     "There is more then allowed number of answers (%s) to process."
                     % to_process)
             self.recompute(info, options)
     else:
         self.recompute(info, options)
     print(' -- total time:', timer('recompute_all'), 'seconds')
Пример #6
0
 def handle_gc(self, options):
     timer('recompute_gc')
     print(' -- collecting garbage')
     to_gc = [str(x.id) for x in EnvironmentInfo.objects.filter(status=EnvironmentInfo.STATUS_DISABLED).all()]
     if not to_gc:
         print(' -- no environment info to collect')
         return
     to_gc_str = ','.join(to_gc)
     with closing(connection.cursor()) as cursor:
         cursor.execute('DELETE FROM proso_models_variable WHERE info_id IN (%s)' % to_gc_str)
         variables = cursor.rowcount
         cursor.execute('DELETE FROM proso_models_audit WHERE info_id IN (%s)' % to_gc_str)
         audits = cursor.rowcount
         cursor.execute('DELETE FROM proso_models_environmentinfo WHERE id IN (%s)' % to_gc_str)
         infos = cursor.rowcount
     print(' -- collecting garbage, time:', timer('recompute_gc'), 'seconds, deleted', variables, 'variables,', audits, 'audit records,', infos, 'environment info records')
Пример #7
0
def to_practice_counts(request):
    """
    Get number of items available to practice.

    filters:                -- use this or body
      json as in BODY
    language:
      language of the items

    BODY
      json in following format:
      {
        "#identifier": []         -- custom identifier (str) and filter
        ...
      }
    """
    data = None
    if request.method == "POST":
        data = json.loads(request.body.decode("utf-8"))["filters"]
    if "filters" in request.GET:
        data = load_query_json(request.GET, "filters")
    if data is None:
        return render_json(request, {},
                           template='models_json.html',
                           help_text=to_practice_counts.__doc__)
    language = get_language(request)
    timer('to_practice_counts')
    filter_names, filter_filters = list(zip(*sorted(data.items())))
    reachable_leaves = Item.objects.filter_all_reachable_leaves_many(
        filter_filters, language)
    response = {
        group_id: {
            'filter': data[group_id],
            'number_of_items': len(items),
        }
        for group_id, items in zip(filter_names, reachable_leaves)
    }
    LOGGER.debug(
        "flashcard_counts - getting flashcards in groups took %s seconds",
        (timer('to_practice_counts')))
    return render_json(request,
                       response,
                       template='models_json.html',
                       help_text=to_practice_counts.__doc__)
Пример #8
0
def to_practice_counts(request):
    """
    Get number of items available to practice.

    filters:                -- use this or body
      json as in BODY
    language:
      language of the items

    BODY
      json in following format:
      {
        "#identifier": []         -- custom identifier (str) and filter
        ...
      }
    """
    data = None
    if request.method == "POST":
        data = json.loads(request.body.decode("utf-8"))["filters"]
    if "filters" in request.GET:
        data = load_query_json(request.GET, "filters")
    if data is None:
        return render_json(request, {}, template='models_json.html', help_text=to_practice_counts.__doc__)
    language = get_language(request)
    timer('to_practice_counts')
    filter_names, filter_filters = list(zip(*sorted(data.items())))
    reachable_leaves = Item.objects.filter_all_reachable_leaves_many(filter_filters, language)
    response = {
        group_id: {
            'filter': data[group_id],
            'number_of_items': len(items),
        }
        for group_id, items in zip(filter_names, reachable_leaves)
    }
    LOGGER.debug("flashcard_counts - getting flashcards in groups took %s seconds", (timer('to_practice_counts')))
    return render_json(request, response, template='models_json.html', help_text=to_practice_counts.__doc__)
Пример #9
0
def user_stats(request):
    """
    Get user statistics for selected groups of items

    time:
      time in format '%Y-%m-%d_%H:%M:%S' used for practicing
    user:
      identifier of the user (only for stuff users)
    username:
      username of user (only for users with public profile)
    filters:                -- use this or body
      json as in BODY
    mastered:
      use model to compute number of mastered items - can be slowed
    language:
      language of the items

    BODY
      json in following format:
      {
        "#identifier": []         -- custom identifier (str) and filter
        ...
      }
    """
    timer('user_stats')
    response = {}
    data = None
    if request.method == "POST":
        data = json.loads(request.body.decode("utf-8"))["filters"]
    if "filters" in request.GET:
        data = load_query_json(request.GET, "filters")
    if data is None:
        return render_json(request, {},
                           template='models_user_stats.html',
                           help_text=user_stats.__doc__)
    environment = get_environment()
    if is_time_overridden(request):
        environment.shift_time(get_time(request))
    user_id = get_user_id(request)
    language = get_language(request)
    filter_names, filter_filters = list(zip(*sorted(data.items())))
    reachable_leaves = Item.objects.filter_all_reachable_leaves_many(
        filter_filters, language)
    all_leaves = flatten(reachable_leaves)
    answers = dict(
        list(
            zip(all_leaves,
                environment.number_of_answers_more_items(all_leaves,
                                                         user_id))))
    correct_answers = dict(
        list(
            zip(
                all_leaves,
                environment.number_of_correct_answers_more_items(
                    all_leaves, user_id))))
    if request.GET.get("mastered"):
        timer('user_stats_mastered')
        mastery_threshold = get_mastery_trashold()
        predictions = get_predictive_model().predict_more_items(
            environment, user_id, all_leaves, get_time(request))
        mastered = dict(
            list(zip(all_leaves,
                     [p >= mastery_threshold for p in predictions])))
        LOGGER.debug(
            "user_stats - getting predictions for flashcards took %s seconds",
            (timer('user_stats_mastered')))
    for identifier, items in zip(filter_names, reachable_leaves):
        if len(items) == 0:
            response[identifier] = {
                "filter": data[identifier],
                "number_of_flashcards": 0,
            }
        else:
            response[identifier] = {
                "filter":
                data[identifier],
                "number_of_flashcards":
                len(items),
                "number_of_practiced_flashcards":
                sum(answers[i] > 0 for i in items),
                "number_of_answers":
                sum(answers[i] for i in items),
                "number_of_correct_answers":
                sum(correct_answers[i] for i in items),
            }
            if request.GET.get("mastered"):
                response[identifier]["number_of_mastered_flashcards"] = sum(
                    mastered[i] for i in items)
    return render_json(request,
                       response,
                       template='models_user_stats.html',
                       help_text=user_stats.__doc__)
Пример #10
0
 def recompute(self, info, options):
     print(' -- preparing phase')
     timer('recompute_prepare')
     environment = self.load_environment(info)
     users, items = self.load_user_and_item_ids(info, options['batch_size'])
     environment.prefetch(users, items)
     predictive_model = get_predictive_model()
     print(' -- preparing phase, time:', timer('recompute_prepare'),
           'seconds')
     timer('recompute_model')
     print(' -- model phase')
     with closing(connection.cursor()) as cursor:
         cursor.execute(
             '''
             SELECT
                 id,
                 user_id,
                 item_id,
                 item_asked_id,
                 item_answered_id,
                 time,
                 response_time,
                 guess
             FROM proso_models_answer
             ORDER BY id
             OFFSET %s LIMIT %s
             ''', [info.load_progress, options['batch_size']])
         progress_bar = progress.bar(cursor,
                                     every=max(1, cursor.rowcount / 100),
                                     expected_size=cursor.rowcount)
         info.load_progress += cursor.rowcount
         for (answer_id, user, item, asked, answered, time, response_time,
              guess) in progress_bar:
             predictive_model.predict_and_update(environment,
                                                 user,
                                                 item,
                                                 asked == answered,
                                                 time.replace(tzinfo=None),
                                                 item_answered=answered,
                                                 item_asked=asked,
                                                 guess=guess,
                                                 answer_id=answer_id)
             environment.process_answer(user, item, asked, answered, time,
                                        answer_id, response_time, guess)
     print(' -- model phase, time:', timer('recompute_model'), 'seconds')
     timer('recompute_flush')
     print(' -- flushing phase')
     environment.flush(clean=options['finish'])
     print(' -- flushing phase, time:', timer('recompute_flush'),
           'seconds, total number of answers:', info.load_progress)
     if options['finish']:
         timer('recompute_finish')
         print(' -- finishing phase')
         try:
             previous_info = EnvironmentInfo.objects.get(
                 status=EnvironmentInfo.STATUS_ACTIVE)
             previous_info.status = EnvironmentInfo.STATUS_DISABLED
             previous_info.save()
             cache.delete(ENVIRONMENT_INFO_CACHE_KEY)
         except EnvironmentInfo.DoesNotExist:
             pass
         info.status = EnvironmentInfo.STATUS_ACTIVE
         print(' -- finishing phase, time:', timer('recompute_finish'),
               'seconds')
     info.save()
Пример #11
0
 def recompute(self, info, options):
     print(' -- preparing phase')
     timer('recompute_prepare')
     environment = self.load_environment(info)
     users, items = self.load_user_and_item_ids(info, options['batch_size'])
     environment.prefetch(users, items)
     predictive_model = get_predictive_model()
     print(' -- preparing phase, time:', timer('recompute_prepare'), 'seconds')
     timer('recompute_model')
     print(' -- model phase')
     with closing(connection.cursor()) as cursor:
         cursor.execute(
             '''
             SELECT
                 id,
                 user_id,
                 item_id,
                 item_asked_id,
                 item_answered_id,
                 time,
                 response_time,
                 guess
             FROM proso_models_answer
             ORDER BY id
             OFFSET %s LIMIT %s
             ''', [info.load_progress, options['batch_size']])
         progress_bar = progress.bar(cursor, every=max(1, cursor.rowcount / 100), expected_size=cursor.rowcount)
         info.load_progress += cursor.rowcount
         for (answer_id, user, item, asked, answered, time, response_time, guess) in progress_bar:
             predictive_model.predict_and_update(
                 environment,
                 user,
                 item,
                 asked == answered,
                 time,
                 item_answered=answered,
                 item_asked=asked,
                 guess=guess,
                 answer_id=answer_id)
             environment.process_answer(user, item, asked, answered, time, answer_id, response_time, guess)
     print(' -- model phase, time:', timer('recompute_model'), 'seconds')
     timer('recompute_flush')
     print(' -- flushing phase')
     environment.flush(clean=options['finish'])
     print(' -- flushing phase, time:', timer('recompute_flush'), 'seconds, total number of answers:', info.load_progress)
     if options['finish']:
         timer('recompute_finish')
         print(' -- finishing phase')
         try:
             previous_info = EnvironmentInfo.objects.get(status=EnvironmentInfo.STATUS_ACTIVE)
             previous_info.status = EnvironmentInfo.STATUS_DISABLED
             previous_info.save()
             cache.delete(ENVIRONMENT_INFO_CACHE_KEY)
         except EnvironmentInfo.DoesNotExist:
             pass
         info.status = EnvironmentInfo.STATUS_ACTIVE
         print(' -- finishing phase, time:', timer('recompute_finish'), 'seconds')
     info.save()
Пример #12
0
def user_stats(request):
    """
    Get user statistics for selected groups of items

    time:
      time in format '%Y-%m-%d_%H:%M:%S' used for practicing
    user:
      identifier of the user (only for stuff users)
    username:
      username of user (only for users with public profile)
    filters:                -- use this or body
      json as in BODY
    mastered:
      use model to compute number of mastered items - can be slowed
    language:
      language of the items

    BODY
      json in following format:
      {
        "#identifier": []         -- custom identifier (str) and filter
        ...
      }
    """
    timer('user_stats')
    response = {}
    data = None
    if request.method == "POST":
        data = json.loads(request.body.decode("utf-8"))["filters"]
    if "filters" in request.GET:
        data = load_query_json(request.GET, "filters")
    if data is None:
        return render_json(request, {}, template='models_user_stats.html', help_text=user_stats.__doc__)
    environment = get_environment()
    if is_time_overridden(request):
        environment.shift_time(get_time(request))
    user_id = get_user_id(request)
    language = get_language(request)
    filter_names, filter_filters = list(zip(*sorted(data.items())))
    reachable_leaves = Item.objects.filter_all_reachable_leaves_many(filter_filters, language)
    all_leaves = flatten(reachable_leaves)
    answers = dict(list(zip(all_leaves, environment.number_of_answers_more_items(all_leaves, user_id))))
    correct_answers = dict(list(zip(all_leaves, environment.number_of_correct_answers_more_items(all_leaves, user_id))))
    if request.GET.get("mastered"):
        timer('user_stats_mastered')
        mastery_threshold = get_mastery_trashold()
        predictions = get_predictive_model().predict_more_items(environment, user_id, all_leaves, get_time(request))
        mastered = dict(list(zip(all_leaves, [p >= mastery_threshold for p in predictions])))
        LOGGER.debug("user_stats - getting predictions for flashcards took %s seconds", (timer('user_stats_mastered')))
    for identifier, items in zip(filter_names, reachable_leaves):
        if len(items) == 0:
            response[identifier] = {
                "filter": data[identifier],
                "number_of_flashcards": 0,
            }
        else:
            response[identifier] = {
                "filter": data[identifier],
                "number_of_flashcards": len(items),
                "number_of_practiced_flashcards": sum(answers[i] > 0 for i in items),
                "number_of_answers": sum(answers[i] for i in items),
                "number_of_correct_answers": sum(correct_answers[i] for i in items),
            }
            if request.GET.get("mastered"):
                response[identifier]["number_of_mastered_flashcards"]= sum(mastered[i] for i in items)
    return render_json(request, response, template='models_user_stats.html', help_text=user_stats.__doc__)