Commit 85235913 by Victor Shnayder

refactor + style self-assessment in progress

parent 1b550e6c
""" """
Add Self Assessment module so students can write essay, submit, then see a rubric and rate themselves. A Self Assessment module that allows students to write open-ended responses,
Persists student supplied hints, answers, and correctness judgment (currently only correct/incorrect). submit, then see a rubric and rate themselves. Persists student supplied
hints, answers, and correctness judgment (currently only correct/incorrect).
Parses xml definition file--see below for exact format. Parses xml definition file--see below for exact format.
""" """
...@@ -37,6 +38,26 @@ MAX_ATTEMPTS = 1 ...@@ -37,6 +38,26 @@ MAX_ATTEMPTS = 1
MAX_SCORE = 1 MAX_SCORE = 1
class SelfAssessmentModule(XModule): class SelfAssessmentModule(XModule):
"""
States:
initial (prompt, textbox shown)
|
assessing (read-only textbox, rubric + assessment input shown)
|
request_hint (read-only textbox, read-only rubric and assessment, hint input box shown)
|
done (submitted msg, green checkmark, everything else read-only. If attempts < max, shows
a reset button that goes back to initial state. Saves previous
submissions too.)
"""
# states
INITIAL = 'initial'
ASSESSING = 'assessing'
REQUEST_HINT = 'request_hint'
DONE = 'done'
js = {'coffee': [resource_string(__name__, 'js/src/selfassessment/display.coffee')]} js = {'coffee': [resource_string(__name__, 'js/src/selfassessment/display.coffee')]}
js_module_name = "SelfAssessment" js_module_name = "SelfAssessment"
...@@ -93,16 +114,13 @@ class SelfAssessmentModule(XModule): ...@@ -93,16 +114,13 @@ class SelfAssessmentModule(XModule):
# self-assessment and hint yet: this means that the answers, # self-assessment and hint yet: this means that the answers,
# correctness, hints always stay in sync, and have the same number of # correctness, hints always stay in sync, and have the same number of
# elements. # elements.
self.temp_answer = instance_state.get('temp_answer', '') self.state = instance_state.get('state', 'initial')
# Used for progress / grading. Currently get credit just for # Used for progress / grading. Currently get credit just for
# completion (doesn't matter if you self-assessed correct/incorrect). # completion (doesn't matter if you self-assessed correct/incorrect).
self.score = instance_state.get('score', 0) self.score = instance_state.get('score', 0)
self.top_score = instance_state.get('top_score', MAX_SCORE) self.top_score = instance_state.get('top_score', MAX_SCORE)
# TODO: do we need this? True once everything is done
self.done = instance_state.get('done', False)
#Get number of attempts student has used from instance state #Get number of attempts student has used from instance state
self.attempts = instance_state.get('attempts', 0) self.attempts = instance_state.get('attempts', 0)
...@@ -124,6 +142,9 @@ class SelfAssessmentModule(XModule): ...@@ -124,6 +142,9 @@ class SelfAssessmentModule(XModule):
'prompt' : self.prompt, 'prompt' : self.prompt,
'previous_answer' : previous_answer, 'previous_answer' : previous_answer,
'ajax_url' : system.ajax_url, 'ajax_url' : system.ajax_url,
'initial_rubric' : self.get_rubric_html(),
'initial_hint' : self.get_hint_html(),
'initial_message' : self.get_message_html(),
} }
self.html = self.system.render_template('self_assessment_prompt.html', context) self.html = self.system.render_template('self_assessment_prompt.html', context)
...@@ -175,6 +196,55 @@ class SelfAssessmentModule(XModule): ...@@ -175,6 +196,55 @@ class SelfAssessmentModule(XModule):
}) })
return json.dumps(d, cls=ComplexEncoder) return json.dumps(d, cls=ComplexEncoder)
def get_rubric_html(self):
"""
Return the appropriate version of the rubric, based on the state.
"""
if self.state == self.INITIAL:
return ''
# we'll render it
context = {'rubric' : self.rubric}
if self.state == self.ASSESSING:
context['read_only'] = False
elif self.state in (self.REQUEST_HINT, self.DONE):
context['read_only'] = True
else:
raise ValueError("Illegal state '%r'" % self.state)
return self.system.render_template('self_assessment_rubric.html', context)
def get_hint_html(self):
"""
Return the appropriate version of the hint view, based on state.
"""
if self.state in (self.INITIAL, self.ASSESSING):
return ''
# else we'll render it
context = {'hint_prompt': self.hint_prompt,
'hint': self.hint}
if self.state == self.REQUEST_HINT:
context['read_only'] = False
elif self.state == self.DONE:
context['read_only'] = True
else:
raise ValueError("Illegal state '%r'" % self.state)
return self.system.render_template('self_assessment_hint.html', context)
def get_message_html(self):
"""
Return the appropriate version of the message view, based on state.
"""
if self.state != self.DONE:
return ""
return """<div class="save_message">{0}</div>""".format(self.message)
def show_rubric(self, get): def show_rubric(self, get):
""" """
After the answer is submitted, show the rubric. After the answer is submitted, show the rubric.
...@@ -184,13 +254,9 @@ class SelfAssessmentModule(XModule): ...@@ -184,13 +254,9 @@ class SelfAssessmentModule(XModule):
# Dump to temp_answer to keep answer in sync with correctness and hint # Dump to temp_answer to keep answer in sync with correctness and hint
self.temp_answer = get['student_answer'] self.temp_answer = get['student_answer']
# Return success and return rubric html to ajax call
rubric_context = {'rubric' : self.rubric,
'hint_prompt' : self.hint_prompt,}
return { return {
'success': True, 'success': True,
'rubric': self.system.render_template('self_assessment_rubric.html', rubric_context) 'rubric': self.get_rubric_html()
} }
else: else:
# If too many attempts, prevent student from saving answer and seeing rubric. # If too many attempts, prevent student from saving answer and seeing rubric.
...@@ -213,8 +279,7 @@ class SelfAssessmentModule(XModule): ...@@ -213,8 +279,7 @@ class SelfAssessmentModule(XModule):
self.correctness.append(get['assessment'].lower()) self.correctness.append(get['assessment'].lower())
self.student_answers.append(self.temp_answer) self.student_answers.append(self.temp_answer)
#Student is done, and increment attempts # increment attempts
self.done = True
self.attempts = self.attempts + 1 self.attempts = self.attempts + 1
#Create and store event info dict #Create and store event info dict
...@@ -239,7 +304,7 @@ class SelfAssessmentModule(XModule): ...@@ -239,7 +304,7 @@ class SelfAssessmentModule(XModule):
def get_instance_state(self): def get_instance_state(self):
""" """
Get the current correctness, points, and done status Get the current correctness, points, and state
""" """
#Assign points based on completion. May want to change to correctness-based down the road. #Assign points based on completion. May want to change to correctness-based down the road.
points = 1 points = 1
...@@ -251,7 +316,6 @@ class SelfAssessmentModule(XModule): ...@@ -251,7 +316,6 @@ class SelfAssessmentModule(XModule):
'correctness': self.correctness, 'correctness': self.correctness,
'score': points, 'score': points,
'top_score' : MAX_SCORE, 'top_score' : MAX_SCORE,
'done': self.done,
'attempts' : self.attempts 'attempts' : self.attempts
} }
return json.dumps(state) return json.dumps(state)
......
...@@ -242,4 +242,9 @@ div.course-wrapper { ...@@ -242,4 +242,9 @@ div.course-wrapper {
} }
.self-assessment {
textarea {
height: 200px;
}
}
<div class="hint">
<div class="hint-prompt">
${hint_prompt}
</div>
<textarea name="hint" class="hint" cols="50" rows="5"
${'readonly="true"' if read_only else ''}>${hint}</textarea>
</div>
...@@ -8,7 +8,11 @@ ...@@ -8,7 +8,11 @@
<textarea name="answer" class="answer" cols="80" rows="20">${previous_answer|h}</textarea> <textarea name="answer" class="answer" cols="80" rows="20">${previous_answer|h}</textarea>
</div> </div>
<div class="rubric-wrapper"></div> <div class="rubric-wrapper">${initial_rubric}</div>
<div class="hint-wrapper">${initial_hint}</div>
<div class="message-wrapper">${initial_message}</div>
<input type="button" value="Submit" class="submit-button" name="show"/> <input type="button" value="Submit" class="submit-button" name="show"/>
</section> </section>
...@@ -4,15 +4,11 @@ ...@@ -4,15 +4,11 @@
${rubric} ${rubric}
</div> </div>
% if not read_only:
<select name="assessment" class="assessment"> <select name="assessment" class="assessment">
<option value="incorrect">Incorrect</option> <option value="incorrect">Incorrect</option>
<option value="correct">Correct</option> <option value="correct">Correct</option>
</select> </select>
% endif
<div class="hint-prompt">
${hint_prompt}
</div>
<textarea name="hint" class="hint" cols="50" rows="5"/>
<div class="save_message"></div>
</div> </div>
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