prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Showing 120% score in exam report
  ### Observed behavior
  After submitting exam, when coach user watching progress of each user in exam report. Coach user see 120% score in exam report. We have attached screenshot and database file,so you can easily re-generate this issue.
  
  ### Expected behavior
  Score must be between 0-100%.
  
  ### Steps to reproduce
  1. Copy attached database file in .kolibri folder.
  2. login with username "pm" and password "sc".
  3. Click on Coach.
  4. Click on Class 4A.
  5. Click on Exams.
  6. See report of the Unit 2B-Final exam.
  7. See learner Junaid Shaikh.
  
  ### Context
   * Kolibri version : Kolibri 0.4.9
   * Operating system : Ubuntu 14.04
   * Browser : Chrome 
  
  ### Screenshots
  ![1](https://user-images.githubusercontent.com/12776071/34758551-fc3ec802-f5fc-11e7-8055-f09bf143dc7d.png)
  
  ### Database
  [db.sqlite3.zip](https://github.com/learningequality/kolibri/files/1617728/db.sqlite3.zip)
  
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `kolibri/logger/serializers.py`
  Content:
  ```
  1 from django.db.models import Sum
  2 from django.utils.timezone import now
  3 from kolibri.auth.models import FacilityUser
  4 from kolibri.core.serializers import KolibriModelSerializer
  5 from kolibri.logger.models import AttemptLog, ContentSessionLog, ContentSummaryLog, ExamAttemptLog, ExamLog, MasteryLog, UserSessionLog
  6 from rest_framework import serializers
  7 
  8 
  9 class ContentSessionLogSerializer(KolibriModelSerializer):
  10 
  11     extra_fields = serializers.JSONField(default='{}')
  12 
  13     class Meta:
  14         model = ContentSessionLog
  15         fields = ('pk', 'user', 'content_id', 'channel_id', 'start_timestamp',
  16                   'end_timestamp', 'time_spent', 'kind', 'extra_fields', 'progress')
  17 
  18 class ExamLogSerializer(KolibriModelSerializer):
  19     progress = serializers.SerializerMethodField()
  20     score = serializers.SerializerMethodField()
  21 
  22     def get_progress(self, obj):
  23         return obj.attemptlogs.count()
  24 
  25     def get_score(self, obj):
  26         return obj.attemptlogs.aggregate(Sum('correct')).get('correct__sum')
  27 
  28     class Meta:
  29         model = ExamLog
  30         fields = ('id', 'exam', 'user', 'closed', 'progress', 'score', 'completion_timestamp')
  31         read_only_fields = ('completion_timestamp', )
  32 
  33     def update(self, instance, validated_data):
  34         # This has changed, set the completion timestamp
  35         if validated_data.get('closed') and not instance.closed:
  36             instance.completion_timestamp = now()
  37         return super(ExamLogSerializer, self).update(instance, validated_data)
  38 
  39 class MasteryLogSerializer(KolibriModelSerializer):
  40 
  41     pastattempts = serializers.SerializerMethodField()
  42     totalattempts = serializers.SerializerMethodField()
  43     mastery_criterion = serializers.JSONField(default='{}')
  44 
  45     class Meta:
  46         model = MasteryLog
  47         fields = ('id', 'summarylog', 'start_timestamp', 'pastattempts', 'totalattempts', 'user',
  48                   'end_timestamp', 'completion_timestamp', 'mastery_criterion', 'mastery_level', 'complete')
  49 
  50     def get_pastattempts(self, obj):
  51         # will return a list of the latest 10 correct and hint_taken fields for each attempt.
  52         return AttemptLog.objects.filter(masterylog__summarylog=obj.summarylog).values('correct', 'hinted').order_by('-start_timestamp')[:10]
  53 
  54     def get_totalattempts(self, obj):
  55         return AttemptLog.objects.filter(masterylog__summarylog=obj.summarylog).count()
  56 
  57 class AttemptLogSerializer(KolibriModelSerializer):
  58     answer = serializers.JSONField(default='{}')
  59     interaction_history = serializers.JSONField(default='[]')
  60 
  61     class Meta:
  62         model = AttemptLog
  63         fields = ('id', 'masterylog', 'start_timestamp', 'sessionlog',
  64                   'end_timestamp', 'completion_timestamp', 'item', 'time_spent', 'user',
  65                   'complete', 'correct', 'hinted', 'answer', 'simple_answer', 'interaction_history')
  66 
  67 class ExamAttemptLogSerializer(KolibriModelSerializer):
  68     answer = serializers.JSONField(default='{}', allow_null=True)
  69     interaction_history = serializers.JSONField(default='[]')
  70 
  71     class Meta:
  72         model = ExamAttemptLog
  73         fields = ('id', 'examlog', 'start_timestamp', 'channel_id', 'content_id',
  74                   'end_timestamp', 'completion_timestamp', 'item', 'time_spent', 'user',
  75                   'complete', 'correct', 'hinted', 'answer', 'simple_answer', 'interaction_history')
  76 
  77     def validate(self, data):
  78         # Only do this validation when both are being set
  79         # not necessary on PATCH, for example
  80         if data.get('examlog') and data.get('user'):
  81             try:
  82                 if data['examlog'].user != data['user']:
  83                     raise serializers.ValidationError('User field and user for related exam log are not the same')
  84             except ExamLog.DoesNotExist:
  85                 raise serializers.ValidationError('Invalid exam log')
  86         return data
  87 
  88 class ContentSummaryLogSerializer(KolibriModelSerializer):
  89 
  90     currentmasterylog = serializers.SerializerMethodField()
  91     extra_fields = serializers.JSONField(default='{}')
  92 
  93     class Meta:
  94         model = ContentSummaryLog
  95         fields = ('pk', 'user', 'content_id', 'channel_id', 'start_timestamp', 'currentmasterylog',
  96                   'end_timestamp', 'completion_timestamp', 'time_spent', 'progress', 'kind', 'extra_fields')
  97 
  98     def get_currentmasterylog(self, obj):
  99         try:
  100             current_log = obj.masterylogs.latest('end_timestamp')
  101             return MasteryLogSerializer(current_log).data
  102         except MasteryLog.DoesNotExist:
  103             return None
  104 
  105 class UserSessionLogSerializer(KolibriModelSerializer):
  106 
  107     class Meta:
  108         model = UserSessionLog
  109         fields = ('pk', 'user', 'channels', 'start_timestamp', 'last_interaction_timestamp', 'pages')
  110 
  111 class TotalContentProgressSerializer(serializers.ModelSerializer):
  112 
  113     progress = serializers.SerializerMethodField()
  114 
  115     class Meta:
  116         model = FacilityUser
  117         fields = ('progress', 'id')
  118 
  119     def get_progress(self, obj):
  120         return obj.contentsummarylog_set.filter(progress=1).aggregate(Sum('progress')).get('progress__sum')
  121
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/kolibri/logger/serializers.py b/kolibri/logger/serializers.py
  --- a/kolibri/logger/serializers.py
  +++ b/kolibri/logger/serializers.py
  @@ -20,10 +20,10 @@
       score = serializers.SerializerMethodField()
   
       def get_progress(self, obj):
  -        return obj.attemptlogs.count()
  +        return obj.exam.question_count
   
       def get_score(self, obj):
  -        return obj.attemptlogs.aggregate(Sum('correct')).get('correct__sum')
  +        return obj.attemptlogs.values_list('item').order_by('completion_timestamp').distinct().aggregate(Sum('correct')).get('correct__sum')
   
       class Meta:
           model = ExamLog
  
verification_info: {"golden_diff": "diff --git a/kolibri/logger/serializers.py b/kolibri/logger/serializers.py\n--- a/kolibri/logger/serializers.py\n+++ b/kolibri/logger/serializers.py\n@@ -20,10 +20,10 @@\n     score = serializers.SerializerMethodField()\n \n     def get_progress(self, obj):\n-        return obj.attemptlogs.count()\n+        return obj.exam.question_count\n \n     def get_score(self, obj):\n-        return obj.attemptlogs.aggregate(Sum('correct')).get('correct__sum')\n+        return obj.attemptlogs.values_list('item').order_by('completion_timestamp').distinct().aggregate(Sum('correct')).get('correct__sum')\n \n     class Meta:\n         model = ExamLog\n", "issue": "Showing 120% score in exam report\n### Observed behavior\r\nAfter submitting exam, when coach user watching progress of each user in exam report. Coach user see 120% score in exam report. We have attached screenshot and database file,so you can easily re-generate this issue.\r\n\r\n### Expected behavior\r\nScore must be between 0-100%.\r\n\r\n### Steps to reproduce\r\n1. Copy attached database file in .kolibri folder.\r\n2. login with username \"pm\" and password \"sc\".\r\n3. Click on Coach.\r\n4. Click on Class 4A.\r\n5. Click on Exams.\r\n6. See report of the Unit 2B-Final exam.\r\n7. See learner Junaid Shaikh.\r\n\r\n### Context\r\n * Kolibri version : Kolibri 0.4.9\r\n * Operating system : Ubuntu 14.04\r\n * Browser : Chrome \r\n\r\n### Screenshots\r\n![1](https://user-images.githubusercontent.com/12776071/34758551-fc3ec802-f5fc-11e7-8055-f09bf143dc7d.png)\r\n\r\n### Database\r\n[db.sqlite3.zip](https://github.com/learningequality/kolibri/files/1617728/db.sqlite3.zip)\r\n\r\n\r\n\n", "before_files": [{"content": "from django.db.models import Sum\nfrom django.utils.timezone import now\nfrom kolibri.auth.models import FacilityUser\nfrom kolibri.core.serializers import KolibriModelSerializer\nfrom kolibri.logger.models import AttemptLog, ContentSessionLog, ContentSummaryLog, ExamAttemptLog, ExamLog, MasteryLog, UserSessionLog\nfrom rest_framework import serializers\n\n\nclass ContentSessionLogSerializer(KolibriModelSerializer):\n\n    extra_fields = serializers.JSONField(default='{}')\n\n    class Meta:\n        model = ContentSessionLog\n        fields = ('pk', 'user', 'content_id', 'channel_id', 'start_timestamp',\n                  'end_timestamp', 'time_spent', 'kind', 'extra_fields', 'progress')\n\nclass ExamLogSerializer(KolibriModelSerializer):\n    progress = serializers.SerializerMethodField()\n    score = serializers.SerializerMethodField()\n\n    def get_progress(self, obj):\n        return obj.attemptlogs.count()\n\n    def get_score(self, obj):\n        return obj.attemptlogs.aggregate(Sum('correct')).get('correct__sum')\n\n    class Meta:\n        model = ExamLog\n        fields = ('id', 'exam', 'user', 'closed', 'progress', 'score', 'completion_timestamp')\n        read_only_fields = ('completion_timestamp', )\n\n    def update(self, instance, validated_data):\n        # This has changed, set the completion timestamp\n        if validated_data.get('closed') and not instance.closed:\n            instance.completion_timestamp = now()\n        return super(ExamLogSerializer, self).update(instance, validated_data)\n\nclass MasteryLogSerializer(KolibriModelSerializer):\n\n    pastattempts = serializers.SerializerMethodField()\n    totalattempts = serializers.SerializerMethodField()\n    mastery_criterion = serializers.JSONField(default='{}')\n\n    class Meta:\n        model = MasteryLog\n        fields = ('id', 'summarylog', 'start_timestamp', 'pastattempts', 'totalattempts', 'user',\n                  'end_timestamp', 'completion_timestamp', 'mastery_criterion', 'mastery_level', 'complete')\n\n    def get_pastattempts(self, obj):\n        # will return a list of the latest 10 correct and hint_taken fields for each attempt.\n        return AttemptLog.objects.filter(masterylog__summarylog=obj.summarylog).values('correct', 'hinted').order_by('-start_timestamp')[:10]\n\n    def get_totalattempts(self, obj):\n        return AttemptLog.objects.filter(masterylog__summarylog=obj.summarylog).count()\n\nclass AttemptLogSerializer(KolibriModelSerializer):\n    answer = serializers.JSONField(default='{}')\n    interaction_history = serializers.JSONField(default='[]')\n\n    class Meta:\n        model = AttemptLog\n        fields = ('id', 'masterylog', 'start_timestamp', 'sessionlog',\n                  'end_timestamp', 'completion_timestamp', 'item', 'time_spent', 'user',\n                  'complete', 'correct', 'hinted', 'answer', 'simple_answer', 'interaction_history')\n\nclass ExamAttemptLogSerializer(KolibriModelSerializer):\n    answer = serializers.JSONField(default='{}', allow_null=True)\n    interaction_history = serializers.JSONField(default='[]')\n\n    class Meta:\n        model = ExamAttemptLog\n        fields = ('id', 'examlog', 'start_timestamp', 'channel_id', 'content_id',\n                  'end_timestamp', 'completion_timestamp', 'item', 'time_spent', 'user',\n                  'complete', 'correct', 'hinted', 'answer', 'simple_answer', 'interaction_history')\n\n    def validate(self, data):\n        # Only do this validation when both are being set\n        # not necessary on PATCH, for example\n        if data.get('examlog') and data.get('user'):\n            try:\n                if data['examlog'].user != data['user']:\n                    raise serializers.ValidationError('User field and user for related exam log are not the same')\n            except ExamLog.DoesNotExist:\n                raise serializers.ValidationError('Invalid exam log')\n        return data\n\nclass ContentSummaryLogSerializer(KolibriModelSerializer):\n\n    currentmasterylog = serializers.SerializerMethodField()\n    extra_fields = serializers.JSONField(default='{}')\n\n    class Meta:\n        model = ContentSummaryLog\n        fields = ('pk', 'user', 'content_id', 'channel_id', 'start_timestamp', 'currentmasterylog',\n                  'end_timestamp', 'completion_timestamp', 'time_spent', 'progress', 'kind', 'extra_fields')\n\n    def get_currentmasterylog(self, obj):\n        try:\n            current_log = obj.masterylogs.latest('end_timestamp')\n            return MasteryLogSerializer(current_log).data\n        except MasteryLog.DoesNotExist:\n            return None\n\nclass UserSessionLogSerializer(KolibriModelSerializer):\n\n    class Meta:\n        model = UserSessionLog\n        fields = ('pk', 'user', 'channels', 'start_timestamp', 'last_interaction_timestamp', 'pages')\n\nclass TotalContentProgressSerializer(serializers.ModelSerializer):\n\n    progress = serializers.SerializerMethodField()\n\n    class Meta:\n        model = FacilityUser\n        fields = ('progress', 'id')\n\n    def get_progress(self, obj):\n        return obj.contentsummarylog_set.filter(progress=1).aggregate(Sum('progress')).get('progress__sum')\n", "path": "kolibri/logger/serializers.py"}], "after_files": [{"content": "from django.db.models import Sum\nfrom django.utils.timezone import now\nfrom kolibri.auth.models import FacilityUser\nfrom kolibri.core.serializers import KolibriModelSerializer\nfrom kolibri.logger.models import AttemptLog, ContentSessionLog, ContentSummaryLog, ExamAttemptLog, ExamLog, MasteryLog, UserSessionLog\nfrom rest_framework import serializers\n\n\nclass ContentSessionLogSerializer(KolibriModelSerializer):\n\n    extra_fields = serializers.JSONField(default='{}')\n\n    class Meta:\n        model = ContentSessionLog\n        fields = ('pk', 'user', 'content_id', 'channel_id', 'start_timestamp',\n                  'end_timestamp', 'time_spent', 'kind', 'extra_fields', 'progress')\n\nclass ExamLogSerializer(KolibriModelSerializer):\n    progress = serializers.SerializerMethodField()\n    score = serializers.SerializerMethodField()\n\n    def get_progress(self, obj):\n        return obj.exam.question_count\n\n    def get_score(self, obj):\n        return obj.attemptlogs.values_list('item').order_by('completion_timestamp').distinct().aggregate(Sum('correct')).get('correct__sum')\n\n    class Meta:\n        model = ExamLog\n        fields = ('id', 'exam', 'user', 'closed', 'progress', 'score', 'completion_timestamp')\n        read_only_fields = ('completion_timestamp', )\n\n    def update(self, instance, validated_data):\n        # This has changed, set the completion timestamp\n        if validated_data.get('closed') and not instance.closed:\n            instance.completion_timestamp = now()\n        return super(ExamLogSerializer, self).update(instance, validated_data)\n\nclass MasteryLogSerializer(KolibriModelSerializer):\n\n    pastattempts = serializers.SerializerMethodField()\n    totalattempts = serializers.SerializerMethodField()\n    mastery_criterion = serializers.JSONField(default='{}')\n\n    class Meta:\n        model = MasteryLog\n        fields = ('id', 'summarylog', 'start_timestamp', 'pastattempts', 'totalattempts', 'user',\n                  'end_timestamp', 'completion_timestamp', 'mastery_criterion', 'mastery_level', 'complete')\n\n    def get_pastattempts(self, obj):\n        # will return a list of the latest 10 correct and hint_taken fields for each attempt.\n        return AttemptLog.objects.filter(masterylog__summarylog=obj.summarylog).values('correct', 'hinted').order_by('-start_timestamp')[:10]\n\n    def get_totalattempts(self, obj):\n        return AttemptLog.objects.filter(masterylog__summarylog=obj.summarylog).count()\n\nclass AttemptLogSerializer(KolibriModelSerializer):\n    answer = serializers.JSONField(default='{}')\n    interaction_history = serializers.JSONField(default='[]')\n\n    class Meta:\n        model = AttemptLog\n        fields = ('id', 'masterylog', 'start_timestamp', 'sessionlog',\n                  'end_timestamp', 'completion_timestamp', 'item', 'time_spent', 'user',\n                  'complete', 'correct', 'hinted', 'answer', 'simple_answer', 'interaction_history')\n\nclass ExamAttemptLogSerializer(KolibriModelSerializer):\n    answer = serializers.JSONField(default='{}', allow_null=True)\n    interaction_history = serializers.JSONField(default='[]')\n\n    class Meta:\n        model = ExamAttemptLog\n        fields = ('id', 'examlog', 'start_timestamp', 'channel_id', 'content_id',\n                  'end_timestamp', 'completion_timestamp', 'item', 'time_spent', 'user',\n                  'complete', 'correct', 'hinted', 'answer', 'simple_answer', 'interaction_history')\n\n    def validate(self, data):\n        # Only do this validation when both are being set\n        # not necessary on PATCH, for example\n        if data.get('examlog') and data.get('user'):\n            try:\n                if data['examlog'].user != data['user']:\n                    raise serializers.ValidationError('User field and user for related exam log are not the same')\n            except ExamLog.DoesNotExist:\n                raise serializers.ValidationError('Invalid exam log')\n        return data\n\nclass ContentSummaryLogSerializer(KolibriModelSerializer):\n\n    currentmasterylog = serializers.SerializerMethodField()\n    extra_fields = serializers.JSONField(default='{}')\n\n    class Meta:\n        model = ContentSummaryLog\n        fields = ('pk', 'user', 'content_id', 'channel_id', 'start_timestamp', 'currentmasterylog',\n                  'end_timestamp', 'completion_timestamp', 'time_spent', 'progress', 'kind', 'extra_fields')\n\n    def get_currentmasterylog(self, obj):\n        try:\n            current_log = obj.masterylogs.latest('end_timestamp')\n            return MasteryLogSerializer(current_log).data\n        except MasteryLog.DoesNotExist:\n            return None\n\nclass UserSessionLogSerializer(KolibriModelSerializer):\n\n    class Meta:\n        model = UserSessionLog\n        fields = ('pk', 'user', 'channels', 'start_timestamp', 'last_interaction_timestamp', 'pages')\n\nclass TotalContentProgressSerializer(serializers.ModelSerializer):\n\n    progress = serializers.SerializerMethodField()\n\n    class Meta:\n        model = FacilityUser\n        fields = ('progress', 'id')\n\n    def get_progress(self, obj):\n        return obj.contentsummarylog_set.filter(progress=1).aggregate(Sum('progress')).get('progress__sum')\n", "path": "kolibri/logger/serializers.py"}]}