From ef1f55a29380c846e9b7b81ac2143591f1355e08 Mon Sep 17 00:00:00 2001 From: Waheed Ahmed Date: Wed, 11 Dec 2013 20:42:31 +0500 Subject: [PATCH 01/10] Added command for open ended statistics. --- .../management/commands/openended_stats.py | 61 ++++++++++++++++ lms/djangoapps/instructor/utils.py | 69 +++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 lms/djangoapps/instructor/management/commands/openended_stats.py create mode 100644 lms/djangoapps/instructor/utils.py diff --git a/lms/djangoapps/instructor/management/commands/openended_stats.py b/lms/djangoapps/instructor/management/commands/openended_stats.py new file mode 100644 index 000000000000..15535bc774eb --- /dev/null +++ b/lms/djangoapps/instructor/management/commands/openended_stats.py @@ -0,0 +1,61 @@ +#!/usr/bin/python +# +# django management command: dump grades to csv files +# for use by batch processes + +from instructor.offline_gradecalc import offline_grade_calculation +from courseware.courses import get_course_by_id +from xmodule.modulestore.django import modulestore +from courseware.models import StudentModule +from courseware.model_data import FieldDataCache +from courseware.module_render import get_module, get_module_for_descriptor +from django.contrib.auth.models import User +from ...utils import create_module, get_descriptor, DummyRequest + +from django.core.management.base import BaseCommand + + +class Command(BaseCommand): + help = "Usage: openended_stats course_id location \n" + + def handle(self, *args, **options): + + print "args = ", args + + if len(args) > 0: + course_id = args[0] + location = args[1] + else: + print self.help + return + + request = DummyRequest() + course = get_course_by_id(course_id) + descriptor = get_descriptor(course, location) + if descriptor is None: + print "Location not found in course" + return + + enrolled_students = User.objects.filter( + courseenrollment__course_id=course_id, + courseenrollment__is_active=1 + ).prefetch_related("groups").order_by('username') + + for student in enrolled_students: + request.user = student + request.session = {} + module = create_module(descriptor, course, student, request) + tasks = len(module.task_states) + # if tasks>0: + print tasks + + try: + student_module = StudentModule.objects.get( + student=student, + course_id=course_id, + module_state_key=descriptor.id + ) + # print student_module + + except StudentModule.DoesNotExist: + student_module = None diff --git a/lms/djangoapps/instructor/utils.py b/lms/djangoapps/instructor/utils.py new file mode 100644 index 000000000000..a9ec9fd3e0d9 --- /dev/null +++ b/lms/djangoapps/instructor/utils.py @@ -0,0 +1,69 @@ + +from courseware.model_data import FieldDataCache +from courseware.module_render import get_module, get_module_for_descriptor +from courseware.courses import get_course_by_id +from django.contrib.auth.models import User + + +def get_descriptor(course, location): + if isinstance(course, str): + course = get_course_by_id(course) + grading_context = course.grading_context + descriptor = None + for section_format, sections in grading_context['graded_sections'].iteritems(): + try: + for section in sections: + section_descriptor = section['section_descriptor'] + descriptor = find_descriptor_in_children(section_descriptor, location) + if descriptor: + break + + if descriptor: + break + + except Exception as err: + print err.message + + return descriptor + + +def find_descriptor_in_children(descriptor, location): + try: + if descriptor.id == location: + return descriptor + children = descriptor.get_children() + except: + children = [] + for module_descriptor in children: + child_descriptor = find_descriptor_in_children(module_descriptor, location) + if child_descriptor: + return child_descriptor + return None + +def create_module(descriptor, course, student, request): + field_data_cache = FieldDataCache([descriptor], course.id, student) + return get_module_for_descriptor(student, request, descriptor, field_data_cache, course.id) + +def get_module_for_student(student_name, course_id, location): + try: + student = User.objects.get(username=student_name) + request = DummyRequest() + request.user = student + request.session = {} + course = get_course_by_id(course_id) + descriptor = get_descriptor(course, location) + module = create_module(descriptor, course, student, request) + return module + except Exception as e: + print e.message + return None + + +class DummyRequest(object): + META = {} + def __init__(self): + return + def get_host(self): + return 'edx.mit.edu' + def is_secure(self): + return False \ No newline at end of file From b140d668d8f5800abc4641e1fefd1f24f466937b Mon Sep 17 00:00:00 2001 From: Waheed Ahmed Date: Thu, 12 Dec 2013 18:46:53 +0500 Subject: [PATCH 02/10] Django management command for open ended problems. --- .../combined_open_ended_modulev1.py | 23 +++++++ .../management/commands/openended_stats.py | 68 +++++++++---------- lms/djangoapps/instructor/utils.py | 61 ++++++++++++----- 3 files changed, 99 insertions(+), 53 deletions(-) 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 2c02833baa5a..cabb5d177f75 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 @@ -348,6 +348,29 @@ def fix_invalid_state(self): last_completed_child = next((i for i, child in reversed(list(enumerate(children))) if child['child_state'] == self.DONE), 0) self.current_task_number = min(last_completed_child + 1, len(best_task_states) - 1) + def create_task(self, task_state, task_xml): + """Create task object for given task state and task xml.""" + + tag_name = self.get_tag_name(task_xml) + children = self.child_modules() + task_descriptor = children['descriptors'][tag_name](self.system) + task_parsed_xml = task_descriptor.definition_from_xml(etree.fromstring(task_xml), self.system) + task = children['modules'][tag_name]( + self.system, + self.location, + task_parsed_xml, + task_descriptor, + self.static_data, + instance_state=task_state, + ) + return task + + def get_latest_task(self): + """Return latest task object.""" + + last_task_state = self.task_states[-1] + last_task_xml = self.task_xml[-1] + return self.create_task(last_task_state, last_task_xml) def reset_task_state(self, message=""): """ diff --git a/lms/djangoapps/instructor/management/commands/openended_stats.py b/lms/djangoapps/instructor/management/commands/openended_stats.py index 15535bc774eb..e3b88e76ef3d 100644 --- a/lms/djangoapps/instructor/management/commands/openended_stats.py +++ b/lms/djangoapps/instructor/management/commands/openended_stats.py @@ -1,24 +1,19 @@ #!/usr/bin/python # -# django management command: dump grades to csv files -# for use by batch processes - -from instructor.offline_gradecalc import offline_grade_calculation -from courseware.courses import get_course_by_id -from xmodule.modulestore.django import modulestore -from courseware.models import StudentModule -from courseware.model_data import FieldDataCache -from courseware.module_render import get_module, get_module_for_descriptor -from django.contrib.auth.models import User -from ...utils import create_module, get_descriptor, DummyRequest +# Admin command for open ended problems. +from xmodule.open_ended_grading_classes.openendedchild import OpenEndedChild +from ...utils import get_descriptor, get_module_for_student, get_enrolled_students from django.core.management.base import BaseCommand class Command(BaseCommand): + """Admin command for open ended problems.""" + help = "Usage: openended_stats course_id location \n" def handle(self, *args, **options): + """Handler for command.""" print "args = ", args @@ -29,33 +24,32 @@ def handle(self, *args, **options): print self.help return - request = DummyRequest() - course = get_course_by_id(course_id) - descriptor = get_descriptor(course, location) + descriptor = get_descriptor(course_id, location) if descriptor is None: print "Location not found in course" return - enrolled_students = User.objects.filter( - courseenrollment__course_id=course_id, - courseenrollment__is_active=1 - ).prefetch_related("groups").order_by('username') - - for student in enrolled_students: - request.user = student - request.session = {} - module = create_module(descriptor, course, student, request) - tasks = len(module.task_states) - # if tasks>0: - print tasks - - try: - student_module = StudentModule.objects.get( - student=student, - course_id=course_id, - module_state_key=descriptor.id - ) - # print student_module - - except StudentModule.DoesNotExist: - student_module = None + enrolled_students = get_enrolled_students(course_id) + print "Total students enrolled: {0}".format(enrolled_students.count()) + + self.get_state_counts(enrolled_students, course_id, location) + + def get_state_counts(self, students, course_id, location): + """Print stats of students.""" + + stats = { + OpenEndedChild.INITIAL: 0, + OpenEndedChild.ASSESSING: 0, + OpenEndedChild.POST_ASSESSMENT: 0, + OpenEndedChild.DONE: 0 + } + + for index, student in enumerate(students): + if index % 100 == 0: + print "{0} students processed".format(index) + + module = get_module_for_student(student, course_id, location) + latest_task = module._xmodule.child_module.get_latest_task() + stats[latest_task.child_state] += 1 + + print stats diff --git a/lms/djangoapps/instructor/utils.py b/lms/djangoapps/instructor/utils.py index a9ec9fd3e0d9..191ea14376e7 100644 --- a/lms/djangoapps/instructor/utils.py +++ b/lms/djangoapps/instructor/utils.py @@ -1,13 +1,14 @@ from courseware.model_data import FieldDataCache -from courseware.module_render import get_module, get_module_for_descriptor +from courseware.module_render import get_module_for_descriptor from courseware.courses import get_course_by_id from django.contrib.auth.models import User -def get_descriptor(course, location): - if isinstance(course, str): - course = get_course_by_id(course) +def get_descriptor(course_id, location): + """Find descriptor for the location in the course.""" + + course = get_course_by_id(course_id) grading_context = course.grading_context descriptor = None for section_format, sections in grading_context['graded_sections'].iteritems(): @@ -28,6 +29,8 @@ def get_descriptor(course, location): def find_descriptor_in_children(descriptor, location): + """Recursively look for location in descriptors children.""" + try: if descriptor.id == location: return descriptor @@ -40,30 +43,56 @@ def find_descriptor_in_children(descriptor, location): return child_descriptor return None -def create_module(descriptor, course, student, request): + +def create_module(student, course, descriptor, request): + """Create module for student from descriptor.""" + field_data_cache = FieldDataCache([descriptor], course.id, student) return get_module_for_descriptor(student, request, descriptor, field_data_cache, course.id) -def get_module_for_student(student_name, course_id, location): - try: - student = User.objects.get(username=student_name) + +def get_module_for_student(student, course, location, request=None): + """Return module for student from location.""" + + if isinstance(student, str): + try: + student = User.objects.get(username=student) + except User.DoesNotExist: + return None + + if request is None: request = DummyRequest() request.user = student request.session = {} - course = get_course_by_id(course_id) - descriptor = get_descriptor(course, location) - module = create_module(descriptor, course, student, request) - return module - except Exception as e: - print e.message - return None + if isinstance(course, str): + course = get_course_by_id(course) + if course is None: + return None + descriptor = get_descriptor(course.id, location) + module = create_module(student, course, descriptor, request) + return module + + +def get_enrolled_students(course_id): + """Return enrolled students for course.""" + + enrolled_students = User.objects.filter( + courseenrollment__course_id=course_id, + courseenrollment__is_active=1 + ).prefetch_related("groups").order_by('username') + return enrolled_students class DummyRequest(object): + """Dummy request""" + META = {} + def __init__(self): return + def get_host(self): return 'edx.mit.edu' + def is_secure(self): - return False \ No newline at end of file + return False From 0d31772ac769fc8be8b725e6893028617f6d58ea Mon Sep 17 00:00:00 2001 From: Waheed Ahmed Date: Fri, 13 Dec 2013 14:37:24 +0500 Subject: [PATCH 03/10] Added csv reader to get student ids from csv. --- lms/djangoapps/instructor/utils.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lms/djangoapps/instructor/utils.py b/lms/djangoapps/instructor/utils.py index 191ea14376e7..3d297f911073 100644 --- a/lms/djangoapps/instructor/utils.py +++ b/lms/djangoapps/instructor/utils.py @@ -2,6 +2,7 @@ from courseware.model_data import FieldDataCache from courseware.module_render import get_module_for_descriptor from courseware.courses import get_course_by_id +import csv from django.contrib.auth.models import User @@ -83,6 +84,20 @@ def get_enrolled_students(course_id): return enrolled_students +def read_csv(path_to_csv): + """ + reads a csv and returns a list + """ + + affected_students_ids = [] + with open(path_to_csv) as csv_file: + csv_reader = csv.reader(csv_file) + for row in csv_reader: + affected_students_ids.append(row[0]) + + return affected_students_ids + + class DummyRequest(object): """Dummy request""" From 1c13360a0c3dea7569040577f2cd429f95a987da Mon Sep 17 00:00:00 2001 From: Waheed Ahmed Date: Fri, 13 Dec 2013 15:48:27 +0500 Subject: [PATCH 04/10] Adedd django command for student submission send to grader. --- .../management/commands/openended_post.py | 38 +++++++++++++++++++ lms/djangoapps/instructor/utils.py | 10 +++++ 2 files changed, 48 insertions(+) create mode 100644 lms/djangoapps/instructor/management/commands/openended_post.py diff --git a/lms/djangoapps/instructor/management/commands/openended_post.py b/lms/djangoapps/instructor/management/commands/openended_post.py new file mode 100644 index 000000000000..99127e575486 --- /dev/null +++ b/lms/djangoapps/instructor/management/commands/openended_post.py @@ -0,0 +1,38 @@ +#!/usr/bin/python +# +# django management command: dump grades to csv files +# for use by batch processes + +from ...utils import get_descriptor, read_csv, get_affected_students_from_ids, get_module_for_student +from django.core.management.base import BaseCommand + + +class Command(BaseCommand): + help = "Usage: posts problem to xqueue \n" + + def handle(self, *args, **options): + + print "args = ", args + + if len(args) > 0: + course_id = args[0] + location = args[1] + affected_students_ids = read_csv(args[2]) + else: + print self.help + return + + descriptor = get_descriptor(course_id, location) + if descriptor is None: + print "Location not found in course" + return + + affected_students = get_affected_students_from_ids(affected_students_ids) + + for student in affected_students: + try: + module = get_module_for_student(student, course_id, location) + latest_task = module._xmodule.child_module.get_latest_task() + latest_task.send_to_grader(latest_task.latest_answer(), latest_task.system) + except Exception as err: + print err diff --git a/lms/djangoapps/instructor/utils.py b/lms/djangoapps/instructor/utils.py index 3d297f911073..8b1244c80409 100644 --- a/lms/djangoapps/instructor/utils.py +++ b/lms/djangoapps/instructor/utils.py @@ -84,6 +84,16 @@ def get_enrolled_students(course_id): return enrolled_students +def get_affected_students_from_ids(affected_students_ids): + """Return affected students form ids list.""" + + affected_students = User.objects.filter( + id__in=affected_students_ids, + courseenrollment__is_active=1 + ).prefetch_related("groups").order_by('username') + return affected_students + + def read_csv(path_to_csv): """ reads a csv and returns a list From f47e7cc3aaf62488f3b8660d5c600fd49dd8b121 Mon Sep 17 00:00:00 2001 From: Usman Khalid Date: Fri, 13 Dec 2013 20:27:10 +0500 Subject: [PATCH 05/10] Added some checking and logging --- .../management/commands/openended_post.py | 35 ++++++++++++++---- lms/djangoapps/instructor/utils.py | 36 +++++++++---------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/lms/djangoapps/instructor/management/commands/openended_post.py b/lms/djangoapps/instructor/management/commands/openended_post.py index 99127e575486..6f3a84d3a398 100644 --- a/lms/djangoapps/instructor/management/commands/openended_post.py +++ b/lms/djangoapps/instructor/management/commands/openended_post.py @@ -3,21 +3,22 @@ # django management command: dump grades to csv files # for use by batch processes -from ...utils import get_descriptor, read_csv, get_affected_students_from_ids, get_module_for_student +from xmodule.open_ended_grading_classes.openendedchild import OpenEndedChild +from ...utils import get_descriptor, create_list_from_csv, get_users_from_ids, get_module_for_student from django.core.management.base import BaseCommand class Command(BaseCommand): - help = "Usage: posts problem to xqueue \n" + help = "Usage: openended_post \n" def handle(self, *args, **options): print "args = ", args - if len(args) > 0: + if len(args) == 3: course_id = args[0] location = args[1] - affected_students_ids = read_csv(args[2]) + students_ids = create_list_from_csv(args[2]) else: print self.help return @@ -27,12 +28,32 @@ def handle(self, *args, **options): print "Location not found in course" return - affected_students = get_affected_students_from_ids(affected_students_ids) + students = get_users_from_ids(students_ids) + print "Number of students: {0}".format(students.count()) - for student in affected_students: + for student in students: + print "------Student {0}:{1}------".format(student.id, student.username) try: module = get_module_for_student(student, course_id, location) + if module is None: + print "No state found." + continue + latest_task = module._xmodule.child_module.get_latest_task() - latest_task.send_to_grader(latest_task.latest_answer(), latest_task.system) + if latest_task is None: + print "State is invalid." + latest_task_state = latest_task.child_state + + if latest_task_state == OpenEndedChild.INITIAL: + print "No submission." + elif latest_task_state == OpenEndedChild.POST_ASSESSMENT or latest_task_state == OpenEndedChild.DONE: + print "Submission already graded." + elif latest_task_state == OpenEndedChild.ASSESSING: + print "Sending submission to grader." + latest_task.send_to_grader(latest_task.latest_answer(), latest_task.system) + else: + print "Invalid task_state: {0}".format(latest_task_state) except Exception as err: print err + else: + print "Successfully sent to grader." diff --git a/lms/djangoapps/instructor/utils.py b/lms/djangoapps/instructor/utils.py index 8b1244c80409..f2a092f3dae9 100644 --- a/lms/djangoapps/instructor/utils.py +++ b/lms/djangoapps/instructor/utils.py @@ -61,14 +61,16 @@ def get_module_for_student(student, course, location, request=None): except User.DoesNotExist: return None - if request is None: - request = DummyRequest() - request.user = student - request.session = {} if isinstance(course, str): course = get_course_by_id(course) if course is None: return None + + if request is None: + request = DummyRequest() + request.user = student + request.session = {} + descriptor = get_descriptor(course.id, location) module = create_module(student, course, descriptor, request) return module @@ -84,28 +86,24 @@ def get_enrolled_students(course_id): return enrolled_students -def get_affected_students_from_ids(affected_students_ids): - """Return affected students form ids list.""" - - affected_students = User.objects.filter( - id__in=affected_students_ids, - courseenrollment__is_active=1 - ).prefetch_related("groups").order_by('username') - return affected_students +def get_users_from_ids(ids): + """Return students from a list of ids.""" + users = User.objects.filter( + id__in=ids, + ).order_by('username') + return users -def read_csv(path_to_csv): - """ - reads a csv and returns a list - """ +def create_list_from_csv(path_to_csv): + """Read a csv and return items in a list.""" - affected_students_ids = [] + items = [] with open(path_to_csv) as csv_file: csv_reader = csv.reader(csv_file) for row in csv_reader: - affected_students_ids.append(row[0]) + items.append(row[0]) - return affected_students_ids + return items class DummyRequest(object): From c599dfd8821876429fccb0b6cf131ebd5141dfe9 Mon Sep 17 00:00:00 2001 From: Usman Khalid Date: Fri, 13 Dec 2013 20:40:50 +0500 Subject: [PATCH 06/10] Minor fixes --- .../instructor/management/commands/openended_post.py | 9 ++++----- .../instructor/management/commands/openended_stats.py | 8 ++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lms/djangoapps/instructor/management/commands/openended_post.py b/lms/djangoapps/instructor/management/commands/openended_post.py index 6f3a84d3a398..a30e66cbcfa3 100644 --- a/lms/djangoapps/instructor/management/commands/openended_post.py +++ b/lms/djangoapps/instructor/management/commands/openended_post.py @@ -1,7 +1,6 @@ -#!/usr/bin/python +#!/usr/bin/env python # -# django management command: dump grades to csv files -# for use by batch processes +# Command to post student submissions to ORA from xmodule.open_ended_grading_classes.openendedchild import OpenEndedChild from ...utils import get_descriptor, create_list_from_csv, get_users_from_ids, get_module_for_student @@ -9,12 +8,12 @@ class Command(BaseCommand): + """ """ + help = "Usage: openended_post \n" def handle(self, *args, **options): - print "args = ", args - if len(args) == 3: course_id = args[0] location = args[1] diff --git a/lms/djangoapps/instructor/management/commands/openended_stats.py b/lms/djangoapps/instructor/management/commands/openended_stats.py index e3b88e76ef3d..0b8f5beef4f9 100644 --- a/lms/djangoapps/instructor/management/commands/openended_stats.py +++ b/lms/djangoapps/instructor/management/commands/openended_stats.py @@ -1,6 +1,6 @@ -#!/usr/bin/python +#!/usr/bin/env python # -# Admin command for open ended problems. +# Command to get statistics about an openended problem. from xmodule.open_ended_grading_classes.openendedchild import OpenEndedChild from ...utils import get_descriptor, get_module_for_student, get_enrolled_students @@ -10,14 +10,14 @@ class Command(BaseCommand): """Admin command for open ended problems.""" - help = "Usage: openended_stats course_id location \n" + help = "Usage: openended_stats \n" def handle(self, *args, **options): """Handler for command.""" print "args = ", args - if len(args) > 0: + if len(args) == 2: course_id = args[0] location = args[1] else: From 9891acbef1c49fef5037dab86816168a7b222110 Mon Sep 17 00:00:00 2001 From: Usman Khalid Date: Fri, 13 Dec 2013 21:48:14 +0500 Subject: [PATCH 07/10] If score_msg is empty dont try to parse it --- .../xmodule/open_ended_grading_classes/open_ended_module.py | 4 ++++ 1 file changed, 4 insertions(+) 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 680ed031d123..6e0254ca7ae7 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 @@ -485,6 +485,10 @@ def _parse_score_msg(self, score_msg, system, join_feedback=True): 'grader_ids': [0], 'submission_ids': [0], } + + if score_msg == "": + return fail + try: score_result = json.loads(score_msg) except (TypeError, ValueError): From 627cb9e196efc9524bc83e6ddc34b17d15f84006 Mon Sep 17 00:00:00 2001 From: Usman Khalid Date: Fri, 13 Dec 2013 21:49:28 +0500 Subject: [PATCH 08/10] Fixes --- .../combined_open_ended_modulev1.py | 15 +++++++++------ .../management/commands/openended_post.py | 7 +++++-- .../management/commands/openended_stats.py | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) 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 cabb5d177f75..6fdb11565092 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 @@ -365,12 +365,15 @@ def create_task(self, task_state, task_xml): ) return task - def get_latest_task(self): - """Return latest task object.""" - - last_task_state = self.task_states[-1] - last_task_xml = self.task_xml[-1] - return self.create_task(last_task_state, last_task_xml) + def get_current_task(self): + """Return current task object.""" + + if len(self.task_states) > 0: + current_task_index = len(self.task_states) - 1 + current_task_state = self.task_states[current_task_index] + current_task_xml = self.task_xml[current_task_index] + return self.create_task(current_task_state, current_task_xml) + return None def reset_task_state(self, message=""): """ diff --git a/lms/djangoapps/instructor/management/commands/openended_post.py b/lms/djangoapps/instructor/management/commands/openended_post.py index a30e66cbcfa3..3e78ea6df25d 100644 --- a/lms/djangoapps/instructor/management/commands/openended_post.py +++ b/lms/djangoapps/instructor/management/commands/openended_post.py @@ -38,9 +38,11 @@ def handle(self, *args, **options): print "No state found." continue - latest_task = module._xmodule.child_module.get_latest_task() + latest_task = module._xmodule.child_module.get_current_task() if latest_task is None: print "State is invalid." + continue + latest_task_state = latest_task.child_state if latest_task_state == OpenEndedChild.INITIAL: @@ -48,8 +50,9 @@ def handle(self, *args, **options): elif latest_task_state == OpenEndedChild.POST_ASSESSMENT or latest_task_state == OpenEndedChild.DONE: print "Submission already graded." elif latest_task_state == OpenEndedChild.ASSESSING: + latest_answer = latest_task.latest_answer() print "Sending submission to grader." - latest_task.send_to_grader(latest_task.latest_answer(), latest_task.system) + latest_task.send_to_grader(latest_answer, latest_task.system) else: print "Invalid task_state: {0}".format(latest_task_state) except Exception as err: diff --git a/lms/djangoapps/instructor/management/commands/openended_stats.py b/lms/djangoapps/instructor/management/commands/openended_stats.py index 0b8f5beef4f9..59ea6588ae46 100644 --- a/lms/djangoapps/instructor/management/commands/openended_stats.py +++ b/lms/djangoapps/instructor/management/commands/openended_stats.py @@ -49,7 +49,7 @@ def get_state_counts(self, students, course_id, location): print "{0} students processed".format(index) module = get_module_for_student(student, course_id, location) - latest_task = module._xmodule.child_module.get_latest_task() + latest_task = module._xmodule.child_module.get_current_task() stats[latest_task.child_state] += 1 print stats From fce9c45a0d2098eee90d15213fcf17db7fca9bc5 Mon Sep 17 00:00:00 2001 From: Usman Khalid Date: Fri, 13 Dec 2013 21:57:00 +0500 Subject: [PATCH 09/10] Removed hashbang --- .../instructor/management/commands/openended_post.py | 4 ---- .../instructor/management/commands/openended_stats.py | 4 ---- 2 files changed, 8 deletions(-) diff --git a/lms/djangoapps/instructor/management/commands/openended_post.py b/lms/djangoapps/instructor/management/commands/openended_post.py index 3e78ea6df25d..9c9ae21e9150 100644 --- a/lms/djangoapps/instructor/management/commands/openended_post.py +++ b/lms/djangoapps/instructor/management/commands/openended_post.py @@ -1,7 +1,3 @@ -#!/usr/bin/env python -# -# Command to post student submissions to ORA - from xmodule.open_ended_grading_classes.openendedchild import OpenEndedChild from ...utils import get_descriptor, create_list_from_csv, get_users_from_ids, get_module_for_student from django.core.management.base import BaseCommand diff --git a/lms/djangoapps/instructor/management/commands/openended_stats.py b/lms/djangoapps/instructor/management/commands/openended_stats.py index 59ea6588ae46..d708ef5512ae 100644 --- a/lms/djangoapps/instructor/management/commands/openended_stats.py +++ b/lms/djangoapps/instructor/management/commands/openended_stats.py @@ -1,7 +1,3 @@ -#!/usr/bin/env python -# -# Command to get statistics about an openended problem. - from xmodule.open_ended_grading_classes.openendedchild import OpenEndedChild from ...utils import get_descriptor, get_module_for_student, get_enrolled_students from django.core.management.base import BaseCommand From 0b506137224cee52a5219ade6d651da35078be8f Mon Sep 17 00:00:00 2001 From: Usman Khalid Date: Fri, 13 Dec 2013 22:01:55 +0500 Subject: [PATCH 10/10] Improved log messages. --- .../management/commands/openended_post.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lms/djangoapps/instructor/management/commands/openended_post.py b/lms/djangoapps/instructor/management/commands/openended_post.py index 9c9ae21e9150..db7aadd06b01 100644 --- a/lms/djangoapps/instructor/management/commands/openended_post.py +++ b/lms/djangoapps/instructor/management/commands/openended_post.py @@ -31,27 +31,25 @@ def handle(self, *args, **options): try: module = get_module_for_student(student, course_id, location) if module is None: - print "No state found." + print "WARNING: No state found." continue latest_task = module._xmodule.child_module.get_current_task() if latest_task is None: - print "State is invalid." + print "WARNING: No state found." continue latest_task_state = latest_task.child_state if latest_task_state == OpenEndedChild.INITIAL: - print "No submission." + print "WARNING: No submission." elif latest_task_state == OpenEndedChild.POST_ASSESSMENT or latest_task_state == OpenEndedChild.DONE: - print "Submission already graded." + print "WARNING: Submission already graded." elif latest_task_state == OpenEndedChild.ASSESSING: latest_answer = latest_task.latest_answer() - print "Sending submission to grader." latest_task.send_to_grader(latest_answer, latest_task.system) + print "Successfully sent to grader." else: - print "Invalid task_state: {0}".format(latest_task_state) + print "WARNING: Invalid task_state: {0}".format(latest_task_state) except Exception as err: print err - else: - print "Successfully sent to grader."