def _get_user_course_grades(self, user, course_id): """ Get the user's grade for the given course. Note: For performance reasons, we use the cached gradebook data here. Once persistent grades are enabled on the solutions fork, we'll use CourseGradeFactory instead. """ course_key = get_course_key(course_id) data = get_cached_data('grade', course_id, user.id) params = { 'exclude_users': get_aggregate_exclusion_user_ids(course_key, roles=None) } if not data: course_avg = StudentGradebook.course_grade_avg( course_key, **params) user_grade = StudentGradebook.get_user_grade(course_key, user.id) data = {'user_grade': user_grade, 'course_avg': course_avg} cache_course_data('grade', course_id, {'course_avg': course_avg}) cache_course_user_data('grade', course_id, user.id, {'user_grade': user_grade}) return { 'course_grade': data.get('user_grade'), 'course_average_grade': data.get('course_avg') }
def create_course_reference_data(course_key): """ Populates DB with test data """ user = UserFactory() group = GroupFactory() CourseGroupRelationship(course_id=course_key, group=group).save() StudentGradebook( user=user, course_id=course_key, grade=0.9, proforma_grade=0.91, progress_summary='test', grade_summary='test', grading_policy='test', ).save() StudentProgress(user=user, course_id=course_key, completions=1).save() CourseModuleCompletion(user=user, course_id=course_key, content_id='test', stage='test').save() CourseEnrollment(user=user, course_id=course_key).save() CourseAccessRole(user=user, course_id=course_key, org='test', role='TA').save() handouts_usage_key = course_key.make_usage_key('course_info', 'handouts') StudentModule(student=user, course_id=course_key, module_state_key=handouts_usage_key).save() CourseAggregatedMetaData(id=course_key, total_assessments=10, total_modules=20).save() structure_json = '{"test": true}' course_structure, created = CourseStructure.objects.get_or_create( course_id=course_key, defaults={'structure_json': structure_json} ) if not created: course_structure.structure_json = structure_json course_structure.save() CourseOverview.get_from_id(course_key)
def _get_course_average_grade(self, course_key): """ Get the average grade for all the users in the specified course. Note: For performance reasons, we use the cached gradebook data here. Once persistent grades are enabled on the solutions fork, we'll use CourseGradeFactory instead. """ return StudentGradebook.course_grade_avg(course_key)
def handle_studentgradebook_post_save_signal(sender, instance, **kwargs): """ Handle the pre-save ORM event on CourseModuleCompletions """ if settings.FEATURES['ENABLE_NOTIFICATIONS']: # attach the rank of the user before the save is completed data = StudentGradebook.get_user_position( instance.course_id, instance.user.id, exclude_users=get_aggregate_exclusion_user_ids(instance.course_id)) leaderboard_rank = data['user_position'] grade = data['user_grade'] # logic for Notification trigger is when a user enters into the Leaderboard if grade > 0.0: leaderboard_size = getattr(settings, 'LEADERBOARD_SIZE', 3) presave_leaderboard_rank = instance.presave_leaderboard_rank if instance.presave_leaderboard_rank else sys.maxint if leaderboard_rank <= leaderboard_size and presave_leaderboard_rank > leaderboard_size: try: notification_msg = NotificationMessage( msg_type=get_notification_type( u'open-edx.lms.leaderboard.gradebook.rank-changed' ), namespace=unicode(instance.course_id), payload={ '_schema_version': '1', 'rank': leaderboard_rank, 'leaderboard_name': 'Proficiency', }) # # add in all the context parameters we'll need to # generate a URL back to the website that will # present the new course announcement # # IMPORTANT: This can be changed to msg.add_click_link() if we # have a particular URL that we wish to use. In the initial use case, # we need to make the link point to a different front end website # so we need to resolve these links at dispatch time # notification_msg.add_click_link_params({ 'course_id': unicode(instance.course_id), }) publish_notification_to_user(int(instance.user.id), notification_msg) except Exception, ex: # Notifications are never critical, so we don't want to disrupt any # other logic processing. So log and continue. log.exception(ex)
def handle_studentgradebook_post_save_signal(sender, instance, **kwargs): """ Handle the pre-save ORM event on CourseModuleCompletions """ invalid_user_data_cache('grade', instance.course_id, instance.user.id) if settings.FEATURES['ENABLE_NOTIFICATIONS']: # attach the rank of the user before the save is completed data = StudentGradebook.get_user_position( instance.course_id, user_id=instance.user.id, exclude_users=get_aggregate_exclusion_user_ids(instance.course_id) ) leaderboard_rank = data['user_position'] grade = data['user_grade'] # logic for Notification trigger is when a user enters into the Leaderboard if grade > 0.0: leaderboard_size = getattr(settings, 'LEADERBOARD_SIZE', 3) presave_leaderboard_rank = instance.presave_leaderboard_rank if instance.presave_leaderboard_rank else sys.maxint if leaderboard_rank <= leaderboard_size and presave_leaderboard_rank > leaderboard_size: try: notification_msg = NotificationMessage( msg_type=get_notification_type(u'open-edx.lms.leaderboard.gradebook.rank-changed'), namespace=unicode(instance.course_id), payload={ '_schema_version': '1', 'rank': leaderboard_rank, 'leaderboard_name': 'Proficiency', } ) # # add in all the context parameters we'll need to # generate a URL back to the website that will # present the new course announcement # # IMPORTANT: This can be changed to msg.add_click_link() if we # have a particular URL that we wish to use. In the initial use case, # we need to make the link point to a different front end website # so we need to resolve these links at dispatch time # notification_msg.add_click_link_params({ 'course_id': unicode(instance.course_id), }) publish_notification_to_user(int(instance.user.id), notification_msg) except Exception, ex: # Notifications are never critical, so we don't want to disrupt any # other logic processing. So log and continue. log.exception(ex)
def test_course_passed(self): course = self.setup_course_with_grading() course2 = self.setup_course_with_grading() CourseEnrollmentFactory.create(user=self.user, course_id=course.id) CourseEnrollmentFactory.create(user=self.user, course_id=course2.id) module = self.get_module_for_user(self.user, course, course.homework_assignment) grade_dict = {'value': 0.5, 'max_value': 1, 'user_id': self.user.id} module.system.publish(module, 'grade', grade_dict) gradebook = StudentGradebook.objects.filter(is_passed=True) self.assertEqual(len(gradebook), 0) history = StudentGradebookHistory.objects.filter(is_passed=True) self.assertEqual(len(history), 0) module = self.get_module_for_user(self.user, course2, course2.midterm_assignment) grade_dict = {'value': 1, 'max_value': 1, 'user_id': self.user.id} module.system.publish(module, 'grade', grade_dict) gradebook = StudentGradebook.objects.filter(is_passed=True) self.assertEqual(len(gradebook), 1) gradebook = StudentGradebook.objects.filter(is_passed=True, user=self.user) self.assertEqual(len(gradebook), 1) history = StudentGradebookHistory.objects.filter(is_passed=True) self.assertEqual(len(history), 1) passed_count = StudentGradebook.get_passed_users_gradebook( course2.id).count() self.assertEqual(passed_count, 1) passed_count = StudentGradebook.get_passed_users_gradebook( course2.id, exclude_users=[self.user.id]).count() self.assertEqual(passed_count, 0)
def handle_studentgradebook_pre_save_signal(sender, instance, **kwargs): """ Handle the pre-save ORM event on CourseModuleCompletions """ if settings.FEATURES['ENABLE_NOTIFICATIONS']: # attach the rank of the user before the save is completed data = StudentGradebook.get_user_position( instance.course_id, instance.user.id, exclude_users=get_aggregate_exclusion_user_ids(instance.course_id)) grade = data['user_grade'] leaderboard_rank = data['user_position'] if grade > 0.0 else 0 instance.presave_leaderboard_rank = leaderboard_rank
def handle_studentgradebook_pre_save_signal(sender, instance, **kwargs): """ Handle the pre-save ORM event on CourseModuleCompletions """ if settings.FEATURES['ENABLE_NOTIFICATIONS']: # attach the rank of the user before the save is completed data = StudentGradebook.get_user_position( instance.course_id, user_id=instance.user.id, exclude_users=get_aggregate_exclusion_user_ids(instance.course_id) ) grade = data['user_grade'] leaderboard_rank = data['user_position'] if grade > 0.0 else 0 instance.presave_leaderboard_rank = leaderboard_rank