diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py
index 4b9996b2bb..6e9dda13f8 100644
--- a/common/lib/capa/capa/responsetypes.py
+++ b/common/lib/capa/capa/responsetypes.py
@@ -655,6 +655,7 @@ class ChoiceResponse(LoncapaResponse):
response_tag = 'choiceresponse'
max_inputfields = 1
allowed_inputfields = ['checkboxgroup', 'radiogroup']
+ correct_choices = None
def setup_response(self):
@@ -706,6 +707,7 @@ class MultipleChoiceResponse(LoncapaResponse):
response_tag = 'multiplechoiceresponse'
max_inputfields = 1
allowed_inputfields = ['choicegroup']
+ correct_choices = None
def setup_response(self):
# call secondary setup for MultipleChoice questions, to set name
@@ -791,6 +793,7 @@ class OptionResponse(LoncapaResponse):
response_tag = 'optionresponse'
hint_tag = 'optionhint'
allowed_inputfields = ['optioninput']
+ answer_fields = None
def setup_response(self):
self.answer_fields = self.inputfields
@@ -949,6 +952,7 @@ class StringResponse(LoncapaResponse):
allowed_inputfields = ['textline']
required_attributes = ['answer']
max_inputfields = 1
+ correct_answer = None
def setup_response(self):
self.correct_answer = contextualize_text(
@@ -974,7 +978,7 @@ class StringResponse(LoncapaResponse):
hxml.get('answer'), self.context).strip()
if self.check_string(correct_answer, given):
hints_to_show.append(name)
- log.debug('hints_to_show = %s' % hints_to_show)
+ log.debug('hints_to_show = %s', hints_to_show)
return hints_to_show
def get_answers(self):
@@ -996,6 +1000,8 @@ class CustomResponse(LoncapaResponse):
'drag_and_drop_input', 'editamoleculeinput',
'designprotein2dinput', 'editageneinput',
'annotationinput', 'jsinput', 'formulaequationinput']
+ code = None
+ expect = None
def setup_response(self):
xml = self.xml
@@ -1004,7 +1010,7 @@ class CustomResponse(LoncapaResponse):
# that
self.expect = xml.get('expect') or xml.get('answer')
- log.debug('answer_ids=%s' % self.answer_ids)
+ log.debug('answer_ids=%s', self.answer_ids)
# the ... stanza should be local to the current .
# So try looking there first.
@@ -1020,7 +1026,7 @@ class CustomResponse(LoncapaResponse):
# stanza instead
cfn = xml.get('cfn')
if cfn:
- log.debug("cfn = %s" % cfn)
+ log.debug("cfn = %s", cfn)
# This is a bit twisty. We used to grab the cfn function from
# the context, but now that we sandbox Python execution, we
@@ -1055,7 +1061,7 @@ class CustomResponse(LoncapaResponse):
if not self.code:
if answer is None:
log.error("[courseware.capa.responsetypes.customresponse] missing"
- " code checking script! id=%s" % self.id)
+ " code checking script! id=%s", self.id)
self.code = ''
else:
answer_src = answer.get('src')
@@ -1071,7 +1077,7 @@ class CustomResponse(LoncapaResponse):
of each key removed (the string before the first "_").
'''
- log.debug('%s: student_answers=%s' % (unicode(self), student_answers))
+ log.debug('%s: student_answers=%s', unicode(self), student_answers)
# ordered list of answer id's
idset = sorted(self.answer_ids)
@@ -1182,10 +1188,10 @@ class CustomResponse(LoncapaResponse):
answer_given = submission[0] if (len(idset) == 1) else submission
kwnames = self.xml.get("cfn_extra_args", "").split()
kwargs = {n: self.context.get(n) for n in kwnames}
- log.debug(" submission = %s" % submission)
+ log.debug(" submission = %s", submission)
try:
ret = fn(self.expect, answer_given, **kwargs)
- except Exception as err:
+ except Exception as err: # pylint: disable=broad-except
self._handle_exec_exception(err)
log.debug(
"[courseware.capa.responsetypes.customresponse.get_score] ret = %s",
@@ -1340,22 +1346,21 @@ class SymbolicResponse(CustomResponse):
debug=self.context.get('debug'),
)
except Exception as err:
- log.error("oops in symbolicresponse (cfn) error %s" % err)
+ log.error("oops in symbolicresponse (cfn) error %s", err)
log.error(traceback.format_exc())
- raise Exception("oops in symbolicresponse (cfn) error %s" % err)
+ raise Exception("oops in symbolicresponse (cfn) error %s", err)
self.context['messages'][0] = self.clean_message_html(ret['msg'])
self.context['correct'] = ['correct' if ret['ok'] else 'incorrect'] * len(idset)
#-----------------------------------------------------------------------------
-"""
-valid: Flag indicating valid score_msg format (Boolean)
-correct: Correctness of submission (Boolean)
-score: Points to be assigned (numeric, can be float)
-msg: Message from grader to display to student (string)
-"""
-ScoreMessage = namedtuple('ScoreMessage',
- ['valid', 'correct', 'points', 'msg'])
+## ScoreMessage named tuple ##
+## valid: Flag indicating valid score_msg format (Boolean)
+## correct: Correctness of submission (Boolean)
+## score: Points to be assigned (numeric, can be float)
+## msg: Message from grader to display to student (string)
+
+ScoreMessage = namedtuple('ScoreMessage', ['valid', 'correct', 'points', 'msg']) # pylint: disable=invalid-name
class CodeResponse(LoncapaResponse):
@@ -1377,6 +1382,11 @@ class CodeResponse(LoncapaResponse):
response_tag = 'coderesponse'
allowed_inputfields = ['textbox', 'filesubmission', 'matlabinput']
max_inputfields = 1
+ payload = None
+ initial_display = None
+ url = None
+ answer = None
+ queue_name = None
def setup_response(self):
'''
@@ -1427,8 +1437,8 @@ class CodeResponse(LoncapaResponse):
except Exception as err:
log.error(
'Error in CodeResponse %s: cannot get student answer for %s;'
- ' student_answers=%s' %
- (err, self.answer_id, convert_files_to_filenames(student_answers))
+ ' student_answers=%s',
+ err, self.answer_id, convert_files_to_filenames(student_answers)
)
raise Exception(err)
@@ -1511,9 +1521,8 @@ class CodeResponse(LoncapaResponse):
return cmap
def update_score(self, score_msg, oldcmap, queuekey):
-
- (valid_score_msg, correct, points,
- msg) = self._parse_score_msg(score_msg)
+ """Updates the user's score based on the returned message from the grader."""
+ (valid_score_msg, correct, points, msg) = self._parse_score_msg(score_msg)
if not valid_score_msg:
oldcmap.set(self.answer_id,
msg='Invalid grader reply. Please contact the course staff.')
@@ -1536,8 +1545,11 @@ class CodeResponse(LoncapaResponse):
self.answer_id, npoints=points, correctness=correctness,
msg=msg.replace(' ', ' '), queuestate=None)
else:
- log.debug('CodeResponse: queuekey %s does not match for answer_id=%s.' %
- (queuekey, self.answer_id))
+ log.debug(
+ 'CodeResponse: queuekey %s does not match for answer_id=%s.',
+ queuekey,
+ self.answer_id
+ )
return oldcmap
@@ -1546,6 +1558,10 @@ class CodeResponse(LoncapaResponse):
return {self.answer_id: anshtml}
def get_initial_display(self):
+ """
+ The course author can specify an initial display
+ to be displayed the code response box.
+ """
return {self.answer_id: self.initial_display}
def _parse_score_msg(self, score_msg):
@@ -1566,11 +1582,11 @@ class CodeResponse(LoncapaResponse):
score_result = json.loads(score_msg)
except (TypeError, ValueError):
log.error("External grader message should be a JSON-serialized dict."
- " Received score_msg = %s" % score_msg)
+ " Received score_msg = %s", score_msg)
return fail
if not isinstance(score_result, dict):
log.error("External grader message should be a JSON-serialized dict."
- " Received score_result = %s" % score_result)
+ " Received score_result = %s", score_result)
return fail
for tag in ['correct', 'score', 'msg']:
if tag not in score_result:
@@ -1585,9 +1601,9 @@ class CodeResponse(LoncapaResponse):
msg = score_result['msg']
try:
etree.fromstring(msg)
- except etree.XMLSyntaxError as err:
+ except etree.XMLSyntaxError as _err:
log.error("Unable to parse external grader message as valid"
- " XML: score_msg['msg']=%s" % msg)
+ " XML: score_msg['msg']=%s", msg)
return fail
return (True, score_result['correct'], score_result['score'], msg)
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index d5109aae32..6d664acbf6 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -1,3 +1,4 @@
+"""Implements basics of Capa, including class CapaModule."""
import cgi
import datetime
import hashlib
@@ -40,11 +41,11 @@ def randomization_bin(seed, problem_id):
interesting. To avoid having sets of students that always get the same problems,
we'll combine the system's per-student seed with the problem id in picking the bin.
"""
- h = hashlib.sha1()
- h.update(str(seed))
- h.update(str(problem_id))
+ r_hash = hashlib.sha1()
+ r_hash.update(str(seed))
+ r_hash.update(str(problem_id))
# get the first few digits of the hash, convert to an int, then mod.
- return int(h.hexdigest()[:7], 16) % NUM_RANDOMIZATION_BINS
+ return int(r_hash.hexdigest()[:7], 16) % NUM_RANDOMIZATION_BINS
class Randomization(String):
@@ -220,7 +221,7 @@ class CapaModule(CapaFields, XModule):
if self.seed is None:
self.seed = self.lcp.seed
- except Exception as err:
+ except Exception as err: # pylint: disable=broad-except
msg = u'cannot create LoncapaProblem {loc}: {err}'.format(
loc=self.location.url(), err=err)
# TODO (vshnayder): do modules need error handlers too?
@@ -318,9 +319,9 @@ class CapaModule(CapaFields, XModule):
"""
For now, just return score / max_score
"""
- d = self.get_score()
- score = d['score']
- total = d['total']
+ score_dict = self.get_score()
+ score = score_dict['score']
+ total = score_dict['total']
if total > 0:
if self.weight is not None:
@@ -525,7 +526,7 @@ class CapaModule(CapaFields, XModule):
# If we cannot construct the problem HTML,
# then generate an error message instead.
- except Exception as err:
+ except Exception as err: # pylint: disable=broad-except
html = self.handle_problem_html_error(err)
# The convention is to pass the name of the check button
@@ -610,11 +611,11 @@ class CapaModule(CapaFields, XModule):
result = handlers[dispatch](data)
except NotFoundError as err:
- _, _, traceback_obj = sys.exc_info()
+ _, _, traceback_obj = sys.exc_info() # pylint: disable=redefined-outer-name
raise ProcessingError, (not_found_error_message, err), traceback_obj
except Exception as err:
- _, _, traceback_obj = sys.exc_info()
+ _, _, traceback_obj = sys.exc_info() # pylint: disable=redefined-outer-name
raise ProcessingError, (generic_error_message, err), traceback_obj
after = self.get_progress()
@@ -668,8 +669,8 @@ class CapaModule(CapaFields, XModule):
"""
True iff full points
"""
- d = self.get_score()
- return d['score'] == d['total']
+ score_dict = self.get_score()
+ return score_dict['score'] == score_dict['total']
def answer_available(self):
"""
@@ -757,7 +758,7 @@ class CapaModule(CapaFields, XModule):
self.set_state_from_lcp()
return response
- def get_answer(self, data):
+ def get_answer(self, _data):
"""
For the "show answer" button.
@@ -797,7 +798,6 @@ class CapaModule(CapaFields, XModule):
"""
return {'html': self.get_problem_html(encapsulate=False)}
-
@staticmethod
def make_dict_of_responses(data):
"""
@@ -840,7 +840,7 @@ class CapaModule(CapaFields, XModule):
# We only want to consider each key a single time, so we use set(data.keys())
for key in set(data.keys()):
# e.g. input_resistor_1 ==> resistor_1
- _, _, name = key.partition('_')
+ _, _, name = key.partition('_') # pylint: disable=redefined-outer-name
# If key has no underscores, then partition
# will return (key, '', '')