diff --git a/common/lib/xmodule/xmodule/combined_open_ended_module.py b/common/lib/xmodule/xmodule/combined_open_ended_module.py
index 4fddb29bf1..ecdc67a120 100644
--- a/common/lib/xmodule/xmodule/combined_open_ended_module.py
+++ b/common/lib/xmodule/xmodule/combined_open_ended_module.py
@@ -283,6 +283,9 @@ class CombinedOpenEndedModule(XModule):
return json.dumps(state)
+ def get_status(self):
+ pass
+
class CombinedOpenEndedDescriptor(XmlDescriptor, EditingDescriptor):
"""
Module for adding self assessment questions to courses
diff --git a/common/lib/xmodule/xmodule/open_ended_module.py b/common/lib/xmodule/xmodule/open_ended_module.py
index e0911b6489..174fa5e326 100644
--- a/common/lib/xmodule/xmodule/open_ended_module.py
+++ b/common/lib/xmodule/xmodule/open_ended_module.py
@@ -28,6 +28,7 @@ from .stringify import stringify_children
from .xml_module import XmlDescriptor
from xmodule.modulestore import Location
from capa.util import *
+import openendedchild
from datetime import datetime
@@ -42,89 +43,9 @@ MAX_ATTEMPTS = 1
# Overriden by max_score specified in xml.
MAX_SCORE = 1
-class OpenEndedModule():
- """
- States:
-
- initial (prompt, textbox shown)
- |
- assessing (read-only textbox, rubric + assessment input shown)
- |
- request_hint (read-only textbox, read-only rubric and assessment, hint input box shown)
- |
- done (submitted msg, green checkmark, everything else read-only. If attempts < max, shows
- a reset button that goes back to initial state. Saves previous
- submissions too.)
- """
-
- DEFAULT_QUEUE = 'open-ended'
- DEFAULT_MESSAGE_QUEUE = 'open-ended-message'
- max_inputfields = 1
-
- STATE_VERSION = 1
-
- # states
- INITIAL = 'initial'
- ASSESSING = 'assessing'
- POST_ASSESSMENT = 'post_assessment'
- DONE = 'done'
-
- def __init__(self, system, location, definition, descriptor,
- instance_state=None, shared_state=None, **kwargs):
- """
- Definition file should have 4 blocks -- prompt, rubric, submitmessage, hintprompt,
- and two optional attributes:
- attempts, which should be an integer that defaults to 1.
- If it's > 1, the student will be able to re-submit after they see
- the rubric.
- max_score, which should be an integer that defaults to 1.
- It defines the maximum number of points a student can get. Assumed to be integer scale
- from 0 to max_score, with an interval of 1.
-
- Note: all the submissions are stored.
-
- Sample file:
-
-
-
- Insert prompt text here. (arbitrary html)
-
-
- Insert grading rubric here. (arbitrary html)
-
-
- Please enter a hint below: (arbitrary html)
-
-
- Thanks for submitting! (arbitrary html)
-
-
- """
-
- # Load instance state
- if instance_state is not None:
- log.debug(instance_state)
- instance_state = json.loads(instance_state)
- 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
- self.history = instance_state.get('history', [])
-
- self.state = instance_state.get('state', 'initial')
-
- self.created = instance_state.get('created', "False")
-
- self.attempts = instance_state.get('attempts', 0)
- self.max_attempts = int(instance_state.get('attempts', MAX_ATTEMPTS))
-
- # Used for progress / grading. Currently get credit just for
- # completion (doesn't matter if you self-assessed correct/incorrect).
- self._max_score = int(instance_state.get('max_score', MAX_SCORE))
+class OpenEndedModule(openendedchild.OpenEndedChild):
+ def setup_response(self, system, location, definition, descriptor):
oeparam = definition['oeparam']
prompt = definition['prompt']
rubric = definition['rubric']
@@ -179,7 +100,7 @@ class OpenEndedModule():
self.initial_display = find_with_default(oeparam, 'initial_display', '')
self.answer = find_with_default(oeparam, 'answer_display', 'No answer given.')
-
+
parsed_grader_payload.update({
'location' : system.location.url(),
'course_id' : system.course_id,
diff --git a/common/lib/xmodule/xmodule/openendedchild.py b/common/lib/xmodule/xmodule/openendedchild.py
new file mode 100644
index 0000000000..b8162800a9
--- /dev/null
+++ b/common/lib/xmodule/xmodule/openendedchild.py
@@ -0,0 +1,130 @@
+"""
+A Self Assessment module that allows students to write open-ended responses,
+submit, then see a rubric and rate themselves. Persists student supplied
+hints, answers, and assessment judgment (currently only correct/incorrect).
+Parses xml definition file--see below for exact format.
+"""
+
+import copy
+from fs.errors import ResourceNotFoundError
+import itertools
+import json
+import logging
+from lxml import etree
+from lxml.html import rewrite_links
+from path import path
+import os
+import sys
+import hashlib
+import capa.xqueue_interface as xqueue_interface
+
+from pkg_resources import resource_string
+
+from .capa_module import only_one, ComplexEncoder
+from .editing_module import EditingDescriptor
+from .html_checker import check_html
+from progress import Progress
+from .stringify import stringify_children
+from .xml_module import XmlDescriptor
+from xmodule.modulestore import Location
+from capa.util import *
+
+from datetime import datetime
+
+log = logging.getLogger("mitx.courseware")
+
+# Set the default number of max attempts. Should be 1 for production
+# Set higher for debugging/testing
+# attempts specified in xml definition overrides this.
+MAX_ATTEMPTS = 1
+
+# Set maximum available number of points.
+# Overriden by max_score specified in xml.
+MAX_SCORE = 1
+
+class OpenEndedChild():
+ """
+ States:
+
+ initial (prompt, textbox shown)
+ |
+ assessing (read-only textbox, rubric + assessment input shown)
+ |
+ request_hint (read-only textbox, read-only rubric and assessment, hint input box shown)
+ |
+ done (submitted msg, green checkmark, everything else read-only. If attempts < max, shows
+ a reset button that goes back to initial state. Saves previous
+ submissions too.)
+ """
+
+ DEFAULT_QUEUE = 'open-ended'
+ DEFAULT_MESSAGE_QUEUE = 'open-ended-message'
+ max_inputfields = 1
+
+ STATE_VERSION = 1
+
+ # states
+ INITIAL = 'initial'
+ ASSESSING = 'assessing'
+ POST_ASSESSMENT = 'post_assessment'
+ DONE = 'done'
+
+ def __init__(self, system, location, definition, descriptor,
+ instance_state=None, shared_state=None, **kwargs):
+ """
+ Definition file should have 4 blocks -- prompt, rubric, submitmessage, hintprompt,
+ and two optional attributes:
+ attempts, which should be an integer that defaults to 1.
+ If it's > 1, the student will be able to re-submit after they see
+ the rubric.
+ max_score, which should be an integer that defaults to 1.
+ It defines the maximum number of points a student can get. Assumed to be integer scale
+ from 0 to max_score, with an interval of 1.
+
+ Note: all the submissions are stored.
+
+ Sample file:
+
+
+
+ Insert prompt text here. (arbitrary html)
+
+
+ Insert grading rubric here. (arbitrary html)
+
+
+ Please enter a hint below: (arbitrary html)
+
+
+ Thanks for submitting! (arbitrary html)
+
+
+ """
+
+ # Load instance state
+ if instance_state is not None:
+ instance_state = json.loads(instance_state)
+ 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
+ self.history = instance_state.get('history', [])
+
+ self.state = instance_state.get('state', 'initial')
+
+ self.created = instance_state.get('created', "False")
+
+ self.attempts = instance_state.get('attempts', 0)
+ self.max_attempts = int(instance_state.get('attempts', MAX_ATTEMPTS))
+
+ # Used for progress / grading. Currently get credit just for
+ # completion (doesn't matter if you self-assessed correct/incorrect).
+ self._max_score = int(instance_state.get('max_score', MAX_SCORE))
+
+ self.setup_response(system, location, definition, descriptor)
+
+ def setup_response(self, system, location, definition, descriptor):
+ pass
\ No newline at end of file
diff --git a/common/lib/xmodule/xmodule/self_assessment_module.py b/common/lib/xmodule/xmodule/self_assessment_module.py
index 64edb2bb8a..6c064bebf8 100644
--- a/common/lib/xmodule/xmodule/self_assessment_module.py
+++ b/common/lib/xmodule/xmodule/self_assessment_module.py
@@ -26,6 +26,7 @@ from .stringify import stringify_children
from .x_module import XModule
from .xml_module import XmlDescriptor
from xmodule.modulestore import Location
+import openendedchild
log = logging.getLogger("mitx.courseware")
@@ -38,92 +39,14 @@ MAX_ATTEMPTS = 1
# Overriden by max_score specified in xml.
MAX_SCORE = 1
-class SelfAssessmentModule():
- """
- States:
-
- initial (prompt, textbox shown)
- |
- assessing (read-only textbox, rubric + assessment input shown)
- |
- request_hint (read-only textbox, read-only rubric and assessment, hint input box shown)
- |
- done (submitted msg, green checkmark, everything else read-only. If attempts < max, shows
- a reset button that goes back to initial state. Saves previous
- submissions too.)
- """
-
- STATE_VERSION = 1
-
- # states
- INITIAL = 'initial'
- ASSESSING = 'assessing'
- REQUEST_HINT = 'post_assessment'
- DONE = 'done'
-
- def __init__(self, system, location, definition, descriptor,
- instance_state=None, shared_state=None, **kwargs):
- """
- Definition file should have 4 blocks -- prompt, rubric, submitmessage, hintprompt,
- and two optional attributes:
- attempts, which should be an integer that defaults to 1.
- If it's > 1, the student will be able to re-submit after they see
- the rubric.
- max_score, which should be an integer that defaults to 1.
- It defines the maximum number of points a student can get. Assumed to be integer scale
- from 0 to max_score, with an interval of 1.
-
- Note: all the submissions are stored.
-
- Sample file:
-
-
-
- Insert prompt text here. (arbitrary html)
-
-
- Insert grading rubric here. (arbitrary html)
-
-
- Please enter a hint below: (arbitrary html)
-
-
- Thanks for submitting! (arbitrary html)
-
-
- """
-
- # Load instance state
- if instance_state is not None:
- instance_state = json.loads(instance_state)
- else:
- instance_state = {}
-
- instance_state = self.convert_state_to_current_format(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
- self.history = instance_state.get('history', [])
-
- self.created = instance_state.get('created', "False")
-
- self.state = instance_state.get('state', 'initial')
-
- self.attempts = instance_state.get('attempts', 0)
- self.max_attempts = int(instance_state.get('attempts', MAX_ATTEMPTS))
-
- # Used for progress / grading. Currently get credit just for
- # completion (doesn't matter if you self-assessed correct/incorrect).
- self._max_score = int(instance_state.get('max_score', MAX_SCORE))
+class SelfAssessmentModule(openendedchild.OpenEndedChild):
+ def setup_response(self, system, location, definition, descriptor):
self.rubric = definition['rubric']
self.prompt = definition['prompt']
self.submit_message = definition['submitmessage']
self.hint_prompt = definition['hintprompt']
-
def latest_answer(self):
"""None if not available"""
if not self.history:
diff --git a/lms/templates/combined_open_ended.html b/lms/templates/combined_open_ended.html
index 5b6823e809..a050dad906 100644
--- a/lms/templates/combined_open_ended.html
+++ b/lms/templates/combined_open_ended.html
@@ -6,5 +6,8 @@
+
+
${status | n}
+
diff --git a/lms/templates/combined_open_ended_status.html b/lms/templates/combined_open_ended_status.html
new file mode 100644
index 0000000000..770870b077
--- /dev/null
+++ b/lms/templates/combined_open_ended_status.html
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file