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
d95a5e46
Commit
d95a5e46
authored
May 20, 2012
by
Piotr Mitros
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Modular refactor: Better names (grade to get_score, etc.
parent
29f565dd
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
76 additions
and
29 deletions
+76
-29
djangoapps/courseware/capa/inputtypes.py
+63
-16
djangoapps/courseware/capa/responsetypes.py
+13
-13
No files found.
djangoapps/courseware/capa/inputtypes.py
View file @
d95a5e46
...
@@ -33,7 +33,7 @@ from lxml import etree
...
@@ -33,7 +33,7 @@ from lxml import etree
from
mitxmako.shortcuts
import
render_to_string
from
mitxmako.shortcuts
import
render_to_string
class
SimpleInput
():
# XModule
class
SimpleInput
():
# XModule
''' Type for simple inputs
''' Type for simple inputs
-- plain HTML with a form element
State is a dictionary with optional keys:
State is a dictionary with optional keys:
* Value
* Value
* ID
* ID
...
@@ -42,18 +42,18 @@ class SimpleInput():# XModule
...
@@ -42,18 +42,18 @@ class SimpleInput():# XModule
feedback from previous attempt)
feedback from previous attempt)
'''
'''
simple_type
s
=
{}
## Maps tags to functions
xml_tag
s
=
{}
## Maps tags to functions
@classmethod
@classmethod
def
get_xml_tags
(
c
):
def
get_xml_tags
(
c
):
return
c
.
simple_type
s
.
keys
()
return
c
.
xml_tag
s
.
keys
()
@classmethod
@classmethod
def
get_uses
(
c
):
def
get_uses
(
c
):
return
[
'capa_input'
]
return
[
'capa_input'
,
'capa_transform'
]
def
get_html
(
self
):
def
get_html
(
self
):
return
self
.
simple_type
s
[
self
.
tag
](
self
.
xml
,
self
.
value
,
self
.
status
,
self
.
msg
)
return
self
.
xml_tag
s
[
self
.
tag
](
self
.
xml
,
self
.
value
,
self
.
status
,
self
.
msg
)
def
__init__
(
self
,
system
,
xml
,
item_id
=
None
,
track_url
=
None
,
state
=
None
,
use
=
'capa_input'
):
def
__init__
(
self
,
system
,
xml
,
item_id
=
None
,
track_url
=
None
,
state
=
None
,
use
=
'capa_input'
):
self
.
xml
=
xml
self
.
xml
=
xml
...
@@ -80,18 +80,65 @@ class SimpleInput():# XModule
...
@@ -80,18 +80,65 @@ class SimpleInput():# XModule
if
'status'
in
state
:
if
'status'
in
state
:
self
.
status
=
state
[
'status'
]
self
.
status
=
state
[
'status'
]
def
simpleinput
(
fn
,
names
=
None
):
## TODO
# class SimpleTransform():
# ''' Type for simple XML to HTML transforms. Examples:
# * Math tags, which go from LON-CAPA-style m-tags to MathJAX
# '''
# xml_tags = {} ## Maps tags to functions
# @classmethod
# def get_xml_tags(c):
# return c.xml_tags.keys()
# @classmethod
# def get_uses(c):
# return ['capa_transform']
# def get_html(self):
# return self.xml_tags[self.tag](self.xml, self.value, self.status, self.msg)
# def __init__(self, system, xml, item_id = None, track_url=None, state=None, use = 'capa_input'):
# self.xml = xml
# self.tag = xml.tag
# if not state:
# state = {}
# if item_id:
# self.id = item_id
# if xml.get('id'):
# self.id = xml.get('id')
# if 'id' in state:
# self.id = state['id']
# self.system = system
# self.value = ''
# if 'value' in state:
# self.value = state['value']
# self.msg = ''
# if 'feedback' in state and 'message' in state['feedback']:
# self.msg = state['feedback']['message']
# self.status = 'unanswered'
# if 'status' in state:
# self.status = state['status']
def
register_render_function
(
fn
,
names
=
None
,
cls
=
SimpleInput
):
if
names
==
None
:
if
names
==
None
:
SimpleInput
.
simple_type
s
[
fn
.
__name__
]
=
fn
SimpleInput
.
xml_tag
s
[
fn
.
__name__
]
=
fn
else
:
else
:
raise
"Unimplemented/input types"
raise
"Unimplemented/input types"
def
wrapped
():
def
wrapped
():
return
fn
return
fn
return
wrapped
return
wrapped
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@
simpleinput
@
register_render_function
def
optioninput
(
element
,
value
,
status
,
msg
=
''
):
def
optioninput
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
Select option input type.
Select option input type.
...
@@ -125,7 +172,7 @@ def optioninput(element, value, status, msg=''):
...
@@ -125,7 +172,7 @@ def optioninput(element, value, status, msg=''):
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@
simpleinput
@
register_render_function
def
choicegroup
(
element
,
value
,
status
,
msg
=
''
):
def
choicegroup
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
Radio button inputs: multiple choice or true/false
Radio button inputs: multiple choice or true/false
...
@@ -148,7 +195,7 @@ def choicegroup(element, value, status, msg=''):
...
@@ -148,7 +195,7 @@ def choicegroup(element, value, status, msg=''):
html
=
render_to_string
(
"choicegroup.html"
,
context
)
html
=
render_to_string
(
"choicegroup.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
@
simpleinput
@
register_render_function
def
textline
(
element
,
value
,
state
,
msg
=
""
):
def
textline
(
element
,
value
,
state
,
msg
=
""
):
eid
=
element
.
get
(
'id'
)
eid
=
element
.
get
(
'id'
)
count
=
int
(
eid
.
split
(
'_'
)[
-
2
])
-
1
# HACK
count
=
int
(
eid
.
split
(
'_'
)[
-
2
])
-
1
# HACK
...
@@ -159,7 +206,7 @@ def textline(element, value, state, msg=""):
...
@@ -159,7 +206,7 @@ def textline(element, value, state, msg=""):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@
simpleinput
@
register_render_function
def
js_textline
(
element
,
value
,
status
,
msg
=
''
):
def
js_textline
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
Plan: We will inspect element to figure out type
Plan: We will inspect element to figure out type
...
@@ -185,7 +232,7 @@ def js_textline(element, value, status, msg=''):
...
@@ -185,7 +232,7 @@ def js_textline(element, value, status, msg=''):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
## TODO: Make a wrapper for <codeinput>
## TODO: Make a wrapper for <codeinput>
@
simpleinput
@
register_render_function
def
textbox
(
element
,
value
,
status
,
msg
=
''
):
def
textbox
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
The textbox is used for code input. The message is the return HTML string from
The textbox is used for code input. The message is the return HTML string from
...
@@ -201,7 +248,7 @@ def textbox(element, value, status, msg=''):
...
@@ -201,7 +248,7 @@ def textbox(element, value, status, msg=''):
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@
simpleinput
@
register_render_function
def
schematic
(
element
,
value
,
status
,
msg
=
''
):
def
schematic
(
element
,
value
,
status
,
msg
=
''
):
eid
=
element
.
get
(
'id'
)
eid
=
element
.
get
(
'id'
)
height
=
element
.
get
(
'height'
)
height
=
element
.
get
(
'height'
)
...
@@ -226,7 +273,7 @@ def schematic(element, value, status, msg=''):
...
@@ -226,7 +273,7 @@ def schematic(element, value, status, msg=''):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
### TODO: Move out of inputtypes
### TODO: Move out of inputtypes
@
simpleinput
@
register_render_function
def
math
(
element
,
value
,
status
,
msg
=
''
):
def
math
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
This is not really an input type. It is a convention from Lon-CAPA, used for
This is not really an input type. It is a convention from Lon-CAPA, used for
...
@@ -261,7 +308,7 @@ def math(element, value, status, msg=''):
...
@@ -261,7 +308,7 @@ def math(element, value, status, msg=''):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@
simpleinput
@
register_render_function
def
solution
(
element
,
value
,
status
,
msg
=
''
):
def
solution
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
This is not really an input type. It is just a <span>...</span> which is given an ID,
This is not really an input type. It is just a <span>...</span> which is given an ID,
...
@@ -282,7 +329,7 @@ def solution(element, value, status, msg=''):
...
@@ -282,7 +329,7 @@ def solution(element, value, status, msg=''):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@
simpleinput
@
register_render_function
def
imageinput
(
element
,
value
,
status
,
msg
=
''
):
def
imageinput
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
Clickable image as an input field. Element should specify the image source, height, and width, eg
Clickable image as an input field. Element should specify the image source, height, and width, eg
...
...
djangoapps/courseware/capa/responsetypes.py
View file @
d95a5e46
...
@@ -47,10 +47,10 @@ def compare_with_tolerance(v1, v2, tol):
...
@@ -47,10 +47,10 @@ def compare_with_tolerance(v1, v2, tol):
return
abs
(
v1
-
v2
)
<=
tolerance
return
abs
(
v1
-
v2
)
<=
tolerance
class
GenericResponse
(
object
):
class
GenericResponse
(
object
):
__metaclass__
=
abc
.
ABCMeta
__metaclass__
=
abc
.
ABCMeta
# abc = Abstract Base Class
@abc.abstractmethod
@abc.abstractmethod
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
pass
pass
@abc.abstractmethod
@abc.abstractmethod
...
@@ -61,7 +61,7 @@ class GenericResponse(object):
...
@@ -61,7 +61,7 @@ class GenericResponse(object):
def
preprocess_response
(
self
):
def
preprocess_response
(
self
):
pass
pass
#Every response type needs methods "g
rad
e" and "get_answers"
#Every response type needs methods "g
et_scor
e" and "get_answers"
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
...
@@ -95,7 +95,7 @@ class MultipleChoiceResponse(GenericResponse):
...
@@ -95,7 +95,7 @@ class MultipleChoiceResponse(GenericResponse):
raise
Exception
(
"should have exactly one choice group per multiplechoicceresponse"
)
raise
Exception
(
"should have exactly one choice group per multiplechoicceresponse"
)
self
.
answer_id
=
self
.
answer_id
[
0
]
self
.
answer_id
=
self
.
answer_id
[
0
]
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_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
:
...
@@ -132,7 +132,7 @@ class TrueFalseResponse(MultipleChoiceResponse):
...
@@ -132,7 +132,7 @@ class TrueFalseResponse(MultipleChoiceResponse):
else
:
else
:
choice
.
set
(
"name"
,
"choice_"
+
choice
.
get
(
"name"
))
choice
.
set
(
"name"
,
"choice_"
+
choice
.
get
(
"name"
))
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
correct
=
set
(
self
.
correct_choices
)
correct
=
set
(
self
.
correct_choices
)
answers
=
set
(
student_answers
.
get
(
self
.
answer_id
,
[]))
answers
=
set
(
student_answers
.
get
(
self
.
answer_id
,
[]))
...
@@ -162,7 +162,7 @@ class OptionResponse(GenericResponse):
...
@@ -162,7 +162,7 @@ class OptionResponse(GenericResponse):
print
'[courseware.capa.responsetypes.OR.init] answer_fields=
%
s'
%
(
self
.
answer_fields
)
print
'[courseware.capa.responsetypes.OR.init] answer_fields=
%
s'
%
(
self
.
answer_fields
)
self
.
context
=
context
self
.
context
=
context
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
cmap
=
{}
cmap
=
{}
amap
=
self
.
get_answers
()
amap
=
self
.
get_answers
()
for
aid
in
amap
:
for
aid
in
amap
:
...
@@ -194,7 +194,7 @@ class NumericalResponse(GenericResponse):
...
@@ -194,7 +194,7 @@ class NumericalResponse(GenericResponse):
except
Exception
,
err
:
except
Exception
,
err
:
self
.
answer_id
=
None
self
.
answer_id
=
None
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
''' Display HTML for a numeric response '''
''' Display HTML for a numeric response '''
student_answer
=
student_answers
[
self
.
answer_id
]
student_answer
=
student_answers
[
self
.
answer_id
]
try
:
try
:
...
@@ -300,7 +300,7 @@ def sympy_check2():
...
@@ -300,7 +300,7 @@ def sympy_check2():
else
:
else
:
self
.
code
=
answer
.
text
self
.
code
=
answer
.
text
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
'''
'''
student_answers is a dict with everything from request.POST, but with the first part
student_answers is a dict with everything from request.POST, but with the first part
of each key removed (the string before the first "_").
of each key removed (the string before the first "_").
...
@@ -363,7 +363,7 @@ def sympy_check2():
...
@@ -363,7 +363,7 @@ def sympy_check2():
print
"oops in customresponse (cfn) error
%
s"
%
err
print
"oops in customresponse (cfn) error
%
s"
%
err
# print "context = ",self.context
# print "context = ",self.context
print
traceback
.
format_exc
()
print
traceback
.
format_exc
()
if
settings
.
DEBUG
:
print
"[courseware.capa.responsetypes.customresponse.g
rad
e] ret = "
,
ret
if
settings
.
DEBUG
:
print
"[courseware.capa.responsetypes.customresponse.g
et_scor
e] ret = "
,
ret
if
type
(
ret
)
==
dict
:
if
type
(
ret
)
==
dict
:
correct
[
0
]
=
'correct'
if
ret
[
'ok'
]
else
'incorrect'
correct
[
0
]
=
'correct'
if
ret
[
'ok'
]
else
'incorrect'
msg
=
ret
[
'msg'
]
msg
=
ret
[
'msg'
]
...
@@ -428,7 +428,7 @@ class ExternalResponse(GenericResponse):
...
@@ -428,7 +428,7 @@ class ExternalResponse(GenericResponse):
self
.
tests
=
xml
.
get
(
'answer'
)
self
.
tests
=
xml
.
get
(
'answer'
)
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
submission
=
[
student_answers
[
k
]
for
k
in
sorted
(
self
.
answer_ids
)]
submission
=
[
student_answers
[
k
]
for
k
in
sorted
(
self
.
answer_ids
)]
self
.
context
.
update
({
'submission'
:
submission
})
self
.
context
.
update
({
'submission'
:
submission
})
...
@@ -504,7 +504,7 @@ class FormulaResponse(GenericResponse):
...
@@ -504,7 +504,7 @@ class FormulaResponse(GenericResponse):
self
.
case_sensitive
=
False
self
.
case_sensitive
=
False
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
variables
=
self
.
samples
.
split
(
'@'
)[
0
]
.
split
(
','
)
variables
=
self
.
samples
.
split
(
'@'
)[
0
]
.
split
(
','
)
numsamples
=
int
(
self
.
samples
.
split
(
'@'
)[
1
]
.
split
(
'#'
)[
1
])
numsamples
=
int
(
self
.
samples
.
split
(
'@'
)[
1
]
.
split
(
'#'
)[
1
])
sranges
=
zip
(
*
map
(
lambda
x
:
map
(
float
,
x
.
split
(
","
)),
sranges
=
zip
(
*
map
(
lambda
x
:
map
(
float
,
x
.
split
(
","
)),
...
@@ -566,7 +566,7 @@ class SchematicResponse(GenericResponse):
...
@@ -566,7 +566,7 @@ class SchematicResponse(GenericResponse):
else
:
else
:
self
.
code
=
answer
.
text
self
.
code
=
answer
.
text
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
from
capa_problem
import
global_context
from
capa_problem
import
global_context
submission
=
[
json
.
loads
(
student_answers
[
k
])
for
k
in
sorted
(
self
.
answer_ids
)]
submission
=
[
json
.
loads
(
student_answers
[
k
])
for
k
in
sorted
(
self
.
answer_ids
)]
self
.
context
.
update
({
'submission'
:
submission
})
self
.
context
.
update
({
'submission'
:
submission
})
...
@@ -605,7 +605,7 @@ class ImageResponse(GenericResponse):
...
@@ -605,7 +605,7 @@ class ImageResponse(GenericResponse):
self
.
ielements
=
xml
.
findall
(
'imageinput'
)
self
.
ielements
=
xml
.
findall
(
'imageinput'
)
self
.
answer_ids
=
[
ie
.
get
(
'id'
)
for
ie
in
self
.
ielements
]
self
.
answer_ids
=
[
ie
.
get
(
'id'
)
for
ie
in
self
.
ielements
]
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
correct_map
=
{}
correct_map
=
{}
expectedset
=
self
.
get_answers
()
expectedset
=
self
.
get_answers
()
...
...
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