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
54026886
Commit
54026886
authored
Apr 09, 2012
by
Lyla Fischer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
multiple choice
parent
c5598334
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
115 additions
and
54 deletions
+115
-54
djangoapps/courseware/capa/capa_problem.py
+10
-19
djangoapps/courseware/capa/inputtypes.py
+42
-33
djangoapps/courseware/capa/responsetypes.py
+28
-0
templates/choicegroup.html
+21
-0
templates/problem.js
+14
-2
No files found.
djangoapps/courseware/capa/capa_problem.py
View file @
54026886
...
...
@@ -14,8 +14,8 @@ from lxml.etree import Element
from
mako.template
import
Template
from
util
import
contextualize_text
from
inputtypes
import
textline
,
schematic
from
responsetypes
import
numericalresponse
,
formularesponse
,
customresponse
,
schematicresponse
,
StudentInputError
import
inputtypes
from
responsetypes
import
numericalresponse
,
formularesponse
,
customresponse
,
schematicresponse
,
multiplechoiceresponse
,
StudentInputError
import
calc
import
eia
...
...
@@ -25,8 +25,9 @@ log = logging.getLogger("mitx.courseware")
response_types
=
{
'numericalresponse'
:
numericalresponse
,
'formularesponse'
:
formularesponse
,
'customresponse'
:
customresponse
,
'schematicresponse'
:
schematicresponse
}
entry_types
=
[
'textline'
,
'schematic'
]
'schematicresponse'
:
schematicresponse
,
'multiplechoiceresponse'
:
multiplechoiceresponse
}
entry_types
=
[
'textline'
,
'schematic'
,
'choicegroup'
]
response_properties
=
[
"responseparam"
,
"answer"
]
# How to convert from original XML to HTML
# We should do this with xlst later
...
...
@@ -35,6 +36,7 @@ html_transforms = {'problem': {'tag':'div'},
"customresponse"
:
{
'tag'
:
'span'
},
"schematicresponse"
:
{
'tag'
:
'span'
},
"formularesponse"
:
{
'tag'
:
'span'
},
"multiplechoiceresponse"
:
{
'tag'
:
'span'
},
"text"
:
{
'tag'
:
'span'
}}
global_context
=
{
'random'
:
random
,
...
...
@@ -48,29 +50,20 @@ global_context={'random':random,
html_problem_semantics
=
[
"responseparam"
,
"answer"
,
"script"
]
# These should be removed from HTML output, but keeping subelements
html_skip
=
[
"numericalresponse"
,
"customresponse"
,
"schematicresponse"
,
"formularesponse"
,
"text"
]
# These should be transformed
html_special_response
=
{
"textline"
:
textline
.
render
,
"schematic"
:
schematic
.
render
}
class
LoncapaProblem
(
object
):
def
__init__
(
self
,
filename
,
id
=
None
,
state
=
None
,
seed
=
None
):
def
__init__
(
self
,
filename
,
id
,
state
=
None
,
seed
=
None
):
## Initialize class variables from state
self
.
seed
=
None
self
.
student_answers
=
dict
()
self
.
correct_map
=
dict
()
self
.
done
=
False
self
.
filename
=
filename
self
.
problem_id
=
id
if
seed
!=
None
:
self
.
seed
=
seed
if
id
:
self
.
problem_id
=
id
else
:
print
"NO ID"
raise
Exception
(
"This should never happen (183)"
)
#self.problem_id = filename
if
state
:
if
'seed'
in
state
:
self
.
seed
=
state
[
'seed'
]
...
...
@@ -82,7 +75,6 @@ class LoncapaProblem(object):
self
.
done
=
state
[
'done'
]
# print self.seed
# TODO: Does this deplete the Linux entropy pool? Is this fast enough?
if
not
self
.
seed
:
self
.
seed
=
struct
.
unpack
(
'i'
,
os
.
urandom
(
4
))[
0
]
...
...
@@ -175,7 +167,7 @@ class LoncapaProblem(object):
if
problemtree
.
tag
in
html_problem_semantics
:
return
if
problemtree
.
tag
in
html_special_response
:
if
hasattr
(
inputtypes
,
problemtree
.
tag
)
:
status
=
"unsubmitted"
if
problemtree
.
get
(
'id'
)
in
self
.
correct_map
:
status
=
self
.
correct_map
[
problemtree
.
get
(
'id'
)]
...
...
@@ -184,7 +176,7 @@ class LoncapaProblem(object):
if
self
.
student_answers
and
problemtree
.
get
(
'id'
)
in
self
.
student_answers
:
value
=
self
.
student_answers
[
problemtree
.
get
(
'id'
)]
return
html_special_response
[
problemtree
.
tag
]
(
problemtree
,
value
,
status
)
#TODO
return
getattr
(
inputtypes
,
problemtree
.
tag
)
(
problemtree
,
value
,
status
)
#TODO
tree
=
Element
(
problemtree
.
tag
)
for
item
in
problemtree
:
...
...
@@ -210,7 +202,6 @@ class LoncapaProblem(object):
# TODO: Fix. This loses Element().tail
#if problemtree.tag in html_skip:
# return tree
return
[
tree
]
def
preprocess_problem
(
self
,
tree
,
correct_map
=
dict
(),
answer_map
=
dict
()):
# private
...
...
djangoapps/courseware/capa/inputtypes.py
View file @
54026886
from
lxml.etree
import
Element
from
lxml
import
etree
from
mitxmako.shortcuts
import
render_to_
response
,
render_to_
string
from
mitxmako.shortcuts
import
render_to_string
class
textline
(
object
):
@staticmethod
def
render
(
element
,
value
,
state
):
eid
=
element
.
get
(
'id'
)
count
=
int
(
eid
.
split
(
'_'
)[
-
2
])
-
1
# HACK
size
=
element
.
get
(
'size'
)
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
state
,
'count'
:
count
,
'size'
:
size
}
html
=
render_to_string
(
"textinput.html"
,
context
)
return
etree
.
XML
(
html
)
#takes the xml tree as 'element', the student's previous answer as 'value', and the graded status as 'state'
class
schematic
(
object
):
@staticmethod
def
render
(
element
,
value
,
state
):
eid
=
element
.
get
(
'id'
)
height
=
element
.
get
(
'height'
)
width
=
element
.
get
(
'width'
)
parts
=
element
.
get
(
'parts'
)
analyses
=
element
.
get
(
'analyses'
)
initial_value
=
element
.
get
(
'initial_value'
)
submit_analyses
=
element
.
get
(
'submit_analyses'
)
context
=
{
'id'
:
eid
,
'value'
:
value
,
'initial_value'
:
initial_value
,
'state'
:
state
,
'width'
:
width
,
'height'
:
height
,
'parts'
:
parts
,
'analyses'
:
analyses
,
'submit_analyses'
:
submit_analyses
,
}
html
=
render_to_string
(
"schematicinput.html"
,
context
)
return
etree
.
XML
(
html
)
def
choicegroup
(
element
,
value
,
state
):
eid
=
element
.
get
(
'id'
)
type
=
"radio"
#because right now, we are only doing multiple choice
choices
=
{}
for
choice
in
element
:
assert
choice
.
tag
==
"choice"
,
"only <choice> tags should be immediate children of a <choicegroup>"
choices
[
choice
.
get
(
"name"
)]
=
etree
.
tostring
(
choice
[
0
])
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
state
,
'type'
:
type
,
'choices'
:
choices
}
html
=
render_to_string
(
"choicegroup.html"
,
context
)
return
etree
.
XML
(
html
)
def
textline
(
element
,
value
,
state
):
eid
=
element
.
get
(
'id'
)
count
=
int
(
eid
.
split
(
'_'
)[
-
2
])
-
1
# HACK
size
=
element
.
get
(
'size'
)
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
state
,
'count'
:
count
,
'size'
:
size
}
html
=
render_to_string
(
"textinput.html"
,
context
)
return
etree
.
XML
(
html
)
def
schematic
(
element
,
value
,
state
):
eid
=
element
.
get
(
'id'
)
height
=
element
.
get
(
'height'
)
width
=
element
.
get
(
'width'
)
parts
=
element
.
get
(
'parts'
)
analyses
=
element
.
get
(
'analyses'
)
initial_value
=
element
.
get
(
'initial_value'
)
submit_analyses
=
element
.
get
(
'submit_analyses'
)
context
=
{
'id'
:
eid
,
'value'
:
value
,
'initial_value'
:
initial_value
,
'state'
:
state
,
'width'
:
width
,
'height'
:
height
,
'parts'
:
parts
,
'analyses'
:
analyses
,
'submit_analyses'
:
submit_analyses
,
}
html
=
render_to_string
(
"schematicinput.html"
,
context
)
return
etree
.
XML
(
html
)
djangoapps/courseware/capa/responsetypes.py
View file @
54026886
...
...
@@ -9,6 +9,8 @@ import traceback
from
calc
import
evaluator
,
UndefinedVariable
from
django.conf
import
settings
from
util
import
contextualize_text
from
lxml
import
etree
from
lxml.etree
import
Element
import
calc
import
eia
...
...
@@ -34,6 +36,32 @@ def compare_with_tolerance(v1, v2, tol):
tolerance
=
evaluator
(
dict
(),
dict
(),
tol
)
return
abs
(
v1
-
v2
)
<=
tolerance
#Every response type needs methods "grade" and "get_answers"
class
multiplechoiceresponse
(
object
):
def
__init__
(
self
,
xml
,
context
):
self
.
xml
=
xml
self
.
correct_choices
=
xml
.
xpath
(
'//*[@id=$id]//choice[@correct="true"]'
,
id
=
xml
.
get
(
'id'
))
self
.
correct_choices
=
[
choice
.
get
(
'name'
)
for
choice
in
self
.
correct_choices
]
self
.
context
=
context
self
.
answer_id
=
xml
.
xpath
(
'//*[@id=$id]//choicegroup/@id'
,
id
=
xml
.
get
(
'id'
))
assert
len
(
self
.
answer_id
)
==
1
,
"should have exactly one choice group per multiplechoicceresponse"
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
:
return
{
self
.
answer_id
:
'incorrect'
}
def
get_answers
(
self
):
return
{
self
.
answer_id
:
self
.
correct_choices
}
class
numericalresponse
(
object
):
def
__init__
(
self
,
xml
,
context
):
self
.
xml
=
xml
...
...
templates/choicegroup.html
0 → 100644
View file @
54026886
<form
class=
"multiple-choice"
>
% 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:
checked=
"true"
%
endif
/>
${choice_description}
</label>
% endfor
<span
id=
"answer_${id}"
></span>
% if state == 'unsubmitted':
<span
class=
"unanswered"
style=
"display:inline-block;"
id=
"status_${id}"
></span>
% elif state == 'correct':
<span
class=
"correct"
id=
"status_${id}"
></span>
% elif state == 'incorrect':
<span
class=
"incorrect"
id=
"status_${id}"
></span>
% elif state == 'incomplete':
<span
class=
"incorrect"
id=
"status_${id}"
></span>
% endif
</form>
templates/problem.js
View file @
54026886
...
...
@@ -5,11 +5,23 @@ function ${ id }_load() {
update_schematics
();
$
(
'#check_${ id }'
).
click
(
function
()
{
$
(
"input.schematic"
).
each
(
function
(
index
,
element
){
element
.
schematic
.
update_value
();
});
$
(
"input.schematic"
).
each
(
function
(
index
,
element
){
element
.
schematic
.
update_value
();
});
var
submit_data
=
{};
$
.
each
(
$
(
"[id^=input_${ id }_]"
),
function
(
index
,
value
){
submit_data
[
value
.
id
]
=
value
.
value
;
if
(
value
.
type
===
"radio"
||
value
.
type
===
"checkbox"
){
if
(
value
.
checked
)
{
console
.
log
(
"adding a radio or checkbox value"
);
if
(
typeof
submit_data
[
value
.
name
]
==
'undefined'
)
submit_data
[
value
.
name
]
=
[]
submit_data
[
value
.
name
]
+=
value
.
value
;
}
}
else
{
console
.
log
(
"adding a standard value"
);
submit_data
[
value
.
id
]
=
value
.
value
;
}
});
console
.
log
(
submit_data
)
postJSON
(
'/modx/problem/${ id }/problem_check'
,
submit_data
,
function
(
json
)
{
...
...
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