Commit 4566cf0a by Piotr Mitros

Due dates and number of submissions work

parent 07454b82
...@@ -11,7 +11,7 @@ class UserProfile(models.Model): ...@@ -11,7 +11,7 @@ class UserProfile(models.Model):
language = models.TextField(blank=True) language = models.TextField(blank=True)
location = models.TextField(blank=True) location = models.TextField(blank=True)
meta = models.TextField(blank=True) # JSON dictionary for future expansion meta = models.TextField(blank=True) # JSON dictionary for future expansion
courseware = models.TextField(blank=True) courseware = models.TextField(blank=True, default='courseware.xml')
class Registration(models.Model): class Registration(models.Model):
''' Allows us to wait for e-mail before user is registered. A ''' Allows us to wait for e-mail before user is registered. A
......
...@@ -25,13 +25,15 @@ class LoncapaModule(XModule): ...@@ -25,13 +25,15 @@ class LoncapaModule(XModule):
xml_tags = ["problem"] xml_tags = ["problem"]
id_attribute = "filename" id_attribute = "filename"
attempts = None attempts = 0
max_attempts = None max_attempts = None
due_date = None due_date = None
def get_state(self): def get_state(self):
return self.lcp.get_state() state = self.lcp.get_state()
state['attempts'] = self.attempts
return json.dumps(state)
def get_score(self): def get_score(self):
return self.lcp.get_score() return self.lcp.get_score()
...@@ -56,14 +58,34 @@ class LoncapaModule(XModule): ...@@ -56,14 +58,34 @@ class LoncapaModule(XModule):
content={'name':self.name, content={'name':self.name,
'html':html} 'html':html}
closed = False closed = False
if self.lcp.done: if self.lcp.done:
check_button="Reset" check_button="Reset"
else: else:
check_button="Check" check_button="Check"
save_button = True
if self.max_attempts == None:
pass
elif self.max_attempts == self.attempts:
save_button = False
check_button = False
else:
check_button = check_button + \
" ({a}/{m})".format(a=self.attempts, m=self.max_attempts)
if self.due_date != None and datetime.datetime.utcnow() > self.due_date:
save_button = False
check_button = False
results = True
html=render_to_string('problem.html', html=render_to_string('problem.html',
{'problem':content, {'problem':content,
'id':self.filename, 'id':self.filename,
'check_button':check_button, 'check_button':check_button,
'save_button':save_button,
'ajax_url':self.ajax_url, 'ajax_url':self.ajax_url,
}) })
if encapsulate: if encapsulate:
...@@ -88,6 +110,11 @@ class LoncapaModule(XModule): ...@@ -88,6 +110,11 @@ class LoncapaModule(XModule):
else: else:
self.max_attempts=None self.max_attempts=None
if state!=None:
state=json.loads(state)
if state!=None and 'attempts' in state:
self.attempts=state['attempts']
self.filename=node.getAttribute("filename") self.filename=node.getAttribute("filename")
filename=settings.DATA_DIR+self.filename+".xml" filename=settings.DATA_DIR+self.filename+".xml"
self.name=node.getAttribute("name") self.name=node.getAttribute("name")
...@@ -102,6 +129,8 @@ class LoncapaModule(XModule): ...@@ -102,6 +129,8 @@ class LoncapaModule(XModule):
response = self.check_problem(get) response = self.check_problem(get)
elif dispatch=='problem_reset': elif dispatch=='problem_reset':
response = self.reset_problem(get) response = self.reset_problem(get)
elif dispatch=='problem_save':
response = self.save_problem(get)
else: else:
return "Error" return "Error"
return response return response
...@@ -116,19 +145,47 @@ class LoncapaModule(XModule): ...@@ -116,19 +145,47 @@ class LoncapaModule(XModule):
def check_problem(self, get): def check_problem(self, get):
''' Checks whether answers to a problem are correct, and returns ''' Checks whether answers to a problem are correct, and returns
a map of correct/incorrect answers ''' a map of correct/incorrect answers '''
if self.attempts == self.max_attempts:
return "Too many attempts. You shouldn't be here."
if self.due_date != None and datetime.datetime.utcnow() > self.due_date:
return "Too late. problem was due."
self.attempts = self.attempts + 1
self.lcp.done=True self.lcp.done=True
answer=dict() answers=dict()
# input_resistor_1 ==> resistor_1 # input_resistor_1 ==> resistor_1
for key in get: for key in get:
answer['_'.join(key.split('_')[1:])]=get[key] answers['_'.join(key.split('_')[1:])]=get[key]
js=json.dumps(self.lcp.grade_answers(answer)) js=json.dumps(self.lcp.grade_answers(answers))
return js return js
def save_problem(self, get):
if self.attempts == self.max_attempts:
return "Too many attempts. You shouldn't be here."
if self.due_date != None and datetime.datetime.utcnow() > self.due_date:
return "Too late. problem was due."
answers=dict()
for key in get:
answers['_'.join(key.split('_')[1:])]=get[key]
self.lcp.answers=answers
return json.dumps({'success':True})
def reset_problem(self, get): def reset_problem(self, get):
''' Changes problem state to unfinished -- removes student answers, ''' Changes problem state to unfinished -- removes student answers,
and causes problem to rerender itself. ''' and causes problem to rerender itself. '''
if self.attempts == self.max_attempts:
return "Too many attempts. You shouldn't be here."
if self.due_date != None and datetime.datetime.utcnow() > self.due_date:
return "Too late. problem was due."
self.lcp.done=False self.lcp.done=False
self.lcp.answers=dict() self.lcp.answers=dict()
self.lcp.context=dict() self.lcp.context=dict()
......
...@@ -17,10 +17,10 @@ class LoncapaProblem(): ...@@ -17,10 +17,10 @@ class LoncapaProblem():
''' Stored per-user session data neeeded to: ''' Stored per-user session data neeeded to:
1) Recreate the problem 1) Recreate the problem
2) Populate any student answers. ''' 2) Populate any student answers. '''
return json.dumps({'seed':self.seed, return {'seed':self.seed,
'answers':self.answers, 'answers':self.answers,
'correct_map':self.correct_map, 'correct_map':self.correct_map,
'done':self.done}) 'done':self.done}
def get_score(self): def get_score(self):
correct=0 correct=0
...@@ -44,9 +44,7 @@ class LoncapaProblem(): ...@@ -44,9 +44,7 @@ class LoncapaProblem():
seed will provide the random seed. Alternatively, passing seed will provide the random seed. Alternatively, passing
context will bypass all script execution, and use the context will bypass all script execution, and use the
given execution context. ''' given execution context. '''
if state!=None: if state==None:
state=json.loads(state)
else:
state={} state={}
self.gid=id self.gid=id
......
...@@ -92,9 +92,7 @@ def render_x_module(request, xml_module): ...@@ -92,9 +92,7 @@ def render_x_module(request, xml_module):
# Check if problem has an instance in DB # Check if problem has an instance in DB
module_type=xml_module.nodeName module_type=xml_module.nodeName
module_class=modx_modules[module_type] module_class=modx_modules[module_type]
print "mida",module_class.id_attribute
module_id=xml_module.getAttribute(module_class.id_attribute) module_id=xml_module.getAttribute(module_class.id_attribute)
print "mid",module_id
# Grab state from database # Grab state from database
s = StudentModule.objects.filter(student=request.user, s = StudentModule.objects.filter(student=request.user,
......
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