Пример #1
0
def user_problem_exp_view(request, problem_id):
    curr_exp = Experience(request.user)
    try:
        difficulty = ProblemDifficulty.objects.get(problem=problem_id)
        problem_exp = difficulty.experience
    except ProblemDifficulty.DoesNotExist:
        problem_exp = 0
    new_exp = Experience(level=curr_exp.current_level,
                         experience=curr_exp.current_experience + problem_exp)

    if new_exp.current_level == curr_exp.current_level:
        exp_diff_percent = \
            ((new_exp.current_experience - curr_exp.current_experience) /
            curr_exp.required_experience_to_lvlup) * 100
    else:
        whole_levels = \
            (new_exp.current_level - curr_exp.current_level - 1) * 100
        from_curr = \
            100 - ((curr_exp.current_experience /
                    curr_exp.required_experience_to_lvlup) * 100)
        to_expected = (new_exp.current_experience /
                       new_exp.required_experience_to_lvlup) * 100
        exp_diff_percent = whole_levels + from_curr + to_expected

    return JsonResponse({
        'current_exp':
        (curr_exp.current_experience / curr_exp.required_experience_to_lvlup) *
        100,
        'current_lvl':
        curr_exp.current_level,
        'exp_to_add':
        exp_diff_percent
    })
Пример #2
0
 def test_experience_basic(self):
     # Yeah I guess not that much testing can be done here
     self.assertRaises(ValueError, Experience.exp_to_lvl, -1)
     self.assertRaises(ValueError, Experience.exp_to_lvl, 0)
     self.assertEquals(Experience.exp_to_lvl(1), ExpMultiplier)
     self.assertEquals(Experience.exp_to_lvl(2), ExpBase * ExpMultiplier)
     self.assertEquals(
         Experience.exp_to_lvl(SoftCapLevel + 1),
         Experience.exp_to_lvl(SoftCapLevel) + LinearMultiplier)
Пример #3
0
 def test_experience_basic(self):
     # Yeah I guess not that much testing can be done here
     self.assertRaises(ValueError, Experience.exp_to_lvl, -1)
     self.assertRaises(ValueError, Experience.exp_to_lvl, 0)
     self.assertEquals(Experience.exp_to_lvl(1), ExpMultiplier)
     self.assertEquals(Experience.exp_to_lvl(2), ExpBase * ExpMultiplier)
     self.assertEquals(
         Experience.exp_to_lvl(SoftCapLevel + 1), Experience.exp_to_lvl(SoftCapLevel) + LinearMultiplier
     )
Пример #4
0
def _experience_widget(user, size):
    exp = Experience(user)
    percentage = exp.current_experience \
                 / float(exp.required_experience_to_lvlup)

    is_big = (size == 'big')

    outer_radius = LARGE_WIDGET_OUTER_RADIUS if is_big \
                   else SMALL_WIDGET_OUTER_RADIUS

    angle = 2 * math.pi * percentage
    endX = outer_radius * math.sin(angle)
    endY = outer_radius * (1 - math.cos(angle))
    end = str(endX) + ' ' + str(endY)

    large_arc_flag = '1' if percentage > 0.5 else '0'

    center = str(outer_radius) + ' ' + str(outer_radius)
    arc_parameters = center + ' 0 ' + large_arc_flag + ' 1 ' + end

    return {
        'percentage': percentage,
        'level': exp.current_level,
        'inner_radius': LARGE_WIDGET_INNER_RADIUS,
        'outer_radius': outer_radius,
        'diameter': outer_radius * 2,
        'size': size,
        'arc_parameters': arc_parameters
    }
Пример #5
0
    def test_experience_from_pair(self):
        test_user = User.objects.get(username='******')

        experience = Experience(level=0, experience=ExpMultiplier + 2)
        self.assertEquals(experience.level_exp_tuple, (1, 2))
        self.assertEquals(experience.current_level, 1)
        self.assertEquals(experience.current_experience, 2)
        self.assertRaises(ValueError, experience.force_recalculate)

        experience2 = Experience(level=0, experience=ExpMultiplier - 1)
        self.assertEquals(experience2.level_exp_tuple, (0, ExpMultiplier - 1))

        self.assertRaises(ValueError, Experience, user=test_user, level=1)
        self.assertRaises(ValueError, Experience, user=test_user, experience=1)
        self.assertRaises(ValueError,
                          Experience,
                          user=test_user,
                          level=1,
                          experience=1)
Пример #6
0
    def test_experience_counter(self):
        url = reverse('view_current_profile')
        url_other = reverse('view_profile', args=['test_user2'])

        self.client.login(username='******')
        response = self.client.get(url)
        self.assertIn('0</text>', response.content)
        self.assertIn('Level: 0', response.content)
        self.assertIn('0%', response.content)

        response = self.client.get(url_other)
        self.assertIn('0</text>', response.content)
        self.assertIn('Level: 0', response.content)
        self.assertIn('0%', response.content)

        exp_to_lvl = Experience.exp_to_lvl

        class TrivialSource(ExperienceSource):
            def get_experience(self, user):
                if user.username == 'test_user':
                    return exp_to_lvl(1) + 10
                else:
                    return exp_to_lvl(1) + exp_to_lvl(2) + 10

            def force_recalculate(self, user):
                pass

        try:
            Experience.add_experience_source(TrivialSource())
            response = self.client.get(url)
            self.assertIn('1</text>', response.content)
            self.assertIn('Level: 1', response.content)
            self.assertIn('Experience: %d%%' % (100 * 10 / exp_to_lvl(2)),
                          response.content)

            response = self.client.get(url_other)
            self.assertIn('2</text>', response.content)
            self.assertIn('Level: 2', response.content)
            self.assertIn('Experience: %d%%' % (100 * 10 / exp_to_lvl(3)),
                          response.content)
        finally:
            Experience.clear_experience_sources()
Пример #7
0
    def test_softcap(self):
        class ConstSource(ExperienceSource):
            """
            This source always returns the same value
            """
            def __init__(self, value):
                self.value = value

            def get_experience(self, user):
                return self.value

            def force_recalculate(self, user):
                pass

        def total_exp_to_lvl(level):
            total = 0
            for i in xrange(1, level + 1):
                total += Experience.exp_to_lvl(i)
            return total

        try:
            Experience.add_experience_source(
                ConstSource(total_exp_to_lvl(SoftCapLevel)))

            test_user = User.objects.get(username='******')

            exp = Experience(test_user)

            self.assertEquals(exp.current_level, SoftCapLevel)
            self.assertEquals(
                exp.required_experience_to_lvlup,
                Experience.exp_to_lvl(SoftCapLevel) + LinearMultiplier)

            Experience.add_experience_source(
                ConstSource(Experience.exp_to_lvl((SoftCapLevel + 1))))

            self.assertEquals(
                exp.required_experience_to_lvlup,
                Experience.exp_to_lvl(SoftCapLevel) + 2 * LinearMultiplier)

        finally:
            Experience.clear_experience_sources()
Пример #8
0
    def test_experience_counter(self):
        url = reverse('view_current_profile')
        url_other = reverse('view_profile', args=['test_user2'])

        self.client.login(username='******')
        response = self.client.get(url)
        self.assertIn('0</text>', response.content)
        self.assertIn('Level: 0', response.content)
        self.assertIn('0%', response.content)

        response = self.client.get(url_other)
        self.assertIn('0</text>', response.content)
        self.assertIn('Level: 0', response.content)
        self.assertIn('0%', response.content)

        exp_to_lvl = Experience.exp_to_lvl

        class TrivialSource(ExperienceSource):
            def get_experience(self, user):
                if user.username == 'test_user':
                    return exp_to_lvl(1) + 10
                else:
                    return exp_to_lvl(1) + exp_to_lvl(2) + 10

            def force_recalculate(self, user):
                pass

        try:
            Experience.add_experience_source(TrivialSource())
            response = self.client.get(url)
            self.assertIn('1</text>', response.content)
            self.assertIn('Level: 1', response.content)
            self.assertIn('Experience: %d%%' % (100 * 10 / exp_to_lvl(2)),
                          response.content)

            response = self.client.get(url_other)
            self.assertIn('2</text>', response.content)
            self.assertIn('Level: 2', response.content)
            self.assertIn('Experience: %d%%' % (100 * 10 / exp_to_lvl(3)),
                          response.content)
        finally:
            Experience.clear_experience_sources()
Пример #9
0
    def test_softcap(self):
        class ConstSource(ExperienceSource):
            """
            This source always returns the same value
            """
            def __init__(self, value):
                self.value = value

            def get_experience(self, user):
                return self.value

            def force_recalculate(self, user):
                pass

        def total_exp_to_lvl(level):
            total = 0
            for i in xrange(1, level + 1):
                total += Experience.exp_to_lvl(i)
            return total

        try:
            Experience.add_experience_source(
                ConstSource(total_exp_to_lvl(SoftCapLevel))
            )

            test_user = User.objects.get(username='******')

            exp = Experience(test_user)

            self.assertEquals(exp.current_level, SoftCapLevel)
            self.assertEquals(
                exp.required_experience_to_lvlup,
                Experience.exp_to_lvl(SoftCapLevel) + LinearMultiplier
            )

            Experience.add_experience_source(
                ConstSource(Experience.exp_to_lvl((SoftCapLevel + 1)))
            )

            self.assertEquals(
                exp.required_experience_to_lvlup,
                Experience.exp_to_lvl(SoftCapLevel) + 2*LinearMultiplier
            )

        finally:
            Experience.clear_experience_sources()
Пример #10
0
    def test_experience_counter(self):
        url = reverse("view_current_profile")
        url_other = reverse("view_profile", args=["test_user2"])

        self.client.login(username="******")
        response = self.client.get(url)
        self.assertIn("0</text>", response.content)
        self.assertIn("Level: 0", response.content)
        self.assertIn("0%", response.content)

        response = self.client.get(url_other)
        self.assertIn("0</text>", response.content)
        self.assertIn("Level: 0", response.content)
        self.assertIn("0%", response.content)

        exp_to_lvl = Experience.exp_to_lvl

        class TrivialSource(ExperienceSource):
            def get_experience(self, user):
                if user.username == "test_user":
                    return exp_to_lvl(1) + 10
                else:
                    return exp_to_lvl(1) + exp_to_lvl(2) + 10

            def force_recalculate(self, user):
                pass

        try:
            Experience.add_experience_source(TrivialSource())
            response = self.client.get(url)
            self.assertIn("1</text>", response.content)
            self.assertIn("Level: 1", response.content)
            self.assertIn("Experience: %d%%" % (100 * 10 / exp_to_lvl(2)), response.content)

            response = self.client.get(url_other)
            self.assertIn("2</text>", response.content)
            self.assertIn("Level: 2", response.content)
            self.assertIn("Experience: %d%%" % (100 * 10 / exp_to_lvl(3)), response.content)
        finally:
            Experience.clear_experience_sources()
Пример #11
0
def profile_view(request, username=None):
    shown_user = None

    if username is None:
        shown_user = request.user
    else:
        shown_user = get_object_or_404(User.objects, username=username)

    exp = Experience(shown_user)
    friends = UserFriends(request.user)
    is_friend = friends.is_friends_with(shown_user)
    pending_incoming_friendship_request = friends.has_request_from(shown_user)
    sent_friendship_request = friends.sent_request_to(shown_user)

    has_portal = False
    if 'oioioi.portals' in settings.INSTALLED_APPS:
        from oioioi.portals.models import Portal
        if Portal.objects.filter(owner=shown_user).exists():
            has_portal = True

    sections = []
    for func in profile_registry.items:
        response = func(request, shown_user)

        if isinstance(response, HttpResponseRedirect):
            return response

        if isinstance(response, TemplateResponse):
            sections.append(response.render().content)
        else:
            sections.append(response)

    return TemplateResponse(
        request, 'gamification/profile.html', {
            'shown_user':
            shown_user,
            'is_my_friend':
            is_friend,
            'exp':
            exp,
            'exp_percentage':
            int(100 * exp.current_experience /
                exp.required_experience_to_lvlup),
            'has_portal':
            has_portal,
            'pending_incoming_friendship_request':
            pending_incoming_friendship_request,
            'sent_friendship_request':
            sent_friendship_request,
            'sections':
            sections
        })
Пример #12
0
    def test_problem_source(self):
        try:
            Experience.add_experience_source(PROBLEM_EXPERIENCE_SOURCE)

            user = User.objects.get(username='******')

            # test_user has solved a trivial task
            user_exp = Experience(user)
            user_exp.force_recalculate()
            self.assertEquals(user_exp.current_level, 0)
            self.assertEquals(user_exp.current_experience, Lvl1TaskExp)

            # Update on problem difficulty change
            pd = ProblemDifficulty.objects.get(problem__id=10)
            pd.difficulty = DIFFICULTY.EASY
            pd.save()
            self.assertEquals(user_exp.current_level, 1)
            self.assertEquals(user_exp.current_experience, 0)

        finally:
            Experience.clear_experience_sources()
Пример #13
0
    def test_problem_source(self):
        try:
            Experience.add_experience_source(PROBLEM_EXPERIENCE_SOURCE)

            user = User.objects.get(username="******")

            # test_user has solved a trivial task
            user_exp = Experience(user)
            user_exp.force_recalculate()
            self.assertEquals(user_exp.current_level, 0)
            self.assertEquals(user_exp.current_experience, Lvl1TaskExp)

            # Update on problem difficulty change
            pd = ProblemDifficulty.objects.get(problem__id=10)
            pd.difficulty = DIFFICULTY.EASY
            pd.save()
            self.assertEquals(user_exp.current_level, 1)
            self.assertEquals(user_exp.current_experience, 0)

        finally:
            Experience.clear_experience_sources()
Пример #14
0
    def suggest_task(self, user):
        """Returns a problem object as a suggestion for the user or None if no
           suggestion can be returned
        """
        if not user.is_authenticated():
            return None

        user_level = Experience(user).current_level

        if user_level >= SuggestLvl5From:
            qset = get_problems_by_difficulty(DIFFICULTY.IMPOSSIBLE)
        elif user_level >= SuggestLvl4From:
            qset = get_problems_by_difficulty(DIFFICULTY.HARD)
        elif user_level >= SuggestLvl3From:
            qset = get_problems_by_difficulty(DIFFICULTY.MEDIUM)
        elif user_level >= SuggestLvl2From:
            qset = get_problems_by_difficulty(DIFFICULTY.EASY)
        else:
            qset = get_problems_by_difficulty(DIFFICULTY.TRIVIAL)

        try:
            return qset.filter(is_public=True).order_by('?').first()
        except Problem.DoesNotExist:
            return None
Пример #15
0
    def test_experience_with_sources(self):
        class TestSource(ExperienceSource):
            """
            This class simulates desync with real experience, initially
            get_experience() returns one value, but after force_recalculate()
            return totally different one
            """
            def __init__(self, initial, after_recalc):
                self.value = initial
                self.recalc = after_recalc

            def get_experience(self, user):
                return self.value

            def force_recalculate(self, user):
                self.value = self.recalc

        # To level up to lvl 1 you need the ExpMultiplier experience
        test_source = TestSource(1, ExpMultiplier)
        test_source1 = TestSource(3, 1)
        try:
            Experience.add_experience_source(test_source)
            Experience.add_experience_source(test_source1)

            test_user = User.objects.get(username='******')

            exp = Experience(test_user)

            self.assertEquals(exp.current_experience, 4)
            self.assertEquals(exp.current_level, 0)
            self.assertEquals(exp.required_experience_to_lvlup, ExpMultiplier)
            self.assertEquals(exp.level_exp_tuple, (0, 4))

            exp.force_recalculate()

            self.assertEquals(exp.current_experience, 1)
            self.assertEquals(exp.current_level, 1)
            self.assertEquals(exp.required_experience_to_lvlup,
                              ExpBase * ExpMultiplier)
            self.assertEquals(exp.level_exp_tuple, (1, 1))

            Experience.clear_experience_sources()

            self.assertEquals(exp.level_exp_tuple, (0, 0))

        finally:
            Experience.clear_experience_sources()
Пример #16
0
 def setUp(self):
     self._backup_experience_sources = Experience._sources
     Experience.clear_experience_sources()
Пример #17
0
 def total_exp_to_lvl(level):
     total = 0
     for i in xrange(1, level + 1):
         total += Experience.exp_to_lvl(i)
     return total
Пример #18
0
 def total_exp_to_lvl(level):
     total = 0
     for i in xrange(1, level + 1):
         total += Experience.exp_to_lvl(i)
     return total
Пример #19
0
    def test_experience_with_sources(self):
        class TestSource(ExperienceSource):
            """
            This class simulates desync with real experience, initially
            get_experience() returns one value, but after force_recalculate()
            return totally different one
            """
            def __init__(self, initial, after_recalc):
                self.value = initial
                self.recalc = after_recalc

            def get_experience(self, user):
                return self.value

            def force_recalculate(self, user):
                self.value = self.recalc

        # To level up to lvl 1 you need the ExpMultiplier experience
        test_source = TestSource(1, ExpMultiplier)
        test_source1 = TestSource(3, 1)
        try:
            Experience.add_experience_source(test_source)
            Experience.add_experience_source(test_source1)

            test_user = User.objects.get(username='******')

            exp = Experience(test_user)

            self.assertEquals(exp.current_experience, 4)
            self.assertEquals(exp.current_level, 0)
            self.assertEquals(
                exp.required_experience_to_lvlup,
                ExpMultiplier
            )
            self.assertEquals(exp.level_exp_tuple, (0, 4))

            exp.force_recalculate()

            self.assertEquals(exp.current_experience, 1)
            self.assertEquals(exp.current_level, 1)
            self.assertEquals(
                exp.required_experience_to_lvlup,
                ExpBase*ExpMultiplier
            )
            self.assertEquals(exp.level_exp_tuple, (1, 1))

            Experience.clear_experience_sources()

            self.assertEquals(exp.level_exp_tuple, (0, 0))

        finally:
            Experience.clear_experience_sources()
Пример #20
0
 def setUp(self):
     self._backup_experience_sources = Experience._sources
     Experience.clear_experience_sources()