Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
13a095fc
Commit
13a095fc
authored
May 07, 2012
by
Lyla Fischer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
checkboxes
parent
1f7a3f83
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
80 additions
and
34 deletions
+80
-34
djangoapps/courseware/capa/capa_problem.py
+8
-4
djangoapps/courseware/capa/inputtypes.py
+6
-1
djangoapps/courseware/capa/responsetypes.py
+39
-8
djangoapps/courseware/module_render.py
+4
-1
djangoapps/courseware/modules/capa_module.py
+0
-2
static/js/video_player.js
+2
-2
templates/choicegroup.html
+1
-1
templates/problem.js
+20
-15
No files found.
djangoapps/courseware/capa/capa_problem.py
View file @
13a095fc
...
@@ -15,7 +15,7 @@ from mako.template import Template
...
@@ -15,7 +15,7 @@ from mako.template import Template
from
util
import
contextualize_text
from
util
import
contextualize_text
import
inputtypes
import
inputtypes
from
responsetypes
import
NumericalResponse
,
FormulaResponse
,
CustomResponse
,
SchematicResponse
,
MultipleChoiceResponse
,
StudentInputError
from
responsetypes
import
NumericalResponse
,
FormulaResponse
,
CustomResponse
,
SchematicResponse
,
MultipleChoiceResponse
,
StudentInputError
,
TrueFalseResponse
import
calc
import
calc
import
eia
import
eia
...
@@ -26,7 +26,8 @@ response_types = {'numericalresponse':NumericalResponse,
...
@@ -26,7 +26,8 @@ response_types = {'numericalresponse':NumericalResponse,
'formularesponse'
:
FormulaResponse
,
'formularesponse'
:
FormulaResponse
,
'customresponse'
:
CustomResponse
,
'customresponse'
:
CustomResponse
,
'schematicresponse'
:
SchematicResponse
,
'schematicresponse'
:
SchematicResponse
,
'multiplechoiceresponse'
:
MultipleChoiceResponse
}
'multiplechoiceresponse'
:
MultipleChoiceResponse
,
'truefalseresponse'
:
TrueFalseResponse
}
entry_types
=
[
'textline'
,
'schematic'
,
'choicegroup'
]
entry_types
=
[
'textline'
,
'schematic'
,
'choicegroup'
]
response_properties
=
[
"responseparam"
,
"answer"
]
response_properties
=
[
"responseparam"
,
"answer"
]
# How to convert from original XML to HTML
# How to convert from original XML to HTML
...
@@ -92,6 +93,10 @@ class LoncapaProblem(object):
...
@@ -92,6 +93,10 @@ class LoncapaProblem(object):
self
.
preprocess_problem
(
self
.
tree
,
correct_map
=
self
.
correct_map
,
answer_map
=
self
.
student_answers
)
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
)
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
):
def
get_state
(
self
):
''' Stored per-user session data neeeded to:
''' Stored per-user session data neeeded to:
...
@@ -129,7 +134,6 @@ class LoncapaProblem(object):
...
@@ -129,7 +134,6 @@ class LoncapaProblem(object):
grader
=
response_types
[
response
.
tag
](
response
,
self
.
context
)
grader
=
response_types
[
response
.
tag
](
response
,
self
.
context
)
results
=
grader
.
grade
(
answers
)
results
=
grader
.
grade
(
answers
)
self
.
correct_map
.
update
(
results
)
self
.
correct_map
.
update
(
results
)
return
self
.
correct_map
return
self
.
correct_map
def
get_question_answers
(
self
):
def
get_question_answers
(
self
):
...
@@ -181,7 +185,7 @@ class LoncapaProblem(object):
...
@@ -181,7 +185,7 @@ class LoncapaProblem(object):
tree
=
Element
(
problemtree
.
tag
)
tree
=
Element
(
problemtree
.
tag
)
for
item
in
problemtree
:
for
item
in
problemtree
:
subitems
=
self
.
extract_html
(
item
)
subitems
=
self
.
extract_html
(
item
)
if
subitems
:
if
len
(
subitems
)
:
for
subitem
in
subitems
:
for
subitem
in
subitems
:
tree
.
append
(
subitem
)
tree
.
append
(
subitem
)
for
(
key
,
value
)
in
problemtree
.
items
():
for
(
key
,
value
)
in
problemtree
.
items
():
...
...
djangoapps/courseware/capa/inputtypes.py
View file @
13a095fc
...
@@ -7,7 +7,12 @@ from mitxmako.shortcuts import render_to_string
...
@@ -7,7 +7,12 @@ from mitxmako.shortcuts import render_to_string
def
choicegroup
(
element
,
value
,
state
):
def
choicegroup
(
element
,
value
,
state
):
eid
=
element
.
get
(
'id'
)
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
=
{}
choices
=
{}
for
choice
in
element
:
for
choice
in
element
:
assert
choice
.
tag
==
"choice"
,
"only <choice> tags should be immediate children of a <choicegroup>"
assert
choice
.
tag
==
"choice"
,
"only <choice> tags should be immediate children of a <choicegroup>"
...
...
djangoapps/courseware/capa/responsetypes.py
View file @
13a095fc
...
@@ -5,6 +5,7 @@ import numpy
...
@@ -5,6 +5,7 @@ import numpy
import
random
import
random
import
scipy
import
scipy
import
traceback
import
traceback
import
copy
from
calc
import
evaluator
,
UndefinedVariable
from
calc
import
evaluator
,
UndefinedVariable
from
django.conf
import
settings
from
django.conf
import
settings
...
@@ -36,9 +37,17 @@ def compare_with_tolerance(v1, v2, tol):
...
@@ -36,9 +37,17 @@ def compare_with_tolerance(v1, v2, tol):
tolerance
=
evaluator
(
dict
(),
dict
(),
tol
)
tolerance
=
evaluator
(
dict
(),
dict
(),
tol
)
return
abs
(
v1
-
v2
)
<=
tolerance
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"
#Every response type needs methods "grade" and "get_answers"
class
MultipleChoiceResponse
(
object
):
class
MultipleChoiceResponse
(
GenericResponse
):
def
__init__
(
self
,
xml
,
context
):
def
__init__
(
self
,
xml
,
context
):
self
.
xml
=
xml
self
.
xml
=
xml
self
.
correct_choices
=
xml
.
xpath
(
'//*[@id=$id]//choice[@correct="true"]'
,
self
.
correct_choices
=
xml
.
xpath
(
'//*[@id=$id]//choice[@correct="true"]'
,
...
@@ -52,8 +61,6 @@ class MultipleChoiceResponse(object):
...
@@ -52,8 +61,6 @@ class MultipleChoiceResponse(object):
self
.
answer_id
=
self
.
answer_id
[
0
]
self
.
answer_id
=
self
.
answer_id
[
0
]
def
grade
(
self
,
student_answers
):
def
grade
(
self
,
student_answers
):
answers
=
{}
if
self
.
answer_id
in
student_answers
and
student_answers
[
self
.
answer_id
]
in
self
.
correct_choices
:
if
self
.
answer_id
in
student_answers
and
student_answers
[
self
.
answer_id
]
in
self
.
correct_choices
:
return
{
self
.
answer_id
:
'correct'
}
return
{
self
.
answer_id
:
'correct'
}
else
:
else
:
...
@@ -61,8 +68,32 @@ class MultipleChoiceResponse(object):
...
@@ -61,8 +68,32 @@ class MultipleChoiceResponse(object):
def
get_answers
(
self
):
def
get_answers
(
self
):
return
{
self
.
answer_id
:
self
.
correct_choices
}
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
):
def
__init__
(
self
,
xml
,
context
):
self
.
xml
=
xml
self
.
xml
=
xml
self
.
correct_answer
=
contextualize_text
(
xml
.
get
(
'answer'
),
context
)
self
.
correct_answer
=
contextualize_text
(
xml
.
get
(
'answer'
),
context
)
...
@@ -91,7 +122,7 @@ class NumericalResponse(object):
...
@@ -91,7 +122,7 @@ class NumericalResponse(object):
def
get_answers
(
self
):
def
get_answers
(
self
):
return
{
self
.
answer_id
:
self
.
correct_answer
}
return
{
self
.
answer_id
:
self
.
correct_answer
}
class
CustomResponse
(
object
):
class
CustomResponse
(
GenericResponse
):
def
__init__
(
self
,
xml
,
context
):
def
__init__
(
self
,
xml
,
context
):
self
.
xml
=
xml
self
.
xml
=
xml
## CRITICAL TODO: Should cover all entrytypes
## CRITICAL TODO: Should cover all entrytypes
...
@@ -122,7 +153,7 @@ class CustomResponse(object):
...
@@ -122,7 +153,7 @@ class CustomResponse(object):
class
StudentInputError
(
Exception
):
class
StudentInputError
(
Exception
):
pass
pass
class
FormulaResponse
(
object
):
class
FormulaResponse
(
GenericResponse
):
def
__init__
(
self
,
xml
,
context
):
def
__init__
(
self
,
xml
,
context
):
self
.
xml
=
xml
self
.
xml
=
xml
self
.
correct_answer
=
contextualize_text
(
xml
.
get
(
'answer'
),
context
)
self
.
correct_answer
=
contextualize_text
(
xml
.
get
(
'answer'
),
context
)
...
@@ -192,7 +223,7 @@ class FormulaResponse(object):
...
@@ -192,7 +223,7 @@ class FormulaResponse(object):
def
get_answers
(
self
):
def
get_answers
(
self
):
return
{
self
.
answer_id
:
self
.
correct_answer
}
return
{
self
.
answer_id
:
self
.
correct_answer
}
class
SchematicResponse
(
object
):
class
SchematicResponse
(
GenericResponse
):
def
__init__
(
self
,
xml
,
context
):
def
__init__
(
self
,
xml
,
context
):
self
.
xml
=
xml
self
.
xml
=
xml
self
.
answer_ids
=
xml
.
xpath
(
'//*[@id=$id]//schematic/@id'
,
self
.
answer_ids
=
xml
.
xpath
(
'//*[@id=$id]//schematic/@id'
,
...
...
djangoapps/courseware/module_render.py
View file @
13a095fc
...
@@ -83,7 +83,10 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
...
@@ -83,7 +83,10 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
track_function
=
make_track_function
(
request
),
track_function
=
make_track_function
(
request
),
render_function
=
None
)
render_function
=
None
)
# Let the module handle the AJAX
# 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
# Save the state back to the database
s
.
state
=
instance
.
get_state
()
s
.
state
=
instance
.
get_state
()
if
instance
.
get_score
():
if
instance
.
get_score
():
...
...
djangoapps/courseware/modules/capa_module.py
View file @
13a095fc
...
@@ -270,8 +270,6 @@ class Module(XModule):
...
@@ -270,8 +270,6 @@ class Module(XModule):
for
key
in
get
:
for
key
in
get
:
answers
[
'_'
.
join
(
key
.
split
(
'_'
)[
1
:])]
=
get
[
key
]
answers
[
'_'
.
join
(
key
.
split
(
'_'
)[
1
:])]
=
get
[
key
]
# print "XXX", answers, get
event_info
[
'answers'
]
=
answers
event_info
[
'answers'
]
=
answers
# Too late. Cannot submit
# Too late. Cannot submit
...
...
static/js/video_player.js
View file @
13a095fc
...
@@ -42,7 +42,7 @@ function postJSON(url, data, callback) {
...
@@ -42,7 +42,7 @@ function postJSON(url, data, callback) {
$
.
ajax
({
type
:
'POST'
,
$
.
ajax
({
type
:
'POST'
,
url
:
url
,
url
:
url
,
dataType
:
'json'
,
dataType
:
'json'
,
data
:
data
,
data
:
JSON
.
stringify
(
data
)
,
success
:
callback
,
success
:
callback
,
headers
:
{
'X-CSRFToken'
:
getCookie
(
'csrftoken'
)}
headers
:
{
'X-CSRFToken'
:
getCookie
(
'csrftoken'
)}
});
});
...
@@ -52,7 +52,7 @@ function postJSONAsync(url, data, callback) {
...
@@ -52,7 +52,7 @@ function postJSONAsync(url, data, callback) {
$
.
ajax
({
type
:
'POST'
,
$
.
ajax
({
type
:
'POST'
,
url
:
url
,
url
:
url
,
dataType
:
'json'
,
dataType
:
'json'
,
data
:
data
,
data
:
JSON
.
stringify
(
data
)
,
success
:
callback
,
success
:
callback
,
headers
:
{
'X-CSRFToken'
:
getCookie
(
'csrftoken'
)},
headers
:
{
'X-CSRFToken'
:
getCookie
(
'csrftoken'
)},
async
:
true
async
:
true
...
...
templates/choicegroup.html
View file @
13a095fc
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
% for choice_id, choice_description in choices.items():
% 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}"
<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"
checked=
"true"
%
endif
%
endif
/>
${choice_description}
</label>
/>
${choice_description}
</label>
...
...
templates/problem.js
View file @
13a095fc
...
@@ -8,12 +8,17 @@ function ${ id }_load() {
...
@@ -8,12 +8,17 @@ function ${ id }_load() {
$
(
"input.schematic"
).
each
(
function
(
index
,
element
){
element
.
schematic
.
update_value
();
});
$
(
"input.schematic"
).
each
(
function
(
index
,
element
){
element
.
schematic
.
update_value
();
});
var
submit_data
=
{};
var
submit_data
=
{};
$
.
each
(
$
(
"[id^=input_${ id }_]"
),
function
(
index
,
value
){
$
.
each
(
$
(
"[id^=input_${ id }_]"
),
function
(
index
,
value
){
if
(
value
.
type
===
"
radio"
||
value
.
type
===
"
checkbox"
){
if
(
value
.
type
===
"checkbox"
){
if
(
value
.
checked
)
{
if
(
value
.
checked
)
{
if
(
typeof
submit_data
[
value
.
name
]
==
'undefined'
){
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
{
else
{
...
@@ -21,18 +26,18 @@ function ${ id }_load() {
...
@@ -21,18 +26,18 @@ function ${ id }_load() {
}
}
});
});
postJSON
(
'/modx/problem/${ id }/problem_check'
,
postJSON
(
'/modx/problem/${ id }/problem_check'
,
submit_data
,
submit_data
,
function
(
json
)
{
function
(
json
)
{
switch
(
json
.
success
)
{
switch
(
json
.
success
)
{
case
'incorrect'
:
// Worked, but answer not
case
'incorrect'
:
// Worked, but answer not
case
'correct'
:
case
'correct'
:
$
{
id
}
_load
();
$
{
id
}
_load
();
//alert("!!"+json.success);
//alert("!!"+json.success);
break
;
break
;
default
:
default
:
alert
(
json
.
success
);
alert
(
json
.
success
);
}
}
});
});
log_event
(
'problem_check'
,
submit_data
);
log_event
(
'problem_check'
,
submit_data
);
});
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment