예제 #1
0
class WordCloudFields(object):
    """XFields for word cloud."""
    num_inputs = Integer(
        display_name="Inputs",
        help=
        "Number of text boxes available for students to input words/sentences.",
        scope=Scope.settings,
        default=5,
        values={"min": 1})
    num_top_words = Integer(
        display_name="Maximum Words",
        help="Maximum number of words to be displayed in generated word cloud.",
        scope=Scope.settings,
        default=250,
        values={"min": 1})
    display_student_percents = Boolean(
        display_name="Show Percents",
        help="Statistics are shown for entered words near that word.",
        scope=Scope.settings,
        default=True)

    # Fields for descriptor.
    submitted = Boolean(
        help="Whether this student has posted words to the cloud.",
        scope=Scope.user_state,
        default=False)
    student_words = List(help="Student answer.",
                         scope=Scope.user_state,
                         default=[])
    all_words = Dict(help="All possible words from all students.",
                     scope=Scope.content)
    top_words = Dict(help="Top num_top_words words for word cloud.",
                     scope=Scope.content)
예제 #2
0
class WordCloudFields(object):
    """XFields for word cloud."""
    display_name = String(help="Display name for this module",
                          scope=Scope.settings)
    num_inputs = Integer(help="Number of inputs.",
                         scope=Scope.settings,
                         default=5)
    num_top_words = Integer(
        help="Number of max words, which will be displayed.",
        scope=Scope.settings,
        default=250)
    display_student_percents = Boolean(
        help="Display usage percents for each word?",
        scope=Scope.settings,
        default=True)

    # Fields for descriptor.
    submitted = Boolean(
        help="Whether this student has posted words to the cloud.",
        scope=Scope.user_state,
        default=False)
    student_words = List(help="Student answer.",
                         scope=Scope.user_state,
                         default=[])
    all_words = Object(help="All possible words from all students.",
                       scope=Scope.content)
    top_words = Object(help="Top num_top_words words for word cloud.",
                       scope=Scope.content)
예제 #3
0
class FolditFields(object):
    # default to what Spring_7012x uses
    required_level = Integer(default=4, scope=Scope.settings)
    required_sublevel = Integer(default=5, scope=Scope.settings)
    due = Date(help="Date that this problem is due by", scope=Scope.settings)

    show_basic_score = String(scope=Scope.settings, default='false')
    show_leaderboard = String(scope=Scope.settings, default='false')
예제 #4
0
파일: test_core.py 프로젝트: metajon/XBlock
def test_field_name_defaults():
    # Tests field display name default values
    attempts = Integer()
    attempts._name = "max_problem_attempts"
    assert_equals('max_problem_attempts', attempts.display_name)

    class NamespaceTestClass(Namespace):
        """Toy class for Namespace testing"""
        field_x = List()

    assert_equals("field_x", NamespaceTestClass.field_x.display_name)
예제 #5
0
파일: test_core.py 프로젝트: metajon/XBlock
def test_field_display_name():
    attempts = Integer(display_name='Maximum Problem Attempts')
    attempts._name = "max_problem_attempts"
    assert_equals("Maximum Problem Attempts", attempts.display_name)

    boolean_field = Boolean(display_name="boolean field")
    assert_equals("boolean field", boolean_field.display_name)

    class NamespaceTestClass(Namespace):
        """Toy class for Namespace testing"""
        field_x = List(display_name="Field Known as X")

    assert_equals("Field Known as X", NamespaceTestClass.field_x.display_name)
class VideoFields(object):
    """Fields for `VideoModule` and `VideoDescriptor`."""
    display_name = String(
        display_name="Display Name",
        help="This name appears in the horizontal navigation at the top of the page.",
        scope=Scope.settings,
        # it'd be nice to have a useful default but it screws up other things; so,
        # use display_name_with_default for those
        default="Video"
    )
    data = String(
        help="XML data for the problem",
        default='',
        scope=Scope.content
    )
    position = Integer(help="Current position in the video", scope=Scope.user_state, default=0)
    show_captions = Boolean(help="This controls whether or not captions are shown by default.", display_name="Show Captions", scope=Scope.settings, default=True)
    youtube_id_1_0 = String(help="This is the Youtube ID reference for the normal speed video.", display_name="Default Speed", scope=Scope.settings, default="OEoXaMPEzfM")
    youtube_id_0_75 = String(help="The Youtube ID for the .75x speed video.", display_name="Speed: .75x", scope=Scope.settings, default="")
    youtube_id_1_25 = String(help="The Youtube ID for the 1.25x speed video.", display_name="Speed: 1.25x", scope=Scope.settings, default="")
    youtube_id_1_5 = String(help="The Youtube ID for the 1.5x speed video.", display_name="Speed: 1.5x", scope=Scope.settings, default="")
    start_time = Float(help="Time the video starts", display_name="Start Time", scope=Scope.settings, default=0.0)
    end_time = Float(help="Time the video ends", display_name="End Time", scope=Scope.settings, default=0.0)
    source = String(help="The external URL to download the video. This appears as a link beneath the video.", display_name="Download Video", scope=Scope.settings, default="")
    track = String(help="The external URL to download the subtitle track. This appears as a link beneath the video.", display_name="Download Track", scope=Scope.settings, default="")
예제 #7
0
class CrowdsourceHinterFields(object):
    """Defines fields for the crowdsource hinter module."""
    has_children = True

    moderate = String(help='String "True"/"False" - activates moderation',
                      scope=Scope.content,
                      default='False')
    debug = String(help='String "True"/"False" - allows multiple voting',
                   scope=Scope.content,
                   default='False')
    # Usage: hints[answer] = {str(pk): [hint_text, #votes]}
    # hints is a dictionary that takes answer keys.
    # Each value is itself a dictionary, accepting hint_pk strings as keys,
    # and returning [hint text, #votes] pairs as values
    hints = Dict(help='A dictionary containing all the active hints.',
                 scope=Scope.content,
                 default={})
    mod_queue = Dict(
        help='A dictionary containing hints still awaiting approval',
        scope=Scope.content,
        default={})
    hint_pk = Integer(help='Used to index hints.',
                      scope=Scope.content,
                      default=0)
    # A list of previous answers this student made to this problem.
    # Of the form [answer, [hint_pk_1, hint_pk_2, hint_pk_3]] for each problem.  hint_pk's are
    # None if the hint was not given.
    previous_answers = List(help='A list of previous submissions.',
                            scope=Scope.user_state,
                            default=[])
    user_voted = Boolean(
        help='Specifies if the user has voted on this problem or not.',
        scope=Scope.user_state,
        default=False)
예제 #8
0
class VideoAlphaFields(object):
    data = String(help="XML data for the problem", scope=Scope.content)
    position = Integer(help="Current position in the video",
                       scope=Scope.user_state,
                       default=0)
    display_name = String(help="Display name for this module",
                          scope=Scope.settings)
예제 #9
0
class SequenceFields(object):
    has_children = True

    # NOTE: Position is 1-indexed.  This is silly, but there are now student
    # positions saved on prod, so it's not easy to fix.
    position = Integer(help="Last tab viewed in this sequence",
                       scope=Scope.user_state)
예제 #10
0
class PeerGradingFields(object):
    use_for_single_location = Boolean(
        display_name="Show Single Problem",
        help='When True, only the single problem specified by "Link to Problem Location" is shown. '
             'When False, a panel is displayed with all problems available for peer grading.',
        default=USE_FOR_SINGLE_LOCATION, scope=Scope.settings
    )
    link_to_location = String(
        display_name="Link to Problem Location",
        help='The location of the problem being graded. Only used when "Show Single Problem" is True.',
        default=LINK_TO_LOCATION, scope=Scope.settings
    )
    is_graded = Boolean(
        display_name="Graded",
        help='Defines whether the student gets credit for grading this problem. Only used when "Show Single Problem" is True.',
        default=IS_GRADED, scope=Scope.settings
    )
    due_date = Date(help="Due date that should be displayed.", default=None, scope=Scope.settings)
    grace_period_string = String(help="Amount of grace to give on the due date.", default=None, scope=Scope.settings)
    max_grade = Integer(
        help="The maximum grade that a student can receive for this problem.", default=MAX_SCORE,
        scope=Scope.settings, values={"min": 0}
    )
    student_data_for_location = Dict(
        help="Student data for a given peer grading problem.",
        scope=Scope.user_state
    )
    weight = Float(
        display_name="Problem Weight",
        help="Defines the number of points each problem is worth. If the value is not set, each problem is worth one point.",
        scope=Scope.settings, values={"min": 0, "step": ".1"}
    )
예제 #11
0
class CrowdsourceHinterFields(object):
    """Defines fields for the crowdsource hinter module."""
    has_children = True

    moderate = String(help='String "True"/"False" - activates moderation', scope=Scope.content,
                      default='False')
    debug = String(help='String "True"/"False" - allows multiple voting', scope=Scope.content,
                   default='False')
    # Usage: hints[answer] = {str(pk): [hint_text, #votes]}
    # hints is a dictionary that takes answer keys.
    # Each value is itself a dictionary, accepting hint_pk strings as keys,
    # and returning [hint text, #votes] pairs as values
    hints = Dict(help='A dictionary containing all the active hints.', scope=Scope.content, default={})
    mod_queue = Dict(help='A dictionary containing hints still awaiting approval', scope=Scope.content,
                     default={})
    hint_pk = Integer(help='Used to index hints.', scope=Scope.content, default=0)

    # A list of previous hints that a student viewed.
    # Of the form [answer, [hint_pk_1, ...]] for each problem.
    # Sorry about the variable name - I know it's confusing.
    previous_answers = List(help='A list of hints viewed.', scope=Scope.user_state, default=[])

    # user_submissions actually contains a list of previous answers submitted.
    # (Originally, preivous_answers did this job, hence the name confusion.)
    user_submissions = List(help='A list of previous submissions', scope=Scope.user_state, default=[])
    user_voted = Boolean(help='Specifies if the user has voted on this problem or not.',
                         scope=Scope.user_state, default=False)
예제 #12
0
class Slider(XBlock):
    min_value = Integer(help="Minimum value", default=0, scope=Scope.content)
    max_value = Integer(help="Maximum value", default=100, scope=Scope.content)
    value = Integer(help="Student value", default=0, scope=Scope.user_state)

    def student_view(self, context):
        html = SLIDER_TEMPLATE.format(min=self.min_value,
                                      max=self.max_value,
                                      val=self.value)
        frag = Fragment(html)
        frag.add_css("input[type=range] { width=100px; }")
        frag.add_javascript(SLIDER_JS)
        frag.initialize_js('Slider')

        return frag

    def update(self, request):
        data = json.loads(request.body)
        self.value = int(data['value'])
        return Response()
예제 #13
0
class VideoFields(object):
    """Fields for `VideoModule` and `VideoDescriptor`."""
    position = Integer(help="Current position in the video",
                       scope=Scope.user_state,
                       default=0)
    show_captions = Boolean(
        help="This controls whether or not captions are shown by default.",
        display_name="Show Captions",
        scope=Scope.settings,
        default=True)
    youtube_id_1_0 = String(
        help="This is the Youtube ID reference for the normal speed video.",
        display_name="Default Speed",
        scope=Scope.settings,
        default="OEoXaMPEzfM")
    youtube_id_0_75 = String(help="The Youtube ID for the .75x speed video.",
                             display_name="Speed: .75x",
                             scope=Scope.settings,
                             default="")
    youtube_id_1_25 = String(help="The Youtube ID for the 1.25x speed video.",
                             display_name="Speed: 1.25x",
                             scope=Scope.settings,
                             default="")
    youtube_id_1_5 = String(help="The Youtube ID for the 1.5x speed video.",
                            display_name="Speed: 1.5x",
                            scope=Scope.settings,
                            default="")
    start_time = Float(help="Time the video starts",
                       display_name="Start Time",
                       scope=Scope.settings,
                       default=0.0)
    end_time = Float(help="Time the video ends",
                     display_name="End Time",
                     scope=Scope.settings,
                     default=0.0)
    source = String(
        help=
        "The external URL to download the video. This appears as a link beneath the video.",
        display_name="Download Video",
        scope=Scope.settings,
        default="")
    track = String(
        help=
        "The external URL to download the subtitle track. This appears as a link beneath the video.",
        display_name="Download Track",
        scope=Scope.settings,
        default="")
class VideoAlphaFields(object):
    """Fields for `VideoAlphaModule` and `VideoAlphaDescriptor`."""
    data = String(help="XML data for the problem",
                  default=textwrap.dedent('''\
                       <videoalpha show_captions="true" sub="name_of_file" youtube="0.75:JMD_ifUUfsU,1.0:OEoXaMPEzfM,1.25:AKqURZnYqpk,1.50:DYpADpL7jAY" >
                           <source src="https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.mp4"/>
                           <source src="https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.webm"/>
                           <source src="https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.ogv"/>
                       </videoalpha>'''),
                  scope=Scope.content)
    position = Integer(help="Current position in the video",
                       scope=Scope.user_state,
                       default=0)
    display_name = String(display_name="Display Name",
                          help="Display name for this module",
                          default="Video Alpha",
                          scope=Scope.settings)
예제 #15
0
class VideoFields(object):
    """Fields for `VideoModule` and `VideoDescriptor`."""
    data = String(help="通过编辑XML数据来给定视频参数和信息", scope=Scope.content, default="")
    position = Integer(help="当前视频中的位置", scope=Scope.user_state, default=0)
    source = String(
        help=
        '视频的URL地址,支持mp4/m4v/webm/ogv/flv, 支持 <button class="button upload-button" onclick="openwin($(this).parent().prev().children().eq(1).attr('
        + "'id'" + '));">上传视频</button>',
        display_name="视频地址",
        scope=Scope.settings,
        default="")
    track_zh = String(help="中文字幕的上传路径,字幕将显示在视频底部,支持srt/vtt",
                      display_name="视频字幕 (中文)",
                      scope=Scope.settings,
                      default="")
    track_en = String(help="英文字幕的上传路径,字幕将显示在视频底部,支持srt/vtt",
                      display_name="视频字幕 (英文)",
                      scope=Scope.settings,
                      default="")
예제 #16
0
class TestFields(object):
    # Will be returned by editable_metadata_fields.
    max_attempts = Integer(scope=Scope.settings,
                           default=1000,
                           values={
                               'min': 1,
                               'max': 10
                           })
    # Will not be returned by editable_metadata_fields because filtered out by non_editable_metadata_fields.
    due = Date(scope=Scope.settings)
    # Will not be returned by editable_metadata_fields because is not Scope.settings.
    student_answers = Dict(scope=Scope.user_state)
    # Will be returned, and can override the inherited value from XModule.
    display_name = String(scope=Scope.settings,
                          default='local default',
                          display_name='Local Display Name',
                          help='local help')
    # Used for testing select type, effect of to_json method
    string_select = CrazyJsonString(scope=Scope.settings,
                                    default='default value',
                                    values=[{
                                        'display_name': 'first',
                                        'value': 'value a'
                                    }, {
                                        'display_name': 'second',
                                        'value': 'value b'
                                    }])
    # Used for testing select type
    float_select = Float(scope=Scope.settings,
                         default=.999,
                         values=[1.23, 0.98])
    # Used for testing float type
    float_non_select = Float(scope=Scope.settings,
                             default=.999,
                             values={
                                 'min': 0,
                                 'step': .3
                             })
    # Used for testing that Booleans get mapped to select type
    boolean_select = Boolean(scope=Scope.settings)
    # Used for testing Lists
    list_field = List(scope=Scope.settings, default=[])
예제 #17
0
class RandomizeFields(object):
    choice = Integer(help="Which random child was chosen",
                     scope=Scope.user_state)
예제 #18
0
class VideoFields(object):
    """Fields for `VideoModule` and `VideoDescriptor`."""
    data = String(help="XML data for the problem", scope=Scope.content)
    position = Integer(help="Current position in the video",
                       scope=Scope.user_state,
                       default=0)
예제 #19
0
class ThumbsBlock(InputBlock):
    """
    An XBlock with thumbs-up/thumbs-down voting.

    Vote totals are stored for all students to see.  Each student is recorded
    as has-voted or not.

    This demonstrates multiple data scopes and ajax handlers.

    """

    upvotes = Integer(help="Number of up votes",
                      default=0,
                      scope=Scope.content)
    downvotes = Integer(help="Number of down votes",
                        default=0,
                        scope=Scope.content)
    voted = Boolean(help="Has this student voted?",
                    default=False,
                    scope=Scope.user_state)

    def student_view(self, context):
        frag = Fragment(u"""
            <p>
                <span class='upvote'><span class='count'>{self.upvotes}</span>&uarr;</span>
                <span class='downvote'><span class='count'>{self.downvotes}</span>&darr;</span>
            </p>
            """.format(self=self))
        frag.add_css("""
            .upvote, .downvote {
                cursor: pointer;
                border: 1px solid #888;
                padding: 0 .5em;
            }
            .upvote { color: green; }
            .downvote { color: red; }
            """)
        frag.add_javascript("""
            function ThumbsBlock(runtime, element) {
                function update_votes(votes) {
                    $('.upvote .count', element).text(votes.up);
                    $('.downvote .count', element).text(votes.down);
                }

                var handler_url = runtime.handler_url('vote');

                $('.upvote', element).bind('click.ThumbsBlock.up', function() {
                    $.post(handler_url, JSON.stringify({vote_type: 'up'})).success(update_votes);
                });

                $('.downvote', element).bind('click.ThumbsBlock.up', function() {
                    $.post(handler_url, JSON.stringify({vote_type: 'down'})).success(update_votes);
                });
            };
            """)
        frag.initialize_js('ThumbsBlock')
        return frag

    problem_view = student_view

    @XBlock.json_handler
    def vote(self, data):
        # Here is where we would prevent a student from voting twice, but then
        # we couldn't click more than once in the demo!
        #
        # if self.student.voted:
        #    log.error("cheater!")
        #    return
        if data['vote_type'] not in ('up', 'down'):
            log.error('error!')
            return

        if data['vote_type'] == 'up':
            self.upvotes += 1
        else:
            self.downvotes += 1

        self.voted = True

        return {'up': self.upvotes, 'down': self.downvotes}

    @staticmethod
    def workbench_scenarios():
        """A canned scenario for display in the workbench."""
        return [("three thumbs at once", """\
                <vertical>
                    <thumbs/>
                    <thumbs/>
                    <thumbs/>
                </vertical>
             """)]
예제 #20
0
class CapaFields(object):
    """
    Define the possible fields for a Capa problem
    """
    display_name = String(
        display_name="Display Name",
        help=
        "This name appears in the horizontal navigation at the top of the page.",
        scope=Scope.settings,
        # it'd be nice to have a useful default but it screws up other things; so,
        # use display_name_with_default for those
        default="Blank Advanced Problem")
    attempts = Integer(
        help="Number of attempts taken by the student on this problem",
        default=0,
        scope=Scope.user_state)
    max_attempts = Integer(
        display_name="Maximum Attempts",
        help=
        ("Defines the number of times a student can try to answer this problem. "
         "If the value is not set, infinite attempts are allowed."),
        values={"min": 0},
        scope=Scope.settings)
    due = Date(help="Date that this problem is due by", scope=Scope.settings)
    graceperiod = Timedelta(
        help=
        "Amount of time after the due date that submissions will be accepted",
        scope=Scope.settings)
    showanswer = String(
        display_name="Show Answer",
        help=("Defines when to show the answer to the problem. "
              "A default value can be set in Advanced Settings."),
        scope=Scope.settings,
        default="finished",
        values=[{
            "display_name": "Always",
            "value": "always"
        }, {
            "display_name": "Answered",
            "value": "answered"
        }, {
            "display_name": "Attempted",
            "value": "attempted"
        }, {
            "display_name": "Closed",
            "value": "closed"
        }, {
            "display_name": "Finished",
            "value": "finished"
        }, {
            "display_name": "Past Due",
            "value": "past_due"
        }, {
            "display_name": "Never",
            "value": "never"
        }])
    force_save_button = Boolean(
        help="Whether to force the save button to appear on the page",
        scope=Scope.settings,
        default=False)
    rerandomize = Randomization(
        display_name="Randomization",
        help=
        "Defines how often inputs are randomized when a student loads the problem. "
        "This setting only applies to problems that can have randomly generated numeric values. "
        "A default value can be set in Advanced Settings.",
        default="never",
        scope=Scope.settings,
        values=[{
            "display_name": "Always",
            "value": "always"
        }, {
            "display_name": "On Reset",
            "value": "onreset"
        }, {
            "display_name": "Never",
            "value": "never"
        }, {
            "display_name": "Per Student",
            "value": "per_student"
        }])
    data = String(help="XML data for the problem",
                  scope=Scope.content,
                  default="<problem></problem>")
    correct_map = Dict(
        help="Dictionary with the correctness of current student answers",
        scope=Scope.user_state,
        default={})
    input_state = Dict(
        help="Dictionary for maintaining the state of inputtypes",
        scope=Scope.user_state)
    student_answers = Dict(
        help="Dictionary with the current student responses",
        scope=Scope.user_state)
    done = Boolean(help="Whether the student has answered the problem",
                   scope=Scope.user_state)
    seed = Integer(help="Random seed for this student", scope=Scope.user_state)
    weight = Float(
        display_name="Problem Weight",
        help=
        ("Defines the number of points each problem is worth. "
         "If the value is not set, each response field in the problem is worth one point."
         ),
        values={
            "min": 0,
            "step": .1
        },
        scope=Scope.settings)
    markdown = String(help="Markdown source of this module",
                      default=None,
                      scope=Scope.settings)
    source_code = String(
        help=
        "Source code for LaTeX and Word problems. This feature is not well-supported.",
        scope=Scope.settings)
예제 #21
0
class ThumbsBlock(InputBlock):
    """
    An XBlock with thumbs-up/thumbs-down voting.

    Vote totals are stored for all students to see.  Each student is recorded
    as has-voted or not.

    This demonstrates multiple data scopes and ajax handlers.

    """

    upvotes = Integer(help="Number of up votes",
                      default=0,
                      scope=Scope.content)
    downvotes = Integer(help="Number of down votes",
                        default=0,
                        scope=Scope.content)
    voted = Boolean(help="Has this student voted?",
                    default=False,
                    scope=Scope.user_state)

    def student_view(self, context):
        """
        Create a fragment used to display the XBlock to a student.
        `context` is a dictionary used to configure the display (unused)

        Returns a `Fragment` object specifying the HTML, CSS, and JavaScript
        to display.
        """

        # Load the HTML fragment from within the package and fill in the template
        html_str = pkg_resources.resource_string(__name__,
                                                 "static/html/thumbs.html")
        frag = Fragment(unicode(html_str).format(self=self))

        # Load the CSS and JavaScript fragments from within the package
        css_str = pkg_resources.resource_string(__name__,
                                                "static/css/thumbs.css")
        frag.add_css(unicode(css_str))

        js_str = pkg_resources.resource_string(__name__,
                                               "static/js/src/thumbs.js")
        frag.add_javascript(unicode(js_str))

        frag.initialize_js('ThumbsBlock')
        return frag

    problem_view = student_view

    @XBlock.json_handler
    def vote(self, data):
        """ Update the vote count in response to a user action. """
        # Here is where we would prevent a student from voting twice, but then
        # we couldn't click more than once in the demo!
        #
        # if self.student.voted:
        #    log.error("cheater!")
        #    return
        if data['vote_type'] not in ('up', 'down'):
            log.error('error!')
            return

        if data['vote_type'] == 'up':
            self.upvotes += 1
        else:
            self.downvotes += 1

        self.voted = True

        return {'up': self.upvotes, 'down': self.downvotes}

    @staticmethod
    def workbench_scenarios():
        """A canned scenario for display in the workbench."""
        return [("three thumbs at once", """\
                <vertical>
                    <thumbs/>
                    <thumbs/>
                    <thumbs/>
                </vertical>
             """)]
예제 #22
0
class VideoFields(object):
    """Fields for `VideoModule` and `VideoDescriptor`."""
    display_name = String(display_name="Display Name",
                          help="Display name for this module.",
                          default="Video",
                          scope=Scope.settings)
    position = Integer(help="Current position in the video",
                       scope=Scope.user_state,
                       default=0)
    show_captions = Boolean(
        help="This controls whether or not captions are shown by default.",
        display_name="Show Captions",
        scope=Scope.settings,
        default=True)
    # TODO: This should be moved to Scope.content, but this will
    # require data migration to support the old video module.
    youtube_id_1_0 = String(
        help="This is the Youtube ID reference for the normal speed video.",
        display_name="Youtube ID",
        scope=Scope.settings,
        default="OEoXaMPEzfM")
    youtube_id_0_75 = String(help="The Youtube ID for the .75x speed video.",
                             display_name="Youtube ID for .75x speed",
                             scope=Scope.settings,
                             default="")
    youtube_id_1_25 = String(help="The Youtube ID for the 1.25x speed video.",
                             display_name="Youtube ID for 1.25x speed",
                             scope=Scope.settings,
                             default="")
    youtube_id_1_5 = String(help="The Youtube ID for the 1.5x speed video.",
                            display_name="Youtube ID for 1.5x speed",
                            scope=Scope.settings,
                            default="")
    start_time = Float(help="Start time for the video.",
                       display_name="Start Time",
                       scope=Scope.settings,
                       default=0.0)
    end_time = Float(help="End time for the video.",
                     display_name="End Time",
                     scope=Scope.settings,
                     default=0.0)
    source = String(
        help=
        "The external URL to download the video. This appears as a link beneath the video.",
        display_name="Download Video",
        scope=Scope.settings,
        default="")
    html5_sources = List(
        help=
        "A list of filenames to be used with HTML5 video. The first supported filetype will be displayed.",
        display_name="Video Sources",
        scope=Scope.settings,
        default=[])
    track = String(
        help=
        "The external URL to download the subtitle track. This appears as a link beneath the video.",
        display_name="Download Track",
        scope=Scope.settings,
        default="")
    sub = String(
        help="The name of the subtitle track (for non-Youtube videos).",
        display_name="HTML5 Subtitles",
        scope=Scope.settings,
        default="")
class CombinedOpenEndedFields(object):
    display_name = String(
        display_name="Display Name",
        help=
        "This name appears in the horizontal navigation at the top of the page.",
        default="Open Ended Grading",
        scope=Scope.settings)
    current_task_number = Integer(help="Current task that the student is on.",
                                  default=0,
                                  scope=Scope.user_state)
    task_states = List(
        help="List of state dictionaries of each task within this module.",
        scope=Scope.user_state)
    state = String(
        help="Which step within the current task that the student is on.",
        default="initial",
        scope=Scope.user_state)
    student_attempts = Integer(
        help="Number of attempts taken by the student on this problem",
        default=0,
        scope=Scope.user_state)
    ready_to_reset = Boolean(
        help="If the problem is ready to be reset or not.",
        default=False,
        scope=Scope.user_state)
    attempts = Integer(
        display_name="Maximum Attempts",
        help="The number of times the student can try to answer this problem.",
        default=1,
        scope=Scope.settings,
        values={"min": 1})
    is_graded = Boolean(display_name="Graded",
                        help="Whether or not the problem is graded.",
                        default=False,
                        scope=Scope.settings)
    accept_file_upload = Boolean(
        display_name="Allow File Uploads",
        help="Whether or not the student can submit files as a response.",
        default=False,
        scope=Scope.settings)
    skip_spelling_checks = Boolean(
        display_name="Disable Quality Filter",
        help=
        "If False, the Quality Filter is enabled and submissions with poor spelling, short length, or poor grammar will not be peer reviewed.",
        default=False,
        scope=Scope.settings)
    due = Date(help="Date that this problem is due by",
               default=None,
               scope=Scope.settings)
    graceperiod = String(
        help=
        "Amount of time after the due date that submissions will be accepted",
        default=None,
        scope=Scope.settings)
    version = VersionInteger(help="Current version number",
                             default=DEFAULT_VERSION,
                             scope=Scope.settings)
    data = String(help="XML data for the problem", scope=Scope.content)
    weight = Float(
        display_name="Problem Weight",
        help=
        "Defines the number of points each problem is worth. If the value is not set, each problem is worth one point.",
        scope=Scope.settings,
        values={
            "min": 0,
            "step": ".1"
        })
    markdown = String(help="Markdown source of this module",
                      scope=Scope.settings)
class CombinedOpenEndedFields(object):
    display_name = String(
        display_name="Display Name",
        help="This name appears in the horizontal navigation at the top of the page.",
        default="Open Response Assessment",
        scope=Scope.settings
    )
    current_task_number = Integer(
        help="Current task that the student is on.",
        default=0,
        scope=Scope.user_state
    )
    task_states = List(
        help="List of state dictionaries of each task within this module.",
        scope=Scope.user_state
    )
    state = String(
        help="Which step within the current task that the student is on.",
        default="initial",
        scope=Scope.user_state
    )
    graded = Boolean(
        display_name="Graded",
        help='Defines whether the student gets credit for grading this problem.',
        default=False,
        scope=Scope.settings
    )
    student_attempts = Integer(
        help="Number of attempts taken by the student on this problem",
        default=0,
        scope=Scope.user_state
    )
    ready_to_reset = Boolean(
        help="If the problem is ready to be reset or not.",
        default=False,
        scope=Scope.user_state
    )
    max_attempts = Integer(
        display_name="Maximum Attempts",
        help="The number of times the student can try to answer this problem.",
        default=1,
        scope=Scope.settings,
        values={"min" : 1 }
    )
    accept_file_upload = Boolean(
        display_name="Allow File Uploads",
        help="Whether or not the student can submit files as a response.",
        default=False,
        scope=Scope.settings
    )
    skip_spelling_checks = Boolean(
        display_name="Disable Quality Filter",
        help="If False, the Quality Filter is enabled and submissions with poor spelling, short length, or poor grammar will not be peer reviewed.",
        default=False,
        scope=Scope.settings
    )
    due = Date(
        help="Date that this problem is due by",
        default=None,
        scope=Scope.settings
    )
    graceperiod = Timedelta(
        help="Amount of time after the due date that submissions will be accepted",
        default=None,
        scope=Scope.settings
    )
    version = VersionInteger(help="Current version number", default=DEFAULT_VERSION, scope=Scope.settings)
    data = String(help="XML data for the problem", scope=Scope.content,
        default=DEFAULT_DATA)
    weight = Float(
        display_name="Problem Weight",
        help="Defines the number of points each problem is worth. If the value is not set, each problem is worth one point.",
        scope=Scope.settings,
        values={"min" : 0 , "step": ".1"},
        default=1
    )
    min_to_calibrate = Integer(
        display_name="Minimum Peer Grading Calibrations",
        help="The minimum number of calibration essays each student will need to complete for peer grading.",
        default=3,
        scope=Scope.settings,
        values={"min" : 1, "max" : 20, "step" : "1"}
    )
    max_to_calibrate = Integer(
        display_name="Maximum Peer Grading Calibrations",
        help="The maximum number of calibration essays each student will need to complete for peer grading.",
        default=6,
        scope=Scope.settings,
        values={"min" : 1, "max" : 20, "step" : "1"}
    )
    peer_grader_count = Integer(
        display_name="Peer Graders per Response",
        help="The number of peers who will grade each submission.",
        default=3,
        scope=Scope.settings,
        values={"min" : 1, "step" : "1", "max" : 5}
    )
    required_peer_grading = Integer(
        display_name="Required Peer Grading",
        help="The number of other students each student making a submission will have to grade.",
        default=3,
        scope=Scope.settings,
        values={"min" : 1, "step" : "1", "max" : 5}
    )
    markdown = String(
        help="Markdown source of this module",
        default=textwrap.dedent("""\
                    [prompt]
                        <h3>Censorship in the Libraries</h3>

                        <p>'All of us can think of a book that we hope none of our children or any other children have taken off the shelf. But if I have the right to remove that book from the shelf -- that work I abhor -- then you also have exactly the same right and so does everyone else. And then we have no books left on the shelf for any of us.' --Katherine Paterson, Author
                        </p>

                        <p>
                        Write a persuasive essay to a newspaper reflecting your vies on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading.
                        </p>
                    [prompt]
                    [rubric]
                    + Ideas
                    - Difficult for the reader to discern the main idea.  Too brief or too repetitive to establish or maintain a focus.
                    - Attempts a main idea.  Sometimes loses focus or ineffectively displays focus.
                    - Presents a unifying theme or main idea, but may include minor tangents.  Stays somewhat focused on topic and task.
                    - Presents a unifying theme or main idea without going off on tangents.  Stays completely focused on topic and task.
                    + Content
                    - Includes little information with few or no details or unrelated details.  Unsuccessful in attempts to explore any facets of the topic.
                    - Includes little information and few or no details.  Explores only one or two facets of the topic.
                    - Includes sufficient information and supporting details. (Details may not be fully developed; ideas may be listed.)  Explores some facets of the topic.
                    - Includes in-depth information and exceptional supporting details that are fully developed.  Explores all facets of the topic.
                    + Organization
                    - Ideas organized illogically, transitions weak, and response difficult to follow.
                    - Attempts to logically organize ideas.  Attempts to progress in an order that enhances meaning, and demonstrates use of transitions.
                    - Ideas organized logically.  Progresses in an order that enhances meaning.  Includes smooth transitions.
                    + Style
                    - Contains limited vocabulary, with many words used incorrectly.  Demonstrates problems with sentence patterns.
                    - Contains basic vocabulary, with words that are predictable and common.  Contains mostly simple sentences (although there may be an attempt at more varied sentence patterns).
                    - Includes vocabulary to make explanations detailed and precise.  Includes varied sentence patterns, including complex sentences.
                    + Voice
                    - Demonstrates language and tone that may be inappropriate to task and reader.
                    - Demonstrates an attempt to adjust language and tone to task and reader.
                    - Demonstrates effective adjustment of language and tone to task and reader.
                    [rubric]
                    [tasks]
                    (Self), ({4-12}AI), ({9-12}Peer)
                    [tasks]

        """),
        scope=Scope.settings
    )
예제 #25
0
class VideoFields(object):
    data = String(help="XML data for the problem", scope=Scope.content)
    position = Integer(help="Current position in the video", scope=Scope.user_state, default=0)