Commit 25524f50 by Jason Bau

Merge pull request #2471 from edx/jbau/timed-capa

HACKED TOGETHER time limit for DB class midterm
parents 18d6d411 ef2f20a6
...@@ -141,7 +141,9 @@ class CapaFields(object): ...@@ -141,7 +141,9 @@ class CapaFields(object):
student_answers = Dict(help="Dictionary with the current student responses", scope=Scope.user_state) student_answers = Dict(help="Dictionary with the current student responses", scope=Scope.user_state)
done = Boolean(help="Whether the student has answered the problem", scope=Scope.user_state) done = Boolean(help="Whether the student has answered the problem", scope=Scope.user_state)
seed = Integer(help="Random seed for this student", scope=Scope.user_state) seed = Integer(help="Random seed for this student", scope=Scope.user_state)
minutes_allowed = Integer(help="EXPERIMENTAL FEATURE: DO NOT USE. Number of minutes allowed to finish this assessment. Set 0 for no time-limit",
default=0, scope=Scope.settings)
time_started = Date(help="time student started this assessment", scope=Scope.user_state)
last_submission_time = Date(help="Last submission time", scope=Scope.user_state) last_submission_time = Date(help="Last submission time", scope=Scope.user_state)
submission_wait_seconds = Integer( submission_wait_seconds = Integer(
display_name="Timer Between Attempts", display_name="Timer Between Attempts",
...@@ -311,6 +313,12 @@ class CapaModule(CapaFields, XModule): ...@@ -311,6 +313,12 @@ class CapaModule(CapaFields, XModule):
self.student_answers = lcp_state['student_answers'] self.student_answers = lcp_state['student_answers']
self.seed = lcp_state['seed'] self.seed = lcp_state['seed']
def set_time_started(self):
"""
Sets the time when the student started the module.
"""
self.time_started = datetime.datetime.now(UTC())
def set_last_submission_time(self): def set_last_submission_time(self):
""" """
Set the module's last submission time (when the problem was checked) Set the module's last submission time (when the problem was checked)
...@@ -551,6 +559,20 @@ class CapaModule(CapaFields, XModule): ...@@ -551,6 +559,20 @@ class CapaModule(CapaFields, XModule):
else: else:
check_button = False check_button = False
problem_is_timed = self.minutes_allowed > 0
if problem_is_timed and not self.time_started:
self.set_time_started()
end_time_to_display = (self.time_started + datetime.timedelta(minutes=self.minutes_allowed)
if problem_is_timed
else None)
# because we use self.due and not self.close_date below, this is not the actual end_time, but the
# end_time we want to display to the user
if self.due and end_time_to_display:
end_time_to_display = min(self.due, end_time_to_display)
content = {'name': self.display_name_with_default, content = {'name': self.display_name_with_default,
'html': html, 'html': html,
'weight': self.weight, 'weight': self.weight,
...@@ -558,6 +580,9 @@ class CapaModule(CapaFields, XModule): ...@@ -558,6 +580,9 @@ class CapaModule(CapaFields, XModule):
context = {'problem': content, context = {'problem': content,
'id': self.id, 'id': self.id,
'problem_is_timed': problem_is_timed,
'start_time': self.time_started,
'end_time_to_display': end_time_to_display,
'check_button': check_button, 'check_button': check_button,
'reset_button': self.should_show_reset_button(), 'reset_button': self.should_show_reset_button(),
'save_button': self.should_show_save_button(), 'save_button': self.should_show_save_button(),
...@@ -642,6 +667,17 @@ class CapaModule(CapaFields, XModule): ...@@ -642,6 +667,17 @@ class CapaModule(CapaFields, XModule):
return json.dumps(result, cls=ComplexEncoder) return json.dumps(result, cls=ComplexEncoder)
def exceeded_time_limit(self):
"""
Has student used up allotted time, if set
"""
if self.minutes_allowed <= 0 or not self.time_started:
return False
now = datetime.datetime.now(UTC())
# built in hardcoded grace period of 5 min
time_limit_end = self.time_started + datetime.timedelta(minutes=(self.minutes_allowed + 5))
return now > time_limit_end
def is_past_due(self): def is_past_due(self):
""" """
Is it now past this problem's due date, including grace period? Is it now past this problem's due date, including grace period?
...@@ -657,7 +693,8 @@ class CapaModule(CapaFields, XModule): ...@@ -657,7 +693,8 @@ class CapaModule(CapaFields, XModule):
return True return True
if self.is_past_due(): if self.is_past_due():
return True return True
if self.exceeded_time_limit():
return True
return False return False
def is_submitted(self): def is_submitted(self):
......
<%! from django.utils.translation import ugettext as _ %> <%!
from django.utils.translation import ugettext as _
from xmodule.util.date_utils import get_time_display
from django.conf import settings
%>
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<h2 class="problem-header"> <h2 class="problem-header">
...@@ -8,6 +12,20 @@ ...@@ -8,6 +12,20 @@
<section class="problem-progress"> <section class="problem-progress">
</section> </section>
% if problem_is_timed:
<section class="time_limit">
<p>
${_("At {start_time}, you started this exam.").format(
start_time=get_time_display(start_time, coerce_tz=settings.TIME_ZONE))}
<br />
<b>
${_("By {end_time}, you must manually click the 'Final Submit' button below!").format(
end_time=get_time_display(end_time_to_display, coerce_tz=settings.TIME_ZONE))}
</b>
</p>
</section>
% endif
<section class="problem"> <section class="problem">
${ problem['html'] } ${ problem['html'] }
......
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