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
e3f12607
Commit
e3f12607
authored
Feb 27, 2013
by
Arthur Barrett
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add grading for annotationinput
parent
9d939cba
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
142 additions
and
24 deletions
+142
-24
common/lib/capa/capa/inputtypes.py
+15
-17
common/lib/capa/capa/responsetypes.py
+101
-1
common/lib/capa/capa/templates/annotationinput.html
+3
-1
common/static/js/capa/annotationinput.js
+23
-5
No files found.
common/lib/capa/capa/inputtypes.py
View file @
e3f12607
...
@@ -988,27 +988,25 @@ class AnnotationInput(InputTypeBase):
...
@@ -988,27 +988,25 @@ class AnnotationInput(InputTypeBase):
self
.
value
=
'null'
self
.
value
=
'null'
def
_find_options
(
self
):
def
_find_options
(
self
):
options
=
[]
''' Returns an array of dicts where each dict represents an option. '''
index
=
0
elements
=
self
.
xml
.
findall
(
'./options/option'
)
for
option
in
self
.
xml
.
findall
(
'./options/option'
):
return
[{
options
.
append
({
'id'
:
index
,
'id'
:
index
,
'description'
:
option
.
text
,
'description'
:
option
.
text
,
'score'
:
option
.
get
(
'score'
,
0
)
'choice'
:
option
.
get
(
'choice'
)
})
}
for
(
index
,
option
)
in
enumerate
(
elements
)
]
index
+=
1
return
options
def
_unpack_value
(
self
):
def
_unpack
(
self
,
json_value
):
unpacked_value
=
json
.
loads
(
self
.
value
)
''' Unpacks the json input state into a dict. '''
if
type
(
unpacked_value
)
!=
dict
:
d
=
json
.
loads
(
json_value
)
unpacked_value
=
{}
if
type
(
d
)
!=
dict
:
d
=
{}
comment_value
=
unpacked_value
.
get
(
'comment'
,
''
)
comment_value
=
d
.
get
(
'comment'
,
''
)
if
not
isinstance
(
comment_value
,
basestring
):
if
not
isinstance
(
comment_value
,
basestring
):
comment_value
=
''
comment_value
=
''
options_value
=
unpacked_value
.
get
(
'options'
,
[])
options_value
=
d
.
get
(
'options'
,
[])
if
not
isinstance
(
options_value
,
list
):
if
not
isinstance
(
options_value
,
list
):
options_value
=
[]
options_value
=
[]
...
@@ -1027,9 +1025,9 @@ class AnnotationInput(InputTypeBase):
...
@@ -1027,9 +1025,9 @@ class AnnotationInput(InputTypeBase):
'options'
:
self
.
options
,
'options'
:
self
.
options
,
'return_to_annotation'
:
self
.
return_to_annotation
,
'return_to_annotation'
:
self
.
return_to_annotation
,
'debug'
:
self
.
debug
'debug'
:
self
.
debug
}
}
unpacked_value
=
self
.
_unpack_value
()
extra_context
.
update
(
unpacked_value
)
extra_context
.
update
(
self
.
_unpack
(
self
.
value
)
)
return
extra_context
return
extra_context
...
...
common/lib/capa/capa/responsetypes.py
View file @
e3f12607
...
@@ -1843,6 +1843,105 @@ class ImageResponse(LoncapaResponse):
...
@@ -1843,6 +1843,105 @@ class ImageResponse(LoncapaResponse):
dict
([(
ie
.
get
(
'id'
),
ie
.
get
(
'regions'
))
for
ie
in
self
.
ielements
]))
dict
([(
ie
.
get
(
'id'
),
ie
.
get
(
'regions'
))
for
ie
in
self
.
ielements
]))
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
class
AnnotationResponse
(
LoncapaResponse
):
response_tag
=
'annotationresponse'
allowed_inputfields
=
[
'annotationinput'
]
max_inputfields
=
1
default_scoring
=
{
'incorrect'
:
0
,
'partial'
:
1
,
'correct'
:
2
}
def
setup_response
(
self
):
xml
=
self
.
xml
self
.
points_map
=
self
.
_get_points_map
()
self
.
answer_map
=
self
.
_get_answer_map
()
def
_get_points_map
(
self
):
''' Returns a dict of option->scoring for each input. '''
scoring
=
self
.
default_scoring
choices
=
dict
(
zip
(
scoring
.
keys
(),
scoring
.
keys
()))
points_map
=
{}
for
inputfield
in
self
.
inputfields
:
option_map
=
dict
([(
option
[
'id'
],
{
'correctness'
:
choices
.
get
(
option
[
'choice'
]),
'points'
:
scoring
.
get
(
option
[
'choice'
])
})
for
option
in
self
.
_find_options
(
inputfield
)
])
points_map
[
inputfield
.
get
(
'id'
)]
=
option_map
return
points_map
def
_get_answer_map
(
self
):
''' Returns a dict of answers for each input.'''
answer_map
=
{}
for
inputfield
in
self
.
inputfields
:
correct_option
=
self
.
_find_option_with_choice
(
inputfield
,
'correct'
)
answer_map
[
inputfield
.
get
(
'id'
)]
=
correct_option
[
'description'
]
return
answer_map
def
_find_options
(
self
,
inputfield
):
''' Returns an array of dicts where each dict represents an option. '''
elements
=
inputfield
.
findall
(
'./options/option'
)
return
[{
'id'
:
index
,
'description'
:
option
.
text
,
'choice'
:
option
.
get
(
'choice'
)
}
for
(
index
,
option
)
in
enumerate
(
elements
)
]
def
_find_option_with_choice
(
self
,
inputfield
,
choice
):
''' Returns the option with the given choice value, otherwise None. '''
for
option
in
self
.
_find_options
(
inputfield
):
if
option
[
'choice'
]
==
choice
:
return
option
def
_unpack
(
self
,
json_value
):
''' Unpacks a student response value submitted as JSON.'''
d
=
json
.
loads
(
json_value
)
if
type
(
d
)
!=
dict
:
d
=
{}
comment_value
=
d
.
get
(
'comment'
,
''
)
if
not
isinstance
(
d
,
basestring
):
comment_value
=
''
options_value
=
d
.
get
(
'options'
,
[])
if
not
isinstance
(
options_value
,
list
):
options_value
=
[]
return
{
'options_value'
:
options_value
,
'comment_value'
:
comment_value
}
def
_get_submitted_option
(
self
,
student_answer
):
''' Return the single option that was selected, otherwise None.'''
value
=
self
.
_unpack
(
student_answer
)
options
=
value
[
'options_value'
]
if
len
(
options
)
==
1
:
return
options
[
0
]
return
None
def
get_score
(
self
,
student_answers
):
''' Returns a CorrectMap for the student answer, which may include
partially correct answers.'''
student_answer
=
student_answers
[
self
.
answer_id
]
student_option
=
self
.
_get_submitted_option
(
student_answer
)
scoring
=
self
.
points_map
[
self
.
answer_id
]
is_valid
=
student_option
is
not
None
and
student_option
in
scoring
.
keys
()
(
correctness
,
points
)
=
(
'incorrect'
,
None
)
if
is_valid
:
correctness
=
scoring
[
student_option
][
'correctness'
]
points
=
scoring
[
student_option
][
'points'
]
return
CorrectMap
(
self
.
answer_id
,
correctness
=
correctness
,
npoints
=
points
)
def
get_answers
(
self
):
return
self
.
answer_map
#-----------------------------------------------------------------------------
# TEMPORARY: List of all response subclasses
# TEMPORARY: List of all response subclasses
# FIXME: To be replaced by auto-registration
# FIXME: To be replaced by auto-registration
...
@@ -1859,4 +1958,5 @@ __all__ = [CodeResponse,
...
@@ -1859,4 +1958,5 @@ __all__ = [CodeResponse,
ChoiceResponse
,
ChoiceResponse
,
MultipleChoiceResponse
,
MultipleChoiceResponse
,
TrueFalseResponse
,
TrueFalseResponse
,
JavascriptResponse
]
JavascriptResponse
,
AnnotationResponse
]
common/lib/capa/capa/templates/annotationinput.html
View file @
e3f12607
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
% if debug:
% if debug:
<div
class=
"debug-value"
>
<div
class=
"debug-value"
>
Rendered with value:
<br/>
Rendered with value:
<br/>
<pre>
${value}
</pre>
<pre>
${value
|h
}
</pre>
Current input value:
<br/>
Current input value:
<br/>
<input
type=
"text"
class=
"value"
name=
"input_${id}"
id=
"input_${id}"
value=
"${value|h}"
/>
<input
type=
"text"
class=
"value"
name=
"input_${id}"
id=
"input_${id}"
value=
"${value|h}"
/>
</div>
</div>
...
@@ -38,6 +38,8 @@
...
@@ -38,6 +38,8 @@
<span
class=
"unanswered"
style=
"display:inline-block;"
id=
"status_${id}"
></span>
<span
class=
"unanswered"
style=
"display:inline-block;"
id=
"status_${id}"
></span>
% elif status == 'correct':
% elif status == 'correct':
<span
class=
"correct"
id=
"status_${id}"
></span>
<span
class=
"correct"
id=
"status_${id}"
></span>
% elif status == 'partial':
<span
class=
"partially_correct"
id=
"status_${id}"
>
Partially Correct
</span>
% elif status == 'incorrect':
% elif status == 'incorrect':
<span
class=
"incorrect"
id=
"status_${id}"
></span>
<span
class=
"incorrect"
id=
"status_${id}"
></span>
% elif status == 'incomplete':
% elif status == 'incomplete':
...
...
common/static/js/capa/annotationinput.js
View file @
e3f12607
(
function
()
{
(
function
()
{
var
debug
=
tru
e
;
var
debug
=
fals
e
;
var
module
=
{
var
module
=
{
debug
:
debug
,
debug
:
debug
,
inputSelector
:
'.annotation-input'
,
inputSelector
:
'.annotation-input'
,
tagSelector
:
'.tag'
,
tagSelector
:
'.tag'
,
tagsSelector
:
'.tags'
,
commentSelector
:
'textarea.comment'
,
commentSelector
:
'textarea.comment'
,
valueSelector
:
'input.value'
,
// stash tag selections and comment here as a JSON string...
valueSelector
:
'input.value'
,
// stash tag selections and comment here as a JSON string...
singleSelect
:
true
,
init
:
function
()
{
init
:
function
()
{
var
that
=
this
;
var
that
=
this
;
...
@@ -38,15 +41,30 @@
...
@@ -38,15 +41,30 @@
target_value
=
$
(
e
.
target
).
data
(
'id'
);
target_value
=
$
(
e
.
target
).
data
(
'id'
);
if
(
!
$
(
target_el
).
hasClass
(
'selected'
))
{
if
(
!
$
(
target_el
).
hasClass
(
'selected'
))
{
current_value
.
options
.
push
(
target_value
);
if
(
this
.
singleSelect
)
{
current_value
.
options
=
[
target_value
]
}
else
{
current_value
.
options
.
push
(
target_value
);
}
}
else
{
}
else
{
target_index
=
current_value
.
options
.
indexOf
(
target_value
);
if
(
this
.
singleSelect
)
{
if
(
target_index
!==
-
1
)
{
current_value
.
options
=
[]
current_value
.
options
.
splice
(
target_index
,
1
);
}
else
{
target_index
=
current_value
.
options
.
indexOf
(
target_value
);
if
(
target_index
!==
-
1
)
{
current_value
.
options
.
splice
(
target_index
,
1
);
}
}
}
}
}
this
.
storeValue
(
value_el
,
current_value
);
this
.
storeValue
(
value_el
,
current_value
);
if
(
this
.
singleSelect
)
{
$
(
target_el
).
closest
(
this
.
tagsSelector
)
.
find
(
this
.
tagSelector
)
.
not
(
target_el
)
.
removeClass
(
'selected'
)
}
$
(
target_el
).
toggleClass
(
'selected'
);
$
(
target_el
).
toggleClass
(
'selected'
);
},
},
findValueEl
:
function
(
target_el
)
{
findValueEl
:
function
(
target_el
)
{
...
...
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