From cb54081d2eb4795b334d812edc76433d36d11935 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Tue, 6 Aug 2013 09:55:49 -0400 Subject: [PATCH 1/6] Fix notification problem --- .../open_ended_grading/open_ended_notifications.py | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/lms/djangoapps/open_ended_grading/open_ended_notifications.py b/lms/djangoapps/open_ended_grading/open_ended_notifications.py index 1d6fa22929..44ff41be22 100644 --- a/lms/djangoapps/open_ended_grading/open_ended_notifications.py +++ b/lms/djangoapps/open_ended_grading/open_ended_notifications.py @@ -146,19 +146,7 @@ def combined_notifications(course, user): #Get the time of the last login of the user last_login = user.last_login - - #Find the modules they have seen since they logged in - last_module_seen = StudentModule.objects.filter(student=user, course_id=course_id, - modified__gt=last_login).values('modified').order_by( - '-modified') - last_module_seen_count = last_module_seen.count() - - if last_module_seen_count > 0: - #The last time they viewed an updated notification (last module seen minus how long notifications are cached) - last_time_viewed = last_module_seen[0]['modified'] - datetime.timedelta(seconds=(NOTIFICATION_CACHE_TIME + 60)) - else: - #If they have not seen any modules since they logged in, then don't refresh - return {'pending_grading': False, 'img_path': img_path, 'response': notifications} + last_time_viewed = last_login - datetime.timedelta(seconds=(NOTIFICATION_CACHE_TIME + 60)) try: #Get the notifications from the grading controller From 1be6ce3ee387ead051b001112c0ef68a7a172b03 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 8 Aug 2013 08:34:08 -0400 Subject: [PATCH 2/6] Add in and route control options --- .../xmodule/combined_open_ended_module.py | 33 +++++++++++++++++-- .../combined_open_ended_modulev1.py | 11 +++++++ .../open_ended_module.py | 1 + .../openendedchild.py | 1 + 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/combined_open_ended_module.py b/common/lib/xmodule/xmodule/combined_open_ended_module.py index e01ae49149..f8ae7a3f13 100644 --- a/common/lib/xmodule/xmodule/combined_open_ended_module.py +++ b/common/lib/xmodule/xmodule/combined_open_ended_module.py @@ -14,7 +14,8 @@ import textwrap log = logging.getLogger("mitx.courseware") V1_SETTINGS_ATTRIBUTES = ["display_name", "max_attempts", "graded", "accept_file_upload", - "skip_spelling_checks", "due", "graceperiod", "weight"] + "skip_spelling_checks", "due", "graceperiod", "weight", "min_to_calibrate", + "max_to_calibrate", "peer_grader_count", "required_peer_grading"] V1_STUDENT_ATTRIBUTES = ["current_task_number", "task_states", "state", "student_attempts", "ready_to_reset"] @@ -37,7 +38,7 @@ DEFAULT_DATA = textwrap.dedent("""\

- Write a persuasive essay to a newspaper reflecting your vies on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading. + Write a persuasive essay to a newspaper reflecting your views on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading.

@@ -244,6 +245,34 @@ class CombinedOpenEndedFields(object): values={"min" : 0 , "step": ".1"}, default=1 ) + min_to_calibrate = Integer( + display_name="Minimum Peer Grading Calibrations", + help="The minimum number of calibration essays each student will need to complete for peer grading.", + default=1, + scope=Scope.settings, + values={"min" : 1, "step" : "1"} + ) + max_to_calibrate = Integer( + display_name="Maximum Peer Grading Calibrations", + help="The maximum number of calibration essays each student will need to complete for peer grading.", + default=1, + scope=Scope.settings, + values={"max" : 20, "step" : "1"} + ) + peer_grader_count = Integer( + display_name="Peer Graders per Response", + help="The number of peers who will grade each submission.", + default=1, + scope=Scope.settings, + values={"min" : 1, "step" : "1", "max" : 5} + ) + required_peer_grading = Integer( + display_name="Required Peer Grading", + help="The number of other students each student making a submission will have to grade.", + default=1, + scope=Scope.settings, + values={"min" : 1, "step" : "1", "max" : 5} + ) markdown = String( help="Markdown source of this module", default=textwrap.dedent("""\ diff --git a/common/lib/xmodule/xmodule/open_ended_grading_classes/combined_open_ended_modulev1.py b/common/lib/xmodule/xmodule/open_ended_grading_classes/combined_open_ended_modulev1.py index 933eb0b5bb..c65d30968d 100644 --- a/common/lib/xmodule/xmodule/open_ended_grading_classes/combined_open_ended_modulev1.py +++ b/common/lib/xmodule/xmodule/open_ended_grading_classes/combined_open_ended_modulev1.py @@ -106,6 +106,11 @@ class CombinedOpenEndedV1Module(): self.accept_file_upload = instance_state.get('accept_file_upload', ACCEPT_FILE_UPLOAD) in TRUE_DICT self.skip_basic_checks = instance_state.get('skip_spelling_checks', SKIP_BASIC_CHECKS) in TRUE_DICT + self.required_peer_grading = instance_state.get('required_peer_grading', 3) + self.peer_grader_count = instance_state.get('peer_grader_count', 3) + self.min_to_calibrate = instance_state.get('min_to_calibrate', 3) + self.max_to_calibrate = instance_state.get('max_to_calibrate', 6) + due_date = instance_state.get('due', None) grace_period_string = instance_state.get('graceperiod', None) @@ -131,6 +136,12 @@ class CombinedOpenEndedV1Module(): 'close_date': self.timeinfo.close_date, 's3_interface': self.system.s3_interface, 'skip_basic_checks': self.skip_basic_checks, + 'control': { + 'required_peer_grading': self.required_peer_grading, + 'peer_grader_count': self.peer_grader_count, + 'min_to_calibrate': self.min_to_calibrate, + 'max_to_calibrate': self.max_to_calibrate, + } } self.task_xml = definition['task_xml'] diff --git a/common/lib/xmodule/xmodule/open_ended_grading_classes/open_ended_module.py b/common/lib/xmodule/xmodule/open_ended_grading_classes/open_ended_module.py index 2e7a3eaf89..924ca2c23d 100644 --- a/common/lib/xmodule/xmodule/open_ended_grading_classes/open_ended_module.py +++ b/common/lib/xmodule/xmodule/open_ended_grading_classes/open_ended_module.py @@ -118,6 +118,7 @@ class OpenEndedModule(openendedchild.OpenEndedChild): 'answer': self.answer, 'problem_id': self.display_name, 'skip_basic_checks': self.skip_basic_checks, + 'control': json.dumps(self.control), }) updated_grader_payload = json.dumps(parsed_grader_payload) diff --git a/common/lib/xmodule/xmodule/open_ended_grading_classes/openendedchild.py b/common/lib/xmodule/xmodule/open_ended_grading_classes/openendedchild.py index 10f939b270..7138dcc723 100644 --- a/common/lib/xmodule/xmodule/open_ended_grading_classes/openendedchild.py +++ b/common/lib/xmodule/xmodule/open_ended_grading_classes/openendedchild.py @@ -92,6 +92,7 @@ class OpenEndedChild(object): self.s3_interface = static_data['s3_interface'] self.skip_basic_checks = static_data['skip_basic_checks'] self._max_score = static_data['max_score'] + self.control = static_data['control'] # Used for progress / grading. Currently get credit just for # completion (doesn't matter if you self-assessed correct/incorrect). From 4b5aba29ca3fc0b24ea4195bf5cf5f50065ff7db Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 8 Aug 2013 09:52:13 -0400 Subject: [PATCH 3/6] Fix defaults --- common/lib/xmodule/xmodule/combined_open_ended_module.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/lib/xmodule/xmodule/combined_open_ended_module.py b/common/lib/xmodule/xmodule/combined_open_ended_module.py index f8ae7a3f13..faf22d1926 100644 --- a/common/lib/xmodule/xmodule/combined_open_ended_module.py +++ b/common/lib/xmodule/xmodule/combined_open_ended_module.py @@ -248,28 +248,28 @@ class CombinedOpenEndedFields(object): min_to_calibrate = Integer( display_name="Minimum Peer Grading Calibrations", help="The minimum number of calibration essays each student will need to complete for peer grading.", - default=1, + default=3, scope=Scope.settings, values={"min" : 1, "step" : "1"} ) max_to_calibrate = Integer( display_name="Maximum Peer Grading Calibrations", help="The maximum number of calibration essays each student will need to complete for peer grading.", - default=1, + default=6, scope=Scope.settings, values={"max" : 20, "step" : "1"} ) peer_grader_count = Integer( display_name="Peer Graders per Response", help="The number of peers who will grade each submission.", - default=1, + default=3, scope=Scope.settings, values={"min" : 1, "step" : "1", "max" : 5} ) required_peer_grading = Integer( display_name="Required Peer Grading", help="The number of other students each student making a submission will have to grade.", - default=1, + default=3, scope=Scope.settings, values={"min" : 1, "step" : "1", "max" : 5} ) From 6e41c082b11a89ec4f54fe5b8e362dd460dff570 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Fri, 9 Aug 2013 12:30:05 -0400 Subject: [PATCH 4/6] Fix tests --- .../xmodule/tests/test_combined_open_ended.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/common/lib/xmodule/xmodule/tests/test_combined_open_ended.py b/common/lib/xmodule/xmodule/tests/test_combined_open_ended.py index 4fd0ddccf7..268f8f0b69 100644 --- a/common/lib/xmodule/xmodule/tests/test_combined_open_ended.py +++ b/common/lib/xmodule/xmodule/tests/test_combined_open_ended.py @@ -64,6 +64,12 @@ class OpenEndedChildTest(unittest.TestCase): 's3_interface': "", 'open_ended_grading_interface': {}, 'skip_basic_checks': False, + 'control': { + 'required_peer_grading': 1, + 'peer_grader_count': 1, + 'min_to_calibrate': 3, + 'max_to_calibrate': 6, + } } definition = Mock() descriptor = Mock() @@ -180,6 +186,12 @@ class OpenEndedModuleTest(unittest.TestCase): 's3_interface': test_util_open_ended.S3_INTERFACE, 'open_ended_grading_interface': test_util_open_ended.OPEN_ENDED_GRADING_INTERFACE, 'skip_basic_checks': False, + 'control': { + 'required_peer_grading': 1, + 'peer_grader_count': 1, + 'min_to_calibrate': 3, + 'max_to_calibrate': 6, + } } oeparam = etree.XML(''' From 8cf82f297371df61f93b346bf736b53daec9f381 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Fri, 9 Aug 2013 14:38:30 -0400 Subject: [PATCH 5/6] Fix self assessment test --- common/lib/xmodule/xmodule/tests/test_self_assessment.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common/lib/xmodule/xmodule/tests/test_self_assessment.py b/common/lib/xmodule/xmodule/tests/test_self_assessment.py index 0ccc6864cd..c9140d643a 100644 --- a/common/lib/xmodule/xmodule/tests/test_self_assessment.py +++ b/common/lib/xmodule/xmodule/tests/test_self_assessment.py @@ -49,6 +49,12 @@ class SelfAssessmentTest(unittest.TestCase): 's3_interface': test_util_open_ended.S3_INTERFACE, 'open_ended_grading_interface': test_util_open_ended.OPEN_ENDED_GRADING_INTERFACE, 'skip_basic_checks': False, + 'control': { + 'required_peer_grading': 1, + 'peer_grader_count': 1, + 'min_to_calibrate': 3, + 'max_to_calibrate': 6, + } } self.module = SelfAssessmentModule(get_test_system(), self.location, From 5c9538a9a112129d9d44551e23bdcd2cad35949c Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Fri, 9 Aug 2013 16:46:25 -0400 Subject: [PATCH 6/6] Address review comments --- .../xmodule/xmodule/combined_open_ended_module.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/common/lib/xmodule/xmodule/combined_open_ended_module.py b/common/lib/xmodule/xmodule/combined_open_ended_module.py index faf22d1926..2856c98127 100644 --- a/common/lib/xmodule/xmodule/combined_open_ended_module.py +++ b/common/lib/xmodule/xmodule/combined_open_ended_module.py @@ -13,9 +13,11 @@ import textwrap log = logging.getLogger("mitx.courseware") -V1_SETTINGS_ATTRIBUTES = ["display_name", "max_attempts", "graded", "accept_file_upload", - "skip_spelling_checks", "due", "graceperiod", "weight", "min_to_calibrate", - "max_to_calibrate", "peer_grader_count", "required_peer_grading"] +V1_SETTINGS_ATTRIBUTES = [ + "display_name", "max_attempts", "graded", "accept_file_upload", + "skip_spelling_checks", "due", "graceperiod", "weight", "min_to_calibrate", + "max_to_calibrate", "peer_grader_count", "required_peer_grading", +] V1_STUDENT_ATTRIBUTES = ["current_task_number", "task_states", "state", "student_attempts", "ready_to_reset"] @@ -250,14 +252,14 @@ class CombinedOpenEndedFields(object): help="The minimum number of calibration essays each student will need to complete for peer grading.", default=3, scope=Scope.settings, - values={"min" : 1, "step" : "1"} + values={"min" : 1, "max" : 20, "step" : "1"} ) max_to_calibrate = Integer( display_name="Maximum Peer Grading Calibrations", help="The maximum number of calibration essays each student will need to complete for peer grading.", default=6, scope=Scope.settings, - values={"max" : 20, "step" : "1"} + values={"min" : 1, "max" : 20, "step" : "1"} ) peer_grader_count = Integer( display_name="Peer Graders per Response",