docs: def recalculate_concepts(self, concepts, lang=None):
          """
          Recalculated given concepts for given users
  
          Args:
              concepts (dict): user id (int -> set of concepts to recalculate)
              lang(Optional[str]): language used to get items in all concepts (cached).
                  Defaults to None, in that case are get items only in used concepts
          """
          if len(concepts) == 0:
              return
  
          if lang is None:
              items = Concept.objects.get_concept_item_mapping(concepts=Concept.objects.filter(pk__in=set(flatten(concepts.values()))))
          else:
              items = Concept.objects.get_concept_item_mapping(lang=lang)
  
          environment = get_environment()
          mastery_threshold = get_mastery_trashold()
          for user, concepts in concepts.items():
              all_items = list(set(flatten([items[c] for c in concepts])))
              answer_counts = environment.number_of_answers_more_items(all_items, user)
              correct_answer_counts = environment.number_of_correct_answers_more_items(all_items, user)
              predictions = dict(list(zip(all_items, get_predictive_model().
                                          predict_more_items(environment, user, all_items, time=get_time_for_knowledge_overview()))))
              new_user_stats = []
              stats_to_delete_condition = Q()
              for concept in concepts:
                  answer_aggregates = Answer.objects.filter(user=user, item__in=items[concept]).aggregate(
                      time_spent=Sum("response_time"),
                      sessions=Count("session", True),
                      time_first=Min("time"),
                      time_last=Max("time"),
                  )
                  stats = {
                      "answer_count": sum(answer_counts[i] for i in items[concept]),
                      "correct_answer_count": sum(correct_answer_counts[i] for i in items[concept]),
                      "item_count": len(items[concept]),
                      "practiced_items_count": sum([answer_counts[i] > 0 for i in items[concept]]),
                      "mastered_items_count": sum([predictions[i] >= mastery_threshold for i in items[concept]]),
                      "prediction": sum([predictions[i] for i in items[concept]]) / len(items[concept]),
                      "time_spent": answer_aggregates["time_spent"] / 1000,
                      "session_count": answer_aggregates["sessions"],
                      "time_first": answer_aggregates["time_first"].timestamp(),
                      "time_last": answer_aggregates["time_last"].timestamp(),
                  }
                  stats_to_delete_condition |= Q(user=user, concept=concept)
                  for stat_name, value in stats.items():
                      new_user_stats.append(UserStat(user_id=user, concept_id=concept, stat=stat_name, value=value))
              self.filter(stats_to_delete_condition).delete()
              self.bulk_create(new_user_stats)