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
2f841c8a
Commit
2f841c8a
authored
Jan 08, 2013
by
Vik Paruchuri
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Document combined open ended module
parent
38a81b46
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
127 additions
and
15 deletions
+127
-15
common/lib/xmodule/xmodule/combined_open_ended_module.py
+127
-15
No files found.
common/lib/xmodule/xmodule/combined_open_ended_module.py
View file @
2f841c8a
...
...
@@ -36,6 +36,10 @@ MAX_ATTEMPTS = 10000
MAX_SCORE
=
1
class
CombinedOpenEndedModule
(
XModule
):
"""
This is a module that encapsulates all open ended grading (self assessment, peer assessment, etc).
It transitions between problems, and support arbitrary ordering.
"""
STATE_VERSION
=
1
# states
...
...
@@ -59,16 +63,37 @@ class CombinedOpenEndedModule(XModule):
instance_state
,
shared_state
,
**
kwargs
)
"""
Definition file should have
multiple task blocks
:
Definition file should have
one or many task blocks, a rubric block, and a prompt block
:
Sample file:
<combinedopenended max_score="1" attempts="1">
<task type="self">
<combinedopenended attempts="10000" max_score="1">
<rubric>
Blah blah rubric.
</rubric>
<prompt>
Some prompt.
</prompt>
<task>
<selfassessment>
<hintprompt>
What hint about this problem would you give to someone?
</hintprompt>
<submitmessage>
Save Succcesful. Thanks for participating!
</submitmessage>
</selfassessment>
</task>
<task>
<openended min_score_to_attempt="1" max_score_to_attempt="1">
<openendedparam>
<initial_display>Enter essay here.</initial_display>
<answer_display>This is the answer.</answer_display>
<grader_payload>{"grader_settings" : "ml_grading.conf", "problem_id" : "6.002x/Welcome/OETest"}</grader_payload>
</openendedparam>
</openended>
</task>
</combinedopenended>
"""
# Load instance state
...
...
@@ -77,17 +102,19 @@ class CombinedOpenEndedModule(XModule):
else
:
instance_state
=
{}
# History is a list of tuples of (answer, score, hint), where hint may be
# None for any element, and score and hint can be None for the last (current)
# element.
# Scores are on scale from 0 to max_score
#We need to set the location here so the child modules can use it
system
.
set
(
'location'
,
location
)
#Tells the system which xml definition to load
self
.
current_task_number
=
instance_state
.
get
(
'current_task_number'
,
0
)
#This loads the states of the individual children
self
.
task_states
=
instance_state
.
get
(
'task_states'
,
[])
#Overall state of the combined open ended module
self
.
state
=
instance_state
.
get
(
'state'
,
'initial'
)
self
.
attempts
=
instance_state
.
get
(
'attempts'
,
0
)
#Allow reset is true if student has failed the criteria to move to the next child task
self
.
allow_reset
=
instance_state
.
get
(
'ready_to_reset'
,
False
)
self
.
max_attempts
=
int
(
self
.
metadata
.
get
(
'attempts'
,
MAX_ATTEMPTS
))
...
...
@@ -95,6 +122,7 @@ class CombinedOpenEndedModule(XModule):
# completion (doesn't matter if you self-assessed correct/incorrect).
self
.
_max_score
=
int
(
self
.
metadata
.
get
(
'max_score'
,
MAX_SCORE
))
#Static data is passed to the child modules to render
self
.
static_data
=
{
'max_score'
:
self
.
_max_score
,
'max_attempts'
:
self
.
max_attempts
,
...
...
@@ -106,10 +134,21 @@ class CombinedOpenEndedModule(XModule):
self
.
setup_next_task
()
def
get_tag_name
(
self
,
xml
):
"""
Gets the tag name of a given xml block.
Input: XML string
Output: The name of the root tag
"""
tag
=
etree
.
fromstring
(
xml
)
.
tag
return
tag
def
overwrite_state
(
self
,
current_task_state
):
"""
Overwrites an instance state and sets the latest response to the current response. This is used
to ensure that the student response is carried over from the first child to the rest.
Input: Task state json string
Output: Task state json string
"""
last_response_data
=
self
.
get_last_response
(
self
.
current_task_number
-
1
)
last_response
=
last_response_data
[
'response'
]
...
...
@@ -122,6 +161,12 @@ class CombinedOpenEndedModule(XModule):
return
current_task_state
def
child_modules
(
self
):
"""
Returns the functions associated with the child modules in a dictionary. This makes writing functions
simpler (saves code duplication)
Input: None
Output: A dictionary of dictionaries containing the descriptor functions and module functions
"""
child_modules
=
{
'openended'
:
open_ended_module
.
OpenEndedModule
,
'selfassessment'
:
self_assessment_module
.
SelfAssessmentModule
,
...
...
@@ -137,6 +182,12 @@ class CombinedOpenEndedModule(XModule):
return
children
def
setup_next_task
(
self
,
reset
=
False
):
"""
Sets up the next task for the module. Creates an instance state if none exists, carries over the answer
from the last instance state to the next if needed.
Input: A boolean indicating whether or not the reset function is calling.
Output: Boolean True (not useful right now)
"""
current_task_state
=
None
if
len
(
self
.
task_states
)
>
self
.
current_task_number
:
current_task_state
=
self
.
task_states
[
self
.
current_task_number
]
...
...
@@ -176,6 +227,12 @@ class CombinedOpenEndedModule(XModule):
return
True
def
check_allow_reset
(
self
):
"""
Checks to see if the student has passed the criteria to move to the next module. If not, sets
allow_reset to true and halts the student progress through the tasks.
Input: None
Output: the allow_reset attribute of the current module.
"""
if
not
self
.
allow_reset
:
if
self
.
current_task_number
>
0
:
last_response_data
=
self
.
get_last_response
(
self
.
current_task_number
-
1
)
...
...
@@ -188,6 +245,11 @@ class CombinedOpenEndedModule(XModule):
return
self
.
allow_reset
def
get_context
(
self
):
"""
Generates a context dictionary that is used to render html.
Input: None
Output: A dictionary that can be rendered into the combined open ended template.
"""
task_html
=
self
.
get_html_base
()
#set context variables and render template
...
...
@@ -200,27 +262,47 @@ class CombinedOpenEndedModule(XModule):
'task_number'
:
self
.
current_task_number
+
1
,
'status'
:
self
.
get_status
(),
}
log
.
debug
(
context
)
return
context
def
get_html
(
self
):
"""
Gets HTML for rendering.
Input: None
Output: rendered html
"""
context
=
self
.
get_context
()
html
=
self
.
system
.
render_template
(
'combined_open_ended.html'
,
context
)
return
html
def
get_html_nonsystem
(
self
):
"""
Gets HTML for rendering via AJAX. Does not use system, because system contains some additional
html, which is not appropriate for returning via ajax calls.
Input: None
Output: HTML rendered directly via Mako
"""
context
=
self
.
get_context
()
html
=
render_to_string
(
'combined_open_ended.html'
,
context
)
return
html
def
get_html_base
(
self
):
"""
Gets the HTML associated with the current child task
Input: None
Output: Child task HTML
"""
self
.
update_task_states
()
html
=
self
.
current_task
.
get_html
(
self
.
system
)
return_html
=
rewrite_links
(
html
,
self
.
rewrite_content_links
)
return
return_html
def
get_current_attributes
(
self
,
task_number
):
"""
Gets the min and max score to attempt attributes of the specified task.
Input: The number of the task.
Output: The minimum and maximum scores needed to move on to the specified task.
"""
task_xml
=
self
.
task_xml
[
task_number
]
etree_xml
=
etree
.
fromstring
(
task_xml
)
min_score_to_attempt
=
int
(
etree_xml
.
attrib
.
get
(
'min_score_to_attempt'
,
0
))
...
...
@@ -228,6 +310,11 @@ class CombinedOpenEndedModule(XModule):
return
{
'min_score_to_attempt'
:
min_score_to_attempt
,
'max_score_to_attempt'
:
max_score_to_attempt
}
def
get_last_response
(
self
,
task_number
):
"""
Returns data associated with the specified task number, such as the last response, score, etc.
Input: The number of the task.
Output: A dictionary that contains information about the specified task.
"""
last_response
=
""
task_state
=
self
.
task_states
[
task_number
]
task_xml
=
self
.
task_xml
[
task_number
]
...
...
@@ -270,6 +357,11 @@ class CombinedOpenEndedModule(XModule):
return
last_response_dict
def
update_task_states
(
self
):
"""
Updates the task state of the combined open ended module with the task state of the current child module.
Input: None
Output: boolean indicating whether or not the task state changed.
"""
changed
=
False
if
not
self
.
allow_reset
:
self
.
task_states
[
self
.
current_task_number
]
=
self
.
current_task
.
get_instance_state
()
...
...
@@ -286,6 +378,11 @@ class CombinedOpenEndedModule(XModule):
return
changed
def
update_task_states_ajax
(
self
,
return_html
):
"""
Runs the update task states function for ajax calls. Currently the same as update_task_states
Input: The html returned by the handle_ajax function of the child
Output: New html that should be rendered
"""
changed
=
self
.
update_task_states
()
if
changed
:
#return_html=self.get_html()
...
...
@@ -293,6 +390,11 @@ class CombinedOpenEndedModule(XModule):
return
return_html
def
get_results
(
self
,
get
):
"""
Gets the results of a given grader via ajax.
Input: AJAX get dictionary
Output: Dictionary to be rendered via ajax that contains the result html.
"""
task_number
=
int
(
get
[
'task_number'
])
self
.
update_task_states
()
response_dict
=
self
.
get_last_response
(
task_number
)
...
...
@@ -325,15 +427,19 @@ class CombinedOpenEndedModule(XModule):
return
json
.
dumps
(
d
,
cls
=
ComplexEncoder
)
def
next_problem
(
self
,
get
):
"""
Called via ajax to advance to the next problem.
Input: AJAX get request.
Output: Dictionary to be rendered
"""
self
.
update_task_states
()
return
{
'success'
:
True
,
'html'
:
self
.
get_html_nonsystem
(),
'allow_reset'
:
self
.
allow_reset
}
def
reset
(
self
,
get
):
"""
If resetting is allowed, reset the state.
Returns {'success': bool, 'error': msg}
(error only present if not success)
If resetting is allowed, reset the state of the combined open ended module.
Input: AJAX get dictionary
Output: AJAX dictionary to tbe rendered
"""
if
self
.
state
!=
self
.
DONE
:
if
not
self
.
allow_reset
:
...
...
@@ -358,7 +464,9 @@ class CombinedOpenEndedModule(XModule):
def
get_instance_state
(
self
):
"""
Get the current score and state
Returns the current instance state. The module can be recreated from the instance state.
Input: None
Output: A dictionary containing the instance state.
"""
state
=
{
...
...
@@ -373,6 +481,10 @@ class CombinedOpenEndedModule(XModule):
return
json
.
dumps
(
state
)
def
get_status
(
self
):
"""
Input:
Output:
"""
status
=
[]
for
i
in
xrange
(
0
,
self
.
current_task_number
+
1
):
task_data
=
self
.
get_last_response
(
i
)
...
...
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