checkboxes
This commit is contained in:
@@ -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:
|
||||
@@ -61,8 +68,32 @@ 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{
|
||||
@@ -21,18 +26,18 @@ function ${ id }_load() {
|
||||
}
|
||||
});
|
||||
postJSON('/modx/problem/${ id }/problem_check',
|
||||
submit_data,
|
||||
function(json) {
|
||||
switch(json.success) {
|
||||
case 'incorrect': // Worked, but answer not
|
||||
case 'correct':
|
||||
${ id }_load();
|
||||
//alert("!!"+json.success);
|
||||
break;
|
||||
default:
|
||||
alert(json.success);
|
||||
}
|
||||
});
|
||||
submit_data,
|
||||
function(json) {
|
||||
switch(json.success) {
|
||||
case 'incorrect': // Worked, but answer not
|
||||
case 'correct':
|
||||
${ id }_load();
|
||||
//alert("!!"+json.success);
|
||||
break;
|
||||
default:
|
||||
alert(json.success);
|
||||
}
|
||||
});
|
||||
log_event('problem_check', submit_data);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user