StudentModuleCache now allows a list of descriptors. This speeds up grading significantly.
This commit is contained in:
@@ -501,11 +501,11 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
|
||||
all(getattr(self, attr, None) == getattr(other, attr, None)
|
||||
for attr in self.equality_attributes))
|
||||
|
||||
if not eq:
|
||||
for attr in self.equality_attributes:
|
||||
print(getattr(self, attr, None),
|
||||
getattr(other, attr, None),
|
||||
getattr(self, attr, None) == getattr(other, attr, None))
|
||||
# if not eq:
|
||||
# for attr in self.equality_attributes:
|
||||
# print(getattr(self, attr, None),
|
||||
# getattr(other, attr, None),
|
||||
# getattr(self, attr, None) == getattr(other, attr, None))
|
||||
|
||||
return eq
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ def get_graded_sections(course_descriptor):
|
||||
"section_descriptor" : The section descriptor
|
||||
"xmoduledescriptors" : An array of xmoduledescriptors that could possibly be in the section, for any student
|
||||
"""
|
||||
all_descriptors = []
|
||||
|
||||
graded_sections = {}
|
||||
for c in course_descriptor.get_children():
|
||||
@@ -35,8 +36,11 @@ def get_graded_sections(course_descriptor):
|
||||
|
||||
section_format = s.metadata.get('format', "")
|
||||
graded_sections[ section_format ] = graded_sections.get( section_format, [] ) + [section_description]
|
||||
|
||||
all_descriptors.extend(xmoduledescriptors)
|
||||
all_descriptors.append(s)
|
||||
|
||||
return graded_sections
|
||||
return graded_sections, all_descriptors
|
||||
|
||||
def yield_descriptor_descendents(module_descriptor):
|
||||
for child in module_descriptor.get_children():
|
||||
|
||||
@@ -67,17 +67,30 @@ class StudentModuleCache(object):
|
||||
"""
|
||||
A cache of StudentModules for a specific student
|
||||
"""
|
||||
def __init__(self, user, descriptor, depth=None):
|
||||
def __init__(self, user, descriptor=None, depth=None, descriptors=None, descriptor_filter=lambda descriptor: True):
|
||||
'''
|
||||
Find any StudentModule objects that are needed by any child modules of the
|
||||
supplied descriptor. Avoids making multiple queries to the database
|
||||
|
||||
descriptor: An XModuleDescriptor
|
||||
depth is the number of levels of descendent modules to load StudentModules for, in addition to
|
||||
the supplied descriptor. If depth is None, load all descendent StudentModules
|
||||
supplied descriptor, or caches only the StudentModule objects specifically
|
||||
for every descriptor in descriptors. Avoids making multiple queries to the
|
||||
database.
|
||||
|
||||
There are two ways to init:
|
||||
descriptor: An XModuleDescriptor
|
||||
depth is the number of levels of descendent modules to load StudentModules for, in addition to
|
||||
the supplied descriptor. If depth is None, load all descendent StudentModules
|
||||
OR
|
||||
descriptors: An array of XModuleDescriptors.
|
||||
|
||||
descriptor_filter is a function that accepts a descriptor and return wether the StudentModule
|
||||
should be cached
|
||||
'''
|
||||
if user.is_authenticated():
|
||||
module_ids = self._get_module_state_keys(descriptor, depth)
|
||||
if not (descriptor == None) != (descriptors == None): #An xor on the descriptor and descriptors parameters.
|
||||
raise ValueError("Either the descriptor or descriptors must be supplied to StudentModuleCache.")
|
||||
|
||||
if descriptor != None:
|
||||
descriptors = self._get_child_descriptors(descriptor, depth)
|
||||
module_ids = self._get_module_state_keys(descriptors, descriptor_filter)
|
||||
|
||||
# This works around a limitation in sqlite3 on the number of parameters
|
||||
# that can be put into a single query
|
||||
@@ -91,27 +104,39 @@ class StudentModuleCache(object):
|
||||
|
||||
else:
|
||||
self.cache = []
|
||||
|
||||
def _get_module_state_keys(self, descriptor, depth):
|
||||
'''
|
||||
Get a list of the state_keys needed for StudentModules
|
||||
required for this module descriptor
|
||||
|
||||
|
||||
def _get_child_descriptors(self, descriptor, depth):
|
||||
"""
|
||||
descriptor: An XModuleDescriptor
|
||||
depth is the number of levels of descendent modules to load StudentModules for, in addition to
|
||||
the supplied descriptor. If depth is None, load all descendent StudentModules
|
||||
'''
|
||||
keys = [descriptor.location.url()]
|
||||
|
||||
shared_state_key = getattr(descriptor, 'shared_state_key', None)
|
||||
if shared_state_key is not None:
|
||||
keys.append(shared_state_key)
|
||||
|
||||
"""
|
||||
descriptors = [descriptor]
|
||||
|
||||
if depth is None or depth > 0:
|
||||
new_depth = depth - 1 if depth is not None else depth
|
||||
|
||||
for child in descriptor.get_children():
|
||||
keys.extend(self._get_module_state_keys(child, new_depth))
|
||||
descriptors.extend(self._get_child_descriptors(child, new_depth))
|
||||
|
||||
return descriptors
|
||||
|
||||
def _get_module_state_keys(self, descriptors, descriptor_filter):
|
||||
'''
|
||||
Get a list of the state_keys needed for StudentModules
|
||||
required for this module descriptor
|
||||
|
||||
descriptor_filter is a function that accepts a descriptor and return wether the StudentModule
|
||||
should be cached
|
||||
'''
|
||||
keys = []
|
||||
for descriptor in descriptors:
|
||||
if descriptor_filter(descriptor):
|
||||
keys.append(descriptor.location.url())
|
||||
|
||||
shared_state_key = getattr(descriptor, 'shared_state_key', None)
|
||||
if shared_state_key is not None:
|
||||
keys.append(shared_state_key)
|
||||
|
||||
return keys
|
||||
|
||||
|
||||
@@ -38,9 +38,8 @@ template_imports = {'urllib': urllib}
|
||||
def test_grading(request, course_id):
|
||||
course = check_course(course_id)
|
||||
|
||||
sections = grades.get_graded_sections(course)
|
||||
|
||||
student_module_cache = StudentModuleCache(request.user, course)
|
||||
sections, all_descriptors = grades.get_graded_sections(course)
|
||||
student_module_cache = StudentModuleCache(request.user, descriptors=all_descriptors)
|
||||
|
||||
grade_result = grades.fast_grade(request.user, request, sections, course.grader, student_module_cache)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user