Commit 8b3d9da4 by Sarina Canelake

Merge pull request #4209 from msegado/showanswer-correct-or-past-due

Add "Correct or Past Due" option for showanswer
parents 4bd3093e 42ae5720
......@@ -137,6 +137,7 @@ Han Su Kim <hkim823@gmail.com>
Raees Chachar <raees.chachar@arbisoft.com>
Muhammad Ammar <muhammad.ammar@arbisoft.com>
William Desloge <william.desloge@ionis-group.com>
Martin Segado <msegado@mit.edu>
Marco Re <mrc.re@tiscali.it>
Jonas Jelten <jelten@in.tum.de>
Christine Lytwynec <clytwynec@edx.org>
......
......@@ -523,7 +523,7 @@ from django.utils.translation import ugettext as _
<div class="wrapper-comp-settings metadata_edit" id="settings-tab" data-metadata="{&quot;showanswer&quot;: {&quot;default_value&quot;: &quot;finished&quot;, &quot;explicitly_set&quot;: false, &quot;display_name&quot;: &quot;Show Answer&quot;, &quot;help&quot;: &quot;Defines when to show the answer to the problem. A default value can be set in Advanced Settings.&quot;, &quot;type&quot;: &quot;Select&quot;, &quot;value&quot;: &quot;finished&quot;, &quot;field_name&quot;: &quot;showanswer&quot;, &quot;options&quot;: [{&quot;display_name&quot;: &quot;Always&quot;, &quot;value&quot;: &quot;always&quot;}, {&quot;display_name&quot;: &quot;Answered&quot;, &quot;value&quot;: &quot;answered&quot;}, {&quot;display_name&quot;: &quot;Attempted&quot;, &quot;value&quot;: &quot;attempted&quot;}, {&quot;display_name&quot;: &quot;Closed&quot;, &quot;value&quot;: &quot;closed&quot;}, {&quot;display_name&quot;: &quot;Finished&quot;, &quot;value&quot;: &quot;finished&quot;}, {&quot;display_name&quot;: &quot;Past Due&quot;, &quot;value&quot;: &quot;past_due&quot;}, {&quot;display_name&quot;: &quot;Never&quot;, &quot;value&quot;: &quot;never&quot;}]}, &quot;display_name&quot;: {&quot;default_value&quot;: &quot;Blank Advanced Problem&quot;, &quot;explicitly_set&quot;: true, &quot;display_name&quot;: &quot;Display Name&quot;, &quot;help&quot;: &quot;This name appears in the horizontal navigation at the top of the page.&quot;, &quot;type&quot;: &quot;Generic&quot;, &quot;value&quot;: &quot;Blank Common Problem&quot;, &quot;field_name&quot;: &quot;display_name&quot;, &quot;options&quot;: []}, &quot;weight&quot;: {&quot;default_value&quot;: null, &quot;explicitly_set&quot;: false, &quot;display_name&quot;: &quot;Problem Weight&quot;, &quot;help&quot;: &quot;Defines the number of points each problem is worth. If the value is not set, each response field in the problem is worth one point.&quot;, &quot;type&quot;: &quot;Float&quot;, &quot;value&quot;: null, &quot;field_name&quot;: &quot;weight&quot;, &quot;options&quot;: {&quot;step&quot;: 0.1, &quot;min&quot;: 0}}, &quot;rerandomize&quot;: {&quot;default_value&quot;: &quot;never&quot;, &quot;explicitly_set&quot;: false, &quot;display_name&quot;: &quot;Randomization&quot;, &quot;help&quot;: &quot;Defines how often inputs are randomized when a student loads the problem. This setting only applies to problems that can have randomly generated numeric values. A default value can be set in Advanced Settings.&quot;, &quot;type&quot;: &quot;Select&quot;, &quot;value&quot;: &quot;never&quot;, &quot;field_name&quot;: &quot;rerandomize&quot;, &quot;options&quot;: [{&quot;display_name&quot;: &quot;Always&quot;, &quot;value&quot;: &quot;always&quot;}, {&quot;display_name&quot;: &quot;On Reset&quot;, &quot;value&quot;: &quot;onreset&quot;}, {&quot;display_name&quot;: &quot;Never&quot;, &quot;value&quot;: &quot;never&quot;}, {&quot;display_name&quot;: &quot;Per Student&quot;, &quot;value&quot;: &quot;per_student&quot;}]}, &quot;max_attempts&quot;: {&quot;default_value&quot;: null, &quot;explicitly_set&quot;: false, &quot;display_name&quot;: &quot;Maximum Attempts&quot;, &quot;help&quot;: &quot;Defines the number of times a student can try to answer this problem. If the value is not set, infinite attempts are allowed.&quot;, &quot;type&quot;: &quot;Integer&quot;, &quot;value&quot;: null, &quot;field_name&quot;: &quot;max_attempts&quot;, &quot;options&quot;: {&quot;min&quot;: 0}}}"></div>
<div class="wrapper-comp-settings metadata_edit" id="settings-tab" data-metadata="{&quot;showanswer&quot;: {&quot;default_value&quot;: &quot;finished&quot;, &quot;explicitly_set&quot;: false, &quot;display_name&quot;: &quot;Show Answer&quot;, &quot;help&quot;: &quot;Defines when to show the answer to the problem. A default value can be set in Advanced Settings.&quot;, &quot;type&quot;: &quot;Select&quot;, &quot;value&quot;: &quot;finished&quot;, &quot;field_name&quot;: &quot;showanswer&quot;, &quot;options&quot;: [{&quot;display_name&quot;: &quot;Always&quot;, &quot;value&quot;: &quot;always&quot;}, {&quot;display_name&quot;: &quot;Answered&quot;, &quot;value&quot;: &quot;answered&quot;}, {&quot;display_name&quot;: &quot;Attempted&quot;, &quot;value&quot;: &quot;attempted&quot;}, {&quot;display_name&quot;: &quot;Closed&quot;, &quot;value&quot;: &quot;closed&quot;}, {&quot;display_name&quot;: &quot;Finished&quot;, &quot;value&quot;: &quot;finished&quot;}, {&quot;display_name&quot;: &quot;Correct or Past Due&quot;, &quot;value&quot;: &quot;correct_or_past_due&quot;}, {&quot;display_name&quot;: &quot;Past Due&quot;, &quot;value&quot;: &quot;past_due&quot;}, {&quot;display_name&quot;: &quot;Never&quot;, &quot;value&quot;: &quot;never&quot;}]}, &quot;display_name&quot;: {&quot;default_value&quot;: &quot;Blank Advanced Problem&quot;, &quot;explicitly_set&quot;: true, &quot;display_name&quot;: &quot;Display Name&quot;, &quot;help&quot;: &quot;This name appears in the horizontal navigation at the top of the page.&quot;, &quot;type&quot;: &quot;Generic&quot;, &quot;value&quot;: &quot;Blank Common Problem&quot;, &quot;field_name&quot;: &quot;display_name&quot;, &quot;options&quot;: []}, &quot;weight&quot;: {&quot;default_value&quot;: null, &quot;explicitly_set&quot;: false, &quot;display_name&quot;: &quot;Problem Weight&quot;, &quot;help&quot;: &quot;Defines the number of points each problem is worth. If the value is not set, each response field in the problem is worth one point.&quot;, &quot;type&quot;: &quot;Float&quot;, &quot;value&quot;: null, &quot;field_name&quot;: &quot;weight&quot;, &quot;options&quot;: {&quot;step&quot;: 0.1, &quot;min&quot;: 0}}, &quot;rerandomize&quot;: {&quot;default_value&quot;: &quot;never&quot;, &quot;explicitly_set&quot;: false, &quot;display_name&quot;: &quot;Randomization&quot;, &quot;help&quot;: &quot;Defines how often inputs are randomized when a student loads the problem. This setting only applies to problems that can have randomly generated numeric values. A default value can be set in Advanced Settings.&quot;, &quot;type&quot;: &quot;Select&quot;, &quot;value&quot;: &quot;never&quot;, &quot;field_name&quot;: &quot;rerandomize&quot;, &quot;options&quot;: [{&quot;display_name&quot;: &quot;Always&quot;, &quot;value&quot;: &quot;always&quot;}, {&quot;display_name&quot;: &quot;On Reset&quot;, &quot;value&quot;: &quot;onreset&quot;}, {&quot;display_name&quot;: &quot;Never&quot;, &quot;value&quot;: &quot;never&quot;}, {&quot;display_name&quot;: &quot;Per Student&quot;, &quot;value&quot;: &quot;per_student&quot;}]}, &quot;max_attempts&quot;: {&quot;default_value&quot;: null, &quot;explicitly_set&quot;: false, &quot;display_name&quot;: &quot;Maximum Attempts&quot;, &quot;help&quot;: &quot;Defines the number of times a student can try to answer this problem. If the value is not set, infinite attempts are allowed.&quot;, &quot;type&quot;: &quot;Integer&quot;, &quot;value&quot;: null, &quot;field_name&quot;: &quot;max_attempts&quot;, &quot;options&quot;: {&quot;min&quot;: 0}}}"></div>
</section>
......
......@@ -131,6 +131,7 @@ class CapaFields(object):
{"display_name": _("Attempted"), "value": "attempted"},
{"display_name": _("Closed"), "value": "closed"},
{"display_name": _("Finished"), "value": "finished"},
{"display_name": _("Correct or Past Due"), "value": "correct_or_past_due"},
{"display_name": _("Past Due"), "value": "past_due"},
{"display_name": _("Never"), "value": "never"}]
)
......@@ -712,6 +713,8 @@ class CapaMixin(CapaFields):
elif self.showanswer == 'finished':
return self.closed() or self.is_correct()
elif self.showanswer == 'correct_or_past_due':
return self.is_correct() or self.is_past_due()
elif self.showanswer == 'past_due':
return self.is_past_due()
elif self.showanswer == 'always':
......
......@@ -258,6 +258,43 @@ class CapaModuleTest(unittest.TestCase):
graceperiod=self.two_day_delta_str)
self.assertFalse(still_in_grace.answer_available())
def test_showanswer_correct_or_past_due(self):
"""
With showanswer="correct_or_past_due" should show answer after the answer is correct
or after the problem is closed for everyone--e.g. after due date + grace period.
"""
# can see because answer is correct, even with due date in the future
answer_correct = CapaFactory.create(showanswer='correct_or_past_due',
max_attempts="1",
attempts="0",
due=self.tomorrow_str,
correct=True)
self.assertTrue(answer_correct.answer_available())
# can see after due date, even when answer isn't correct
past_due_date = CapaFactory.create(showanswer='correct_or_past_due',
max_attempts="1",
attempts="0",
due=self.yesterday_str)
self.assertTrue(past_due_date.answer_available())
# can also see after due date when answer _is_ correct
past_due_date_correct = CapaFactory.create(showanswer='correct_or_past_due',
max_attempts="1",
attempts="0",
due=self.yesterday_str,
correct=True)
self.assertTrue(past_due_date_correct.answer_available())
# Can't see because grace period hasn't expired and answer isn't correct
still_in_grace = CapaFactory.create(showanswer='correct_or_past_due',
max_attempts="1",
attempts="1",
due=self.yesterday_str,
graceperiod=self.two_day_delta_str)
self.assertFalse(still_in_grace.answer_available())
def test_showanswer_past_due(self):
"""
With showanswer="past_due" should only show answer after the problem is closed
......
......@@ -360,7 +360,7 @@ Show Answer
===============
This setting defines when the problem shows the answer to the student.
This setting has seven options.
This setting has the following options.
+-------------------+--------------------------------------+
| **Always** | Always show the answer when the |
......@@ -385,6 +385,10 @@ This setting has seven options.
| | the student has no attempts left, or |
| | the problem due date has passed. |
+-------------------+--------------------------------------+
| **Correct or | Show the answer after the student |
| Past Due** | has answered the problem correctly |
| | or the problem due date has passed. |
+-------------------+--------------------------------------+
| **Past Due** | Show the answer after the due date |
| | for the problem has passed. |
+-------------------+--------------------------------------+
......
......@@ -391,13 +391,14 @@ Inherited
When this content should be shown to students. Note that anyone with staff access to the course will always see everything.
`showanswer`
When to show answer. Values: never, attempted, answered, closed, finished, past_due, always. Default: closed. Optional.
When to show answer. Values: never, attempted, answered, closed, finished, correct_or_past_due, past_due, always. Default: closed. Optional.
- `never`: never show answer
- `attempted`: show answer after first attempt
- `answered` : this is slightly different from `attempted` -- resetting the problems makes "done" False, but leaves attempts unchanged.
- `closed` : show answer after problem is closed, ie due date is past, or maximum attempts exceeded.
- `finished` : show answer after problem closed, or is correctly answered.
- `past_due` : show answer after problem due date is past.
- `correct_or_past_due` : like `past_due`, but also allow solution to be seen immediately if the problem is correctly answered.
- `always` : always allow answer to be shown.
`graded`
......
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