def score_published_handler(sender, block, user, raw_earned, raw_possible, only_if_higher, **kwargs): # pylint: disable=unused-argument """ Handles whenever a block's score is published. Returns whether the score was actually updated. """ update_score = True if only_if_higher: previous_score = get_score(user.id, block.location) if previous_score is not None: prev_raw_earned, prev_raw_possible = previous_score # pylint: disable=unpacking-non-sequence if not is_score_higher(prev_raw_earned, prev_raw_possible, raw_earned, raw_possible): update_score = False log.warning( u"Grades: Rescore is not higher than previous: " u"user: {}, block: {}, previous: {}/{}, new: {}/{} ".format( user, block.location, prev_raw_earned, prev_raw_possible, raw_earned, raw_possible, ) ) if update_score: set_score(user.id, block.location, raw_earned, raw_possible) PROBLEM_SCORE_CHANGED.send( sender=None, points_earned=raw_earned, points_possible=raw_possible, user_id=user.id, course_id=unicode(block.location.course_key), usage_id=unicode(block.location), only_if_higher=only_if_higher, ) return update_score
def handle_grade_event(block, event_type, event): # pylint: disable=unused-argument """ Manages the workflow for recording and updating of student module grade state """ user_id = user.id grade = event.get('value') max_grade = event.get('max_value') set_score( user_id, descriptor.location, grade, max_grade, ) # Bin score into range and increment stats score_bucket = get_score_bucket(grade, max_grade) tags = [ u"org:{}".format(course_id.org), u"course:{}".format(course_id), u"score_bucket:{0}".format(score_bucket) ] if grade_bucket_type is not None: tags.append('type:%s' % grade_bucket_type) dog_stats_api.increment("lms.courseware.question_answered", tags=tags) # Cycle through the milestone fulfillment scenarios to see if any are now applicable # thanks to the updated grading information that was just submitted _fulfill_content_milestones( user, course_id, descriptor.location, ) # Send a signal out to any listeners who are waiting for score change # events. SCORE_CHANGED.send( sender=None, points_possible=event['max_value'], points_earned=event['value'], user_id=user_id, course_id=unicode(course_id), usage_id=unicode(descriptor.location) )
def score_published_handler(sender, block, user, raw_earned, raw_possible, only_if_higher, **kwargs): # pylint: disable=unused-argument """ Handles whenever a block's score is published. Returns whether the score was actually updated. """ update_score = True if only_if_higher: previous_score = get_score(user.id, block.location) if previous_score is not None: prev_raw_earned, prev_raw_possible = (previous_score.grade, previous_score.max_grade) if not is_score_higher(prev_raw_earned, prev_raw_possible, raw_earned, raw_possible): update_score = False log.warning( u"Grades: Rescore is not higher than previous: " u"user: {}, block: {}, previous: {}/{}, new: {}/{} ".format( user, block.location, prev_raw_earned, prev_raw_possible, raw_earned, raw_possible, ) ) if update_score: score_modified_time = set_score(user.id, block.location, raw_earned, raw_possible) PROBLEM_RAW_SCORE_CHANGED.send( sender=None, raw_earned=raw_earned, raw_possible=raw_possible, weight=getattr(block, 'weight', None), user_id=user.id, course_id=unicode(block.location.course_key), usage_id=unicode(block.location), only_if_higher=only_if_higher, modified=score_modified_time, ) return update_score
def test_submission_history_contents(self): # log into a staff account admin = AdminFactory.create() self.client.login(username=admin.username, password='******') usage_key = self.course_key.make_usage_key('problem', 'test-history') state_client = DjangoXBlockUserStateClient(admin) # store state via the UserStateClient state_client.set( username=admin.username, block_key=usage_key, state={'field_a': 'x', 'field_b': 'y'} ) set_score(admin.id, usage_key, 0, 3) state_client.set( username=admin.username, block_key=usage_key, state={'field_a': 'a', 'field_b': 'b'} ) set_score(admin.id, usage_key, 3, 3) url = reverse('submission_history', kwargs={ 'course_id': unicode(self.course_key), 'student_username': admin.username, 'location': unicode(usage_key), }) response = self.client.get(url) response_content = HTMLParser().unescape(response.content) # We have update the state 4 times: twice to change content, and twice # to set the scores. We'll check that the identifying content from each is # displayed (but not the order), and also the indexes assigned in the output # #1 - #4 self.assertIn('#1', response_content) self.assertIn(json.dumps({'field_a': 'a', 'field_b': 'b'}, sort_keys=True, indent=2), response_content) self.assertIn("Score: 0.0 / 3.0", response_content) self.assertIn(json.dumps({'field_a': 'x', 'field_b': 'y'}, sort_keys=True, indent=2), response_content) self.assertIn("Score: 3.0 / 3.0", response_content) self.assertIn('#4', response_content)
def score_published_handler(sender, block, user, raw_earned, raw_possible, only_if_higher, **kwargs): # pylint: disable=unused-argument """ Handles whenever a block's score is published. Returns whether the score was actually updated. """ update_score = True if only_if_higher: previous_score = get_score(user.id, block.location) if previous_score is not None: prev_raw_earned, prev_raw_possible = (previous_score.grade, previous_score.max_grade) if not is_score_higher_or_equal(prev_raw_earned, prev_raw_possible, raw_earned, raw_possible): update_score = False log.warning( u"Grades: Rescore is not higher than previous: " u"user: {}, block: {}, previous: {}/{}, new: {}/{} ". format( user, block.location, prev_raw_earned, prev_raw_possible, raw_earned, raw_possible, )) if update_score: # Set the problem score in CSM. score_modified_time = set_score(user.id, block.location, raw_earned, raw_possible) # Set the problem score on the xblock. if isinstance(block, ScorableXBlockMixin): block.set_score( Score(raw_earned=raw_earned, raw_possible=raw_possible)) # Fire a signal (consumed by enqueue_subsection_update, below) PROBLEM_RAW_SCORE_CHANGED.send( sender=None, raw_earned=raw_earned, raw_possible=raw_possible, weight=getattr(block, 'weight', None), user_id=user.id, course_id=unicode(block.location.course_key), usage_id=unicode(block.location), only_if_higher=only_if_higher, modified=score_modified_time, score_db_table=ScoreDatabaseTableEnum.courseware_student_module, score_deleted=kwargs.get('score_deleted', False), ) return update_score
def score_published_handler(sender, block, user, raw_earned, raw_possible, only_if_higher, **kwargs): # pylint: disable=unused-argument """ Handles whenever a block's score is published. Returns whether the score was actually updated. """ update_score = True if only_if_higher: previous_score = get_score(user.id, block.location) if previous_score: prev_raw_earned, prev_raw_possible = previous_score # pylint: disable=unpacking-non-sequence if not is_score_higher(prev_raw_earned, prev_raw_possible, raw_earned, raw_possible): update_score = False log.warning( u"Grades: Rescore is not higher than previous: " u"user: {}, block: {}, previous: {}/{}, new: {}/{} ". format( user, block.location, prev_raw_earned, prev_raw_possible, raw_earned, raw_possible, )) if update_score: set_score(user.id, block.location, raw_earned, raw_possible) SCORE_CHANGED.send( sender=None, points_earned=raw_earned, points_possible=raw_possible, user_id=user.id, course_id=unicode(block.location.course_key), usage_id=unicode(block.location), only_if_higher=only_if_higher, ) return update_score
def test_get_module_score_with_empty_score(self): """ Test test_get_module_score_with_empty_score """ set_score(self.request.user.id, self.problem1.location, None, None) # pylint: disable=no-member set_score(self.request.user.id, self.problem2.location, None, None) # pylint: disable=no-member with self.assertNumQueries(1): score = get_module_score(self.request.user, self.course, self.seq1) self.assertEqual(score, 0) answer_problem(self.course, self.request, self.problem1) with self.assertNumQueries(1): score = get_module_score(self.request.user, self.course, self.seq1) self.assertEqual(score, 0.5) answer_problem(self.course, self.request, self.problem2) with self.assertNumQueries(1): score = get_module_score(self.request.user, self.course, self.seq1) self.assertEqual(score, 1.0)
def score_published_handler(sender, block, user, raw_earned, raw_possible, only_if_higher, **kwargs): # pylint: disable=unused-argument """ Handles whenever a block's score is published. Returns whether the score was actually updated. """ update_score = True if only_if_higher: previous_score = get_score(user.id, block.location) if previous_score is not None: prev_raw_earned, prev_raw_possible = (previous_score.grade, previous_score.max_grade) if not is_score_higher_or_equal(prev_raw_earned, prev_raw_possible, raw_earned, raw_possible): update_score = False log.warning( u"Grades: Rescore is not higher than previous: " u"user: {}, block: {}, previous: {}/{}, new: {}/{} ".format( user, block.location, prev_raw_earned, prev_raw_possible, raw_earned, raw_possible, ) ) if update_score: # Set the problem score in CSM. score_modified_time = set_score(user.id, block.location, raw_earned, raw_possible) # Set the problem score on the xblock. if isinstance(block, ScorableXBlockMixin): block.set_score(Score(raw_earned=raw_earned, raw_possible=raw_possible)) # Fire a signal (consumed by enqueue_subsection_update, below) PROBLEM_RAW_SCORE_CHANGED.send( sender=None, raw_earned=raw_earned, raw_possible=raw_possible, weight=getattr(block, 'weight', None), user_id=user.id, course_id=six.text_type(block.location.course_key), usage_id=six.text_type(block.location), only_if_higher=only_if_higher, modified=score_modified_time, score_db_table=ScoreDatabaseTableEnum.courseware_student_module, score_deleted=kwargs.get('score_deleted', False), grader_response=kwargs.get('grader_response', False) ) return update_score