Commit 8e1ed573 by Jason Bau

HACK capa timed-test on capa_base.py

parent 377f91e9
...@@ -147,6 +147,9 @@ class CapaFields(object): ...@@ -147,6 +147,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",
...@@ -312,6 +315,12 @@ class CapaMixin(CapaFields): ...@@ -312,6 +315,12 @@ class CapaMixin(CapaFields):
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)
...@@ -561,6 +570,21 @@ class CapaMixin(CapaFields): ...@@ -561,6 +570,21 @@ class CapaMixin(CapaFields):
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 = { content = {
'name': self.display_name_with_default, 'name': self.display_name_with_default,
'html': html, 'html': html,
...@@ -570,6 +594,9 @@ class CapaMixin(CapaFields): ...@@ -570,6 +594,9 @@ class CapaMixin(CapaFields):
context = { context = {
'problem': content, '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(),
...@@ -596,6 +623,17 @@ class CapaMixin(CapaFields): ...@@ -596,6 +623,17 @@ class CapaMixin(CapaFields):
return html return html
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?
...@@ -611,6 +649,8 @@ class CapaMixin(CapaFields): ...@@ -611,6 +649,8 @@ class CapaMixin(CapaFields):
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
......
<%! 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