Commit eee555fb by Justin Riley

randomize_module: pep8 cleanup

parent cb06091c
...@@ -14,12 +14,14 @@ log = logging.getLogger('edx.' + __name__) ...@@ -14,12 +14,14 @@ log = logging.getLogger('edx.' + __name__)
class RandomizeFields(object): class RandomizeFields(object):
choice = Integer(help="Which random child was chosen", scope=Scope.user_state) choice = Integer(help="Which random child was chosen",
scope=Scope.user_state)
class RandomizeModule(RandomizeFields, XModule): class RandomizeModule(RandomizeFields, XModule):
""" """
Chooses a random child module. Chooses the same one every time for each student. Chooses a random child module. Chooses the same one every time for each
student.
Example: Example:
<randomize> <randomize>
...@@ -29,34 +31,41 @@ class RandomizeModule(RandomizeFields, XModule): ...@@ -29,34 +31,41 @@ class RandomizeModule(RandomizeFields, XModule):
</randomize> </randomize>
User notes: User notes:
- If you're randomizing amongst graded modules, each of them MUST be
- If you're randomizing amongst graded modules, each of them MUST be worth the same worth the same number of points. Otherwise, the earth will be overrun
number of points. Otherwise, the earth will be overrun by monsters from the by monsters from the deeps. You have been warned.
deeps. You have been warned.
Technical notes: Technical notes:
- There is more dark magic in this code than I'd like. The whole varying-children + - There is more dark magic in this code than I'd like. The whole
grading interaction is a tangle between super and subclasses of descriptors and varying-children + grading interaction is a tangle between super and
modules. subclasses of descriptors and modules.
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(RandomizeModule, self).__init__(*args, **kwargs) super(RandomizeModule, self).__init__(*args, **kwargs)
# NOTE: calling self.get_children() creates a circular reference --
# NOTE: calling self.get_children() creates a circular reference-- # it calls get_child_descriptors() internally, but that doesn't work
# it calls get_child_descriptors() internally, but that doesn't work until # until we've picked a choice
# we've picked a choice # import pudb; pudb.set_trace()
num_choices = len(self.descriptor.get_children()) children = self.descriptor.get_children()
xml_attrs = self.descriptor.xml_attributes or []
use_randrange = 'use_randrange' in xml_attrs
# TODO: use this attr to toggle storing history and never showing the
# same problem twice
# no_repeats = xml_attrs.has_key('no_repeats')
num_choices = len(children)
if self.choice > num_choices: if self.choice > num_choices:
# Oops. Children changed. Reset. # Oops. Children changed. Reset.
self.choice = None self.choice = None
if self.choice is None: if self.choice is None:
# choose one based on the system seed, or randomly if that's not available # choose one based on the system seed, or randomly if that's not
# available
if num_choices > 0: if num_choices > 0:
if self.system.seed is not None and 'use_randrange' not in (self.descriptor.xml_attributes or []): if self.system.seed is not None and not use_randrange:
self.choice = self.system.seed % num_choices self.choice = self.system.seed % num_choices
log.debug('using seed for %s choice=%s' % (str(self.location), self.choice)) log.debug('using seed for %s choice=%s' %
(str(self.location), self.choice))
else: else:
self.choice = random.randrange(0, num_choices) self.choice = random.randrange(0, num_choices)
log.debug('using randrange for %s' % str(self.location)) log.debug('using randrange for %s' % str(self.location))
...@@ -66,8 +75,9 @@ class RandomizeModule(RandomizeFields, XModule): ...@@ -66,8 +75,9 @@ class RandomizeModule(RandomizeFields, XModule):
if self.choice is not None: if self.choice is not None:
self.child_descriptor = self.descriptor.get_children()[self.choice] self.child_descriptor = self.descriptor.get_children()[self.choice]
# Now get_children() should return a list with one element # Now get_children() should return a list with one element
log.debug("choice=%s in %s, children of randomize module (should be only 1): %s", log.debug("choice=%s in %s, children of randomize module "
self.choice, str(self.location), self.get_children()) "(should be only 1): %s", self.choice,
str(self.location), self.get_children())
self.child = self.get_children()[0] self.child = self.get_children()[0]
else: else:
self.child_descriptor = None self.child_descriptor = None
...@@ -79,32 +89,32 @@ class RandomizeModule(RandomizeFields, XModule): ...@@ -79,32 +89,32 @@ class RandomizeModule(RandomizeFields, XModule):
""" """
if self.child_descriptor is None: if self.child_descriptor is None:
return [] return []
return [self.child_descriptor] return [self.child_descriptor]
def student_view(self, context): def student_view(self, context):
if self.child is None: if self.child is None:
# raise error instead? In fact, could complain on descriptor load... # raise error instead? In fact, could complain on descriptor load
return Fragment(content=u"<div>Nothing to randomize between</div>") return Fragment(content=u"<div>Nothing to randomize between</div>")
child_html = self.child.render('student_view', context)
if self.system.user_is_staff: if self.system.user_is_staff:
dishtml = self.system.render_template('randomize_control.html', { dishtml = self.system.render_template('randomize_control.html', {
'element_id': self.location.html_id(), 'element_id': self.location.html_id(),
'is_staff': self.system.user_is_staff, 'is_staff': self.system.user_is_staff,
'ajax_url': self.system.ajax_url, 'ajax_url': self.system.ajax_url,
'choice': self.choice, 'choice': self.choice,
'num_choices': len(self.descriptor.get_children()), 'num_choices': len(self.descriptor.get_children()),
}) })
# html = '<html><p>Welcome, staff. Randomize loc=%s ; Choice=%s</p><br/><hr/></br/>' % (str(self.location), self.choice) # html = '<html><p>Welcome, staff. Randomize loc=%s ;
child_html = self.child.render('student_view', context) # Choice=%s</p><br/><hr/></br/>' % (str(self.location),
return Fragment(u"<html>" + dishtml + child_html.content + u"</html>") # self.choice)
return self.child.render('student_view', context) return Fragment(u"<html>" + dishtml + child_html.content +
u"</html>")
return child_html
def handle_ajax(self, dispatch, data): def handle_ajax(self, dispatch, data):
if dispatch=='next': if dispatch == 'next':
self.choice = self.choice + 1 self.choice = self.choice + 1
elif dispatch=='jump': elif dispatch == 'jump':
log.debug('jump, data=%s' % data) log.debug('jump, data=%s' % data)
self.choice = int(data['choice']) self.choice = int(data['choice'])
num_choices = len(self.descriptor.get_children()) num_choices = len(self.descriptor.get_children())
...@@ -119,14 +129,12 @@ class RandomizeModule(RandomizeFields, XModule): ...@@ -119,14 +129,12 @@ class RandomizeModule(RandomizeFields, XModule):
class RandomizeDescriptor(RandomizeFields, SequenceDescriptor): class RandomizeDescriptor(RandomizeFields, SequenceDescriptor):
# the editing interface can be the same as for sequences -- just a container # the editing interface can be the same as for sequences -- just a
# container
module_class = RandomizeModule module_class = RandomizeModule
filename_extension = "xml" filename_extension = "xml"
def definition_to_xml(self, resource_fs): def definition_to_xml(self, resource_fs):
xml_object = etree.Element('randomize') xml_object = etree.Element('randomize')
for child in self.get_children(): for child in self.get_children():
self.runtime.add_block_as_child_node(child, xml_object) self.runtime.add_block_as_child_node(child, xml_object)
...@@ -134,7 +142,7 @@ class RandomizeDescriptor(RandomizeFields, SequenceDescriptor): ...@@ -134,7 +142,7 @@ class RandomizeDescriptor(RandomizeFields, SequenceDescriptor):
def has_dynamic_children(self): def has_dynamic_children(self):
""" """
Grading needs to know that only one of the children is actually "real". This Grading needs to know that only one of the children is actually "real".
makes it use module.get_child_descriptors(). This makes it use module.get_child_descriptors().
""" """
return True return True
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment