Commit d4b3f1ef by Julian Arni Committed by Carol Tong

New index page for documentation

parent 4955d021
**********************************************
Xml format of conditional module [xmodule]
**********************************************
.. module:: conditional_module
Format description
==================
The main tag of Conditional module input is:
.. code-block:: xml
<conditional> ... </conditional>
``conditional`` can include any number of any xmodule tags (``html``, ``video``, ``poll``, etc.) or ``show`` tags.
conditional tag
---------------
The main container for a single instance of Conditional module. The following attributes can
be specified for this tag::
sources - location id of required modules, separated by ';'
[message | ""] - message for case, where one or more are not passed. Here you can use variable {link}, which generate link to required module.
[completed] - map to `is_completed` module method
[attempted] - map to `is_attempted` module method
[poll_answer] - map to `poll_answer` module attribute
[voted] - map to `voted` module attribute
show tag
--------
Symlink to some set of xmodules. The following attributes can
be specified for this tag::
sources - location id of modules, separated by ';'
Example
=======
Examples of conditional depends on poll
-------------------------------------------
.. code-block:: xml
<conditional sources="i4x://MITx/0.000x/poll_question/first_real_poll_seq_with_reset" poll_answer="man"
message="{link} must be answered for this to become visible.">
<html>
<h2>You see this, cause your vote value for "First question" was "man"</h2>
</html>
</conditional>
Examples of conditional depends on poll (use <show> tag)
-------------------------------------------
.. code-block:: xml
<conditional sources="i4x://MITx/0.000x/poll_question/first_real_poll_seq_with_reset" poll_answer="man"
message="{link} must be answered for this to become visible.">
<html>
<show sources="i4x://MITx/0.000x/problem/test_1; i4x://MITx/0.000x/Video/Avi_resources; i4x://MITx/0.000x/problem/test_1"/>
</html>
</conditional>
Examples of conditional depends on problem
-------------------------------------------
.. code-block:: xml
<conditional sources="i4x://MITx/0.000x/problem/Conditional:lec27_Q1" attempted="True">
<html display_name="HTML for attempted problem">You see this, cause "lec27_Q1" is attempted.</html>
</conditional>
<conditional sources="i4x://MITx/0.000x/problem/Conditional:lec27_Q1" attempted="False">
<html display_name="HTML for not attempted problem">You see this, cause "lec27_Q1" is not attempted.</html>
</conditional>
\ No newline at end of file
###################
Course XML Tutorial
###################
EdX uses an XML format to describe the structure and contents of its courses. While much of this is abstracted away by the Studio authoring interface, it is still helpful to understand how the edX platform renders a course.
This guide was written with the assumption that you've dived straight into the edX platform without necessarily having any prior programming/CS knowledge. It will be especially valuable to you if your course is being authored with XML files rather than Studio -- in which case you're likely using functionality that is not yet fully supported in Studio.
*****
Goals
*****
After reading this, you should be able to:
* Organize your course content into the files and folders the edX platform expects.
* Add new content to a course and make sure it shows up in the courseware.
*Prerequisites:* it would be helpful to know a little bit about xml. Here is a
`simple example <http://www.ultraslavonic.info/intro-to-xml/>`_ if you've never seen it before.
************
Introduction
************
A course is organized hierarchically. We start by describing course-wide parameters, then break the course into chapters, and then go deeper and deeper until we reach a specific pset, video, etc. You could make an analogy to finding a green shirt in your house -> bedroom -> closet -> drawer -> shirts -> green shirt.
We'll begin with a sample course structure as a case study of how XML and files in a course are organized. More technical details will follow, including discussion of some special cases.
**********
Case Study
**********
Let's jump right in by looking at the directory structure of a very simple toy course::
toy/
course/
course.xml
problem/
policies/
roots/
The only top level file is `course.xml`, which should contain one line, looking something like this:
.. code-block:: xml
<course org="edX" course="toy" url_name="2012_Fall"/>
This gives all the information to uniquely identify a particular run of any course -- which organization is producing the course, what the course name is, and what "run" this is, specified via the `url_name` attribute.
Obviously, this doesn't actually specify any of the course content, so we need to find that next. To know where to look, you need to know the standard organizational structure of our system: course elements are uniquely identified by the combination `(category, url_name)`. In this case, we are looking for a `course` element with the `url_name` "2012_Fall". The definition of this element will be in `course/2012_Fall.xml`. Let's look there next::
toy/
course/
2012_Fall.xml # <-- Where we look for category="course", url_name="2012_Fall"
.. code-block:: xml
<!-- Contents of course/2012_Fall.xml -->
<course>
<chapter url_name="Overview">
<videosequence url_name="Toy_Videos">
<problem url_name="warmup"/>
<video url_name="Video_Resources" youtube="1.0:1bK-WdDi6Qw"/>
</videosequence>
<video url_name="Welcome" youtube="1.0:p2Q6BrNhdh8"/>
</chapter>
</course>
Aha. Now we've found some content. We can see that the course is organized hierarchically, in this case with only one chapter, with `url_name` "Overview". The chapter contains a `videosequence` and a `video`, with the sequence containing a problem and another video. When viewed in the courseware, chapters are shown at the top level of the navigation accordion on the left, with any elements directly included in the chapter below.
Looking at this file, we can see the course structure, and the youtube urls for the videos, but what about the "warmup" problem? There is no problem content here! Where should we look? This is a good time to pause and try to answer that question based on our organizational structure above.
As you hopefully guessed, the problem would be in `problem/warmup.xml`. (Note: This tutorial doesn't discuss the xml format for problems -- there are chapters of edx4edx that describe it.) This is an instance of a *pointer tag*: any xml tag with only the category and a url_name attribute will point to the file `{category}/{url_name}.xml`. For example, this means that our toy `course.xml` could have also been written as
.. code-block:: xml
<!-- Contents of course/2012_Fall.xml -->
<course>
<chapter url_name="Overview"/>
</course>
with `chapter/Overview.xml` containing
.. code-block:: xml
<chapter>
<videosequence url_name="Toy_Videos">
<problem url_name="warmup"/>
<video url_name="Video_Resources" youtube="1.0:1bK-WdDi6Qw"/>
</videosequence>
<video url_name="Welcome" youtube="1.0:p2Q6BrNhdh8"/>
</chapter>
In fact, this is the recommended structure for real courses -- putting each chapter into its own file makes it easy to have different people work on each without conflicting or having to merge. Similarly, as sequences get large, it can be handy to split them out as well (in `sequence/{url_name}.xml`, of course).
Note that the `url_name` is only specified once per element -- either the inline definition, or in the pointer tag.
Policy Files
============
We still haven't looked at two of the directories in the top-level listing above: `policies` and `roots`. Let's look at policies next. The policy directory contains one file::
toy/
policies/
2012_Fall.json
and that file is named `{course-url_name}.json`. As you might expect, this file contains a policy for the course. In our example, it looks like this:
.. code-block:: json
{
"course/2012_Fall": {
"graceperiod": "2 days 5 hours 59 minutes 59 seconds",
"start": "2015-07-17T12:00",
"display_name": "Toy Course"
},
"chapter/Overview": {
"display_name": "Overview"
},
"videosequence/Toy_Videos": {
"display_name": "Toy Videos",
"format": "Lecture Sequence"
},
"problem/warmup": {
"display_name": "Getting ready for the semester"
},
"video/Video_Resources": {
"display_name": "Video Resources"
},
"video/Welcome": {
"display_name": "Welcome"
}
}
The policy specifies metadata about the content elements -- things which are not inherent to the definition of the content, but which describe how the content is presented to the user and used in the course. See below for a full list of metadata attributes; as the example shows, they include `display_name`, which is what is shown when this piece of content is referenced or shown in the courseware, and various dates and times, like `start`, which specifies when the content becomes visible to students, and various problem-specific parameters like the allowed number of attempts. One important point is that some metadata is inherited: for example, specifying the start date on the course makes it the default for every element in the course. See below for more details.
It is possible to put metadata directly in the XML, as attributes of the appropriate tag, but using a policy file has two benefits: it puts all the policy in one place, making it easier to check that things like due dates are set properly, and it allows the content definitions to be easily used in another run of the same course, with the same or similar content, but different policy.
Roots
=====
The last directory in the top level listing is `roots`. In our toy course, it contains a single file::
roots/
2012_Fall.xml
This file is identical to the top-level `course.xml`, containing
.. code-block:: xml
<course org="edX" course="toy" url_name="2012_Fall"/>
In fact, the top level `course.xml` is a symbolic link to this file. When there is only one run of a course, the roots directory is not really necessary, and the top-level course.xml file can just specify the `url_name` of the course. However, if we wanted to make a second run of our toy course, we could add another file called, e.g., `roots/2013_Spring.xml`, containing
.. code-block:: xml
<course org="edX" course="toy" url_name="2013_Spring"/>
After creating `course/2013_Spring.xml` with the course structure (possibly as a symbolic link or copy of `course/2012_Fall.xml` if no content was changing), and `policies/2013_Spring.json`, we would have two different runs of the toy course in the course repository. Our build system understands this roots structure, and will build a course package for each root.
.. note::
If you're using a local development environment, make the top level `course.xml` point to the desired root, and check out the repo multiple times if you need multiple runs simultaneously).
That's basically all there is to the organizational structure. Read the next section for details on the tags we support, including some special case tags like `customtag` and `html` invariants, and look at the end for some tips that will make the editing process easier.
****
Tags
****
.. list-table::
:widths: 10 80
:header-rows: 0
* - `abtest`
- Support for A/B testing. TODO: add details..
* - `chapter`
- Top level organization unit of a course. The courseware display code currently expects the top level `course` element to contain only chapters, though there is no philosophical reason why this is required, so we may change it to properly display non-chapters at the top level.
* - `conditional`
- Conditional element, which shows one or more modules only if certain conditions are satisfied.
* - `course`
- Top level tag. Contains everything else.
* - `customtag`
- Render an html template, filling in some parameters, and return the resulting html. See below for details.
* - `discussion`
- Inline discussion forum.
* - `html`
- A reference to an html file.
* - `error`
- Don't put these in by hand :) The internal representation of content that has an error, such as malformed XML or some broken invariant.
* - `problem`
- See elsewhere in edx4edx for documentation on the format.
* - `problemset`
- Logically, a series of related problems. Currently displayed vertically. May contain explanatory html, videos, etc.
* - `sequential`
- A sequence of content, currently displayed with a horizontal list of tabs. If possible, use a more semantically meaningful tag (currently, we only have `videosequence`).
* - `vertical`
- A sequence of content, displayed vertically. Content will be accessed all at once, on the right part of the page. No navigational bar. May have to use browser scroll bars. Content split with separators. If possible, use a more semantically meaningful tag (currently, we only have `problemset`).
* - `video`
- A link to a video, currently expected to be hosted on youtube.
* - `videosequence`
- A sequence of videos. This can contain various non-video content; it just signals to the system that this is logically part of an explanatory sequence of content, as opposed to say an exam sequence.
Container Tags
==============
Container tags include `chapter`, `sequential`, `videosequence`, `vertical`, and `problemset`. They are all specified in the same way in the xml, as shown in the tutorial above.
`course`
========
`course` is also a container, and is similar, with one extra wrinkle: the top level pointer tag *must* have `org` and `course` attributes specified--the organization name, and course name. Note that `course` is referring to the platonic ideal of this course (e.g. "6.002x"), not to any particular run of this course. The `url_name` should be the particular run of this course.
`conditional`
=============
`conditional` is as special kind of container tag as well. Here are two examples:
.. code-block:: xml
<conditional condition="require_completed" required="problem/choiceprob">
<video url_name="secret_video" />
</conditional>
<conditional condition="require_attempted" required="problem/choiceprob&problem/sumprob">
<html url_name="secret_page" />
</conditional>
The condition can be either `require_completed`, in which case the required modules must be completed, or `require_attempted`, in which case the required modules must have been attempted.
The required modules are specified as a set of `tag`/`url_name`, joined by an ampersand.
`customtag`
===========
When we see:
.. code-block:: xml
<customtag impl="special" animal="unicorn" hat="blue"/>
We will:
#. Look for a file called `custom_tags/special` in your course dir.
#. Render it as a mako template, passing parameters {'animal':'unicorn', 'hat':'blue'}, generating html. (Google `mako` for template syntax, or look at existing examples).
Since `customtag` is already a pointer, there is generally no need to put it into a separate file--just use it in place:
.. code-block:: xml
<customtag url_name="my_custom_tag" impl="blah" attr1="..."/>
`discussion`
============
The discussion tag embeds an inline discussion module. The XML format is:
.. code-block:: xml
<discussion for="Course overview" id="6002x_Fall_2012_Overview" discussion_category="Week 1/Overview" />
The meaning of each attribute is as follows:
.. list-table::
:widths: 10 80
:header-rows: 0
* - `for`
- A string that describes the discussion. Purely for descriptive purposes (to the student).
* - `id`
- The identifier that the discussion forum service uses to refer to this inline discussion module. Since the `id` must be unique and lives in a common namespace with all other courses, the preferred convention is to use `<course_name>_<course_run>_<descriptor>` as in the above example. The `id` should be "machine-friendly", e.g. use alphanumeric characters, underscores. Do **not** use a period (e.g. `6.002x_Fall_2012_Overview`).
* - `discussion_category`
- The inline module will be indexed in the main "Discussion" tab of the course. The inline discussions are organized into a directory-like hierarchy. Note that the forward slash indicates depth, as in conventional filesytems. In the above example, this discussion module will show up in the following "directory": `Week 1/Overview/Course overview`
Note that the `for` tag has been appended to the end of the `discussion_category`. This can often lead into deeply nested subforums, which may not be intended. In the above example, if we were to use instead:
.. code-block:: xml
<discussion for="Course overview" id="6002x_Fall_2012_Overview" discussion_category="Week 1" />
This discussion module would show up in the main forums as `Week 1 / Course overview`, which is more succinct.
`html`
======
Most of our content is in XML, but some HTML content may not be proper xml (all tags matched, single top-level tag, etc), since browsers are fairly lenient in what they'll display. So, there are two ways to include HTML content:
* If your HTML content is in a proper XML format, just put it in `html/{url_name}.xml`.
* If your HTML content is not in proper XML format, you can put it in `html/{filename}.html`, and put `<html filename={filename} />` in `html/{filename}.xml`. This allows another level of indirection, and makes sure that we can read the XML file and then just return the actual HTML content without trying to parse it.
`video`
=======
Videos have an attribute `youtube`, which specifies a series of speeds + youtube video IDs:
.. code-block:: xml
<video youtube="0.75:1yk1A8-FPbw,1.0:vNMrbPvwhU4,1.25:gBW_wqe7rDc,1.50:7AE_TKgaBwA"
url_name="S15V14_Response_to_impulse_limit_case"/>
This video has been encoded at 4 different speeds: `0.75x`, `1x`, `1.25x`, and `1.5x`.
More on `url_name`
==================
Every content element (within a course) should have a unique id. This id is formed as `{category}/{url_name}`, or automatically generated from the content if `url_name` is not specified. Categories are the different tag types ('chapter', 'problem', 'html', 'sequential', etc). Url_name is a string containing a-z, A-Z, dot (.), underscore (_), and ':'. This is what appears in urls that point to this object.
Colon (':') is special--when looking for the content definition in an xml, ':' will be replaced with '/'. This allows organizing content into folders. For example, given the pointer tag
.. code-block:: xml
<problem url_name="conceptual:add_apples_and_oranges"/>
we would look for the problem definition in `problem/conceptual/add_apples_and_oranges.xml`. (There is a technical reason why we can't just allow '/' in the url_name directly.)
.. important::
A student's state for a particular content element is tied to the element ID, so automatic ID generation is only ok for elements that do not need to store any student state (e.g. verticals or customtags). For problems, sequentials, and videos, and any other element where we keep track of what the student has done and where they are at, you should specify a unique `url_name`. Of course, any content element that is split out into a file will need a `url_name` to specify where to find the definition.
************
Policy Files
************
* A policy file is useful when running different versions of a course e.g. internal, external, fall, spring, etc. as you can change due dates, etc, by creating multiple policy files.
* A policy file provides information on the metadata of the course--things that are not inherent to the definitions of the contents, but that may vary from run to run.
* Note: We will be expanding our understanding and format for metadata in the not-too-distant future, but for now it is simply a set of key-value pairs.
Locations
=========
* The policy for a course run `some_url_name` should live in `policies/some_url_name/policy.json` (NOTE: the old format of putting it in `policies/some_url_name.json` will also work, but we suggest using the subdirectory to have all the per-course policy files in one place)
* Grading policy files go in `policies/some_url_name/grading_policy.json` (if there's only one course run, can also put it directly in the course root: `/grading_policy.json`)
Contents
========
* The file format is JSON, and is best shown by example, as in the tutorial above.
* The expected contents are a dictionary mapping from keys to values (syntax `{ key : value, key2 : value2, etc}`)
* Keys are in the form `{category}/{url_name}`, which should uniquely identify a content element. Values are dictionaries of the form `{"metadata-key" : "metadata-value"}`.
* The order in which things appear does not matter, though it may be helpful to organize the file in the same order as things appear in the content.
* NOTE: JSON is picky about commas. If you have trailing commas before closing braces, it will complain and refuse to parse the file. This can be irritating at first.
Supported fields at the course level
====================================
.. list-table::
:widths: 10 80
:header-rows: 0
* - `start`
- specify the start date for the course. Format-by-example: `"2012-09-05T12:00"`.
* - `advertised_start`
- specify what you want displayed as the start date of the course in the course listing and course about pages. This can be useful if you want to let people in early before the formal start. Format-by-example: `"2012-09-05T12:"00`.
* - `disable_policy_graph`
- set to true (or "Yes"), if the policy graph should be disabled (ie not shown).
* - `enrollment_start`, `enrollment_end`
- -- when can students enroll? (if not specified, can enroll anytime). Same format as `start`.
* - `end`
- specify the end date for the course. Format-by-example: `"2012-11-05T12:00"`.
* - `end_of_course_survey_url`
- a url for an end of course survey -- shown after course is over, next to certificate download links.
* - `tabs`
- have custom tabs in the courseware. See below for details on config.
* - `discussion_blackouts`
- An array of time intervals during which you want to disable a student's ability to create or edit posts in the forum. Moderators, Community TAs, and Admins are unaffected. You might use this during exam periods, but please be aware that the forum is often a very good place to catch mistakes and clarify points to students. The better long term solution would be to have better flagging/moderation mechanisms, but this is the hammer we have today. Format by example: `[["2012-10-29T04:00", "2012-11-03T04:00"], ["2012-12-30T04:00", "2013-01-02T04:00"]]`
* - `show_calculator`
- (value "Yes" if desired)
* - `days_early_for_beta`
- number of days (floating point ok) early that students in the beta-testers group get to see course content. Can also be specified for any other course element, and overrides values set at higher levels.
* - `cohort_config`
-
* `cohorted` : boolean. Set to true if this course uses student cohorts. If so, all inline discussions are automatically cohorted, and top-level discussion topics are configurable via the cohorted_discussions list. Default is not cohorted).
* `cohorted_discussions`: list of discussions that should be cohorted. Any not specified in this list are not cohorted.
* `auto_cohort`: Truthy.
* `auto_cohort_groups`: `["group name 1", "group name 2", ...]` If `cohorted` and `auto_cohort` is true, automatically put each student into a random group from the `auto_cohort_groups` list, creating the group if needed.
* - `pdf_textbooks`
- have pdf-based textbooks on tabs in the courseware. See below for details on config.
* - `html_textbooks`
- have html-based textbooks on tabs in the courseware. See below for details on config.
Available metadata
==================
Not Inherited
--------------
`display_name`
Name that will appear when this content is displayed in the courseware. Useful for all tag types.
`format`
Subheading under display name -- currently only displayed for chapter sub-sections. Also used by the the grader to know how to process students assessments that the section contains. New formats can be defined as a 'type' in the GRADER variable in course_settings.json. Optional. (TODO: double check this--what's the current behavior?)
`hide_from_toc`
If set to true for a chapter or chapter subsection, will hide that element from the courseware navigation accordion. This is useful if you'd like to link to the content directly instead (e.g. for tutorials)
`ispublic`
Specify whether the course is public. You should be able to use start dates instead (?)
Inherited
---------
`start`
When this content should be shown to students. Note that anyone with staff access to the course will always see everything.
`showanswer`
When to show answer. For 'attempted', will show answer after first attempt. Values: never, attempted, answered, closed. Default: closed. Optional.
`graded`
Whether this section will count towards the students grade. "true" or "false". Defaults to "false".
`rerandomize`
Randomize question on each attempt. Optional. Possible values:
`always` (default)
Students see a different version of the problem after each attempt to solve it.
`onreset`
Randomize question when reset button is pressed by the student.
`never`
All students see the same version of the problem.
`per_student`
Individual students see the same version of the problem each time the look at it, but that version is different from what other students see.
`due`
Due date for assignment. Assignment will be closed after that. Values: valid date. Default: none. Optional.
`attempts`
Number of allowed attempts. Values: integer. Default: infinite. Optional.
`graceperiod`
A default length of time that the problem is still accessible after the due date in the format `"2 days 3 hours"` or `"1 day 15 minutes"`. Note, graceperiods are currently the easiest way to handle time zones. Due dates are all expressed in UTC.
`xqa_key`
For integration with Ike's content QA server. -- should typically be specified at the course level.
Inheritance example
-------------------
This is a sketch ("tue" is not a valid start date), that should help illustrate how metadata inheritance works.
.. code-block:: xml
<course start="tue">
<chap1> -- start tue
<problem> --- start tue
</chap1>
<chap2 start="wed"> -- start wed
<problem2 start="thu"> -- start thu
<problem3> -- start wed
</chap2>
</course>
Specifying metadata in the XML file
-----------------------------------
Metadata can also live in the xml files, but anything defined in the policy file overrides anything in the XML. This is primarily for backwards compatibility, and you should probably not use both. If you do leave some metadata tags in the xml, you should be consistent (e.g. if `display_name` stays in XML, they should all stay in XML. Note `display_name` should be specified in the problem xml definition itself, ie, `<problem display_name="Title">Problem Text</problem>`, in file `ProblemFoo.xml`).
.. note::
Some xml attributes are not metadata. e.g. in `<video youtube="xyz987293487293847"/>`, the `youtube` attribute specifies what video this is, and is logically part of the content, not the policy, so it should stay in the xml.
Another example policy file::
{
"course/2012": {
"graceperiod": "1 day",
"start": "2012-10-15T12:00",
"display_name": "Introduction to Computer Science I",
"xqa_key": "z1y4vdYcy0izkoPeihtPClDxmbY1ogDK"
},
"chapter/Week_0": {
"display_name": "Week 0"
},
"sequential/Pre-Course_Survey": {
"display_name": "Pre-Course Survey",
"format": "Survey"
}
}
Deprecated Formats
------------------
If you look at some older xml, you may see some tags or metadata attributes that aren't listed above. They are deprecated, and should not be used in new content. We include them here so that you can understand how old-format content works.
Obsolete Tags
^^^^^^^^^^^^^
`section`
This used to be necessary within chapters. Now, you can just use any standard tag inside a chapter, so use the container tag that makes the most sense for grouping content--e.g. `problemset`, `videosequence`, and just include content directly if it belongs inside a chapter (e.g. `html`, `video`, `problem`)
`videodev, book, slides, image, discuss`
There used to be special purpose tags that all basically did the same thing, and have been subsumed by `customtag`. The list is `videodev, book, slides, image, discuss`. Use `customtag` in new content. (e.g. instead of `<book page="12"/>`, use `<customtag impl="book" page="12"/>`)
Obsolete Attributes
^^^^^^^^^^^^^^^^^^^
`slug`
Old term for `url_name`. Use `url_name`
`name`
We didn't originally have a distinction between `url_name` and `display_name` -- this made content element ids fragile, so please use `url_name` as a stable unique identifier for the content, and `display_name` as the particular string you'd like to display for it.
************
Static links
************
If your content links (e.g. in an html file) to `"static/blah/ponies.jpg"`, we will look for this...
* If your course dir has a `static/` subdirectory, we will look in `YOUR_COURSE_DIR/static/blah/ponies.jpg`. This is the prefered organization, as it does not expose anything except what's in `static/` to the world.
* If your course dir does not have a `static/` subdirectory, we will look in `YOUR_COURSE_DIR/blah/ponies.jpg`. This is the old organization, and requires that the web server allow access to everything in the couse dir. To switch to the new organization, move all your static content into a new `static/` dir (e.g. if you currently have things in `images/`, `css/`, and `special/`, create a dir called `static/`, and move `images/, css/, and special/` there).
Links that include `/course` will be rewritten to the root of your course in the courseware (e.g. `courses/{org}/{course}/{url_name}/` in the current url structure). This is useful for linking to the course wiki, for example.
****
Tabs
****
If you want to customize the courseware tabs displayed for your course, specify a "tabs" list in the course-level policy, like the following example:
.. code-block:: json
"tabs" : [
{"type": "courseware"},
{
"type": "course_info",
"name": "Course Info"
},
{
"type": "external_link",
"name": "My Discussion",
"link": "http://www.mydiscussion.org/blah"
},
{"type": "progress", "name": "Progress"},
{"type": "wiki", "name": "Wonderwiki"},
{
"type": "static_tab",
"url_slug": "news",
"name": "Exciting news"
},
{"type": "textbooks"},
{"type": "html_textbooks"},
{"type": "pdf_textbooks"}
]
* If you specify any tabs, you must specify all tabs. They will appear in the order given.
* The first two tabs must have types `"courseware"` and `"course_info"`, in that order, or the course will not load.
* The `courseware` tab never has a name attribute -- it's always rendered as "Courseware" for consistency between courses.
* The `textbooks` tab will actually generate one tab per textbook, using the textbook titles as names.
* The `html_textbooks` tab will actually generate one tab per html_textbook. The tab name is found in the html textbook definition.
* The `pdf_textbooks` tab will actually generate one tab per pdf_textbook. The tab name is found in the pdf textbook definition.
* For static tabs, the `url_slug` will be the url that points to the tab. It can not be one of the existing courseware url types (even if those aren't used in your course). The static content will come from `tabs/{course_url_name}/{url_slug}.html`, or `tabs/{url_slug}.html` if that doesn't exist.
* An Instructor tab will be automatically added at the end for course staff users.
.. list-table:: Supported Tabs and Parameters
:widths: 10 80
:header-rows: 0
* - `courseware`
- No other parameters.
* - `course_info`
- Parameter `name`.
* - `wiki`
- Parameter `name`.
* - `discussion`
- Parameter `name`.
* - `external_link`
- Parameters `name`, `link`.
* - `textbooks`
- No parameters--generates tab names from book titles.
* - `html_textbooks`
- No parameters--generates tab names from html book definition. (See discussion below for configuration.)
* - `pdf_textbooks`
- No parameters--generates tab names from pdf book definition. (See discussion below for configuration.)
* - `progress`
- Parameter `name`.
* - `static_tab`
- Parameters `name`, `url_slug`--will look for tab contents in 'tabs/{course_url_name}/{tab url_slug}.html'
* - `staff_grading`
- No parameters. If specified, displays the staff grading tab for instructors.
*********
Textbooks
*********
Support is currently provided for image-based, HTML-based and PDF-based textbooks. In addition to enabling the display of textbooks in tabs (see above), specific information about the location of textbook content must be configured.
Image-based Textbooks
=====================
Configuration
-------------
Image-based textbooks are configured at the course level in the XML markup. Here is an example:
.. code-block:: xml
<course>
<textbook title="Textbook 1" book_url="https://www.example.com/textbook_1/" />
<textbook title="Textbook 2" book_url="https://www.example.com/textbook_2/" />
<chapter url_name="Overview">
<chapter url_name="First week">
</course>
Each `textbook` element is displayed on a different tab. The `title` attribute is used as the tab's name, and the `book_url` attribute points to the remote directory that contains the images of the text. Note the trailing slash on the end of the `book_url` attribute.
The images must be stored in the same directory as the `book_url`, with filenames matching `pXXX.png`, where `XXX` is a three-digit number representing the page number (with leading zeroes as necessary). Pages start at `p001.png`.
Each textbook must also have its own table of contents. This is read from the `book_url` location, by appending `toc.xml`. This file contains a `table_of_contents` parent element, with `entry` elements nested below it. Each `entry` has attributes for `name`, `page_label`, and `page`, as well as an optional `chapter` attribute. An arbitrary number of levels of nesting of `entry` elements within other `entry` elements is supported, but you're likely to only want two levels. The `page` represents the actual page to link to, while the `page_label` matches the displayed page number on that page. Here's an example:
.. code-block:: xml
<table_of_contents>
<entry page="1" page_label="i" name="Title" />
<entry page="2" page_label="ii" name="Preamble">
<entry page="2" page_label="ii" name="Copyright"/>
<entry page="3" page_label="iii" name="Brief Contents"/>
<entry page="5" page_label="v" name="Contents"/>
<entry page="9" page_label="1" name="About the Authors"/>
<entry page="10" page_label="2" name="Acknowledgments"/>
<entry page="11" page_label="3" name="Dedication"/>
<entry page="12" page_label="4" name="Preface"/>
</entry>
<entry page="15" page_label="7" name="Introduction to edX" chapter="1">
<entry page="15" page_label="7" name="edX in the Modern World"/>
<entry page="18" page_label="10" name="The edX Method"/>
<entry page="18" page_label="10" name="A Description of edX"/>
<entry page="29" page_label="21" name="A Brief History of edX"/>
<entry page="51" page_label="43" name="Introduction to edX"/>
<entry page="56" page_label="48" name="Endnotes"/>
</entry>
<entry page="73" page_label="65" name="Art and Photo Credits" chapter="30">
<entry page="73" page_label="65" name="Molecular Models"/>
<entry page="73" page_label="65" name="Photo Credits"/>
</entry>
<entry page="77" page_label="69" name="Index" />
</table_of_contents>
Linking from Content
--------------------
It is possible to add links to specific pages in a textbook by using a URL that encodes the index of the textbook and the page number. The URL is of the form `/course/book/${bookindex}/$page}`. If the page is omitted from the URL, the first page is assumed.
You can use a `customtag` to create a template for such links. For example, you can create a `book` template in the `customtag` directory, containing:
.. code-block:: xml
<img src="/static/images/icons/textbook_icon.png"/> More information given in <a href="/course/book/${book}/${page}">the text</a>.
The course content can then link to page 25 using the `customtag` element:
.. code-block:: xml
<customtag book="0" page="25" impl="book"/>
HTML-based Textbooks
====================
Configuration
-------------
HTML-based textbooks are configured at the course level in the policy file. The JSON markup consists of an array of maps, with each map corresponding to a separate textbook. There are two styles to presenting HTML-based material. The first way is as a single HTML on a tab, which requires only a tab title and a URL for configuration. A second way permits the display of multiple HTML files that should be displayed together on a single view. For this view, a side panel of links is available on the left, allowing selection of a particular HTML to view.
.. code-block:: json
"html_textbooks": [
{"tab_title": "Textbook 1",
"url": "https://www.example.com/thiscourse/book1/book1.html" },
{"tab_title": "Textbook 2",
"chapters": [
{ "title": "Chapter 1", "url": "https://www.example.com/thiscourse/book2/Chapter1.html" },
{ "title": "Chapter 2", "url": "https://www.example.com/thiscourse/book2/Chapter2.html" },
{ "title": "Chapter 3", "url": "https://www.example.com/thiscourse/book2/Chapter3.html" },
{ "title": "Chapter 4", "url": "https://www.example.com/thiscourse/book2/Chapter4.html" },
{ "title": "Chapter 5", "url": "https://www.example.com/thiscourse/book2/Chapter5.html" },
{ "title": "Chapter 6", "url": "https://www.example.com/thiscourse/book2/Chapter6.html" },
{ "title": "Chapter 7", "url": "https://www.example.com/thiscourse/book2/Chapter7.html" }
]
}
]
Some notes:
* It is not a good idea to include a top-level URL and chapter-level URLs in the same textbook configuration.
Linking from Content
--------------------
It is possible to add links to specific pages in a textbook by using a URL that encodes the index of the textbook, the chapter (if chapters are used), and the page number. For a book with no chapters, the URL is of the form `/course/htmlbook/${bookindex}`. For a book with chapters, use `/course/htmlbook/${bookindex}/chapter/${chapter}` for a specific chapter, or `/course/htmlbook/${bookindex}` will default to the first chapter.
For example, for the book with no chapters configured above, the textbook can be reached using the URL `/course/htmlbook/0`. Reaching the third chapter of the second book is accomplished with `/course/htmlbook/1/chapter/3`.
You can use a `customtag` to create a template for such links. For example, you can create a `htmlbook` template in the `customtag` directory, containing:
.. code-block:: xml
<img src="/static/images/icons/textbook_icon.png"/> More information given in <a href="/course/htmlbook/${book}">the text</a>.
And a `htmlchapter` template containing:
.. code-block:: xml
<img src="/static/images/icons/textbook_icon.png"/> More information given in <a href="/course/htmlbook/${book}/chapter/${chapter}">the text</a>.
The example pages can then be linked using the `customtag` element:
.. code-block:: xml
<customtag book="0" impl="htmlbook"/>
<customtag book="1" chapter="3" impl="htmlchapter"/>
PDF-based Textbooks
===================
Configuration
-------------
PDF-based textbooks are configured at the course level in the policy file. The JSON markup consists of an array of maps, with each map corresponding to a separate textbook. There are two styles to presenting PDF-based material. The first way is as a single PDF on a tab, which requires only a tab title and a URL for configuration. A second way permits the display of multiple PDFs that should be displayed together on a single view. For this view, a side panel of links is available on the left, allowing selection of a particular PDF to view.
.. code-block:: json
"pdf_textbooks": [
{"tab_title": "Textbook 1",
"url": "https://www.example.com/thiscourse/book1/book1.pdf" },
{"tab_title": "Textbook 2",
"chapters": [
{ "title": "Chapter 1", "url": "https://www.example.com/thiscourse/book2/Chapter1.pdf" },
{ "title": "Chapter 2", "url": "https://www.example.com/thiscourse/book2/Chapter2.pdf" },
{ "title": "Chapter 3", "url": "https://www.example.com/thiscourse/book2/Chapter3.pdf" },
{ "title": "Chapter 4", "url": "https://www.example.com/thiscourse/book2/Chapter4.pdf" },
{ "title": "Chapter 5", "url": "https://www.example.com/thiscourse/book2/Chapter5.pdf" },
{ "title": "Chapter 6", "url": "https://www.example.com/thiscourse/book2/Chapter6.pdf" },
{ "title": "Chapter 7", "url": "https://www.example.com/thiscourse/book2/Chapter7.pdf" }
]
}
]
Some notes:
* It is not a good idea to include a top-level URL and chapter-level URLs in the same textbook configuration.
Linking from Content
--------------------
It is possible to add links to specific pages in a textbook by using a URL that encodes the index of the textbook, the chapter (if chapters are used), and the page number. For a book with no chapters, the URL is of the form `/course/pdfbook/${bookindex}/$page}`. For a book with chapters, use `/course/pdfbook/${bookindex}/chapter/${chapter}/${page}`. If the page is omitted from the URL, the first page is assumed.
For example, for the book with no chapters configured above, page 25 can be reached using the URL `/course/pdfbook/0/25`. Reaching page 19 in the third chapter of the second book is accomplished with `/course/pdfbook/1/chapter/3/19`.
You can use a `customtag` to create a template for such links. For example, you can create a `pdfbook` template in the `customtag` directory, containing:
.. code-block:: xml
<img src="/static/images/icons/textbook_icon.png"/> More information given in <a href="/course/pdfbook/${book}/${page}">the text</a>.
And a `pdfchapter` template containing:
.. code-block:: xml
<img src="/static/images/icons/textbook_icon.png"/> More information given in <a href="/course/pdfbook/${book}/chapter/${chapter}/${page}">the text</a>.
The example pages can then be linked using the `customtag` element:
.. code-block:: xml
<customtag book="0" page="25" impl="pdfbook"/>
<customtag book="1" chapter="3" page="19" impl="pdfchapter"/>
*************************************
Other file locations (info and about)
*************************************
With different course runs, we may want different course info and about materials. This is now supported by putting files in as follows::
/
about/
foo.html -- shared default for all runs
url_name1/
foo.html -- version used for url_name1
bar.html -- bar for url_name1
url_name2/
bar.html -- bar for url_name2
-- url_name2 will use default foo.html
and the same works for the `info` directory.
***************************
Tips for content developers
***************************
#. We will be making better tools for managing policy files soon. In the meantime, you can add dummy definitions to make it easier to search and separate the file visually. For example, you could add `"WEEK 1" : "###################"`, before the week 1 material to make it easy to find in the file.
#. Come up with a consistent pattern for url_names, so that it's easy to know where to look for any piece of content. It will also help to come up with a standard way of splitting your content files. As a point of departure, we suggest splitting chapters, sequences, html, and problems into separate files.
#. Prefer the most "semantic" name for containers: e.g., use problemset rather than sequential for a problem set. That way, if we decide to display problem sets differently, we don't have to change the XML.
####################################
CustomResponse XML and Python Script
####################################
This document explains how to write a CustomResponse problem. CustomResponse
problems execute Python script to check student answers and provide hints.
There are two general ways to create a CustomResponse problem:
*****************
Answer tag format
*****************
One format puts the Python code in an ``<answer>`` tag:
.. code-block:: xml
<problem>
<p>What is the sum of 2 and 3?</p>
<customresponse expect="5">
<textline math="1" />
</customresponse>
<answer>
# Python script goes here
</answer>
</problem>
The Python script interacts with these variables in the global context:
* ``answers``: An ordered list of answers the student provided.
For example, if the student answered ``6``, then ``answers[0]`` would
equal ``6``.
* ``expect``: The value of the ``expect`` attribute of ``<customresponse>``
(if provided).
* ``correct``: An ordered list of strings indicating whether the
student answered the question correctly. Valid values are
``"correct"``, ``"incorrect"``, and ``"unknown"``. You can set these
values in the script.
* ``messages``: An ordered list of message strings that will be displayed
beneath each input. You can use this to provide hints to users.
For example ``messages[0] = "The capital of California is Sacramento"``
would display that message beneath the first input of the response.
* ``overall_message``: A string that will be displayed beneath the
entire problem. You can use this to provide a hint that applies
to the entire problem rather than a particular input.
Example of a checking script:
.. code-block:: python
if answers[0] == expect:
correct[0] = 'correct'
overall_message = 'Good job!'
else:
correct[0] = 'incorrect'
messages[0] = 'This answer is incorrect'
overall_message = 'Please try again'
**Important**: Python is picky about indentation. Within the ``<answer>`` tag,
you must begin your script with no indentation.
*****************
Script tag format
*****************
The other way to create a CustomResponse is to put a "checking function"
in a ``<script>`` tag, then use the ``cfn`` attribute of the
``<customresponse>`` tag:
.. code-block:: xml
<problem>
<p>What is the sum of 2 and 3?</p>
<customresponse cfn="check_func" expect="5">
<textline math="1" />
</customresponse>
<script type="loncapa/python">
def check_func(expect, ans):
# Python script goes here
</script>
</problem>
**Important**: Python is picky about indentation. Within the ``<script>`` tag,
the ``def check_func(expect, ans):`` line must have no indentation.
The check function accepts two arguments:
* ``expect`` is the value of the ``expect`` attribute of ``<customresponse>``
(if provided)
* ``answer`` is either:
* The value of the answer the student provided, if there is only one input.
* An ordered list of answers the student provided, if there
are multiple inputs.
There are several ways that the check function can indicate whether the student
succeeded. The check function can return any of the following:
* ``True``: Indicates that the student answered correctly for all inputs.
* ``False``: Indicates that the student answered incorrectly.
All inputs will be marked incorrect.
* A dictionary of the form: ``{ 'ok': True, 'msg': 'Message' }``
If the dictionary's value for ``ok`` is set to ``True``, all inputs are
marked correct; if it is set to ``False``, all inputs are marked incorrect.
The ``msg`` is displayed beneath all inputs, and it may contain
XHTML markup.
* A dictionary of the form
.. code-block:: xml
{ 'overall_message': 'Overall message',
'input_list': [
{ 'ok': True, 'msg': 'Feedback for input 1'},
{ 'ok': False, 'msg': 'Feedback for input 2'},
... ] }
The last form is useful for responses that contain multiple inputs.
It allows you to provide feedback for each input individually,
as well as a message that applies to the entire response.
Example of a checking function:
.. code-block:: python
def check_func(expect, answer_given):
check1 = (int(answer_given[0]) == 1)
check2 = (int(answer_given[1]) == 2)
check3 = (int(answer_given[2]) == 3)
return {'overall_message': 'Overall message',
'input_list': [
{ 'ok': check1, 'msg': 'Feedback 1'},
{ 'ok': check2, 'msg': 'Feedback 2'},
{ 'ok': check3, 'msg': 'Feedback 3'} ] }
The function checks that the user entered ``1`` for the first input,
``2`` for the second input, and ``3`` for the third input.
It provides feedback messages for each individual input, as well
as a message displayed beneath the entire problem.
**********************************************
XML format of drag and drop input [inputtypes]
**********************************************
.. module:: drag_and_drop_input
Format description
==================
The main tag of Drag and Drop (DnD) input is::
<drag_and_drop_input> ... </drag_and_drop_input>
``drag_and_drop_input`` can include any number of the following 2 tags:
``draggable`` and ``target``.
drag_and_drop_input tag
-----------------------
The main container for a single instance of DnD. The following attributes can
be specified for this tag::
img - Relative path to an image that will be the base image. All draggables
can be dragged onto it.
target_outline - Specify whether an outline (gray dashed line) should be
drawn around targets (if they are specified). It can be either
'true' or 'false'. If not specified, the default value is
'false'.
one_per_target - Specify whether to allow more than one draggable to be
placed onto a single target. It can be either 'true' or 'false'. If
not specified, the default value is 'true'.
no_labels - default is false, in default behaviour if label is not set, label
is obtained from id. If no_labels is true, labels are not automatically
populated from id, and one can not set labels and obtain only icons.
draggable tag
-------------
Draggable tag specifies a single draggable object which has the following
attributes::
id - Unique identifier of the draggable object.
label - Human readable label that will be shown to the user.
icon - Relative path to an image that will be shown to the user.
can_reuse - true or false, default is false. If true, same draggable can be
used multiple times.
A draggable is what the user must drag out of the slider and place onto the
base image. After a drag operation, if the center of the draggable ends up
outside the rectangular dimensions of the image, it will be returned back
to the slider.
In order for the grader to work, it is essential that a unique ID
is provided. Otherwise, there will be no way to tell which draggable is at what
coordinate, or over what target. Label and icon attributes are optional. If
they are provided they will be used, otherwise, you can have an empty
draggable. The path is relative to 'course_folder' folder, for example,
/static/images/img1.png.
target tag
----------
Target tag specifies a single target object which has the following required
attributes::
id - Unique identifier of the target object.
x - X-coordinate on the base image where the top left corner of the target
will be positioned.
y - Y-coordinate on the base image where the top left corner of the target
will be positioned.
w - Width of the target.
h - Height of the target.
A target specifies a place on the base image where a draggable can be
positioned. By design, if the center of a draggable lies within the target
(i.e. in the rectangle defined by [[x, y], [x + w, y + h]], then it is within
the target. Otherwise, it is outside.
If at lest one target is provided, the behavior of the client side logic
changes. If a draggable is not dragged on to a target, it is returned back to
the slider.
If no targets are provided, then a draggable can be dragged and placed anywhere
on the base image.
Targets on draggables
---------------------
Sometimes it is not enough to have targets only on the base image, and all of the
draggables on these targets. If a complex problem exists where a draggable must
become itself a target (or many targets), then the following extended syntax
can be used: ::
<draggable {attribute list}>
<target {attribute list} />
<target {attribute list} />
<target {attribute list} />
...
</draggable>
The attribute list in the tags above ('draggable' and 'target') is the same as for
normal 'draggable' and 'target' tags. The only difference is when you will be
specifying inner target position coordinates. Using the 'x' and 'y' attributes you
are setting the offset of the inner target from the upper-left corner of the
parent draggable (that contains the inner target).
Limitations of targets on draggables
------------------------------------
1.) Currently there is a limitation to the level of nesting of targets.
Even though you can pile up a large number of draggables on targets that themselves
are on draggables, the Drag and Drop instance will be graded only in the case if
there is a maximum of two levels of targets. The first level are the "base" targets.
They are attached to the base image. The second level are the targets defined on
draggables.
2.) Another limitation is that the target bounds are not checked against
other targets.
For now, it is the responsibility of the person who is constructing the course
material to make sure that there is no overlapping of targets. It is also preferable
that targets on draggables are smaller than the actual parent draggable. Technically
this is not necessary, but from the usability perspective it is desirable.
3.) You can have targets on draggables only in the case when there are base targets
defined (base targets are attached to the base image).
If you do not have base targets, then you can only have a single level of nesting
(draggables on the base image). In this case the client side will be reporting (x,y)
positions of each draggables on the base image.
Correct answer format
---------------------
(NOTE: For specifying answers for targets on draggables please see next section.)
There are two correct answer formats: short and long
If short from correct answer is mapping of 'draggable_id' to 'target_id'::
correct_answer = {'grass': [[300, 200], 200], 'ant': [[500, 0], 200]}
correct_answer = {'name4': 't1', '7': 't2'}
In long form correct answer is list of dicts. Every dict has 3 keys:
draggables, targets and rule. For example::
correct_answer = [
{
'draggables': ['7', '8'],
'targets': ['t5_c', 't6_c'],
'rule': 'anyof'
},
{
'draggables': ['1', '2'],
'targets': ['t2_h', 't3_h', 't4_h', 't7_h', 't8_h', 't10_h'],
'rule': 'anyof'
}]
Draggables is list of draggables id. Target is list of targets id, draggables
must be dragged to with considering rule. Rule is string.
Draggables in dicts inside correct_answer list must not intersect!!!
Wrong (for draggable id 7)::
correct_answer = [
{
'draggables': ['7', '8'],
'targets': ['t5_c', 't6_c'],
'rule': 'anyof'
},
{
'draggables': ['7', '2'],
'targets': ['t2_h', 't3_h', 't4_h', 't7_h', 't8_h', 't10_h'],
'rule': 'anyof'
}]
Rules are: exact, anyof, unordered_equal, anyof+number, unordered_equal+number
.. such long lines are needed for sphinx to display lists correctly
- Exact rule means that targets for draggable id's in user_answer are the same that targets from correct answer. For example, for draggables 7 and 8 user must drag 7 to target1 and 8 to target2 if correct_answer is::
correct_answer = [
{
'draggables': ['7', '8'],
'targets': ['tartget1', 'target2'],
'rule': 'exact'
}]
- unordered_equal rule allows draggables be dragged to targets unordered. If one want to allow for student to drag 7 to target1 or target2 and 8 to target2 or target 1 and 7 and 8 must be in different targets, then correct answer must be::
correct_answer = [
{
'draggables': ['7', '8'],
'targets': ['tartget1', 'target2'],
'rule': 'unordered_equal'
}]
- Anyof rule allows draggables to be dragged to any of targets. If one want to allow for student to drag 7 and 8 to target1 or target2, which means that if 7 is on target1 and 8 is on target1 or 7 on target2 and 8 on target2 or 7 on target1 and 8 on target2. Any of theese are correct which anyof rule::
correct_answer = [
{
'draggables': ['7', '8'],
'targets': ['tartget1', 'target2'],
'rule': 'anyof'
}]
- If you have can_reuse true, then you, for example, have draggables a,b,c and 10 targets. These will allow you to drag 4 'a' draggables to ['target1', 'target4', 'target7', 'target10'] , you do not need to write 'a' four times. Also this will allow you to drag 'b' draggable to target2 or target5 for target5 and target2 etc..::
correct_answer = [
{
'draggables': ['a'],
'targets': ['target1', 'target4', 'target7', 'target10'],
'rule': 'unordered_equal'
},
{
'draggables': ['b'],
'targets': ['target2', 'target5', 'target8'],
'rule': 'anyof'
},
{
'draggables': ['c'],
'targets': ['target3', 'target6', 'target9'],
'rule': 'unordered_equal'
}]
- And sometimes you want to allow drag only two 'b' draggables, in these case you should use 'anyof+number' of 'unordered_equal+number' rule::
correct_answer = [
{
'draggables': ['a', 'a', 'a'],
'targets': ['target1', 'target4', 'target7'],
'rule': 'unordered_equal+numbers'
},
{
'draggables': ['b', 'b'],
'targets': ['target2', 'target5', 'target8'],
'rule': 'anyof+numbers'
},
{
'draggables': ['c'],
'targets': ['target3', 'target6', 'target9'],
'rule': 'unordered_equal'
}]
In case if we have no multiple draggables per targets (one_per_target="true"),
for same number of draggables, anyof is equal to unordered_equal
If we have can_reuse=true, than one must use only long form of correct answer.
Answer format for targets on draggables
---------------------------------------
As with the cases described above, an answer must provide precise positioning for
each draggable (on which targets it must reside). In the case when a draggable must
be placed on a target that itself is on a draggable, then the answer must contain
the chain of target-draggable-target. It is best to understand this on an example.
Suppose we have three draggables - 'up', 's', and 'p'. Draggables 's', and 'p' have targets
on themselves. More specifically, 'p' has three targets - '1', '2', and '3'. The first
requirement is that 's', and 'p' are positioned on specific targets on the base image.
The second requirement is that draggable 'up' is positioned on specific targets of
draggable 'p'. Below is an excerpt from a problem.::
<draggable id="up" icon="/static/images/images_list/lcao-mo/up.png" can_reuse="true" />
<draggable id="s" icon="/static/images/images_list/lcao-mo/orbital_single.png" label="s orbital" can_reuse="true" >
<target id="1" x="0" y="0" w="32" h="32"/>
</draggable>
<draggable id="p" icon="/static/images/images_list/lcao-mo/orbital_triple.png" can_reuse="true" label="p orbital" >
<target id="1" x="0" y="0" w="32" h="32"/>
<target id="2" x="34" y="0" w="32" h="32"/>
<target id="3" x="68" y="0" w="32" h="32"/>
</draggable>
...
correct_answer = [
{
'draggables': ['p'],
'targets': ['p-left-target', 'p-right-target'],
'rule': 'unordered_equal'
},
{
'draggables': ['s'],
'targets': ['s-left-target', 's-right-target'],
'rule': 'unordered_equal'
},
{
'draggables': ['up'],
'targets': ['p-left-target[p][1]', 'p-left-target[p][2]', 'p-right-target[p][2]', 'p-right-target[p][3]',],
'rule': 'unordered_equal'
}
]
Note that it is a requirement to specify rules for all draggables, even if some draggable gets included
in more than one chain.
Grading logic
-------------
1. User answer (that comes from browser) and correct answer (from xml) are parsed to the same format::
group_id: group_draggables, group_targets, group_rule
Group_id is ordinal number, for every dict in correct answer incremental
group_id is assigned: 0, 1, 2, ...
Draggables from user answer are added to same group_id where identical draggables
from correct answer are, for example::
If correct_draggables[group_0] = [t1, t2] then
user_draggables[group_0] are all draggables t1 and t2 from user answer:
[t1] or [t1, t2] or [t1, t2, t2] etc..
2. For every group from user answer, for that group draggables, if 'number' is in group rule, set() is applied,
if 'number' is not in rule, set is not applied::
set() : [t1, t2, t3, t3] -> [t1, t2, ,t3]
For every group, at this step, draggables lists are equal.
3. For every group, lists of targets are compared using rule for that group.
Set and '+number' cases
.......................
Set() and '+number' are needed only for case of reusable draggables,
for other cases there are no equal draggables in list, so set() does nothing.
.. such long lines needed for sphinx to display nicely
* Usage of set() operation allows easily create rule for case of "any number of same draggable can be dragged to some targets"::
{
'draggables': ['draggable_1'],
'targets': ['target3', 'target6', 'target9'],
'rule': 'anyof'
}
* 'number' rule is used for the case of reusable draggables, when one want to fix number of draggable to drag. In this example only two instances of draggables_1 are allowed to be dragged::
{
'draggables': ['draggable_1', 'draggable_1'],
'targets': ['target3', 'target6', 'target9'],
'rule': 'anyof+number'
}
* Note, that in using rule 'exact', one does not need 'number', because you can't recognize from user interface which reusable draggable is on which target. Absurd example::
{
'draggables': ['draggable_1', 'draggable_1', 'draggable_2'],
'targets': ['target3', 'target6', 'target9'],
'rule': 'exact'
}
Correct handling of this example is to create different rules for draggable_1 and
draggable_2
* For 'unordered_equal' (or 'exact' too) we don't need 'number' if you have only same draggable in group, as targets length will provide constraint for the number of draggables::
{
'draggables': ['draggable_1'],
'targets': ['target3', 'target6', 'target9'],
'rule': 'unordered_equal'
}
This means that only three draggaggables 'draggable_1' can be dragged.
* But if you have more that one different reusable draggable in list, you may use 'number' rule::
{
'draggables': ['draggable_1', 'draggable_1', 'draggable_2'],
'targets': ['target3', 'target6', 'target9'],
'rule': 'unordered_equal+number'
}
If not use number, draggables list will be setted to ['draggable_1', 'draggable_2']
Logic flow
----------
(Click on image to see full size version.)
.. image:: draganddrop_logic_flow.png
:width: 100%
:target: _images/draganddrop_logic_flow.png
Example
=======
Examples of draggables that can't be reused
-------------------------------------------
.. literalinclude:: drag-n-drop-demo.xml
Draggables can be reused
------------------------
.. literalinclude:: drag-n-drop-demo2.xml
Examples of targets on draggables
------------------------
.. literalinclude:: drag-n-drop-demo3.xml
##############
Course Grading
##############
This document is written to help professors understand how a final grade for a
course is computed.
Course grading is the process of taking all of the problems scores for a student
in a course and generating a final score (and corresponding letter grade). This
grading process can be split into two phases - totaling sections and section
weighting.
*****************
Totaling sections
*****************
The process of totaling sections is to get a percentage score (between 0.0 and
1.0) for every section in the course. A section is any module that is a direct
child of a chapter. For example, psets, labs, and sequences are all common
sections. Only the *percentage* on the section will be available to compute the
final grade, *not* the final number of points earned / possible.
.. important::
For a section to be included in the final grade, the policies file must set
`graded = True` for the section.
For each section, the grading function retrieves all problems within the
section. The section percentage is computed as (total points earned) / (total
points possible).
******************
Weighting Problems
******************
In some cases, one might want to give weights to problems within a section. For
example, a final exam might contain four questions each worth 1 point by default.
This means each question would by default have the same weight. If one wanted
the first problem to be worth 50% of the final exam, the policy file could specify
weights of 30, 10, 10, and 10 to the four problems, respectively.
Note that the default weight of a problem **is not 1**. The default weight of a
problem is the module's `max_grade`.
If weighting is set, each problem is worth the number of points assigned, regardless of the number of responses it contains.
Consider a Homework section that contains two problems.
.. code-block:: xml
<problem display_name=”Problem 1”>
<numericalresponse> ... </numericalreponse>
</problem>
.. code-block:: xml
<problem display_name=”Problem 2”>
<numericalresponse> ... </numericalreponse>
<numericalresponse> ... </numericalreponse>
<numericalresponse> ... </numericalreponse>
</problem>
Without weighting, Problem 1 is worth 25% of the assignment, and Problem 2 is worth 75% of the assignment.
Weighting for the problems can be set in the policy.json file.
.. code-block:: json
"problem/problem1": {
"weight": 2
},
"problem/problem2": {
"weight": 2
},
With the above weighting, Problems 1 and 2 are each worth 50% of the assignment.
Please note: When problems have weight, the point value is automatically included in the display name *except* when `"weight": 1`. When the weight is 1, no visual change occurs in the display name, leaving the point value open to interpretation to the student.
******************
Weighting Sections
******************
Once each section has a percentage score, we must total those sections into a
final grade. Of course, not every section has equal weight in the final grade.
The policies for weighting sections into a final grade are specified in the
grading_policy.json file.
The `grading_policy.json` file specifies several sub-graders that are each given
a weight and factored into the final grade. There are currently two types of
sub-graders, section format graders and single section graders.
We will use this simple example of a grader with one section format grader and
one single section grader.
.. code-block:: json
"GRADER" : [
{
"type" : "Homework",
"min_count" : 12,
"drop_count" : 2,
"short_label" : "HW",
"weight" : 0.4
},
{
"type" : "Final",
"name" : "Final Exam",
"short_label" : "Final",
"weight" : 0.6
}
]
Section Format Graders
======================
A section format grader grades a set of sections with the same format, as
defined in the course policy file. To make a vertical named Homework1 be graded
by the Homework section format grader, the following definition would be in the
course policy file.
.. code-block:: json
"vertical/Homework1": {
"display_name": "Homework 1",
"graded": true,
"format": "Homework"
},
In the example above, the section format grader declares that it will expect to
find at least 12 sections with the format "Homework". It will drop the lowest 2.
All of the homework assignments will have equal weight, relative to each other
(except, of course, for the assignments that are dropped).
This format supports forecasting the number of homework assignments. For
example, if the course only has 3 homeworks written, but the section format
grader has been told to expect 12, the missing 9 will have an assumed 0% and
will still show up in the grade breakdown.
A section format grader will also show the average of that section in the grade
breakdown (shown on the Progress page, gradebook, etc.).
Single Section Graders
======================
A single section grader grades exactly that - a single section. If a section
is found with a matching format and display name then the score of that section
is used. If not, a score of 0% is assumed.
Combining sub-graders
=====================
The final grade is computed by taking the score and weight of each sub grader.
In the above example, homework will be 40% of the final grade. The final exam
will be 60% of the final grade.
**************************
Displaying the final grade
**************************
The final grade is then rounded up to the nearest percentage point. This is so
the system can consistently display a percentage without worrying whether the
displayed percentage has been rounded up or down (potentially misleading the
student). The formula for the rounding is::
rounded_percent = round(computed_percent * 100 + 0.05) / 100
The grading policy file also specifies the cutoffs for the grade levels. A
grade is either A, B, or C. If the student does not reach the cutoff threshold
for a C grade then the student has not earned a grade and will not be eligible
for a certificate. Letter grades are only awarded to students who have
completed the course. There is no notion of a failing letter grade.
*********************************************
XML format of graphical slider tool [xmodule]
*********************************************
.. module:: xml_format_gst
Format description
==================
Graphical slider tool (GST) main tag is::
<graphical_slider_tool> BODY </graphical_slider_tool>
``graphical_slider_tool`` tag must have two children tags: ``render``
and ``configuration``.
Render tag
----------
Render tag can contain usual html tags mixed with some GST specific tags::
<slider/> - represents jQuery slider for changing a parameter's value
<textbox/> - represents a text input field for changing a parameter's value
<plot/> - represents Flot JS plot element
Also GST will track all elements inside ``<render></render>`` where ``id``
attribute is set, and a corresponding parameter referencing that ``id`` is present
in the configuration section below. These will be referred to as dynamic elements.
The contents of the <render> section will be shown to the user after
all occurrences of::
<slider var="{parameter name}" [style="{CSS statements}"] />
<textbox var="{parameter name}" [style="{CSS statements}"] />
<plot [style="{CSS statements}"] />
have been converted to actual sliders, text inputs, and a plot graph.
Everything in square brackets is optional. After initialization, all
text input fields, sliders, and dynamic elements will be set to the initial
values of the parameters that they are assigned to.
``{parameter name}`` specifies the parameter to which the slider or text
input will be attached to.
[style="{CSS statements}"] specifies valid CSS styling. It will be passed
directly to the browser without any parsing.
There is a one-to-one relationship between a slider and a parameter.
I.e. for one parameter you can put only one ``<slider>`` in the
``<render>`` section. However, you don't have to specify a slider - they
are optional.
There is a many-to-one relationship between text inputs and a
parameter. I.e. for one parameter you can put many '<textbox>' elements in
the ``<render>`` section. However, you don't have to specify a text
input - they are optional.
You can put only one ``<plot>`` in the ``<render>`` section. It is not
required.
Slider tag
..........
Slider tag must have ``var`` attribute and optional ``style`` attribute::
<slider var='a' style="width:400px;float:left;" />
After processing, slider tags will be replaced by jQuery UI sliders with applied
``style`` attribute.
``var`` attribute must correspond to a parameter. Parameters can be used in any
of the ``function`` tags in ``functions`` tag. By moving slider, value of
parameter ``a`` will change, and so result of function, that depends on parameter
``a``, will also change.
Textbox tag
...........
Texbox tag must have ``var`` attribute and optional ``style`` attribute::
<textbox var="b" style="width:50px; float:left; margin-left:10px;" />
After processing, textbox tags will be replaced by html text inputs with applied
``style`` attribute. If you want a readonly text input, then you should use a
dynamic element instead (see section below "HTML tagsd with ID").
``var`` attribute must correspond to a parameter. Parameters can be used in any
of the ``function`` tags in ``functions`` tag. By changing the value on the text input,
value of parameter ``a`` will change, and so result of function, that depends on
parameter ``a``, will also change.
Plot tag
........
Plot tag may have optional ``style`` attribute::
<plot style="width:50px; float:left; margin-left:10px;" />
After processing plot tags will be replaced by Flot JS plot with applied
``style`` attribute.
HTML tags with ID (dynamic elements)
....................................
Any HTML tag with ID, e.g. ``<span id="answer_span_1">`` can be used as a
place where result of function can be inserted. To insert function result to
an element, element ID must be included in ``function`` tag as ``el_id`` attribute
and ``output`` value must be ``"element"``::
<function output="element" el_id="answer_span_1">
function add(a, b, precision) {
var x = Math.pow(10, precision || 2);
return (Math.round(a * x) + Math.round(b * x)) / x;
}
return add(a, b, 5);
</function>
Configuration tag
-----------------
The configuration tag contains parameter settings, graph
settings, and function definitions which are to be plotted on the
graph and that use specified parameters.
Configuration tag contains two mandatory tag ``functions`` and ``parameters`` and
may contain another ``plot`` tag.
Parameters tag
..............
``Parameters`` tag contains ``parameter`` tags. Each ``parameter`` tag must have
``var``, ``max``, ``min``, ``step`` and ``initial`` attributes::
<parameters>
<param var="a" min="-10.0" max="10.0" step="0.1" initial="0" />
<param var="b" min="-10.0" max="10.0" step="0.1" initial="0" />
</parameters>
``var`` attribute links min, max, step and initial values to parameter name.
``min`` attribute is the minimal value that a parameter can take. Slider and input
values can not go below it.
``max`` attribute is the maximal value that a parameter can take. Slider and input
values can not go over it.
``step`` attribute is value of slider step. When a slider increase or decreases
the specified parameter, it will do so by the amount specified with 'step'
``initial`` attribute is the initial value that the specified parameter should be
set to. Sliders and inputs will initially show this value.
The parameter's name is specified by the ``var`` property. All occurrences
of sliders and/or text inputs that specify a ``var`` property, will be
connected to this parameter - i.e. they will reflect the current
value of the parameter, and will be updated when the parameter
changes.
If at lest one of these attributes is not set, then the parameter
will not be used, slider's and/or text input elements that specify
this parameter will not be activated, and the specified functions
which use this parameter will not return a numeric value. This means
that neglecting to specify at least one of the attributes for some
parameter will have the result of the whole GST instance not working
properly.
Functions tag
.............
For the GST to do something, you must defined at least one
function, which can use any of the specified parameter values. The
function expects to take the ``x`` value, do some calculations, and
return the ``y`` value. I.e. this is a 2D plot in Cartesian
coordinates. This is how the default function is meant to be used for
the graph.
There are other special cases of functions. They are used mainly for
outputting to elements, plot labels, or for custom output. Because
the return a single value, and that value is meant for a single element,
these function are invoked only with the set of all of the parameters.
I.e. no ``x`` value is available inside them. They are useful for
showing the current value of a parameter, showing complex static
formulas where some parameter's value must change, and other useful
things.
The different style of function is specified by the ``output`` attribute.
Each function must be defined inside ``function`` tag in ``functions`` tag::
<functions>
<function output="element" el_id="answer_span_1">
function add(a, b, precision) {
var x = Math.pow(10, precision || 2);
return (Math.round(a * x) + Math.round(b * x)) / x;
}
return add(a, b, 5);
</function>
</functions>
The parameter names (along with their values, as provided from text
inputs and/or sliders), will be available inside all defined
functions. A defined function body string will be parsed internally
by the browser's JavaScript engine and converted to a true JS
function.
The function's parameter list will automatically be created and
populated, and will include the ``x`` (when ``output`` is not specified or
is set to ``"graph"``), and all of the specified parameter values (from sliders
and text inputs). This means that each of the defined functions will have
access to all of the parameter values. You don't have to use them, but
they will be there.
Examples::
<function>
return x;
</function>
<function dot="true" label="\(y_2\)">
return (x + a) * Math.sin(x * b);
</function>
<function color="green">
function helperFunc(c1) {
return c1 * c1 - a;
}
return helperFunc(x + 10 * a * b) + Math.sin(a - x);
</function>
Required parameters::
function body:
A string composing a normal JavaScript function
except that there is no function declaration
(along with parameters), and no closing bracket.
So if you normally would have written your
JavaScript function like this:
function myFunc(x, a, b) {
return x * a + b;
}
here you must specify just the function body
(everything that goes between '{' and '}'). So,
you would specify the above function like so (the
bare-bone minimum):
<function>return x * a + b;</function>
VERY IMPORTANT: Because the function will be passed
to the browser as a single string, depending on implementation
specifics, the end-of-line characters can be stripped. This
means that single line JavaScript comments (starting with "//")
can lead to the effect that everything after the first such comment
will be treated as a comment. Therefore, it is absolutely
necessary that such single line comments are not used when
defining functions for GST. You can safely use the alternative
multiple line JavaScript comments (such comments start with "/*"
and end with "*/).
VERY IMPORTANT: If you have a large function body, and decide to
split it into several lines, than you must wrap it in "CDATA" like
so:
<function>
<![CDATA[
var dNew;
dNew = 0.3;
return x * a + b - dNew;
]]>
</function>
Optional parameters::
color: Color name ('red', 'green', etc.) or in the form of
'#FFFF00'. If not specified, a default color (different
one for each graphed function) will be given by Flot JS.
line: A string - 'true' or 'false'. Should the data points be
connected by a line on the graph? Default is 'true'.
dot: A string - 'true' or 'false'. Should points be shown for
each data point on the graph? Default is 'false'.
bar: A string - 'true' or 'false'. When set to 'true', points
will be plotted as bars.
label: A string. If provided, will be shown in the legend, along
with the color that was used to plot the function.
output: 'element', 'none', 'plot_label', or 'graph'. If not defined,
function will be plotted (same as setting 'output' to 'graph').
If defined, and other than 'graph', function will not be
plotted, but it's output will be inserted into the element
with ID specified by 'el_id' attribute.
el_id: Id of HTML element, defined in '<render>' section. Value of
function will be inserted as content of this element.
disable_auto_return: By default, if JavaScript function string is written
without a "return" statement, the "return" will be
prepended to it. Set to "true" to disable this
functionality. This is done so that simple functions
can be defined in an easy fashion (for example, "a",
which will be translated into "return a").
update_on: A string - 'change', or 'slide'. Default (if not set) is
'slide'. This defines the event on which a given function is
called, and its result is inserted into an element. This
setting is relevant only when "output" is other than "graph".
When specifying ``el_id``, it is essential to set "output" to one of
element - GST will invoke the function, and the return of it will be
inserted into a HTML element with id specified by ``el_id``.
none - GST will simply inoke the function. It is left to the instructor
who writes the JavaScript function body to update all necesary
HTML elements inside the function, before it exits. This is done
so that extra steps can be preformed after an HTML element has
been updated with a value. Note, that because the return value
from this function is not actually used, it will be tempting to
omit the "return" statement. However, in this case, the attribute
"disable_auto_return" must be set to "true" in order to prevent
GST from inserting a "return" statement automatically.
plot_label - GST will process all plot labels (which are strings), and
will replace the all instances of substrings specified by
``el_id`` with the returned value of the function. This is
necessary if you want a label in the graph to have some changing
number. Because of the nature of Flot JS, it is impossible to
achieve the same effect by setting the "output" attribute
to "element", and including a HTML element in the label.
The above values for "output" will tell GST that the function is meant for an
HTML element (not for graph), and that it should not get an 'x' parameter (along
with some value).
[Note on MathJax and labels]
............................
Independently of this module, will render all TeX code
within the ``<render>`` section into nice mathematical formulas. Just
remember to wrap it in one of::
\( and \) - for inline formulas (formulas surrounded by
standard text)
\[ and \] - if you want the formula to be a separate line
It is possible to define a label in standard TeX notation. The JS
library MathJax will work on these labels also because they are
inserted on top of the plot as standard HTML (text within a DIV).
If the label is dynamic, i.e. it will contain some text (numeric, or other)
that has to be updated on a parameter's change, then one can define
a special function to handle this. The "output" of such a function must be
set to "none", and the JavaScript code inside this function must update the
MathJax element by itself. Before exiting, MathJax typeset function should
be called so that the new text will be re-rendered by MathJax. For example,
<render>
...
<span id="dynamic_mathjax"></span>
</render>
...
<function output="none" el_id="dynamic_mathjax">
<![CDATA[
var out_text;
out_text = "\\[\\mathrm{Percent \\space of \\space treated \\space with \\space YSS=\\frac{"
+(treated_men*10)+"\\space men *"
+(your_m_tx_yss/100)+"\\space prev. +\\space "
+((100-treated_men)*10)+"\\space women *"
+(your_f_tx_yss/100)+"\\space prev.}"
+"{1000\\space total\\space treated\\space patients}"
+"="+drummond_combined[0][1]+"\\%}\\]";
mathjax_for_prevalence_calcs+="\\[\\mathrm{Percent \\space of \\space untreated \\space with \\space YSS=\\frac{"
+(untreated_men*10)+"\\space men *"
+(your_m_utx_yss/100)+"\\space prev. +\\space "
+((100-untreated_men)*10)+"\\space women *"
+(your_f_utx_yss/100)+"\\space prev.}"
+"{1000\\space total\\space untreated\\space patients}"
+"="+drummond_combined[1][1]+"\\%}\\]";
$("#dynamic_mathjax").html(out_text);
MathJax.Hub.Queue(["Typeset",MathJax.Hub,"dynamic_mathjax"]);
]]>
</function>
...
Plot tag
........
``Plot`` tag inside ``configuration`` tag defines settings for plot output.
Required parameters::
xrange: 2 functions that must return value. Value is constant (3.1415)
or depend on parameter from parameters section:
<xrange>
<min>return 0;</min>
<max>return 30;</max>
</xrange>
or
<xrange>
<min>return -a;</min>
<max>return a;</max>
</xrange>
All functions will be calculated over domain between xrange:min
and xrange:max. Xrange depending on parameter is extremely
useful when domain(s) of your function(s) depends on parameter
(like circle, when parameter is radius and you want to allow
to change it).
Optional parameters::
num_points: Number of data points to generated for the plot. If
this is not set, the number of points will be
calculated as width / 5.
bar_width: If functions are present which are to be plotted as bars,
then this parameter specifies the width of the bars. A
numeric value for this parameter is expected.
bar_align: If functions are present which are to be plotted as bars,
then this parameter specifies how to align the bars relative
to the tick. Available values are "left" and "center".
xticks,
yticks: 3 floating point numbers separated by commas. This
specifies how many ticks are created, what number they
start at, and what number they end at. This is different
from the 'xrange' setting in that it has nothing to do
with the data points - it control what area of the
Cartesian space you will see. The first number is the
first tick's value, the second number is the step
between each tick, the third number is the value of the
last tick. If these configurations are not specified,
Flot will chose them for you based on the data points
set that he is currently plotting. Usually, this results
in a nice graph, however, sometimes you need to fine
grain the controls. For example, when you want to show
a fixed area of the Cartesian space, even when the data
set changes. On it's own, Flot will recalculate the
ticks, which will result in a different graph each time.
By specifying the xticks, yticks configurations, only
the plotted data will change - the axes (ticks) will
remain as you have defined them.
xticks_names, yticks_names:
A JSON string which represents a mapping of xticks, yticks
values to some defined strings. If specified, the graph will
not have any xticks, yticks except those for which a string
value has been defined in the JSON string. Note that the
matching will be string-based and not numeric. I.e. if a tick
value was "3.70" before, then inside the JSON there should be
a mapping like {..., "3.70": "Some string", ...}. Example:
<xticks_names>
<![CDATA[
{
"1": "Treated", "2": "Not Treated",
"4": "Treated", "5": "Not Treated",
"7": "Treated", "8": "Not Treated"
}
]]>
</xticks_names>
<yticks_names>
<![CDATA[
{"0": "0%", "10": "10%", "20": "20%", "30": "30%", "40": "40%", "50": "50%"}
]]>
</yticks_names>
xunits,
yunits: Units values to be set on axes. Use MathJax. Example:
<xunits>\(cm\)</xunits>
<yunits>\(m\)</yunits>
moving_label:
A way to specify a label that should be positioned dynamically,
based on the values of some parameters, or some other factors.
It is similar to a <function>, but it is only valid for a plot
because it is drawn relative to the plot coordinate system.
Multiple "moving_label" configurations can be provided, each one
with a unique text and a unique set of functions that determine
it's dynamic positioning.
Each "moving_label" can have a "color" attribute (CSS color notation),
and a "weight" attribute. "weight" can be one of "normal" or "bold",
and determines the styling of moving label's text.
Each "moving_label" function should return an object with a 'x'
and 'y properties. Within those functions, all of the parameter
names along with their value are available.
Example (note that "return" statement is missing; it will be automatically
inserted by GST):
<moving_label text="Co" weight="bold" color="red>
<![CDATA[ {'x': -50, 'y': c0};]]>
</moving_label>
asymptote:
Add a vertical or horizontal asymptote to the graph which will
be dynamically repositioned based on the specified function.
It is similar to the function in that it provides a JavaScript body function
string. This function will be used to calculate the position of the asymptote
relative to the axis specified by the "type" parameter.
Required parameters:
type:
Which axis should the asymptote be plotted against. Available values
are "x" and "y".
Optional parameters:
color:
The color of the line. A valid CSS color string is expected.
Example
=======
Plotting, sliders and inputs
----------------------------
.. literalinclude:: gst_example_with_documentation.xml
Update of html elements, no plotting
------------------------------------
.. literalinclude:: gst_example_html_element_output.xml
Circle with dynamic radius
--------------------------
.. literalinclude:: gst_example_dynamic_range.xml
Example of a bar graph
----------------------
.. literalinclude:: gst_example_bars.xml
Example of moving labels of graph
---------------------------------
.. literalinclude:: gst_example_dynamic_labels.xml
**********************************************
Xml format of poll module [xmodule]
**********************************************
.. module:: poll_module
Format description
==================
The main tag of Poll module input is:
.. code-block:: xml
<poll_question> ... </poll_question>
``poll_question`` can include any number of the following tags:
any xml and ``answer`` tag. All inner xml, except for ``answer`` tags, we call "question".
poll_question tag
-----------------
Xmodule for creating poll functionality - voting system. The following attributes can
be specified for this tag::
name - Name of xmodule.
[display_name| AUTOGENERATE] - Display name of xmodule. When this attribute is not defined - display name autogenerate with some hash.
[reset | False] - Can reset/revote many time (value = True/False)
answer tag
----------
Define one of the possible answer for poll module. The following attributes can
be specified for this tag::
id - unique identifier (using to identify the different answers)
Inner text - Display text for answer choice.
Example
=======
Examples of poll
----------------
.. code-block:: xml
<poll_question name="second_question" display_name="Second question">
<h3>Age</h3>
<p>How old are you?</p>
<answer id="less18">&lt; 18</answer>
<answer id="10_25">from 10 to 25</answer>
<answer id="more25">&gt; 25</answer>
</poll_question>
Examples of poll with unable reset functionality
------------------------------------------------
.. code-block:: xml
<poll_question name="first_question_with_reset" display_name="First question with reset"
reset="True">
<h3>Your gender</h3>
<p>You are man or woman?</p>
<answer id="man">Man</answer>
<answer id="woman">Woman</answer>
</poll_question>
\ No newline at end of file
#################
Symbolic Response
#################
This document plans to document features that the current symbolic response
supports. In general it allows the input and validation of math expressions,
up to commutativity and some identities.
********
Features
********
This is a partial list of features, to be revised as we go along:
* sub and superscripts: an expression following the ``^`` character
indicates exponentiation. To use superscripts in variables, the syntax
is ``b_x__d`` for the variable ``b`` with subscript ``x`` and super
``d``.
An example of a problem::
<symbolicresponse expect="a_b^c + b_x__d" size="30">
<textline math="1"
preprocessorClassName="SymbolicMathjaxPreprocessor"
preprocessorSrc="/static/js/capa/symbolic_mathjax_preprocessor.js"/>
</symbolicresponse>
It's a bit of a pain to enter that.
* The script-style math variant. What would be outputted in latex if you
entered ``\mathcal{N}``. This is used in some variables.
An example::
<symbolicresponse expect="scriptN_B + x" size="30">
<textline math="1"/>
</symbolicresponse>
There is no fancy preprocessing needed, but if you had superscripts or
something, you would need to include that part.
..
Public facing docs for non-developers go here. Please do not add any Python
dependencies for code introspection here (we may temporarily host it some
place where those dependencies are cumbersome to build).
edX Data Documentation
======================
The following documents are targetted at those who are working with various data formats consumed and produced by the edX platform -- primarily course authors and those who are conducting research on data in our system. Developer oriented discussion of architecture and strictly internal APIs should be documented elsewhere.
Course Data Formats
-------------------
These are data formats written by people to specify course structure and content. Some of this is abstracted away if you are using the Studio authoring user interface.
.. toctree::
:maxdepth: 2
course_data_formats/course_xml.rst
course_data_formats/grading.rst
Specific Problem Types
^^^^^^^^^^^^^^^^^^^^^^
.. toctree::
:maxdepth: 1
course_data_formats/drag_and_drop/drag_and_drop_input.rst
course_data_formats/graphical_slider_tool/graphical_slider_tool.rst
course_data_formats/poll_module/poll_module.rst
course_data_formats/conditional_module/conditional_module.rst
course_data_formats/custom_response.rst
Internal Data Formats
---------------------
These document describe how we store course structure, student state/progress, and events internally. Useful for developers or researchers who interact with our raw data exports.
.. toctree::
:maxdepth: 2
internal_data_formats/sql_schema.rst
internal_data_formats/discussion_data.rst
internal_data_formats/tracking_logs.rst
Indices and tables
==================
* :ref:`search`
######################
Discussion Forums Data
######################
Discussions in edX are stored in a MongoDB database as collections of JSON documents.
The primary collection holding all posts and comments written by users is `contents`. There are two types of objects stored here, though they share much of the same structure. A `CommentThread` represents a comment that opens a new thread -- usually a student question of some sort. A `Comment` is a reply in the conversation started by a `CommentThread`.
*****************
Shared Attributes
*****************
The attributes that `Comment` and `CommentThread` objects share are listed below.
`_id`
-----
The 12-byte MongoDB unique ID for this collection. Like all MongoDB IDs, they are monotonically increasing and the first four bytes are a timestamp.
`_type`
-------
`CommentThread` or `Comment` depending on the type of object.
`anonymous`
-----------
If true, this `Comment` or `CommentThread` will show up as written by anonymous, even to those who have moderator privileges in the forums.
`anonymous_to_peers`
--------------------
The idea behind this field was that `anonymous_to_peers = true` would make the the comment appear anonymous to your fellow students, but would allow the course staff to see who you were. However, that was never implemented in the UI, and only `anonymous` is actually used. The `anonymous_to_peers` field is always false.
`at_position_list`
------------------
No longer used. Child comments (replies) are just sorted by their `created_at` timestamp instead.
`author_id`
-----------
The user who wrote this. Corresponds to the user IDs we store in our MySQL database as `auth_user.id`
`body`
------
Text of the comment in Markdown. UTF-8 encoded.
`course_id`
-----------
The full course_id of the course that this comment was made in, including org and run. This value can be seen in the URL when browsing the courseware section. Example: `BerkeleyX/Stat2.1x/2013_Spring`
`created_at`
------------
Timestamp in UTC. Example: `ISODate("2013-02-21T03:03:04.587Z")`
`updated_at`
------------
Timestamp in UTC. Example: `ISODate("2013-02-21T03:03:04.587Z")`
`votes`
-------
Both `CommentThread` and `Comment` objects support voting. `Comment` objects that are replies to other comments still have this attribute, even though there is no way to actually vote on them in the UI. This attribute is a dictionary that has the following inside:
* `up` = list of User IDs that up-voted this comment or thread.
* `down` = list of User IDs that down-voted this comment or thread (no longer used).
* `up_count` = total upvotes received.
* `down_count` = total downvotes received (no longer used).
* `count` = total votes cast.
* `point` = net vote, now always equal to `up_count`.
A user only has one vote per `Comment` or `CommentThread`. Though it's still written to the database, the UI no longer displays an option to downvote anything.
*************
CommentThread
*************
The following fields are specific to `CommentThread` objects. Each thread in the forums is represented by one `CommentThread`.
`closed`
--------
If true, this thread was closed by a forum moderator/admin.
`comment_count`
---------------
The number of comment replies in this thread. This includes all replies to replies, but does not include the original comment that started the thread. So if we had::
CommentThread: "What's a good breakfast?"
* Comment: "Just eat cereal!"
* Comment: "Try a Loco Moco, it's amazing!"
* Comment: "A Loco Moco? Only if you want a heart attack!"
* Comment: "But it's worth it! Just get a spam musubi on the side."
In that exchange, the `comment_count` for the `CommentThread` is `4`.
`commentable_id`
----------------
We can attach a discussion to any piece of content in the course, or to top level categories like "General" and "Troubleshooting". When the `commentable_id` is a high level category, it's specified in the course's policy file. When it's a specific content piece (e.g. `600x_l5_p8`, meaning 6.00x, Lecture Sequence 5, Problem 8), it's taken from a discussion module in the course.
`last_activity_at`
------------------
Timestamp in UTC indicating the last time there was activity in the thread (new posts, edits, etc). Closing the thread does not affect the value in this field.
`tags_array`
------------
Meant to be a list of tags that were user definable, but no longer used.
`title`
-------
Title of the thread, UTF-8 string.
*******
Comment
*******
The following fields are specific to `Comment` objects. A `Comment` is a reply to a `CommentThread` (so an answer to the question), or a reply to another `Comment` (a comment about somebody's answer). It used to be the case that `Comment` replies could nest much more deeply, but we later capped it at just these three levels (question, answer, comment) much in the way that StackOverflow does.
`endorsed`
----------
Boolean value, true if a forum moderator or instructor has marked that this `Comment` is a correct answer for whatever question the thread was asking. Exists for `Comments` that are replies to other `Comments`, but in that case `endorsed` is always false because there's no way to endorse such comments through the UI.
`comment_thread_id`
-------------------
What `CommentThread` are we a part of? All `Comment` objects have this.
`parent_id`
-----------
The `parent_id` is the `_id` of the `Comment` that this comment was made in reply to. Note that this only occurs in a `Comment` that is a reply to another `Comment`; it does not appear in a `Comment` that is a reply to a `CommentThread`.
`parent_ids`
------------
The `parent_ids` attribute appears in all `Comment` objects, and contains the `_id` of all ancestor comments. Since the UI now prevents comments from being nested more than one layer deep, it will only ever have at most one element in it. If a `Comment` has no parent, it's an empty list.
##############################
Student Info and Progress Data
##############################
The following sections detail how edX stores student state data internally, and is useful for developers and researchers who are examining database exports. This information includes demographic information collected at signup, course enrollment, course progress, and certificate status.
Conventions to keep in mind:
* We currently use MySQL 5.1 with InnoDB tables
* All strings are stored as UTF-8.
* All datetimes are stored as UTC.
* Tables that are built into the Django framework are not documented here unless we use them in unconventional ways.
All of our tables will be described below, first in summary form with field types and constraints, and then with a detailed explanation of each field. For those not familiar with the MySQL schema terminology in the table summaries:
`Type`
This is the kind of data it is, along with the size of the field. When a numeric field has a length specified, it just means that's how many digits we want displayed -- it has no affect on the number of bytes used.
.. list-table::
:widths: 10 80
:header-rows: 1
* - Value
- Meaning
* - `int`
- 4 byte integer.
* - `smallint`
- 2 byte integer, sometimes used for enumerated values.
* - `tinyint`
- 1 byte integer, but usually just used to indicate a boolean field with 0 = False and 1 = True.
* - `varchar`
- String, typically short and indexable. The length is the number of chars, not bytes (so unicode friendly).
* - `longtext`
- A long block of text, usually not indexed.
* - `date`
- Date
* - `datetime`
- Datetime in UTC, precision in seconds.
`Null`
.. list-table::
:widths: 10 80
:header-rows: 1
* - Value
- Meaning
* - `YES`
- `NULL` values are allowed
* - `NO`
- `NULL` values are not allowed
.. note::
Django often just places blank strings instead of NULL when it wants to indicate a text value is optional. This is used more meaningful for numeric and date fields.
`Key`
.. list-table::
:widths: 10 80
:header-rows: 1
* - Value
- Meaning
* - `PRI`
- Primary key for the table, usually named `id`, unique
* - `UNI`
- Unique
* - `MUL`
- Indexed for fast lookup, but the same value can appear multiple times. A Unique index that allows `NULL` can also show up as `MUL`.
****************
User Information
****************
`auth_user`
===========
The `auth_user` table is built into the Django web framework that we use. It holds generic information necessary for basic login and permissions information. It has the following fields::
+------------------------------+--------------+------+-----+
| Field | Type | Null | Key |
+------------------------------+--------------+------+-----+
| id | int(11) | NO | PRI |
| username | varchar(30) | NO | UNI |
| first_name | varchar(30) | NO | | # Never used
| last_name | varchar(30) | NO | | # Never used
| email | varchar(75) | NO | UNI |
| password | varchar(128) | NO | |
| is_staff | tinyint(1) | NO | |
| is_active | tinyint(1) | NO | |
| is_superuser | tinyint(1) | NO | |
| last_login | datetime | NO | |
| date_joined | datetime | NO | |
| status | varchar(2) | NO | | # No longer used
| email_key | varchar(32) | YES | | # No longer used
| avatar_type | varchar(1) | NO | | # No longer used
| country | varchar(2) | NO | | # No longer used
| show_country | tinyint(1) | NO | | # No longer used
| date_of_birth | date | YES | | # No longer used
| interesting_tags | longtext | NO | | # No longer used
| ignored_tags | longtext | NO | | # No longer used
| email_tag_filter_strategy | smallint(6) | NO | | # No longer used
| display_tag_filter_strategy | smallint(6) | NO | | # No longer used
| consecutive_days_visit_count | int(11) | NO | | # No longer used
+------------------------------+--------------+------+-----+
`id`
----
Primary key, and the value typically used in URLs that reference the user. A user has the same value for `id` here as they do in the MongoDB database's users collection. Foreign keys referencing `auth_user.id` will often be named `user_id`, but are sometimes named `student_id`.
`username`
----------
The unique username for a user in our system. It may contain alphanumeric, _, @, +, . and - characters. The username is the only information that the students give about themselves that we currently expose to other students. We have never allowed people to change their usernames so far, but that's not something we guarantee going forward.
`first_name`
------------
.. note::
Not used; we store a user's full name in `auth_userprofile.name` instead.
`last_name`
-----------
.. note::
Not used; we store a user's full name in `auth_userprofile.name` instead.
`email`
-------
Their email address. While Django by default makes this optional, we make it required, since it's the primary mechanism through which people log in. Must be unique to each user. Never shown to other users.
`password`
----------
A hashed version of the user's password. Depending on when the password was last set, this will either be a SHA1 hash or PBKDF2 with SHA256 (Django 1.3 uses the former and 1.4 the latter).
`is_staff`
----------
This value is `1` if the user is a staff member *of edX* with corresponding elevated privileges that cut across courses. It does not indicate that the person is a member of the course staff for any given course. Generally, users with this flag set to 1 are either edX program managers responsible for course delivery, or edX developers who need access for testing and debugging purposes. People who have `is_staff = 1` get instructor privileges on all courses, along with having additional debug information show up in the instructor tab.
Note that this designation has no bearing with a user's role in the forums, and confers no elevated privileges there.
Most users have a `0` for this value.
`is_active`
-----------
This value is `1` if the user has clicked on the activation link that was sent to them when they created their account, and `0` otherwise. Users who have `is_active = 0` generally cannot log into the system. However, when users first create their account, they are automatically logged in even though they are not active. This is to let them experience the site immediately without having to check their email. They just get a little banner at the top of their dashboard reminding them to check their email and activate their account when they have time. If they log out, they won't be able to log back in again until they've activated. However, because our sessions last a long time, it is theoretically possible for someone to use the site as a student for days without being "active".
Once `is_active` is set to `1`, the only circumstance where it would be set back to `0` would be if we decide to ban the user (which is very rare, manual operation).
`is_superuser`
--------------
Value is `1` if the user has admin privileges. Only the earliest developers of the system have this set to `1`, and it's no longer really used in the codebase. Set to 0 for almost everybody.
`last_login`
------------
A datetime of the user's last login. Should not be used as a proxy for activity, since people can use the site all the time and go days between logging in and out.
`date_joined`
-------------
Date that the account was created (NOT when it was activated).
`(obsolete fields)`
-------------------
All the following fields were added by an application called Askbot, a discussion forum package that is no longer part of the system:
* `status`
* `email_key`
* `avatar_type`
* `country`
* `show_country`
* `date_of_birth`
* `interesting_tags`
* `ignored_tags`
* `email_tag_filter_strategy`
* `display_tag_filter_strategy`
* `consecutive_days_visit_count`
Only users who were part of the prototype 6.002x course run in the Spring of 2012 would have any information in these fields. Even with those users, most of this information was never collected. Only the fields that are automatically generated have any values in them, such as tag settings.
These fields are completely unrelated to the discussion forums we currently use, and will eventually be dropped from this table.
`auth_userprofile`
==================
The `auth_userprofile` table is mostly used to store user demographic information collected during the signup process. We also use it to store certain additional metadata relating to certificates. Every row in this table corresponds to one row in `auth_user`::
+--------------------+--------------+------+-----+
| Field | Type | Null | Key |
+--------------------+--------------+------+-----+
| id | int(11) | NO | PRI |
| user_id | int(11) | NO | UNI |
| name | varchar(255) | NO | MUL |
| language | varchar(255) | NO | MUL | # Prototype course users only
| location | varchar(255) | NO | MUL | # Prototype course users only
| meta | longtext | NO | |
| courseware | varchar(255) | NO | | # No longer used
| gender | varchar(6) | YES | MUL | # Only users signed up after prototype
| mailing_address | longtext | YES | | # Only users signed up after prototype
| year_of_birth | int(11) | YES | MUL | # Only users signed up after prototype
| level_of_education | varchar(6) | YES | MUL | # Only users signed up after prototype
| goals | longtext | YES | | # Only users signed up after prototype
| allow_certificate | tinyint(1) | NO | |
+--------------------+--------------+------+-----+
There is an important split in demographic data gathered for the students who signed up during the MITx prototype phase in the spring of 2012, and those that signed up afterwards.
`id`
----
Primary key, not referenced anywhere else.
`user_id`
---------
A foreign key that maps to `auth_user.id`.
`name`
------
String for a user's full name. We make no constraints on language or breakdown into first/last name. The names are never shown to other students. Foreign students usually enter a romanized version of their names, but not always.
It used to be our policy to require manual approval of name changes to guard the integrity of the certificates. Students would submit a name change request and someone from the team would approve or reject as appropriate. Later, we decided to allow the name changes to take place automatically, but to log previous names in the `meta` field.
`language`
----------
User's preferred language, asked during the sign up process for the 6.002x prototype course given in the Spring of 2012. This information stopped being collected after the transition from MITx to edX happened, but we never removed the values from our first group of students. Sometimes written in those languages.
`location`
----------
User's location, asked during the sign up process for the 6.002x prototype course given in the Spring of 2012. We weren't specific, so people tended to put the city they were in, though some just specified their country and some got as specific as their street address. Again, sometimes romanized and sometimes written in their native language. Like `language`, we stopped collecting this field when we transitioned from MITx to edX, so it's only available for our first batch of students.
`meta`
------
An optional, freeform text field that stores JSON data. This was a hack to allow us to associate arbitrary metadata with a user. An example of the JSON that can be stored here is::
{
"old_names" : [
["David Ormsbee", "I want to add my middle name as well.", "2012-11-15T17:28:12.658126"],
["Dave Ormsbee", "Dave's too informal for a certificate.", "2013-02-07T11:15:46.524331"]
],
"old_emails" : [["dormsbee@mitx.mit.edu", "2012-10-18T15:21:41.916389"]],
"6002x_exit_response" : {
"rating": ["6"],
"teach_ee": ["I do not teach EE."],
"improvement_textbook": ["I'd like to get the full PDF."],
"future_offerings": ["true"],
"university_comparison":
["This course was <strong>on the same level</strong> as the university class."],
"improvement_lectures": ["More PowerPoint!"],
"highest_degree": ["Bachelor's degree."],
"future_classes": ["true"],
"future_updates": ["true"],
"favorite_parts": ["Releases, bug fixes, and askbot."]
}
}
The following are details about this metadata. Please note that the fields described below are found as JSON attributes *inside* the `meta` field, and are *not* separate database fields of their own.
`old_names`
A list of the previous names this user had, and the timestamps at which they submitted a request to change those names. These name change request submissions used to require a staff member to approve it before the name change took effect. This is no longer the case, though we still record their previous names.
Note that the value stored for each entry is the name they had, not the name they requested to get changed to. People often changed their names as the time for certificate generation approached, to replace nicknames with their actual names or correct spelling/punctuation errors.
The timestamps are UTC, like all datetimes stored in our system.
`old_emails`
A list of previous emails this user had, with timestamps of when they changed them, in a format similar to `old_names`. There was never an approval process for this.
The timestamps are UTC, like all datetimes stored in our system.
`6002x_exit_response`
Answers to a survey that was sent to students after the prototype 6.002x course in the Spring of 2012. The questions and number of questions were randomly selected to measure how much survey length affected response rate. Only students from this course have this field.
`courseware`
------------
This can be ignored. At one point, it was part of a way to do A/B tests, but it has not been used for anything meaningful since the conclusion of the prototype course in the spring of 2012.
`gender`
--------
Dropdown field collected during student signup. We only started collecting this information after the transition from MITx to edX, so prototype course students will have `NULL` for this field.
.. list-table::
:widths: 10 80
:header-rows: 1
* - Value
- Meaning
* - `NULL`
- This student signed up before this information was collected
* - `''` (blank)
- User did not specify gender
* - `'f'`
- Female
* - `'m'`
- Male
* - `'o'`
- Other
`mailing_address`
-----------------
Text field collected during student signup. We only started collecting this information after the transition from MITx to edX, so prototype course students will have `NULL` for this field. Students who elected not to enter anything will have a blank string.
`year_of_birth`
---------------
Dropdown field collected during student signup. We only started collecting this information after the transition from MITx to edX, so prototype course students will have `NULL` for this field. Students who decided not to fill this in will also have NULL.
`level_of_education`
--------------------
Dropdown field collected during student signup. We only started collecting this information after the transition from MITx to edX, so prototype course students will have `NULL` for this field.
.. list-table::
:widths: 10 80
:header-rows: 1
* - Value
- Meaning
* - `NULL`
- This student signed up before this information was collected
* - `''` (blank)
- User did not specify level of education.
* - `'p'`
- Doctorate
* - `'p_se'`
- Doctorate in science or engineering (no longer used)
* - `'p_oth'`
- Doctorate in another field (no longer used)
* - `'m'`
- Master's or professional degree
* - `'b'`
- Bachelor's degree
* - `'a'`
- Associate's degree
* - `'hs'`
- Secondary/high school
* - `'jhs'`
- Junior secondary/junior high/middle school
* - `'el'`
- Elementary/primary school
* - `'none'`
- None
* - `'other'`
- Other
`goals`
-------
Text field collected during student signup in response to the prompt, "Goals in signing up for edX". We only started collecting this information after the transition from MITx to edX, so prototype course students will have `NULL` for this field. Students who elected not to enter anything will have a blank string.
`allow_certificate`
-------------------
Set to `1` for most students. This field is set to `0` if log analysis has revealed that this student is accessing our site from a country that the US has an embargo against. At this time, we do not issue certificates to students from those countries.
`student_courseenrollment`
==========================
A row in this table represents a student's enrollment for a particular course run. If they decide to unenroll in the course, we delete their entry in this table, but we still leave all their state in `courseware_studentmodule` untouched.
`id`
----
Primary key.
`user_id`
---------
Student's ID in `auth_user.id`
`course_id`
-----------
The ID of the course run they're enrolling in (e.g. `MITx/6.002x/2012_Fall`). You can get this from the URL when you're viewing courseware on your browser.
`created`
---------
Datetime of enrollment, UTC.
*******************
Courseware Progress
*******************
Any piece of content in the courseware can store state and score in the `courseware_studentmodule` table. Grades and the user Progress page are generated by doing a walk of the course contents, searching for graded items, looking up a student's entries for those items in `courseware_studentmodule` via `(course_id, student_id, module_id)`, and then applying the grade weighting found in the course policy and grading policy files. Course policy files determine how much weight one problem has relative to another, and grading policy files determine how much categories of problems are weighted (e.g. HW=50%, Final=25%, etc.).
.. warning::
**Modules might not be what you expect!**
It's important to understand what "modules" are in the context of our system, as the terminology can be confusing. For the conventions of this table and many parts of our code, a "module" is a content piece that appears in the courseware. This can be nearly anything that appears when users are in the courseware tab: a video, a piece of HTML, a problem, etc. Modules can also be collections of other modules, such as sequences, verticals (modules stacked together on the same page), weeks, chapters, etc. In fact, the course itself is a top level module that contains all the other contents of the course as children. You can imagine the entire course as a tree with modules at every node.
Modules can store state, but whether and how they do so is up to the implemenation for that particular kind of module. When a user loads page, we look up all the modules they need to render in order to display it, and then we ask the database to look up state for those modules for that user. If there is corresponding entry for that user for a given module, we create a new row and set the state to an empty JSON dictionary.
`courseware_studentmodule`
==========================
The `courseware_studentmodule` table holds all courseware state for a given user. Every student has a separate row for every piece of content in the course, making this by far our largest table::
+-------------+--------------+------+-----+
| Field | Type | Null | Key |
+-------------+--------------+------+-----+
| id | int(11) | NO | PRI |
| module_type | varchar(32) | NO | MUL |
| module_id | varchar(255) | NO | MUL |
| student_id | int(11) | NO | MUL |
| state | longtext | YES | |
| grade | double | YES | MUL | # problem, selfassessment, and combinedopenended use this
| created | datetime | NO | MUL |
| modified | datetime | NO | MUL |
| max_grade | double | YES | | # problem, selfassessment, and combinedopenended use this
| done | varchar(8) | NO | MUL | # ignore this
| course_id | varchar(255) | NO | MUL |
+-------------+--------------+------+-----+
`id`
----
Primary key. Rarely used though, since most lookups on this table are searches on the three tuple of `(course_id, student_id, module_id)`.
`module_type`
-------------
.. list-table::
:widths: 10 80
:header-rows: 0
* - `chapter`
- The top level categories for a course. Each of these is usually labeled as a Week in the courseware, but this is just convention.
* - `combinedopenended`
- A new module type developed for grading open ended questions via self assessment, peer assessment, and machine learning.
* - `conditional`
- A new module type recently developed for 8.02x, this allows you to prevent access to certain parts of the courseware if other parts have not been completed first.
* - `course`
- The top level course module of which all course content is descended.
* - `problem`
- A problem that the user can submit solutions for. We have many different varieties.
* - `problemset`
- A collection of problems and supplementary materials, typically used for homeworks and rendered as a horizontal icon bar in the courseware. Use is inconsistent, and some courses use a `sequential` instead.
* - `selfassessment`
- Self assessment problems. An early test of the open ended grading system that is not in widespread use yet. Recently deprecated in favor of `combinedopenended`.
* - `sequential`
- A collection of videos, problems, and other materials, rendered as a horizontal icon bar in the courseware.
* - `timelimit`
- A special module that records the time you start working on a piece of courseware and enforces time limits, used for Pearson exams. This hasn't been completely generalized yet, so is not available for widespread use.
* - `videosequence`
- A collection of videos, exercise problems, and other materials, rendered as a horizontal icon bar in the courseware. Use is inconsistent, and some courses use a `sequential` instead.
There's been substantial muddling of our container types, particularly between sequentials, problemsets, and videosequences. In the beginning we only had sequentials, and these ended up being used primarily for two purposes: creating a sequence of lecture videos and exercises for instruction, and creating homework problem sets. The `problemset` and `videosequence` types were created with the hope that our system would have a better semantic understanding of what a sequence actually represented, and could at a later point choose to render them differently to the user if it was appropriate. Due to a variety of reasons, migration over to this has been spotty. They all render the same way at the moment.
`module_id`
-----------
Unique ID for a distinct piece of content in a course, these are recorded as URLs of the form `i4x://{org}/{course_num}/{module_type}/{module_name}`. Having URLs of this form allows us to give content a canonical representation even as we are in a state of transition between backend data stores.
.. list-table:: Breakdown of example `module_id`: `i4x://MITx/3.091x/problemset/Sample_Problems`
:widths: 10 20 70
:header-rows: 1
* - Part
- Example
- Definition
* - `i4x://`
-
- Just a convention we ran with. We had plans for the domain `i4x.org` at one point.
* - `org`
- `MITx`
- The organization part of the ID, indicating what organization created this piece of content.
* - `course_num`
- `3.091x`
- The course number this content was created for. Note that there is no run information here, so you can't know what runs of the course this content is being used for from the `module_id` alone; you have to look at the `courseware_studentmodule.course_id` field.
* - `module_type`
- `problemset`
- The module type, same value as what's in the `courseware_studentmodule.module_type` field.
* - `module_name`
- `Sample_Problems`
- The name given for this module by the content creators. If the module was not named, the system will generate a name based on the type and a hash of its contents (ex: `selfassessment_03c483062389`).
`student_id`
------------
A reference to `auth_user.id`, this is the student that this module state row belongs to.
`state`
-------
This is a JSON text field where different module types are free to store their state however they wish.
Container Modules: `course`, `chapter`, `problemset`, `sequential`, `videosequence`
The state for all of these is a JSON dictionary indicating the user's last known position within this container. This is 1-indexed, not 0-indexed, mostly because it went out that way at one point and we didn't want to later break saved navigation state for users.
Example: `{"position" : 3}`
When this user last interacted with this course/chapter/etc., they had clicked on the third child element. Note that the position is a simple index and not a `module_id`, so if you rearranged the order of the contents, it would not be smart enough to accomodate the changes and would point users to the wrong place.
The hierarchy goes: `course > chapter > (problemset | sequential | videosequence)`
`combinedopenended`
TODO: More details to come.
`conditional`
Conditionals don't actually store any state, so this value is always an empty JSON dictionary (`'{}'`). We should probably remove these entries altogether.
`problem`
There are many kinds of problems supported by the system, and they all have different state requirements. Note that one problem can have many different response fields. If a problem generates a random circuit and asks five questions about it, then all of that is stored in one row in `courseware_studentmodule`.
TODO: Write out different problem types and their state.
`selfassessment`
TODO: More details to come.
`timelimit`
This very uncommon type was only used in one Pearson exam for one course, and the format may change significantly in the future. It is currently a JSON dictionary with fields:
.. list-table::
:widths: 10 20 70
:header-rows: 1
* - JSON field
- Example
- Definition
* - `beginning_at`
- `1360590255.488154`
- UTC time as measured in seconds since UNIX epoch representing when the exam was started.
* - `ending_at`
- `1360596632.559758`
- UTC time as measured in seconds since UNIX epoch representing the time the exam will close.
* - `accomodation_codes`
- `DOUBLE`
- (optional) Sometimes students are given more time for accessibility reasons. Possible values are:
* `NONE`: no time accommodation
* `ADDHALFTIME`: 1.5X normal time allowance
* `ADD30MIN`: normal time allowance + 30 minutes
* `DOUBLE`: 2X normal time allowance
* `TESTING`: extra long period (for testing/debugging)
`grade`
-------
Floating point value indicating the total unweighted grade for this problem that the student has scored. Basically how many responses they got right within the problem.
Only `problem` and `selfassessment` types use this field. All other modules set this to `NULL`. Due to a quirk in how rendering is done, `grade` can also be `NULL` for a tenth of a second or so the first time that a user loads a problem. The initial load will trigger two writes, the first of which will set the `grade` to `NULL`, and the second of which will set it to `0`.
`created`
---------
Datetime when this row was created (i.e. when the student first accessed this piece of content).
`modified`
----------
Datetime when we last updated this row. Set to be equal to `created` at first. A change in `modified` implies that there was a state change, usually in response to a user action like saving or submitting a problem, or clicking on a navigational element that records its state. However it can also be triggered if the module writes multiple times on its first load, like problems do (see note in `grade`).
`max_grade`
-----------
Floating point value indicating the total possible unweighted grade for this problem, or basically the number of responses that are in this problem. Though in practice it's the same for every entry with the same `module_id`, it is technically possible for it to be anything. The problems are dynamic enough where you could create a random number of responses if you wanted. This a bad idea and will probably cause grading errors, but it is possible.
Another way in which `max_grade` can differ between entries with the same `module_id` is if the problem was modified after the `max_grade` was written and the user never went back to the problem after it was updated. This might happen if a member of the course staff puts out a problem with five parts, realizes that the last part doesn't make sense, and decides to remove it. People who saw and answered it when it had five parts and never came back to it after the changes had been made will have a `max_grade` of `5`, while people who saw it later will have a `max_grade` of `4`.
These complexities in our grading system are a high priority target for refactoring in the near future.
Only `problem` and `selfassessment` types use this field. All other modules set this to `NULL`.
`done`
------
Ignore this field. It was supposed to be an indication whether something was finished, but was never properly used and is just `'na'` in every row.
`course_id`
-----------
The course that this row applies to, represented in the form org/course/run (ex: `MITx/6.002x/2012_Fall`). The same course content (same `module_id`) can be used in different courses, and a student's state needs to be tracked separately for each course.
************
Certificates
************
`certificates_generatedcertificate`
===================================
The generatedcertificate table tracks certificate state for students who have been graded after a course completes. Currently the table is only populated when a course ends and a script is run to grade students who have completed the course::
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | MUL | NULL | |
| download_url | varchar(128) | NO | | NULL | |
| grade | varchar(5) | NO | | NULL | |
| course_id | varchar(255) | NO | MUL | NULL | |
| key | varchar(32) | NO | | NULL | |
| distinction | tinyint(1) | NO | | NULL | |
| status | varchar(32) | NO | | NULL | |
| verify_uuid | varchar(32) | NO | | NULL | |
| download_uuid | varchar(32) | NO | | NULL | |
| name | varchar(255) | NO | | NULL | |
| created_date | datetime | NO | | NULL | |
| modified_date | datetime | NO | | NULL | |
| error_reason | varchar(512) | NO | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
`user_id`, `course_id`
----------------------
The table is indexed by user and course
`status`
--------
Status may be one of these states:
* `unavailable`
* `generating`
* `regenerating`
* `deleting`
* `deleted`
* `downloadable`
* `notpassing`
* `restricted`
* `error`
After a course has been graded and certificates have been issued status will be one of:
* `downloadable`
* `notpassing`
* `restricted`
If the status is `downloadable` then the student passed the course and there will be a certificate available for download.
`download_url`
--------------
The `download_uuid` has the full URL to the certificate
`download_uuid`, `verify_uuid`
------------------------------
The two uuids are what uniquely identify the download url and the url used to download the certificate.
`distinction`
-------------
This was used for letters of distinction for 188.1x and is not being used for any current courses
`name`
------
This field records the name of the student that was set at the time the student was graded and the certificate was generated.
`grade`
-------
The grade of the student recorded at the time the certificate was generated. This may be different than the current grade since grading is only done once for a course when it ends.
#############
Tracking Logs
#############
* Tracking logs are made available as separate tar files on S3 in the course-data bucket.
* They are represented as JSON files that catalog all user interactions with the site.
* To avoid filename collisions the tracking logs are organized by server name, where each directory corresponds to a server where they were stored.
*************
Common Fields
*************
.. list-table::
:widths: 10 40 10 25
:header-rows: 1
* - field
- details
- type
- values/format
* - `username`
- username of the user who triggered the event, empty string for anonymous events (not logged in)
- string
-
* - `session`
- key identifying the user's session, may be undefined
- string
- 32 digits key
* - `time`
- GMT time the event was triggered
- string
- `YYYY-MM-DDThh:mm:ss.xxxxxx`
* - `ip`
- user ip address
- string
-
* - `agent`
- users browser agent string
- string
-
* - `page`
- page the user was visiting when the event was generated
- string
- `$URL`
* - event_source
- event source
- string
- `browser`, `server`
* - `event_type`
- type of event triggered, values depends on `event_source`
- string
- *more details listed below*
* - `event`
- specifics of the event (dependenty of the event_type)
- string/json
- *the event string may encode a JSON record*
*************
Event Sources
*************
The `event_source` field identifies whether the event originated in the browser (via javascript) or on the server (during the processing of a request).
Server Events
=============
.. list-table::
:widths: 20 10 10 10 50
:header-rows: 1
* - event_type
- event fields
- type
- values/format
- details
* - `show_answer`
- `problem_id`
- string
-
- id of the problem being shown. Ex: `i4x://MITx/6.00x/problem/L15:L15_Problem_2`
* - `save_problem_check`
- `problem_id`
- string
-
- id of the problem being shown
* -
- `success`
- string
- correct, incorrect
- whether the problem was correct
* -
- `attempts`
- integer
- number of attempts
-
* -
- `correct_map`
- string/json
-
- see details below
* -
- `state`
- string/json
-
- current problem state
* -
- `answers`
- string/json
-
- students answers
* -
- `reset_problem`
- problem_id
- string
- id of the problem being shown
`correct_map` details
---------------------
.. list-table::
:widths: 15 10 15 10
:header-rows: 1
* - correct_map fields
- type
- values/format
- null allowed?
* - hint
- string
-
-
* - hintmode
- boolean
-
- yes
* - correctness
- string
- correct, incorrect
-
* - npoints
- integer
-
- yes
* - msg
- string
-
-
* - queuestate
- string/json
- keys: key, time
-
Browser Events
==============
.. list-table::
:widths: 10 10 8 12 20 10
:header-rows: 1
* - event_type
- fields
- type
- values/format
- details
- example
* - `book`
- `type`
- string
- `gotopage`
-
-
* -
- `old`
- integer
- `$PAGE`
- from page number
- `2`
* -
- `new`
- integer
- `$PAGE`
- to page number
- `25`
* - `book`
- `type`
- string
- `nextpage`
-
-
* -
- new
- integer
- `$PAGE`
- next page number
- `10`
* - `page_close`
- *empty*
- string
-
- 'page' field indicates which page was being closed
-
* - play_video
- `id`
- string
-
- edX id of the video being watched
- `i4x-HarvardX-PH207x-video-Simple_Random_Sample`
* -
- code
- string
-
- youtube id of the video being watched
- `FU3fCJNs94Y`
* -
- `currentTime`
- float
-
- time the video was paused at, in seconds
- `1.264`
* -
- `speed`
- string
- `0.75, 1.0, 1.25, 1.50`
- video speed being played
- `"1.0"`
* - `pause_video`
- `id`
- string
-
- edX id of the video being watched
-
* -
- `code`
- string
-
- youtube id of the video being watched
-
* -
- `currentTime`
- float
-
- time the video was paused at
-
* -
- `speed`
- string
- `0.75, 1.0, 1.25, 1.50`
- video speed being played
-
* - `problem_check`
- *none*
- string
-
- event field contains the values of all input fields from the problem being checked (in the style of GET parameters (`key=value&key=value`))
-
* - `problem_show`
- `problem`
- string
-
- id of the problem being checked
-
* - `seq_goto`
- `id`
- string
-
- edX id of the sequence
-
* -
- `old`
- integer
-
- sequence element being jumped from
- `3`
* -
- `new`
- integer
-
- sequence element being jumped to
- `5`
* - `seq_next`
- `id`
- string
-
- edX id of the sequence
-
* -
- `old`
- integer
-
- sequence element being jumped from
- `4`
* -
- `new`
- integer
-
- sequence element being jumped to
- `6`
* - `rubric_select`
- `location`
- string
-
- location of the rubric's problem
- `i4x://MITx/6.00x/problem/L15:L15_Problem_2`
* -
- `category`
- integer
-
- category number of the rubric selection
-
* -
- `value`
- integer
-
- value selected within the category
-
* - `(oe / peer_grading / staff_grading)`
`_show_problem`
- `location`
- string
-
- the location of the problem whose prompt we're showing
-
* - `(oe / peer_grading / staff_grading)`
`_hide_problem`
- `location`
- string
-
- the location of the problem whose prompt we're hiding
-
* - `oe_show_full_feedback`
- *empty*
-
-
- the page where they're showing full feedback is already recorded
-
* - `oe_show_respond_to_feedback`
- *empty*
-
-
- the page where they're showing the feedback response form is already recorded
-
* - `oe_feedback_response_selected`
- `value`
- integer
-
- the value selected in the feedback response form
-
/*
* basic.css
* ~~~~~~~~~
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox input[type="text"] {
width: 170px;
}
div.sphinxsidebar #searchbox input[type="submit"] {
width: 30px;
}
img {
border: 0;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- general body styles --------------------------------------------------- */
a.headerlink {
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.field-list ul {
padding-left: 1em;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
img.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
background-color: #ffe;
width: 40%;
float: right;
}
p.sidebar-title {
font-weight: bold;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
border: 0;
border-collapse: collapse;
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.field-list td, table.field-list th {
border: 0 !important;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
dl {
margin-bottom: 15px;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dt:target, .highlighted {
background-color: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.refcount {
color: #060;
}
.optional {
font-size: 1.3em;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
tt.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
tt.descclassname {
background-color: transparent;
}
tt.xref, a tt {
background-color: transparent;
font-weight: bold;
}
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}
\ No newline at end of file
/*
* doctools.js
* ~~~~~~~~~~~
*
* Sphinx JavaScript utilities for all documentation.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* select a different prefix for underscore
*/
$u = _.noConflict();
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
"dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
"profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {};
}
*/
/**
* small helper function to urldecode strings
*/
jQuery.urldecode = function(x) {
return decodeURIComponent(x).replace(/\+/g, ' ');
}
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s == 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};
/**
* small function to check if an array contains
* a given item.
*/
jQuery.contains = function(arr, item) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == item)
return true;
}
return false;
};
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node) {
if (node.nodeType == 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
var span = document.createElement("span");
span.className = className;
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this);
});
}
}
return this.each(function() {
highlight(this);
});
};
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated == 'undefined')
return string;
return (typeof translated == 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated == 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
*/
addContextElements : function() {
$('div[id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
},
/**
* workaround a firefox stupidity
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlighted');
});
}, 10);
$('<p class="highlight-link"><a href="javascript:Documentation.' +
'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
.appendTo($('#searchbox'));
}
},
/**
* init the domain index toggle buttons
*/
initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) == 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('#searchbox .highlight-link').fadeOut(300);
$('span.highlighted').removeClass('highlighted');
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this == '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});
/*!
* jQuery JavaScript Library v1.4.2
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Sat Feb 13 22:33:48 2010 -0500
*/
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
.highlight .hll { background-color: #ffffcc }
.highlight { background: #eeffcc; }
.highlight .c { color: #408090; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #007020; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #007020 } /* Comment.Preproc */
.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #303030 } /* Generic.Output */
.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0040D0 } /* Generic.Traceback */
.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #007020 } /* Keyword.Pseudo */
.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #902000 } /* Keyword.Type */
.highlight .m { color: #208050 } /* Literal.Number */
.highlight .s { color: #4070a0 } /* Literal.String */
.highlight .na { color: #4070a0 } /* Name.Attribute */
.highlight .nb { color: #007020 } /* Name.Builtin */
.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.highlight .no { color: #60add5 } /* Name.Constant */
.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #007020 } /* Name.Exception */
.highlight .nf { color: #06287e } /* Name.Function */
.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #bb60d5 } /* Name.Variable */
.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #208050 } /* Literal.Number.Float */
.highlight .mh { color: #208050 } /* Literal.Number.Hex */
.highlight .mi { color: #208050 } /* Literal.Number.Integer */
.highlight .mo { color: #208050 } /* Literal.Number.Oct */
.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
.highlight .sc { color: #4070a0 } /* Literal.String.Char */
.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
.highlight .sx { color: #c65d09 } /* Literal.String.Other */
.highlight .sr { color: #235388 } /* Literal.String.Regex */
.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
.highlight .ss { color: #517918 } /* Literal.String.Symbol */
.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
\ No newline at end of file
/*
* searchtools.js_t
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilties for the full-text search.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
* words. the first one is used to find the occurance, the
* latter for highlighting it.
*/
jQuery.makeSearchSummary = function(text, keywords, hlwords) {
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
var i = textLower.indexOf(this.toLowerCase());
if (i > -1)
start = i;
});
start = Math.max(start - 120, 0);
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<div class="context"></div>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlighted');
});
return rv;
}
/**
* Porter Stemmer
*/
var Stemmer = function() {
var step2list = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
};
var step3list = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
};
var c = "[^aeiou]"; // consonant
var v = "[aeiouy]"; // vowel
var C = c + "[^aeiouy]*"; // consonant sequence
var V = v + "[aeiou]*"; // vowel sequence
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
var s_v = "^(" + C + ")?" + v; // vowel in stem
this.stemWord = function (w) {
var stem;
var suffix;
var firstch;
var origword = w;
if (w.length < 3)
return w;
var re;
var re2;
var re3;
var re4;
firstch = w.substr(0,1);
if (firstch == "y")
w = firstch.toUpperCase() + w.substr(1);
// Step 1a
re = /^(.+?)(ss|i)es$/;
re2 = /^(.+?)([^s])s$/;
if (re.test(w))
w = w.replace(re,"$1$2");
else if (re2.test(w))
w = w.replace(re2,"$1$2");
// Step 1b
re = /^(.+?)eed$/;
re2 = /^(.+?)(ed|ing)$/;
if (re.test(w)) {
var fp = re.exec(w);
re = new RegExp(mgr0);
if (re.test(fp[1])) {
re = /.$/;
w = w.replace(re,"");
}
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1];
re2 = new RegExp(s_v);
if (re2.test(stem)) {
w = stem;
re2 = /(at|bl|iz)$/;
re3 = new RegExp("([^aeiouylsz])\\1$");
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re2.test(w))
w = w + "e";
else if (re3.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
else if (re4.test(w))
w = w + "e";
}
}
// Step 1c
re = /^(.+?)y$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(s_v);
if (re.test(stem))
w = stem + "i";
}
// Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step2list[suffix];
}
// Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step3list[suffix];
}
// Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
re2 = /^(.+?)(s|t)(ion)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
if (re.test(stem))
w = stem;
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1] + fp[2];
re2 = new RegExp(mgr1);
if (re2.test(stem))
w = stem;
}
// Step 5
re = /^(.+?)e$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
re2 = new RegExp(meq1);
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
w = stem;
}
re = /ll$/;
re2 = new RegExp(mgr1);
if (re.test(w) && re2.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
// and turn initial Y back to y
if (firstch == "y")
w = firstch.toLowerCase() + w.substr(1);
return w;
}
}
/**
* Search Module
*/
var Search = {
_index : null,
_queued_query : null,
_pulse_status : -1,
init : function() {
var params = $.getQueryParameters();
if (params.q) {
var query = params.q[0];
$('input[name="q"]')[0].value = query;
this.performSearch(query);
}
},
loadIndex : function(url) {
$.ajax({type: "GET", url: url, data: null, success: null,
dataType: "script", cache: true});
},
setIndex : function(index) {
var q;
this._index = index;
if ((q = this._queued_query) !== null) {
this._queued_query = null;
Search.query(q);
}
},
hasIndex : function() {
return this._index !== null;
},
deferQuery : function(query) {
this._queued_query = query;
},
stopPulse : function() {
this._pulse_status = 0;
},
startPulse : function() {
if (this._pulse_status >= 0)
return;
function pulse() {
Search._pulse_status = (Search._pulse_status + 1) % 4;
var dotString = '';
for (var i = 0; i < Search._pulse_status; i++)
dotString += '.';
Search.dots.text(dotString);
if (Search._pulse_status > -1)
window.setTimeout(pulse, 500);
};
pulse();
},
/**
* perform a search for something
*/
performSearch : function(query) {
// create the required interface elements
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p style="display: none"></p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
this.startPulse();
// index already loaded, the browser was quick!
if (this.hasIndex())
this.query(query);
else
this.deferQuery(query);
},
query : function(query) {
var stopwords = ["and","then","into","it","as","are","in","if","for","no","there","their","was","is","be","to","that","but","they","not","such","with","by","a","on","these","of","will","this","near","the","or","at"];
// Stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = query.split(/\s+/);
var objectterms = [];
for (var i = 0; i < tmp.length; i++) {
if (tmp[i] != "") {
objectterms.push(tmp[i].toLowerCase());
}
if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) ||
tmp[i] == "") {
// skip this "word"
continue;
}
// stem the word
var word = stemmer.stemWord(tmp[i]).toLowerCase();
// select the correct list
if (word[0] == '-') {
var toAppend = excluded;
word = word.substr(1);
}
else {
var toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
}
// only add if not already in the list
if (!$.contains(toAppend, word))
toAppend.push(word);
};
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
// console.debug('SEARCH: searching for:');
// console.info('required: ', searchterms);
// console.info('excluded: ', excluded);
// prepare search
var filenames = this._index.filenames;
var titles = this._index.titles;
var terms = this._index.terms;
var fileMap = {};
var files = null;
// different result priorities
var importantResults = [];
var objectResults = [];
var regularResults = [];
var unimportantResults = [];
$('#search-progress').empty();
// lookup as object
for (var i = 0; i < objectterms.length; i++) {
var others = [].concat(objectterms.slice(0,i),
objectterms.slice(i+1, objectterms.length))
var results = this.performObjectSearch(objectterms[i], others);
// Assume first word is most likely to be the object,
// other words more likely to be in description.
// Therefore put matches for earlier words first.
// (Results are eventually used in reverse order).
objectResults = results[0].concat(objectResults);
importantResults = results[1].concat(importantResults);
unimportantResults = results[2].concat(unimportantResults);
}
// perform the search on the required terms
for (var i = 0; i < searchterms.length; i++) {
var word = searchterms[i];
// no match but word was a required one
if ((files = terms[word]) == null)
break;
if (files.length == undefined) {
files = [files];
}
// create the mapping
for (var j = 0; j < files.length; j++) {
var file = files[j];
if (file in fileMap)
fileMap[file].push(word);
else
fileMap[file] = [word];
}
}
// now check if the files don't contain excluded terms
for (var file in fileMap) {
var valid = true;
// check if all requirements are matched
if (fileMap[file].length != searchterms.length)
continue;
// ensure that none of the excluded terms is in the
// search result.
for (var i = 0; i < excluded.length; i++) {
if (terms[excluded[i]] == file ||
$.contains(terms[excluded[i]] || [], file)) {
valid = false;
break;
}
}
// if we have still a valid result we can add it
// to the result list
if (valid)
regularResults.push([filenames[file], titles[file], '', null]);
}
// delete unused variables in order to not waste
// memory until list is retrieved completely
delete filenames, titles, terms;
// now sort the regular results descending by title
regularResults.sort(function(a, b) {
var left = a[1].toLowerCase();
var right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
});
// combine all results
var results = unimportantResults.concat(regularResults)
.concat(objectResults).concat(importantResults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li style="display:none"></li>');
if (DOCUMENTATION_OPTIONS.FILE_SUFFIX == '') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
dirname = dirname.substring(0, dirname.length-6);
} else if (dirname == 'index/') {
dirname = '';
}
listItem.append($('<a/>').attr('href',
DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
highlightstring + item[2]).html(item[1]));
} else {
// normal html builders
listItem.append($('<a/>').attr('href',
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
highlightstring + item[2]).html(item[1]));
}
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
$.get(DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' +
item[0] + '.txt', function(data) {
if (data != '') {
listItem.append($.makeSearchSummary(data, searchterms, hlterms));
Search.output.append(listItem);
}
listItem.slideDown(5, function() {
displayNextItem();
});
}, "text");
} else {
// no source available, just display title
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount)
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
else
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
Search.status.fadeIn(500);
}
}
displayNextItem();
},
performObjectSearch : function(object, otherterms) {
var filenames = this._index.filenames;
var objects = this._index.objects;
var objnames = this._index.objnames;
var titles = this._index.titles;
var importantResults = [];
var objectResults = [];
var unimportantResults = [];
for (var prefix in objects) {
for (var name in objects[prefix]) {
var fullname = (prefix ? prefix + '.' : '') + name;
if (fullname.toLowerCase().indexOf(object) > -1) {
var match = objects[prefix][name];
var objname = objnames[match[1]][2];
var title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
if (otherterms.length > 0) {
var haystack = (prefix + ' ' + name + ' ' +
objname + ' ' + title).toLowerCase();
var allfound = true;
for (var i = 0; i < otherterms.length; i++) {
if (haystack.indexOf(otherterms[i]) == -1) {
allfound = false;
break;
}
}
if (!allfound) {
continue;
}
}
var descr = objname + _(', in ') + title;
anchor = match[3];
if (anchor == '')
anchor = fullname;
else if (anchor == '-')
anchor = objnames[match[1]][1] + '-' + fullname;
result = [filenames[match[0]], fullname, '#'+anchor, descr];
switch (match[2]) {
case 1: objectResults.push(result); break;
case 0: importantResults.push(result); break;
case 2: unimportantResults.push(result); break;
}
}
}
}
// sort results descending
objectResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
importantResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
unimportantResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
return [importantResults, objectResults, unimportantResults]
}
}
$(document).ready(function() {
Search.init();
});
\ No newline at end of file
/*
* sphinxdoc.css_t
* ~~~~~~~~~~~~~~~
*
* Sphinx stylesheet -- sphinxdoc theme. Originally created by
* Armin Ronacher for Werkzeug.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
'Verdana', sans-serif;
font-size: 14px;
letter-spacing: -0.01em;
line-height: 150%;
text-align: center;
background-color: #BFD1D4;
color: black;
padding: 0;
border: 1px solid #aaa;
margin: 0px 80px 0px 80px;
min-width: 740px;
}
div.document {
background-color: white;
text-align: left;
background-image: url(contents.png);
background-repeat: repeat-x;
}
div.bodywrapper {
margin: 0 240px 0 0;
border-right: 1px solid #ccc;
}
div.body {
margin: 0;
padding: 0.5em 20px 20px 20px;
}
div.related {
font-size: 1em;
}
div.related ul {
background-image: url(navigation.png);
height: 2em;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
div.related ul li {
margin: 0;
padding: 0;
height: 2em;
float: left;
}
div.related ul li.right {
float: right;
margin-right: 5px;
}
div.related ul li a {
margin: 0;
padding: 0 5px 0 5px;
line-height: 1.75em;
color: #EE9816;
}
div.related ul li a:hover {
color: #3CA8E7;
}
div.sphinxsidebarwrapper {
padding: 0;
}
div.sphinxsidebar {
margin: 0;
padding: 0.5em 15px 15px 0;
width: 210px;
float: right;
font-size: 1em;
text-align: left;
}
div.sphinxsidebar h3, div.sphinxsidebar h4 {
margin: 1em 0 0.5em 0;
font-size: 1em;
padding: 0.1em 0 0.1em 0.5em;
color: white;
border: 1px solid #86989B;
background-color: #AFC1C4;
}
div.sphinxsidebar h3 a {
color: white;
}
div.sphinxsidebar ul {
padding-left: 1.5em;
margin-top: 7px;
padding: 0;
line-height: 130%;
}
div.sphinxsidebar ul ul {
margin-left: 20px;
}
div.footer {
background-color: #E3EFF1;
color: #86989B;
padding: 3px 8px 3px 0;
clear: both;
font-size: 0.8em;
text-align: right;
}
div.footer a {
color: #86989B;
text-decoration: underline;
}
/* -- body styles ----------------------------------------------------------- */
p {
margin: 0.8em 0 0.5em 0;
}
a {
color: #CA7900;
text-decoration: none;
}
a:hover {
color: #2491CF;
}
div.body a {
text-decoration: underline;
}
h1 {
margin: 0;
padding: 0.7em 0 0.3em 0;
font-size: 1.5em;
color: #11557C;
}
h2 {
margin: 1.3em 0 0.2em 0;
font-size: 1.35em;
padding: 0;
}
h3 {
margin: 1em 0 -0.3em 0;
font-size: 1.2em;
}
div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a {
color: black!important;
}
h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
display: none;
margin: 0 0 0 0.3em;
padding: 0 0.2em 0 0.2em;
color: #aaa!important;
}
h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
h5:hover a.anchor, h6:hover a.anchor {
display: inline;
}
h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
h5 a.anchor:hover, h6 a.anchor:hover {
color: #777;
background-color: #eee;
}
a.headerlink {
color: #c60f0f!important;
font-size: 1em;
margin-left: 6px;
padding: 0 4px 0 4px;
text-decoration: none!important;
}
a.headerlink:hover {
background-color: #ccc;
color: white!important;
}
cite, code, tt {
font-family: 'Consolas', 'Deja Vu Sans Mono',
'Bitstream Vera Sans Mono', monospace;
font-size: 0.95em;
letter-spacing: 0.01em;
}
tt {
background-color: #f2f2f2;
border-bottom: 1px solid #ddd;
color: #333;
}
tt.descname, tt.descclassname, tt.xref {
border: 0;
}
hr {
border: 1px solid #abc;
margin: 2em;
}
a tt {
border: 0;
color: #CA7900;
}
a tt:hover {
color: #2491CF;
}
pre {
font-family: 'Consolas', 'Deja Vu Sans Mono',
'Bitstream Vera Sans Mono', monospace;
font-size: 0.95em;
letter-spacing: 0.015em;
line-height: 120%;
padding: 0.5em;
border: 1px solid #ccc;
background-color: #f8f8f8;
}
pre a {
color: inherit;
text-decoration: underline;
}
td.linenos pre {
padding: 0.5em 0;
}
div.quotebar {
background-color: #f8f8f8;
max-width: 250px;
float: right;
padding: 2px 7px;
border: 1px solid #ccc;
}
div.topic {
background-color: #f8f8f8;
}
table {
border-collapse: collapse;
margin: 0 -0.5em 0 -0.5em;
}
table td, table th {
padding: 0.2em 0.5em 0.2em 0.5em;
}
div.admonition, div.warning {
font-size: 0.9em;
margin: 1em 0 1em 0;
border: 1px solid #86989B;
background-color: #f7f7f7;
padding: 0;
}
div.admonition p, div.warning p {
margin: 0.5em 1em 0.5em 1em;
padding: 0;
}
div.admonition pre, div.warning pre {
margin: 0.4em 1em 0.4em 1em;
}
div.admonition p.admonition-title,
div.warning p.admonition-title {
margin: 0;
padding: 0.1em 0 0.1em 0.5em;
color: white;
border-bottom: 1px solid #86989B;
font-weight: bold;
background-color: #AFC1C4;
}
div.warning {
border: 1px solid #940000;
}
div.warning p.admonition-title {
background-color: #CF0000;
border-bottom-color: #940000;
}
div.admonition ul, div.admonition ol,
div.warning ul, div.warning ol {
margin: 0.1em 0.5em 0.5em 3em;
padding: 0;
}
div.versioninfo {
margin: 1em 0 0 0;
border: 1px solid #ccc;
background-color: #DDEAF0;
padding: 8px;
line-height: 1.3em;
font-size: 0.9em;
}
.viewcode-back {
font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
'Verdana', sans-serif;
}
div.viewcode-block:target {
background-color: #f4debf;
border-top: 1px solid #ac9;
border-bottom: 1px solid #ac9;
}
\ No newline at end of file
// Underscore.js 0.5.5
// (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the terms of the MIT license.
// Portions of Underscore are inspired by or borrowed from Prototype.js,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore/
(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e<f;e++)c.call(d,
a[e],e,a);else{var g=b.keys(a);f=g.length;for(e=0;e<f;e++)c.call(d,a[g[e]],g[e],a)}}catch(h){if(h!=m)throw h;}return a};b.map=function(a,c,d){if(a&&b.isFunction(a.map))return a.map(c,d);var e=[];b.each(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(a&&b.isFunction(a.reduce))return a.reduce(b.bind(d,e),c);b.each(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(a&&b.isFunction(a.reduceRight))return a.reduceRight(b.bind(d,e),c);
var f=b.clone(b.toArray(a)).reverse();b.each(f,function(g,h){c=d.call(e,c,g,h,a)});return c};b.detect=function(a,c,d){var e;b.each(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.select=function(a,c,d){if(a&&b.isFunction(a.filter))return a.filter(c,d);var e=[];b.each(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];b.each(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.all=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.every))return a.every(c,
d);var e=true;b.each(a,function(f,g,h){(e=e&&c.call(d,f,g,h))||b.breakLoop()});return e};b.any=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.some))return a.some(c,d);var e=false;b.each(a,function(f,g,h){if(e=c.call(d,f,g,h))b.breakLoop()});return e};b.include=function(a,c){if(b.isArray(a))return b.indexOf(a,c)!=-1;var d=false;b.each(a,function(e){if(d=e===c)b.breakLoop()});return d};b.invoke=function(a,c){var d=b.rest(arguments,2);return b.map(a,function(e){return(c?e[c]:e).apply(e,d)})};b.pluck=
function(a,c){return b.map(a,function(d){return d[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,
function(e,f,g){return{value:e,criteria:c.call(d,e,f,g)}}).sort(function(e,f){e=e.criteria;f=f.criteria;return e<f?-1:e>f?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?(e=g+1):(f=g)}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return k.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=function(a,c,d){return c&&!d?k.call(a,
0,c):a[0]};b.rest=function(a,c,d){return k.call(a,b.isUndefined(c)||d?1:c)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.select(a,function(c){return!!c})};b.flatten=function(a){return b.reduce(a,[],function(c,d){if(b.isArray(d))return c.concat(b.flatten(d));c.push(d);return c})};b.without=function(a){var c=b.rest(arguments);return b.select(a,function(d){return!b.include(c,d)})};b.uniq=function(a,c){return b.reduce(a,[],function(d,e,f){if(0==f||(c===true?b.last(d)!=e:!b.include(d,
e)))d.push(e);return d})};b.intersect=function(a){var c=b.rest(arguments);return b.select(b.uniq(a),function(d){return b.all(c,function(e){return b.indexOf(e,d)>=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e<c;e++)d[e]=b.pluck(a,String(e));return d};b.indexOf=function(a,c){if(a.indexOf)return a.indexOf(c);for(var d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,c){if(a.lastIndexOf)return a.lastIndexOf(c);for(var d=
a.length;d--;)if(a[d]===c)return d;return-1};b.range=function(a,c,d){var e=b.toArray(arguments),f=e.length<=1;a=f?0:e[0];c=f?e[0]:e[1];d=e[2]||1;e=Math.ceil((c-a)/d);if(e<=0)return[];e=new Array(e);f=a;for(var g=0;1;f+=d){if((d>0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)});
return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length);
var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false;
if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length==
0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&&
a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g,
" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments);
o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})();
/*
* websupport.js
* ~~~~~~~~~~~~~
*
* sphinx.websupport utilties for all documentation.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
(function($) {
$.fn.autogrow = function() {
return this.each(function() {
var textarea = this;
$.fn.autogrow.resize(textarea);
$(textarea)
.focus(function() {
textarea.interval = setInterval(function() {
$.fn.autogrow.resize(textarea);
}, 500);
})
.blur(function() {
clearInterval(textarea.interval);
});
});
};
$.fn.autogrow.resize = function(textarea) {
var lineHeight = parseInt($(textarea).css('line-height'), 10);
var lines = textarea.value.split('\n');
var columns = textarea.cols;
var lineCount = 0;
$.each(lines, function() {
lineCount += Math.ceil(this.length / columns) || 1;
});
var height = lineHeight * (lineCount + 1);
$(textarea).css('height', height);
};
})(jQuery);
(function($) {
var comp, by;
function init() {
initEvents();
initComparator();
}
function initEvents() {
$('a.comment-close').live("click", function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
});
$('a.vote').live("click", function(event) {
event.preventDefault();
handleVote($(this));
});
$('a.reply').live("click", function(event) {
event.preventDefault();
openReply($(this).attr('id').substring(2));
});
$('a.close-reply').live("click", function(event) {
event.preventDefault();
closeReply($(this).attr('id').substring(2));
});
$('a.sort-option').live("click", function(event) {
event.preventDefault();
handleReSort($(this));
});
$('a.show-proposal').live("click", function(event) {
event.preventDefault();
showProposal($(this).attr('id').substring(2));
});
$('a.hide-proposal').live("click", function(event) {
event.preventDefault();
hideProposal($(this).attr('id').substring(2));
});
$('a.show-propose-change').live("click", function(event) {
event.preventDefault();
showProposeChange($(this).attr('id').substring(2));
});
$('a.hide-propose-change').live("click", function(event) {
event.preventDefault();
hideProposeChange($(this).attr('id').substring(2));
});
$('a.accept-comment').live("click", function(event) {
event.preventDefault();
acceptComment($(this).attr('id').substring(2));
});
$('a.delete-comment').live("click", function(event) {
event.preventDefault();
deleteComment($(this).attr('id').substring(2));
});
$('a.comment-markup').live("click", function(event) {
event.preventDefault();
toggleCommentMarkupBox($(this).attr('id').substring(2));
});
}
/**
* Set comp, which is a comparator function used for sorting and
* inserting comments into the list.
*/
function setComparator() {
// If the first three letters are "asc", sort in ascending order
// and remove the prefix.
if (by.substring(0,3) == 'asc') {
var i = by.substring(3);
comp = function(a, b) { return a[i] - b[i]; };
} else {
// Otherwise sort in descending order.
comp = function(a, b) { return b[by] - a[by]; };
}
// Reset link styles and format the selected sort option.
$('a.sel').attr('href', '#').removeClass('sel');
$('a.by' + by).removeAttr('href').addClass('sel');
}
/**
* Create a comp function. If the user has preferences stored in
* the sortBy cookie, use those, otherwise use the default.
*/
function initComparator() {
by = 'rating'; // Default to sort by rating.
// If the sortBy cookie is set, use that instead.
if (document.cookie.length > 0) {
var start = document.cookie.indexOf('sortBy=');
if (start != -1) {
start = start + 7;
var end = document.cookie.indexOf(";", start);
if (end == -1) {
end = document.cookie.length;
by = unescape(document.cookie.substring(start, end));
}
}
}
setComparator();
}
/**
* Show a comment div.
*/
function show(id) {
$('#ao' + id).hide();
$('#ah' + id).show();
var context = $.extend({id: id}, opts);
var popup = $(renderTemplate(popupTemplate, context)).hide();
popup.find('textarea[name="proposal"]').hide();
popup.find('a.by' + by).addClass('sel');
var form = popup.find('#cf' + id);
form.submit(function(event) {
event.preventDefault();
addComment(form);
});
$('#s' + id).after(popup);
popup.slideDown('fast', function() {
getComments(id);
});
}
/**
* Hide a comment div.
*/
function hide(id) {
$('#ah' + id).hide();
$('#ao' + id).show();
var div = $('#sc' + id);
div.slideUp('fast', function() {
div.remove();
});
}
/**
* Perform an ajax request to get comments for a node
* and insert the comments into the comments tree.
*/
function getComments(id) {
$.ajax({
type: 'GET',
url: opts.getCommentsURL,
data: {node: id},
success: function(data, textStatus, request) {
var ul = $('#cl' + id);
var speed = 100;
$('#cf' + id)
.find('textarea[name="proposal"]')
.data('source', data.source);
if (data.comments.length === 0) {
ul.html('<li>No comments yet.</li>');
ul.data('empty', true);
} else {
// If there are comments, sort them and put them in the list.
var comments = sortComments(data.comments);
speed = data.comments.length * 100;
appendComments(comments, ul);
ul.data('empty', false);
}
$('#cn' + id).slideUp(speed + 200);
ul.slideDown(speed);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem retrieving the comments.');
},
dataType: 'json'
});
}
/**
* Add a comment via ajax and insert the comment into the comment tree.
*/
function addComment(form) {
var node_id = form.find('input[name="node"]').val();
var parent_id = form.find('input[name="parent"]').val();
var text = form.find('textarea[name="comment"]').val();
var proposal = form.find('textarea[name="proposal"]').val();
if (text == '') {
showError('Please enter a comment.');
return;
}
// Disable the form that is being submitted.
form.find('textarea,input').attr('disabled', 'disabled');
// Send the comment to the server.
$.ajax({
type: "POST",
url: opts.addCommentURL,
dataType: 'json',
data: {
node: node_id,
parent: parent_id,
text: text,
proposal: proposal
},
success: function(data, textStatus, error) {
// Reset the form.
if (node_id) {
hideProposeChange(node_id);
}
form.find('textarea')
.val('')
.add(form.find('input'))
.removeAttr('disabled');
var ul = $('#cl' + (node_id || parent_id));
if (ul.data('empty')) {
$(ul).empty();
ul.data('empty', false);
}
insertComment(data.comment);
var ao = $('#ao' + node_id);
ao.find('img').attr({'src': opts.commentBrightImage});
if (node_id) {
// if this was a "root" comment, remove the commenting box
// (the user can get it back by reopening the comment popup)
$('#ca' + node_id).slideUp();
}
},
error: function(request, textStatus, error) {
form.find('textarea,input').removeAttr('disabled');
showError('Oops, there was a problem adding the comment.');
}
});
}
/**
* Recursively append comments to the main comment list and children
* lists, creating the comment tree.
*/
function appendComments(comments, ul) {
$.each(comments, function() {
var div = createCommentDiv(this);
ul.append($(document.createElement('li')).html(div));
appendComments(this.children, div.find('ul.comment-children'));
// To avoid stagnating data, don't store the comments children in data.
this.children = null;
div.data('comment', this);
});
}
/**
* After adding a new comment, it must be inserted in the correct
* location in the comment tree.
*/
function insertComment(comment) {
var div = createCommentDiv(comment);
// To avoid stagnating data, don't store the comments children in data.
comment.children = null;
div.data('comment', comment);
var ul = $('#cl' + (comment.node || comment.parent));
var siblings = getChildren(ul);
var li = $(document.createElement('li'));
li.hide();
// Determine where in the parents children list to insert this comment.
for(i=0; i < siblings.length; i++) {
if (comp(comment, siblings[i]) <= 0) {
$('#cd' + siblings[i].id)
.parent()
.before(li.html(div));
li.slideDown('fast');
return;
}
}
// If we get here, this comment rates lower than all the others,
// or it is the only comment in the list.
ul.append(li.html(div));
li.slideDown('fast');
}
function acceptComment(id) {
$.ajax({
type: 'POST',
url: opts.acceptCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
$('#cm' + id).fadeOut('fast');
$('#cd' + id).removeClass('moderate');
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem accepting the comment.');
}
});
}
function deleteComment(id) {
$.ajax({
type: 'POST',
url: opts.deleteCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
var div = $('#cd' + id);
if (data == 'delete') {
// Moderator mode: remove the comment and all children immediately
div.slideUp('fast', function() {
div.remove();
});
return;
}
// User mode: only mark the comment as deleted
div
.find('span.user-id:first')
.text('[deleted]').end()
.find('div.comment-text:first')
.text('[deleted]').end()
.find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
.remove();
var comment = div.data('comment');
comment.username = '[deleted]';
comment.text = '[deleted]';
div.data('comment', comment);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem deleting the comment.');
}
});
}
function showProposal(id) {
$('#sp' + id).hide();
$('#hp' + id).show();
$('#pr' + id).slideDown('fast');
}
function hideProposal(id) {
$('#hp' + id).hide();
$('#sp' + id).show();
$('#pr' + id).slideUp('fast');
}
function showProposeChange(id) {
$('#pc' + id).hide();
$('#hc' + id).show();
var textarea = $('#pt' + id);
textarea.val(textarea.data('source'));
$.fn.autogrow.resize(textarea[0]);
textarea.slideDown('fast');
}
function hideProposeChange(id) {
$('#hc' + id).hide();
$('#pc' + id).show();
var textarea = $('#pt' + id);
textarea.val('').removeAttr('disabled');
textarea.slideUp('fast');
}
function toggleCommentMarkupBox(id) {
$('#mb' + id).toggle();
}
/** Handle when the user clicks on a sort by link. */
function handleReSort(link) {
var classes = link.attr('class').split(/\s+/);
for (var i=0; i<classes.length; i++) {
if (classes[i] != 'sort-option') {
by = classes[i].substring(2);
}
}
setComparator();
// Save/update the sortBy cookie.
var expiration = new Date();
expiration.setDate(expiration.getDate() + 365);
document.cookie= 'sortBy=' + escape(by) +
';expires=' + expiration.toUTCString();
$('ul.comment-ul').each(function(index, ul) {
var comments = getChildren($(ul), true);
comments = sortComments(comments);
appendComments(comments, $(ul).empty());
});
}
/**
* Function to process a vote when a user clicks an arrow.
*/
function handleVote(link) {
if (!opts.voting) {
showError("You'll need to login to vote.");
return;
}
var id = link.attr('id');
if (!id) {
// Didn't click on one of the voting arrows.
return;
}
// If it is an unvote, the new vote value is 0,
// Otherwise it's 1 for an upvote, or -1 for a downvote.
var value = 0;
if (id.charAt(1) != 'u') {
value = id.charAt(0) == 'u' ? 1 : -1;
}
// The data to be sent to the server.
var d = {
comment_id: id.substring(2),
value: value
};
// Swap the vote and unvote links.
link.hide();
$('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
.show();
// The div the comment is displayed in.
var div = $('div#cd' + d.comment_id);
var data = div.data('comment');
// If this is not an unvote, and the other vote arrow has
// already been pressed, unpress it.
if ((d.value !== 0) && (data.vote === d.value * -1)) {
$('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
$('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
}
// Update the comments rating in the local data.
data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
data.vote = d.value;
div.data('comment', data);
// Change the rating text.
div.find('.rating:first')
.text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
// Send the vote information to the server.
$.ajax({
type: "POST",
url: opts.processVoteURL,
data: d,
error: function(request, textStatus, error) {
showError('Oops, there was a problem casting that vote.');
}
});
}
/**
* Open a reply form used to reply to an existing comment.
*/
function openReply(id) {
// Swap out the reply link for the hide link
$('#rl' + id).hide();
$('#cr' + id).show();
// Add the reply li to the children ul.
var div = $(renderTemplate(replyTemplate, {id: id})).hide();
$('#cl' + id)
.prepend(div)
// Setup the submit handler for the reply form.
.find('#rf' + id)
.submit(function(event) {
event.preventDefault();
addComment($('#rf' + id));
closeReply(id);
})
.find('input[type=button]')
.click(function() {
closeReply(id);
});
div.slideDown('fast', function() {
$('#rf' + id).find('textarea').focus();
});
}
/**
* Close the reply form opened with openReply.
*/
function closeReply(id) {
// Remove the reply div from the DOM.
$('#rd' + id).slideUp('fast', function() {
$(this).remove();
});
// Swap out the hide link for the reply link
$('#cr' + id).hide();
$('#rl' + id).show();
}
/**
* Recursively sort a tree of comments using the comp comparator.
*/
function sortComments(comments) {
comments.sort(comp);
$.each(comments, function() {
this.children = sortComments(this.children);
});
return comments;
}
/**
* Get the children comments from a ul. If recursive is true,
* recursively include childrens' children.
*/
function getChildren(ul, recursive) {
var children = [];
ul.children().children("[id^='cd']")
.each(function() {
var comment = $(this).data('comment');
if (recursive)
comment.children = getChildren($(this).find('#cl' + comment.id), true);
children.push(comment);
});
return children;
}
/** Create a div to display a comment in. */
function createCommentDiv(comment) {
if (!comment.displayed && !opts.moderator) {
return $('<div class="moderate">Thank you! Your comment will show up '
+ 'once it is has been approved by a moderator.</div>');
}
// Prettify the comment rating.
comment.pretty_rating = comment.rating + ' point' +
(comment.rating == 1 ? '' : 's');
// Make a class (for displaying not yet moderated comments differently)
comment.css_class = comment.displayed ? '' : ' moderate';
// Create a div for this comment.
var context = $.extend({}, opts, comment);
var div = $(renderTemplate(commentTemplate, context));
// If the user has voted on this comment, highlight the correct arrow.
if (comment.vote) {
var direction = (comment.vote == 1) ? 'u' : 'd';
div.find('#' + direction + 'v' + comment.id).hide();
div.find('#' + direction + 'u' + comment.id).show();
}
if (opts.moderator || comment.text != '[deleted]') {
div.find('a.reply').show();
if (comment.proposal_diff)
div.find('#sp' + comment.id).show();
if (opts.moderator && !comment.displayed)
div.find('#cm' + comment.id).show();
if (opts.moderator || (opts.username == comment.username))
div.find('#dc' + comment.id).show();
}
return div;
}
/**
* A simple template renderer. Placeholders such as <%id%> are replaced
* by context['id'] with items being escaped. Placeholders such as <#id#>
* are not escaped.
*/
function renderTemplate(template, context) {
var esc = $(document.createElement('div'));
function handle(ph, escape) {
var cur = context;
$.each(ph.split('.'), function() {
cur = cur[this];
});
return escape ? esc.text(cur || "").html() : cur;
}
return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
return handle(arguments[2], arguments[1] == '%' ? true : false);
});
}
/** Flash an error message briefly. */
function showError(message) {
$(document.createElement('div')).attr({'class': 'popup-error'})
.append($(document.createElement('div'))
.attr({'class': 'error-message'}).text(message))
.appendTo('body')
.fadeIn("slow")
.delay(2000)
.fadeOut("slow");
}
/** Add a link the user uses to open the comments popup. */
$.fn.comment = function() {
return this.each(function() {
var id = $(this).attr('id').substring(1);
var count = COMMENT_METADATA[id];
var title = count + ' comment' + (count == 1 ? '' : 's');
var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
var addcls = count == 0 ? ' nocomment' : '';
$(this)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-open' + addcls,
id: 'ao' + id
})
.append($(document.createElement('img')).attr({
src: image,
alt: 'comment',
title: title
}))
.click(function(event) {
event.preventDefault();
show($(this).attr('id').substring(2));
})
)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-close hidden',
id: 'ah' + id
})
.append($(document.createElement('img')).attr({
src: opts.closeCommentImage,
alt: 'close',
title: 'close'
}))
.click(function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
})
);
});
};
var opts = {
processVoteURL: '/_process_vote',
addCommentURL: '/_add_comment',
getCommentsURL: '/_get_comments',
acceptCommentURL: '/_accept_comment',
deleteCommentURL: '/_delete_comment',
commentImage: '/static/_static/comment.png',
closeCommentImage: '/static/_static/comment-close.png',
loadingImage: '/static/_static/ajax-loader.gif',
commentBrightImage: '/static/_static/comment-bright.png',
upArrow: '/static/_static/up.png',
downArrow: '/static/_static/down.png',
upArrowPressed: '/static/_static/up-pressed.png',
downArrowPressed: '/static/_static/down-pressed.png',
voting: false,
moderator: false
};
if (typeof COMMENT_OPTIONS != "undefined") {
opts = jQuery.extend(opts, COMMENT_OPTIONS);
}
var popupTemplate = '\
<div class="sphinx-comments" id="sc<%id%>">\
<p class="sort-options">\
Sort by:\
<a href="#" class="sort-option byrating">best rated</a>\
<a href="#" class="sort-option byascage">newest</a>\
<a href="#" class="sort-option byage">oldest</a>\
</p>\
<div class="comment-header">Comments</div>\
<div class="comment-loading" id="cn<%id%>">\
loading comments... <img src="<%loadingImage%>" alt="" /></div>\
<ul id="cl<%id%>" class="comment-ul"></ul>\
<div id="ca<%id%>">\
<p class="add-a-comment">Add a comment\
(<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
<div class="comment-markup-box" id="mb<%id%>">\
reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
<tt>``code``</tt>, \
code blocks: <tt>::</tt> and an indented block after blank line</div>\
<form method="post" id="cf<%id%>" class="comment-form" action="">\
<textarea name="comment" cols="80"></textarea>\
<p class="propose-button">\
<a href="#" id="pc<%id%>" class="show-propose-change">\
Propose a change &#9657;\
</a>\
<a href="#" id="hc<%id%>" class="hide-propose-change">\
Propose a change &#9663;\
</a>\
</p>\
<textarea name="proposal" id="pt<%id%>" cols="80"\
spellcheck="false"></textarea>\
<input type="submit" value="Add comment" />\
<input type="hidden" name="node" value="<%id%>" />\
<input type="hidden" name="parent" value="" />\
</form>\
</div>\
</div>';
var commentTemplate = '\
<div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
<div class="vote">\
<div class="arrow">\
<a href="#" id="uv<%id%>" class="vote" title="vote up">\
<img src="<%upArrow%>" />\
</a>\
<a href="#" id="uu<%id%>" class="un vote" title="vote up">\
<img src="<%upArrowPressed%>" />\
</a>\
</div>\
<div class="arrow">\
<a href="#" id="dv<%id%>" class="vote" title="vote down">\
<img src="<%downArrow%>" id="da<%id%>" />\
</a>\
<a href="#" id="du<%id%>" class="un vote" title="vote down">\
<img src="<%downArrowPressed%>" />\
</a>\
</div>\
</div>\
<div class="comment-content">\
<p class="tagline comment">\
<span class="user-id"><%username%></span>\
<span class="rating"><%pretty_rating%></span>\
<span class="delta"><%time.delta%></span>\
</p>\
<div class="comment-text comment"><#text#></div>\
<p class="comment-opts comment">\
<a href="#" class="reply hidden" id="rl<%id%>">reply &#9657;</a>\
<a href="#" class="close-reply" id="cr<%id%>">reply &#9663;</a>\
<a href="#" id="sp<%id%>" class="show-proposal">proposal &#9657;</a>\
<a href="#" id="hp<%id%>" class="hide-proposal">proposal &#9663;</a>\
<a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
<span id="cm<%id%>" class="moderation hidden">\
<a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
</span>\
</p>\
<pre class="proposal" id="pr<%id%>">\
<#proposal_diff#>\
</pre>\
<ul class="comment-children" id="cl<%id%>"></ul>\
</div>\
<div class="clearleft"></div>\
</div>\
</div>';
var replyTemplate = '\
<li>\
<div class="reply-div" id="rd<%id%>">\
<form id="rf<%id%>">\
<textarea name="comment" cols="80"></textarea>\
<input type="submit" value="Add reply" />\
<input type="button" value="Cancel" />\
<input type="hidden" name="parent" value="<%id%>" />\
<input type="hidden" name="node" value="" />\
</form>\
</div>\
</li>';
$(document).ready(function() {
init();
});
})(jQuery);
$(document).ready(function() {
// add comment anchors for all paragraphs that are commentable
$('.sphinx-has-comment').comment();
// highlight search words in search results
$("div.context").each(function() {
var params = $.getQueryParameters();
var terms = (params.q) ? params.q[0].split(/\s+/) : [];
var result = $(this);
$.each(terms, function() {
result.highlightText(this.toLowerCase(), 'highlighted');
});
});
// directly open comment window if requested
var anchor = document.location.hash;
if (anchor.substring(0, 9) == '#comment-') {
$('#ao' + anchor.substring(9)).click();
document.location.hash = '#s' + anchor.substring(9);
}
});
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Xml format of conditional module [xmodule] &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../../',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="../../index.html" />
<link rel="next" title="CustomResponse XML and Python Script" href="../custom_response.html" />
<link rel="prev" title="Xml format of poll module [xmodule]" href="../poll_module/poll_module.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../custom_response.html" title="CustomResponse XML and Python Script"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="../poll_module/poll_module.html" title="Xml format of poll module [xmodule]"
accesskey="P">previous</a> |</li>
<li><a href="../../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Xml format of conditional module [xmodule]</a><ul>
<li><a class="reference internal" href="#format-description">Format description</a><ul>
<li><a class="reference internal" href="#conditional-tag">conditional tag</a></li>
<li><a class="reference internal" href="#show-tag">show tag</a></li>
</ul>
</li>
<li><a class="reference internal" href="#example">Example</a><ul>
<li><a class="reference internal" href="#examples-of-conditional-depends-on-poll">Examples of conditional depends on poll</a></li>
<li><a class="reference internal" href="#examples-of-conditional-depends-on-poll-use-show-tag">Examples of conditional depends on poll (use &lt;show&gt; tag)</a></li>
<li><a class="reference internal" href="#examples-of-conditional-depends-on-problem">Examples of conditional depends on problem</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="../poll_module/poll_module.html"
title="previous chapter">Xml format of poll module [xmodule]</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="../custom_response.html"
title="next chapter">CustomResponse XML and Python Script</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../../_sources/course_data_formats/conditional_module/conditional_module.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-conditional_module">
<span id="xml-format-of-conditional-module-xmodule"></span><h1>Xml format of conditional module [xmodule]<a class="headerlink" href="#module-conditional_module" title="Permalink to this headline"></a></h1>
<div class="section" id="format-description">
<h2>Format description<a class="headerlink" href="#format-description" title="Permalink to this headline"></a></h2>
<p>The main tag of Conditional module input is:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;conditional&gt;</span> ... <span class="nt">&lt;/conditional&gt;</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">conditional</span></tt> can include any number of any xmodule tags (<tt class="docutils literal"><span class="pre">html</span></tt>, <tt class="docutils literal"><span class="pre">video</span></tt>, <tt class="docutils literal"><span class="pre">poll</span></tt>, etc.) or <tt class="docutils literal"><span class="pre">show</span></tt> tags.</p>
<div class="section" id="conditional-tag">
<h3>conditional tag<a class="headerlink" href="#conditional-tag" title="Permalink to this headline"></a></h3>
<p>The main container for a single instance of Conditional module. The following attributes can
be specified for this tag:</p>
<div class="highlight-python"><pre>sources - location id of required modules, separated by ';'
[message | ""] - message for case, where one or more are not passed. Here you can use variable {link}, which generate link to required module.
[completed] - map to `is_completed` module method
[attempted] - map to `is_attempted` module method
[poll_answer] - map to `poll_answer` module attribute
[voted] - map to `voted` module attribute</pre>
</div>
</div>
<div class="section" id="show-tag">
<h3>show tag<a class="headerlink" href="#show-tag" title="Permalink to this headline"></a></h3>
<p>Symlink to some set of xmodules. The following attributes can
be specified for this tag:</p>
<div class="highlight-python"><pre>sources - location id of modules, separated by ';'</pre>
</div>
</div>
</div>
<div class="section" id="example">
<h2>Example<a class="headerlink" href="#example" title="Permalink to this headline"></a></h2>
<div class="section" id="examples-of-conditional-depends-on-poll">
<h3>Examples of conditional depends on poll<a class="headerlink" href="#examples-of-conditional-depends-on-poll" title="Permalink to this headline"></a></h3>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;conditional</span> <span class="na">sources=</span><span class="s">&quot;i4x://MITx/0.000x/poll_question/first_real_poll_seq_with_reset&quot;</span> <span class="na">poll_answer=</span><span class="s">&quot;man&quot;</span>
<span class="na">message=</span><span class="s">&quot;{link} must be answered for this to become visible.&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;h2&gt;</span>You see this, cause your vote value for &quot;First question&quot; was &quot;man&quot;<span class="nt">&lt;/h2&gt;</span>
<span class="nt">&lt;/html&gt;</span>
<span class="nt">&lt;/conditional&gt;</span>
</pre></div>
</div>
</div>
<div class="section" id="examples-of-conditional-depends-on-poll-use-show-tag">
<h3>Examples of conditional depends on poll (use &lt;show&gt; tag)<a class="headerlink" href="#examples-of-conditional-depends-on-poll-use-show-tag" title="Permalink to this headline"></a></h3>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;conditional</span> <span class="na">sources=</span><span class="s">&quot;i4x://MITx/0.000x/poll_question/first_real_poll_seq_with_reset&quot;</span> <span class="na">poll_answer=</span><span class="s">&quot;man&quot;</span>
<span class="na">message=</span><span class="s">&quot;{link} must be answered for this to become visible.&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;show</span> <span class="na">sources=</span><span class="s">&quot;i4x://MITx/0.000x/problem/test_1; i4x://MITx/0.000x/Video/Avi_resources; i4x://MITx/0.000x/problem/test_1&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/html&gt;</span>
<span class="nt">&lt;/conditional&gt;</span>
</pre></div>
</div>
</div>
<div class="section" id="examples-of-conditional-depends-on-problem">
<h3>Examples of conditional depends on problem<a class="headerlink" href="#examples-of-conditional-depends-on-problem" title="Permalink to this headline"></a></h3>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;conditional</span> <span class="na">sources=</span><span class="s">&quot;i4x://MITx/0.000x/problem/Conditional:lec27_Q1&quot;</span> <span class="na">attempted=</span><span class="s">&quot;True&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;html</span> <span class="na">display_name=</span><span class="s">&quot;HTML for attempted problem&quot;</span><span class="nt">&gt;</span>You see this, cause &quot;lec27_Q1&quot; is attempted.<span class="nt">&lt;/html&gt;</span>
<span class="nt">&lt;/conditional&gt;</span>
<span class="nt">&lt;conditional</span> <span class="na">sources=</span><span class="s">&quot;i4x://MITx/0.000x/problem/Conditional:lec27_Q1&quot;</span> <span class="na">attempted=</span><span class="s">&quot;False&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;html</span> <span class="na">display_name=</span><span class="s">&quot;HTML for not attempted problem&quot;</span><span class="nt">&gt;</span>You see this, cause &quot;lec27_Q1&quot; is not attempted.<span class="nt">&lt;/html&gt;</span>
<span class="nt">&lt;/conditional&gt;</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../custom_response.html" title="CustomResponse XML and Python Script"
>next</a> |</li>
<li class="right" >
<a href="../poll_module/poll_module.html" title="Xml format of poll module [xmodule]"
>previous</a> |</li>
<li><a href="../../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Course XML Tutorial &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="../index.html" />
<link rel="next" title="Course Grading" href="grading.html" />
<link rel="prev" title="edX Data Documentation" href="../index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="grading.html" title="Course Grading"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="../index.html" title="edX Data Documentation"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Course XML Tutorial</a><ul>
<li><a class="reference internal" href="#goals">Goals</a></li>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#case-study">Case Study</a><ul>
<li><a class="reference internal" href="#policy-files">Policy Files</a></li>
<li><a class="reference internal" href="#roots">Roots</a></li>
</ul>
</li>
<li><a class="reference internal" href="#tags">Tags</a><ul>
<li><a class="reference internal" href="#container-tags">Container Tags</a></li>
<li><a class="reference internal" href="#course"><cite>course</cite></a></li>
<li><a class="reference internal" href="#conditional"><cite>conditional</cite></a></li>
<li><a class="reference internal" href="#customtag"><cite>customtag</cite></a></li>
<li><a class="reference internal" href="#discussion"><cite>discussion</cite></a></li>
<li><a class="reference internal" href="#html"><cite>html</cite></a></li>
<li><a class="reference internal" href="#video"><cite>video</cite></a></li>
<li><a class="reference internal" href="#more-on-url-name">More on <cite>url_name</cite></a></li>
</ul>
</li>
<li><a class="reference internal" href="#id1">Policy Files</a><ul>
<li><a class="reference internal" href="#locations">Locations</a></li>
<li><a class="reference internal" href="#contents">Contents</a></li>
<li><a class="reference internal" href="#supported-fields-at-the-course-level">Supported fields at the course level</a></li>
<li><a class="reference internal" href="#available-metadata">Available metadata</a><ul>
<li><a class="reference internal" href="#not-inherited">Not Inherited</a></li>
<li><a class="reference internal" href="#inherited">Inherited</a></li>
<li><a class="reference internal" href="#inheritance-example">Inheritance example</a></li>
<li><a class="reference internal" href="#specifying-metadata-in-the-xml-file">Specifying metadata in the XML file</a></li>
<li><a class="reference internal" href="#deprecated-formats">Deprecated Formats</a><ul>
<li><a class="reference internal" href="#obsolete-tags">Obsolete Tags</a></li>
<li><a class="reference internal" href="#obsolete-attributes">Obsolete Attributes</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#static-links">Static links</a></li>
<li><a class="reference internal" href="#tabs">Tabs</a></li>
<li><a class="reference internal" href="#textbooks">Textbooks</a><ul>
<li><a class="reference internal" href="#image-based-textbooks">Image-based Textbooks</a><ul>
<li><a class="reference internal" href="#configuration">Configuration</a></li>
<li><a class="reference internal" href="#linking-from-content">Linking from Content</a></li>
</ul>
</li>
<li><a class="reference internal" href="#html-based-textbooks">HTML-based Textbooks</a><ul>
<li><a class="reference internal" href="#id2">Configuration</a></li>
<li><a class="reference internal" href="#id3">Linking from Content</a></li>
</ul>
</li>
<li><a class="reference internal" href="#pdf-based-textbooks">PDF-based Textbooks</a><ul>
<li><a class="reference internal" href="#id4">Configuration</a></li>
<li><a class="reference internal" href="#id5">Linking from Content</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#other-file-locations-info-and-about">Other file locations (info and about)</a></li>
<li><a class="reference internal" href="#tips-for-content-developers">Tips for content developers</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="../index.html"
title="previous chapter">edX Data Documentation</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="grading.html"
title="next chapter">Course Grading</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/course_data_formats/course_xml.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="course-xml-tutorial">
<h1>Course XML Tutorial<a class="headerlink" href="#course-xml-tutorial" title="Permalink to this headline"></a></h1>
<p>EdX uses an XML format to describe the structure and contents of its courses. While much of this is abstracted away by the Studio authoring interface, it is still helpful to understand how the edX platform renders a course.</p>
<p>This guide was written with the assumption that you&#8217;ve dived straight into the edX platform without necessarily having any prior programming/CS knowledge. It will be especially valuable to you if your course is being authored with XML files rather than Studio &#8211; in which case you&#8217;re likely using functionality that is not yet fully supported in Studio.</p>
<div class="section" id="goals">
<h2>Goals<a class="headerlink" href="#goals" title="Permalink to this headline"></a></h2>
<p>After reading this, you should be able to:</p>
<ul class="simple">
<li>Organize your course content into the files and folders the edX platform expects.</li>
<li>Add new content to a course and make sure it shows up in the courseware.</li>
</ul>
<p><em>Prerequisites:</em> it would be helpful to know a little bit about xml. Here is a
<a class="reference external" href="http://www.ultraslavonic.info/intro-to-xml/">simple example</a> if you&#8217;ve never seen it before.</p>
</div>
<div class="section" id="introduction">
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p>A course is organized hierarchically. We start by describing course-wide parameters, then break the course into chapters, and then go deeper and deeper until we reach a specific pset, video, etc. You could make an analogy to finding a green shirt in your house -&gt; bedroom -&gt; closet -&gt; drawer -&gt; shirts -&gt; green shirt.</p>
<p>We&#8217;ll begin with a sample course structure as a case study of how XML and files in a course are organized. More technical details will follow, including discussion of some special cases.</p>
</div>
<div class="section" id="case-study">
<h2>Case Study<a class="headerlink" href="#case-study" title="Permalink to this headline"></a></h2>
<p>Let&#8217;s jump right in by looking at the directory structure of a very simple toy course:</p>
<div class="highlight-python"><pre>toy/
course/
course.xml
problem/
policies/
roots/</pre>
</div>
<p>The only top level file is <cite>course.xml</cite>, which should contain one line, looking something like this:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;course</span> <span class="na">org=</span><span class="s">&quot;edX&quot;</span> <span class="na">course=</span><span class="s">&quot;toy&quot;</span> <span class="na">url_name=</span><span class="s">&quot;2012_Fall&quot;</span><span class="nt">/&gt;</span>
</pre></div>
</div>
<p>This gives all the information to uniquely identify a particular run of any course &#8211; which organization is producing the course, what the course name is, and what &#8220;run&#8221; this is, specified via the <cite>url_name</cite> attribute.</p>
<p>Obviously, this doesn&#8217;t actually specify any of the course content, so we need to find that next. To know where to look, you need to know the standard organizational structure of our system: course elements are uniquely identified by the combination <cite>(category, url_name)</cite>. In this case, we are looking for a <cite>course</cite> element with the <cite>url_name</cite> &#8220;2012_Fall&#8221;. The definition of this element will be in <cite>course/2012_Fall.xml</cite>. Let&#8217;s look there next:</p>
<div class="highlight-python"><pre>toy/
course/
2012_Fall.xml # &lt;-- Where we look for category="course", url_name="2012_Fall"</pre>
</div>
<div class="highlight-xml"><div class="highlight"><pre><span class="c">&lt;!-- Contents of course/2012_Fall.xml --&gt;</span>
<span class="nt">&lt;course&gt;</span>
<span class="nt">&lt;chapter</span> <span class="na">url_name=</span><span class="s">&quot;Overview&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;videosequence</span> <span class="na">url_name=</span><span class="s">&quot;Toy_Videos&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;problem</span> <span class="na">url_name=</span><span class="s">&quot;warmup&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;video</span> <span class="na">url_name=</span><span class="s">&quot;Video_Resources&quot;</span> <span class="na">youtube=</span><span class="s">&quot;1.0:1bK-WdDi6Qw&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/videosequence&gt;</span>
<span class="nt">&lt;video</span> <span class="na">url_name=</span><span class="s">&quot;Welcome&quot;</span> <span class="na">youtube=</span><span class="s">&quot;1.0:p2Q6BrNhdh8&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/chapter&gt;</span>
<span class="nt">&lt;/course&gt;</span>
</pre></div>
</div>
<p>Aha. Now we&#8217;ve found some content. We can see that the course is organized hierarchically, in this case with only one chapter, with <cite>url_name</cite> &#8220;Overview&#8221;. The chapter contains a <cite>videosequence</cite> and a <cite>video</cite>, with the sequence containing a problem and another video. When viewed in the courseware, chapters are shown at the top level of the navigation accordion on the left, with any elements directly included in the chapter below.</p>
<p>Looking at this file, we can see the course structure, and the youtube urls for the videos, but what about the &#8220;warmup&#8221; problem? There is no problem content here! Where should we look? This is a good time to pause and try to answer that question based on our organizational structure above.</p>
<p>As you hopefully guessed, the problem would be in <cite>problem/warmup.xml</cite>. (Note: This tutorial doesn&#8217;t discuss the xml format for problems &#8211; there are chapters of edx4edx that describe it.) This is an instance of a <em>pointer tag</em>: any xml tag with only the category and a url_name attribute will point to the file <cite>{category}/{url_name}.xml</cite>. For example, this means that our toy <cite>course.xml</cite> could have also been written as</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="c">&lt;!-- Contents of course/2012_Fall.xml --&gt;</span>
<span class="nt">&lt;course&gt;</span>
<span class="nt">&lt;chapter</span> <span class="na">url_name=</span><span class="s">&quot;Overview&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/course&gt;</span>
</pre></div>
</div>
<p>with <cite>chapter/Overview.xml</cite> containing</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;chapter&gt;</span>
<span class="nt">&lt;videosequence</span> <span class="na">url_name=</span><span class="s">&quot;Toy_Videos&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;problem</span> <span class="na">url_name=</span><span class="s">&quot;warmup&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;video</span> <span class="na">url_name=</span><span class="s">&quot;Video_Resources&quot;</span> <span class="na">youtube=</span><span class="s">&quot;1.0:1bK-WdDi6Qw&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/videosequence&gt;</span>
<span class="nt">&lt;video</span> <span class="na">url_name=</span><span class="s">&quot;Welcome&quot;</span> <span class="na">youtube=</span><span class="s">&quot;1.0:p2Q6BrNhdh8&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/chapter&gt;</span>
</pre></div>
</div>
<p>In fact, this is the recommended structure for real courses &#8211; putting each chapter into its own file makes it easy to have different people work on each without conflicting or having to merge. Similarly, as sequences get large, it can be handy to split them out as well (in <cite>sequence/{url_name}.xml</cite>, of course).</p>
<p>Note that the <cite>url_name</cite> is only specified once per element &#8211; either the inline definition, or in the pointer tag.</p>
<div class="section" id="policy-files">
<h3>Policy Files<a class="headerlink" href="#policy-files" title="Permalink to this headline"></a></h3>
<p>We still haven&#8217;t looked at two of the directories in the top-level listing above: <cite>policies</cite> and <cite>roots</cite>. Let&#8217;s look at policies next. The policy directory contains one file:</p>
<div class="highlight-python"><pre>toy/
policies/
2012_Fall.json</pre>
</div>
<p>and that file is named <cite>{course-url_name}.json</cite>. As you might expect, this file contains a policy for the course. In our example, it looks like this:</p>
<div class="highlight-json"><div class="highlight"><pre><span class="p">{</span>
<span class="nt">&quot;course/2012_Fall&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;graceperiod&quot;</span><span class="p">:</span> <span class="s2">&quot;2 days 5 hours 59 minutes 59 seconds&quot;</span><span class="p">,</span>
<span class="nt">&quot;start&quot;</span><span class="p">:</span> <span class="s2">&quot;2015-07-17T12:00&quot;</span><span class="p">,</span>
<span class="nt">&quot;display_name&quot;</span><span class="p">:</span> <span class="s2">&quot;Toy Course&quot;</span>
<span class="p">},</span>
<span class="nt">&quot;chapter/Overview&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;display_name&quot;</span><span class="p">:</span> <span class="s2">&quot;Overview&quot;</span>
<span class="p">},</span>
<span class="nt">&quot;videosequence/Toy_Videos&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;display_name&quot;</span><span class="p">:</span> <span class="s2">&quot;Toy Videos&quot;</span><span class="p">,</span>
<span class="nt">&quot;format&quot;</span><span class="p">:</span> <span class="s2">&quot;Lecture Sequence&quot;</span>
<span class="p">},</span>
<span class="nt">&quot;problem/warmup&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;display_name&quot;</span><span class="p">:</span> <span class="s2">&quot;Getting ready for the semester&quot;</span>
<span class="p">},</span>
<span class="nt">&quot;video/Video_Resources&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;display_name&quot;</span><span class="p">:</span> <span class="s2">&quot;Video Resources&quot;</span>
<span class="p">},</span>
<span class="nt">&quot;video/Welcome&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;display_name&quot;</span><span class="p">:</span> <span class="s2">&quot;Welcome&quot;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The policy specifies metadata about the content elements &#8211; things which are not inherent to the definition of the content, but which describe how the content is presented to the user and used in the course. See below for a full list of metadata attributes; as the example shows, they include <cite>display_name</cite>, which is what is shown when this piece of content is referenced or shown in the courseware, and various dates and times, like <cite>start</cite>, which specifies when the content becomes visible to students, and various problem-specific parameters like the allowed number of attempts. One important point is that some metadata is inherited: for example, specifying the start date on the course makes it the default for every element in the course. See below for more details.</p>
<p>It is possible to put metadata directly in the XML, as attributes of the appropriate tag, but using a policy file has two benefits: it puts all the policy in one place, making it easier to check that things like due dates are set properly, and it allows the content definitions to be easily used in another run of the same course, with the same or similar content, but different policy.</p>
</div>
<div class="section" id="roots">
<h3>Roots<a class="headerlink" href="#roots" title="Permalink to this headline"></a></h3>
<p>The last directory in the top level listing is <cite>roots</cite>. In our toy course, it contains a single file:</p>
<div class="highlight-python"><pre>roots/
2012_Fall.xml</pre>
</div>
<p>This file is identical to the top-level <cite>course.xml</cite>, containing</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;course</span> <span class="na">org=</span><span class="s">&quot;edX&quot;</span> <span class="na">course=</span><span class="s">&quot;toy&quot;</span> <span class="na">url_name=</span><span class="s">&quot;2012_Fall&quot;</span><span class="nt">/&gt;</span>
</pre></div>
</div>
<p>In fact, the top level <cite>course.xml</cite> is a symbolic link to this file. When there is only one run of a course, the roots directory is not really necessary, and the top-level course.xml file can just specify the <cite>url_name</cite> of the course. However, if we wanted to make a second run of our toy course, we could add another file called, e.g., <cite>roots/2013_Spring.xml</cite>, containing</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;course</span> <span class="na">org=</span><span class="s">&quot;edX&quot;</span> <span class="na">course=</span><span class="s">&quot;toy&quot;</span> <span class="na">url_name=</span><span class="s">&quot;2013_Spring&quot;</span><span class="nt">/&gt;</span>
</pre></div>
</div>
<p>After creating <cite>course/2013_Spring.xml</cite> with the course structure (possibly as a symbolic link or copy of <cite>course/2012_Fall.xml</cite> if no content was changing), and <cite>policies/2013_Spring.json</cite>, we would have two different runs of the toy course in the course repository. Our build system understands this roots structure, and will build a course package for each root.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you&#8217;re using a local development environment, make the top level <cite>course.xml</cite> point to the desired root, and check out the repo multiple times if you need multiple runs simultaneously).</p>
</div>
<p>That&#8217;s basically all there is to the organizational structure. Read the next section for details on the tags we support, including some special case tags like <cite>customtag</cite> and <cite>html</cite> invariants, and look at the end for some tips that will make the editing process easier.</p>
</div>
</div>
<div class="section" id="tags">
<h2>Tags<a class="headerlink" href="#tags" title="Permalink to this headline"></a></h2>
<blockquote>
<div><table border="1" class="docutils">
<colgroup>
<col width="11%" />
<col width="89%" />
</colgroup>
<tbody valign="top">
<tr class="row-odd"><td><cite>abtest</cite></td>
<td>Support for A/B testing. TODO: add details..</td>
</tr>
<tr class="row-even"><td><cite>chapter</cite></td>
<td>Top level organization unit of a course. The courseware display code currently expects the top level <cite>course</cite> element to contain only chapters, though there is no philosophical reason why this is required, so we may change it to properly display non-chapters at the top level.</td>
</tr>
<tr class="row-odd"><td><cite>conditional</cite></td>
<td>Conditional element, which shows one or more modules only if certain conditions are satisfied.</td>
</tr>
<tr class="row-even"><td><cite>course</cite></td>
<td>Top level tag. Contains everything else.</td>
</tr>
<tr class="row-odd"><td><cite>customtag</cite></td>
<td>Render an html template, filling in some parameters, and return the resulting html. See below for details.</td>
</tr>
<tr class="row-even"><td><cite>discussion</cite></td>
<td>Inline discussion forum.</td>
</tr>
<tr class="row-odd"><td><cite>html</cite></td>
<td>A reference to an html file.</td>
</tr>
<tr class="row-even"><td><cite>error</cite></td>
<td>Don&#8217;t put these in by hand :) The internal representation of content that has an error, such as malformed XML or some broken invariant.</td>
</tr>
<tr class="row-odd"><td><cite>problem</cite></td>
<td>See elsewhere in edx4edx for documentation on the format.</td>
</tr>
<tr class="row-even"><td><cite>problemset</cite></td>
<td>Logically, a series of related problems. Currently displayed vertically. May contain explanatory html, videos, etc.</td>
</tr>
<tr class="row-odd"><td><cite>sequential</cite></td>
<td>A sequence of content, currently displayed with a horizontal list of tabs. If possible, use a more semantically meaningful tag (currently, we only have <cite>videosequence</cite>).</td>
</tr>
<tr class="row-even"><td><cite>vertical</cite></td>
<td>A sequence of content, displayed vertically. Content will be accessed all at once, on the right part of the page. No navigational bar. May have to use browser scroll bars. Content split with separators. If possible, use a more semantically meaningful tag (currently, we only have <cite>problemset</cite>).</td>
</tr>
<tr class="row-odd"><td><cite>video</cite></td>
<td>A link to a video, currently expected to be hosted on youtube.</td>
</tr>
<tr class="row-even"><td><cite>videosequence</cite></td>
<td>A sequence of videos. This can contain various non-video content; it just signals to the system that this is logically part of an explanatory sequence of content, as opposed to say an exam sequence.</td>
</tr>
</tbody>
</table>
</div></blockquote>
<div class="section" id="container-tags">
<h3>Container Tags<a class="headerlink" href="#container-tags" title="Permalink to this headline"></a></h3>
<p>Container tags include <cite>chapter</cite>, <cite>sequential</cite>, <cite>videosequence</cite>, <cite>vertical</cite>, and <cite>problemset</cite>. They are all specified in the same way in the xml, as shown in the tutorial above.</p>
</div>
<div class="section" id="course">
<h3><cite>course</cite><a class="headerlink" href="#course" title="Permalink to this headline"></a></h3>
<p><cite>course</cite> is also a container, and is similar, with one extra wrinkle: the top level pointer tag <em>must</em> have <cite>org</cite> and <cite>course</cite> attributes specified&#8211;the organization name, and course name. Note that <cite>course</cite> is referring to the platonic ideal of this course (e.g. &#8220;6.002x&#8221;), not to any particular run of this course. The <cite>url_name</cite> should be the particular run of this course.</p>
</div>
<div class="section" id="conditional">
<h3><cite>conditional</cite><a class="headerlink" href="#conditional" title="Permalink to this headline"></a></h3>
<p><cite>conditional</cite> is as special kind of container tag as well. Here are two examples:</p>
<blockquote>
<div><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;conditional</span> <span class="na">condition=</span><span class="s">&quot;require_completed&quot;</span> <span class="na">required=</span><span class="s">&quot;problem/choiceprob&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;video</span> <span class="na">url_name=</span><span class="s">&quot;secret_video&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/conditional&gt;</span>
<span class="nt">&lt;conditional</span> <span class="na">condition=</span><span class="s">&quot;require_attempted&quot;</span> <span class="na">required=</span><span class="s">&quot;problem/choiceprob&amp;problem/sumprob&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;html</span> <span class="na">url_name=</span><span class="s">&quot;secret_page&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/conditional&gt;</span>
</pre></div>
</div>
</div></blockquote>
<p>The condition can be either <cite>require_completed</cite>, in which case the required modules must be completed, or <cite>require_attempted</cite>, in which case the required modules must have been attempted.</p>
<p>The required modules are specified as a set of <cite>tag</cite>/<cite>url_name</cite>, joined by an ampersand.</p>
</div>
<div class="section" id="customtag">
<h3><cite>customtag</cite><a class="headerlink" href="#customtag" title="Permalink to this headline"></a></h3>
<p>When we see:</p>
<blockquote>
<div><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;customtag</span> <span class="na">impl=</span><span class="s">&quot;special&quot;</span> <span class="na">animal=</span><span class="s">&quot;unicorn&quot;</span> <span class="na">hat=</span><span class="s">&quot;blue&quot;</span><span class="nt">/&gt;</span>
</pre></div>
</div>
</div></blockquote>
<p>We will:</p>
<ol class="arabic simple">
<li>Look for a file called <cite>custom_tags/special</cite> in your course dir.</li>
<li>Render it as a mako template, passing parameters {&#8216;animal&#8217;:&#8217;unicorn&#8217;, &#8216;hat&#8217;:&#8217;blue&#8217;}, generating html. (Google <cite>mako</cite> for template syntax, or look at existing examples).</li>
</ol>
<p>Since <cite>customtag</cite> is already a pointer, there is generally no need to put it into a separate file&#8211;just use it in place:</p>
<blockquote>
<div><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;customtag</span> <span class="na">url_name=</span><span class="s">&quot;my_custom_tag&quot;</span> <span class="na">impl=</span><span class="s">&quot;blah&quot;</span> <span class="na">attr1=</span><span class="s">&quot;...&quot;</span><span class="nt">/&gt;</span>
</pre></div>
</div>
</div></blockquote>
</div>
<div class="section" id="discussion">
<h3><cite>discussion</cite><a class="headerlink" href="#discussion" title="Permalink to this headline"></a></h3>
<p>The discussion tag embeds an inline discussion module. The XML format is:</p>
<blockquote>
<div><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;discussion</span> <span class="na">for=</span><span class="s">&quot;Course overview&quot;</span> <span class="na">id=</span><span class="s">&quot;6002x_Fall_2012_Overview&quot;</span> <span class="na">discussion_category=</span><span class="s">&quot;Week 1/Overview&quot;</span> <span class="nt">/&gt;</span>
</pre></div>
</div>
</div></blockquote>
<p>The meaning of each attribute is as follows:</p>
<blockquote>
<div><table border="1" class="docutils">
<colgroup>
<col width="11%" />
<col width="89%" />
</colgroup>
<tbody valign="top">
<tr class="row-odd"><td><cite>for</cite></td>
<td>A string that describes the discussion. Purely for descriptive purposes (to the student).</td>
</tr>
<tr class="row-even"><td><cite>id</cite></td>
<td>The identifier that the discussion forum service uses to refer to this inline discussion module. Since the <cite>id</cite> must be unique and lives in a common namespace with all other courses, the preferred convention is to use <cite>&lt;course_name&gt;_&lt;course_run&gt;_&lt;descriptor&gt;</cite> as in the above example. The <cite>id</cite> should be &#8220;machine-friendly&#8221;, e.g. use alphanumeric characters, underscores. Do <strong>not</strong> use a period (e.g. <cite>6.002x_Fall_2012_Overview</cite>).</td>
</tr>
<tr class="row-odd"><td><cite>discussion_category</cite></td>
<td>The inline module will be indexed in the main &#8220;Discussion&#8221; tab of the course. The inline discussions are organized into a directory-like hierarchy. Note that the forward slash indicates depth, as in conventional filesytems. In the above example, this discussion module will show up in the following &#8220;directory&#8221;: <cite>Week 1/Overview/Course overview</cite></td>
</tr>
</tbody>
</table>
</div></blockquote>
<p>Note that the <cite>for</cite> tag has been appended to the end of the <cite>discussion_category</cite>. This can often lead into deeply nested subforums, which may not be intended. In the above example, if we were to use instead:</p>
<blockquote>
<div><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;discussion</span> <span class="na">for=</span><span class="s">&quot;Course overview&quot;</span> <span class="na">id=</span><span class="s">&quot;6002x_Fall_2012_Overview&quot;</span> <span class="na">discussion_category=</span><span class="s">&quot;Week 1&quot;</span> <span class="nt">/&gt;</span>
</pre></div>
</div>
</div></blockquote>
<p>This discussion module would show up in the main forums as <cite>Week 1 / Course overview</cite>, which is more succinct.</p>
</div>
<div class="section" id="html">
<h3><cite>html</cite><a class="headerlink" href="#html" title="Permalink to this headline"></a></h3>
<p>Most of our content is in XML, but some HTML content may not be proper xml (all tags matched, single top-level tag, etc), since browsers are fairly lenient in what they&#8217;ll display. So, there are two ways to include HTML content:</p>
<ul class="simple">
<li>If your HTML content is in a proper XML format, just put it in <cite>html/{url_name}.xml</cite>.</li>
<li>If your HTML content is not in proper XML format, you can put it in <cite>html/{filename}.html</cite>, and put <cite>&lt;html filename={filename} /&gt;</cite> in <cite>html/{filename}.xml</cite>. This allows another level of indirection, and makes sure that we can read the XML file and then just return the actual HTML content without trying to parse it.</li>
</ul>
</div>
<div class="section" id="video">
<h3><cite>video</cite><a class="headerlink" href="#video" title="Permalink to this headline"></a></h3>
<p>Videos have an attribute <cite>youtube</cite>, which specifies a series of speeds + youtube video IDs:</p>
<blockquote>
<div><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;video</span> <span class="na">youtube=</span><span class="s">&quot;0.75:1yk1A8-FPbw,1.0:vNMrbPvwhU4,1.25:gBW_wqe7rDc,1.50:7AE_TKgaBwA&quot;</span>
<span class="na">url_name=</span><span class="s">&quot;S15V14_Response_to_impulse_limit_case&quot;</span><span class="nt">/&gt;</span>
</pre></div>
</div>
</div></blockquote>
<p>This video has been encoded at 4 different speeds: <cite>0.75x</cite>, <cite>1x</cite>, <cite>1.25x</cite>, and <cite>1.5x</cite>.</p>
</div>
<div class="section" id="more-on-url-name">
<h3>More on <cite>url_name</cite><a class="headerlink" href="#more-on-url-name" title="Permalink to this headline"></a></h3>
<p>Every content element (within a course) should have a unique id. This id is formed as <cite>{category}/{url_name}</cite>, or automatically generated from the content if <cite>url_name</cite> is not specified. Categories are the different tag types (&#8216;chapter&#8217;, &#8216;problem&#8217;, &#8216;html&#8217;, &#8216;sequential&#8217;, etc). Url_name is a string containing a-z, A-Z, dot (.), underscore (_), and &#8216;:&#8217;. This is what appears in urls that point to this object.</p>
<p>Colon (&#8216;:&#8217;) is special&#8211;when looking for the content definition in an xml, &#8216;:&#8217; will be replaced with &#8216;/&#8217;. This allows organizing content into folders. For example, given the pointer tag</p>
<blockquote>
<div><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;problem</span> <span class="na">url_name=</span><span class="s">&quot;conceptual:add_apples_and_oranges&quot;</span><span class="nt">/&gt;</span>
</pre></div>
</div>
</div></blockquote>
<p>we would look for the problem definition in <cite>problem/conceptual/add_apples_and_oranges.xml</cite>. (There is a technical reason why we can&#8217;t just allow &#8216;/&#8217; in the url_name directly.)</p>
<div class="admonition important">
<p class="first admonition-title">Important</p>
<p class="last">A student&#8217;s state for a particular content element is tied to the element ID, so automatic ID generation is only ok for elements that do not need to store any student state (e.g. verticals or customtags). For problems, sequentials, and videos, and any other element where we keep track of what the student has done and where they are at, you should specify a unique <cite>url_name</cite>. Of course, any content element that is split out into a file will need a <cite>url_name</cite> to specify where to find the definition.</p>
</div>
</div>
</div>
<div class="section" id="id1">
<h2>Policy Files<a class="headerlink" href="#id1" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>A policy file is useful when running different versions of a course e.g. internal, external, fall, spring, etc. as you can change due dates, etc, by creating multiple policy files.</li>
<li>A policy file provides information on the metadata of the course&#8211;things that are not inherent to the definitions of the contents, but that may vary from run to run.</li>
<li>Note: We will be expanding our understanding and format for metadata in the not-too-distant future, but for now it is simply a set of key-value pairs.</li>
</ul>
<div class="section" id="locations">
<h3>Locations<a class="headerlink" href="#locations" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li>The policy for a course run <cite>some_url_name</cite> should live in <cite>policies/some_url_name/policy.json</cite> (NOTE: the old format of putting it in <cite>policies/some_url_name.json</cite> will also work, but we suggest using the subdirectory to have all the per-course policy files in one place)</li>
<li>Grading policy files go in <cite>policies/some_url_name/grading_policy.json</cite> (if there&#8217;s only one course run, can also put it directly in the course root: <cite>/grading_policy.json</cite>)</li>
</ul>
</div>
<div class="section" id="contents">
<h3>Contents<a class="headerlink" href="#contents" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li>The file format is JSON, and is best shown by example, as in the tutorial above.</li>
<li>The expected contents are a dictionary mapping from keys to values (syntax <cite>{ key : value, key2 : value2, etc}</cite>)</li>
<li>Keys are in the form <cite>{category}/{url_name}</cite>, which should uniquely identify a content element. Values are dictionaries of the form <cite>{&#8220;metadata-key&#8221; : &#8220;metadata-value&#8221;}</cite>.</li>
<li>The order in which things appear does not matter, though it may be helpful to organize the file in the same order as things appear in the content.</li>
<li>NOTE: JSON is picky about commas. If you have trailing commas before closing braces, it will complain and refuse to parse the file. This can be irritating at first.</li>
</ul>
</div>
<div class="section" id="supported-fields-at-the-course-level">
<h3>Supported fields at the course level<a class="headerlink" href="#supported-fields-at-the-course-level" title="Permalink to this headline"></a></h3>
<blockquote>
<div><table border="1" class="docutils">
<colgroup>
<col width="11%" />
<col width="89%" />
</colgroup>
<tbody valign="top">
<tr class="row-odd"><td><cite>start</cite></td>
<td>specify the start date for the course. Format-by-example: <cite>&#8220;2012-09-05T12:00&#8221;</cite>.</td>
</tr>
<tr class="row-even"><td><cite>advertised_start</cite></td>
<td>specify what you want displayed as the start date of the course in the course listing and course about pages. This can be useful if you want to let people in early before the formal start. Format-by-example: <cite>&#8220;2012-09-05T12:&#8221;00</cite>.</td>
</tr>
<tr class="row-odd"><td><cite>disable_policy_graph</cite></td>
<td>set to true (or &#8220;Yes&#8221;), if the policy graph should be disabled (ie not shown).</td>
</tr>
<tr class="row-even"><td><cite>enrollment_start</cite>, <cite>enrollment_end</cite></td>
<td>&#8211; when can students enroll? (if not specified, can enroll anytime). Same format as <cite>start</cite>.</td>
</tr>
<tr class="row-odd"><td><cite>end</cite></td>
<td>specify the end date for the course. Format-by-example: <cite>&#8220;2012-11-05T12:00&#8221;</cite>.</td>
</tr>
<tr class="row-even"><td><cite>end_of_course_survey_url</cite></td>
<td>a url for an end of course survey &#8211; shown after course is over, next to certificate download links.</td>
</tr>
<tr class="row-odd"><td><cite>tabs</cite></td>
<td>have custom tabs in the courseware. See below for details on config.</td>
</tr>
<tr class="row-even"><td><cite>discussion_blackouts</cite></td>
<td>An array of time intervals during which you want to disable a student&#8217;s ability to create or edit posts in the forum. Moderators, Community TAs, and Admins are unaffected. You might use this during exam periods, but please be aware that the forum is often a very good place to catch mistakes and clarify points to students. The better long term solution would be to have better flagging/moderation mechanisms, but this is the hammer we have today. Format by example: <cite>[[&#8220;2012-10-29T04:00&#8221;, &#8220;2012-11-03T04:00&#8221;], [&#8220;2012-12-30T04:00&#8221;, &#8220;2013-01-02T04:00&#8221;]]</cite></td>
</tr>
<tr class="row-odd"><td><cite>show_calculator</cite></td>
<td>(value &#8220;Yes&#8221; if desired)</td>
</tr>
<tr class="row-even"><td><cite>days_early_for_beta</cite></td>
<td>number of days (floating point ok) early that students in the beta-testers group get to see course content. Can also be specified for any other course element, and overrides values set at higher levels.</td>
</tr>
<tr class="row-odd"><td><cite>cohort_config</cite></td>
<td><ul class="first last simple">
<li><cite>cohorted</cite> : boolean. Set to true if this course uses student cohorts. If so, all inline discussions are automatically cohorted, and top-level discussion topics are configurable via the cohorted_discussions list. Default is not cohorted).</li>
<li><cite>cohorted_discussions</cite>: list of discussions that should be cohorted. Any not specified in this list are not cohorted.</li>
<li><cite>auto_cohort</cite>: Truthy.</li>
<li><cite>auto_cohort_groups</cite>: <cite>[&#8220;group name 1&#8221;, &#8220;group name 2&#8221;, ...]</cite> If <cite>cohorted</cite> and <cite>auto_cohort</cite> is true, automatically put each student into a random group from the <cite>auto_cohort_groups</cite> list, creating the group if needed.</li>
</ul>
</td>
</tr>
<tr class="row-even"><td><cite>pdf_textbooks</cite></td>
<td>have pdf-based textbooks on tabs in the courseware. See below for details on config.</td>
</tr>
<tr class="row-odd"><td><cite>html_textbooks</cite></td>
<td>have html-based textbooks on tabs in the courseware. See below for details on config.</td>
</tr>
</tbody>
</table>
</div></blockquote>
</div>
<div class="section" id="available-metadata">
<h3>Available metadata<a class="headerlink" href="#available-metadata" title="Permalink to this headline"></a></h3>
<div class="section" id="not-inherited">
<h4>Not Inherited<a class="headerlink" href="#not-inherited" title="Permalink to this headline"></a></h4>
<dl class="docutils">
<dt><cite>display_name</cite></dt>
<dd>Name that will appear when this content is displayed in the courseware. Useful for all tag types.</dd>
<dt><cite>format</cite></dt>
<dd>Subheading under display name &#8211; currently only displayed for chapter sub-sections. Also used by the the grader to know how to process students assessments that the section contains. New formats can be defined as a &#8216;type&#8217; in the GRADER variable in course_settings.json. Optional. (TODO: double check this&#8211;what&#8217;s the current behavior?)</dd>
<dt><cite>hide_from_toc</cite></dt>
<dd>If set to true for a chapter or chapter subsection, will hide that element from the courseware navigation accordion. This is useful if you&#8217;d like to link to the content directly instead (e.g. for tutorials)</dd>
<dt><cite>ispublic</cite></dt>
<dd>Specify whether the course is public. You should be able to use start dates instead (?)</dd>
</dl>
</div>
<div class="section" id="inherited">
<h4>Inherited<a class="headerlink" href="#inherited" title="Permalink to this headline"></a></h4>
<dl class="docutils">
<dt><cite>start</cite></dt>
<dd>When this content should be shown to students. Note that anyone with staff access to the course will always see everything.</dd>
<dt><cite>showanswer</cite></dt>
<dd>When to show answer. For &#8216;attempted&#8217;, will show answer after first attempt. Values: never, attempted, answered, closed. Default: closed. Optional.</dd>
<dt><cite>graded</cite></dt>
<dd>Whether this section will count towards the students grade. &#8220;true&#8221; or &#8220;false&#8221;. Defaults to &#8220;false&#8221;.</dd>
<dt><cite>rerandomize</cite></dt>
<dd><p class="first">Randomize question on each attempt. Optional. Possible values:</p>
<dl class="last docutils">
<dt><cite>always</cite> (default)</dt>
<dd>Students see a different version of the problem after each attempt to solve it.</dd>
<dt><cite>onreset</cite></dt>
<dd>Randomize question when reset button is pressed by the student.</dd>
<dt><cite>never</cite></dt>
<dd>All students see the same version of the problem.</dd>
<dt><cite>per_student</cite></dt>
<dd>Individual students see the same version of the problem each time the look at it, but that version is different from what other students see.</dd>
<dt><cite>due</cite></dt>
<dd>Due date for assignment. Assignment will be closed after that. Values: valid date. Default: none. Optional.</dd>
<dt><cite>attempts</cite></dt>
<dd>Number of allowed attempts. Values: integer. Default: infinite. Optional.</dd>
<dt><cite>graceperiod</cite></dt>
<dd>A default length of time that the problem is still accessible after the due date in the format <cite>&#8220;2 days 3 hours&#8221;</cite> or <cite>&#8220;1 day 15 minutes&#8221;</cite>. Note, graceperiods are currently the easiest way to handle time zones. Due dates are all expressed in UTC.</dd>
<dt><cite>xqa_key</cite></dt>
<dd>For integration with Ike&#8217;s content QA server. &#8211; should typically be specified at the course level.</dd>
</dl>
</dd>
</dl>
</div>
<div class="section" id="inheritance-example">
<h4>Inheritance example<a class="headerlink" href="#inheritance-example" title="Permalink to this headline"></a></h4>
<p>This is a sketch (&#8220;tue&#8221; is not a valid start date), that should help illustrate how metadata inheritance works.</p>
<blockquote>
<div><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;course</span> <span class="na">start=</span><span class="s">&quot;tue&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;chap1&gt;</span> -- start tue
<span class="nt">&lt;problem&gt;</span> --- start tue
<span class="nt">&lt;/chap1&gt;</span>
<span class="nt">&lt;chap2</span> <span class="na">start=</span><span class="s">&quot;wed&quot;</span><span class="nt">&gt;</span> -- start wed
<span class="nt">&lt;problem2</span> <span class="na">start=</span><span class="s">&quot;thu&quot;</span><span class="nt">&gt;</span> -- start thu
<span class="nt">&lt;problem3&gt;</span> -- start wed
<span class="nt">&lt;/chap2&gt;</span>
<span class="nt">&lt;/course&gt;</span>
</pre></div>
</div>
</div></blockquote>
</div>
<div class="section" id="specifying-metadata-in-the-xml-file">
<h4>Specifying metadata in the XML file<a class="headerlink" href="#specifying-metadata-in-the-xml-file" title="Permalink to this headline"></a></h4>
<p>Metadata can also live in the xml files, but anything defined in the policy file overrides anything in the XML. This is primarily for backwards compatibility, and you should probably not use both. If you do leave some metadata tags in the xml, you should be consistent (e.g. if <cite>display_name</cite> stays in XML, they should all stay in XML. Note <cite>display_name</cite> should be specified in the problem xml definition itself, ie, <cite>&lt;problem display_name=&#8221;Title&#8221;&gt;Problem Text&lt;/problem&gt;</cite>, in file <cite>ProblemFoo.xml</cite>).</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Some xml attributes are not metadata. e.g. in <cite>&lt;video youtube=&#8221;xyz987293487293847&#8221;/&gt;</cite>, the <cite>youtube</cite> attribute specifies what video this is, and is logically part of the content, not the policy, so it should stay in the xml.</p>
</div>
<p>Another example policy file:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="p">{</span>
<span class="s">&quot;course/2012&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="s">&quot;graceperiod&quot;</span><span class="p">:</span> <span class="s">&quot;1 day&quot;</span><span class="p">,</span>
<span class="s">&quot;start&quot;</span><span class="p">:</span> <span class="s">&quot;2012-10-15T12:00&quot;</span><span class="p">,</span>
<span class="s">&quot;display_name&quot;</span><span class="p">:</span> <span class="s">&quot;Introduction to Computer Science I&quot;</span><span class="p">,</span>
<span class="s">&quot;xqa_key&quot;</span><span class="p">:</span> <span class="s">&quot;z1y4vdYcy0izkoPeihtPClDxmbY1ogDK&quot;</span>
<span class="p">},</span>
<span class="s">&quot;chapter/Week_0&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="s">&quot;display_name&quot;</span><span class="p">:</span> <span class="s">&quot;Week 0&quot;</span>
<span class="p">},</span>
<span class="s">&quot;sequential/Pre-Course_Survey&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="s">&quot;display_name&quot;</span><span class="p">:</span> <span class="s">&quot;Pre-Course Survey&quot;</span><span class="p">,</span>
<span class="s">&quot;format&quot;</span><span class="p">:</span> <span class="s">&quot;Survey&quot;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="deprecated-formats">
<h4>Deprecated Formats<a class="headerlink" href="#deprecated-formats" title="Permalink to this headline"></a></h4>
<p>If you look at some older xml, you may see some tags or metadata attributes that aren&#8217;t listed above. They are deprecated, and should not be used in new content. We include them here so that you can understand how old-format content works.</p>
<div class="section" id="obsolete-tags">
<h5>Obsolete Tags<a class="headerlink" href="#obsolete-tags" title="Permalink to this headline"></a></h5>
<dl class="docutils">
<dt><cite>section</cite></dt>
<dd>This used to be necessary within chapters. Now, you can just use any standard tag inside a chapter, so use the container tag that makes the most sense for grouping content&#8211;e.g. <cite>problemset</cite>, <cite>videosequence</cite>, and just include content directly if it belongs inside a chapter (e.g. <cite>html</cite>, <cite>video</cite>, <cite>problem</cite>)</dd>
<dt><cite>videodev, book, slides, image, discuss</cite></dt>
<dd>There used to be special purpose tags that all basically did the same thing, and have been subsumed by <cite>customtag</cite>. The list is <cite>videodev, book, slides, image, discuss</cite>. Use <cite>customtag</cite> in new content. (e.g. instead of <cite>&lt;book page=&#8221;12&#8221;/&gt;</cite>, use <cite>&lt;customtag impl=&#8221;book&#8221; page=&#8221;12&#8221;/&gt;</cite>)</dd>
</dl>
</div>
<div class="section" id="obsolete-attributes">
<h5>Obsolete Attributes<a class="headerlink" href="#obsolete-attributes" title="Permalink to this headline"></a></h5>
<dl class="docutils">
<dt><cite>slug</cite></dt>
<dd>Old term for <cite>url_name</cite>. Use <cite>url_name</cite></dd>
<dt><cite>name</cite></dt>
<dd>We didn&#8217;t originally have a distinction between <cite>url_name</cite> and <cite>display_name</cite> &#8211; this made content element ids fragile, so please use <cite>url_name</cite> as a stable unique identifier for the content, and <cite>display_name</cite> as the particular string you&#8217;d like to display for it.</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="section" id="static-links">
<h2>Static links<a class="headerlink" href="#static-links" title="Permalink to this headline"></a></h2>
<p>If your content links (e.g. in an html file) to <cite>&#8220;static/blah/ponies.jpg&#8221;</cite>, we will look for this...</p>
<ul class="simple">
<li>If your course dir has a <cite>static/</cite> subdirectory, we will look in <cite>YOUR_COURSE_DIR/static/blah/ponies.jpg</cite>. This is the prefered organization, as it does not expose anything except what&#8217;s in <cite>static/</cite> to the world.</li>
<li>If your course dir does not have a <cite>static/</cite> subdirectory, we will look in <cite>YOUR_COURSE_DIR/blah/ponies.jpg</cite>. This is the old organization, and requires that the web server allow access to everything in the couse dir. To switch to the new organization, move all your static content into a new <cite>static/</cite> dir (e.g. if you currently have things in <cite>images/</cite>, <cite>css/</cite>, and <cite>special/</cite>, create a dir called <cite>static/</cite>, and move <cite>images/, css/, and special/</cite> there).</li>
</ul>
<p>Links that include <cite>/course</cite> will be rewritten to the root of your course in the courseware (e.g. <cite>courses/{org}/{course}/{url_name}/</cite> in the current url structure). This is useful for linking to the course wiki, for example.</p>
</div>
<div class="section" id="tabs">
<h2>Tabs<a class="headerlink" href="#tabs" title="Permalink to this headline"></a></h2>
<p>If you want to customize the courseware tabs displayed for your course, specify a &#8220;tabs&#8221; list in the course-level policy, like the following example:</p>
<div class="highlight-json"><pre>"tabs" : [
{"type": "courseware"},
{
"type": "course_info",
"name": "Course Info"
},
{
"type": "external_link",
"name": "My Discussion",
"link": "http://www.mydiscussion.org/blah"
},
{"type": "progress", "name": "Progress"},
{"type": "wiki", "name": "Wonderwiki"},
{
"type": "static_tab",
"url_slug": "news",
"name": "Exciting news"
},
{"type": "textbooks"},
{"type": "html_textbooks"},
{"type": "pdf_textbooks"}
]</pre>
</div>
<ul class="simple">
<li>If you specify any tabs, you must specify all tabs. They will appear in the order given.</li>
<li>The first two tabs must have types <cite>&#8220;courseware&#8221;</cite> and <cite>&#8220;course_info&#8221;</cite>, in that order, or the course will not load.</li>
<li>The <cite>courseware</cite> tab never has a name attribute &#8211; it&#8217;s always rendered as &#8220;Courseware&#8221; for consistency between courses.</li>
<li>The <cite>textbooks</cite> tab will actually generate one tab per textbook, using the textbook titles as names.</li>
<li>The <cite>html_textbooks</cite> tab will actually generate one tab per html_textbook. The tab name is found in the html textbook definition.</li>
<li>The <cite>pdf_textbooks</cite> tab will actually generate one tab per pdf_textbook. The tab name is found in the pdf textbook definition.</li>
<li>For static tabs, the <cite>url_slug</cite> will be the url that points to the tab. It can not be one of the existing courseware url types (even if those aren&#8217;t used in your course). The static content will come from <cite>tabs/{course_url_name}/{url_slug}.html</cite>, or <cite>tabs/{url_slug}.html</cite> if that doesn&#8217;t exist.</li>
<li>An Instructor tab will be automatically added at the end for course staff users.</li>
</ul>
<table border="1" class="docutils">
<caption>Supported Tabs and Parameters</caption>
<colgroup>
<col width="11%" />
<col width="89%" />
</colgroup>
<tbody valign="top">
<tr class="row-odd"><td><cite>courseware</cite></td>
<td>No other parameters.</td>
</tr>
<tr class="row-even"><td><cite>course_info</cite></td>
<td>Parameter <cite>name</cite>.</td>
</tr>
<tr class="row-odd"><td><cite>wiki</cite></td>
<td>Parameter <cite>name</cite>.</td>
</tr>
<tr class="row-even"><td><cite>discussion</cite></td>
<td>Parameter <cite>name</cite>.</td>
</tr>
<tr class="row-odd"><td><cite>external_link</cite></td>
<td>Parameters <cite>name</cite>, <cite>link</cite>.</td>
</tr>
<tr class="row-even"><td><cite>textbooks</cite></td>
<td>No parameters&#8211;generates tab names from book titles.</td>
</tr>
<tr class="row-odd"><td><cite>html_textbooks</cite></td>
<td>No parameters&#8211;generates tab names from html book definition. (See discussion below for configuration.)</td>
</tr>
<tr class="row-even"><td><cite>pdf_textbooks</cite></td>
<td>No parameters&#8211;generates tab names from pdf book definition. (See discussion below for configuration.)</td>
</tr>
<tr class="row-odd"><td><cite>progress</cite></td>
<td>Parameter <cite>name</cite>.</td>
</tr>
<tr class="row-even"><td><cite>static_tab</cite></td>
<td>Parameters <cite>name</cite>, <cite>url_slug</cite>&#8211;will look for tab contents in &#8216;tabs/{course_url_name}/{tab url_slug}.html&#8217;</td>
</tr>
<tr class="row-odd"><td><cite>staff_grading</cite></td>
<td>No parameters. If specified, displays the staff grading tab for instructors.</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="textbooks">
<h2>Textbooks<a class="headerlink" href="#textbooks" title="Permalink to this headline"></a></h2>
<p>Support is currently provided for image-based, HTML-based and PDF-based textbooks. In addition to enabling the display of textbooks in tabs (see above), specific information about the location of textbook content must be configured.</p>
<div class="section" id="image-based-textbooks">
<h3>Image-based Textbooks<a class="headerlink" href="#image-based-textbooks" title="Permalink to this headline"></a></h3>
<div class="section" id="configuration">
<h4>Configuration<a class="headerlink" href="#configuration" title="Permalink to this headline"></a></h4>
<p>Image-based textbooks are configured at the course level in the XML markup. Here is an example:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;course&gt;</span>
<span class="nt">&lt;textbook</span> <span class="na">title=</span><span class="s">&quot;Textbook 1&quot;</span> <span class="na">book_url=</span><span class="s">&quot;https://www.example.com/textbook_1/&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;textbook</span> <span class="na">title=</span><span class="s">&quot;Textbook 2&quot;</span> <span class="na">book_url=</span><span class="s">&quot;https://www.example.com/textbook_2/&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;chapter</span> <span class="na">url_name=</span><span class="s">&quot;Overview&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;chapter</span> <span class="na">url_name=</span><span class="s">&quot;First week&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;/course&gt;</span>
</pre></div>
</div>
<p>Each <cite>textbook</cite> element is displayed on a different tab. The <cite>title</cite> attribute is used as the tab&#8217;s name, and the <cite>book_url</cite> attribute points to the remote directory that contains the images of the text. Note the trailing slash on the end of the <cite>book_url</cite> attribute.</p>
<p>The images must be stored in the same directory as the <cite>book_url</cite>, with filenames matching <cite>pXXX.png</cite>, where <cite>XXX</cite> is a three-digit number representing the page number (with leading zeroes as necessary). Pages start at <cite>p001.png</cite>.</p>
<p>Each textbook must also have its own table of contents. This is read from the <cite>book_url</cite> location, by appending <cite>toc.xml</cite>. This file contains a <cite>table_of_contents</cite> parent element, with <cite>entry</cite> elements nested below it. Each <cite>entry</cite> has attributes for <cite>name</cite>, <cite>page_label</cite>, and <cite>page</cite>, as well as an optional <cite>chapter</cite> attribute. An arbitrary number of levels of nesting of <cite>entry</cite> elements within other <cite>entry</cite> elements is supported, but you&#8217;re likely to only want two levels. The <cite>page</cite> represents the actual page to link to, while the <cite>page_label</cite> matches the displayed page number on that page. Here&#8217;s an example:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;table_of_contents&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;1&quot;</span> <span class="na">page_label=</span><span class="s">&quot;i&quot;</span> <span class="na">name=</span><span class="s">&quot;Title&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;2&quot;</span> <span class="na">page_label=</span><span class="s">&quot;ii&quot;</span> <span class="na">name=</span><span class="s">&quot;Preamble&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;2&quot;</span> <span class="na">page_label=</span><span class="s">&quot;ii&quot;</span> <span class="na">name=</span><span class="s">&quot;Copyright&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;3&quot;</span> <span class="na">page_label=</span><span class="s">&quot;iii&quot;</span> <span class="na">name=</span><span class="s">&quot;Brief Contents&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;5&quot;</span> <span class="na">page_label=</span><span class="s">&quot;v&quot;</span> <span class="na">name=</span><span class="s">&quot;Contents&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;9&quot;</span> <span class="na">page_label=</span><span class="s">&quot;1&quot;</span> <span class="na">name=</span><span class="s">&quot;About the Authors&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;10&quot;</span> <span class="na">page_label=</span><span class="s">&quot;2&quot;</span> <span class="na">name=</span><span class="s">&quot;Acknowledgments&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;11&quot;</span> <span class="na">page_label=</span><span class="s">&quot;3&quot;</span> <span class="na">name=</span><span class="s">&quot;Dedication&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;12&quot;</span> <span class="na">page_label=</span><span class="s">&quot;4&quot;</span> <span class="na">name=</span><span class="s">&quot;Preface&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/entry&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;15&quot;</span> <span class="na">page_label=</span><span class="s">&quot;7&quot;</span> <span class="na">name=</span><span class="s">&quot;Introduction to edX&quot;</span> <span class="na">chapter=</span><span class="s">&quot;1&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;15&quot;</span> <span class="na">page_label=</span><span class="s">&quot;7&quot;</span> <span class="na">name=</span><span class="s">&quot;edX in the Modern World&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;18&quot;</span> <span class="na">page_label=</span><span class="s">&quot;10&quot;</span> <span class="na">name=</span><span class="s">&quot;The edX Method&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;18&quot;</span> <span class="na">page_label=</span><span class="s">&quot;10&quot;</span> <span class="na">name=</span><span class="s">&quot;A Description of edX&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;29&quot;</span> <span class="na">page_label=</span><span class="s">&quot;21&quot;</span> <span class="na">name=</span><span class="s">&quot;A Brief History of edX&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;51&quot;</span> <span class="na">page_label=</span><span class="s">&quot;43&quot;</span> <span class="na">name=</span><span class="s">&quot;Introduction to edX&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;56&quot;</span> <span class="na">page_label=</span><span class="s">&quot;48&quot;</span> <span class="na">name=</span><span class="s">&quot;Endnotes&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/entry&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;73&quot;</span> <span class="na">page_label=</span><span class="s">&quot;65&quot;</span> <span class="na">name=</span><span class="s">&quot;Art and Photo Credits&quot;</span> <span class="na">chapter=</span><span class="s">&quot;30&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;73&quot;</span> <span class="na">page_label=</span><span class="s">&quot;65&quot;</span> <span class="na">name=</span><span class="s">&quot;Molecular Models&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;73&quot;</span> <span class="na">page_label=</span><span class="s">&quot;65&quot;</span> <span class="na">name=</span><span class="s">&quot;Photo Credits&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/entry&gt;</span>
<span class="nt">&lt;entry</span> <span class="na">page=</span><span class="s">&quot;77&quot;</span> <span class="na">page_label=</span><span class="s">&quot;69&quot;</span> <span class="na">name=</span><span class="s">&quot;Index&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/table_of_contents&gt;</span>
</pre></div>
</div>
</div>
<div class="section" id="linking-from-content">
<h4>Linking from Content<a class="headerlink" href="#linking-from-content" title="Permalink to this headline"></a></h4>
<p>It is possible to add links to specific pages in a textbook by using a URL that encodes the index of the textbook and the page number. The URL is of the form <cite>/course/book/${bookindex}/$page}</cite>. If the page is omitted from the URL, the first page is assumed.</p>
<p>You can use a <cite>customtag</cite> to create a template for such links. For example, you can create a <cite>book</cite> template in the <cite>customtag</cite> directory, containing:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">&quot;/static/images/icons/textbook_icon.png&quot;</span><span class="nt">/&gt;</span> More information given in <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/course/book/${book}/${page}&quot;</span><span class="nt">&gt;</span>the text<span class="nt">&lt;/a&gt;</span>.
</pre></div>
</div>
<p>The course content can then link to page 25 using the <cite>customtag</cite> element:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;customtag</span> <span class="na">book=</span><span class="s">&quot;0&quot;</span> <span class="na">page=</span><span class="s">&quot;25&quot;</span> <span class="na">impl=</span><span class="s">&quot;book&quot;</span><span class="nt">/&gt;</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="html-based-textbooks">
<h3>HTML-based Textbooks<a class="headerlink" href="#html-based-textbooks" title="Permalink to this headline"></a></h3>
<div class="section" id="id2">
<h4>Configuration<a class="headerlink" href="#id2" title="Permalink to this headline"></a></h4>
<p>HTML-based textbooks are configured at the course level in the policy file. The JSON markup consists of an array of maps, with each map corresponding to a separate textbook. There are two styles to presenting HTML-based material. The first way is as a single HTML on a tab, which requires only a tab title and a URL for configuration. A second way permits the display of multiple HTML files that should be displayed together on a single view. For this view, a side panel of links is available on the left, allowing selection of a particular HTML to view.</p>
<div class="highlight-json"><pre>"html_textbooks": [
{"tab_title": "Textbook 1",
"url": "https://www.example.com/thiscourse/book1/book1.html" },
{"tab_title": "Textbook 2",
"chapters": [
{ "title": "Chapter 1", "url": "https://www.example.com/thiscourse/book2/Chapter1.html" },
{ "title": "Chapter 2", "url": "https://www.example.com/thiscourse/book2/Chapter2.html" },
{ "title": "Chapter 3", "url": "https://www.example.com/thiscourse/book2/Chapter3.html" },
{ "title": "Chapter 4", "url": "https://www.example.com/thiscourse/book2/Chapter4.html" },
{ "title": "Chapter 5", "url": "https://www.example.com/thiscourse/book2/Chapter5.html" },
{ "title": "Chapter 6", "url": "https://www.example.com/thiscourse/book2/Chapter6.html" },
{ "title": "Chapter 7", "url": "https://www.example.com/thiscourse/book2/Chapter7.html" }
]
}
]</pre>
</div>
<p>Some notes:</p>
<ul class="simple">
<li>It is not a good idea to include a top-level URL and chapter-level URLs in the same textbook configuration.</li>
</ul>
</div>
<div class="section" id="id3">
<h4>Linking from Content<a class="headerlink" href="#id3" title="Permalink to this headline"></a></h4>
<p>It is possible to add links to specific pages in a textbook by using a URL that encodes the index of the textbook, the chapter (if chapters are used), and the page number. For a book with no chapters, the URL is of the form <cite>/course/htmlbook/${bookindex}</cite>. For a book with chapters, use <cite>/course/htmlbook/${bookindex}/chapter/${chapter}</cite> for a specific chapter, or <cite>/course/htmlbook/${bookindex}</cite> will default to the first chapter.</p>
<p>For example, for the book with no chapters configured above, the textbook can be reached using the URL <cite>/course/htmlbook/0</cite>. Reaching the third chapter of the second book is accomplished with <cite>/course/htmlbook/1/chapter/3</cite>.</p>
<p>You can use a <cite>customtag</cite> to create a template for such links. For example, you can create a <cite>htmlbook</cite> template in the <cite>customtag</cite> directory, containing:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">&quot;/static/images/icons/textbook_icon.png&quot;</span><span class="nt">/&gt;</span> More information given in <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/course/htmlbook/${book}&quot;</span><span class="nt">&gt;</span>the text<span class="nt">&lt;/a&gt;</span>.
</pre></div>
</div>
<p>And a <cite>htmlchapter</cite> template containing:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">&quot;/static/images/icons/textbook_icon.png&quot;</span><span class="nt">/&gt;</span> More information given in <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/course/htmlbook/${book}/chapter/${chapter}&quot;</span><span class="nt">&gt;</span>the text<span class="nt">&lt;/a&gt;</span>.
</pre></div>
</div>
<p>The example pages can then be linked using the <cite>customtag</cite> element:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;customtag</span> <span class="na">book=</span><span class="s">&quot;0&quot;</span> <span class="na">impl=</span><span class="s">&quot;htmlbook&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;customtag</span> <span class="na">book=</span><span class="s">&quot;1&quot;</span> <span class="na">chapter=</span><span class="s">&quot;3&quot;</span> <span class="na">impl=</span><span class="s">&quot;htmlchapter&quot;</span><span class="nt">/&gt;</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="pdf-based-textbooks">
<h3>PDF-based Textbooks<a class="headerlink" href="#pdf-based-textbooks" title="Permalink to this headline"></a></h3>
<div class="section" id="id4">
<h4>Configuration<a class="headerlink" href="#id4" title="Permalink to this headline"></a></h4>
<p>PDF-based textbooks are configured at the course level in the policy file. The JSON markup consists of an array of maps, with each map corresponding to a separate textbook. There are two styles to presenting PDF-based material. The first way is as a single PDF on a tab, which requires only a tab title and a URL for configuration. A second way permits the display of multiple PDFs that should be displayed together on a single view. For this view, a side panel of links is available on the left, allowing selection of a particular PDF to view.</p>
<div class="highlight-json"><pre>"pdf_textbooks": [
{"tab_title": "Textbook 1",
"url": "https://www.example.com/thiscourse/book1/book1.pdf" },
{"tab_title": "Textbook 2",
"chapters": [
{ "title": "Chapter 1", "url": "https://www.example.com/thiscourse/book2/Chapter1.pdf" },
{ "title": "Chapter 2", "url": "https://www.example.com/thiscourse/book2/Chapter2.pdf" },
{ "title": "Chapter 3", "url": "https://www.example.com/thiscourse/book2/Chapter3.pdf" },
{ "title": "Chapter 4", "url": "https://www.example.com/thiscourse/book2/Chapter4.pdf" },
{ "title": "Chapter 5", "url": "https://www.example.com/thiscourse/book2/Chapter5.pdf" },
{ "title": "Chapter 6", "url": "https://www.example.com/thiscourse/book2/Chapter6.pdf" },
{ "title": "Chapter 7", "url": "https://www.example.com/thiscourse/book2/Chapter7.pdf" }
]
}
]</pre>
</div>
<p>Some notes:</p>
<ul class="simple">
<li>It is not a good idea to include a top-level URL and chapter-level URLs in the same textbook configuration.</li>
</ul>
</div>
<div class="section" id="id5">
<h4>Linking from Content<a class="headerlink" href="#id5" title="Permalink to this headline"></a></h4>
<p>It is possible to add links to specific pages in a textbook by using a URL that encodes the index of the textbook, the chapter (if chapters are used), and the page number. For a book with no chapters, the URL is of the form <cite>/course/pdfbook/${bookindex}/$page}</cite>. For a book with chapters, use <cite>/course/pdfbook/${bookindex}/chapter/${chapter}/${page}</cite>. If the page is omitted from the URL, the first page is assumed.</p>
<p>For example, for the book with no chapters configured above, page 25 can be reached using the URL <cite>/course/pdfbook/0/25</cite>. Reaching page 19 in the third chapter of the second book is accomplished with <cite>/course/pdfbook/1/chapter/3/19</cite>.</p>
<p>You can use a <cite>customtag</cite> to create a template for such links. For example, you can create a <cite>pdfbook</cite> template in the <cite>customtag</cite> directory, containing:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">&quot;/static/images/icons/textbook_icon.png&quot;</span><span class="nt">/&gt;</span> More information given in <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/course/pdfbook/${book}/${page}&quot;</span><span class="nt">&gt;</span>the text<span class="nt">&lt;/a&gt;</span>.
</pre></div>
</div>
<p>And a <cite>pdfchapter</cite> template containing:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">&quot;/static/images/icons/textbook_icon.png&quot;</span><span class="nt">/&gt;</span> More information given in <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/course/pdfbook/${book}/chapter/${chapter}/${page}&quot;</span><span class="nt">&gt;</span>the text<span class="nt">&lt;/a&gt;</span>.
</pre></div>
</div>
<p>The example pages can then be linked using the <cite>customtag</cite> element:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;customtag</span> <span class="na">book=</span><span class="s">&quot;0&quot;</span> <span class="na">page=</span><span class="s">&quot;25&quot;</span> <span class="na">impl=</span><span class="s">&quot;pdfbook&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;customtag</span> <span class="na">book=</span><span class="s">&quot;1&quot;</span> <span class="na">chapter=</span><span class="s">&quot;3&quot;</span> <span class="na">page=</span><span class="s">&quot;19&quot;</span> <span class="na">impl=</span><span class="s">&quot;pdfchapter&quot;</span><span class="nt">/&gt;</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="other-file-locations-info-and-about">
<h2>Other file locations (info and about)<a class="headerlink" href="#other-file-locations-info-and-about" title="Permalink to this headline"></a></h2>
<p>With different course runs, we may want different course info and about materials. This is now supported by putting files in as follows:</p>
<div class="highlight-python"><pre>/
about/
foo.html -- shared default for all runs
url_name1/
foo.html -- version used for url_name1
bar.html -- bar for url_name1
url_name2/
bar.html -- bar for url_name2
-- url_name2 will use default foo.html</pre>
</div>
<p>and the same works for the <cite>info</cite> directory.</p>
</div>
<div class="section" id="tips-for-content-developers">
<h2>Tips for content developers<a class="headerlink" href="#tips-for-content-developers" title="Permalink to this headline"></a></h2>
<ol class="arabic simple">
<li>We will be making better tools for managing policy files soon. In the meantime, you can add dummy definitions to make it easier to search and separate the file visually. For example, you could add <cite>&#8220;WEEK 1&#8221; : &#8220;###################&#8221;</cite>, before the week 1 material to make it easy to find in the file.</li>
<li>Come up with a consistent pattern for url_names, so that it&#8217;s easy to know where to look for any piece of content. It will also help to come up with a standard way of splitting your content files. As a point of departure, we suggest splitting chapters, sequences, html, and problems into separate files.</li>
<li>Prefer the most &#8220;semantic&#8221; name for containers: e.g., use problemset rather than sequential for a problem set. That way, if we decide to display problem sets differently, we don&#8217;t have to change the XML.</li>
</ol>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="grading.html" title="Course Grading"
>next</a> |</li>
<li class="right" >
<a href="../index.html" title="edX Data Documentation"
>previous</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CustomResponse XML and Python Script &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="../index.html" />
<link rel="next" title="Student Info and Progress Data" href="../internal_data_formats/sql_schema.html" />
<link rel="prev" title="Xml format of conditional module [xmodule]" href="conditional_module/conditional_module.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../internal_data_formats/sql_schema.html" title="Student Info and Progress Data"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="conditional_module/conditional_module.html" title="Xml format of conditional module [xmodule]"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">CustomResponse XML and Python Script</a><ul>
<li><a class="reference internal" href="#answer-tag-format">Answer tag format</a></li>
<li><a class="reference internal" href="#script-tag-format">Script tag format</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="conditional_module/conditional_module.html"
title="previous chapter">Xml format of conditional module [xmodule]</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="../internal_data_formats/sql_schema.html"
title="next chapter">Student Info and Progress Data</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/course_data_formats/custom_response.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="customresponse-xml-and-python-script">
<h1>CustomResponse XML and Python Script<a class="headerlink" href="#customresponse-xml-and-python-script" title="Permalink to this headline"></a></h1>
<p>This document explains how to write a CustomResponse problem. CustomResponse
problems execute Python script to check student answers and provide hints.</p>
<p>There are two general ways to create a CustomResponse problem:</p>
<div class="section" id="answer-tag-format">
<h2>Answer tag format<a class="headerlink" href="#answer-tag-format" title="Permalink to this headline"></a></h2>
<p>One format puts the Python code in an <tt class="docutils literal"><span class="pre">&lt;answer&gt;</span></tt> tag:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;problem&gt;</span>
<span class="nt">&lt;p&gt;</span>What is the sum of 2 and 3?<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;customresponse</span> <span class="na">expect=</span><span class="s">&quot;5&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;textline</span> <span class="na">math=</span><span class="s">&quot;1&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/customresponse&gt;</span>
<span class="nt">&lt;answer&gt;</span>
# Python script goes here
<span class="nt">&lt;/answer&gt;</span>
<span class="nt">&lt;/problem&gt;</span>
</pre></div>
</div>
<dl class="docutils">
<dt>The Python script interacts with these variables in the global context:</dt>
<dd><ul class="first last simple">
<li><tt class="docutils literal"><span class="pre">answers</span></tt>: An ordered list of answers the student provided.
For example, if the student answered <tt class="docutils literal"><span class="pre">6</span></tt>, then <tt class="docutils literal"><span class="pre">answers[0]</span></tt> would
equal <tt class="docutils literal"><span class="pre">6</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">expect</span></tt>: The value of the <tt class="docutils literal"><span class="pre">expect</span></tt> attribute of <tt class="docutils literal"><span class="pre">&lt;customresponse&gt;</span></tt>
(if provided).</li>
<li><tt class="docutils literal"><span class="pre">correct</span></tt>: An ordered list of strings indicating whether the
student answered the question correctly. Valid values are
<tt class="docutils literal"><span class="pre">&quot;correct&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;incorrect&quot;</span></tt>, and <tt class="docutils literal"><span class="pre">&quot;unknown&quot;</span></tt>. You can set these
values in the script.</li>
<li><tt class="docutils literal"><span class="pre">messages</span></tt>: An ordered list of message strings that will be displayed
beneath each input. You can use this to provide hints to users.
For example <tt class="docutils literal"><span class="pre">messages[0]</span> <span class="pre">=</span> <span class="pre">&quot;The</span> <span class="pre">capital</span> <span class="pre">of</span> <span class="pre">California</span> <span class="pre">is</span> <span class="pre">Sacramento&quot;</span></tt>
would display that message beneath the first input of the response.</li>
<li><tt class="docutils literal"><span class="pre">overall_message</span></tt>: A string that will be displayed beneath the
entire problem. You can use this to provide a hint that applies
to the entire problem rather than a particular input.</li>
</ul>
</dd>
</dl>
<p>Example of a checking script:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">if</span> <span class="n">answers</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="n">expect</span><span class="p">:</span>
<span class="n">correct</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;correct&#39;</span>
<span class="n">overall_message</span> <span class="o">=</span> <span class="s">&#39;Good job!&#39;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">correct</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;incorrect&#39;</span>
<span class="n">messages</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;This answer is incorrect&#39;</span>
<span class="n">overall_message</span> <span class="o">=</span> <span class="s">&#39;Please try again&#39;</span>
</pre></div>
</div>
<p><strong>Important</strong>: Python is picky about indentation. Within the <tt class="docutils literal"><span class="pre">&lt;answer&gt;</span></tt> tag,
you must begin your script with no indentation.</p>
</div>
<div class="section" id="script-tag-format">
<h2>Script tag format<a class="headerlink" href="#script-tag-format" title="Permalink to this headline"></a></h2>
<p>The other way to create a CustomResponse is to put a &#8220;checking function&#8221;
in a <tt class="docutils literal"><span class="pre">&lt;script&gt;</span></tt> tag, then use the <tt class="docutils literal"><span class="pre">cfn</span></tt> attribute of the
<tt class="docutils literal"><span class="pre">&lt;customresponse&gt;</span></tt> tag:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;problem&gt;</span>
<span class="nt">&lt;p&gt;</span>What is the sum of 2 and 3?<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;customresponse</span> <span class="na">cfn=</span><span class="s">&quot;check_func&quot;</span> <span class="na">expect=</span><span class="s">&quot;5&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;textline</span> <span class="na">math=</span><span class="s">&quot;1&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/customresponse&gt;</span>
<span class="nt">&lt;script</span> <span class="na">type=</span><span class="s">&quot;loncapa/python&quot;</span><span class="nt">&gt;</span>
def check_func(expect, ans):
# Python script goes here
<span class="nt">&lt;/script&gt;</span>
<span class="nt">&lt;/problem&gt;</span>
</pre></div>
</div>
<p><strong>Important</strong>: Python is picky about indentation. Within the <tt class="docutils literal"><span class="pre">&lt;script&gt;</span></tt> tag,
the <tt class="docutils literal"><span class="pre">def</span> <span class="pre">check_func(expect,</span> <span class="pre">ans):</span></tt> line must have no indentation.</p>
<dl class="docutils">
<dt>The check function accepts two arguments:</dt>
<dd><ul class="first last">
<li><p class="first"><tt class="docutils literal"><span class="pre">expect</span></tt> is the value of the <tt class="docutils literal"><span class="pre">expect</span></tt> attribute of <tt class="docutils literal"><span class="pre">&lt;customresponse&gt;</span></tt>
(if provided)</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">answer</span></tt> is either:</p>
<blockquote>
<div><ul class="simple">
<li>The value of the answer the student provided, if there is only one input.</li>
<li>An ordered list of answers the student provided, if there
are multiple inputs.</li>
</ul>
</div></blockquote>
</li>
</ul>
</dd>
</dl>
<p>There are several ways that the check function can indicate whether the student
succeeded. The check function can return any of the following:</p>
<blockquote>
<div><ul class="simple">
<li><tt class="docutils literal"><span class="pre">True</span></tt>: Indicates that the student answered correctly for all inputs.</li>
<li><tt class="docutils literal"><span class="pre">False</span></tt>: Indicates that the student answered incorrectly.
All inputs will be marked incorrect.</li>
<li>A dictionary of the form: <tt class="docutils literal"><span class="pre">{</span> <span class="pre">'ok':</span> <span class="pre">True,</span> <span class="pre">'msg':</span> <span class="pre">'Message'</span> <span class="pre">}</span></tt>
If the dictionary&#8217;s value for <tt class="docutils literal"><span class="pre">ok</span></tt> is set to <tt class="docutils literal"><span class="pre">True</span></tt>, all inputs are
marked correct; if it is set to <tt class="docutils literal"><span class="pre">False</span></tt>, all inputs are marked incorrect.
The <tt class="docutils literal"><span class="pre">msg</span></tt> is displayed beneath all inputs, and it may contain
XHTML markup.</li>
<li>A dictionary of the form</li>
</ul>
</div></blockquote>
<div class="highlight-xml"><div class="highlight"><pre>{ &#39;overall_message&#39;: &#39;Overall message&#39;,
&#39;input_list&#39;: [
{ &#39;ok&#39;: True, &#39;msg&#39;: &#39;Feedback for input 1&#39;},
{ &#39;ok&#39;: False, &#39;msg&#39;: &#39;Feedback for input 2&#39;},
... ] }
</pre></div>
</div>
<p>The last form is useful for responses that contain multiple inputs.
It allows you to provide feedback for each input individually,
as well as a message that applies to the entire response.</p>
<p>Example of a checking function:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">check_func</span><span class="p">(</span><span class="n">expect</span><span class="p">,</span> <span class="n">answer_given</span><span class="p">):</span>
<span class="n">check1</span> <span class="o">=</span> <span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">answer_given</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">check2</span> <span class="o">=</span> <span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">answer_given</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">check3</span> <span class="o">=</span> <span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">answer_given</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span> <span class="o">==</span> <span class="mi">3</span><span class="p">)</span>
<span class="k">return</span> <span class="p">{</span><span class="s">&#39;overall_message&#39;</span><span class="p">:</span> <span class="s">&#39;Overall message&#39;</span><span class="p">,</span>
<span class="s">&#39;input_list&#39;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span> <span class="s">&#39;ok&#39;</span><span class="p">:</span> <span class="n">check1</span><span class="p">,</span> <span class="s">&#39;msg&#39;</span><span class="p">:</span> <span class="s">&#39;Feedback 1&#39;</span><span class="p">},</span>
<span class="p">{</span> <span class="s">&#39;ok&#39;</span><span class="p">:</span> <span class="n">check2</span><span class="p">,</span> <span class="s">&#39;msg&#39;</span><span class="p">:</span> <span class="s">&#39;Feedback 2&#39;</span><span class="p">},</span>
<span class="p">{</span> <span class="s">&#39;ok&#39;</span><span class="p">:</span> <span class="n">check3</span><span class="p">,</span> <span class="s">&#39;msg&#39;</span><span class="p">:</span> <span class="s">&#39;Feedback 3&#39;</span><span class="p">}</span> <span class="p">]</span> <span class="p">}</span>
</pre></div>
</div>
<p>The function checks that the user entered <tt class="docutils literal"><span class="pre">1</span></tt> for the first input,
<tt class="docutils literal"><span class="pre">2</span></tt> for the second input, and <tt class="docutils literal"><span class="pre">3</span></tt> for the third input.
It provides feedback messages for each individual input, as well
as a message displayed beneath the entire problem.</p>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../internal_data_formats/sql_schema.html" title="Student Info and Progress Data"
>next</a> |</li>
<li class="right" >
<a href="conditional_module/conditional_module.html" title="Xml format of conditional module [xmodule]"
>previous</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>XML format of drag and drop input [inputtypes] &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../../',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="../../index.html" />
<link rel="next" title="XML format of graphical slider tool [xmodule]" href="../graphical_slider_tool/graphical_slider_tool.html" />
<link rel="prev" title="Course Grading" href="../grading.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../graphical_slider_tool/graphical_slider_tool.html" title="XML format of graphical slider tool [xmodule]"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="../grading.html" title="Course Grading"
accesskey="P">previous</a> |</li>
<li><a href="../../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">XML format of drag and drop input [inputtypes]</a><ul>
<li><a class="reference internal" href="#format-description">Format description</a><ul>
<li><a class="reference internal" href="#drag-and-drop-input-tag">drag_and_drop_input tag</a></li>
<li><a class="reference internal" href="#draggable-tag">draggable tag</a></li>
<li><a class="reference internal" href="#target-tag">target tag</a></li>
<li><a class="reference internal" href="#targets-on-draggables">Targets on draggables</a></li>
<li><a class="reference internal" href="#limitations-of-targets-on-draggables">Limitations of targets on draggables</a></li>
<li><a class="reference internal" href="#correct-answer-format">Correct answer format</a></li>
<li><a class="reference internal" href="#answer-format-for-targets-on-draggables">Answer format for targets on draggables</a></li>
<li><a class="reference internal" href="#grading-logic">Grading logic</a><ul>
<li><a class="reference internal" href="#set-and-number-cases">Set and &#8216;+number&#8217; cases</a></li>
</ul>
</li>
<li><a class="reference internal" href="#logic-flow">Logic flow</a></li>
</ul>
</li>
<li><a class="reference internal" href="#example">Example</a><ul>
<li><a class="reference internal" href="#examples-of-draggables-that-can-t-be-reused">Examples of draggables that can&#8217;t be reused</a></li>
<li><a class="reference internal" href="#draggables-can-be-reused">Draggables can be reused</a></li>
<li><a class="reference internal" href="#examples-of-targets-on-draggables">Examples of targets on draggables</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="../grading.html"
title="previous chapter">Course Grading</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="../graphical_slider_tool/graphical_slider_tool.html"
title="next chapter">XML format of graphical slider tool [xmodule]</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../../_sources/course_data_formats/drag_and_drop/drag_and_drop_input.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-drag_and_drop_input">
<span id="xml-format-of-drag-and-drop-input-inputtypes"></span><h1>XML format of drag and drop input [inputtypes]<a class="headerlink" href="#module-drag_and_drop_input" title="Permalink to this headline"></a></h1>
<div class="section" id="format-description">
<h2>Format description<a class="headerlink" href="#format-description" title="Permalink to this headline"></a></h2>
<p>The main tag of Drag and Drop (DnD) input is:</p>
<div class="highlight-python"><pre>&lt;drag_and_drop_input&gt; ... &lt;/drag_and_drop_input&gt;</pre>
</div>
<p><tt class="docutils literal"><span class="pre">drag_and_drop_input</span></tt> can include any number of the following 2 tags:
<tt class="docutils literal"><span class="pre">draggable</span></tt> and <tt class="docutils literal"><span class="pre">target</span></tt>.</p>
<div class="section" id="drag-and-drop-input-tag">
<h3>drag_and_drop_input tag<a class="headerlink" href="#drag-and-drop-input-tag" title="Permalink to this headline"></a></h3>
<p>The main container for a single instance of DnD. The following attributes can
be specified for this tag:</p>
<div class="highlight-python"><pre>img - Relative path to an image that will be the base image. All draggables
can be dragged onto it.
target_outline - Specify whether an outline (gray dashed line) should be
drawn around targets (if they are specified). It can be either
'true' or 'false'. If not specified, the default value is
'false'.
one_per_target - Specify whether to allow more than one draggable to be
placed onto a single target. It can be either 'true' or 'false'. If
not specified, the default value is 'true'.
no_labels - default is false, in default behaviour if label is not set, label
is obtained from id. If no_labels is true, labels are not automatically
populated from id, and one can not set labels and obtain only icons.</pre>
</div>
</div>
<div class="section" id="draggable-tag">
<h3>draggable tag<a class="headerlink" href="#draggable-tag" title="Permalink to this headline"></a></h3>
<p>Draggable tag specifies a single draggable object which has the following
attributes:</p>
<div class="highlight-python"><pre>id - Unique identifier of the draggable object.
label - Human readable label that will be shown to the user.
icon - Relative path to an image that will be shown to the user.
can_reuse - true or false, default is false. If true, same draggable can be
used multiple times.</pre>
</div>
<p>A draggable is what the user must drag out of the slider and place onto the
base image. After a drag operation, if the center of the draggable ends up
outside the rectangular dimensions of the image, it will be returned back
to the slider.</p>
<p>In order for the grader to work, it is essential that a unique ID
is provided. Otherwise, there will be no way to tell which draggable is at what
coordinate, or over what target. Label and icon attributes are optional. If
they are provided they will be used, otherwise, you can have an empty
draggable. The path is relative to &#8216;course_folder&#8217; folder, for example,
/static/images/img1.png.</p>
</div>
<div class="section" id="target-tag">
<h3>target tag<a class="headerlink" href="#target-tag" title="Permalink to this headline"></a></h3>
<p>Target tag specifies a single target object which has the following required
attributes:</p>
<div class="highlight-python"><pre>id - Unique identifier of the target object.
x - X-coordinate on the base image where the top left corner of the target
will be positioned.
y - Y-coordinate on the base image where the top left corner of the target
will be positioned.
w - Width of the target.
h - Height of the target.</pre>
</div>
<p>A target specifies a place on the base image where a draggable can be
positioned. By design, if the center of a draggable lies within the target
(i.e. in the rectangle defined by [[x, y], [x + w, y + h]], then it is within
the target. Otherwise, it is outside.</p>
<p>If at lest one target is provided, the behavior of the client side logic
changes. If a draggable is not dragged on to a target, it is returned back to
the slider.</p>
<p>If no targets are provided, then a draggable can be dragged and placed anywhere
on the base image.</p>
</div>
<div class="section" id="targets-on-draggables">
<h3>Targets on draggables<a class="headerlink" href="#targets-on-draggables" title="Permalink to this headline"></a></h3>
<p>Sometimes it is not enough to have targets only on the base image, and all of the
draggables on these targets. If a complex problem exists where a draggable must
become itself a target (or many targets), then the following extended syntax
can be used:</p>
<div class="highlight-python"><pre>&lt;draggable {attribute list}&gt;
&lt;target {attribute list} /&gt;
&lt;target {attribute list} /&gt;
&lt;target {attribute list} /&gt;
...
&lt;/draggable&gt;</pre>
</div>
<p>The attribute list in the tags above (&#8216;draggable&#8217; and &#8216;target&#8217;) is the same as for
normal &#8216;draggable&#8217; and &#8216;target&#8217; tags. The only difference is when you will be
specifying inner target position coordinates. Using the &#8216;x&#8217; and &#8216;y&#8217; attributes you
are setting the offset of the inner target from the upper-left corner of the
parent draggable (that contains the inner target).</p>
</div>
<div class="section" id="limitations-of-targets-on-draggables">
<h3>Limitations of targets on draggables<a class="headerlink" href="#limitations-of-targets-on-draggables" title="Permalink to this headline"></a></h3>
<p>1.) Currently there is a limitation to the level of nesting of targets.</p>
<p>Even though you can pile up a large number of draggables on targets that themselves
are on draggables, the Drag and Drop instance will be graded only in the case if
there is a maximum of two levels of targets. The first level are the &#8220;base&#8221; targets.
They are attached to the base image. The second level are the targets defined on
draggables.</p>
<p>2.) Another limitation is that the target bounds are not checked against
other targets.</p>
<p>For now, it is the responsibility of the person who is constructing the course
material to make sure that there is no overlapping of targets. It is also preferable
that targets on draggables are smaller than the actual parent draggable. Technically
this is not necessary, but from the usability perspective it is desirable.</p>
<p>3.) You can have targets on draggables only in the case when there are base targets
defined (base targets are attached to the base image).</p>
<p>If you do not have base targets, then you can only have a single level of nesting
(draggables on the base image). In this case the client side will be reporting (x,y)
positions of each draggables on the base image.</p>
</div>
<div class="section" id="correct-answer-format">
<h3>Correct answer format<a class="headerlink" href="#correct-answer-format" title="Permalink to this headline"></a></h3>
<p>(NOTE: For specifying answers for targets on draggables please see next section.)</p>
<p>There are two correct answer formats: short and long
If short from correct answer is mapping of &#8216;draggable_id&#8217; to &#8216;target_id&#8217;:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">correct_answer</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;grass&#39;</span><span class="p">:</span> <span class="p">[[</span><span class="mi">300</span><span class="p">,</span> <span class="mi">200</span><span class="p">],</span> <span class="mi">200</span><span class="p">],</span> <span class="s">&#39;ant&#39;</span><span class="p">:</span> <span class="p">[[</span><span class="mi">500</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="mi">200</span><span class="p">]}</span>
<span class="n">correct_answer</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;name4&#39;</span><span class="p">:</span> <span class="s">&#39;t1&#39;</span><span class="p">,</span> <span class="s">&#39;7&#39;</span><span class="p">:</span> <span class="s">&#39;t2&#39;</span><span class="p">}</span>
</pre></div>
</div>
<p>In long form correct answer is list of dicts. Every dict has 3 keys:
draggables, targets and rule. For example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">correct_answer</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;7&#39;</span><span class="p">,</span> <span class="s">&#39;8&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;t5_c&#39;</span><span class="p">,</span> <span class="s">&#39;t6_c&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;anyof&#39;</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;1&#39;</span><span class="p">,</span> <span class="s">&#39;2&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;t2_h&#39;</span><span class="p">,</span> <span class="s">&#39;t3_h&#39;</span><span class="p">,</span> <span class="s">&#39;t4_h&#39;</span><span class="p">,</span> <span class="s">&#39;t7_h&#39;</span><span class="p">,</span> <span class="s">&#39;t8_h&#39;</span><span class="p">,</span> <span class="s">&#39;t10_h&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;anyof&#39;</span>
<span class="p">}]</span>
</pre></div>
</div>
<p>Draggables is list of draggables id. Target is list of targets id, draggables
must be dragged to with considering rule. Rule is string.</p>
<p>Draggables in dicts inside correct_answer list must not intersect!!!</p>
<p>Wrong (for draggable id 7):</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">correct_answer</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;7&#39;</span><span class="p">,</span> <span class="s">&#39;8&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;t5_c&#39;</span><span class="p">,</span> <span class="s">&#39;t6_c&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;anyof&#39;</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;7&#39;</span><span class="p">,</span> <span class="s">&#39;2&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;t2_h&#39;</span><span class="p">,</span> <span class="s">&#39;t3_h&#39;</span><span class="p">,</span> <span class="s">&#39;t4_h&#39;</span><span class="p">,</span> <span class="s">&#39;t7_h&#39;</span><span class="p">,</span> <span class="s">&#39;t8_h&#39;</span><span class="p">,</span> <span class="s">&#39;t10_h&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;anyof&#39;</span>
<span class="p">}]</span>
</pre></div>
</div>
<p>Rules are: exact, anyof, unordered_equal, anyof+number, unordered_equal+number</p>
<ul>
<li><p class="first">Exact rule means that targets for draggable id&#8217;s in user_answer are the same that targets from correct answer. For example, for draggables 7 and 8 user must drag 7 to target1 and 8 to target2 if correct_answer is:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">correct_answer</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;7&#39;</span><span class="p">,</span> <span class="s">&#39;8&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;tartget1&#39;</span><span class="p">,</span> <span class="s">&#39;target2&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;exact&#39;</span>
<span class="p">}]</span>
</pre></div>
</div>
</li>
<li><p class="first">unordered_equal rule allows draggables be dragged to targets unordered. If one want to allow for student to drag 7 to target1 or target2 and 8 to target2 or target 1 and 7 and 8 must be in different targets, then correct answer must be:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">correct_answer</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;7&#39;</span><span class="p">,</span> <span class="s">&#39;8&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;tartget1&#39;</span><span class="p">,</span> <span class="s">&#39;target2&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;unordered_equal&#39;</span>
<span class="p">}]</span>
</pre></div>
</div>
</li>
<li><p class="first">Anyof rule allows draggables to be dragged to any of targets. If one want to allow for student to drag 7 and 8 to target1 or target2, which means that if 7 is on target1 and 8 is on target1 or 7 on target2 and 8 on target2 or 7 on target1 and 8 on target2. Any of theese are correct which anyof rule:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">correct_answer</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;7&#39;</span><span class="p">,</span> <span class="s">&#39;8&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;tartget1&#39;</span><span class="p">,</span> <span class="s">&#39;target2&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;anyof&#39;</span>
<span class="p">}]</span>
</pre></div>
</div>
</li>
<li><p class="first">If you have can_reuse true, then you, for example, have draggables a,b,c and 10 targets. These will allow you to drag 4 &#8216;a&#8217; draggables to [&#8216;target1&#8217;, &#8216;target4&#8217;, &#8216;target7&#8217;, &#8216;target10&#8217;] , you do not need to write &#8216;a&#8217; four times. Also this will allow you to drag &#8216;b&#8217; draggable to target2 or target5 for target5 and target2 etc..:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">correct_answer</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;a&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;target1&#39;</span><span class="p">,</span> <span class="s">&#39;target4&#39;</span><span class="p">,</span> <span class="s">&#39;target7&#39;</span><span class="p">,</span> <span class="s">&#39;target10&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;unordered_equal&#39;</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;b&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;target2&#39;</span><span class="p">,</span> <span class="s">&#39;target5&#39;</span><span class="p">,</span> <span class="s">&#39;target8&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;anyof&#39;</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;c&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;target3&#39;</span><span class="p">,</span> <span class="s">&#39;target6&#39;</span><span class="p">,</span> <span class="s">&#39;target9&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;unordered_equal&#39;</span>
<span class="p">}]</span>
</pre></div>
</div>
</li>
<li><p class="first">And sometimes you want to allow drag only two &#8216;b&#8217; draggables, in these case you should use &#8216;anyof+number&#8217; of &#8216;unordered_equal+number&#8217; rule:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">correct_answer</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;a&#39;</span><span class="p">,</span> <span class="s">&#39;a&#39;</span><span class="p">,</span> <span class="s">&#39;a&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;target1&#39;</span><span class="p">,</span> <span class="s">&#39;target4&#39;</span><span class="p">,</span> <span class="s">&#39;target7&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;unordered_equal+numbers&#39;</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;b&#39;</span><span class="p">,</span> <span class="s">&#39;b&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;target2&#39;</span><span class="p">,</span> <span class="s">&#39;target5&#39;</span><span class="p">,</span> <span class="s">&#39;target8&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;anyof+numbers&#39;</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;c&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;target3&#39;</span><span class="p">,</span> <span class="s">&#39;target6&#39;</span><span class="p">,</span> <span class="s">&#39;target9&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;unordered_equal&#39;</span>
<span class="p">}]</span>
</pre></div>
</div>
</li>
</ul>
<p>In case if we have no multiple draggables per targets (one_per_target=&#8221;true&#8221;),
for same number of draggables, anyof is equal to unordered_equal</p>
<p>If we have can_reuse=true, than one must use only long form of correct answer.</p>
</div>
<div class="section" id="answer-format-for-targets-on-draggables">
<h3>Answer format for targets on draggables<a class="headerlink" href="#answer-format-for-targets-on-draggables" title="Permalink to this headline"></a></h3>
<p>As with the cases described above, an answer must provide precise positioning for
each draggable (on which targets it must reside). In the case when a draggable must
be placed on a target that itself is on a draggable, then the answer must contain
the chain of target-draggable-target. It is best to understand this on an example.</p>
<p>Suppose we have three draggables - &#8216;up&#8217;, &#8216;s&#8217;, and &#8216;p&#8217;. Draggables &#8216;s&#8217;, and &#8216;p&#8217; have targets
on themselves. More specifically, &#8216;p&#8217; has three targets - &#8216;1&#8217;, &#8216;2&#8217;, and &#8216;3&#8217;. The first
requirement is that &#8216;s&#8217;, and &#8216;p&#8217; are positioned on specific targets on the base image.
The second requirement is that draggable &#8216;up&#8217; is positioned on specific targets of
draggable &#8216;p&#8217;. Below is an excerpt from a problem.:</p>
<div class="highlight-python"><pre>&lt;draggable id="up" icon="/static/images/images_list/lcao-mo/up.png" can_reuse="true" /&gt;
&lt;draggable id="s" icon="/static/images/images_list/lcao-mo/orbital_single.png" label="s orbital" can_reuse="true" &gt;
&lt;target id="1" x="0" y="0" w="32" h="32"/&gt;
&lt;/draggable&gt;
&lt;draggable id="p" icon="/static/images/images_list/lcao-mo/orbital_triple.png" can_reuse="true" label="p orbital" &gt;
&lt;target id="1" x="0" y="0" w="32" h="32"/&gt;
&lt;target id="2" x="34" y="0" w="32" h="32"/&gt;
&lt;target id="3" x="68" y="0" w="32" h="32"/&gt;
&lt;/draggable&gt;
...
correct_answer = [
{
'draggables': ['p'],
'targets': ['p-left-target', 'p-right-target'],
'rule': 'unordered_equal'
},
{
'draggables': ['s'],
'targets': ['s-left-target', 's-right-target'],
'rule': 'unordered_equal'
},
{
'draggables': ['up'],
'targets': ['p-left-target[p][1]', 'p-left-target[p][2]', 'p-right-target[p][2]', 'p-right-target[p][3]',],
'rule': 'unordered_equal'
}
]</pre>
</div>
<p>Note that it is a requirement to specify rules for all draggables, even if some draggable gets included
in more than one chain.</p>
</div>
<div class="section" id="grading-logic">
<h3>Grading logic<a class="headerlink" href="#grading-logic" title="Permalink to this headline"></a></h3>
<ol class="arabic">
<li><p class="first">User answer (that comes from browser) and correct answer (from xml) are parsed to the same format:</p>
<div class="highlight-python"><pre>group_id: group_draggables, group_targets, group_rule</pre>
</div>
</li>
</ol>
<p>Group_id is ordinal number, for every dict in correct answer incremental
group_id is assigned: 0, 1, 2, ...</p>
<p>Draggables from user answer are added to same group_id where identical draggables
from correct answer are, for example:</p>
<div class="highlight-python"><pre>If correct_draggables[group_0] = [t1, t2] then
user_draggables[group_0] are all draggables t1 and t2 from user answer:
[t1] or [t1, t2] or [t1, t2, t2] etc..</pre>
</div>
<p>2. For every group from user answer, for that group draggables, if &#8216;number&#8217; is in group rule, set() is applied,
if &#8216;number&#8217; is not in rule, set is not applied:</p>
<div class="highlight-python"><pre>set() : [t1, t2, t3, t3] -&gt; [t1, t2, ,t3]</pre>
</div>
<p>For every group, at this step, draggables lists are equal.</p>
<ol class="arabic simple" start="3">
<li>For every group, lists of targets are compared using rule for that group.</li>
</ol>
<div class="section" id="set-and-number-cases">
<h4>Set and &#8216;+number&#8217; cases<a class="headerlink" href="#set-and-number-cases" title="Permalink to this headline"></a></h4>
<p>Set() and &#8216;+number&#8217; are needed only for case of reusable draggables,
for other cases there are no equal draggables in list, so set() does nothing.</p>
<ul>
<li><p class="first">Usage of set() operation allows easily create rule for case of &#8220;any number of same draggable can be dragged to some targets&#8221;:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;draggable_1&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;target3&#39;</span><span class="p">,</span> <span class="s">&#39;target6&#39;</span><span class="p">,</span> <span class="s">&#39;target9&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;anyof&#39;</span>
<span class="p">}</span>
</pre></div>
</div>
</li>
<li><p class="first">&#8216;number&#8217; rule is used for the case of reusable draggables, when one want to fix number of draggable to drag. In this example only two instances of draggables_1 are allowed to be dragged:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="p">{</span>
<span class="s">&#39;draggables&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;draggable_1&#39;</span><span class="p">,</span> <span class="s">&#39;draggable_1&#39;</span><span class="p">],</span>
<span class="s">&#39;targets&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&#39;target3&#39;</span><span class="p">,</span> <span class="s">&#39;target6&#39;</span><span class="p">,</span> <span class="s">&#39;target9&#39;</span><span class="p">],</span>
<span class="s">&#39;rule&#39;</span><span class="p">:</span> <span class="s">&#39;anyof+number&#39;</span>
<span class="p">}</span>
</pre></div>
</div>
</li>
<li><p class="first">Note, that in using rule &#8216;exact&#8217;, one does not need &#8216;number&#8217;, because you can&#8217;t recognize from user interface which reusable draggable is on which target. Absurd example:</p>
<div class="highlight-python"><pre>{
'draggables': ['draggable_1', 'draggable_1', 'draggable_2'],
'targets': ['target3', 'target6', 'target9'],
'rule': 'exact'
}
Correct handling of this example is to create different rules for draggable_1 and
draggable_2</pre>
</div>
</li>
<li><p class="first">For &#8216;unordered_equal&#8217; (or &#8216;exact&#8217; too) we don&#8217;t need &#8216;number&#8217; if you have only same draggable in group, as targets length will provide constraint for the number of draggables:</p>
<div class="highlight-python"><pre>{
'draggables': ['draggable_1'],
'targets': ['target3', 'target6', 'target9'],
'rule': 'unordered_equal'
}
This means that only three draggaggables 'draggable_1' can be dragged.</pre>
</div>
</li>
<li><p class="first">But if you have more that one different reusable draggable in list, you may use &#8216;number&#8217; rule:</p>
<div class="highlight-python"><pre>{
'draggables': ['draggable_1', 'draggable_1', 'draggable_2'],
'targets': ['target3', 'target6', 'target9'],
'rule': 'unordered_equal+number'
}
If not use number, draggables list will be setted to ['draggable_1', 'draggable_2']</pre>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="logic-flow">
<h3>Logic flow<a class="headerlink" href="#logic-flow" title="Permalink to this headline"></a></h3>
<p>(Click on image to see full size version.)</p>
<a class="reference external image-reference" href="_images/draganddrop_logic_flow.png"><img alt="../../_images/draganddrop_logic_flow.png" src="../../_images/draganddrop_logic_flow.png" style="width: 100%;" /></a>
</div>
</div>
<div class="section" id="example">
<h2>Example<a class="headerlink" href="#example" title="Permalink to this headline"></a></h2>
<div class="section" id="examples-of-draggables-that-can-t-be-reused">
<h3>Examples of draggables that can&#8217;t be reused<a class="headerlink" href="#examples-of-draggables-that-can-t-be-reused" title="Permalink to this headline"></a></h3>
<div class="highlight-python"><pre>&lt;problem display_name="Drag and drop demos: drag and drop icons or labels
to proper positions." &gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Anyof rule example]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Please label hydrogen atoms connected with left carbon atom.&lt;/h4&gt;
&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/images_list/ethglycol.jpg" target_outline="true"
one_per_target="true" no_labels="true" label_bg_color="rgb(222, 139, 238)"&gt;
&lt;draggable id="1" label="Hydrogen" /&gt;
&lt;draggable id="2" label="Hydrogen" /&gt;
&lt;target id="t1_o" x="10" y="67" w="100" h="100"/&gt;
&lt;target id="t2" x="133" y="3" w="70" h="70"/&gt;
&lt;target id="t3" x="2" y="384" w="70" h="70"/&gt;
&lt;target id="t4" x="95" y="386" w="70" h="70"/&gt;
&lt;target id="t5_c" x="94" y="293" w="91" h="91"/&gt;
&lt;target id="t6_c" x="328" y="294" w="91" h="91"/&gt;
&lt;target id="t7" x="393" y="463" w="70" h="70"/&gt;
&lt;target id="t8" x="344" y="214" w="70" h="70"/&gt;
&lt;target id="t9_o" x="445" y="162" w="100" h="100"/&gt;
&lt;target id="t10" x="591" y="132" w="70" h="70"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [
{'draggables': ['1', '2'],
'targets': ['t2', 't3', 't4' ],
'rule':'anyof'
}]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Complex grading example]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Describe carbon molecule in LCAO-MO.&lt;/h4&gt;
&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/images_list/lcao-mo/lcao-mo.jpg" target_outline="true" &gt;
&lt;!-- filled bond --&gt;
&lt;draggable id="1" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="2" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="3" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="4" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="5" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="6" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;!-- up bond --&gt;
&lt;draggable id="7" icon="/static/images/images_list/lcao-mo/up.png"/&gt;
&lt;draggable id="8" icon="/static/images/images_list/lcao-mo/up.png"/&gt;
&lt;draggable id="9" icon="/static/images/images_list/lcao-mo/up.png"/&gt;
&lt;draggable id="10" icon="/static/images/images_list/lcao-mo/up.png"/&gt;
&lt;!-- sigma --&gt;
&lt;draggable id="11" icon="/static/images/images_list/lcao-mo/sigma.png"/&gt;
&lt;draggable id="12" icon="/static/images/images_list/lcao-mo/sigma.png"/&gt;
&lt;!-- sigma* --&gt;
&lt;draggable id="13" icon="/static/images/images_list/lcao-mo/sigma_s.png"/&gt;
&lt;draggable id="14" icon="/static/images/images_list/lcao-mo/sigma_s.png"/&gt;
&lt;!-- pi --&gt;
&lt;draggable id="15" icon="/static/images/images_list/lcao-mo/pi.png" /&gt;
&lt;!-- pi* --&gt;
&lt;draggable id="16" icon="/static/images/images_list/lcao-mo/pi_s.png" /&gt;
&lt;!-- images that should not be dragged --&gt;
&lt;draggable id="17" icon="/static/images/images_list/lcao-mo/d.png" /&gt;
&lt;draggable id="18" icon="/static/images/images_list/lcao-mo/d.png" /&gt;
&lt;!-- positions of electrons and electron pairs --&gt;
&lt;target id="s_left" x="130" y="360" w="32" h="32"/&gt;
&lt;target id="s_right" x="505" y="360" w="32" h="32"/&gt;
&lt;target id="s_sigma" x="320" y="425" w="32" h="32"/&gt;
&lt;target id="s_sigma_star" x="320" y="290" w="32" h="32"/&gt;
&lt;target id="p_left_1" x="80" y="100" w="32" h="32"/&gt;
&lt;target id="p_left_2" x="125" y="100" w="32" h="32"/&gt;
&lt;target id="p_left_3" x="175" y="100" w="32" h="32"/&gt;
&lt;target id="p_right_1" x="465" y="100" w="32" h="32"/&gt;
&lt;target id="p_right_2" x="515" y="100" w="32" h="32"/&gt;
&lt;target id="p_right_3" x="560" y="100" w="32" h="32"/&gt;
&lt;target id="p_pi_1" x="290" y="220" w="32" h="32"/&gt;
&lt;target id="p_pi_2" x="335" y="220" w="32" h="32"/&gt;
&lt;target id="p_sigma" x="315" y="170" w="32" h="32"/&gt;
&lt;target id="p_pi_star_1" x="290" y="40" w="32" h="32"/&gt;
&lt;target id="p_pi_star_2" x="340" y="40" w="32" h="32"/&gt;
&lt;target id="p_sigma_star" x="315" y="0" w="32" h="32"/&gt;
&lt;!-- positions of names of energy levels --&gt;
&lt;target id="s_sigma_name" x="400" y="425" w="32" h="32"/&gt;
&lt;target id="s_sigma_star_name" x="400" y="290" w="32" h="32"/&gt;
&lt;target id="p_pi_name" x="400" y="220" w="32" h="32"/&gt;
&lt;target id="p_sigma_name" x="400" y="170" w="32" h="32"/&gt;
&lt;target id="p_pi_star_name" x="400" y="40" w="32" h="32"/&gt;
&lt;target id="p_sigma_star_name" x="400" y="0" w="32" h="32"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [
{
'draggables': ['1', '2', '3', '4', '5', '6'],
'targets': [
's_left', 's_right', 's_sigma', 's_sigma_star', 'p_pi_1', 'p_pi_2'
],
'rule': 'unordered_equal'
}, {
'draggables': ['7','8', '9', '10'],
'targets': ['p_left_1', 'p_left_2', 'p_right_1','p_right_2'],
'rule': 'unordered_equal'
}, {
'draggables': ['11', '12'],
'targets': ['s_sigma_name', 'p_sigma_name'],
'rule': 'unordered_equal'
}, {
'draggables': ['13', '14'],
'targets': ['s_sigma_star_name', 'p_sigma_star_name'],
'rule': 'unordered_equal'
}, {
'draggables': ['15'],
'targets': ['p_pi_name'],
'rule': 'unordered_equal'
}, {
'draggables': ['16'],
'targets': ['p_pi_star_name'],
'rule': 'unordered_equal'
}]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Another complex grading example]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Describe oxygen molecule in LCAO-MO&lt;/h4&gt;
&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/images_list/lcao-mo/lcao-mo.jpg" target_outline="true" one_per_target="true"&gt;
&lt;!-- filled bond --&gt;
&lt;draggable id="1" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="2" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="3" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="4" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="5" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="6" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="v_fb_1" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="v_fb_2" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;draggable id="v_fb_3" icon="/static/images/images_list/lcao-mo/u_d.png" /&gt;
&lt;!-- up bond --&gt;
&lt;draggable id="7" icon="/static/images/images_list/lcao-mo/up.png"/&gt;
&lt;draggable id="8" icon="/static/images/images_list/lcao-mo/up.png"/&gt;
&lt;draggable id="9" icon="/static/images/images_list/lcao-mo/up.png"/&gt;
&lt;draggable id="10" icon="/static/images/images_list/lcao-mo/up.png"/&gt;
&lt;draggable id="v_ub_1" icon="/static/images/images_list/lcao-mo/up.png"/&gt;
&lt;draggable id="v_ub_2" icon="/static/images/images_list/lcao-mo/up.png"/&gt;
&lt;!-- sigma --&gt;
&lt;draggable id="11" icon="/static/images/images_list/lcao-mo/sigma.png"/&gt;
&lt;draggable id="12" icon="/static/images/images_list/lcao-mo/sigma.png"/&gt;
&lt;!-- sigma* --&gt;
&lt;draggable id="13" icon="/static/images/images_list/lcao-mo/sigma_s.png"/&gt;
&lt;draggable id="14" icon="/static/images/images_list/lcao-mo/sigma_s.png"/&gt;
&lt;!-- pi --&gt;
&lt;draggable id="15" icon="/static/images/images_list/lcao-mo/pi.png" /&gt;
&lt;!-- pi* --&gt;
&lt;draggable id="16" icon="/static/images/images_list/lcao-mo/pi_s.png" /&gt;
&lt;!-- images that should not be dragged --&gt;
&lt;draggable id="17" icon="/static/images/images_list/lcao-mo/d.png" /&gt;
&lt;draggable id="18" icon="/static/images/images_list/lcao-mo/d.png" /&gt;
&lt;!-- positions of electrons and electron pairs --&gt;
&lt;target id="s_left" x="130" y="360" w="32" h="32"/&gt;
&lt;target id="s_right" x="505" y="360" w="32" h="32"/&gt;
&lt;target id="s_sigma" x="320" y="425" w="32" h="32"/&gt;
&lt;target id="s_sigma_star" x="320" y="290" w="32" h="32"/&gt;
&lt;target id="p_left_1" x="80" y="100" w="32" h="32"/&gt;
&lt;target id="p_left_2" x="125" y="100" w="32" h="32"/&gt;
&lt;target id="p_left_3" x="175" y="100" w="32" h="32"/&gt;
&lt;target id="p_right_1" x="465" y="100" w="32" h="32"/&gt;
&lt;target id="p_right_2" x="515" y="100" w="32" h="32"/&gt;
&lt;target id="p_right_3" x="560" y="100" w="32" h="32"/&gt;
&lt;target id="p_pi_1" x="290" y="220" w="32" h="32"/&gt;
&lt;target id="p_pi_2" x="335" y="220" w="32" h="32"/&gt;
&lt;target id="p_sigma" x="315" y="170" w="32" h="32"/&gt;
&lt;target id="p_pi_star_1" x="290" y="40" w="32" h="32"/&gt;
&lt;target id="p_pi_star_2" x="340" y="40" w="32" h="32"/&gt;
&lt;target id="p_sigma_star" x="315" y="0" w="32" h="32"/&gt;
&lt;!-- positions of names of energy levels --&gt;
&lt;target id="s_sigma_name" x="400" y="425" w="32" h="32"/&gt;
&lt;target id="s_sigma_star_name" x="400" y="290" w="32" h="32"/&gt;
&lt;target id="p_pi_name" x="400" y="220" w="32" h="32"/&gt;
&lt;target id="p_pi_star_name" x="400" y="40" w="32" h="32"/&gt;
&lt;target id="p_sigma_name" x="400" y="170" w="32" h="32"/&gt;
&lt;target id="p_sigma_star_name" x="400" y="0" w="32" h="32"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [{
'draggables': ['1', '2', '3', '4', '5', '6', 'v_fb_1', 'v_fb_2', 'v_fb_3'],
'targets': [
's_left', 's_right', 's_sigma', 's_sigma_star', 'p_pi_1', 'p_pi_2',
'p_sigma', 'p_left_1', 'p_right_3'
],
'rule': 'anyof'
}, {
'draggables': ['7', '8', '9', '10', 'v_ub_1', 'v_ub_2'],
'targets': [
'p_left_2', 'p_left_3', 'p_right_1', 'p_right_2', 'p_pi_star_1',
'p_pi_star_2'
],
'rule': 'anyof'
}, {
'draggables': ['11', '12'],
'targets': ['s_sigma_name', 'p_sigma_name'],
'rule': 'anyof'
}, {
'draggables': ['13', '14'],
'targets': ['s_sigma_star_name', 'p_sigma_star_name'],
'rule': 'anyof'
}, {
'draggables': ['15'],
'targets': ['p_pi_name'],
'rule': 'anyof'
}, {
'draggables': ['16'],
'targets': ['p_pi_star_name'],
'rule': 'anyof'
}]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Individual targets with outlines, One draggable per target]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;
Drag -Ant- to first position and -Star- to third position &lt;/h4&gt;&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/cow.png" target_outline="true"&gt;
&lt;draggable id="1" label="Label 1"/&gt;
&lt;draggable id="name_with_icon" label="Ant" icon="/static/images/images_list/ant.jpg"/&gt;
&lt;draggable id="with_icon" label="Cloud" icon="/static/images/images_list/cloud.jpg" /&gt;
&lt;draggable id="5" label="Label2" /&gt;
&lt;draggable id="2" label="Drop" icon="/static/images/images_list/drop.jpg" /&gt;
&lt;draggable id="name_label_icon3" label="Grass" icon="/static/images/images_list/grass.jpg" /&gt;
&lt;draggable id="name4" label="Star" icon="/static/images/images_list/star.png" /&gt;
&lt;draggable id="7" label="Label3" /&gt;
&lt;target id="t1" x="20" y="20" w="90" h="90"/&gt;
&lt;target id="t2" x="300" y="100" w="90" h="90"/&gt;
&lt;target id="t3" x="150" y="40" w="50" h="50"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = {'name_with_icon': 't1', 'name4': 't2'}
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[SMALL IMAGE, Individual targets WITHOUT outlines, One draggable
per target]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;
Move -Star- to the volcano opening, and -Label3- on to
the right ear of the cow.
&lt;/h4&gt;&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/cow3.png" target_outline="false"&gt;
&lt;draggable id="1" label="Label 1"/&gt;
&lt;draggable id="name_with_icon" label="Ant" icon="/static/images/images_list/ant.jpg"/&gt;
&lt;draggable id="with_icon" label="Cloud" icon="/static/images/images_list/cloud.jpg" /&gt;
&lt;draggable id="5" label="Label2" /&gt;
&lt;draggable id="2" label="Drop" icon="/static/images/images_list/drop.jpg" /&gt;
&lt;draggable id="name_label_icon3" label="Grass" icon="/static/images/images_list/grass.jpg" /&gt;
&lt;draggable id="name4" label="Star" icon="/static/images/images_list/star.png" /&gt;
&lt;draggable id="7" label="Label3" /&gt;
&lt;target id="t1" x="111" y="58" w="90" h="90"/&gt;
&lt;target id="t2" x="212" y="90" w="90" h="90"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = {'name4': 't1',
'7': 't2'}
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Many draggables per target]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Move -Star- and -Ant- to most left target
and -Label3- and -Label2- to most right target.&lt;/h4&gt;&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/cow.png" target_outline="true" one_per_target="false"&gt;
&lt;draggable id="1" label="Label 1"/&gt;
&lt;draggable id="name_with_icon" label="Ant" icon="/static/images/images_list/ant.jpg"/&gt;
&lt;draggable id="with_icon" label="Cloud" icon="/static/images/images_list/cloud.jpg" /&gt;
&lt;draggable id="5" label="Label2" /&gt;
&lt;draggable id="2" label="Drop" icon="/static/images/images_list/drop.jpg" /&gt;
&lt;draggable id="name_label_icon3" label="Grass" icon="/static/images/images_list/grass.jpg" /&gt;
&lt;draggable id="name4" label="Star" icon="/static/images/images_list/star.png" /&gt;
&lt;draggable id="7" label="Label3" /&gt;
&lt;target id="t1" x="20" y="20" w="90" h="90"/&gt;
&lt;target id="t2" x="300" y="100" w="90" h="90"/&gt;
&lt;target id="t3" x="150" y="40" w="50" h="50"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = {'name4': 't1',
'name_with_icon': 't1',
'5': 't2',
'7':'t2'}
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Draggables can be placed anywhere on base image]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;
Place -Grass- in the middle of the image and -Ant- in the
right upper corner.&lt;/h4&gt;&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/cow.png" &gt;
&lt;draggable id="1" label="Label 1"/&gt;
&lt;draggable id="ant" label="Ant" icon="/static/images/images_list/ant.jpg"/&gt;
&lt;draggable id="with_icon" label="Cloud" icon="/static/images/images_list/cloud.jpg" /&gt;
&lt;draggable id="5" label="Label2" /&gt;
&lt;draggable id="2" label="Drop" icon="/static/images/images_list/drop.jpg" /&gt;
&lt;draggable id="grass" label="Grass" icon="/static/images/images_list/grass.jpg" /&gt;
&lt;draggable id="name4" label="Star" icon="/static/images/images_list/star.png" /&gt;
&lt;draggable id="7" label="Label3" /&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = {'grass': [[300, 200], 200],
'ant': [[500, 0], 200]}
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Another anyof example]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Please identify the Carbon and Oxygen atoms in the molecule.&lt;/h4&gt;&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/images_list/ethglycol.jpg" target_outline="true" one_per_target="true"&gt;
&lt;draggable id="l1_c" label="Carbon" /&gt;
&lt;draggable id="l2" label="Methane"/&gt;
&lt;draggable id="l3_o" label="Oxygen" /&gt;
&lt;draggable id="l4" label="Calcium" /&gt;
&lt;draggable id="l5" label="Methane"/&gt;
&lt;draggable id="l6" label="Calcium" /&gt;
&lt;draggable id="l7" label="Hydrogen" /&gt;
&lt;draggable id="l8_c" label="Carbon" /&gt;
&lt;draggable id="l9" label="Hydrogen" /&gt;
&lt;draggable id="l10_o" label="Oxygen" /&gt;
&lt;target id="t1_o" x="10" y="67" w="100" h="100"/&gt;
&lt;target id="t2" x="133" y="3" w="70" h="70"/&gt;
&lt;target id="t3" x="2" y="384" w="70" h="70"/&gt;
&lt;target id="t4" x="95" y="386" w="70" h="70"/&gt;
&lt;target id="t5_c" x="94" y="293" w="91" h="91"/&gt;
&lt;target id="t6_c" x="328" y="294" w="91" h="91"/&gt;
&lt;target id="t7" x="393" y="463" w="70" h="70"/&gt;
&lt;target id="t8" x="344" y="214" w="70" h="70"/&gt;
&lt;target id="t9_o" x="445" y="162" w="100" h="100"/&gt;
&lt;target id="t10" x="591" y="132" w="70" h="70"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [
{
'draggables': ['l3_o', 'l10_o'],
'targets': ['t1_o', 't9_o'],
'rule': 'anyof'
},
{
'draggables': ['l1_c','l8_c'],
'targets': ['t5_c','t6_c'],
'rule': 'anyof'
}
]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Again another anyof example]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;If the element appears in this molecule, drag the label onto it&lt;/h4&gt;
&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/images_list/ethglycol.jpg" target_outline="true"
one_per_target="true" no_labels="true" label_bg_color="rgb(222, 139, 238)"&gt;
&lt;draggable id="1" label="Hydrogen" /&gt;
&lt;draggable id="2" label="Hydrogen" /&gt;
&lt;draggable id="3" label="Nytrogen" /&gt;
&lt;draggable id="4" label="Nytrogen" /&gt;
&lt;draggable id="5" label="Boron" /&gt;
&lt;draggable id="6" label="Boron" /&gt;
&lt;draggable id="7" label="Carbon" /&gt;
&lt;draggable id="8" label="Carbon" /&gt;
&lt;target id="t1_o" x="10" y="67" w="100" h="100"/&gt;
&lt;target id="t2_h" x="133" y="3" w="70" h="70"/&gt;
&lt;target id="t3_h" x="2" y="384" w="70" h="70"/&gt;
&lt;target id="t4_h" x="95" y="386" w="70" h="70"/&gt;
&lt;target id="t5_c" x="94" y="293" w="91" h="91"/&gt;
&lt;target id="t6_c" x="328" y="294" w="91" h="91"/&gt;
&lt;target id="t7_h" x="393" y="463" w="70" h="70"/&gt;
&lt;target id="t8_h" x="344" y="214" w="70" h="70"/&gt;
&lt;target id="t9_o" x="445" y="162" w="100" h="100"/&gt;
&lt;target id="t10_h" x="591" y="132" w="70" h="70"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [
{
'draggables': ['7', '8'],
'targets': ['t5_c', 't6_c'],
'rule': 'anyof'
},
{
'draggables': ['1', '2'],
'targets': ['t2_h', 't3_h', 't4_h', 't7_h', 't8_h', 't10_h'],
'rule': 'anyof'
}]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Wrong base image url example]
&lt;/h4&gt;&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/cow3_bad.png" target_outline="false"&gt;
&lt;draggable id="1" label="Label 1"/&gt;
&lt;draggable id="name_with_icon" label="Ant" icon="/static/images/images_list/ant.jpg"/&gt;
&lt;draggable id="with_icon" label="Cloud" icon="/static/images/images_list/cloud.jpg" /&gt;
&lt;draggable id="5" label="Label2" /&gt;
&lt;draggable id="2" label="Drop" icon="/static/images/images_list/drop.jpg" /&gt;
&lt;draggable id="name_label_icon3" label="Grass" icon="/static/images/images_list/grass.jpg" /&gt;
&lt;draggable id="name4" label="Star" icon="/static/images/images_list/star.png" /&gt;
&lt;draggable id="7" label="Label3" /&gt;
&lt;target id="t1" x="111" y="58" w="90" h="90"/&gt;
&lt;target id="t2" x="212" y="90" w="90" h="90"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = {'name4': 't1',
'7': 't2'}
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;/problem&gt;
</pre>
</div>
</div>
<div class="section" id="draggables-can-be-reused">
<h3>Draggables can be reused<a class="headerlink" href="#draggables-can-be-reused" title="Permalink to this headline"></a></h3>
<div class="highlight-python"><pre>&lt;problem display_name="Drag and drop demos: drag and drop icons or labels
to proper positions." &gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Draggable is reusable example]&lt;/h4&gt;
&lt;br/&gt;
&lt;h4&gt;Please label all hydrogen atoms.&lt;/h4&gt;
&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input
img="/static/images/images_list/ethglycol.jpg"
target_outline="true"
one_per_target="true"
no_labels="true"
label_bg_color="rgb(222, 139, 238)"
&gt;
&lt;draggable id="1" label="Hydrogen" can_reuse='true' /&gt;
&lt;target id="t1_o" x="10" y="67" w="100" h="100" /&gt;
&lt;target id="t2" x="133" y="3" w="70" h="70" /&gt;
&lt;target id="t3" x="2" y="384" w="70" h="70" /&gt;
&lt;target id="t4" x="95" y="386" w="70" h="70" /&gt;
&lt;target id="t5_c" x="94" y="293" w="91" h="91" /&gt;
&lt;target id="t6_c" x="328" y="294" w="91" h="91" /&gt;
&lt;target id="t7" x="393" y="463" w="70" h="70" /&gt;
&lt;target id="t8" x="344" y="214" w="70" h="70" /&gt;
&lt;target id="t9_o" x="445" y="162" w="100" h="100" /&gt;
&lt;target id="t10" x="591" y="132" w="70" h="70" /&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;
&lt;![CDATA[
correct_answer = [{
'draggables': ['1'],
'targets': ['t2', 't3', 't4', 't7', 't8', 't10'],
'rule': 'exact'
}]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;
&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Complex grading example]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Describe carbon molecule in LCAO-MO.&lt;/h4&gt;
&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/images_list/lcao-mo/lcao-mo.jpg" target_outline="true" &gt;
&lt;!-- filled bond --&gt;
&lt;draggable id="1" icon="/static/images/images_list/lcao-mo/u_d.png" can_reuse="true" /&gt;
&lt;!-- up bond --&gt;
&lt;draggable id="7" icon="/static/images/images_list/lcao-mo/up.png" can_reuse="true" /&gt;
&lt;!-- sigma --&gt;
&lt;draggable id="11" icon="/static/images/images_list/lcao-mo/sigma.png" can_reuse="true" /&gt;
&lt;!-- sigma* --&gt;
&lt;draggable id="13" icon="/static/images/images_list/lcao-mo/sigma_s.png" can_reuse="true" /&gt;
&lt;!-- pi --&gt;
&lt;draggable id="15" icon="/static/images/images_list/lcao-mo/pi.png" can_reuse="true" /&gt;
&lt;!-- pi* --&gt;
&lt;draggable id="16" icon="/static/images/images_list/lcao-mo/pi_s.png" can_reuse="true" /&gt;
&lt;!-- images that should not be dragged --&gt;
&lt;draggable id="17" icon="/static/images/images_list/lcao-mo/d.png" can_reuse="true" /&gt;
&lt;!-- positions of electrons and electron pairs --&gt;
&lt;target id="s_left" x="130" y="360" w="32" h="32"/&gt;
&lt;target id="s_right" x="505" y="360" w="32" h="32"/&gt;
&lt;target id="s_sigma" x="320" y="425" w="32" h="32"/&gt;
&lt;target id="s_sigma_star" x="320" y="290" w="32" h="32"/&gt;
&lt;target id="p_left_1" x="80" y="100" w="32" h="32"/&gt;
&lt;target id="p_left_2" x="125" y="100" w="32" h="32"/&gt;
&lt;target id="p_left_3" x="175" y="100" w="32" h="32"/&gt;
&lt;target id="p_right_1" x="465" y="100" w="32" h="32"/&gt;
&lt;target id="p_right_2" x="515" y="100" w="32" h="32"/&gt;
&lt;target id="p_right_3" x="560" y="100" w="32" h="32"/&gt;
&lt;target id="p_pi_1" x="290" y="220" w="32" h="32"/&gt;
&lt;target id="p_pi_2" x="335" y="220" w="32" h="32"/&gt;
&lt;target id="p_sigma" x="315" y="170" w="32" h="32"/&gt;
&lt;target id="p_pi_star_1" x="290" y="40" w="32" h="32"/&gt;
&lt;target id="p_pi_star_2" x="340" y="40" w="32" h="32"/&gt;
&lt;target id="p_sigma_star" x="315" y="0" w="32" h="32"/&gt;
&lt;!-- positions of names of energy levels --&gt;
&lt;target id="s_sigma_name" x="400" y="425" w="32" h="32"/&gt;
&lt;target id="s_sigma_star_name" x="400" y="290" w="32" h="32"/&gt;
&lt;target id="p_pi_name" x="400" y="220" w="32" h="32"/&gt;
&lt;target id="p_sigma_name" x="400" y="170" w="32" h="32"/&gt;
&lt;target id="p_pi_star_name" x="400" y="40" w="32" h="32"/&gt;
&lt;target id="p_sigma_star_name" x="400" y="0" w="32" h="32"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [
{
'draggables': ['1'],
'targets': [
's_left', 's_right', 's_sigma', 's_sigma_star', 'p_pi_1', 'p_pi_2'
],
'rule': 'exact'
}, {
'draggables': ['7'],
'targets': ['p_left_1', 'p_left_2', 'p_right_1','p_right_2'],
'rule': 'exact'
}, {
'draggables': ['11'],
'targets': ['s_sigma_name', 'p_sigma_name'],
'rule': 'exact'
}, {
'draggables': ['13'],
'targets': ['s_sigma_star_name', 'p_sigma_star_name'],
'rule': 'exact'
}, {
'draggables': ['15'],
'targets': ['p_pi_name'],
'rule': 'exact'
}, {
'draggables': ['16'],
'targets': ['p_pi_star_name'],
'rule': 'exact'
}]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Many draggables per target]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Move two Stars and three Ants to most left target
and one Label3 and four Label2 to most right target.&lt;/h4&gt;&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/cow.png" target_outline="true" one_per_target="false"&gt;
&lt;draggable id="1" label="Label 1" can_reuse="true" /&gt;
&lt;draggable id="name_with_icon" label="Ant" icon="/static/images/images_list/ant.jpg" can_reuse="true" /&gt;
&lt;draggable id="with_icon" label="Cloud" icon="/static/images/images_list/cloud.jpg" can_reuse="true" /&gt;
&lt;draggable id="5" label="Label2" can_reuse="true" /&gt;
&lt;draggable id="2" label="Drop" icon="/static/images/images_list/drop.jpg" can_reuse="true" /&gt;
&lt;draggable id="name_label_icon3" label="Grass" icon="/static/images/images_list/grass.jpg" can_reuse="true" /&gt;
&lt;draggable id="name4" label="Star" icon="/static/images/images_list/star.png" can_reuse="true" /&gt;
&lt;draggable id="7" label="Label3" can_reuse="true" /&gt;
&lt;target id="t1" x="20" y="20" w="90" h="90"/&gt;
&lt;target id="t2" x="300" y="100" w="90" h="90"/&gt;
&lt;target id="t3" x="150" y="40" w="50" h="50"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [
{
'draggables': ['name4'],
'targets': [
't1', 't1'
],
'rule': 'exact'
},
{
'draggables': ['name_with_icon'],
'targets': [
't1', 't1', 't1'
],
'rule': 'exact'
},
{
'draggables': ['5'],
'targets': [
't2', 't2', 't2', 't2'
],
'rule': 'exact'
},
{
'draggables': ['7'],
'targets': [
't2'
],
'rule': 'exact'
}
]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Draggables can be placed anywhere on base image]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;
Place -Grass- in the middle of the image and -Ant- in the
right upper corner.&lt;/h4&gt;&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/cow.png" &gt;
&lt;draggable id="1" label="Label 1" can_reuse="true" /&gt;
&lt;draggable id="ant" label="Ant" icon="/static/images/images_list/ant.jpg" can_reuse="true" /&gt;
&lt;draggable id="with_icon" label="Cloud" icon="/static/images/images_list/cloud.jpg" can_reuse="true" /&gt;
&lt;draggable id="5" label="Label2" can_reuse="true" /&gt;
&lt;draggable id="2" label="Drop" icon="/static/images/images_list/drop.jpg" can_reuse="true" /&gt;
&lt;draggable id="grass" label="Grass" icon="/static/images/images_list/grass.jpg" can_reuse="true" /&gt;
&lt;draggable id="name4" label="Star" icon="/static/images/images_list/star.png" can_reuse="true" /&gt;
&lt;draggable id="7" label="Label3" can_reuse="true" /&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = {
'grass': [[300, 200], 200],
'ant': [[500, 0], 200]
}
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Another anyof example]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Please identify the Carbon and Oxygen atoms in the molecule.&lt;/h4&gt;&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/images_list/ethglycol.jpg" target_outline="true" one_per_target="true"&gt;
&lt;draggable id="l1_c" label="Carbon" can_reuse="true" /&gt;
&lt;draggable id="l2" label="Methane" can_reuse="true" /&gt;
&lt;draggable id="l3_o" label="Oxygen" can_reuse="true" /&gt;
&lt;draggable id="l4" label="Calcium" can_reuse="true" /&gt;
&lt;draggable id="l7" label="Hydrogen" can_reuse="true" /&gt;
&lt;target id="t1_o" x="10" y="67" w="100" h="100"/&gt;
&lt;target id="t2" x="133" y="3" w="70" h="70"/&gt;
&lt;target id="t3" x="2" y="384" w="70" h="70"/&gt;
&lt;target id="t4" x="95" y="386" w="70" h="70"/&gt;
&lt;target id="t5_c" x="94" y="293" w="91" h="91"/&gt;
&lt;target id="t6_c" x="328" y="294" w="91" h="91"/&gt;
&lt;target id="t7" x="393" y="463" w="70" h="70"/&gt;
&lt;target id="t8" x="344" y="214" w="70" h="70"/&gt;
&lt;target id="t9_o" x="445" y="162" w="100" h="100"/&gt;
&lt;target id="t10" x="591" y="132" w="70" h="70"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [
{
'draggables': ['l3_o'],
'targets': ['t1_o', 't9_o'],
'rule': 'exact'
},
{
'draggables': ['l1_c'],
'targets': ['t5_c', 't6_c'],
'rule': 'exact'
}
]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Exact number of draggables for a set of targets.]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Drag two Grass and one Star to first or second positions, and three Cloud to any of the three positions.&lt;/h4&gt;
&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/cow.png" target_outline="true" one_per_target="false"&gt;
&lt;draggable id="1" label="Label 1" can_reuse="true" /&gt;
&lt;draggable id="name_with_icon" label="Ant" icon="/static/images/images_list/ant.jpg" can_reuse="true" /&gt;
&lt;draggable id="with_icon" label="Cloud" icon="/static/images/images_list/cloud.jpg" can_reuse="true" /&gt;
&lt;draggable id="5" label="Label2" can_reuse="true" /&gt;
&lt;draggable id="2" label="Drop" icon="/static/images/images_list/drop.jpg" can_reuse="true" /&gt;
&lt;draggable id="name_label_icon3" label="Grass" icon="/static/images/images_list/grass.jpg" can_reuse="true" /&gt;
&lt;draggable id="name4" label="Star" icon="/static/images/images_list/star.png" can_reuse="true" /&gt;
&lt;draggable id="7" label="Label3" can_reuse="true" /&gt;
&lt;target id="t1" x="20" y="20" w="90" h="90"/&gt;
&lt;target id="t2" x="300" y="100" w="90" h="90"/&gt;
&lt;target id="t3" x="150" y="40" w="50" h="50"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [
{
'draggables': ['name_label_icon3', 'name_label_icon3'],
'targets': ['t1', 't3'],
'rule': 'unordered_equal+number'
},
{
'draggables': ['name4'],
'targets': ['t1', 't3'],
'rule': 'anyof+number'
},
{
'draggables': ['with_icon', 'with_icon', 'with_icon'],
'targets': ['t1', 't2', 't3'],
'rule': 'anyof+number'
}
]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[As many as you like draggables for a set of targets.]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Drag some Grass to any of the targets, and some Stars to either first or last target.&lt;/h4&gt;
&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/cow.png" target_outline="true" one_per_target="false"&gt;
&lt;draggable id="1" label="Label 1" can_reuse="true" /&gt;
&lt;draggable id="name_with_icon" label="Ant" icon="/static/images/images_list/ant.jpg" can_reuse="true" /&gt;
&lt;draggable id="with_icon" label="Cloud" icon="/static/images/images_list/cloud.jpg" can_reuse="true" /&gt;
&lt;draggable id="5" label="Label2" can_reuse="true" /&gt;
&lt;draggable id="2" label="Drop" icon="/static/images/images_list/drop.jpg" can_reuse="true" /&gt;
&lt;draggable id="name_label_icon3" label="Grass" icon="/static/images/images_list/grass.jpg" can_reuse="true" /&gt;
&lt;draggable id="name4" label="Star" icon="/static/images/images_list/star.png" can_reuse="true" /&gt;
&lt;draggable id="7" label="Label3" can_reuse="true" /&gt;
&lt;target id="t1" x="20" y="20" w="90" h="90"/&gt;
&lt;target id="t2" x="300" y="100" w="90" h="90"/&gt;
&lt;target id="t3" x="150" y="40" w="50" h="50"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [
{
'draggables': ['name_label_icon3'],
'targets': ['t1', 't2', 't3'],
'rule': 'anyof'
},
{
'draggables': ['name4'],
'targets': ['t1', 't2'],
'rule': 'anyof'
}
]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;/problem&gt;
</pre>
</div>
</div>
<div class="section" id="examples-of-targets-on-draggables">
<h3>Examples of targets on draggables<a class="headerlink" href="#examples-of-targets-on-draggables" title="Permalink to this headline"></a></h3>
<div class="highlight-python"><pre>&lt;problem display_name="Drag and drop demos chem features: drag and drop icons or labels
to proper positions." attempts="10"&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Simple grading example: draggables on draggables]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Describe carbon molecule in LCAO-MO.&lt;/h4&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/images_list/lcao-mo/lcao-mo.jpg" target_outline="true" &gt;
&lt;!-- filled bond --&gt;
&lt;draggable id="up_and_down" icon="/static/images/images_list/lcao-mo/u_d.png" can_reuse="true" /&gt;
&lt;!-- up bond --&gt;
&lt;draggable id="up" icon="/static/images/images_list/lcao-mo/up.png" can_reuse="true" /&gt;
&lt;draggable id="s" icon="/static/images/images_list/lcao-mo/orbital_single.png" label="s orbital" can_reuse="true" &gt;
&lt;target id="1" x="0" y="0" w="32" h="32"/&gt;
&lt;/draggable&gt;
&lt;draggable id="p" icon="/static/images/images_list/lcao-mo/orbital_triple.png" can_reuse="true" &gt;
&lt;target id="1" x="0" y="0" w="32" h="32"/&gt;
&lt;target id="2" x="34" y="0" w="32" h="32"/&gt;
&lt;target id="3" x="68" y="0" w="32" h="32"/&gt;
&lt;/draggable&gt;
&lt;!-- positions of electrons and electron pairs --&gt;
&lt;target id="s_l" x="130" y="360" w="32" h="32"/&gt;
&lt;target id="s_r" x="505" y="360" w="32" h="32"/&gt;
&lt;target id="p_l" x="80" y="100" w="100" h="32"/&gt;
&lt;target id="p_r" x="465" y="100" w="100" h="32"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [
{
'draggables': ['p'],
'targets': ['p_l', 'p_r'],
'rule': 'unordered_equal'
},
{
'draggables': ['s'],
'targets': ['s_l', 's_r'],
'rule': 'unordered_equal'
},
{
'draggables': ['up_and_down'],
'targets': [
's_l[s][1]', 's_r[s][1]'
],
'rule': 'unordered_equal'
},
{
'draggables': ['up'],
'targets': [
'p_l[p][1]', 'p_l[p][3]', 'p_r[p][1]', 'p_r[p][3]'
],
'rule': 'unordered_equal'
}
]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Complex grading example: draggables on draggables]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Describe carbon molecule in LCAO-MO.&lt;/h4&gt;
&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/images_list/lcao-mo/lcao-mo-clean.jpg" target_outline="true" &gt;
&lt;!-- filled bond --&gt;
&lt;draggable id="up_and_down" icon="/static/images/images_list/lcao-mo/u_d.png" can_reuse="true" /&gt;
&lt;!-- up bond --&gt;
&lt;draggable id="up" icon="/static/images/images_list/lcao-mo/up.png" can_reuse="true" /&gt;
&lt;!-- images that should not be dragged --&gt;
&lt;draggable id="down" icon="/static/images/images_list/lcao-mo/d.png" can_reuse="true" /&gt;
&lt;draggable id="s" icon="/static/images/images_list/lcao-mo/orbital_single.png" label="s orbital" can_reuse="true" &gt;
&lt;target id="1" x="0" y="0" w="32" h="32"/&gt;
&lt;/draggable&gt;
&lt;draggable id="p" icon="/static/images/images_list/lcao-mo/orbital_triple.png" can_reuse="true" label="p orbital" &gt;
&lt;target id="1" x="0" y="0" w="32" h="32"/&gt;
&lt;target id="2" x="34" y="0" w="32" h="32"/&gt;
&lt;target id="3" x="68" y="0" w="32" h="32"/&gt;
&lt;/draggable&gt;
&lt;draggable id="s-sigma" icon="/static/images/images_list/lcao-mo/orbital_single.png" label="s-sigma orbital" can_reuse="true" &gt;
&lt;target id="1" x="0" y="0" w="32" h="32"/&gt;
&lt;/draggable&gt;
&lt;draggable id="s-sigma*" icon="/static/images/images_list/lcao-mo/orbital_single.png" label="s-sigma* orbital" can_reuse="true" &gt;
&lt;target id="1" x="0" y="0" w="32" h="32"/&gt;
&lt;/draggable&gt;
&lt;draggable id="p-pi" icon="/static/images/images_list/lcao-mo/orbital_double.png" label="p-pi orbital" can_reuse="true" &gt;
&lt;target id="1" x="0" y="0" w="32" h="32"/&gt;
&lt;target id="2" x="34" y="0" w="32" h="32"/&gt;
&lt;/draggable&gt;
&lt;draggable id="p-sigma" icon="/static/images/images_list/lcao-mo/orbital_single.png" label="p-sigma orbital" can_reuse="true" &gt;
&lt;target id="1" x="0" y="0" w="32" h="32"/&gt;
&lt;/draggable&gt;
&lt;draggable id="p-pi*" icon="/static/images/images_list/lcao-mo/orbital_double.png" label="p-pi* orbital" can_reuse="true" &gt;
&lt;target id="1" x="0" y="0" w="32" h="32"/&gt;
&lt;target id="2" x="34" y="0" w="32" h="32"/&gt;
&lt;/draggable&gt;
&lt;draggable id="p-sigma*" icon="/static/images/images_list/lcao-mo/orbital_single.png" label="p-sigma* orbital" can_reuse="true" &gt;
&lt;target id="1" x="0" y="0" w="32" h="32"/&gt;
&lt;/draggable&gt;
&lt;!-- positions of electrons and electron pairs --&gt;
&lt;target id="s-left-target" x="130" y="360" w="32" h="32"/&gt;
&lt;target id="s-right-target" x="505" y="360" w="32" h="32"/&gt;
&lt;target id="s-sigma-target" x="315" y="425" w="32" h="32"/&gt;
&lt;target id="s-sigma*-target" x="315" y="290" w="32" h="32"/&gt;
&lt;target id="p-left-target" x="80" y="100" w="100" h="32"/&gt;
&lt;target id="p-right-target" x="480" y="100" w="100" h="32"/&gt;
&lt;target id="p-pi-target" x="300" y="220" w="66" h="32"/&gt;
&lt;target id="p-sigma-target" x="315" y="170" w="32" h="32"/&gt;
&lt;target id="p-pi*-target" x="300" y="40" w="66" h="32"/&gt;
&lt;target id="p-sigma*-target" x="315" y="0" w="32" h="32"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [
{'draggables': ['p'], 'targets': ['p-left-target', 'p-right-target'], 'rule': 'unordered_equal'},
{'draggables': ['s'], 'targets': ['s-left-target', 's-right-target'], 'rule': 'unordered_equal'},
{'draggables': ['s-sigma'], 'targets': ['s-sigma-target'], 'rule': 'exact'},
{'draggables': ['s-sigma*'], 'targets': ['s-sigma*-target'], 'rule': 'exact'},
{'draggables': ['p-pi'], 'targets': ['p-pi-target'], 'rule': 'exact'},
{'draggables': ['p-sigma'], 'targets': ['p-sigma-target'], 'rule': 'exact'},
{'draggables': ['p-pi*'], 'targets': ['p-pi*-target'], 'rule': 'exact'},
{'draggables': ['p-sigma*'], 'targets': ['p-sigma*-target'], 'rule': 'exact'},
{
'draggables': ['up_and_down'],
'targets': ['s-left-target[s][1]', 's-right-target[s][1]', 's-sigma-target[s-sigma][1]', 's-sigma*-target[s-sigma*][1]', 'p-pi-target[p-pi][1]', 'p-pi-target[p-pi][2]'],
'rule': 'unordered_equal'
},
{
'draggables': ['up'],
'targets': ['p-left-target[p][1]', 'p-left-target[p][2]', 'p-right-target[p][2]', 'p-right-target[p][3]',],
'rule': 'unordered_equal'
}
]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;customresponse&gt;
&lt;text&gt;
&lt;h4&gt;[Complex grading example: no draggables on draggables]&lt;/h4&gt;&lt;br/&gt;
&lt;h4&gt;Describe carbon molecule in LCAO-MO.&lt;/h4&gt;
&lt;br/&gt;
&lt;/text&gt;
&lt;drag_and_drop_input img="/static/images/images_list/lcao-mo/lcao-mo.jpg" target_outline="true"&gt;
&lt;!-- filled bond --&gt;
&lt;draggable id="1" icon="/static/images/images_list/lcao-mo/u_d.png" can_reuse="true" /&gt;
&lt;!-- up bond --&gt;
&lt;draggable id="7" icon="/static/images/images_list/lcao-mo/up.png" can_reuse="true" /&gt;
&lt;!-- sigma --&gt;
&lt;draggable id="11" icon="/static/images/images_list/lcao-mo/sigma.png" can_reuse="true" /&gt;
&lt;!-- sigma* --&gt;
&lt;draggable id="13" icon="/static/images/images_list/lcao-mo/sigma_s.png" can_reuse="true" /&gt;
&lt;!-- pi --&gt;
&lt;draggable id="15" icon="/static/images/images_list/lcao-mo/pi.png" can_reuse="true" /&gt;
&lt;!-- pi* --&gt;
&lt;draggable id="16" icon="/static/images/images_list/lcao-mo/pi_s.png" can_reuse="true" /&gt;
&lt;!-- images that should not be dragged --&gt;
&lt;draggable id="17" icon="/static/images/images_list/lcao-mo/d.png" can_reuse="true" /&gt;
&lt;!-- positions of electrons and electron pairs --&gt;
&lt;target id="s_left" x="130" y="360" w="32" h="32"/&gt;
&lt;target id="s_right" x="505" y="360" w="32" h="32"/&gt;
&lt;target id="s_sigma" x="320" y="425" w="32" h="32"/&gt;
&lt;target id="s_sigma_star" x="320" y="290" w="32" h="32"/&gt;
&lt;target id="p_left_1" x="80" y="100" w="32" h="32"/&gt;
&lt;target id="p_left_2" x="125" y="100" w="32" h="32"/&gt;
&lt;target id="p_left_3" x="175" y="100" w="32" h="32"/&gt;
&lt;target id="p_right_1" x="465" y="100" w="32" h="32"/&gt;
&lt;target id="p_right_2" x="515" y="100" w="32" h="32"/&gt;
&lt;target id="p_right_3" x="560" y="100" w="32" h="32"/&gt;
&lt;target id="p_pi_1" x="290" y="220" w="32" h="32"/&gt;
&lt;target id="p_pi_2" x="335" y="220" w="32" h="32"/&gt;
&lt;target id="p_sigma" x="315" y="170" w="32" h="32"/&gt;
&lt;target id="p_pi_star_1" x="290" y="40" w="32" h="32"/&gt;
&lt;target id="p_pi_star_2" x="340" y="40" w="32" h="32"/&gt;
&lt;target id="p_sigma_star" x="315" y="0" w="32" h="32"/&gt;
&lt;!-- positions of names of energy levels --&gt;
&lt;target id="s_sigma_name" x="400" y="425" w="32" h="32"/&gt;
&lt;target id="s_sigma_star_name" x="400" y="290" w="32" h="32"/&gt;
&lt;target id="p_pi_name" x="400" y="220" w="32" h="32"/&gt;
&lt;target id="p_sigma_name" x="400" y="170" w="32" h="32"/&gt;
&lt;target id="p_pi_star_name" x="400" y="40" w="32" h="32"/&gt;
&lt;target id="p_sigma_star_name" x="400" y="0" w="32" h="32"/&gt;
&lt;/drag_and_drop_input&gt;
&lt;answer type="loncapa/python"&gt;&lt;![CDATA[
correct_answer = [
{
'draggables': ['1'],
'targets': [
's_left', 's_right', 's_sigma', 's_sigma_star', 'p_pi_1', 'p_pi_2'
],
'rule': 'exact'
}, {
'draggables': ['7'],
'targets': ['p_left_1', 'p_left_2', 'p_right_2','p_right_3'],
'rule': 'exact'
}, {
'draggables': ['11'],
'targets': ['s_sigma_name', 'p_sigma_name'],
'rule': 'exact'
}, {
'draggables': ['13'],
'targets': ['s_sigma_star_name', 'p_sigma_star_name'],
'rule': 'exact'
}, {
'draggables': ['15'],
'targets': ['p_pi_name'],
'rule': 'exact'
}, {
'draggables': ['16'],
'targets': ['p_pi_star_name'],
'rule': 'exact'
}]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
]]&gt;&lt;/answer&gt;
&lt;/customresponse&gt;
&lt;/problem&gt;
</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../graphical_slider_tool/graphical_slider_tool.html" title="XML format of graphical slider tool [xmodule]"
>next</a> |</li>
<li class="right" >
<a href="../grading.html" title="Course Grading"
>previous</a> |</li>
<li><a href="../../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Course Grading &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="../index.html" />
<link rel="next" title="XML format of drag and drop input [inputtypes]" href="drag_and_drop/drag_and_drop_input.html" />
<link rel="prev" title="Course XML Tutorial" href="course_xml.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="drag_and_drop/drag_and_drop_input.html" title="XML format of drag and drop input [inputtypes]"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="course_xml.html" title="Course XML Tutorial"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Course Grading</a><ul>
<li><a class="reference internal" href="#totaling-sections">Totaling sections</a></li>
<li><a class="reference internal" href="#weighting-problems">Weighting Problems</a></li>
<li><a class="reference internal" href="#weighting-sections">Weighting Sections</a><ul>
<li><a class="reference internal" href="#section-format-graders">Section Format Graders</a></li>
<li><a class="reference internal" href="#single-section-graders">Single Section Graders</a></li>
<li><a class="reference internal" href="#combining-sub-graders">Combining sub-graders</a></li>
</ul>
</li>
<li><a class="reference internal" href="#displaying-the-final-grade">Displaying the final grade</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="course_xml.html"
title="previous chapter">Course XML Tutorial</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="drag_and_drop/drag_and_drop_input.html"
title="next chapter">XML format of drag and drop input [inputtypes]</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/course_data_formats/grading.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="course-grading">
<h1>Course Grading<a class="headerlink" href="#course-grading" title="Permalink to this headline"></a></h1>
<p>This document is written to help professors understand how a final grade for a
course is computed.</p>
<p>Course grading is the process of taking all of the problems scores for a student
in a course and generating a final score (and corresponding letter grade). This
grading process can be split into two phases - totaling sections and section
weighting.</p>
<div class="section" id="totaling-sections">
<h2>Totaling sections<a class="headerlink" href="#totaling-sections" title="Permalink to this headline"></a></h2>
<p>The process of totaling sections is to get a percentage score (between 0.0 and
1.0) for every section in the course. A section is any module that is a direct
child of a chapter. For example, psets, labs, and sequences are all common
sections. Only the <em>percentage</em> on the section will be available to compute the
final grade, <em>not</em> the final number of points earned / possible.</p>
<div class="admonition important">
<p class="first admonition-title">Important</p>
<p class="last">For a section to be included in the final grade, the policies file must set
<cite>graded = True</cite> for the section.</p>
</div>
<p>For each section, the grading function retrieves all problems within the
section. The section percentage is computed as (total points earned) / (total
points possible).</p>
</div>
<div class="section" id="weighting-problems">
<h2>Weighting Problems<a class="headerlink" href="#weighting-problems" title="Permalink to this headline"></a></h2>
<p>In some cases, one might want to give weights to problems within a section. For
example, a final exam might contain four questions each worth 1 point by default.
This means each question would by default have the same weight. If one wanted
the first problem to be worth 50% of the final exam, the policy file could specify
weights of 30, 10, 10, and 10 to the four problems, respectively.</p>
<p>Note that the default weight of a problem <strong>is not 1</strong>. The default weight of a
problem is the module&#8217;s <cite>max_grade</cite>.</p>
<p>If weighting is set, each problem is worth the number of points assigned, regardless of the number of responses it contains.</p>
<p>Consider a Homework section that contains two problems.</p>
<div class="highlight-xml"><pre>&lt;problem display_name=”Problem 1”&gt;
&lt;numericalresponse&gt; ... &lt;/numericalreponse&gt;
&lt;/problem&gt;</pre>
</div>
<div class="highlight-xml"><pre>&lt;problem display_name=”Problem 2”&gt;
&lt;numericalresponse&gt; ... &lt;/numericalreponse&gt;
&lt;numericalresponse&gt; ... &lt;/numericalreponse&gt;
&lt;numericalresponse&gt; ... &lt;/numericalreponse&gt;
&lt;/problem&gt;</pre>
</div>
<p>Without weighting, Problem 1 is worth 25% of the assignment, and Problem 2 is worth 75% of the assignment.</p>
<p>Weighting for the problems can be set in the policy.json file.</p>
<div class="highlight-json"><pre>"problem/problem1": {
"weight": 2
},
"problem/problem2": {
"weight": 2
},</pre>
</div>
<p>With the above weighting, Problems 1 and 2 are each worth 50% of the assignment.</p>
<p>Please note: When problems have weight, the point value is automatically included in the display name <em>except</em> when <cite>&#8220;weight&#8221;: 1</cite>. When the weight is 1, no visual change occurs in the display name, leaving the point value open to interpretation to the student.</p>
</div>
<div class="section" id="weighting-sections">
<h2>Weighting Sections<a class="headerlink" href="#weighting-sections" title="Permalink to this headline"></a></h2>
<p>Once each section has a percentage score, we must total those sections into a
final grade. Of course, not every section has equal weight in the final grade.
The policies for weighting sections into a final grade are specified in the
grading_policy.json file.</p>
<p>The <cite>grading_policy.json</cite> file specifies several sub-graders that are each given
a weight and factored into the final grade. There are currently two types of
sub-graders, section format graders and single section graders.</p>
<p>We will use this simple example of a grader with one section format grader and
one single section grader.</p>
<div class="highlight-json"><pre>"GRADER" : [
{
"type" : "Homework",
"min_count" : 12,
"drop_count" : 2,
"short_label" : "HW",
"weight" : 0.4
},
{
"type" : "Final",
"name" : "Final Exam",
"short_label" : "Final",
"weight" : 0.6
}
]</pre>
</div>
<div class="section" id="section-format-graders">
<h3>Section Format Graders<a class="headerlink" href="#section-format-graders" title="Permalink to this headline"></a></h3>
<p>A section format grader grades a set of sections with the same format, as
defined in the course policy file. To make a vertical named Homework1 be graded
by the Homework section format grader, the following definition would be in the
course policy file.</p>
<div class="highlight-json"><pre>"vertical/Homework1": {
"display_name": "Homework 1",
"graded": true,
"format": "Homework"
},</pre>
</div>
<p>In the example above, the section format grader declares that it will expect to
find at least 12 sections with the format &#8220;Homework&#8221;. It will drop the lowest 2.
All of the homework assignments will have equal weight, relative to each other
(except, of course, for the assignments that are dropped).</p>
<p>This format supports forecasting the number of homework assignments. For
example, if the course only has 3 homeworks written, but the section format
grader has been told to expect 12, the missing 9 will have an assumed 0% and
will still show up in the grade breakdown.</p>
<p>A section format grader will also show the average of that section in the grade
breakdown (shown on the Progress page, gradebook, etc.).</p>
</div>
<div class="section" id="single-section-graders">
<h3>Single Section Graders<a class="headerlink" href="#single-section-graders" title="Permalink to this headline"></a></h3>
<p>A single section grader grades exactly that - a single section. If a section
is found with a matching format and display name then the score of that section
is used. If not, a score of 0% is assumed.</p>
</div>
<div class="section" id="combining-sub-graders">
<h3>Combining sub-graders<a class="headerlink" href="#combining-sub-graders" title="Permalink to this headline"></a></h3>
<p>The final grade is computed by taking the score and weight of each sub grader.
In the above example, homework will be 40% of the final grade. The final exam
will be 60% of the final grade.</p>
</div>
</div>
<div class="section" id="displaying-the-final-grade">
<h2>Displaying the final grade<a class="headerlink" href="#displaying-the-final-grade" title="Permalink to this headline"></a></h2>
<p>The final grade is then rounded up to the nearest percentage point. This is so
the system can consistently display a percentage without worrying whether the
displayed percentage has been rounded up or down (potentially misleading the
student). The formula for the rounding is:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">rounded_percent</span> <span class="o">=</span> <span class="nb">round</span><span class="p">(</span><span class="n">computed_percent</span> <span class="o">*</span> <span class="mi">100</span> <span class="o">+</span> <span class="mf">0.05</span><span class="p">)</span> <span class="o">/</span> <span class="mi">100</span>
</pre></div>
</div>
<p>The grading policy file also specifies the cutoffs for the grade levels. A
grade is either A, B, or C. If the student does not reach the cutoff threshold
for a C grade then the student has not earned a grade and will not be eligible
for a certificate. Letter grades are only awarded to students who have
completed the course. There is no notion of a failing letter grade.</p>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="drag_and_drop/drag_and_drop_input.html" title="XML format of drag and drop input [inputtypes]"
>next</a> |</li>
<li class="right" >
<a href="course_xml.html" title="Course XML Tutorial"
>previous</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>XML format of graphical slider tool [xmodule] &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../../',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="../../index.html" />
<link rel="next" title="Xml format of poll module [xmodule]" href="../poll_module/poll_module.html" />
<link rel="prev" title="XML format of drag and drop input [inputtypes]" href="../drag_and_drop/drag_and_drop_input.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../poll_module/poll_module.html" title="Xml format of poll module [xmodule]"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="../drag_and_drop/drag_and_drop_input.html" title="XML format of drag and drop input [inputtypes]"
accesskey="P">previous</a> |</li>
<li><a href="../../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">XML format of graphical slider tool [xmodule]</a><ul>
<li><a class="reference internal" href="#format-description">Format description</a><ul>
<li><a class="reference internal" href="#render-tag">Render tag</a><ul>
<li><a class="reference internal" href="#slider-tag">Slider tag</a></li>
<li><a class="reference internal" href="#textbox-tag">Textbox tag</a></li>
<li><a class="reference internal" href="#plot-tag">Plot tag</a></li>
<li><a class="reference internal" href="#html-tags-with-id-dynamic-elements">HTML tags with ID (dynamic elements)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#configuration-tag">Configuration tag</a><ul>
<li><a class="reference internal" href="#parameters-tag">Parameters tag</a></li>
<li><a class="reference internal" href="#functions-tag">Functions tag</a></li>
<li><a class="reference internal" href="#note-on-mathjax-and-labels">[Note on MathJax and labels]</a></li>
<li><a class="reference internal" href="#id9">Plot tag</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#example">Example</a><ul>
<li><a class="reference internal" href="#plotting-sliders-and-inputs">Plotting, sliders and inputs</a></li>
<li><a class="reference internal" href="#update-of-html-elements-no-plotting">Update of html elements, no plotting</a></li>
<li><a class="reference internal" href="#circle-with-dynamic-radius">Circle with dynamic radius</a></li>
<li><a class="reference internal" href="#example-of-a-bar-graph">Example of a bar graph</a></li>
<li><a class="reference internal" href="#example-of-moving-labels-of-graph">Example of moving labels of graph</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="../drag_and_drop/drag_and_drop_input.html"
title="previous chapter">XML format of drag and drop input [inputtypes]</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="../poll_module/poll_module.html"
title="next chapter">Xml format of poll module [xmodule]</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../../_sources/course_data_formats/graphical_slider_tool/graphical_slider_tool.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-xml_format_gst">
<span id="xml-format-of-graphical-slider-tool-xmodule"></span><h1>XML format of graphical slider tool [xmodule]<a class="headerlink" href="#module-xml_format_gst" title="Permalink to this headline"></a></h1>
<div class="section" id="format-description">
<h2>Format description<a class="headerlink" href="#format-description" title="Permalink to this headline"></a></h2>
<p>Graphical slider tool (GST) main tag is:</p>
<div class="highlight-python"><pre>&lt;graphical_slider_tool&gt; BODY &lt;/graphical_slider_tool&gt;</pre>
</div>
<p><tt class="docutils literal"><span class="pre">graphical_slider_tool</span></tt> tag must have two children tags: <tt class="docutils literal"><span class="pre">render</span></tt>
and <tt class="docutils literal"><span class="pre">configuration</span></tt>.</p>
<div class="section" id="render-tag">
<h3>Render tag<a class="headerlink" href="#render-tag" title="Permalink to this headline"></a></h3>
<p>Render tag can contain usual html tags mixed with some GST specific tags:</p>
<div class="highlight-python"><pre>&lt;slider/&gt; - represents jQuery slider for changing a parameter's value
&lt;textbox/&gt; - represents a text input field for changing a parameter's value
&lt;plot/&gt; - represents Flot JS plot element</pre>
</div>
<p>Also GST will track all elements inside <tt class="docutils literal"><span class="pre">&lt;render&gt;&lt;/render&gt;</span></tt> where <tt class="docutils literal"><span class="pre">id</span></tt>
attribute is set, and a corresponding parameter referencing that <tt class="docutils literal"><span class="pre">id</span></tt> is present
in the configuration section below. These will be referred to as dynamic elements.</p>
<p>The contents of the &lt;render&gt; section will be shown to the user after
all occurrences of:</p>
<div class="highlight-python"><pre>&lt;slider var="{parameter name}" [style="{CSS statements}"] /&gt;
&lt;textbox var="{parameter name}" [style="{CSS statements}"] /&gt;
&lt;plot [style="{CSS statements}"] /&gt;</pre>
</div>
<p>have been converted to actual sliders, text inputs, and a plot graph.
Everything in square brackets is optional. After initialization, all
text input fields, sliders, and dynamic elements will be set to the initial
values of the parameters that they are assigned to.</p>
<p><tt class="docutils literal"><span class="pre">{parameter</span> <span class="pre">name}</span></tt> specifies the parameter to which the slider or text
input will be attached to.</p>
<p>[style=&#8221;{CSS statements}&#8221;] specifies valid CSS styling. It will be passed
directly to the browser without any parsing.</p>
<p>There is a one-to-one relationship between a slider and a parameter.
I.e. for one parameter you can put only one <tt class="docutils literal"><span class="pre">&lt;slider&gt;</span></tt> in the
<tt class="docutils literal"><span class="pre">&lt;render&gt;</span></tt> section. However, you don&#8217;t have to specify a slider - they
are optional.</p>
<p>There is a many-to-one relationship between text inputs and a
parameter. I.e. for one parameter you can put many &#8216;&lt;textbox&gt;&#8217; elements in
the <tt class="docutils literal"><span class="pre">&lt;render&gt;</span></tt> section. However, you don&#8217;t have to specify a text
input - they are optional.</p>
<p>You can put only one <tt class="docutils literal"><span class="pre">&lt;plot&gt;</span></tt> in the <tt class="docutils literal"><span class="pre">&lt;render&gt;</span></tt> section. It is not
required.</p>
<div class="section" id="slider-tag">
<h4>Slider tag<a class="headerlink" href="#slider-tag" title="Permalink to this headline"></a></h4>
<p>Slider tag must have <tt class="docutils literal"><span class="pre">var</span></tt> attribute and optional <tt class="docutils literal"><span class="pre">style</span></tt> attribute:</p>
<div class="highlight-python"><pre>&lt;slider var='a' style="width:400px;float:left;" /&gt;</pre>
</div>
<p>After processing, slider tags will be replaced by jQuery UI sliders with applied
<tt class="docutils literal"><span class="pre">style</span></tt> attribute.</p>
<p><tt class="docutils literal"><span class="pre">var</span></tt> attribute must correspond to a parameter. Parameters can be used in any
of the <tt class="docutils literal"><span class="pre">function</span></tt> tags in <tt class="docutils literal"><span class="pre">functions</span></tt> tag. By moving slider, value of
parameter <tt class="docutils literal"><span class="pre">a</span></tt> will change, and so result of function, that depends on parameter
<tt class="docutils literal"><span class="pre">a</span></tt>, will also change.</p>
</div>
<div class="section" id="textbox-tag">
<h4>Textbox tag<a class="headerlink" href="#textbox-tag" title="Permalink to this headline"></a></h4>
<p>Texbox tag must have <tt class="docutils literal"><span class="pre">var</span></tt> attribute and optional <tt class="docutils literal"><span class="pre">style</span></tt> attribute:</p>
<div class="highlight-python"><pre>&lt;textbox var="b" style="width:50px; float:left; margin-left:10px;" /&gt;</pre>
</div>
<p>After processing, textbox tags will be replaced by html text inputs with applied
<tt class="docutils literal"><span class="pre">style</span></tt> attribute. If you want a readonly text input, then you should use a
dynamic element instead (see section below &#8220;HTML tagsd with ID&#8221;).</p>
<p><tt class="docutils literal"><span class="pre">var</span></tt> attribute must correspond to a parameter. Parameters can be used in any
of the <tt class="docutils literal"><span class="pre">function</span></tt> tags in <tt class="docutils literal"><span class="pre">functions</span></tt> tag. By changing the value on the text input,
value of parameter <tt class="docutils literal"><span class="pre">a</span></tt> will change, and so result of function, that depends on
parameter <tt class="docutils literal"><span class="pre">a</span></tt>, will also change.</p>
</div>
<div class="section" id="plot-tag">
<h4>Plot tag<a class="headerlink" href="#plot-tag" title="Permalink to this headline"></a></h4>
<p>Plot tag may have optional <tt class="docutils literal"><span class="pre">style</span></tt> attribute:</p>
<div class="highlight-python"><pre>&lt;plot style="width:50px; float:left; margin-left:10px;" /&gt;</pre>
</div>
<p>After processing plot tags will be replaced by Flot JS plot with applied
<tt class="docutils literal"><span class="pre">style</span></tt> attribute.</p>
</div>
<div class="section" id="html-tags-with-id-dynamic-elements">
<h4>HTML tags with ID (dynamic elements)<a class="headerlink" href="#html-tags-with-id-dynamic-elements" title="Permalink to this headline"></a></h4>
<p>Any HTML tag with ID, e.g. <tt class="docutils literal"><span class="pre">&lt;span</span> <span class="pre">id=&quot;answer_span_1&quot;&gt;</span></tt> can be used as a
place where result of function can be inserted. To insert function result to
an element, element ID must be included in <tt class="docutils literal"><span class="pre">function</span></tt> tag as <tt class="docutils literal"><span class="pre">el_id</span></tt> attribute
and <tt class="docutils literal"><span class="pre">output</span></tt> value must be <tt class="docutils literal"><span class="pre">&quot;element&quot;</span></tt>:</p>
<div class="highlight-python"><pre>&lt;function output="element" el_id="answer_span_1"&gt;
function add(a, b, precision) {
var x = Math.pow(10, precision || 2);
return (Math.round(a * x) + Math.round(b * x)) / x;
}
return add(a, b, 5);
&lt;/function&gt;</pre>
</div>
</div>
</div>
<div class="section" id="configuration-tag">
<h3>Configuration tag<a class="headerlink" href="#configuration-tag" title="Permalink to this headline"></a></h3>
<p>The configuration tag contains parameter settings, graph
settings, and function definitions which are to be plotted on the
graph and that use specified parameters.</p>
<p>Configuration tag contains two mandatory tag <tt class="docutils literal"><span class="pre">functions</span></tt> and <tt class="docutils literal"><span class="pre">parameters</span></tt> and
may contain another <tt class="docutils literal"><span class="pre">plot</span></tt> tag.</p>
<div class="section" id="parameters-tag">
<h4>Parameters tag<a class="headerlink" href="#parameters-tag" title="Permalink to this headline"></a></h4>
<p><tt class="docutils literal"><span class="pre">Parameters</span></tt> tag contains <tt class="docutils literal"><span class="pre">parameter</span></tt> tags. Each <tt class="docutils literal"><span class="pre">parameter</span></tt> tag must have
<tt class="docutils literal"><span class="pre">var</span></tt>, <tt class="docutils literal"><span class="pre">max</span></tt>, <tt class="docutils literal"><span class="pre">min</span></tt>, <tt class="docutils literal"><span class="pre">step</span></tt> and <tt class="docutils literal"><span class="pre">initial</span></tt> attributes:</p>
<div class="highlight-python"><pre>&lt;parameters&gt;
&lt;param var="a" min="-10.0" max="10.0" step="0.1" initial="0" /&gt;
&lt;param var="b" min="-10.0" max="10.0" step="0.1" initial="0" /&gt;
&lt;/parameters&gt;</pre>
</div>
<p><tt class="docutils literal"><span class="pre">var</span></tt> attribute links min, max, step and initial values to parameter name.</p>
<p><tt class="docutils literal"><span class="pre">min</span></tt> attribute is the minimal value that a parameter can take. Slider and input
values can not go below it.</p>
<p><tt class="docutils literal"><span class="pre">max</span></tt> attribute is the maximal value that a parameter can take. Slider and input
values can not go over it.</p>
<p><tt class="docutils literal"><span class="pre">step</span></tt> attribute is value of slider step. When a slider increase or decreases
the specified parameter, it will do so by the amount specified with &#8216;step&#8217;</p>
<p><tt class="docutils literal"><span class="pre">initial</span></tt> attribute is the initial value that the specified parameter should be
set to. Sliders and inputs will initially show this value.</p>
<p>The parameter&#8217;s name is specified by the <tt class="docutils literal"><span class="pre">var</span></tt> property. All occurrences
of sliders and/or text inputs that specify a <tt class="docutils literal"><span class="pre">var</span></tt> property, will be
connected to this parameter - i.e. they will reflect the current
value of the parameter, and will be updated when the parameter
changes.</p>
<p>If at lest one of these attributes is not set, then the parameter
will not be used, slider&#8217;s and/or text input elements that specify
this parameter will not be activated, and the specified functions
which use this parameter will not return a numeric value. This means
that neglecting to specify at least one of the attributes for some
parameter will have the result of the whole GST instance not working
properly.</p>
</div>
<div class="section" id="functions-tag">
<h4>Functions tag<a class="headerlink" href="#functions-tag" title="Permalink to this headline"></a></h4>
<p>For the GST to do something, you must defined at least one
function, which can use any of the specified parameter values. The
function expects to take the <tt class="docutils literal"><span class="pre">x</span></tt> value, do some calculations, and
return the <tt class="docutils literal"><span class="pre">y</span></tt> value. I.e. this is a 2D plot in Cartesian
coordinates. This is how the default function is meant to be used for
the graph.</p>
<p>There are other special cases of functions. They are used mainly for
outputting to elements, plot labels, or for custom output. Because
the return a single value, and that value is meant for a single element,
these function are invoked only with the set of all of the parameters.
I.e. no <tt class="docutils literal"><span class="pre">x</span></tt> value is available inside them. They are useful for
showing the current value of a parameter, showing complex static
formulas where some parameter&#8217;s value must change, and other useful
things.</p>
<p>The different style of function is specified by the <tt class="docutils literal"><span class="pre">output</span></tt> attribute.</p>
<p>Each function must be defined inside <tt class="docutils literal"><span class="pre">function</span></tt> tag in <tt class="docutils literal"><span class="pre">functions</span></tt> tag:</p>
<div class="highlight-python"><pre>&lt;functions&gt;
&lt;function output="element" el_id="answer_span_1"&gt;
function add(a, b, precision) {
var x = Math.pow(10, precision || 2);
return (Math.round(a * x) + Math.round(b * x)) / x;
}
return add(a, b, 5);
&lt;/function&gt;
&lt;/functions&gt;</pre>
</div>
<p>The parameter names (along with their values, as provided from text
inputs and/or sliders), will be available inside all defined
functions. A defined function body string will be parsed internally
by the browser&#8217;s JavaScript engine and converted to a true JS
function.</p>
<p>The function&#8217;s parameter list will automatically be created and
populated, and will include the <tt class="docutils literal"><span class="pre">x</span></tt> (when <tt class="docutils literal"><span class="pre">output</span></tt> is not specified or
is set to <tt class="docutils literal"><span class="pre">&quot;graph&quot;</span></tt>), and all of the specified parameter values (from sliders
and text inputs). This means that each of the defined functions will have
access to all of the parameter values. You don&#8217;t have to use them, but
they will be there.</p>
<p>Examples:</p>
<div class="highlight-python"><pre>&lt;function&gt;
return x;
&lt;/function&gt;
&lt;function dot="true" label="\(y_2\)"&gt;
return (x + a) * Math.sin(x * b);
&lt;/function&gt;
&lt;function color="green"&gt;
function helperFunc(c1) {
return c1 * c1 - a;
}
return helperFunc(x + 10 * a * b) + Math.sin(a - x);
&lt;/function&gt;</pre>
</div>
<p>Required parameters:</p>
<div class="highlight-python"><pre>function body:
A string composing a normal JavaScript function
except that there is no function declaration
(along with parameters), and no closing bracket.
So if you normally would have written your
JavaScript function like this:
function myFunc(x, a, b) {
return x * a + b;
}
here you must specify just the function body
(everything that goes between '{' and '}'). So,
you would specify the above function like so (the
bare-bone minimum):
&lt;function&gt;return x * a + b;&lt;/function&gt;
VERY IMPORTANT: Because the function will be passed
to the browser as a single string, depending on implementation
specifics, the end-of-line characters can be stripped. This
means that single line JavaScript comments (starting with "//")
can lead to the effect that everything after the first such comment
will be treated as a comment. Therefore, it is absolutely
necessary that such single line comments are not used when
defining functions for GST. You can safely use the alternative
multiple line JavaScript comments (such comments start with "/*"
and end with "*/).
VERY IMPORTANT: If you have a large function body, and decide to
split it into several lines, than you must wrap it in "CDATA" like
so:
&lt;function&gt;
&lt;![CDATA[
var dNew;
dNew = 0.3;
return x * a + b - dNew;
]]&gt;
&lt;/function&gt;</pre>
</div>
<p>Optional parameters:</p>
<div class="highlight-python"><pre>color: Color name ('red', 'green', etc.) or in the form of
'#FFFF00'. If not specified, a default color (different
one for each graphed function) will be given by Flot JS.
line: A string - 'true' or 'false'. Should the data points be
connected by a line on the graph? Default is 'true'.
dot: A string - 'true' or 'false'. Should points be shown for
each data point on the graph? Default is 'false'.
bar: A string - 'true' or 'false'. When set to 'true', points
will be plotted as bars.
label: A string. If provided, will be shown in the legend, along
with the color that was used to plot the function.
output: 'element', 'none', 'plot_label', or 'graph'. If not defined,
function will be plotted (same as setting 'output' to 'graph').
If defined, and other than 'graph', function will not be
plotted, but it's output will be inserted into the element
with ID specified by 'el_id' attribute.
el_id: Id of HTML element, defined in '&lt;render&gt;' section. Value of
function will be inserted as content of this element.
disable_auto_return: By default, if JavaScript function string is written
without a "return" statement, the "return" will be
prepended to it. Set to "true" to disable this
functionality. This is done so that simple functions
can be defined in an easy fashion (for example, "a",
which will be translated into "return a").
update_on: A string - 'change', or 'slide'. Default (if not set) is
'slide'. This defines the event on which a given function is
called, and its result is inserted into an element. This
setting is relevant only when "output" is other than "graph".</pre>
</div>
<dl class="docutils">
<dt>When specifying <tt class="docutils literal"><span class="pre">el_id</span></tt>, it is essential to set &#8220;output&#8221; to one of</dt>
<dd><dl class="first last docutils">
<dt>element - GST will invoke the function, and the return of it will be</dt>
<dd>inserted into a HTML element with id specified by <tt class="docutils literal"><span class="pre">el_id</span></tt>.</dd>
<dt>none - GST will simply inoke the function. It is left to the instructor</dt>
<dd>who writes the JavaScript function body to update all necesary
HTML elements inside the function, before it exits. This is done
so that extra steps can be preformed after an HTML element has
been updated with a value. Note, that because the return value
from this function is not actually used, it will be tempting to
omit the &#8220;return&#8221; statement. However, in this case, the attribute
&#8220;disable_auto_return&#8221; must be set to &#8220;true&#8221; in order to prevent
GST from inserting a &#8220;return&#8221; statement automatically.</dd>
<dt>plot_label - GST will process all plot labels (which are strings), and</dt>
<dd>will replace the all instances of substrings specified by
<tt class="docutils literal"><span class="pre">el_id</span></tt> with the returned value of the function. This is
necessary if you want a label in the graph to have some changing
number. Because of the nature of Flot JS, it is impossible to
achieve the same effect by setting the &#8220;output&#8221; attribute
to &#8220;element&#8221;, and including a HTML element in the label.</dd>
</dl>
</dd>
</dl>
<p>The above values for &#8220;output&#8221; will tell GST that the function is meant for an
HTML element (not for graph), and that it should not get an &#8216;x&#8217; parameter (along
with some value).</p>
</div>
<div class="section" id="note-on-mathjax-and-labels">
<h4>[Note on MathJax and labels]<a class="headerlink" href="#note-on-mathjax-and-labels" title="Permalink to this headline"></a></h4>
<p>Independently of this module, will render all TeX code
within the <tt class="docutils literal"><span class="pre">&lt;render&gt;</span></tt> section into nice mathematical formulas. Just
remember to wrap it in one of:</p>
<div class="highlight-python"><pre>\( and \) - for inline formulas (formulas surrounded by
standard text)
\[ and \] - if you want the formula to be a separate line</pre>
</div>
<p>It is possible to define a label in standard TeX notation. The JS
library MathJax will work on these labels also because they are
inserted on top of the plot as standard HTML (text within a DIV).</p>
<p>If the label is dynamic, i.e. it will contain some text (numeric, or other)
that has to be updated on a parameter&#8217;s change, then one can define
a special function to handle this. The &#8220;output&#8221; of such a function must be
set to &#8220;none&#8221;, and the JavaScript code inside this function must update the
MathJax element by itself. Before exiting, MathJax typeset function should
be called so that the new text will be re-rendered by MathJax. For example,</p>
<blockquote>
<div><dl class="docutils">
<dt>&lt;render&gt;</dt>
<dd>...
&lt;span id=&#8221;dynamic_mathjax&#8221;&gt;&lt;/span&gt;</dd>
</dl>
<p>&lt;/render&gt;
...
&lt;function output=&#8221;none&#8221; el_id=&#8221;dynamic_mathjax&#8221;&gt;
&lt;![CDATA[</p>
<blockquote>
<div><p>var out_text;</p>
<dl class="docutils">
<dt>out_text = &#8220;\[\mathrm{Percent \space of \space treated \space with \space YSS=\frac{&#8220;</dt>
<dd>+(treated_men*10)+&#8221;\space men <a href="#id1"><span class="problematic" id="id2">*</span></a>&#8221;
+(your_m_tx_yss/100)+&#8221;\space prev. +\space &#8221;
+((100-treated_men)*10)+&#8221;\space women <a href="#id3"><span class="problematic" id="id4">*</span></a>&#8221;
+(your_f_tx_yss/100)+&#8221;\space prev.}&#8221;
+&#8221;{1000\space total\space treated\space patients}&#8221;
+&#8221;=&#8221;+drummond_combined[0][1]+&#8221;\%}\]&#8221;;
mathjax_for_prevalence_calcs+=&#8221;\[\mathrm{Percent \space of \space untreated \space with \space YSS=\frac{&#8221;
+(untreated_men*10)+&#8221;\space men <a href="#id5"><span class="problematic" id="id6">*</span></a>&#8221;
+(your_m_utx_yss/100)+&#8221;\space prev. +\space &#8221;
+((100-untreated_men)*10)+&#8221;\space women <a href="#id7"><span class="problematic" id="id8">*</span></a>&#8221;
+(your_f_utx_yss/100)+&#8221;\space prev.}&#8221;
+&#8221;{1000\space total\space untreated\space patients}&#8221;
+&#8221;=&#8221;+drummond_combined[1][1]+&#8221;\%}\]&#8221;;</dd>
</dl>
<p>$(&#8220;#dynamic_mathjax&#8221;).html(out_text);</p>
<p>MathJax.Hub.Queue([&#8220;Typeset&#8221;,MathJax.Hub,&#8221;dynamic_mathjax&#8221;]);</p>
</div></blockquote>
<p>]]&gt;
&lt;/function&gt;
...</p>
</div></blockquote>
</div>
<div class="section" id="id9">
<h4>Plot tag<a class="headerlink" href="#id9" title="Permalink to this headline"></a></h4>
<p><tt class="docutils literal"><span class="pre">Plot</span></tt> tag inside <tt class="docutils literal"><span class="pre">configuration</span></tt> tag defines settings for plot output.</p>
<p>Required parameters:</p>
<div class="highlight-python"><pre>xrange: 2 functions that must return value. Value is constant (3.1415)
or depend on parameter from parameters section:
&lt;xrange&gt;
&lt;min&gt;return 0;&lt;/min&gt;
&lt;max&gt;return 30;&lt;/max&gt;
&lt;/xrange&gt;
or
&lt;xrange&gt;
&lt;min&gt;return -a;&lt;/min&gt;
&lt;max&gt;return a;&lt;/max&gt;
&lt;/xrange&gt;
All functions will be calculated over domain between xrange:min
and xrange:max. Xrange depending on parameter is extremely
useful when domain(s) of your function(s) depends on parameter
(like circle, when parameter is radius and you want to allow
to change it).</pre>
</div>
<p>Optional parameters:</p>
<div class="highlight-python"><pre>num_points: Number of data points to generated for the plot. If
this is not set, the number of points will be
calculated as width / 5.
bar_width: If functions are present which are to be plotted as bars,
then this parameter specifies the width of the bars. A
numeric value for this parameter is expected.
bar_align: If functions are present which are to be plotted as bars,
then this parameter specifies how to align the bars relative
to the tick. Available values are "left" and "center".
xticks,
yticks: 3 floating point numbers separated by commas. This
specifies how many ticks are created, what number they
start at, and what number they end at. This is different
from the 'xrange' setting in that it has nothing to do
with the data points - it control what area of the
Cartesian space you will see. The first number is the
first tick's value, the second number is the step
between each tick, the third number is the value of the
last tick. If these configurations are not specified,
Flot will chose them for you based on the data points
set that he is currently plotting. Usually, this results
in a nice graph, however, sometimes you need to fine
grain the controls. For example, when you want to show
a fixed area of the Cartesian space, even when the data
set changes. On it's own, Flot will recalculate the
ticks, which will result in a different graph each time.
By specifying the xticks, yticks configurations, only
the plotted data will change - the axes (ticks) will
remain as you have defined them.
xticks_names, yticks_names:
A JSON string which represents a mapping of xticks, yticks
values to some defined strings. If specified, the graph will
not have any xticks, yticks except those for which a string
value has been defined in the JSON string. Note that the
matching will be string-based and not numeric. I.e. if a tick
value was "3.70" before, then inside the JSON there should be
a mapping like {..., "3.70": "Some string", ...}. Example:
&lt;xticks_names&gt;
&lt;![CDATA[
{
"1": "Treated", "2": "Not Treated",
"4": "Treated", "5": "Not Treated",
"7": "Treated", "8": "Not Treated"
}
]]&gt;
&lt;/xticks_names&gt;
&lt;yticks_names&gt;
&lt;![CDATA[
{"0": "0%", "10": "10%", "20": "20%", "30": "30%", "40": "40%", "50": "50%"}
]]&gt;
&lt;/yticks_names&gt;
xunits,
yunits: Units values to be set on axes. Use MathJax. Example:
&lt;xunits&gt;\(cm\)&lt;/xunits&gt;
&lt;yunits&gt;\(m\)&lt;/yunits&gt;
moving_label:
A way to specify a label that should be positioned dynamically,
based on the values of some parameters, or some other factors.
It is similar to a &lt;function&gt;, but it is only valid for a plot
because it is drawn relative to the plot coordinate system.
Multiple "moving_label" configurations can be provided, each one
with a unique text and a unique set of functions that determine
it's dynamic positioning.
Each "moving_label" can have a "color" attribute (CSS color notation),
and a "weight" attribute. "weight" can be one of "normal" or "bold",
and determines the styling of moving label's text.
Each "moving_label" function should return an object with a 'x'
and 'y properties. Within those functions, all of the parameter
names along with their value are available.
Example (note that "return" statement is missing; it will be automatically
inserted by GST):
&lt;moving_label text="Co" weight="bold" color="red&gt;
&lt;![CDATA[ {'x': -50, 'y': c0};]]&gt;
&lt;/moving_label&gt;
asymptote:
Add a vertical or horizontal asymptote to the graph which will
be dynamically repositioned based on the specified function.
It is similar to the function in that it provides a JavaScript body function
string. This function will be used to calculate the position of the asymptote
relative to the axis specified by the "type" parameter.
Required parameters:
type:
Which axis should the asymptote be plotted against. Available values
are "x" and "y".
Optional parameters:
color:
The color of the line. A valid CSS color string is expected.</pre>
</div>
</div>
</div>
</div>
<div class="section" id="example">
<h2>Example<a class="headerlink" href="#example" title="Permalink to this headline"></a></h2>
<div class="section" id="plotting-sliders-and-inputs">
<h3>Plotting, sliders and inputs<a class="headerlink" href="#plotting-sliders-and-inputs" title="Permalink to this headline"></a></h3>
<div class="highlight-python"><pre>&lt;vertical&gt;
&lt;graphical_slider_tool&gt;
&lt;render&gt;
&lt;h2&gt;Graphic slider tool: full example.&lt;/h2&gt;
&lt;p&gt;
A simple equation
\(
y_1 = 10 \times b \times \frac{sin(a \times x) \times sin(b \times x)}{cos(b \times x) + 10}
\)
can be plotted.
&lt;/p&gt;
&lt;!-- make text and input or slider at the same line --&gt;
&lt;div&gt;
&lt;p style="float:left;"&gt; Currently \(a\) is&lt;/p&gt;
&lt;!-- readonly input for a --&gt;
&lt;span id="a_readonly" style="width:50px; float:left; margin-left:10px;"/&gt;
&lt;/div&gt;
&lt;!-- clear:left will make next text to begin from new line --&gt;
&lt;p style="clear:left"&gt; This one
\(
y_2 = sin(a \times x)
\)
will be overlayed on top.
&lt;/p&gt;
&lt;div&gt;
&lt;p style="float:left;"&gt;Currently \(b\) is &lt;/p&gt;
&lt;textbox var="b" style="width:50px; float:left; margin-left:10px;"/&gt;
&lt;/div&gt;
&lt;div style="clear:left;"&gt;
&lt;p style="float:left;"&gt;To change \(a\) use:&lt;/p&gt;
&lt;slider var="a" style="width:400px;float:left;margin-left:10px;"/&gt;
&lt;/div&gt;
&lt;div style="clear:left;"&gt;
&lt;p style="float:left;"&gt;To change \(b\) use:&lt;/p&gt;
&lt;slider var="b" style="width:400px;float:left;margin-left:10px;"/&gt;
&lt;/div&gt;
&lt;plot style='clear:left;width:600px;padding-top:15px;padding-bottom:20px;'/&gt;
&lt;div style="clear:left;height:50px;"&gt;
&lt;p style="float:left;"&gt;Second input for b:&lt;/p&gt;
&lt;!-- editable input for b --&gt;
&lt;textbox var="b" style="color:red;width:60px;float:left;margin-left:10px;"/&gt;
&lt;/div &gt;
&lt;/render&gt;
&lt;configuration&gt;
&lt;parameters&gt;
&lt;param var="a" min="90" max="120" step="10" initial="100" /&gt;
&lt;param var="b" min="120" max="200" step="2.3" initial="120" /&gt;
&lt;/parameters&gt;
&lt;functions&gt;
&lt;function color="#0000FF" line="false" dot="true" label="\(y_1\)"&gt;
return 10.0 * b * Math.sin(a * x) * Math.sin(b * x) / (Math.cos(b * x) + 10);
&lt;/function&gt;
&lt;function color="red" line="true" dot="false" label="\(y_2\)"&gt;
&lt;!-- works w/o return, if function is single line --&gt;
Math.sin(a * x);
&lt;/function&gt;
&lt;function color="#FFFF00" line="false" dot="false" label="unknown"&gt;
function helperFunc(c1) {
return c1 * c1 - a;
}
return helperFunc(x + 10 * a * b) + Math.sin(a - x);
&lt;/function&gt;
&lt;function output="element" el_id="a_readonly"&gt;a&lt;/function&gt;
&lt;/functions&gt;
&lt;plot&gt;
&lt;xrange&gt;
&lt;min&gt;return 0;&lt;/min&gt;
&lt;!-- works w/o return --&gt;
&lt;max&gt;30&lt;/max&gt;
&lt;/xrange&gt;
&lt;num_points&gt;120&lt;/num_points&gt;
&lt;xticks&gt;0, 3, 30&lt;/xticks&gt;
&lt;yticks&gt;-1.5, 1.5, 13.5&lt;/yticks&gt;
&lt;xunits&gt;\(cm\)&lt;/xunits&gt;
&lt;yunits&gt;\(m\)&lt;/yunits&gt;
&lt;/plot&gt;
&lt;/configuration&gt;
&lt;/graphical_slider_tool&gt;
&lt;/vertical&gt;
</pre>
</div>
</div>
<div class="section" id="update-of-html-elements-no-plotting">
<h3>Update of html elements, no plotting<a class="headerlink" href="#update-of-html-elements-no-plotting" title="Permalink to this headline"></a></h3>
<div class="highlight-python"><pre>&lt;vertical&gt;
&lt;graphical_slider_tool&gt;
&lt;render&gt;
&lt;h2&gt;Graphic slider tool: Output to DOM element.&lt;/h2&gt;
&lt;p&gt;a + b = &lt;span id="answer_span_1"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="clear:both"&gt;
&lt;p style="float:left;margin-right:10px;"&gt;a&lt;/p&gt;
&lt;slider var='a' style="width:400px;float:left;"/&gt;
&lt;textbox var='a' style="width:50px;float:left;margin-left:15px;"/&gt;
&lt;/div&gt;
&lt;div style="clear:both"&gt;
&lt;p style="float:left;margin-right:10px;"&gt;b&lt;/p&gt;
&lt;slider var='b' style="width:400px;float:left;"/&gt;
&lt;textbox var='b' style="width:50px;float:left;margin-left:15px;"/&gt;
&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;
&lt;plot/&gt;
&lt;/render&gt;
&lt;configuration&gt;
&lt;parameters&gt;
&lt;param var="a" min="-10.0" max="10.0" step="0.1" initial="0" /&gt;
&lt;param var="b" min="-10.0" max="10.0" step="0.1" initial="0" /&gt;
&lt;/parameters&gt;
&lt;functions&gt;
&lt;function output="element" el_id="answer_span_1"&gt;
function add(a, b, precision) {
var x = Math.pow(10, precision || 2);
return (Math.round(a * x) + Math.round(b * x)) / x;
}
return add(a, b, 5);
&lt;/function&gt;
&lt;/functions&gt;
&lt;/configuration&gt;
&lt;/graphical_slider_tool&gt;
&lt;/vertical&gt;
</pre>
</div>
</div>
<div class="section" id="circle-with-dynamic-radius">
<h3>Circle with dynamic radius<a class="headerlink" href="#circle-with-dynamic-radius" title="Permalink to this headline"></a></h3>
<div class="highlight-python"><pre>&lt;vertical&gt;
&lt;graphical_slider_tool&gt;
&lt;render&gt;
&lt;h2&gt;Graphic slider tool: Dynamic range and implicit functions.&lt;/h2&gt;
&lt;p&gt;You can make x range (not ticks of x axis) of functions to depend on
parameter value. This can be useful when function domain depends
on parameter.&lt;/p&gt;
&lt;p&gt;Also implicit functons like circle can be plotted as 2 separate
functions of same color.&lt;/p&gt;
&lt;div style="height:50px;"&gt;
&lt;slider var='a' style="width:400px;float:left;"/&gt;
&lt;textbox var='a' style="float:left;width:60px;margin-left:15px;"/&gt;
&lt;/div&gt;
&lt;plot style="margin-top:15px;margin-bottom:15px;"/&gt;
&lt;/render&gt;
&lt;configuration&gt;
&lt;parameters&gt;
&lt;param var="a" min="5" max="25" step="0.5" initial="12.5" /&gt;
&lt;/parameters&gt;
&lt;functions&gt;
&lt;function color="red"&gt;Math.sqrt(a * a - x * x)&lt;/function&gt;
&lt;function color="red"&gt;-Math.sqrt(a * a - x * x)&lt;/function&gt;
&lt;/functions&gt;
&lt;plot&gt;
&lt;xrange&gt;
&lt;!-- dynamic range --&gt;
&lt;min&gt;-a&lt;/min&gt;
&lt;max&gt;a&lt;/max&gt;
&lt;/xrange&gt;
&lt;num_points&gt;1000&lt;/num_points&gt;
&lt;xticks&gt;-30, 6, 30&lt;/xticks&gt;
&lt;yticks&gt;-30, 6, 30&lt;/yticks&gt;
&lt;/plot&gt;
&lt;/configuration&gt;
&lt;/graphical_slider_tool&gt;
&lt;/vertical&gt;
</pre>
</div>
</div>
<div class="section" id="example-of-a-bar-graph">
<h3>Example of a bar graph<a class="headerlink" href="#example-of-a-bar-graph" title="Permalink to this headline"></a></h3>
<div class="highlight-python"><pre>&lt;vertical&gt;
&lt;graphical_slider_tool&gt;
&lt;render&gt;
&lt;h2&gt;Graphic slider tool: Bar graph example.&lt;/h2&gt;
&lt;p&gt;We can request the API to plot us a bar graph.&lt;/p&gt;
&lt;div style="clear:both"&gt;
&lt;p style="width:60px;float:left;"&gt;a&lt;/p&gt;
&lt;slider var='a' style="width:400px;float:left;"/&gt;
&lt;textbox var='a' style="width:50px;float:left;margin-left:15px;"/&gt;
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;p style="width:60px;float:left;"&gt;b&lt;/p&gt;
&lt;slider var='b' style="width:400px;float:left;"/&gt;
&lt;textbox var='b' style="width:50px;float:left;margin-left:15px;"/&gt;
&lt;/div&gt;
&lt;plot style="clear:left;"/&gt;
&lt;/render&gt;
&lt;configuration&gt;
&lt;parameters&gt;
&lt;param var="a" min="-100" max="100" step="5" initial="25" /&gt;
&lt;param var="b" min="-100" max="100" step="5" initial="50" /&gt;
&lt;/parameters&gt;
&lt;functions&gt;
&lt;function bar="true" color="blue" label="Men"&gt;
&lt;![CDATA[if (((x&gt;0.9) &amp;&amp; (x&lt;1.1)) || ((x&gt;4.9) &amp;&amp; (x&lt;5.1))) { return Math.sin(a * 0.01 * Math.PI + 2.952 * x); }
else {return undefined;}]]&gt;
&lt;/function&gt;
&lt;function bar="true" color="red" label="Women"&gt;
&lt;![CDATA[if (((x&gt;1.9) &amp;&amp; (x&lt;2.1)) || ((x&gt;3.9) &amp;&amp; (x&lt;4.1))) { return Math.cos(b * 0.01 * Math.PI + 3.432 * x); }
else {return undefined;}]]&gt;
&lt;/function&gt;
&lt;function bar="true" color="green" label="Other 1"&gt;
&lt;![CDATA[if (((x&gt;1.9) &amp;&amp; (x&lt;2.1)) || ((x&gt;3.9) &amp;&amp; (x&lt;4.1))) { return Math.cos((b - 10 * a) * 0.01 * Math.PI + 3.432 * x); }
else {return undefined;}]]&gt;
&lt;/function&gt;
&lt;function bar="true" color="yellow" label="Other 2"&gt;
&lt;![CDATA[if (((x&gt;1.9) &amp;&amp; (x&lt;2.1)) || ((x&gt;3.9) &amp;&amp; (x&lt;4.1))) { return Math.cos((b + 7 * a) * 0.01 * Math.PI + 3.432 * x); }
else {return undefined;}]]&gt;
&lt;/function&gt;
&lt;/functions&gt;
&lt;plot&gt;
&lt;xrange&gt;&lt;min&gt;1&lt;/min&gt;&lt;max&gt;5&lt;/max&gt;&lt;/xrange&gt;
&lt;num_points&gt;5&lt;/num_points&gt;
&lt;xticks&gt;0, 0.5, 6&lt;/xticks&gt;
&lt;yticks&gt;-1.5, 0.1, 1.5&lt;/yticks&gt;
&lt;xticks_names&gt;
&lt;![CDATA[
{
"1.5": "Single", "4.5": "Married"
}
]]&gt;
&lt;/xticks_names&gt;
&lt;yticks_names&gt;
&lt;![CDATA[
{
"-1.0": "-100%", "-0.5": "-50%", "0.0": "0%", "0.5": "50%", "1.0": "100%"
}
]]&gt;
&lt;/yticks_names&gt;
&lt;bar_width&gt;0.4&lt;/bar_width&gt;
&lt;/plot&gt;
&lt;/configuration&gt;
&lt;/graphical_slider_tool&gt;
&lt;/vertical&gt;
</pre>
</div>
</div>
<div class="section" id="example-of-moving-labels-of-graph">
<h3>Example of moving labels of graph<a class="headerlink" href="#example-of-moving-labels-of-graph" title="Permalink to this headline"></a></h3>
<div class="highlight-python"><pre>&lt;vertical&gt;
&lt;graphical_slider_tool&gt;
&lt;render&gt;
&lt;h1&gt;Graphic slider tool: Dynamic labels.&lt;/h1&gt;
&lt;p&gt;There are two kinds of dynamic lables.
1) Dynamic changing values in graph legends.
2) Dynamic labels, which coordinates depend on parameters &lt;/p&gt;
&lt;p&gt;a: &lt;slider var="a"/&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;b: &lt;slider var="b"/&gt;&lt;/p&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;plot style="width:400px; height:400px;"/&gt;
&lt;/render&gt;
&lt;configuration&gt;
&lt;parameters&gt;
&lt;param var="a" min="-10" max="10" step="1" initial="0" /&gt;
&lt;param var="b" min="0" max="10" step="0.5" initial="5" /&gt;
&lt;/parameters&gt;
&lt;functions&gt;
&lt;function label="Value of a is: dyn_val_1"&gt;a * x + b&lt;/function&gt;
&lt;!-- dynamic values in legend --&gt;
&lt;function output="plot_label" el_id="dyn_val_1"&gt;a&lt;/function&gt;
&lt;/functions&gt;
&lt;plot&gt;
&lt;xrange&gt;&lt;min&gt;0&lt;/min&gt;&lt;max&gt;30&lt;/max&gt;&lt;/xrange&gt;
&lt;num_points&gt;10&lt;/num_points&gt;
&lt;xticks&gt;0, 6, 30&lt;/xticks&gt;
&lt;yticks&gt;-9, 1, 9&lt;/yticks&gt;
&lt;!-- custom labels with coordinates as any function of parameter --&gt;
&lt;moving_label text="Dynam_lbl 1" weight="bold"&gt;
&lt;![CDATA[ {'x': 10, 'y': a};]]&gt;
&lt;/moving_label&gt;
&lt;moving_label text="Dynam lbl 2" weight="bold"&gt;
&lt;![CDATA[ {'x': -6, 'y': b};]]&gt;
&lt;/moving_label&gt;
&lt;/plot&gt;
&lt;/configuration&gt;
&lt;/graphical_slider_tool&gt;
&lt;/vertical&gt;</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../poll_module/poll_module.html" title="Xml format of poll module [xmodule]"
>next</a> |</li>
<li class="right" >
<a href="../drag_and_drop/drag_and_drop_input.html" title="XML format of drag and drop input [inputtypes]"
>previous</a> |</li>
<li><a href="../../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Xml format of poll module [xmodule] &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../../',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="../../index.html" />
<link rel="next" title="Xml format of conditional module [xmodule]" href="../conditional_module/conditional_module.html" />
<link rel="prev" title="XML format of graphical slider tool [xmodule]" href="../graphical_slider_tool/graphical_slider_tool.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../conditional_module/conditional_module.html" title="Xml format of conditional module [xmodule]"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="../graphical_slider_tool/graphical_slider_tool.html" title="XML format of graphical slider tool [xmodule]"
accesskey="P">previous</a> |</li>
<li><a href="../../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Xml format of poll module [xmodule]</a><ul>
<li><a class="reference internal" href="#format-description">Format description</a><ul>
<li><a class="reference internal" href="#poll-question-tag">poll_question tag</a></li>
<li><a class="reference internal" href="#answer-tag">answer tag</a></li>
</ul>
</li>
<li><a class="reference internal" href="#example">Example</a><ul>
<li><a class="reference internal" href="#examples-of-poll">Examples of poll</a></li>
<li><a class="reference internal" href="#examples-of-poll-with-unable-reset-functionality">Examples of poll with unable reset functionality</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="../graphical_slider_tool/graphical_slider_tool.html"
title="previous chapter">XML format of graphical slider tool [xmodule]</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="../conditional_module/conditional_module.html"
title="next chapter">Xml format of conditional module [xmodule]</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../../_sources/course_data_formats/poll_module/poll_module.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-poll_module">
<span id="xml-format-of-poll-module-xmodule"></span><h1>Xml format of poll module [xmodule]<a class="headerlink" href="#module-poll_module" title="Permalink to this headline"></a></h1>
<div class="section" id="format-description">
<h2>Format description<a class="headerlink" href="#format-description" title="Permalink to this headline"></a></h2>
<p>The main tag of Poll module input is:</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;poll_question&gt;</span> ... <span class="nt">&lt;/poll_question&gt;</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">poll_question</span></tt> can include any number of the following tags:
any xml and <tt class="docutils literal"><span class="pre">answer</span></tt> tag. All inner xml, except for <tt class="docutils literal"><span class="pre">answer</span></tt> tags, we call &#8220;question&#8221;.</p>
<div class="section" id="poll-question-tag">
<h3>poll_question tag<a class="headerlink" href="#poll-question-tag" title="Permalink to this headline"></a></h3>
<p>Xmodule for creating poll functionality - voting system. The following attributes can
be specified for this tag:</p>
<div class="highlight-python"><pre>name - Name of xmodule.
[display_name| AUTOGENERATE] - Display name of xmodule. When this attribute is not defined - display name autogenerate with some hash.
[reset | False] - Can reset/revote many time (value = True/False)</pre>
</div>
</div>
<div class="section" id="answer-tag">
<h3>answer tag<a class="headerlink" href="#answer-tag" title="Permalink to this headline"></a></h3>
<p>Define one of the possible answer for poll module. The following attributes can
be specified for this tag:</p>
<div class="highlight-python"><pre>id - unique identifier (using to identify the different answers)</pre>
</div>
<p>Inner text - Display text for answer choice.</p>
</div>
</div>
<div class="section" id="example">
<h2>Example<a class="headerlink" href="#example" title="Permalink to this headline"></a></h2>
<div class="section" id="examples-of-poll">
<h3>Examples of poll<a class="headerlink" href="#examples-of-poll" title="Permalink to this headline"></a></h3>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;poll_question</span> <span class="na">name=</span><span class="s">&quot;second_question&quot;</span> <span class="na">display_name=</span><span class="s">&quot;Second question&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;h3&gt;</span>Age<span class="nt">&lt;/h3&gt;</span>
<span class="nt">&lt;p&gt;</span>How old are you?<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;answer</span> <span class="na">id=</span><span class="s">&quot;less18&quot;</span><span class="nt">&gt;</span><span class="ni">&amp;lt;</span> 18<span class="nt">&lt;/answer&gt;</span>
<span class="nt">&lt;answer</span> <span class="na">id=</span><span class="s">&quot;10_25&quot;</span><span class="nt">&gt;</span>from 10 to 25<span class="nt">&lt;/answer&gt;</span>
<span class="nt">&lt;answer</span> <span class="na">id=</span><span class="s">&quot;more25&quot;</span><span class="nt">&gt;</span><span class="ni">&amp;gt;</span> 25<span class="nt">&lt;/answer&gt;</span>
<span class="nt">&lt;/poll_question&gt;</span>
</pre></div>
</div>
</div>
<div class="section" id="examples-of-poll-with-unable-reset-functionality">
<h3>Examples of poll with unable reset functionality<a class="headerlink" href="#examples-of-poll-with-unable-reset-functionality" title="Permalink to this headline"></a></h3>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;poll_question</span> <span class="na">name=</span><span class="s">&quot;first_question_with_reset&quot;</span> <span class="na">display_name=</span><span class="s">&quot;First question with reset&quot;</span>
<span class="na">reset=</span><span class="s">&quot;True&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;h3&gt;</span>Your gender<span class="nt">&lt;/h3&gt;</span>
<span class="nt">&lt;p&gt;</span>You are man or woman?<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;answer</span> <span class="na">id=</span><span class="s">&quot;man&quot;</span><span class="nt">&gt;</span>Man<span class="nt">&lt;/answer&gt;</span>
<span class="nt">&lt;answer</span> <span class="na">id=</span><span class="s">&quot;woman&quot;</span><span class="nt">&gt;</span>Woman<span class="nt">&lt;/answer&gt;</span>
<span class="nt">&lt;/poll_question&gt;</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../conditional_module/conditional_module.html" title="Xml format of conditional module [xmodule]"
>next</a> |</li>
<li class="right" >
<a href="../graphical_slider_tool/graphical_slider_tool.html" title="XML format of graphical slider tool [xmodule]"
>previous</a> |</li>
<li><a href="../../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Symbolic Response &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="../index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Symbolic Response</a><ul>
<li><a class="reference internal" href="#features">Features</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/course_data_formats/symbolic_response.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="symbolic-response">
<h1>Symbolic Response<a class="headerlink" href="#symbolic-response" title="Permalink to this headline"></a></h1>
<p>This document plans to document features that the current symbolic response
supports. In general it allows the input and validation of math expressions,
up to commutativity and some identities.</p>
<div class="section" id="features">
<h2>Features<a class="headerlink" href="#features" title="Permalink to this headline"></a></h2>
<dl class="docutils">
<dt>This is a partial list of features, to be revised as we go along:</dt>
<dd><ul class="first last">
<li><p class="first">sub and superscripts: an expression following the <tt class="docutils literal"><span class="pre">^</span></tt> character
indicates exponentiation. To use superscripts in variables, the syntax
is <tt class="docutils literal"><span class="pre">b_x__d</span></tt> for the variable <tt class="docutils literal"><span class="pre">b</span></tt> with subscript <tt class="docutils literal"><span class="pre">x</span></tt> and super
<tt class="docutils literal"><span class="pre">d</span></tt>.</p>
<p>An example of a problem:</p>
<div class="highlight-python"><pre>&lt;symbolicresponse expect="a_b^c + b_x__d" size="30"&gt;</pre>
</div>
<blockquote>
<div><dl class="docutils">
<dt>&lt;textline math=&#8221;1&#8221;</dt>
<dd><p class="first last">preprocessorClassName=&#8221;SymbolicMathjaxPreprocessor&#8221;
preprocessorSrc=&#8221;/static/js/capa/symbolic_mathjax_preprocessor.js&#8221;/&gt;</p>
</dd>
</dl>
</div></blockquote>
<p>&lt;/symbolicresponse&gt;</p>
<p>It&#8217;s a bit of a pain to enter that.</p>
</li>
<li><p class="first">The script-style math variant. What would be outputted in latex if you
entered <tt class="docutils literal"><span class="pre">\mathcal{N}</span></tt>. This is used in some variables.</p>
<p>An example:</p>
<div class="highlight-python"><pre>&lt;symbolicresponse expect="scriptN_B + x" size="30"&gt;
&lt;textline math="1"/&gt;
&lt;/symbolicresponse&gt;</pre>
</div>
<p>There is no fancy preprocessing needed, but if you had superscripts or
something, you would need to include that part.</p>
</li>
</ul>
</dd>
</dl>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Index &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="#" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1 id="index">Index</h1>
<div class="genindex-jumpbox">
<a href="#C"><strong>C</strong></a>
| <a href="#D"><strong>D</strong></a>
| <a href="#P"><strong>P</strong></a>
| <a href="#X"><strong>X</strong></a>
</div>
<h2 id="C">C</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="course_data_formats/conditional_module/conditional_module.html#module-conditional_module">conditional_module (module)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="D">D</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="course_data_formats/drag_and_drop/drag_and_drop_input.html#module-drag_and_drop_input">drag_and_drop_input (module)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="P">P</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="course_data_formats/poll_module/poll_module.html#module-poll_module">poll_module (module)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="X">X</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="course_data_formats/graphical_slider_tool/graphical_slider_tool.html#module-xml_format_gst">xml_format_gst (module)</a>
</dt>
</dl></td>
</tr></table>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="#" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>edX Data Documentation &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="#" />
<link rel="next" title="Course XML Tutorial" href="course_data_formats/course_xml.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="course_data_formats/course_xml.html" title="Course XML Tutorial"
accesskey="N">next</a> |</li>
<li><a href="#">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="#">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">edX Data Documentation</a><ul>
<li><a class="reference internal" href="#course-data-formats">Course Data Formats</a><ul>
<li><a class="reference internal" href="#specific-problem-types">Specific Problem Types</a><ul>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#internal-data-formats">Internal Data Formats</a><ul>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
</ul>
<h4>Next topic</h4>
<p class="topless"><a href="course_data_formats/course_xml.html"
title="next chapter">Course XML Tutorial</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/index.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="edx-data-documentation">
<h1>edX Data Documentation<a class="headerlink" href="#edx-data-documentation" title="Permalink to this headline"></a></h1>
<p>The following documents are targetted at those who are working with various data formats consumed and produced by the edX platform &#8211; primarily course authors and those who are conducting research on data in our system. Developer oriented discussion of architecture and strictly internal APIs should be documented elsewhere.</p>
<div class="section" id="course-data-formats">
<h2>Course Data Formats<a class="headerlink" href="#course-data-formats" title="Permalink to this headline"></a></h2>
<p>These are data formats written by people to specify course structure and content. Some of this is abstracted away if you are using the Studio authoring user interface.</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="course_data_formats/course_xml.html">Course XML Tutorial</a><ul>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/course_xml.html#goals">Goals</a></li>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/course_xml.html#introduction">Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/course_xml.html#case-study">Case Study</a></li>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/course_xml.html#tags">Tags</a></li>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/course_xml.html#id1">Policy Files</a></li>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/course_xml.html#static-links">Static links</a></li>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/course_xml.html#tabs">Tabs</a></li>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/course_xml.html#textbooks">Textbooks</a></li>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/course_xml.html#other-file-locations-info-and-about">Other file locations (info and about)</a></li>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/course_xml.html#tips-for-content-developers">Tips for content developers</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="course_data_formats/grading.html">Course Grading</a><ul>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/grading.html#totaling-sections">Totaling sections</a></li>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/grading.html#weighting-problems">Weighting Problems</a></li>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/grading.html#weighting-sections">Weighting Sections</a></li>
<li class="toctree-l2"><a class="reference internal" href="course_data_formats/grading.html#displaying-the-final-grade">Displaying the final grade</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="specific-problem-types">
<h3>Specific Problem Types<a class="headerlink" href="#specific-problem-types" title="Permalink to this headline"></a></h3>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="course_data_formats/drag_and_drop/drag_and_drop_input.html">XML format of drag and drop input [inputtypes]</a></li>
<li class="toctree-l1"><a class="reference internal" href="course_data_formats/graphical_slider_tool/graphical_slider_tool.html">XML format of graphical slider tool [xmodule]</a></li>
<li class="toctree-l1"><a class="reference internal" href="course_data_formats/poll_module/poll_module.html">Xml format of poll module [xmodule]</a></li>
<li class="toctree-l1"><a class="reference internal" href="course_data_formats/conditional_module/conditional_module.html">Xml format of conditional module [xmodule]</a></li>
<li class="toctree-l1"><a class="reference internal" href="course_data_formats/custom_response.html">CustomResponse XML and Python Script</a></li>
</ul>
</div>
</div>
</div>
<div class="section" id="internal-data-formats">
<h2>Internal Data Formats<a class="headerlink" href="#internal-data-formats" title="Permalink to this headline"></a></h2>
<p>These document describe how we store course structure, student state/progress, and events internally. Useful for developers or researchers who interact with our raw data exports.</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="internal_data_formats/sql_schema.html">Student Info and Progress Data</a><ul>
<li class="toctree-l2"><a class="reference internal" href="internal_data_formats/sql_schema.html#user-information">User Information</a></li>
<li class="toctree-l2"><a class="reference internal" href="internal_data_formats/sql_schema.html#courseware-progress">Courseware Progress</a></li>
<li class="toctree-l2"><a class="reference internal" href="internal_data_formats/sql_schema.html#certificates">Certificates</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="internal_data_formats/discussion_data.html">Discussion Forums Data</a><ul>
<li class="toctree-l2"><a class="reference internal" href="internal_data_formats/discussion_data.html#shared-attributes">Shared Attributes</a></li>
<li class="toctree-l2"><a class="reference internal" href="internal_data_formats/discussion_data.html#commentthread">CommentThread</a></li>
<li class="toctree-l2"><a class="reference internal" href="internal_data_formats/discussion_data.html#comment">Comment</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="internal_data_formats/tracking_logs.html">Tracking Logs</a><ul>
<li class="toctree-l2"><a class="reference internal" href="internal_data_formats/tracking_logs.html#common-fields">Common Fields</a></li>
<li class="toctree-l2"><a class="reference internal" href="internal_data_formats/tracking_logs.html#event-sources">Event Sources</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div class="section" id="indices-and-tables">
<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline"></a></h1>
<ul class="simple">
<li><a class="reference internal" href="search.html"><em>Search Page</em></a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="course_data_formats/course_xml.html" title="Course XML Tutorial"
>next</a> |</li>
<li><a href="#">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Discussion Forums Data &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="../index.html" />
<link rel="next" title="Tracking Logs" href="tracking_logs.html" />
<link rel="prev" title="Student Info and Progress Data" href="sql_schema.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="tracking_logs.html" title="Tracking Logs"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="sql_schema.html" title="Student Info and Progress Data"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Discussion Forums Data</a><ul>
<li><a class="reference internal" href="#shared-attributes">Shared Attributes</a><ul>
<li><a class="reference internal" href="#id"><cite>_id</cite></a></li>
<li><a class="reference internal" href="#type"><cite>_type</cite></a></li>
<li><a class="reference internal" href="#anonymous"><cite>anonymous</cite></a></li>
<li><a class="reference internal" href="#anonymous-to-peers"><cite>anonymous_to_peers</cite></a></li>
<li><a class="reference internal" href="#at-position-list"><cite>at_position_list</cite></a></li>
<li><a class="reference internal" href="#author-id"><cite>author_id</cite></a></li>
<li><a class="reference internal" href="#body"><cite>body</cite></a></li>
<li><a class="reference internal" href="#course-id"><cite>course_id</cite></a></li>
<li><a class="reference internal" href="#created-at"><cite>created_at</cite></a></li>
<li><a class="reference internal" href="#updated-at"><cite>updated_at</cite></a></li>
<li><a class="reference internal" href="#votes"><cite>votes</cite></a></li>
</ul>
</li>
<li><a class="reference internal" href="#commentthread">CommentThread</a><ul>
<li><a class="reference internal" href="#closed"><cite>closed</cite></a></li>
<li><a class="reference internal" href="#comment-count"><cite>comment_count</cite></a></li>
<li><a class="reference internal" href="#commentable-id"><cite>commentable_id</cite></a></li>
<li><a class="reference internal" href="#last-activity-at"><cite>last_activity_at</cite></a></li>
<li><a class="reference internal" href="#tags-array"><cite>tags_array</cite></a></li>
<li><a class="reference internal" href="#title"><cite>title</cite></a></li>
</ul>
</li>
<li><a class="reference internal" href="#comment">Comment</a><ul>
<li><a class="reference internal" href="#endorsed"><cite>endorsed</cite></a></li>
<li><a class="reference internal" href="#comment-thread-id"><cite>comment_thread_id</cite></a></li>
<li><a class="reference internal" href="#parent-id"><cite>parent_id</cite></a></li>
<li><a class="reference internal" href="#parent-ids"><cite>parent_ids</cite></a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="sql_schema.html"
title="previous chapter">Student Info and Progress Data</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="tracking_logs.html"
title="next chapter">Tracking Logs</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/internal_data_formats/discussion_data.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="discussion-forums-data">
<h1>Discussion Forums Data<a class="headerlink" href="#discussion-forums-data" title="Permalink to this headline"></a></h1>
<p>Discussions in edX are stored in a MongoDB database as collections of JSON documents.</p>
<p>The primary collection holding all posts and comments written by users is <cite>contents</cite>. There are two types of objects stored here, though they share much of the same structure. A <cite>CommentThread</cite> represents a comment that opens a new thread &#8211; usually a student question of some sort. A <cite>Comment</cite> is a reply in the conversation started by a <cite>CommentThread</cite>.</p>
<div class="section" id="shared-attributes">
<h2>Shared Attributes<a class="headerlink" href="#shared-attributes" title="Permalink to this headline"></a></h2>
<p>The attributes that <cite>Comment</cite> and <cite>CommentThread</cite> objects share are listed below.</p>
<div class="section" id="id">
<h3><cite>_id</cite><a class="headerlink" href="#id" title="Permalink to this headline"></a></h3>
<blockquote>
<div>The 12-byte MongoDB unique ID for this collection. Like all MongoDB IDs, they are monotonically increasing and the first four bytes are a timestamp.</div></blockquote>
</div>
<div class="section" id="type">
<h3><cite>_type</cite><a class="headerlink" href="#type" title="Permalink to this headline"></a></h3>
<blockquote>
<div><cite>CommentThread</cite> or <cite>Comment</cite> depending on the type of object.</div></blockquote>
</div>
<div class="section" id="anonymous">
<h3><cite>anonymous</cite><a class="headerlink" href="#anonymous" title="Permalink to this headline"></a></h3>
<blockquote>
<div>If true, this <cite>Comment</cite> or <cite>CommentThread</cite> will show up as written by anonymous, even to those who have moderator privileges in the forums.</div></blockquote>
</div>
<div class="section" id="anonymous-to-peers">
<h3><cite>anonymous_to_peers</cite><a class="headerlink" href="#anonymous-to-peers" title="Permalink to this headline"></a></h3>
<blockquote>
<div>The idea behind this field was that <cite>anonymous_to_peers = true</cite> would make the the comment appear anonymous to your fellow students, but would allow the course staff to see who you were. However, that was never implemented in the UI, and only <cite>anonymous</cite> is actually used. The <cite>anonymous_to_peers</cite> field is always false.</div></blockquote>
</div>
<div class="section" id="at-position-list">
<h3><cite>at_position_list</cite><a class="headerlink" href="#at-position-list" title="Permalink to this headline"></a></h3>
<blockquote>
<div>No longer used. Child comments (replies) are just sorted by their <cite>created_at</cite> timestamp instead.</div></blockquote>
</div>
<div class="section" id="author-id">
<h3><cite>author_id</cite><a class="headerlink" href="#author-id" title="Permalink to this headline"></a></h3>
<blockquote>
<div>The user who wrote this. Corresponds to the user IDs we store in our MySQL database as <cite>auth_user.id</cite></div></blockquote>
</div>
<div class="section" id="body">
<h3><cite>body</cite><a class="headerlink" href="#body" title="Permalink to this headline"></a></h3>
<blockquote>
<div>Text of the comment in Markdown. UTF-8 encoded.</div></blockquote>
</div>
<div class="section" id="course-id">
<h3><cite>course_id</cite><a class="headerlink" href="#course-id" title="Permalink to this headline"></a></h3>
<blockquote>
<div>The full course_id of the course that this comment was made in, including org and run. This value can be seen in the URL when browsing the courseware section. Example: <cite>BerkeleyX/Stat2.1x/2013_Spring</cite></div></blockquote>
</div>
<div class="section" id="created-at">
<h3><cite>created_at</cite><a class="headerlink" href="#created-at" title="Permalink to this headline"></a></h3>
<blockquote>
<div>Timestamp in UTC. Example: <cite>ISODate(&#8220;2013-02-21T03:03:04.587Z&#8221;)</cite></div></blockquote>
</div>
<div class="section" id="updated-at">
<h3><cite>updated_at</cite><a class="headerlink" href="#updated-at" title="Permalink to this headline"></a></h3>
<blockquote>
<div>Timestamp in UTC. Example: <cite>ISODate(&#8220;2013-02-21T03:03:04.587Z&#8221;)</cite></div></blockquote>
</div>
<div class="section" id="votes">
<h3><cite>votes</cite><a class="headerlink" href="#votes" title="Permalink to this headline"></a></h3>
<blockquote>
<div>Both <cite>CommentThread</cite> and <cite>Comment</cite> objects support voting. <cite>Comment</cite> objects that are replies to other comments still have this attribute, even though there is no way to actually vote on them in the UI. This attribute is a dictionary that has the following inside:</div></blockquote>
<ul class="simple">
<li><cite>up</cite> = list of User IDs that up-voted this comment or thread.</li>
<li><cite>down</cite> = list of User IDs that down-voted this comment or thread (no longer used).</li>
<li><cite>up_count</cite> = total upvotes received.</li>
<li><cite>down_count</cite> = total downvotes received (no longer used).</li>
<li><cite>count</cite> = total votes cast.</li>
<li><cite>point</cite> = net vote, now always equal to <cite>up_count</cite>.</li>
</ul>
<p>A user only has one vote per <cite>Comment</cite> or <cite>CommentThread</cite>. Though it&#8217;s still written to the database, the UI no longer displays an option to downvote anything.</p>
</div>
</div>
<div class="section" id="commentthread">
<h2>CommentThread<a class="headerlink" href="#commentthread" title="Permalink to this headline"></a></h2>
<p>The following fields are specific to <cite>CommentThread</cite> objects. Each thread in the forums is represented by one <cite>CommentThread</cite>.</p>
<div class="section" id="closed">
<h3><cite>closed</cite><a class="headerlink" href="#closed" title="Permalink to this headline"></a></h3>
<blockquote>
<div>If true, this thread was closed by a forum moderator/admin.</div></blockquote>
</div>
<div class="section" id="comment-count">
<h3><cite>comment_count</cite><a class="headerlink" href="#comment-count" title="Permalink to this headline"></a></h3>
<blockquote>
<div><p>The number of comment replies in this thread. This includes all replies to replies, but does not include the original comment that started the thread. So if we had:</p>
<div class="highlight-python"><pre>CommentThread: "What's a good breakfast?"
* Comment: "Just eat cereal!"
* Comment: "Try a Loco Moco, it's amazing!"
* Comment: "A Loco Moco? Only if you want a heart attack!"
* Comment: "But it's worth it! Just get a spam musubi on the side."</pre>
</div>
<p>In that exchange, the <cite>comment_count</cite> for the <cite>CommentThread</cite> is <cite>4</cite>.</p>
</div></blockquote>
</div>
<div class="section" id="commentable-id">
<h3><cite>commentable_id</cite><a class="headerlink" href="#commentable-id" title="Permalink to this headline"></a></h3>
<blockquote>
<div>We can attach a discussion to any piece of content in the course, or to top level categories like &#8220;General&#8221; and &#8220;Troubleshooting&#8221;. When the <cite>commentable_id</cite> is a high level category, it&#8217;s specified in the course&#8217;s policy file. When it&#8217;s a specific content piece (e.g. <cite>600x_l5_p8</cite>, meaning 6.00x, Lecture Sequence 5, Problem 8), it&#8217;s taken from a discussion module in the course.</div></blockquote>
</div>
<div class="section" id="last-activity-at">
<h3><cite>last_activity_at</cite><a class="headerlink" href="#last-activity-at" title="Permalink to this headline"></a></h3>
<blockquote>
<div>Timestamp in UTC indicating the last time there was activity in the thread (new posts, edits, etc). Closing the thread does not affect the value in this field.</div></blockquote>
</div>
<div class="section" id="tags-array">
<h3><cite>tags_array</cite><a class="headerlink" href="#tags-array" title="Permalink to this headline"></a></h3>
<blockquote>
<div>Meant to be a list of tags that were user definable, but no longer used.</div></blockquote>
</div>
<div class="section" id="title">
<h3><cite>title</cite><a class="headerlink" href="#title" title="Permalink to this headline"></a></h3>
<blockquote>
<div>Title of the thread, UTF-8 string.</div></blockquote>
</div>
</div>
<div class="section" id="comment">
<h2>Comment<a class="headerlink" href="#comment" title="Permalink to this headline"></a></h2>
<p>The following fields are specific to <cite>Comment</cite> objects. A <cite>Comment</cite> is a reply to a <cite>CommentThread</cite> (so an answer to the question), or a reply to another <cite>Comment</cite> (a comment about somebody&#8217;s answer). It used to be the case that <cite>Comment</cite> replies could nest much more deeply, but we later capped it at just these three levels (question, answer, comment) much in the way that StackOverflow does.</p>
<div class="section" id="endorsed">
<h3><cite>endorsed</cite><a class="headerlink" href="#endorsed" title="Permalink to this headline"></a></h3>
<blockquote>
<div>Boolean value, true if a forum moderator or instructor has marked that this <cite>Comment</cite> is a correct answer for whatever question the thread was asking. Exists for <cite>Comments</cite> that are replies to other <cite>Comments</cite>, but in that case <cite>endorsed</cite> is always false because there&#8217;s no way to endorse such comments through the UI.</div></blockquote>
</div>
<div class="section" id="comment-thread-id">
<h3><cite>comment_thread_id</cite><a class="headerlink" href="#comment-thread-id" title="Permalink to this headline"></a></h3>
<blockquote>
<div>What <cite>CommentThread</cite> are we a part of? All <cite>Comment</cite> objects have this.</div></blockquote>
</div>
<div class="section" id="parent-id">
<h3><cite>parent_id</cite><a class="headerlink" href="#parent-id" title="Permalink to this headline"></a></h3>
<blockquote>
<div>The <cite>parent_id</cite> is the <cite>_id</cite> of the <cite>Comment</cite> that this comment was made in reply to. Note that this only occurs in a <cite>Comment</cite> that is a reply to another <cite>Comment</cite>; it does not appear in a <cite>Comment</cite> that is a reply to a <cite>CommentThread</cite>.</div></blockquote>
</div>
<div class="section" id="parent-ids">
<h3><cite>parent_ids</cite><a class="headerlink" href="#parent-ids" title="Permalink to this headline"></a></h3>
<blockquote>
<div>The <cite>parent_ids</cite> attribute appears in all <cite>Comment</cite> objects, and contains the <cite>_id</cite> of all ancestor comments. Since the UI now prevents comments from being nested more than one layer deep, it will only ever have at most one element in it. If a <cite>Comment</cite> has no parent, it&#8217;s an empty list.</div></blockquote>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="tracking_logs.html" title="Tracking Logs"
>next</a> |</li>
<li class="right" >
<a href="sql_schema.html" title="Student Info and Progress Data"
>previous</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Student Info and Progress Data &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="../index.html" />
<link rel="next" title="Discussion Forums Data" href="discussion_data.html" />
<link rel="prev" title="CustomResponse XML and Python Script" href="../course_data_formats/custom_response.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="discussion_data.html" title="Discussion Forums Data"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="../course_data_formats/custom_response.html" title="CustomResponse XML and Python Script"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Student Info and Progress Data</a><ul>
<li><a class="reference internal" href="#user-information">User Information</a><ul>
<li><a class="reference internal" href="#auth-user"><cite>auth_user</cite></a><ul>
<li><a class="reference internal" href="#id"><cite>id</cite></a></li>
<li><a class="reference internal" href="#username"><cite>username</cite></a></li>
<li><a class="reference internal" href="#first-name"><cite>first_name</cite></a></li>
<li><a class="reference internal" href="#last-name"><cite>last_name</cite></a></li>
<li><a class="reference internal" href="#email"><cite>email</cite></a></li>
<li><a class="reference internal" href="#password"><cite>password</cite></a></li>
<li><a class="reference internal" href="#is-staff"><cite>is_staff</cite></a></li>
<li><a class="reference internal" href="#is-active"><cite>is_active</cite></a></li>
<li><a class="reference internal" href="#is-superuser"><cite>is_superuser</cite></a></li>
<li><a class="reference internal" href="#last-login"><cite>last_login</cite></a></li>
<li><a class="reference internal" href="#date-joined"><cite>date_joined</cite></a></li>
<li><a class="reference internal" href="#obsolete-fields"><cite>(obsolete fields)</cite></a></li>
</ul>
</li>
<li><a class="reference internal" href="#auth-userprofile"><cite>auth_userprofile</cite></a><ul>
<li><a class="reference internal" href="#id1"><cite>id</cite></a></li>
<li><a class="reference internal" href="#user-id"><cite>user_id</cite></a></li>
<li><a class="reference internal" href="#name"><cite>name</cite></a></li>
<li><a class="reference internal" href="#language"><cite>language</cite></a></li>
<li><a class="reference internal" href="#location"><cite>location</cite></a></li>
<li><a class="reference internal" href="#meta"><cite>meta</cite></a></li>
<li><a class="reference internal" href="#courseware"><cite>courseware</cite></a></li>
<li><a class="reference internal" href="#gender"><cite>gender</cite></a></li>
<li><a class="reference internal" href="#mailing-address"><cite>mailing_address</cite></a></li>
<li><a class="reference internal" href="#year-of-birth"><cite>year_of_birth</cite></a></li>
<li><a class="reference internal" href="#level-of-education"><cite>level_of_education</cite></a></li>
<li><a class="reference internal" href="#goals"><cite>goals</cite></a></li>
<li><a class="reference internal" href="#allow-certificate"><cite>allow_certificate</cite></a></li>
</ul>
</li>
<li><a class="reference internal" href="#student-courseenrollment"><cite>student_courseenrollment</cite></a><ul>
<li><a class="reference internal" href="#id2"><cite>id</cite></a></li>
<li><a class="reference internal" href="#id3"><cite>user_id</cite></a></li>
<li><a class="reference internal" href="#course-id"><cite>course_id</cite></a></li>
<li><a class="reference internal" href="#created"><cite>created</cite></a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#courseware-progress">Courseware Progress</a><ul>
<li><a class="reference internal" href="#courseware-studentmodule"><cite>courseware_studentmodule</cite></a><ul>
<li><a class="reference internal" href="#id4"><cite>id</cite></a></li>
<li><a class="reference internal" href="#module-type"><cite>module_type</cite></a></li>
<li><a class="reference internal" href="#module-id"><cite>module_id</cite></a></li>
<li><a class="reference internal" href="#student-id"><cite>student_id</cite></a></li>
<li><a class="reference internal" href="#state"><cite>state</cite></a></li>
<li><a class="reference internal" href="#grade"><cite>grade</cite></a></li>
<li><a class="reference internal" href="#id5"><cite>created</cite></a></li>
<li><a class="reference internal" href="#modified"><cite>modified</cite></a></li>
<li><a class="reference internal" href="#max-grade"><cite>max_grade</cite></a></li>
<li><a class="reference internal" href="#done"><cite>done</cite></a></li>
<li><a class="reference internal" href="#id6"><cite>course_id</cite></a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#certificates">Certificates</a><ul>
<li><a class="reference internal" href="#certificates-generatedcertificate"><cite>certificates_generatedcertificate</cite></a><ul>
<li><a class="reference internal" href="#user-id-course-id"><cite>user_id</cite>, <cite>course_id</cite></a></li>
<li><a class="reference internal" href="#status"><cite>status</cite></a></li>
<li><a class="reference internal" href="#download-url"><cite>download_url</cite></a></li>
<li><a class="reference internal" href="#download-uuid-verify-uuid"><cite>download_uuid</cite>, <cite>verify_uuid</cite></a></li>
<li><a class="reference internal" href="#distinction"><cite>distinction</cite></a></li>
<li><a class="reference internal" href="#id7"><cite>name</cite></a></li>
<li><a class="reference internal" href="#id8"><cite>grade</cite></a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="../course_data_formats/custom_response.html"
title="previous chapter">CustomResponse XML and Python Script</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="discussion_data.html"
title="next chapter">Discussion Forums Data</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/internal_data_formats/sql_schema.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="student-info-and-progress-data">
<h1>Student Info and Progress Data<a class="headerlink" href="#student-info-and-progress-data" title="Permalink to this headline"></a></h1>
<p>The following sections detail how edX stores student state data internally, and is useful for developers and researchers who are examining database exports. This information includes demographic information collected at signup, course enrollment, course progress, and certificate status.</p>
<p>Conventions to keep in mind:</p>
<ul class="simple">
<li>We currently use MySQL 5.1 with InnoDB tables</li>
<li>All strings are stored as UTF-8.</li>
<li>All datetimes are stored as UTC.</li>
<li>Tables that are built into the Django framework are not documented here unless we use them in unconventional ways.</li>
</ul>
<p>All of our tables will be described below, first in summary form with field types and constraints, and then with a detailed explanation of each field. For those not familiar with the MySQL schema terminology in the table summaries:</p>
<dl class="docutils">
<dt><cite>Type</cite></dt>
<dd><p class="first">This is the kind of data it is, along with the size of the field. When a numeric field has a length specified, it just means that&#8217;s how many digits we want displayed &#8211; it has no affect on the number of bytes used.</p>
<table border="1" class="last docutils">
<colgroup>
<col width="11%" />
<col width="89%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Value</th>
<th class="head">Meaning</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><cite>int</cite></td>
<td>4 byte integer.</td>
</tr>
<tr class="row-odd"><td><cite>smallint</cite></td>
<td>2 byte integer, sometimes used for enumerated values.</td>
</tr>
<tr class="row-even"><td><cite>tinyint</cite></td>
<td>1 byte integer, but usually just used to indicate a boolean field with 0 = False and 1 = True.</td>
</tr>
<tr class="row-odd"><td><cite>varchar</cite></td>
<td>String, typically short and indexable. The length is the number of chars, not bytes (so unicode friendly).</td>
</tr>
<tr class="row-even"><td><cite>longtext</cite></td>
<td>A long block of text, usually not indexed.</td>
</tr>
<tr class="row-odd"><td><cite>date</cite></td>
<td>Date</td>
</tr>
<tr class="row-even"><td><cite>datetime</cite></td>
<td>Datetime in UTC, precision in seconds.</td>
</tr>
</tbody>
</table>
</dd>
</dl>
<p><cite>Null</cite></p>
<blockquote>
<div><table border="1" class="docutils">
<colgroup>
<col width="11%" />
<col width="89%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Value</th>
<th class="head">Meaning</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><cite>YES</cite></td>
<td><cite>NULL</cite> values are allowed</td>
</tr>
<tr class="row-odd"><td><cite>NO</cite></td>
<td><cite>NULL</cite> values are not allowed</td>
</tr>
</tbody>
</table>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Django often just places blank strings instead of NULL when it wants to indicate a text value is optional. This is used more meaningful for numeric and date fields.</p>
</div>
</div></blockquote>
<dl class="docutils">
<dt><cite>Key</cite></dt>
<dd><table border="1" class="first last docutils">
<colgroup>
<col width="11%" />
<col width="89%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Value</th>
<th class="head">Meaning</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><cite>PRI</cite></td>
<td>Primary key for the table, usually named <cite>id</cite>, unique</td>
</tr>
<tr class="row-odd"><td><cite>UNI</cite></td>
<td>Unique</td>
</tr>
<tr class="row-even"><td><cite>MUL</cite></td>
<td>Indexed for fast lookup, but the same value can appear multiple times. A Unique index that allows <cite>NULL</cite> can also show up as <cite>MUL</cite>.</td>
</tr>
</tbody>
</table>
</dd>
</dl>
<div class="section" id="user-information">
<h2>User Information<a class="headerlink" href="#user-information" title="Permalink to this headline"></a></h2>
<div class="section" id="auth-user">
<h3><cite>auth_user</cite><a class="headerlink" href="#auth-user" title="Permalink to this headline"></a></h3>
<p>The <cite>auth_user</cite> table is built into the Django web framework that we use. It holds generic information necessary for basic login and permissions information. It has the following fields:</p>
<div class="highlight-python"><pre>+------------------------------+--------------+------+-----+
| Field | Type | Null | Key |
+------------------------------+--------------+------+-----+
| id | int(11) | NO | PRI |
| username | varchar(30) | NO | UNI |
| first_name | varchar(30) | NO | | # Never used
| last_name | varchar(30) | NO | | # Never used
| email | varchar(75) | NO | UNI |
| password | varchar(128) | NO | |
| is_staff | tinyint(1) | NO | |
| is_active | tinyint(1) | NO | |
| is_superuser | tinyint(1) | NO | |
| last_login | datetime | NO | |
| date_joined | datetime | NO | |
| status | varchar(2) | NO | | # No longer used
| email_key | varchar(32) | YES | | # No longer used
| avatar_type | varchar(1) | NO | | # No longer used
| country | varchar(2) | NO | | # No longer used
| show_country | tinyint(1) | NO | | # No longer used
| date_of_birth | date | YES | | # No longer used
| interesting_tags | longtext | NO | | # No longer used
| ignored_tags | longtext | NO | | # No longer used
| email_tag_filter_strategy | smallint(6) | NO | | # No longer used
| display_tag_filter_strategy | smallint(6) | NO | | # No longer used
| consecutive_days_visit_count | int(11) | NO | | # No longer used
+------------------------------+--------------+------+-----+</pre>
</div>
<div class="section" id="id">
<h4><cite>id</cite><a class="headerlink" href="#id" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Primary key, and the value typically used in URLs that reference the user. A user has the same value for <cite>id</cite> here as they do in the MongoDB database&#8217;s users collection. Foreign keys referencing <cite>auth_user.id</cite> will often be named <cite>user_id</cite>, but are sometimes named <cite>student_id</cite>.</div></blockquote>
</div>
<div class="section" id="username">
<h4><cite>username</cite><a class="headerlink" href="#username" title="Permalink to this headline"></a></h4>
<blockquote>
<div>The unique username for a user in our system. It may contain alphanumeric, _, &#64;, +, . and - characters. The username is the only information that the students give about themselves that we currently expose to other students. We have never allowed people to change their usernames so far, but that&#8217;s not something we guarantee going forward.</div></blockquote>
</div>
<div class="section" id="first-name">
<h4><cite>first_name</cite><a class="headerlink" href="#first-name" title="Permalink to this headline"></a></h4>
<blockquote>
<div><div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Not used; we store a user&#8217;s full name in <cite>auth_userprofile.name</cite> instead.</p>
</div>
</div></blockquote>
</div>
<div class="section" id="last-name">
<h4><cite>last_name</cite><a class="headerlink" href="#last-name" title="Permalink to this headline"></a></h4>
<blockquote>
<div><div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Not used; we store a user&#8217;s full name in <cite>auth_userprofile.name</cite> instead.</p>
</div>
</div></blockquote>
</div>
<div class="section" id="email">
<h4><cite>email</cite><a class="headerlink" href="#email" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Their email address. While Django by default makes this optional, we make it required, since it&#8217;s the primary mechanism through which people log in. Must be unique to each user. Never shown to other users.</div></blockquote>
</div>
<div class="section" id="password">
<h4><cite>password</cite><a class="headerlink" href="#password" title="Permalink to this headline"></a></h4>
<blockquote>
<div>A hashed version of the user&#8217;s password. Depending on when the password was last set, this will either be a SHA1 hash or PBKDF2 with SHA256 (Django 1.3 uses the former and 1.4 the latter).</div></blockquote>
</div>
<div class="section" id="is-staff">
<h4><cite>is_staff</cite><a class="headerlink" href="#is-staff" title="Permalink to this headline"></a></h4>
<blockquote>
<div><p>This value is <cite>1</cite> if the user is a staff member <em>of edX</em> with corresponding elevated privileges that cut across courses. It does not indicate that the person is a member of the course staff for any given course. Generally, users with this flag set to 1 are either edX program managers responsible for course delivery, or edX developers who need access for testing and debugging purposes. People who have <cite>is_staff = 1</cite> get instructor privileges on all courses, along with having additional debug information show up in the instructor tab.</p>
<p>Note that this designation has no bearing with a user&#8217;s role in the forums, and confers no elevated privileges there.</p>
<p>Most users have a <cite>0</cite> for this value.</p>
</div></blockquote>
</div>
<div class="section" id="is-active">
<h4><cite>is_active</cite><a class="headerlink" href="#is-active" title="Permalink to this headline"></a></h4>
<blockquote>
<div><p>This value is <cite>1</cite> if the user has clicked on the activation link that was sent to them when they created their account, and <cite>0</cite> otherwise. Users who have <cite>is_active = 0</cite> generally cannot log into the system. However, when users first create their account, they are automatically logged in even though they are not active. This is to let them experience the site immediately without having to check their email. They just get a little banner at the top of their dashboard reminding them to check their email and activate their account when they have time. If they log out, they won&#8217;t be able to log back in again until they&#8217;ve activated. However, because our sessions last a long time, it is theoretically possible for someone to use the site as a student for days without being &#8220;active&#8221;.</p>
<p>Once <cite>is_active</cite> is set to <cite>1</cite>, the only circumstance where it would be set back to <cite>0</cite> would be if we decide to ban the user (which is very rare, manual operation).</p>
</div></blockquote>
</div>
<div class="section" id="is-superuser">
<h4><cite>is_superuser</cite><a class="headerlink" href="#is-superuser" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Value is <cite>1</cite> if the user has admin privileges. Only the earliest developers of the system have this set to <cite>1</cite>, and it&#8217;s no longer really used in the codebase. Set to 0 for almost everybody.</div></blockquote>
</div>
<div class="section" id="last-login">
<h4><cite>last_login</cite><a class="headerlink" href="#last-login" title="Permalink to this headline"></a></h4>
<blockquote>
<div>A datetime of the user&#8217;s last login. Should not be used as a proxy for activity, since people can use the site all the time and go days between logging in and out.</div></blockquote>
</div>
<div class="section" id="date-joined">
<h4><cite>date_joined</cite><a class="headerlink" href="#date-joined" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Date that the account was created (NOT when it was activated).</div></blockquote>
</div>
<div class="section" id="obsolete-fields">
<h4><cite>(obsolete fields)</cite><a class="headerlink" href="#obsolete-fields" title="Permalink to this headline"></a></h4>
<blockquote>
<div><p>All the following fields were added by an application called Askbot, a discussion forum package that is no longer part of the system:</p>
<ul class="simple">
<li><cite>status</cite></li>
<li><cite>email_key</cite></li>
<li><cite>avatar_type</cite></li>
<li><cite>country</cite></li>
<li><cite>show_country</cite></li>
<li><cite>date_of_birth</cite></li>
<li><cite>interesting_tags</cite></li>
<li><cite>ignored_tags</cite></li>
<li><cite>email_tag_filter_strategy</cite></li>
<li><cite>display_tag_filter_strategy</cite></li>
<li><cite>consecutive_days_visit_count</cite></li>
</ul>
<p>Only users who were part of the prototype 6.002x course run in the Spring of 2012 would have any information in these fields. Even with those users, most of this information was never collected. Only the fields that are automatically generated have any values in them, such as tag settings.</p>
<p>These fields are completely unrelated to the discussion forums we currently use, and will eventually be dropped from this table.</p>
</div></blockquote>
</div>
</div>
<div class="section" id="auth-userprofile">
<h3><cite>auth_userprofile</cite><a class="headerlink" href="#auth-userprofile" title="Permalink to this headline"></a></h3>
<p>The <cite>auth_userprofile</cite> table is mostly used to store user demographic information collected during the signup process. We also use it to store certain additional metadata relating to certificates. Every row in this table corresponds to one row in <cite>auth_user</cite>:</p>
<div class="highlight-python"><pre>+--------------------+--------------+------+-----+
| Field | Type | Null | Key |
+--------------------+--------------+------+-----+
| id | int(11) | NO | PRI |
| user_id | int(11) | NO | UNI |
| name | varchar(255) | NO | MUL |
| language | varchar(255) | NO | MUL | # Prototype course users only
| location | varchar(255) | NO | MUL | # Prototype course users only
| meta | longtext | NO | |
| courseware | varchar(255) | NO | | # No longer used
| gender | varchar(6) | YES | MUL | # Only users signed up after prototype
| mailing_address | longtext | YES | | # Only users signed up after prototype
| year_of_birth | int(11) | YES | MUL | # Only users signed up after prototype
| level_of_education | varchar(6) | YES | MUL | # Only users signed up after prototype
| goals | longtext | YES | | # Only users signed up after prototype
| allow_certificate | tinyint(1) | NO | |
+--------------------+--------------+------+-----+</pre>
</div>
<p>There is an important split in demographic data gathered for the students who signed up during the MITx prototype phase in the spring of 2012, and those that signed up afterwards.</p>
<div class="section" id="id1">
<h4><cite>id</cite><a class="headerlink" href="#id1" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Primary key, not referenced anywhere else.</div></blockquote>
</div>
<div class="section" id="user-id">
<h4><cite>user_id</cite><a class="headerlink" href="#user-id" title="Permalink to this headline"></a></h4>
<blockquote>
<div>A foreign key that maps to <cite>auth_user.id</cite>.</div></blockquote>
</div>
<div class="section" id="name">
<h4><cite>name</cite><a class="headerlink" href="#name" title="Permalink to this headline"></a></h4>
<blockquote>
<div><p>String for a user&#8217;s full name. We make no constraints on language or breakdown into first/last name. The names are never shown to other students. Foreign students usually enter a romanized version of their names, but not always.</p>
<p>It used to be our policy to require manual approval of name changes to guard the integrity of the certificates. Students would submit a name change request and someone from the team would approve or reject as appropriate. Later, we decided to allow the name changes to take place automatically, but to log previous names in the <cite>meta</cite> field.</p>
</div></blockquote>
</div>
<div class="section" id="language">
<h4><cite>language</cite><a class="headerlink" href="#language" title="Permalink to this headline"></a></h4>
<blockquote>
<div>User&#8217;s preferred language, asked during the sign up process for the 6.002x prototype course given in the Spring of 2012. This information stopped being collected after the transition from MITx to edX happened, but we never removed the values from our first group of students. Sometimes written in those languages.</div></blockquote>
</div>
<div class="section" id="location">
<h4><cite>location</cite><a class="headerlink" href="#location" title="Permalink to this headline"></a></h4>
<blockquote>
<div>User&#8217;s location, asked during the sign up process for the 6.002x prototype course given in the Spring of 2012. We weren&#8217;t specific, so people tended to put the city they were in, though some just specified their country and some got as specific as their street address. Again, sometimes romanized and sometimes written in their native language. Like <cite>language</cite>, we stopped collecting this field when we transitioned from MITx to edX, so it&#8217;s only available for our first batch of students.</div></blockquote>
</div>
<div class="section" id="meta">
<h4><cite>meta</cite><a class="headerlink" href="#meta" title="Permalink to this headline"></a></h4>
<blockquote>
<div><p>An optional, freeform text field that stores JSON data. This was a hack to allow us to associate arbitrary metadata with a user. An example of the JSON that can be stored here is:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="p">{</span>
<span class="s">&quot;old_names&quot;</span> <span class="p">:</span> <span class="p">[</span>
<span class="p">[</span><span class="s">&quot;David Ormsbee&quot;</span><span class="p">,</span> <span class="s">&quot;I want to add my middle name as well.&quot;</span><span class="p">,</span> <span class="s">&quot;2012-11-15T17:28:12.658126&quot;</span><span class="p">],</span>
<span class="p">[</span><span class="s">&quot;Dave Ormsbee&quot;</span><span class="p">,</span> <span class="s">&quot;Dave&#39;s too informal for a certificate.&quot;</span><span class="p">,</span> <span class="s">&quot;2013-02-07T11:15:46.524331&quot;</span><span class="p">]</span>
<span class="p">],</span>
<span class="s">&quot;old_emails&quot;</span> <span class="p">:</span> <span class="p">[[</span><span class="s">&quot;dormsbee@mitx.mit.edu&quot;</span><span class="p">,</span> <span class="s">&quot;2012-10-18T15:21:41.916389&quot;</span><span class="p">]],</span>
<span class="s">&quot;6002x_exit_response&quot;</span> <span class="p">:</span> <span class="p">{</span>
<span class="s">&quot;rating&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s">&quot;6&quot;</span><span class="p">],</span>
<span class="s">&quot;teach_ee&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s">&quot;I do not teach EE.&quot;</span><span class="p">],</span>
<span class="s">&quot;improvement_textbook&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s">&quot;I&#39;d like to get the full PDF.&quot;</span><span class="p">],</span>
<span class="s">&quot;future_offerings&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s">&quot;true&quot;</span><span class="p">],</span>
<span class="s">&quot;university_comparison&quot;</span><span class="p">:</span>
<span class="p">[</span><span class="s">&quot;This course was &lt;strong&gt;on the same level&lt;/strong&gt; as the university class.&quot;</span><span class="p">],</span>
<span class="s">&quot;improvement_lectures&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s">&quot;More PowerPoint!&quot;</span><span class="p">],</span>
<span class="s">&quot;highest_degree&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s">&quot;Bachelor&#39;s degree.&quot;</span><span class="p">],</span>
<span class="s">&quot;future_classes&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s">&quot;true&quot;</span><span class="p">],</span>
<span class="s">&quot;future_updates&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s">&quot;true&quot;</span><span class="p">],</span>
<span class="s">&quot;favorite_parts&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s">&quot;Releases, bug fixes, and askbot.&quot;</span><span class="p">]</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The following are details about this metadata. Please note that the fields described below are found as JSON attributes <em>inside</em> the <cite>meta</cite> field, and are <em>not</em> separate database fields of their own.</p>
<dl class="docutils">
<dt><cite>old_names</cite></dt>
<dd><p class="first">A list of the previous names this user had, and the timestamps at which they submitted a request to change those names. These name change request submissions used to require a staff member to approve it before the name change took effect. This is no longer the case, though we still record their previous names.</p>
<p>Note that the value stored for each entry is the name they had, not the name they requested to get changed to. People often changed their names as the time for certificate generation approached, to replace nicknames with their actual names or correct spelling/punctuation errors.</p>
<p class="last">The timestamps are UTC, like all datetimes stored in our system.</p>
</dd>
<dt><cite>old_emails</cite></dt>
<dd><p class="first">A list of previous emails this user had, with timestamps of when they changed them, in a format similar to <cite>old_names</cite>. There was never an approval process for this.</p>
<p class="last">The timestamps are UTC, like all datetimes stored in our system.</p>
</dd>
<dt><cite>6002x_exit_response</cite></dt>
<dd>Answers to a survey that was sent to students after the prototype 6.002x course in the Spring of 2012. The questions and number of questions were randomly selected to measure how much survey length affected response rate. Only students from this course have this field.</dd>
</dl>
</div></blockquote>
</div>
<div class="section" id="courseware">
<h4><cite>courseware</cite><a class="headerlink" href="#courseware" title="Permalink to this headline"></a></h4>
<blockquote>
<div>This can be ignored. At one point, it was part of a way to do A/B tests, but it has not been used for anything meaningful since the conclusion of the prototype course in the spring of 2012.</div></blockquote>
</div>
<div class="section" id="gender">
<h4><cite>gender</cite><a class="headerlink" href="#gender" title="Permalink to this headline"></a></h4>
<blockquote>
<div><p>Dropdown field collected during student signup. We only started collecting this information after the transition from MITx to edX, so prototype course students will have <cite>NULL</cite> for this field.</p>
<table border="1" class="docutils">
<colgroup>
<col width="11%" />
<col width="89%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Value</th>
<th class="head">Meaning</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><cite>NULL</cite></td>
<td>This student signed up before this information was collected</td>
</tr>
<tr class="row-odd"><td><cite>&#8216;&#8217;</cite> (blank)</td>
<td>User did not specify gender</td>
</tr>
<tr class="row-even"><td><cite>&#8216;f&#8217;</cite></td>
<td>Female</td>
</tr>
<tr class="row-odd"><td><cite>&#8216;m&#8217;</cite></td>
<td>Male</td>
</tr>
<tr class="row-even"><td><cite>&#8216;o&#8217;</cite></td>
<td>Other</td>
</tr>
</tbody>
</table>
</div></blockquote>
</div>
<div class="section" id="mailing-address">
<h4><cite>mailing_address</cite><a class="headerlink" href="#mailing-address" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Text field collected during student signup. We only started collecting this information after the transition from MITx to edX, so prototype course students will have <cite>NULL</cite> for this field. Students who elected not to enter anything will have a blank string.</div></blockquote>
</div>
<div class="section" id="year-of-birth">
<h4><cite>year_of_birth</cite><a class="headerlink" href="#year-of-birth" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Dropdown field collected during student signup. We only started collecting this information after the transition from MITx to edX, so prototype course students will have <cite>NULL</cite> for this field. Students who decided not to fill this in will also have NULL.</div></blockquote>
</div>
<div class="section" id="level-of-education">
<h4><cite>level_of_education</cite><a class="headerlink" href="#level-of-education" title="Permalink to this headline"></a></h4>
<blockquote>
<div><p>Dropdown field collected during student signup. We only started collecting this information after the transition from MITx to edX, so prototype course students will have <cite>NULL</cite> for this field.</p>
<table border="1" class="docutils">
<colgroup>
<col width="11%" />
<col width="89%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Value</th>
<th class="head">Meaning</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><cite>NULL</cite></td>
<td>This student signed up before this information was collected</td>
</tr>
<tr class="row-odd"><td><cite>&#8216;&#8217;</cite> (blank)</td>
<td>User did not specify level of education.</td>
</tr>
<tr class="row-even"><td><cite>&#8216;p&#8217;</cite></td>
<td>Doctorate</td>
</tr>
<tr class="row-odd"><td><cite>&#8216;p_se&#8217;</cite></td>
<td>Doctorate in science or engineering (no longer used)</td>
</tr>
<tr class="row-even"><td><cite>&#8216;p_oth&#8217;</cite></td>
<td>Doctorate in another field (no longer used)</td>
</tr>
<tr class="row-odd"><td><cite>&#8216;m&#8217;</cite></td>
<td>Master&#8217;s or professional degree</td>
</tr>
<tr class="row-even"><td><cite>&#8216;b&#8217;</cite></td>
<td>Bachelor&#8217;s degree</td>
</tr>
<tr class="row-odd"><td><cite>&#8216;a&#8217;</cite></td>
<td>Associate&#8217;s degree</td>
</tr>
<tr class="row-even"><td><cite>&#8216;hs&#8217;</cite></td>
<td>Secondary/high school</td>
</tr>
<tr class="row-odd"><td><cite>&#8216;jhs&#8217;</cite></td>
<td>Junior secondary/junior high/middle school</td>
</tr>
<tr class="row-even"><td><cite>&#8216;el&#8217;</cite></td>
<td>Elementary/primary school</td>
</tr>
<tr class="row-odd"><td><cite>&#8216;none&#8217;</cite></td>
<td>None</td>
</tr>
<tr class="row-even"><td><cite>&#8216;other&#8217;</cite></td>
<td>Other</td>
</tr>
</tbody>
</table>
</div></blockquote>
</div>
<div class="section" id="goals">
<h4><cite>goals</cite><a class="headerlink" href="#goals" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Text field collected during student signup in response to the prompt, &#8220;Goals in signing up for edX&#8221;. We only started collecting this information after the transition from MITx to edX, so prototype course students will have <cite>NULL</cite> for this field. Students who elected not to enter anything will have a blank string.</div></blockquote>
</div>
<div class="section" id="allow-certificate">
<h4><cite>allow_certificate</cite><a class="headerlink" href="#allow-certificate" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Set to <cite>1</cite> for most students. This field is set to <cite>0</cite> if log analysis has revealed that this student is accessing our site from a country that the US has an embargo against. At this time, we do not issue certificates to students from those countries.</div></blockquote>
</div>
</div>
<div class="section" id="student-courseenrollment">
<h3><cite>student_courseenrollment</cite><a class="headerlink" href="#student-courseenrollment" title="Permalink to this headline"></a></h3>
<p>A row in this table represents a student&#8217;s enrollment for a particular course run. If they decide to unenroll in the course, we delete their entry in this table, but we still leave all their state in <cite>courseware_studentmodule</cite> untouched.</p>
<div class="section" id="id2">
<h4><cite>id</cite><a class="headerlink" href="#id2" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Primary key.</div></blockquote>
</div>
<div class="section" id="id3">
<h4><cite>user_id</cite><a class="headerlink" href="#id3" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Student&#8217;s ID in <cite>auth_user.id</cite></div></blockquote>
</div>
<div class="section" id="course-id">
<h4><cite>course_id</cite><a class="headerlink" href="#course-id" title="Permalink to this headline"></a></h4>
<blockquote>
<div>The ID of the course run they&#8217;re enrolling in (e.g. <cite>MITx/6.002x/2012_Fall</cite>). You can get this from the URL when you&#8217;re viewing courseware on your browser.</div></blockquote>
</div>
<div class="section" id="created">
<h4><cite>created</cite><a class="headerlink" href="#created" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Datetime of enrollment, UTC.</div></blockquote>
</div>
</div>
</div>
<div class="section" id="courseware-progress">
<h2>Courseware Progress<a class="headerlink" href="#courseware-progress" title="Permalink to this headline"></a></h2>
<p>Any piece of content in the courseware can store state and score in the <cite>courseware_studentmodule</cite> table. Grades and the user Progress page are generated by doing a walk of the course contents, searching for graded items, looking up a student&#8217;s entries for those items in <cite>courseware_studentmodule</cite> via <cite>(course_id, student_id, module_id)</cite>, and then applying the grade weighting found in the course policy and grading policy files. Course policy files determine how much weight one problem has relative to another, and grading policy files determine how much categories of problems are weighted (e.g. HW=50%, Final=25%, etc.).</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p><strong>Modules might not be what you expect!</strong></p>
<p>It&#8217;s important to understand what &#8220;modules&#8221; are in the context of our system, as the terminology can be confusing. For the conventions of this table and many parts of our code, a &#8220;module&#8221; is a content piece that appears in the courseware. This can be nearly anything that appears when users are in the courseware tab: a video, a piece of HTML, a problem, etc. Modules can also be collections of other modules, such as sequences, verticals (modules stacked together on the same page), weeks, chapters, etc. In fact, the course itself is a top level module that contains all the other contents of the course as children. You can imagine the entire course as a tree with modules at every node.</p>
<p class="last">Modules can store state, but whether and how they do so is up to the implemenation for that particular kind of module. When a user loads page, we look up all the modules they need to render in order to display it, and then we ask the database to look up state for those modules for that user. If there is corresponding entry for that user for a given module, we create a new row and set the state to an empty JSON dictionary.</p>
</div>
<div class="section" id="courseware-studentmodule">
<h3><cite>courseware_studentmodule</cite><a class="headerlink" href="#courseware-studentmodule" title="Permalink to this headline"></a></h3>
<p>The <cite>courseware_studentmodule</cite> table holds all courseware state for a given user. Every student has a separate row for every piece of content in the course, making this by far our largest table:</p>
<div class="highlight-python"><pre>+-------------+--------------+------+-----+
| Field | Type | Null | Key |
+-------------+--------------+------+-----+
| id | int(11) | NO | PRI |
| module_type | varchar(32) | NO | MUL |
| module_id | varchar(255) | NO | MUL |
| student_id | int(11) | NO | MUL |
| state | longtext | YES | |
| grade | double | YES | MUL | # problem, selfassessment, and combinedopenended use this
| created | datetime | NO | MUL |
| modified | datetime | NO | MUL |
| max_grade | double | YES | | # problem, selfassessment, and combinedopenended use this
| done | varchar(8) | NO | MUL | # ignore this
| course_id | varchar(255) | NO | MUL |
+-------------+--------------+------+-----+</pre>
</div>
<div class="section" id="id4">
<h4><cite>id</cite><a class="headerlink" href="#id4" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Primary key. Rarely used though, since most lookups on this table are searches on the three tuple of <cite>(course_id, student_id, module_id)</cite>.</div></blockquote>
</div>
<div class="section" id="module-type">
<h4><cite>module_type</cite><a class="headerlink" href="#module-type" title="Permalink to this headline"></a></h4>
<blockquote>
<div><table border="1" class="docutils">
<colgroup>
<col width="11%" />
<col width="89%" />
</colgroup>
<tbody valign="top">
<tr class="row-odd"><td><cite>chapter</cite></td>
<td>The top level categories for a course. Each of these is usually labeled as a Week in the courseware, but this is just convention.</td>
</tr>
<tr class="row-even"><td><cite>combinedopenended</cite></td>
<td>A new module type developed for grading open ended questions via self assessment, peer assessment, and machine learning.</td>
</tr>
<tr class="row-odd"><td><cite>conditional</cite></td>
<td>A new module type recently developed for 8.02x, this allows you to prevent access to certain parts of the courseware if other parts have not been completed first.</td>
</tr>
<tr class="row-even"><td><cite>course</cite></td>
<td>The top level course module of which all course content is descended.</td>
</tr>
<tr class="row-odd"><td><cite>problem</cite></td>
<td>A problem that the user can submit solutions for. We have many different varieties.</td>
</tr>
<tr class="row-even"><td><cite>problemset</cite></td>
<td>A collection of problems and supplementary materials, typically used for homeworks and rendered as a horizontal icon bar in the courseware. Use is inconsistent, and some courses use a <cite>sequential</cite> instead.</td>
</tr>
<tr class="row-odd"><td><cite>selfassessment</cite></td>
<td>Self assessment problems. An early test of the open ended grading system that is not in widespread use yet. Recently deprecated in favor of <cite>combinedopenended</cite>.</td>
</tr>
<tr class="row-even"><td><cite>sequential</cite></td>
<td>A collection of videos, problems, and other materials, rendered as a horizontal icon bar in the courseware.</td>
</tr>
<tr class="row-odd"><td><cite>timelimit</cite></td>
<td>A special module that records the time you start working on a piece of courseware and enforces time limits, used for Pearson exams. This hasn&#8217;t been completely generalized yet, so is not available for widespread use.</td>
</tr>
<tr class="row-even"><td><cite>videosequence</cite></td>
<td>A collection of videos, exercise problems, and other materials, rendered as a horizontal icon bar in the courseware. Use is inconsistent, and some courses use a <cite>sequential</cite> instead.</td>
</tr>
</tbody>
</table>
<p>There&#8217;s been substantial muddling of our container types, particularly between sequentials, problemsets, and videosequences. In the beginning we only had sequentials, and these ended up being used primarily for two purposes: creating a sequence of lecture videos and exercises for instruction, and creating homework problem sets. The <cite>problemset</cite> and <cite>videosequence</cite> types were created with the hope that our system would have a better semantic understanding of what a sequence actually represented, and could at a later point choose to render them differently to the user if it was appropriate. Due to a variety of reasons, migration over to this has been spotty. They all render the same way at the moment.</p>
</div></blockquote>
</div>
<div class="section" id="module-id">
<h4><cite>module_id</cite><a class="headerlink" href="#module-id" title="Permalink to this headline"></a></h4>
<blockquote>
<div><p>Unique ID for a distinct piece of content in a course, these are recorded as URLs of the form <cite>i4x://{org}/{course_num}/{module_type}/{module_name}</cite>. Having URLs of this form allows us to give content a canonical representation even as we are in a state of transition between backend data stores.</p>
<table border="1" class="docutils">
<caption>Breakdown of example <cite>module_id</cite>: <cite>i4x://MITx/3.091x/problemset/Sample_Problems</cite></caption>
<colgroup>
<col width="10%" />
<col width="20%" />
<col width="70%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Part</th>
<th class="head">Example</th>
<th class="head">Definition</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><cite>i4x://</cite></td>
<td>&nbsp;</td>
<td>Just a convention we ran with. We had plans for the domain <cite>i4x.org</cite> at one point.</td>
</tr>
<tr class="row-odd"><td><cite>org</cite></td>
<td><cite>MITx</cite></td>
<td>The organization part of the ID, indicating what organization created this piece of content.</td>
</tr>
<tr class="row-even"><td><cite>course_num</cite></td>
<td><cite>3.091x</cite></td>
<td>The course number this content was created for. Note that there is no run information here, so you can&#8217;t know what runs of the course this content is being used for from the <cite>module_id</cite> alone; you have to look at the <cite>courseware_studentmodule.course_id</cite> field.</td>
</tr>
<tr class="row-odd"><td><cite>module_type</cite></td>
<td><cite>problemset</cite></td>
<td>The module type, same value as what&#8217;s in the <cite>courseware_studentmodule.module_type</cite> field.</td>
</tr>
<tr class="row-even"><td><cite>module_name</cite></td>
<td><cite>Sample_Problems</cite></td>
<td>The name given for this module by the content creators. If the module was not named, the system will generate a name based on the type and a hash of its contents (ex: <cite>selfassessment_03c483062389</cite>).</td>
</tr>
</tbody>
</table>
</div></blockquote>
</div>
<div class="section" id="student-id">
<h4><cite>student_id</cite><a class="headerlink" href="#student-id" title="Permalink to this headline"></a></h4>
<blockquote>
<div>A reference to <cite>auth_user.id</cite>, this is the student that this module state row belongs to.</div></blockquote>
</div>
<div class="section" id="state">
<h4><cite>state</cite><a class="headerlink" href="#state" title="Permalink to this headline"></a></h4>
<blockquote>
<div><p>This is a JSON text field where different module types are free to store their state however they wish.</p>
<dl class="docutils">
<dt>Container Modules: <cite>course</cite>, <cite>chapter</cite>, <cite>problemset</cite>, <cite>sequential</cite>, <cite>videosequence</cite></dt>
<dd><p class="first">The state for all of these is a JSON dictionary indicating the user&#8217;s last known position within this container. This is 1-indexed, not 0-indexed, mostly because it went out that way at one point and we didn&#8217;t want to later break saved navigation state for users.</p>
<dl class="docutils">
<dt>Example: <cite>{&#8220;position&#8221; : 3}</cite></dt>
<dd>When this user last interacted with this course/chapter/etc., they had clicked on the third child element. Note that the position is a simple index and not a <cite>module_id</cite>, so if you rearranged the order of the contents, it would not be smart enough to accomodate the changes and would point users to the wrong place.</dd>
</dl>
<p class="last">The hierarchy goes: <cite>course &gt; chapter &gt; (problemset | sequential | videosequence)</cite></p>
</dd>
<dt><cite>combinedopenended</cite></dt>
<dd>TODO: More details to come.</dd>
<dt><cite>conditional</cite></dt>
<dd>Conditionals don&#8217;t actually store any state, so this value is always an empty JSON dictionary (<cite>&#8216;{}&#8217;</cite>). We should probably remove these entries altogether.</dd>
<dt><cite>problem</cite></dt>
<dd><p class="first">There are many kinds of problems supported by the system, and they all have different state requirements. Note that one problem can have many different response fields. If a problem generates a random circuit and asks five questions about it, then all of that is stored in one row in <cite>courseware_studentmodule</cite>.</p>
<p class="last">TODO: Write out different problem types and their state.</p>
</dd>
<dt><cite>selfassessment</cite></dt>
<dd>TODO: More details to come.</dd>
<dt><cite>timelimit</cite></dt>
<dd><p class="first">This very uncommon type was only used in one Pearson exam for one course, and the format may change significantly in the future. It is currently a JSON dictionary with fields:</p>
<table border="1" class="last docutils">
<colgroup>
<col width="10%" />
<col width="20%" />
<col width="70%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">JSON field</th>
<th class="head">Example</th>
<th class="head">Definition</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><cite>beginning_at</cite></td>
<td><cite>1360590255.488154</cite></td>
<td>UTC time as measured in seconds since UNIX epoch representing when the exam was started.</td>
</tr>
<tr class="row-odd"><td><cite>ending_at</cite></td>
<td><cite>1360596632.559758</cite></td>
<td>UTC time as measured in seconds since UNIX epoch representing the time the exam will close.</td>
</tr>
<tr class="row-even"><td><cite>accomodation_codes</cite></td>
<td><cite>DOUBLE</cite></td>
<td><p class="first">(optional) Sometimes students are given more time for accessibility reasons. Possible values are:</p>
<ul class="last simple">
<li><cite>NONE</cite>: no time accommodation</li>
<li><cite>ADDHALFTIME</cite>: 1.5X normal time allowance</li>
<li><cite>ADD30MIN</cite>: normal time allowance + 30 minutes</li>
<li><cite>DOUBLE</cite>: 2X normal time allowance</li>
<li><cite>TESTING</cite>: extra long period (for testing/debugging)</li>
</ul>
</td>
</tr>
</tbody>
</table>
</dd>
</dl>
</div></blockquote>
</div>
<div class="section" id="grade">
<h4><cite>grade</cite><a class="headerlink" href="#grade" title="Permalink to this headline"></a></h4>
<blockquote>
<div><p>Floating point value indicating the total unweighted grade for this problem that the student has scored. Basically how many responses they got right within the problem.</p>
<p>Only <cite>problem</cite> and <cite>selfassessment</cite> types use this field. All other modules set this to <cite>NULL</cite>. Due to a quirk in how rendering is done, <cite>grade</cite> can also be <cite>NULL</cite> for a tenth of a second or so the first time that a user loads a problem. The initial load will trigger two writes, the first of which will set the <cite>grade</cite> to <cite>NULL</cite>, and the second of which will set it to <cite>0</cite>.</p>
</div></blockquote>
</div>
<div class="section" id="id5">
<h4><cite>created</cite><a class="headerlink" href="#id5" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Datetime when this row was created (i.e. when the student first accessed this piece of content).</div></blockquote>
</div>
<div class="section" id="modified">
<h4><cite>modified</cite><a class="headerlink" href="#modified" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Datetime when we last updated this row. Set to be equal to <cite>created</cite> at first. A change in <cite>modified</cite> implies that there was a state change, usually in response to a user action like saving or submitting a problem, or clicking on a navigational element that records its state. However it can also be triggered if the module writes multiple times on its first load, like problems do (see note in <cite>grade</cite>).</div></blockquote>
</div>
<div class="section" id="max-grade">
<h4><cite>max_grade</cite><a class="headerlink" href="#max-grade" title="Permalink to this headline"></a></h4>
<blockquote>
<div><p>Floating point value indicating the total possible unweighted grade for this problem, or basically the number of responses that are in this problem. Though in practice it&#8217;s the same for every entry with the same <cite>module_id</cite>, it is technically possible for it to be anything. The problems are dynamic enough where you could create a random number of responses if you wanted. This a bad idea and will probably cause grading errors, but it is possible.</p>
<p>Another way in which <cite>max_grade</cite> can differ between entries with the same <cite>module_id</cite> is if the problem was modified after the <cite>max_grade</cite> was written and the user never went back to the problem after it was updated. This might happen if a member of the course staff puts out a problem with five parts, realizes that the last part doesn&#8217;t make sense, and decides to remove it. People who saw and answered it when it had five parts and never came back to it after the changes had been made will have a <cite>max_grade</cite> of <cite>5</cite>, while people who saw it later will have a <cite>max_grade</cite> of <cite>4</cite>.</p>
<p>These complexities in our grading system are a high priority target for refactoring in the near future.</p>
<p>Only <cite>problem</cite> and <cite>selfassessment</cite> types use this field. All other modules set this to <cite>NULL</cite>.</p>
</div></blockquote>
</div>
<div class="section" id="done">
<h4><cite>done</cite><a class="headerlink" href="#done" title="Permalink to this headline"></a></h4>
<blockquote>
<div>Ignore this field. It was supposed to be an indication whether something was finished, but was never properly used and is just <cite>&#8216;na&#8217;</cite> in every row.</div></blockquote>
</div>
<div class="section" id="id6">
<h4><cite>course_id</cite><a class="headerlink" href="#id6" title="Permalink to this headline"></a></h4>
<blockquote>
<div>The course that this row applies to, represented in the form org/course/run (ex: <cite>MITx/6.002x/2012_Fall</cite>). The same course content (same <cite>module_id</cite>) can be used in different courses, and a student&#8217;s state needs to be tracked separately for each course.</div></blockquote>
</div>
</div>
</div>
<div class="section" id="certificates">
<h2>Certificates<a class="headerlink" href="#certificates" title="Permalink to this headline"></a></h2>
<div class="section" id="certificates-generatedcertificate">
<h3><cite>certificates_generatedcertificate</cite><a class="headerlink" href="#certificates-generatedcertificate" title="Permalink to this headline"></a></h3>
<p>The generatedcertificate table tracks certificate state for students who have been graded after a course completes. Currently the table is only populated when a course ends and a script is run to grade students who have completed the course:</p>
<div class="highlight-python"><pre>+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | MUL | NULL | |
| download_url | varchar(128) | NO | | NULL | |
| grade | varchar(5) | NO | | NULL | |
| course_id | varchar(255) | NO | MUL | NULL | |
| key | varchar(32) | NO | | NULL | |
| distinction | tinyint(1) | NO | | NULL | |
| status | varchar(32) | NO | | NULL | |
| verify_uuid | varchar(32) | NO | | NULL | |
| download_uuid | varchar(32) | NO | | NULL | |
| name | varchar(255) | NO | | NULL | |
| created_date | datetime | NO | | NULL | |
| modified_date | datetime | NO | | NULL | |
| error_reason | varchar(512) | NO | | NULL | |
+---------------+--------------+------+-----+---------+----------------+</pre>
</div>
<div class="section" id="user-id-course-id">
<h4><cite>user_id</cite>, <cite>course_id</cite><a class="headerlink" href="#user-id-course-id" title="Permalink to this headline"></a></h4>
<blockquote>
<div>The table is indexed by user and course</div></blockquote>
</div>
<div class="section" id="status">
<h4><cite>status</cite><a class="headerlink" href="#status" title="Permalink to this headline"></a></h4>
<blockquote>
<div><p>Status may be one of these states:</p>
<ul class="simple">
<li><cite>unavailable</cite></li>
<li><cite>generating</cite></li>
<li><cite>regenerating</cite></li>
<li><cite>deleting</cite></li>
<li><cite>deleted</cite></li>
<li><cite>downloadable</cite></li>
<li><cite>notpassing</cite></li>
<li><cite>restricted</cite></li>
<li><cite>error</cite></li>
</ul>
<p>After a course has been graded and certificates have been issued status will be one of:</p>
<ul class="simple">
<li><cite>downloadable</cite></li>
<li><cite>notpassing</cite></li>
<li><cite>restricted</cite></li>
</ul>
<p>If the status is <cite>downloadable</cite> then the student passed the course and there will be a certificate available for download.</p>
</div></blockquote>
</div>
<div class="section" id="download-url">
<h4><cite>download_url</cite><a class="headerlink" href="#download-url" title="Permalink to this headline"></a></h4>
<blockquote>
<div>The <cite>download_uuid</cite> has the full URL to the certificate</div></blockquote>
</div>
<div class="section" id="download-uuid-verify-uuid">
<h4><cite>download_uuid</cite>, <cite>verify_uuid</cite><a class="headerlink" href="#download-uuid-verify-uuid" title="Permalink to this headline"></a></h4>
<blockquote>
<div>The two uuids are what uniquely identify the download url and the url used to download the certificate.</div></blockquote>
</div>
<div class="section" id="distinction">
<h4><cite>distinction</cite><a class="headerlink" href="#distinction" title="Permalink to this headline"></a></h4>
<blockquote>
<div>This was used for letters of distinction for 188.1x and is not being used for any current courses</div></blockquote>
</div>
<div class="section" id="id7">
<h4><cite>name</cite><a class="headerlink" href="#id7" title="Permalink to this headline"></a></h4>
<blockquote>
<div>This field records the name of the student that was set at the time the student was graded and the certificate was generated.</div></blockquote>
</div>
<div class="section" id="id8">
<h4><cite>grade</cite><a class="headerlink" href="#id8" title="Permalink to this headline"></a></h4>
<blockquote>
<div>The grade of the student recorded at the time the certificate was generated. This may be different than the current grade since grading is only done once for a course when it ends.</div></blockquote>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="discussion_data.html" title="Discussion Forums Data"
>next</a> |</li>
<li class="right" >
<a href="../course_data_formats/custom_response.html" title="CustomResponse XML and Python Script"
>previous</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tracking Logs &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="../index.html" />
<link rel="prev" title="Discussion Forums Data" href="discussion_data.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="discussion_data.html" title="Discussion Forums Data"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Tracking Logs</a><ul>
<li><a class="reference internal" href="#common-fields">Common Fields</a></li>
<li><a class="reference internal" href="#event-sources">Event Sources</a><ul>
<li><a class="reference internal" href="#server-events">Server Events</a><ul>
<li><a class="reference internal" href="#correct-map-details"><cite>correct_map</cite> details</a></li>
</ul>
</li>
<li><a class="reference internal" href="#browser-events">Browser Events</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="discussion_data.html"
title="previous chapter">Discussion Forums Data</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/internal_data_formats/tracking_logs.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="tracking-logs">
<h1>Tracking Logs<a class="headerlink" href="#tracking-logs" title="Permalink to this headline"></a></h1>
<ul class="simple">
<li>Tracking logs are made available as separate tar files on S3 in the course-data bucket.</li>
<li>They are represented as JSON files that catalog all user interactions with the site.</li>
<li>To avoid filename collisions the tracking logs are organized by server name, where each directory corresponds to a server where they were stored.</li>
</ul>
<div class="section" id="common-fields">
<h2>Common Fields<a class="headerlink" href="#common-fields" title="Permalink to this headline"></a></h2>
<blockquote>
<div><table border="1" class="docutils">
<colgroup>
<col width="12%" />
<col width="47%" />
<col width="12%" />
<col width="29%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">field</th>
<th class="head">details</th>
<th class="head">type</th>
<th class="head">values/format</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><cite>username</cite></td>
<td>username of the user who triggered the event, empty string for anonymous events (not logged in)</td>
<td>string</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td><cite>session</cite></td>
<td>key identifying the user&#8217;s session, may be undefined</td>
<td>string</td>
<td>32 digits key</td>
</tr>
<tr class="row-even"><td><cite>time</cite></td>
<td>GMT time the event was triggered</td>
<td>string</td>
<td><cite>YYYY-MM-DDThh:mm:ss.xxxxxx</cite></td>
</tr>
<tr class="row-odd"><td><cite>ip</cite></td>
<td>user ip address</td>
<td>string</td>
<td>&nbsp;</td>
</tr>
<tr class="row-even"><td><cite>agent</cite></td>
<td>users browser agent string</td>
<td>string</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td><cite>page</cite></td>
<td>page the user was visiting when the event was generated</td>
<td>string</td>
<td><cite>$URL</cite></td>
</tr>
<tr class="row-even"><td>event_source</td>
<td>event source</td>
<td>string</td>
<td><cite>browser</cite>, <cite>server</cite></td>
</tr>
<tr class="row-odd"><td><cite>event_type</cite></td>
<td>type of event triggered, values depends on <cite>event_source</cite></td>
<td>string</td>
<td><em>more details listed below</em></td>
</tr>
<tr class="row-even"><td><cite>event</cite></td>
<td>specifics of the event (dependenty of the event_type)</td>
<td>string/json</td>
<td><em>the event string may encode a JSON record</em></td>
</tr>
</tbody>
</table>
</div></blockquote>
</div>
<div class="section" id="event-sources">
<h2>Event Sources<a class="headerlink" href="#event-sources" title="Permalink to this headline"></a></h2>
<p>The <cite>event_source</cite> field identifies whether the event originated in the browser (via javascript) or on the server (during the processing of a request).</p>
<div class="section" id="server-events">
<h3>Server Events<a class="headerlink" href="#server-events" title="Permalink to this headline"></a></h3>
<blockquote>
<div><table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="10%" />
<col width="10%" />
<col width="10%" />
<col width="50%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">event_type</th>
<th class="head">event fields</th>
<th class="head">type</th>
<th class="head">values/format</th>
<th class="head">details</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><cite>show_answer</cite></td>
<td><cite>problem_id</cite></td>
<td>string</td>
<td>&nbsp;</td>
<td>id of the problem being shown. Ex: <cite>i4x://MITx/6.00x/problem/L15:L15_Problem_2</cite></td>
</tr>
<tr class="row-odd"><td><cite>save_problem_check</cite></td>
<td><cite>problem_id</cite></td>
<td>string</td>
<td>&nbsp;</td>
<td>id of the problem being shown</td>
</tr>
<tr class="row-even"><td>&nbsp;</td>
<td><cite>success</cite></td>
<td>string</td>
<td>correct, incorrect</td>
<td>whether the problem was correct</td>
</tr>
<tr class="row-odd"><td>&nbsp;</td>
<td><cite>attempts</cite></td>
<td>integer</td>
<td>number of attempts</td>
<td>&nbsp;</td>
</tr>
<tr class="row-even"><td>&nbsp;</td>
<td><cite>correct_map</cite></td>
<td>string/json</td>
<td>&nbsp;</td>
<td>see details below</td>
</tr>
<tr class="row-odd"><td>&nbsp;</td>
<td><cite>state</cite></td>
<td>string/json</td>
<td>&nbsp;</td>
<td>current problem state</td>
</tr>
<tr class="row-even"><td>&nbsp;</td>
<td><cite>answers</cite></td>
<td>string/json</td>
<td>&nbsp;</td>
<td>students answers</td>
</tr>
<tr class="row-odd"><td>&nbsp;</td>
<td><cite>reset_problem</cite></td>
<td>problem_id</td>
<td>string</td>
<td>id of the problem being shown</td>
</tr>
</tbody>
</table>
</div></blockquote>
<div class="section" id="correct-map-details">
<h4><cite>correct_map</cite> details<a class="headerlink" href="#correct-map-details" title="Permalink to this headline"></a></h4>
<blockquote>
<div><table border="1" class="docutils">
<colgroup>
<col width="30%" />
<col width="20%" />
<col width="30%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">correct_map fields</th>
<th class="head">type</th>
<th class="head">values/format</th>
<th class="head">null allowed?</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>hint</td>
<td>string</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td>hintmode</td>
<td>boolean</td>
<td>&nbsp;</td>
<td>yes</td>
</tr>
<tr class="row-even"><td>correctness</td>
<td>string</td>
<td>correct, incorrect</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td>npoints</td>
<td>integer</td>
<td>&nbsp;</td>
<td>yes</td>
</tr>
<tr class="row-even"><td>msg</td>
<td>string</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td>queuestate</td>
<td>string/json</td>
<td>keys: key, time</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</div></blockquote>
</div>
</div>
<div class="section" id="browser-events">
<h3>Browser Events<a class="headerlink" href="#browser-events" title="Permalink to this headline"></a></h3>
<blockquote>
<div><table border="1" class="docutils">
<colgroup>
<col width="14%" />
<col width="14%" />
<col width="11%" />
<col width="17%" />
<col width="29%" />
<col width="14%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">event_type</th>
<th class="head">fields</th>
<th class="head">type</th>
<th class="head">values/format</th>
<th class="head">details</th>
<th class="head">example</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><cite>book</cite></td>
<td><cite>type</cite></td>
<td>string</td>
<td><cite>gotopage</cite></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td>&nbsp;</td>
<td><cite>old</cite></td>
<td>integer</td>
<td><cite>$PAGE</cite></td>
<td>from page number</td>
<td><cite>2</cite></td>
</tr>
<tr class="row-even"><td>&nbsp;</td>
<td><cite>new</cite></td>
<td>integer</td>
<td><cite>$PAGE</cite></td>
<td>to page number</td>
<td><cite>25</cite></td>
</tr>
<tr class="row-odd"><td><cite>book</cite></td>
<td><cite>type</cite></td>
<td>string</td>
<td><cite>nextpage</cite></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class="row-even"><td>&nbsp;</td>
<td>new</td>
<td>integer</td>
<td><cite>$PAGE</cite></td>
<td>next page number</td>
<td><cite>10</cite></td>
</tr>
<tr class="row-odd"><td><cite>page_close</cite></td>
<td><em>empty</em></td>
<td>string</td>
<td>&nbsp;</td>
<td>&#8216;page&#8217; field indicates which page was being closed</td>
<td>&nbsp;</td>
</tr>
<tr class="row-even"><td>play_video</td>
<td><cite>id</cite></td>
<td>string</td>
<td>&nbsp;</td>
<td>edX id of the video being watched</td>
<td><cite>i4x-HarvardX-PH207x-video-Simple_Random_Sample</cite></td>
</tr>
<tr class="row-odd"><td>&nbsp;</td>
<td>code</td>
<td>string</td>
<td>&nbsp;</td>
<td>youtube id of the video being watched</td>
<td><cite>FU3fCJNs94Y</cite></td>
</tr>
<tr class="row-even"><td>&nbsp;</td>
<td><cite>currentTime</cite></td>
<td>float</td>
<td>&nbsp;</td>
<td>time the video was paused at, in seconds</td>
<td><cite>1.264</cite></td>
</tr>
<tr class="row-odd"><td>&nbsp;</td>
<td><cite>speed</cite></td>
<td>string</td>
<td><cite>0.75, 1.0, 1.25, 1.50</cite></td>
<td>video speed being played</td>
<td><cite>&#8220;1.0&#8221;</cite></td>
</tr>
<tr class="row-even"><td><cite>pause_video</cite></td>
<td><cite>id</cite></td>
<td>string</td>
<td>&nbsp;</td>
<td>edX id of the video being watched</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td>&nbsp;</td>
<td><cite>code</cite></td>
<td>string</td>
<td>&nbsp;</td>
<td>youtube id of the video being watched</td>
<td>&nbsp;</td>
</tr>
<tr class="row-even"><td>&nbsp;</td>
<td><cite>currentTime</cite></td>
<td>float</td>
<td>&nbsp;</td>
<td>time the video was paused at</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td>&nbsp;</td>
<td><cite>speed</cite></td>
<td>string</td>
<td><cite>0.75, 1.0, 1.25, 1.50</cite></td>
<td>video speed being played</td>
<td>&nbsp;</td>
</tr>
<tr class="row-even"><td><cite>problem_check</cite></td>
<td><em>none</em></td>
<td>string</td>
<td>&nbsp;</td>
<td>event field contains the values of all input fields from the problem being checked (in the style of GET parameters (<cite>key=value&amp;key=value</cite>))</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td><cite>problem_show</cite></td>
<td><cite>problem</cite></td>
<td>string</td>
<td>&nbsp;</td>
<td>id of the problem being checked</td>
<td>&nbsp;</td>
</tr>
<tr class="row-even"><td><cite>seq_goto</cite></td>
<td><cite>id</cite></td>
<td>string</td>
<td>&nbsp;</td>
<td>edX id of the sequence</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td>&nbsp;</td>
<td><cite>old</cite></td>
<td>integer</td>
<td>&nbsp;</td>
<td>sequence element being jumped from</td>
<td><cite>3</cite></td>
</tr>
<tr class="row-even"><td>&nbsp;</td>
<td><cite>new</cite></td>
<td>integer</td>
<td>&nbsp;</td>
<td>sequence element being jumped to</td>
<td><cite>5</cite></td>
</tr>
<tr class="row-odd"><td><cite>seq_next</cite></td>
<td><cite>id</cite></td>
<td>string</td>
<td>&nbsp;</td>
<td>edX id of the sequence</td>
<td>&nbsp;</td>
</tr>
<tr class="row-even"><td>&nbsp;</td>
<td><cite>old</cite></td>
<td>integer</td>
<td>&nbsp;</td>
<td>sequence element being jumped from</td>
<td><cite>4</cite></td>
</tr>
<tr class="row-odd"><td>&nbsp;</td>
<td><cite>new</cite></td>
<td>integer</td>
<td>&nbsp;</td>
<td>sequence element being jumped to</td>
<td><cite>6</cite></td>
</tr>
<tr class="row-even"><td><cite>rubric_select</cite></td>
<td><cite>location</cite></td>
<td>string</td>
<td>&nbsp;</td>
<td>location of the rubric&#8217;s problem</td>
<td><cite>i4x://MITx/6.00x/problem/L15:L15_Problem_2</cite></td>
</tr>
<tr class="row-odd"><td>&nbsp;</td>
<td><cite>category</cite></td>
<td>integer</td>
<td>&nbsp;</td>
<td>category number of the rubric selection</td>
<td>&nbsp;</td>
</tr>
<tr class="row-even"><td>&nbsp;</td>
<td><cite>value</cite></td>
<td>integer</td>
<td>&nbsp;</td>
<td>value selected within the category</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td><cite>(oe / peer_grading / staff_grading)</cite>
<cite>_show_problem</cite></td>
<td><cite>location</cite></td>
<td>string</td>
<td>&nbsp;</td>
<td>the location of the problem whose prompt we&#8217;re showing</td>
<td>&nbsp;</td>
</tr>
<tr class="row-even"><td><cite>(oe / peer_grading / staff_grading)</cite>
<cite>_hide_problem</cite></td>
<td><cite>location</cite></td>
<td>string</td>
<td>&nbsp;</td>
<td>the location of the problem whose prompt we&#8217;re hiding</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td><cite>oe_show_full_feedback</cite></td>
<td><em>empty</em></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>the page where they&#8217;re showing full feedback is already recorded</td>
<td>&nbsp;</td>
</tr>
<tr class="row-even"><td><cite>oe_show_respond_to_feedback</cite></td>
<td><em>empty</em></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>the page where they&#8217;re showing the feedback response form is already recorded</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td><cite>oe_feedback_response_selected</cite></td>
<td><cite>value</cite></td>
<td>integer</td>
<td>&nbsp;</td>
<td>the value selected in the feedback response form</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</div></blockquote>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="discussion_data.html" title="Discussion Forums Data"
>previous</a> |</li>
<li><a href="../index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
...@@ -62,9 +62,16 @@ ...@@ -62,9 +62,16 @@
</div> </div>
<div class="col-lg-1"> <div class="col-lg-1">
<nav class="resources"> <nav class="resources">
<a rel="external" href="https://userdocs.readthedocs.org/en/latest/"> <a rel="external" href="https://userdocs.readthedocs.org/en/latest/">
<span class="label">Read the Docs</span> <span class="label">HTML version</span>
</a>
<a rel="external"
href="https://media.readthedocs.org/pdf/userdocs/latest/userdocs.pdf">
<span class="label">PDF version</span>
</a> </a>
</nav> </nav>
</div> </div>
...@@ -72,55 +79,58 @@ ...@@ -72,55 +79,58 @@
</li> </li>
<!-- data -->
<li class="list-group-item">
<h3 class="lead"><span
class="list-group-item-heading">Data </span></h3> <!--developers-->
<li class="list-group-item">
<h3 class="lead"><span class="list-group-item-heading">For Developers</span></h3>
<div class="row"> <div class="row">
<div class="col-lg-1"> <div class="col-lg-1">
</div> </div>
<div class="col-lg-6"> <div class="col-lg-6">
<blockquote> <blockquote>
<p> Not sure myself. </p> <p> CMS, LMS, Blades - find your way about it all.
</p>
</blockquote> </blockquote>
</div> </div>
<div class="col-lg-1"> <div class="col-lg-1">
<nav class="resources"> <nav class="resources">
<a rel="external" href="https://doc.readthedocs.org/en/latest/">
<a rel="external" href="https://docstrings.readthedocs.org/en/latest/"> <span class="label">HTML version</span>
<span class="label">Read the Docs</span> </a>
<a rel="external"
href="https://media.readthedocs.org/pdf/doc/latest/docs.pdf">
<span class="label">PDF version</span>
</a> </a>
</nav> </nav>
</div> </div>
</div> </div>
<hr></hr>
</li>
<!--developers-->
<li class="list-group-item">
<h3 class="lead"><span class="list-group-item-heading">For Developers</span></h3>
<div class="row"> <div class="row">
<div class="col-lg-1"> <div class="col-lg-1">
</div> </div>
<div class="col-lg-6"> <div class="col-lg-6">
<blockquote> <blockquote>
<p> CMS, LMS, Blades - find your way about it all. <p> edX docstrings. </p>
</p>
</blockquote> </blockquote>
</div> </div>
<div class="col-lg-1"> <div class="col-lg-1">
<nav class="resources"> <nav class="resources">
<a rel="external" href="https://doc.readthedocs.org/en/latest/">
<span class="label">Read the Docs</span> <a rel="external" href="https://docstrings.readthedocs.org/en/latest/">
<span class="label">HTML version</span>
</a>
<a rel="external"
href="https://media.readthedocs.org/pdf/docstrings/latest/docstrings.pdf">
<span class="label">PDF version</span>
</a> </a>
</nav> </nav>
</div> </div>
......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Python Module Index &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="edX Data 0.1 documentation" href="index.html" />
<script type="text/javascript">
DOCUMENTATION_OPTIONS.COLLAPSE_INDEX = true;
</script>
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="#" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Python Module Index</h1>
<div class="modindex-jumpbox">
<a href="#cap-c"><strong>c</strong></a> |
<a href="#cap-d"><strong>d</strong></a> |
<a href="#cap-p"><strong>p</strong></a> |
<a href="#cap-x"><strong>x</strong></a>
</div>
<table class="indextable modindextable" cellspacing="0" cellpadding="2">
<tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
<tr class="cap" id="cap-c"><td></td><td>
<strong>c</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="course_data_formats/conditional_module/conditional_module.html#module-conditional_module"><tt class="xref">conditional_module</tt></a></td><td>
<em></em></td></tr>
<tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
<tr class="cap" id="cap-d"><td></td><td>
<strong>d</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="course_data_formats/drag_and_drop/drag_and_drop_input.html#module-drag_and_drop_input"><tt class="xref">drag_and_drop_input</tt></a></td><td>
<em></em></td></tr>
<tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
<tr class="cap" id="cap-p"><td></td><td>
<strong>p</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="course_data_formats/poll_module/poll_module.html#module-poll_module"><tt class="xref">poll_module</tt></a></td><td>
<em></em></td></tr>
<tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
<tr class="cap" id="cap-x"><td></td><td>
<strong>x</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="course_data_formats/graphical_slider_tool/graphical_slider_tool.html#module-xml_format_gst"><tt class="xref">xml_format_gst</tt></a></td><td>
<em></em></td></tr>
</table>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="#" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Search &mdash; edX Data 0.1 documentation</title>
<link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="top" title="edX Data 0.1 documentation" href="index.html" />
<script type="text/javascript">
jQuery(function() { Search.loadIndex("searchindex.js"); });
</script>
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1 id="search-documentation">Search</h1>
<div id="fallback" class="admonition warning">
<script type="text/javascript">$('#fallback').hide();</script>
<p>
Please activate JavaScript to enable the search
functionality.
</p>
</div>
<p>
From here you can search these documents. Enter your search
words into the box below and click "search". Note that the search
function will automatically search for all of the words. Pages
containing fewer words won't appear in the result list.
</p>
<form action="" method="get">
<input type="text" name="q" value="" />
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
<div id="search-results">
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">edX Data 0.1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2013, edX Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
\ No newline at end of file
Search.setIndex({objects:{"":{poll_module:[10,0,1,""],conditional_module:[11,0,1,""],drag_and_drop_input:[9,0,1,""],xml_format_gst:[6,0,1,""]}},terms:{s_left:9,yellow:6,four:[8,9,3],num_point:6,whose:5,educ:2,under:7,preprocess:4,sha256:2,worth:[8,3],digit:[7,5,2],everi:[7,9,2,3],consecutive_days_visit_count:2,affect:[8,2],certificates_generatedcertif:2,school:2,math:[0,4,6],p_l:9,direct:3,second:[0,2,5,6,7,9,10],street:2,overall_messag:0,semest:7,chem:9,p_r:9,blue:[7,6],discussion_blackout:7,hide:[7,5],weren:2,target10:9,conduct:1,"new":[8,6,5,2,7],net:8,ever:8,metadata:[7,2],abov:[7,9,6,3],comment_thread_id:8,never:[8,7,2],here:[0,8,2,6,7,11],created_d:2,studio:[1,7],boron:9,untreated_men:6,path:9,enrol:[7,2],interpret:3,forum:[8,1,2,7],spotti:2,precis:[6,9,2],credit:7,permit:7,studi:[1,7],user_dragg:9,pdf_textbook:7,substr:6,unix:2,poll_answ:11,total:[8,1,2,3,6],unit:[7,6],dnd:9,describ:[1,9,2,7],would:[0,8,2,3,4,6,7],with_icon:9,date_join:2,call:[6,2,10,7],recommend:7,old_nam:2,type:[0,1,2,3,5,6,7,8,9],until:[7,2],show_calcul:7,relat:[7,2],award:3,warn:2,hold:[8,2],must:[0,2,3,6,7,9,11],htmlbook:7,join:7,"30t04":7,work:[1,9,2,6,7],"2012_fall":[7,2],conceptu:7,root:7,overrid:7,give:[7,2,3],gotopag:5,indic:[0,1,2,4,5,7,8],unavail:2,want:[8,2,3,6,7,9],david:2,end:[6,9,2,7],v_fb_2:9,how:[0,1,2,3,6,7,10],v_fb_1:9,answer:[0,8,2,5,7,9,10,11],widespread:2,ancestor:8,perspect:9,updat:[6,2],recogn:9,outsid:9,after:[6,9,2,7],lab:3,befor:[6,2,7],wrong:[9,2],sample_problem:2,averag:3,askbot:2,attempt:[7,5,9,11],third:[0,6,9,2,7],obsolet:[7,2],neglect:6,environ:7,enter:[0,4,2],order:[0,6,9,2,7],origin:[8,7,5],feedback:[0,5],bar_width:6,over:[6,9,2,7],fall:7,becaus:[8,6,9,2],privileg:[8,2],vari:7,textbox:6,smallint:2,uuid:2,img:[7,9],fix:[6,9,2],better:[7,2],wddi6qw:7,easier:7,descend:2,them:[8,6,2,7],anim:7,thei:[8,2,5,6,7,9],safe:6,rectangl:9,"break":[7,2],"1yk1a8":7,choic:10,oxygen:9,accommod:2,each:[0,8,2,3,5,6,7,9],debug:2,volcano:9,went:2,side:[8,7,9],bone:6,mean:[8,2,3,6,7,9],allow_certif:2,email_kei:2,vote:[8,10,11],p_right_3:9,p_right_2:9,coursewar:[8,1,2,7],goe:[0,6,2],content:[8,1,2,6,7],got:2,add_apples_and_orang:7,navig:[7,2],written:[8,1,2,3,6,7],free:2,standard:[7,6],table_of_cont:7,inok:6,untreat:6,fairli:7,unabl:10,confus:2,rang:6,render:[6,2,7],grade:[1,9,2,3,7],independ:6,restrict:2,instruct:2,alreadi:[7,5],primari:[8,2],cartesian:6,rewritten:7,problem_show:5,top:[8,6,9,2,7],sometim:[6,9,2],toi:7,master:2,too:[7,9,2],similarli:7,toc:7,namespac:7,tool:[1,6,7],took:2,cdata:[9,6],technic:[7,9,2],target:[1,9,2],warmup:7,provid:[0,7,9,6],tree:2,zero:7,matter:7,minut:[7,2],fashion:6,ran:2,modern:7,mind:2,raw:1,increment:9,seen:[8,7],lbl:6,latter:2,simple_random_sampl:5,course_survei:7,draggable_id:9,even:[8,6,9,2,7],though:[8,7,9,2],usernam:[5,2],object:[8,7,9,6],letter:[2,3],phase:[2,3],email_tag_filter_strategi:2,auto_cohort:7,dom:6,professor:3,flow:9,doe:[8,7,9,2,3],dummi:7,bracket:6,sum:0,dot:[7,6],random:[7,2],"_show_problem":5,radiu:6,syntax:[4,9,7],freeform:2,"0000ff":6,p_pi_1:9,p_pi_2:9,absolut:6,vnmrbpvwhu4:7,submit:2,explain:0,configur:[7,6],releas:2,peer_grad:5,folder:[7,9],selfassess:2,url_slug:7,intersect:9,label2:9,label3:9,target_id:9,report:9,recalcul:6,youtub:[7,5],earn:3,pearson:2,bar:[6,2,7],draggable_2:9,draggable_1:9,emb:7,"public":7,bad:2,ban:2,told:3,first_real_poll_seq_with_reset:11,l3_o:9,mandatori:6,result:[7,6],respons:[0,2,3,4,5,9],update_on:6,hash:[10,2],hammer:7,best:[7,9],awar:7,nytrogen:9,hopefulli:7,databas:[8,2],university_comparison:2,score:[2,3],"587z":8,drawn:[9,6],awai:[1,7],approach:2,attribut:[0,1,2,6,7,8,9,10,11],men:6,extend:9,xrang:6,condit:[1,2,11,7],is_attempt:11,carbon:9,easi:[7,6],cow:9,sumprob:7,howev:[8,6,2,7],against:[6,9,2],logic:[7,9],cow3_bad:9,login:2,browser:[6,5,9,2,7],com:7,height:[9,6],guid:7,assum:[7,3],modifi:2,three:[8,7,9,2],been:[6,2,3,7],computed_perc:3,much:[8,7,2],cereal:8,videodev:7,basic:[7,2],p_se:2,deeper:7,unordered_equ:9,xxx:7,uncommon:2,argument:0,"25x":7,child:[8,2,3],"catch":7,ant:9,ident:[4,9,7],explanatori:7,servic:7,properti:6,ffff00:6,calcium:9,calcul:6,dashboard:2,l15_problem_2:5,module_nam:2,sever:[0,6,3],mako:7,future_upd:2,incorrectli:0,receiv:8,suggest:7,make:[8,2,3,6,7,9],complex:[6,9,2],split:[6,2,3,7],complet:[7,2,3,11],fragil:7,sacramento:0,hand:7,codebas:2,unicorn:7,require_complet:7,thu:7,inherit:7,client:9,thi:[0,1,2,3,4,6,7,8,9,10,11],everyth:[7,6],left:[7,9,6],identifi:[7,5,9,2,10],gbw_wqe7rdc:7,just:[8,6,2,7],photo:7,ordin:9,grader:[7,9,3],human:9,yet:[7,2],languag:2,expos:[7,2],had:[8,4,2],els:[0,6,9,2,7],save:2,hat:7,applic:2,u_d:9,quirk:2,filesytem:7,capa:4,measur:2,specif:[8,1,2,5,6,7,9],arbitrari:[7,2],manual:2,remind:2,course_url_nam:7,www:7,right:[6,9,2,7],page_label:7,interv:7,excerpt:9,maxim:6,percentag:3,preprocessorclassnam:4,intern:[1,2,6,7],download_uuid:2,indirect:7,bottom:6,t10:9,"400px":6,foo:7,bold:6,plot:6,confer:2,repositori:7,peer:2,post:[8,7],"super":4,chapter:[7,2,3],hide_from_toc:7,surround:6,ddthh:5,produc:[1,7],aha:7,"float":[6,5,2,7],encod:[8,7,5],bound:9,down:[8,9,3],wrap:6,old:[7,5,10],a_readonli:6,wai:[0,8,2,6,7,9],rerandom:7,download_url:2,"class":2,avail:[6,5,2,3,7],width:[9,6],acknowledg:7,lowest:3,form:[0,2,5,6,7,9],altogeth:2,"true":[0,8,2,3,6,7,9,10,11],reset:[7,10],your_course_dir:7,maximum:9,tell:[9,6],"20px":6,unrel:2,featur:[4,9],choiceprob:7,textbook:[1,7],inputtyp:[1,9],exist:[8,7,9],subforum:7,label_bg_color:9,check:[0,7,5,9,2],readonli:6,tip:[1,7],refactor:2,role:2,test:[7,2],node:2,intend:7,consid:[9,3],helperfunc:6,femal:2,longer:[8,2],anywher:[9,2],sigma:9,tinyint:2,ignor:2,time:[8,2,5,6,7,9,10],backward:7,mathrm:6,chain:9,t5_c:9,is_act:2,row:2,hierarch:7,decid:[6,2,7],middl:[9,2],depend:[8,6,5,2,11],zone:7,graph:[7,6],readabl:9,yunit:6,lec27_q1:11,bar_align:6,sourc:[1,5,11],string:[0,8,2,5,6,7,9],asymptot:6,customrespons:[0,1,9],days_early_for_beta:7,exact:9,cohorted_discuss:7,orbital_singl:9,hour:7,p_sigma_star_nam:9,level:[8,7,9,2,3],did:[7,2],item:2,team:2,div:6,round:[6,3],dir:7,rubric:5,upper:9,improvement_lectur:2,sign:2,t2_h:9,run:[8,7,2],mydiscuss:7,ormsbe:2,appear:[8,7,9,2],repli:8,showansw:7,v_ub_2:9,v_ub_1:9,current:[2,3,4,5,6,7,9],ampersand:7,dropdown:2,autogener:10,gener:[0,8,2,3,4,5,6,7,11],satisfi:7,target8:9,target9:9,target6:9,target7:9,target4:9,target5:9,target2:9,target3:9,target1:9,male:2,queue:6,problemfoo:7,nextpag:5,extrem:6,t9_o:9,orient:1,semant:[7,2],elect:2,extra:[6,2,7],modul:[8,1,2,3,6,7,10,11],prefer:[7,9,2],video_resourc:7,visibl:[7,11],univers:2,visit:5,todai:7,everybodi:2,live:7,value2:7,msg:[0,5],prev:6,capit:0,peopl:[1,2,7],visual:[7,3],accept:0,examin:2,easiest:7,graphic:[1,6],tagsd:6,cap:8,uniqu:[8,2,6,7,9,10],descriptor:7,can:[0,8,2,3,6,7,9,10,11],purpos:[7,2],nearest:3,agent:5,topic:7,drawer:7,hydrogen:9,occur:[8,3],alwai:[8,7,2],multipl:[0,6,9,2,7],get:[8,2,3,5,6,7,9],write:[0,6,9,2],anyon:7,pure:7,familiar:2,xhtml:0,anyof:9,map:[6,9,2,11,7],max:6,dive:7,usabl:9,xtick:6,bear:2,date:[7,2],underscor:7,data:[8,1,5,2,6],man:[10,11],practic:2,"_hide_problem":5,up_and_down:9,inform:[1,2,7],"switch":7,combin:[7,3],modified_d:2,superscript:4,student_courseenrol:2,orbital_doubl:9,correct_dragg:9,approv:2,still:[8,7,2,3],pointer:7,dynam:[6,2],group:[7,9,2],v_fb_3:9,polici:[8,1,2,3,7],platform:[1,7],main:[7,9,6,11,10],non:7,tab_titl:7,profession:2,initi:[6,2],now:[8,7,9],discuss:[8,1,2,7],introduct:[1,7],term:7,name:[2,3,5,6,7,9,10],config:7,drop:[1,9,2,3],"600x_l5_p8":8,"21t03":8,separ:[6,5,2,11,7],url_name1:7,url_name2:7,domain:[6,2],pdfbook:7,replac:[6,2,7],individu:[0,7,9],group_0:9,significantli:2,"05t12":7,happen:2,shown:[2,3,5,6,7,9],accomplish:7,space:6,formula:[6,3],correct:[0,8,5,9,2],"50px":6,migrat:2,california:0,avi_resourc:11,org:[8,7,2],"byte":[8,2],reusabl:9,departur:7,refus:7,thing:[7,6],place:[6,9,2,7],loncapa:[0,9],nicknam:2,imposs:6,first:[0,8,2,3,6,7,9,10,11],oper:[9,2],directli:[7,6],onc:[7,2,3],arrai:7,harvardx:5,fast:2,oppos:7,open:[8,9,2,3],size:[4,9,2],given:[6,2,3,7],convent:[7,2],citi:2,necessarili:7,circl:6,hub:6,especi:7,copi:7,circumst:2,specifi:[8,1,2,3,6,7,9,10,11],mostli:2,than:[0,8,2,6,7,9],png:[7,9],wide:7,dormsbe:2,were:[8,7,5,2],posit:[6,9,2],supplementari:2,pxxx:7,correct_map:5,seri:7,pre:7,analysi:2,sai:7,pri:2,ani:[0,8,2,3,6,7,9,10,11],dash:9,breakfast:8,saw:2,el_id:6,mislead:3,engin:[6,2],squar:6,notpass:2,drag_and_drop_input:9,note:[8,2,3,6,7,9],ideal:7,selfassessment_03c483062389:2,take:[6,2,3],xxxxxx:5,green:[7,6],"15px":6,noth:[9,6],begin:[0,6,2,7],sure:[7,9],pain:4,normal:[6,9,2],track:[1,5,2,6,7],beta:7,pair:[7,9],problem_id:5,icon:[7,9,2],latex:4,course_nam:7,closet:7,later:[8,2],typeset:6,script:[0,1,2,4],axi:6,preambl:7,p001:7,show:[8,2,3,5,6,7,11],permiss:2,hack:2,threshold:3,corner:9,label:[6,9,2],drop_count:3,xml:[0,1,6,7,9,10,11],onli:[0,8,2,3,6,7,9],activ:[8,6,2],behind:8,dict:9,test_1:11,nearli:2,variou:[1,7],check_func:0,secondari:2,repo:7,cannot:2,min_count:3,requir:[6,9,2,11,7],reveal:2,p_left_1:9,p_left_3:9,p_left_2:9,s_sigma:9,where:[2,5,6,7,9,11],summari:2,wiki:7,unweight:2,is_staff:2,problemset:[7,2],infinit:7,powerpoint:2,enumer:2,"60px":6,forecast:3,answer_span_1:6,enough:[9,2],between:[6,2,3,7],"import":[0,6,2,3,7],"18t15":2,across:2,assumpt:7,parent:[8,7,9],come:[7,9,2],tue:7,ispubl:7,tutori:[1,7],mani:[6,9,2,10],check2:0,check3:0,check1:0,color:6,overview:7,period:[7,2],colon:7,course_id:[8,2],typic:[7,2],poll:[1,10,11],student_id:2,mark:[0,8],comment_count:8,"abstract":[1,7],bookindex:7,problem1:3,repres:[8,6,5,2,7],former:2,those:[8,1,2,3,6,7],"case":[8,1,2,3,6,7,9,11],cast:8,invok:6,graphical_slider_tool:6,margin:6,anytim:7,some_url_nam:7,canon:2,worri:3,blah:7,url_nam:7,fpbw:7,develop:[1,2,7],doctor:2,fu3fcjns94i:5,same:[8,2,3,6,7,9],epoch:2,html:[6,2,11,7],pad:6,document:[0,1,2,3,4,7,8],breakdown:[2,3],finish:2,nest:[8,7,9],someon:2,extern:7,appropri:[7,2],moder:[8,7],inconsist:2,disable_policy_graph:7,markup:[0,7],without:[6,9,2,3,7],model:7,symbolicrespons:4,first_question_with_reset:10,execut:0,when:[8,2,3,5,6,7,9,10],treated_men:6,speed:[7,5],display_nam:[7,9,10,3,11],hint:[0,5],currenttim:5,except:[7,6,3,10],param:6,pile:9,exercis:2,pow:6,earli:[7,2],around:9,read:7,world:7,integ:[7,5,2],server:[7,5],benefit:7,seq_next:5,either:[0,7,9,2,3],output:[4,6],manag:[7,2],yyyi:5,group_rul:9,module_id:2,definit:[6,2,3,7],achiev:6,exit:6,dynam_lbl:6,mathcal:4,refer:[6,2,7],event_typ:5,broken:7,found:[7,2,3],ph207x:5,discussion_categori:7,src:7,teach_e:2,meaning:[7,2],degre:2,commentthread:[8,1],bond:9,elementari:2,"75x":7,terminolog:2,s_sigma_star:9,strip:6,your:[0,8,2,6,7,10,11],unconvent:2,log:[1,5,2],target_outlin:9,area:6,graceperiod:7,start:[8,6,2,7],interfac:[1,9,7],submiss:[9,2],strictli:1,reset_problem:5,tupl:2,conclus:2,"29t04":7,notat:6,possibl:[6,2,3,10,7],"default":[6,9,2,3,7],bucket:5,queuestat:5,show_countri:2,pbkdf2:2,grass:9,connect:[9,6],texbox:6,creat:[0,2,6,7,9,10],certain:[7,2],deep:8,fellow:8,decreas:6,file:[8,1,2,3,5,7],lcao:9,rearrang:2,fill:[7,9,2],incorrect:[0,5,9],again:[0,9,2],googl:7,prepend:6,field:[8,1,2,5,6,7],valid:[0,4,6,7],collis:5,p_right_1:9,you:[0,1,2,4,6,7,8,9,10,11],"1bk":7,architectur:1,"_type":8,sequenc:[8,7,5,2,3],symbol:[4,7],oe_feedback_response_select:5,philosoph:7,directori:[7,5],descript:[7,9,6,11,10],potenti:3,represent:[7,2],all:[0,8,2,3,5,6,7,9,10],illustr:7,abil:7,follow:[0,1,2,3,4,7,8,9,10,11],children:[6,2],disable_auto_return:6,program:[7,2],present:[7,6],woman:10,fals:[0,8,2,6,7,9,10,11],ytick:6,mechan:[7,2],attr1:7,veri:[6,2,7],longtext:2,list:[0,8,2,4,5,6,7,9],last_nam:2,small:9,dimens:9,customtag:7,tex:6,rate:2,design:[9,2],pass:[6,2,11,7],excit:7,what:[0,8,2,4,6,7,9],sub:[4,3,7],z1y4vdycy0izkopeihtpcldxmby1ogdk:7,section:[8,1,2,3,6,7,9],abl:[7,2],brief:7,delet:2,version:[7,9,2],last_login:2,succinct:7,deepli:[8,7],method:[7,11],hasn:2,full:[8,2,5,6,7,9],themselv:[9,2],week_0:7,behaviour:9,grading_polici:[7,3],less18:10,inher:7,strong:2,"17t12":7,legend:6,valu:[0,8,2,3,5,6,7,9,10,11],search:[1,2,7],prior:7,amount:6,action:2,via:[7,5,2],berkeleyx:8,transit:2,deprec:[7,2],href:7,select:[7,5,2],up_count:8,"02t04":7,distinct:[7,2],two:[0,8,2,3,6,7,9],user_answ:9,taken:8,homework:[2,3],max_grad:[2,3],more:[8,2,5,7,9,11],desir:[7,9],tester:7,datetim:2,line:[0,7,9,6],flag:[7,2],particular:[0,7,2],known:2,l10_o:9,none:[6,5,2,7],valuabl:7,hous:7,outlin:9,"6002x_fall_2012_overview":7,histori:7,remain:6,learn:2,edx4edx:7,def:0,"002x_fall_2012_overview":7,prompt:[5,2],necesari:6,share:[8,1,7],templat:7,minimum:6,poni:7,cours:[8,1,2,3,5,7,9],goal:[1,2,7],first_nam:2,rather:[0,7],anoth:[8,6,9,2,7],reject:2,simpl:[6,9,2,3,7],css:[7,6],regener:2,t10_h:9,resourc:7,referenc:[6,2,7],variant:4,reflect:6,catalog:5,cow3:9,"600px":6,associ:2,preprocessorsrc:4,"short":[9,2],onto:9,created_at:8,author:[1,7],django:2,caus:[2,11],ending_at:2,beginning_at:2,answer_given:0,help:[7,3],soon:7,mathjax_for_prevalence_calc:6,through:[8,2],error_reason:2,hierarchi:[7,2],paramet:[7,5,6],p2q6brnhdh8:7,style:[4,5,6,7],videosequ:[7,2],brows:8,might:[7,2,3],good:[0,7,8],"return":[0,7,9,6],timestamp:[8,2],framework:2,somebodi:8,dnew:6,complain:7,eventu:2,troubleshoot:8,easili:[7,9],name_with_icon:9,innodb:2,truthi:7,fulli:7,unicod:2,week:[7,2],weight:[1,2,3,6],monoton:8,idea:[8,7,2],realli:[7,2],functon:6,expect:[0,2,3,4,6,7],energi:9,todo:[7,2],event:[1,5,6],research:[1,2],occurr:6,end_of_course_survey_url:7,proxi:2,guess:7,labl:6,reason:[7,2],base:[6,9,2,7],put:[0,6,2,7],teach:2,earliest:2,prefac:7,thread:8,my_custom_tag:7,omit:[7,6],circuit:2,assign:[7,9,6,3],cfn:0,prevent:[8,6,2],exchang:8,number:[8,2,3,5,6,7,9,10,11],numericalrespons:3,scriptn_b:4,done:[6,2,7],construct:9,blank:2,stabl:7,miss:[6,3],fanci:4,differ:[6,9,2,10,7],l8_c:9,exponenti:4,interact:[0,1,5,2],least:[6,3],commentable_id:8,statement:6,molecular:7,store:[8,1,5,2,7],schema:2,option:[8,6,9,2,7],relationship:6,part:[8,4,2,7],pars:[7,9,6],kind:[6,2,7],remot:7,remov:2,horizont:[6,2,7],jqueri:6,reus:9,toward:7,randomli:2,highest_degre:2,comput:[7,3],packag:[7,2],group_dragg:9,"null":[5,2],imagin:2,built:2,images_list:9,correct_answ:9,also:[6,9,2,3,7],build:7,p_oth:2,brace:7,signup:2,courseware_studentmodul:2,previou:2,reach:[7,3],most:[8,7,9,2],plai:5,plan:[4,2],amaz:8,last_activity_at:8,bug:2,clear:6,cohort_config:7,clean:9,draggables_1:9,i4x:[5,2,11],alphanumer:[7,2],session:[5,2],particularli:2,homework1:3,fine:6,find:[7,3],copyright:7,l1_c:9,solut:[7,2],future_off:2,factor:[6,3],tartget1:9,embargo:2,express:[4,7],nativ:2,wrinkl:7,banner:2,p_pi_star_2:9,p_pi_star_1:9,oe_show_respond_to_feedback:5,rounded_perc:3,timelimit:2,sigma_:9,common:[1,5,3,7],wrote:8,certif:[1,2,3,7],set:[0,2,3,6,7,9,11],art:7,creator:2,see:[8,2,5,6,7,9,11],bare:6,close:[8,6,5,2,7],analog:7,someth:[4,2,6,7],html_textbook:7,page_clos:5,won:2,subscript:4,experi:2,altern:6,isod:8,numer:[6,2],javascript:[5,6],short_label:3,succeed:0,solv:7,popul:[6,9,2],both:[8,7,6],anonymous_to_p:8,last:[0,8,2,6,7,9],alon:2,foreign:2,textlin:[0,4],roman:2,context:[0,2],pdf:[7,2],author_id:8,whole:6,load:[7,2],markdown:8,simpli:[7,6],point:[8,6,2,3,7],address:[5,2],"000x":11,littl:[7,2],mistak:7,can_reus:9,along:[4,2,6],backend:2,vertic:[6,2,3,7],user_id:2,due:[7,2],empti:[8,5,9,2],sinc:[8,7,2],s_sigma_star_nam:9,endnot:7,imag:[7,9],coordin:[9,6],understand:[7,9,2,3],ignored_tag:2,instructor:[8,6,2,7],convers:8,look:[7,2],s_right:9,straight:7,batch:2,"while":[7,2],smart:2,behavior:[7,9],error:[7,2],anonym:[8,5],display_tag_filter_strategi:2,subsect:7,improvement_textbook:2,readi:7,key2:7,jpg:[7,9],itself:[6,9,2,7],pset:[7,3],"00x":[8,5],dedic:7,downvot:8,shirt:7,minim:6,belong:[7,2],lenient:7,your_m_utx_yss:6,conflict:7,higher:7,book_url:7,moment:2,course_fold:9,user:[0,1,2,5,6,7,8,9],stack:2,recent:2,sha1:2,gst:6,older:7,entri:[7,2],p_sigma_nam:9,one_per_target:9,person:[9,2],picki:[0,7],elev:2,self:2,explan:2,cous:7,course_set:7,staff_grad:[7,5],mysql:[8,2],regardless:3,thees:9,cut:2,theoret:2,rgb:9,mailing_address:2,input:[0,1,4,5,6,9,10,11],varchar:2,format:[0,1,2,3,5,6,7,9,10,11],molecul:9,a_b:4,bit:[4,7],formal:7,implemen:2,signal:7,collect:[8,2],"boolean":[8,7,5,2],xunit:6,group_id:9,"10_25":10,sketch:7,subhead:7,often:[7,2],spring:[7,2],some:[8,1,2,3,4,6,7,9,10,11],back:[9,2],global:0,sampl:7,toy_video:7,rubric_select:5,l15:5,per:[8,7,9],draggagg:9,mathemat:6,larg:[7,9,6],slash:7,machin:[7,2],patient:6,step:[9,6],prerequisit:7,meantim:7,symbolic_mathjax_preprocessor:4,p_pi_star_nam:9,constraint:[9,2],auth_userprofil:2,materi:[7,9,2],upvot:8,problem_check:5,countri:2,block:2,cutoff:3,level_of_educ:2,real:7,primarili:[1,2,7],irrit:7,within:[0,2,3,5,6,7,9],xticks_nam:6,span:6,spam:8,question:[0,8,2,3,7,10,11],"long":[7,9,2],custom:[7,6],includ:[8,2,3,4,6,7,9,10,11],forward:[7,2],accomodation_cod:2,myfunc:6,properli:[6,2,7],drummond_combin:6,link:[1,2,11,6,7],translat:6,atom:9,don:[6,9,2,7],yticks_nam:6,junior:2,info:[1,2,7],utc:[8,7,2],utf:[8,2],consist:[7,3],your_f_utx_yss:6,seq_goto:5,similar:[6,2,7],impl:7,constant:6,problem3:7,problem2:[7,3],doesn:[7,2],lectur:[8,7,2],"char":2,flot:6,course_run:7,titl:[8,7],sequenti:[7,2],declar:[6,3],librari:6,moco:8,nice:6,mongodb:[8,2],drag:[1,9],xqa_kei:7,unaffect:7,orbit:9,notion:3,depth:7,play_video:5,came:2,far:2,scroll:7,prototyp:2,code:[0,6,5,2,7],partial:4,onreset:7,future_class:2,edu:2,edx:[8,1,5,2,7],your_f_tx_yss:6,event_sourc:5,elsewher:[1,7],friendli:[7,2],sens:[7,2],draggabl:9,sent:2,at_position_list:8,electron:9,stackoverflow:8,untouch:2,relev:6,gender:[10,2],button:7,"try":[0,7,8],thiscours:7,require_attempt:7,chap2:7,chap1:7,second_quest:10,marri:6,pleas:[0,7,9,2,3],impli:2,smaller:9,natur:6,jump:[7,5],video:[7,5,2,11],accomod:2,download:[7,2],click:[9,2],append:7,compat:7,index:[7,2],compar:9,access:[6,2,7],secret_pag:7,mathjax:6,whatev:8,xmodul:[1,6,11,10],chose:6,"7ae_tkgabwa":7,bachelor:2,let:[7,2],course_num:2,becom:[7,9,11],implicit:6,convert:6,survei:[7,2],b_x__d:4,chang:[6,9,2,3,7],control:6,heart:8,appli:[0,6,9,2],combinedopenend:2,api:[1,6],revot:10,avatar_typ:2,cloud:9,from:[8,2,5,6,7,9,10],commun:7,doubl:[7,2],next:[7,5,9,6],commut:4,sort:8,course_info:7,trail:7,name4:9,rare:2,iii:7,women:6,save_problem_check:5,account:2,retriev:3,unenrol:2,obvious:7,verify_uuid:2,numericalrepons:3,malform:7,t6_c:9,tar:5,process:[6,5,2,3,7],"002x":[7,2],loco:8,high:[8,2],tag:[0,1,2,6,7,8,9,10,11],tab:[1,2,7],t4_h:9,img1:9,subdirectori:7,instead:[8,6,2,7],sin:6,frac:6,stop:2,year_of_birth:2,add30min:2,essenti:[9,6],correspond:[8,2,3,5,6,7],element:[8,2,5,6,7,9],issu:2,allow:[0,8,2,4,5,6,7,9],elig:3,move:[7,9,6],comma:[7,6],"6002x_exit_respons":2,t3_h:9,textbook_1:7,"02x":2,textbook_2:7,date_of_birth:2,external_link:7,therefor:6,advertised_start:7,generatedcertif:2,handl:[7,9,6],overal:0,show_answ:5,handi:7,anyth:[8,7,2],edit:[8,7,6],plot_label:6,slide:[7,6],t8_h:9,"10px":6,beneath:0,consum:1,meta:2,"static":[1,7,9,6,4],our:[8,1,2,7],tenth:2,special:[6,2,7],out:[7,9,2],variabl:[0,4,11,7],s_r:9,oe_show_full_feedback:5,categori:[8,7,5,2],module_typ:2,rel:[6,9,2,3],s_l:9,red:6,clarifi:7,p_pi_nam:9,insid:[8,6,9,2,7],book1:7,book2:7,dictionari:[0,7,8,2],tempt:6,enrollment_end:7,afterward:2,t1_o:9,indent:0,could:[8,7,2,3],ask:[8,2],keep:[7,2],aren:7,length:[7,9,2],enforc:2,t7_h:9,organiz:7,endors:8,"2013_spring":[8,7],mai:[0,2,5,6,7,9],prioriti:2,secret_video:7,unknown:[0,6],system:[1,2,3,6,7,10],messag:[0,11],attach:[8,9,6],attack:8,"final":[1,2,3],slider:[1,9,6],exactli:3,haven:7,structur:[8,1,7],charact:[4,2,6,7],reposit:6,deliveri:2,auto_incr:2,fail:3,have:[0,8,2,3,6,7,9],tabl:[1,2,7],need:[4,9,2,6,7],interesting_tag:2,"07t11":2,min:6,mix:6,group_target:9,which:[2,5,6,7,9,11],mit:2,singl:[7,9,6,3,11],unless:2,who:[8,1,2,3,5,6,9],why:7,url:[8,7,5,9,2],gather:2,request:[6,5,2],absurd:9,determin:[6,2],"_id":8,fact:[7,2],platon:7,text:[8,2,6,7,9,10],addhalftim:2,watch:5,input_list:0,bedroom:7,staff:[8,7,2],inlin:[7,6],locat:[1,5,2,11,7],enrollment_start:7,should:[1,9,2,6,7],suppos:[9,2],local:7,hope:2,meant:[8,6],dependenti:5,per_stud:7,chapter5:7,chapter4:7,chapter7:7,chapter6:7,chapter1:7,chapter3:7,chapter2:7,mul:2,increas:[8,6],htmlchapter:7,enabl:7,organ:[7,5,2],down_count:8,y_2:6,y_1:6,grai:9,integr:[7,2],contain:[0,8,2,3,5,6,7,9,11],your_m_tx_yss:6,view:[7,2],symbolicmathjaxpreprocessor:4,knowledg:7,custom_tag:7,statu:2,correctli:0,pattern:7,tend:2,favor:2,state:[1,5,2,7],progress:[1,2,3,7],email:2,exam:[7,2,3],kei:[7,5,9,2],dynamic_mathjax:6,static_tab:7,moving_label:6,pdfchapter:7,job:0,entir:[0,2],s_sigma_nam:9,out_text:6,addit:[7,2],stat2:8,admin:[8,7,2],accordion:7,equal:[0,8,9,2,3],etc:[8,2,3,6,7,9,11],no_label:9,instanc:[7,9,6,11],grain:6,equat:6,comment:[8,1,6],walk:2,respect:3,is_superus:2,compos:6,json:[8,2,3,5,6,7],treat:6,immedi:2,muddl:2,"091x":2,togeth:[7,2],auth_us:[8,2],"15t17":2,"15t12":7,align:6,rectangular:9,defin:[8,3,6,7,9,10],yss:6,is_complet:11,layer:8,old_email:2,almost:2,demo:9,site:[5,2],substanti:2,revis:4,scienc:[7,2],cohort:7,welcom:7,sqrt:6,member:2,python:[0,1,9],largest:2,s15v14_response_to_impulse_limit_cas:7,spell:2,http:7,effect:[6,2],dai:[7,2],name_label_icon3:9,student:[0,1,2,3,5,7,8,9],uni:2,expand:7,center:[9,6],abtest:7,well:[0,7,2],exampl:[0,8,2,3,4,5,6,7,9,10,11],dyn_val_1:6,choos:2,undefin:[5,6],favorite_part:2,tags_arrai:8,usual:[8,6,2],lest:[9,6],paus:[7,5],obtain:9,distant:7,methan:9,simultan:7,demograph:2,web:[7,2],wed:7,parent_id:8,add:[6,2,7],other:[0,1,2,3,6,7,8,9],match:[7,6,3],gmt:5,orbital_tripl:9,draganddrop:9,varieti:2,piec:[8,7,2],punctuat:2,realiz:2,five:2,know:[7,2],press:7,password:2,insert:6,resid:9,like:[8,6,9,2,7],success:5,unord:9,necessari:[6,9,2,7],page:[1,5,2,3,7],npoint:5,didn:[7,2],gradebook:3,"export":[1,2],pause_video:5,wonderwiki:7,proper:[7,9],guarante:2,mainli:6,lead:[7,6],avoid:5,overlap:9,leav:[7,2,3],overlai:6,p_sigma_star:9,mitx:[5,2,11],usag:9,symlink:11,host:7,offset:9,slug:7,panel:7,about:[0,1,8,2,7],actual:[8,6,9,2,7],disabl:[7,6],own:[6,2,7],automat:[6,9,2,3,7],assess:[7,2],guard:2,xyz987293487293847:7,ethglycol:9,merg:7,support:[8,4,2,3,7],trigger:[5,2],inner:[9,10],"var":6,"function":[0,7,6,3,10],"03t04":7,subsum:7,bodi:[8,6],ear:9,eat:8,count:[8,7],made:[8,7,5,2],whether:[0,2,3,5,7,9],wish:2,displai:[0,1,2,3,7,8,10],record:[5,2],below:[8,2,5,6,7,9],limit:[9,2],otherwis:[9,2],problem:[0,1,2,3,4,5,7,8,9,11],"int":[0,2],dure:[7,5,2],filenam:[7,5],updated_at:8,implement:[8,6],poll_quest:[10,11],probabl:[7,2],tick:6,musubi:8,percent:6,detail:[7,5,2],book:[7,5],lookup:2,futur:[7,2],rememb:6,pi_:9,more25:10,star:9,p_sigma:9,preform:6,stai:7,dave:2,rule:9,hintmod:5,auto_cohort_group:7,invari:7,textbook_icon:7},objtypes:{"0":"py:module"},titles:["CustomResponse XML and Python Script","edX Data Documentation","Student Info and Progress Data","Course Grading","Symbolic Response","Tracking Logs","XML format of graphical slider tool [xmodule]","Course XML Tutorial","Discussion Forums Data","XML format of drag and drop input [inputtypes]","Xml format of poll module [xmodule]","Xml format of conditional module [xmodule]"],objnames:{"0":["py","module","Python module"]},filenames:["course_data_formats/custom_response","index","internal_data_formats/sql_schema","course_data_formats/grading","course_data_formats/symbolic_response","internal_data_formats/tracking_logs","course_data_formats/graphical_slider_tool/graphical_slider_tool","course_data_formats/course_xml","internal_data_formats/discussion_data","course_data_formats/drag_and_drop/drag_and_drop_input","course_data_formats/poll_module/poll_module","course_data_formats/conditional_module/conditional_module"]})
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment