Merge pull request #650 from MITx/feature/bridger/course_grading

Feature/bridger/course grading
This commit is contained in:
David Ormsbee
2012-09-21 08:10:03 -07:00
15 changed files with 450 additions and 80 deletions

View File

@@ -47,11 +47,14 @@ class ABTestModule(XModule):
def get_shared_state(self):
return json.dumps({'group': self.group})
def get_children_locations(self):
return self.definition['data']['group_content'][self.group]
def displayable_items(self):
child_locations = self.definition['data']['group_content'][self.group]
children = [self.system.get_module(loc) for loc in child_locations]
return [c for c in children if c is not None]
# Most modules return "self" as the displayable_item. We never display ourself
# (which is why we don't implement get_html). We only display our children.
return self.get_children()
# TODO (cpennington): Use Groups should be a first class object, rather than being
@@ -158,3 +161,7 @@ class ABTestDescriptor(RawDescriptor, XmlDescriptor):
group_elem.append(etree.fromstring(child.export_to_xml(resource_fs)))
return xml_object
def has_dynamic_children(self):
return True

View File

@@ -125,12 +125,6 @@ class CapaModule(XModule):
self.name = only_one(dom2.xpath('/problem/@name'))
weight_string = only_one(dom2.xpath('/problem/@weight'))
if weight_string:
self.weight = float(weight_string)
else:
self.weight = None
if self.rerandomize == 'never':
self.seed = 1
elif self.rerandomize == "per_student" and hasattr(self.system, 'id'):
@@ -279,7 +273,7 @@ class CapaModule(XModule):
content = {'name': self.display_name,
'html': html,
'weight': self.weight,
'weight': self.descriptor.weight,
}
# We using strings as truthy values, because the terminology of the
@@ -659,3 +653,12 @@ class CapaDescriptor(RawDescriptor):
'problems/' + path[8:],
path[8:],
]
def __init__(self, *args, **kwargs):
super(CapaDescriptor, self).__init__(*args, **kwargs)
weight_string = self.metadata.get('weight', None)
if weight_string:
self.weight = float(weight_string)
else:
self.weight = None

View File

@@ -189,6 +189,7 @@ class CourseDescriptor(SequenceDescriptor):
for s in c.get_children():
if s.metadata.get('graded', False):
xmoduledescriptors = list(yield_descriptor_descendents(s))
xmoduledescriptors.append(s)
# The xmoduledescriptors included here are only the ones that have scores.
section_description = { 'section_descriptor' : s, 'xmoduledescriptors' : filter(lambda child: child.has_score, xmoduledescriptors) }

View File

@@ -219,13 +219,28 @@ class XModule(HTMLSnippet):
Return module instances for all the children of this module.
'''
if self._loaded_children is None:
child_locations = self.definition.get('children', [])
child_locations = self.get_children_locations()
children = [self.system.get_module(loc) for loc in child_locations]
# get_module returns None if the current user doesn't have access
# to the location.
self._loaded_children = [c for c in children if c is not None]
return self._loaded_children
def get_children_locations(self):
'''
Returns the locations of each of child modules.
Overriding this changes the behavior of get_children and
anything that uses get_children, such as get_display_items.
This method will not instantiate the modules of the children
unless absolutely necessary, so it is cheaper to call than get_children
These children will be the same children returned by the
descriptor unless descriptor.has_dynamic_children() is true.
'''
return self.definition.get('children', [])
def get_display_items(self):
'''
@@ -489,6 +504,18 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
self,
metadata=self.metadata
)
def has_dynamic_children(self):
"""
Returns True if this descriptor has dynamic children for a given
student when the module is created.
Returns False if the children of this descriptor are the same
children that the module will return for any student.
"""
return False
# ================================= JSON PARSING ===========================
@staticmethod