Commit 13a095fc by Lyla Fischer

checkboxes

parent 1f7a3f83
......@@ -15,7 +15,7 @@ from mako.template import Template
from util import contextualize_text
import inputtypes
from responsetypes import NumericalResponse, FormulaResponse, CustomResponse, SchematicResponse, MultipleChoiceResponse, StudentInputError
from responsetypes import NumericalResponse, FormulaResponse, CustomResponse, SchematicResponse, MultipleChoiceResponse, StudentInputError, TrueFalseResponse
import calc
import eia
......@@ -26,7 +26,8 @@ response_types = {'numericalresponse':NumericalResponse,
'formularesponse':FormulaResponse,
'customresponse':CustomResponse,
'schematicresponse':SchematicResponse,
'multiplechoiceresponse':MultipleChoiceResponse}
'multiplechoiceresponse':MultipleChoiceResponse,
'truefalseresponse':TrueFalseResponse}
entry_types = ['textline', 'schematic', 'choicegroup']
response_properties = ["responseparam", "answer"]
# How to convert from original XML to HTML
......@@ -92,6 +93,10 @@ class LoncapaProblem(object):
self.preprocess_problem(self.tree, correct_map=self.correct_map, answer_map = self.student_answers)
self.context = self.extract_context(self.tree, seed=self.seed)
for response in self.tree.xpath('//'+"|//".join(response_types)):
responder = response_types[response.tag](response, self.context)
responder.preprocess_response()
def get_state(self):
''' Stored per-user session data neeeded to:
......@@ -129,7 +134,6 @@ class LoncapaProblem(object):
grader = response_types[response.tag](response, self.context)
results = grader.grade(answers)
self.correct_map.update(results)
return self.correct_map
def get_question_answers(self):
......@@ -181,7 +185,7 @@ class LoncapaProblem(object):
tree=Element(problemtree.tag)
for item in problemtree:
subitems = self.extract_html(item)
if subitems:
if len(subitems):
for subitem in subitems:
tree.append(subitem)
for (key,value) in problemtree.items():
......
......@@ -7,7 +7,12 @@ from mitxmako.shortcuts import render_to_string
def choicegroup(element, value, state):
eid=element.get('id')
type="radio" #because right now, we are only doing multiple choice
if element.get('type') == "MultipleChoice":
type="radio"
elif element.get('type') == "TrueFalse":
type="checkbox"
else:
type="radio"
choices={}
for choice in element:
assert choice.tag =="choice", "only <choice> tags should be immediate children of a <choicegroup>"
......
......@@ -5,6 +5,7 @@ import numpy
import random
import scipy
import traceback
import copy
from calc import evaluator, UndefinedVariable
from django.conf import settings
......@@ -36,9 +37,17 @@ def compare_with_tolerance(v1, v2, tol):
tolerance = evaluator(dict(),dict(),tol)
return abs(v1-v2) <= tolerance
class GenericResponse(object):
def grade(self, student_answers):
pass
def get_answers(self):
pass
def preprocess_response(self):
pass
#Every response type needs methods "grade" and "get_answers"
class MultipleChoiceResponse(object):
class MultipleChoiceResponse(GenericResponse):
def __init__(self, xml, context):
self.xml = xml
self.correct_choices = xml.xpath('//*[@id=$id]//choice[@correct="true"]',
......@@ -52,8 +61,6 @@ class MultipleChoiceResponse(object):
self.answer_id=self.answer_id[0]
def grade(self, student_answers):
answers={}
if self.answer_id in student_answers and student_answers[self.answer_id] in self.correct_choices:
return {self.answer_id:'correct'}
else:
......@@ -62,7 +69,31 @@ class MultipleChoiceResponse(object):
def get_answers(self):
return {self.answer_id:self.correct_choices}
class NumericalResponse(object):
def preprocess_response(self):
for response in self.xml.xpath("choicegroup"):
response.set("type", "MultipleChoice")
class TrueFalseResponse(MultipleChoiceResponse):
def preprocess_response(self):
for response in self.xml.xpath("choicegroup"):
response.set("type", "TrueFalse")
def grade(self, student_answers):
correct = copy.deepcopy(self.correct_choices)
if self.answer_id in student_answers and student_answers[self.answer_id]:
for answer in student_answers[self.answer_id]:
if answer in correct:
correct.remove(answer)
else:
return {self.answer_id:'incorrect'}
if len(correct) != 0:
return {self.answer_id:'incorrect'}
else:
return{self.answer_id:'correct'}
else:
return {self.answer_id:'incorrect'}
class NumericalResponse(GenericResponse):
def __init__(self, xml, context):
self.xml = xml
self.correct_answer = contextualize_text(xml.get('answer'), context)
......@@ -91,7 +122,7 @@ class NumericalResponse(object):
def get_answers(self):
return {self.answer_id:self.correct_answer}
class CustomResponse(object):
class CustomResponse(GenericResponse):
def __init__(self, xml, context):
self.xml = xml
## CRITICAL TODO: Should cover all entrytypes
......@@ -122,7 +153,7 @@ class CustomResponse(object):
class StudentInputError(Exception):
pass
class FormulaResponse(object):
class FormulaResponse(GenericResponse):
def __init__(self, xml, context):
self.xml = xml
self.correct_answer = contextualize_text(xml.get('answer'), context)
......@@ -192,7 +223,7 @@ class FormulaResponse(object):
def get_answers(self):
return {self.answer_id:self.correct_answer}
class SchematicResponse(object):
class SchematicResponse(GenericResponse):
def __init__(self, xml, context):
self.xml = xml
self.answer_ids = xml.xpath('//*[@id=$id]//schematic/@id',
......
......@@ -83,7 +83,10 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
track_function = make_track_function(request),
render_function = None)
# Let the module handle the AJAX
ajax_return=instance.handle_ajax(dispatch, request.POST)
post_data=""
if request.raw_post_data:
post_data = json.loads(request.raw_post_data)
ajax_return=instance.handle_ajax(dispatch, post_data)
# Save the state back to the database
s.state=instance.get_state()
if instance.get_score():
......
......@@ -270,8 +270,6 @@ class Module(XModule):
for key in get:
answers['_'.join(key.split('_')[1:])]=get[key]
# print "XXX", answers, get
event_info['answers']=answers
# Too late. Cannot submit
......
......@@ -42,7 +42,7 @@ function postJSON(url, data, callback) {
$.ajax({type:'POST',
url: url,
dataType: 'json',
data: data,
data: JSON.stringify(data),
success: callback,
headers : {'X-CSRFToken':getCookie('csrftoken')}
});
......@@ -52,7 +52,7 @@ function postJSONAsync(url, data, callback) {
$.ajax({type:'POST',
url: url,
dataType: 'json',
data: data,
data: JSON.stringify(data),
success: callback,
headers : {'X-CSRFToken':getCookie('csrftoken')},
async:true
......
......@@ -2,7 +2,7 @@
% for choice_id, choice_description in choices.items():
<label for="input_${id}_${choice_id}"> <input type="${type}" name="input_${id}" id="input_${id}_${choice_id}" value="${choice_id}"
% if value == choice_id:
% if choice_id in value:
checked="true"
% endif
/> ${choice_description} </label>
......
......@@ -8,12 +8,17 @@ function ${ id }_load() {
$("input.schematic").each(function(index,element){ element.schematic.update_value(); });
var submit_data={};
$.each($("[id^=input_${ id }_]"), function(index,value){
if (value.type==="radio" || value.type==="checkbox"){
if (value.type==="checkbox"){
if (value.checked) {
if (typeof submit_data[value.name] == 'undefined'){
submit_data[value.name]=[]
submit_data[value.name]=[];
}
submit_data[value.name]+=value.value;
submit_data[value.name].push(value.value);
}
}
if (value.type==="radio"){
if (value.checked) {
submit_data[value.name]= value.value;
}
}
else{
......
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