Commit 661f37ec by Calen Pennington

Merge remote-tracking branch 'edx/master' into opaque-keys-merge-master

Conflicts:
	lms/djangoapps/courseware/tests/test_views.py
	lms/djangoapps/instructor/tests/test_api.py
	lms/djangoapps/instructor/tests/test_legacy_anon_csv.py
	lms/djangoapps/instructor/views/api.py
	lms/djangoapps/instructor/views/legacy.py
parents 44b15619 0a6ea26c
@shard_3 @shard_1
Feature: CMS Video Component Editor Feature: CMS Video Component Editor
As a course author, I want to be able to create video components As a course author, I want to be able to create video components
......
...@@ -142,3 +142,8 @@ To add a course team member: ...@@ -142,3 +142,8 @@ To add a course team member:
#. Click **Add a New Team Member**. #. Click **Add a New Team Member**.
#. Enter the new team member's email address, then click **ADD USER**. #. Enter the new team member's email address, then click **ADD USER**.
You can also assign privileged roles to users when you work in the LMS.
Regardless of where the role is assigned, these administrative team members can
work on your course in both the LMS and in Studio. For more information on
assigning roles while you run your course, see
:ref:`Course_Staffing`.
\ No newline at end of file
...@@ -12,12 +12,22 @@ May, 2014 ...@@ -12,12 +12,22 @@ May, 2014
* - Date * - Date
- Change - Change
- 05/13/14 * - 05/14/14
- Updated the :ref:`Running Your Course Index` chapter to remove references
to the "new beta" Instructor Dashboard.
* -
- Updated the :ref:`Enrollment` section to reflect that usernames or email - Updated the :ref:`Enrollment` section to reflect that usernames or email
addresses can be used to batch enroll students. addresses can be used to batch enroll students.
* -
- Updated the :ref:`Grades` section to reflect new features on the problem
**Staff Debug** viewer for rescoring, resetting attempts, and deleting
student state.
* -
- Updated the :ref:`Course_Staffing` section to state the labeling
differences between Studio and the LMS with respect to course team roles.
* - 05/09/14 * - 05/09/14
- Updated :ref:`Assigning_discussion_roles` with a note about course staff requiring - Updated :ref:`Assigning_discussion_roles` with a note about course staff
explicit granting of discussion administration roles. requiring explicit granting of discussion administration roles.
* - * -
- Added :ref:`VitalSource` topic. - Added :ref:`VitalSource` topic.
* - 05/08/14 * - 05/08/14
...@@ -26,7 +36,8 @@ May, 2014 ...@@ -26,7 +36,8 @@ May, 2014
- Updated the :ref:`Discussions` chapter to include a topic on closing - Updated the :ref:`Discussions` chapter to include a topic on closing
discussions. discussions.
* - 05/06/14 * - 05/06/14
- Expanded the :ref:`Grades` chapter to include a topic on interpreting the score histograms for problems. - Expanded the :ref:`Grades` chapter to include a topic on interpreting the
score histograms for problems.
* - * -
- Updated :ref:`LTI Component` to reflect changes to the Studio UI. - Updated :ref:`LTI Component` to reflect changes to the Studio UI.
* - 05/02/14 * - 05/02/14
......
...@@ -21,9 +21,7 @@ To view course data: ...@@ -21,9 +21,7 @@ To view course data:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** then **Try New Beta Dashboard**. #. Click **Instructor**, then click **Course Info** if necessary.
#. Click **Course Info** if necessary.
The **Basic Course Information** section of the page that opens lists The **Basic Course Information** section of the page that opens lists
information about the course. information about the course.
......
...@@ -86,9 +86,7 @@ To enroll students or staff members: ...@@ -86,9 +86,7 @@ To enroll students or staff members:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** then **Try New Beta Dashboard**. #. Click **Instructor**, then click **Membership**.
#. Click **Membership**.
#. In the **Batch Enrollment** section of the page, enter the username or email #. In the **Batch Enrollment** section of the page, enter the username or email
address of the student, or enter multiple names or addresses separated by address of the student, or enter multiple names or addresses separated by
...@@ -98,7 +96,7 @@ To enroll students or staff members: ...@@ -98,7 +96,7 @@ To enroll students or staff members:
note that this feature is better suited to courses with smaller enrollments, note that this feature is better suited to courses with smaller enrollments,
rather than courses with massive enrollments. rather than courses with massive enrollments.
5. To streamline the course enrollment process, leave **Auto Enroll** selected. 4. To streamline the course enrollment process, leave **Auto Enroll** selected.
#. To send students an email message, leave **Notify students by email** #. To send students an email message, leave **Notify students by email**
selected. selected.
...@@ -129,9 +127,7 @@ To view the enrollment count for a course: ...@@ -129,9 +127,7 @@ To view the enrollment count for a course:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** then **Try New Beta Dashboard**. #. Click **Instructor**, then click **Course Info** if necessary.
#. Click **Course Info** if necessary.
The **Enrollment Information** section of the page that opens shows the total The **Enrollment Information** section of the page that opens shows the total
number of people who are currently enrolled. number of people who are currently enrolled.
......
...@@ -4,7 +4,11 @@ ...@@ -4,7 +4,11 @@
Grade and Answer Data Grade and Answer Data
############################ ############################
You can review information about how grading is configured for your course, and access student grades, at any time after you create the course. You can also make adjustments to how a problem is graded, for a single student or all students. For information about the grading data that you can access and the changes you can make, see the following topics: You can review information about how grading is configured for your course, and
access student grades, at any time after you create the course. You can also
make adjustments to student grading for a problem, for a single student or all
students. For information about the grading data that you can access and the
changes you can make, see the following topics:
* :ref:`Review_grades` * :ref:`Review_grades`
...@@ -16,7 +20,7 @@ To review student answers to the problems in your course, you can download data ...@@ -16,7 +20,7 @@ To review student answers to the problems in your course, you can download data
For information about how you establish a grading policy and work with the Problem components in your course, see :ref:`Establish a Grading Policy` or :ref:`Working with Problem Components`. For information about how you establish a grading policy and work with the Problem components in your course, see :ref:`Establish a Grading Policy` or :ref:`Working with Problem Components`.
.. important:: If you make changes to your grading policy after a course starts, students can see the effect of your changes on their **Progress** pages. Be sure to announce any changes on your Course Info page. .. important:: If you make changes to your grading policy after a course starts, students can see the effect of your changes on their **Progress** pages. Be sure to announce any changes on your **Course Info** page.
.. _Review_grades: .. _Review_grades:
...@@ -30,9 +34,7 @@ You establish a grading policy for your course when you create it in Studio. Whi ...@@ -30,9 +34,7 @@ You establish a grading policy for your course when you create it in Studio. Whi
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** > **Try New Beta Dashboard**. #. Click **Instructor**, then click **Data Download** > **Grading Configuration**.
#. Click **Data Download** > **Grading Configuration**.
A list of the assignment types in your course displays. In this example, Homework is weighted as 0.3 (30%) of the grade. A list of the assignment types in your course displays. In this example, Homework is weighted as 0.3 (30%) of the grade.
...@@ -64,15 +66,13 @@ To generate grades for the students who are currently enrolled in your course: ...@@ -64,15 +66,13 @@ To generate grades for the students who are currently enrolled in your course:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** > **Try New Beta Dashboard**. #. Click **Instructor**, then click **Data Download**.
#. Click **Data Download**.
#. To start the grading process, click **Generate Grade Report**. #. To start the grading process, click **Generate Grade Report**.
A status message indicates that the grading process is in progress. This process can take some time to complete, but you can navigate away from this page and do other work while it runs. A status message indicates that the grading process is in progress. This process can take some time to complete, but you can navigate away from this page and do other work while it runs.
5. To track the progress of the grading process, reload the page in your browser and scroll down to the **Pending Instructor Tasks** section. 4. To track the progress of the grading process, reload the page in your browser and scroll down to the **Pending Instructor Tasks** section.
========================================== ==========================================
Download Grades for Enrolled Students Download Grades for Enrolled Students
...@@ -86,9 +86,7 @@ To download a file of student grades: ...@@ -86,9 +86,7 @@ To download a file of student grades:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** > **Try New Beta Dashboard**. #. Click **Instructor**, then click **Data Download**.
#. Click **Data Download**.
#. To open or save a grade report file, click the ``{course_id}_grade_report_{date}.csv`` file name at the bottom of the page. #. To open or save a grade report file, click the ``{course_id}_grade_report_{date}.csv`` file name at the bottom of the page.
...@@ -133,9 +131,7 @@ To view the **Progress** page for a student: ...@@ -133,9 +131,7 @@ To view the **Progress** page for a student:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** > **Try New Beta Dashboard**. #. Click **Instructor**, then click **Student Admin**.
#. Click **Student Admin**.
#. In the Student-Specific Grade Inspection section, enter the student's email address or username. #. In the Student-Specific Grade Inspection section, enter the student's email address or username.
...@@ -153,7 +149,7 @@ To view the **Progress** page for a student: ...@@ -153,7 +149,7 @@ To view the **Progress** page for a student:
Below the chart, subsections are listed on the left and the units that contain assignments are listed on the right. The student's individual problem scores display. Below the chart, subsections are listed on the left and the units that contain assignments are listed on the right. The student's individual problem scores display.
.. image:: ../Images/Student_Progress_list.png .. image:: ../Images/Student_Progress_list.png
:alt: Bottom portion of a Progress page for the same student with the score acheived for each problem in the first course subsection :alt: Bottom portion of a Progress page for the same student with the score acheived for each problem in the first course subsection
============================================= =============================================
...@@ -196,26 +192,38 @@ To review a response submitted by a student: ...@@ -196,26 +192,38 @@ To review a response submitted by a student:
#. Enter the username for the student whose work you want to review, then click **View History** at the end of the page. #. Enter the username for the student whose work you want to review, then click **View History** at the end of the page.
Information about the response or responses provided by the student displays. Information about the response or responses provided by the student displays.
To close the Submission History Viewer, click on the browser page outside of the viewer. To close the Submission History Viewer, click on the browser page outside of the viewer.
.. _Adjust_grades: .. _Adjust_grades:
*********************************** ***********************************
Adjust Grades Adjust Grades
*********************************** ***********************************
You can adjust grades for one student at a time, or for all of the enrolled students in the course. For example, your course beta testers can evaluate numerous different correct and incorrect responses to verify that your course is set up as you intend. Students can also report errors while a course is running. You can adjust grades for one student at a time, or for all of the enrolled
students in the course. For example, your course beta testers can evaluate
numerous different correct and incorrect responses to verify that your course is
set up as you intend. Students can also report errors while a course is running.
When an error is discovered or corrected, or if you decide that you must modify
a problem after students or beta testers have attempted to answer it, you can
either:
When an error is discovered or corrected, or if you decide that you must modify a problem after students or beta testers have attempted to answer it, you can either: * Rescore the submitted answers to reevaluate the work. See :ref:`rescore`.
* Rescore the submitted answers to reevaluate the work. * Reset the number of times a student has attempted to answer the problem to
zero so that the student can try again. See :ref:`reset_attempts`.
* Reset the number of attempts made to answer the question correctly so that students can try again. You can make these adjustments for a single student or for all of the students
enrolled in your course. To make an adjustment for all students, you need the unique identifier of the problem. See :ref:`find_URL`.
To make these adjustments, you need to specify a problem by supplying the unique identifier from its URL. Another grade adjustment technique is to delete a student's database history, or
"state", completely for a problem. You can only delete student state for
individual students. For example, you realize that a problem needs to be
rewritten after only a few of your students have answered it. To resolve this
situation, you rewrite the problem and then delete student state for the
affected students only so that they can try again. See :ref:`delete_state`.
.. _find_URL: .. _find_URL:
...@@ -238,75 +246,172 @@ To find the unique identifier in the URL for a problem: ...@@ -238,75 +246,172 @@ To find the unique identifier in the URL for a problem:
.. image:: ../Images/Problem_URL.png .. image:: ../Images/Problem_URL.png
:alt: The Staff Debug view of a problem with the unique identifier indicated at the end of a URL address :alt: The Staff Debug view of a problem with the unique identifier indicated at the end of a URL address
4. To copy the identifier for the problem, select it, right click, and choose **Copy**. 4. To copy the identifier for the problem, select it, right click, and choose **Copy**.
.. note:: If the URL does not include "problem/" before the identifier, you will need to specify that module identifier as well. Select and copy both the module identifier and the problem identifier. .. note:: If the URL does not include "problem/" before the identifier, you will need to specify that module identifier as well. Select and copy both the module identifier and the problem identifier.
To close the Staff Debug viewer, click on the browser page outside of the viewer. To close the Staff Debug viewer, click on the browser page outside of the viewer.
.. _rescore:
=================================================== ===================================================
Rescore Student Submissions Rescore Student Submissions for a Problem
=================================================== ===================================================
Each problem that you define for your course includes a correct answer, and may also include a tolerance or acceptable alternatives. If you decide to make a change to these values, you can rescore any responses that were already submitted. For a specified problem, you can rescore the work submitted by a single student, or rescore the submissions made by every enrolled student. Each problem that you define for your course includes a correct answer, and may
also include a tolerance or acceptable alternatives. If you decide to make a
change to these values, you can rescore any responses that were already
submitted. For a specified problem, you can rescore the work submitted by a
single student, or rescore the submissions made by every enrolled student.
**Note**: You can only rescore problems that have a correct answer entered in edX Studio. Problems that are scored by an external grader cannot be rescored with this procedure. .. note:: You can only rescore problems that have a correct answer entered in edX Studio. This procedure cannot be used to rescore problems that are scored by an external grader.
To specify the problem you want to rescore, you need its unique identifier. See :ref:`find_URL`. Rescore a Submission for an Individual Student
-----------------------------------------------
To rescore a problem: To rescore a problem for a single student, you need that student's username or
email address.
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** > **Try New Beta Dashboard**. #. Click **Courseware** and navigate to the component that contains the problem
you want to rescore.
#. Display the problem, then click **Staff Debug Info**. The Staff Debug viewer
opens.
#. In the **Username** field, enter the student's email address or username,
then click **Rescore Student Submission**. A message indicates a successful
adjustment.
#. To close the Staff Debug viewer, click on the browser page outside of the
viewer.
#. Click **Student Admin**. Rescore Submissions for All Students
------------------------------------
#. Rescore the problem, either for an individual student or for all students. To specify the problem you want to rescore, you need its unique identifier. See :ref:`find_URL`. To rescore a problem:
To rescore a problem for one student, you work in the **Student-Specific Grade Adjustment** section of the page. Enter the student's email address or username and the unique problem identifier, and then click **Rescore Student Submission**. #. View the live version of your course.
#. Click **Instructor**, then click **Student Admin**.
To rescore a problem for all enrolled students, you work in the **Course-Specific Grade Adjustment** section of the page. Enter the unique problem identifier, and then click **Rescore ALL students' problem submissions**. #. In the **Course-Specific Grade Adjustment** section of the page, enter the
unique problem identifier, and then click **Rescore ALL students' problem
submissions**.
5. When you see a dialog box that notifies you that the rescore process is in progress, click **OK**. #. When you see a dialog box that notifies you that the rescore process is in
progress, click **OK**.
This process does not take long for a single student, but can take some time to complete for all enrolled students. The process runs in the background, so you can navigate away from this page and do other work while it runs. This process can take some time to complete for all enrolled students. The
process runs in the background, so you can navigate away from this page and
do other work while it runs.
6. To view the results of the rescore process, click either **Show Background Task History for Student** or **Show Background Task History for Problem**. 6. To view the results of the rescore process, click either **Show Background
Task History for Student** or **Show Background Task History for Problem**.
A table displays the status of the rescore process for each student or problem. A table displays the status of the rescore process for each student or problem.
.. note:: You can use a similar procedure to rescore the submission for a problem by a single student. You work in the **Student-Specific Grade Adjustment** section of the page to enter both the student’s email address or username and the unique problem identifier, and then click **Rescore Student Submission**.
.. _reset_attempts:
=================================================== ===================================================
Reset Student Attempts Reset Student Attempts for a Problem
=================================================== ===================================================
When you create a problem, you can limit the number of times that a student can try to answer that problem correctly. If unexpected issues occur for a problem, you can reset the value for one particular student's attempts back to zero so that the student can begin work over again. If the unexpected behavior affects all of the students in your course, you can reset the number of attempts for all students to zero. When you create a problem, you can limit the number of times that a student can try to answer that problem correctly. If unexpected issues occur for a problem, you can reset the value for one particular student's attempts back to zero so that the student can begin work over again. If the unexpected behavior affects all of the students in your course, you can reset the number of attempts for all students to zero.
For information about modifying a released problem, including other workarounds, see :ref:`Modifying a Released Problem`. For information about modifying a released problem, including other workarounds, see :ref:`Modifying a Released Problem`.
**Note**: To reset the number of attempts for a problem, you need its unique identifier. See :ref:`find_URL`. Reset Attempts for an Individual Student
---------------------------------------------
To reset student attempts for a problem: To reset the number of attempts for a single student, you need that student's
username or email address.
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** > **Try New Beta Dashboard**. #. Click **Courseware** and navigate to the component that contains the problem
you want to reset.
#. Display the problem, then click **Staff Debug Info**. The Staff Debug viewer
opens.
#. Click **Student Admin**. #. In the **Username** field, enter the student's email address or username,
then click **Reset Student Attempts**. A message indicates a successful
adjustment.
#. To close the Staff Debug viewer, click on the browser page outside of the
viewer.
Reset Attempts for All Students
------------------------------------
To reset the number of attempts that all enrolled students have for a problem,
you need the unique identifier of the problem. See :ref:`find_URL`. To reset
attempts for all students:
#. View the live version of your course.
#. To reset the number of attempts for one student, you work in the Student-Specific Grade Adjustment section of the page. Enter the student's email address or username and the unique problem identifier, then click **Reset Student Attempts**. #. Click **Instructor**, then click **Student Admin**.
#. To reset the number of attempts for all enrolled students, you work in the Course-Specific Grade Adjustment section of the page. Enter the unique problem identifier then click **Reset ALL students' attempts**. #. To reset the number of attempts for all enrolled students, you work in the
**Course-Specific Grade Adjustment** section of the page. Enter the unique
problem identifier, then click **Reset ALL students' attempts**.
#. A dialog opens to indicate that the reset process is in progress. Click **OK**. #. A dialog opens to indicate that the reset process is in progress. Click **OK**.
This process does not take long for a single student, but can take some time to complete for all enrolled students. The process runs in the background, so you can navigate away from this page and do other work while it runs. This process can take some time to complete. The process runs in the
background, so you can navigate away from this page and do other work while
it runs.
7. To view the results of the reset process, click either **Show Background Task History for Student** or **Show Background Task History for Problem**. 7. To view the results of the reset process, click either **Show Background Task History for Student** or **Show Background Task History for Problem**.
A table displays the status of the reset process for each student or problem. A table displays the status of the reset process for each student or problem.
.. note:: You can use a similar procedure to reset problem attempts for a single student. You work in the **Student-Specific Grade Adjustment** section of the page to enter both the student’s email address or username and the unique problem identifier, and then click **Reset Student Attempts**.
.. _delete_state:
=============================================
Delete Student State for a Problem
=============================================
To delete a student's entire history for a problem from the database, you need
that student's username or email address.
.. important:: Student state is deleted permanently by this process. This action cannot be undone.
You can use either the Staff Debug viewer or the Instructor Dashboard to delete
student state.
.. future example: this is how to help a student who has gotten poor feedback on an ORA problem.
To use the Staff Debug viewer:
#. View the live version of your course.
#. Click **Courseware** and navigate to the component that contains the problem.
#. Display the problem, then click **Staff Debug Info**. The Staff Debug viewer
opens.
#. In the **Username** field, enter the student's email address or username,
then click **Delete Student State**. A message indicates a successful
adjustment.
#. To close the Staff Debug viewer, click on the browser page outside of the
viewer.
To use the Instructor Dashboard, you need the unique identifier of the problem.
See :ref:`find_URL`.
#. Click **Instructor**, then click **Student Admin**.
#. In the **Student-Specific Grade Adjustment** section of the page, enter both
the student’s email address or username and the unique problem identifier,
and then click **Delete Student State for Problem**.
.. _Review_Answers: .. _Review_Answers:
**************************************** ****************************************
...@@ -365,9 +470,7 @@ To download the most recent file of student answer data: ...@@ -365,9 +470,7 @@ To download the most recent file of student answer data:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** > **Try New Beta Dashboard**. #. Click **Instructor**, then click **Data Download**.
#. Click **Data Download**.
#. At the bottom of the page, click the ``{course_id}_answer_distribution.csv`` file name. You may have to scroll down to find this file. #. At the bottom of the page, click the ``{course_id}_answer_distribution.csv`` file name. You may have to scroll down to find this file.
...@@ -459,9 +562,7 @@ To display the distribution of scores for a problem: ...@@ -459,9 +562,7 @@ To display the distribution of scores for a problem:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** > **Try New Beta Dashboard**. #. Click **Instructor**, then click **Analytics**.
#. Click **Analytics**.
#. In the Score Distribution section, select a problem by using its unique identifier. #. In the Score Distribution section, select a problem by using its unique identifier.
......
...@@ -12,14 +12,13 @@ for working with students, grades, and other members of the staff. ...@@ -12,14 +12,13 @@ for working with students, grades, and other members of the staff.
* Instructors * Instructors
.. **Question**: how does this team, set up on the Instructor Dashboard, differ from the "Course Team Members" that you add in Studio (Settings > Course Team)? You can assign these privileged roles when you work in either the LMS or in
Studio, and the users who have these roles can work on your course in both the
The administrative team that helps you run your course in the LMS can include LMS and Studio. For more information on setting up a team in Studio, see
some, all, or none of the people who help you set up the course in Studio. You
assign these administrative roles in the LMS, separately from the roles you
assign in Studio. For more information on setting up a team in Studio, see
:ref:`Add Course Team Members`. :ref:`Add Course Team Members`.
.. note:: The LMS "Course Staff" role is the same as the Studio "Staff" role, and the LMS "Instructors" role is the same as the Studio "Admin" role.
You can also designate teams of people to beta test your course and to You can also designate teams of people to beta test your course and to
moderate and manage its discussions by assigning other LMS roles. The beta moderate and manage its discussions by assigning other LMS roles. The beta
testers and discussion administrators must be enrolled in your course, but testers and discussion administrators must be enrolled in your course, but
...@@ -76,9 +75,7 @@ To assign a staff role: ...@@ -76,9 +75,7 @@ To assign a staff role:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** then **Try New Beta Dashboard**. #. Click **Instructor**, then click **Membership**.
#. Click **Membership**.
#. In the **Administration List Management** section, use the drop-down list to #. In the **Administration List Management** section, use the drop-down list to
select **Course Staff** or **Instructors**. select **Course Staff** or **Instructors**.
......
...@@ -81,9 +81,7 @@ To download or view student data: ...@@ -81,9 +81,7 @@ To download or view student data:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** then **Try New Beta Dashboard**. #. Click **Instructor**, then click **Data Download**.
#. Click **Data Download**.
#. To download data about enrolled students in a CSV file, click **Download profile information as a CSV**. #. To download data about enrolled students in a CSV file, click **Download profile information as a CSV**.
...@@ -108,9 +106,7 @@ To display demographic data for your students: ...@@ -108,9 +106,7 @@ To display demographic data for your students:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** then **Try New Beta Dashboard**. #. Click **Instructor**, then click **Analytics**.
#. Click **Analytics**.
* The Year of Birth section displays a chart of enrolled students plotted by year of birth. * The Year of Birth section displays a chart of enrolled students plotted by year of birth.
...@@ -139,9 +135,8 @@ To download a file of assigned user IDs and anonymized user IDs: ...@@ -139,9 +135,8 @@ To download a file of assigned user IDs and anonymized user IDs:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** > **Try New Beta Dashboard**. #. Click **Instructor**, then click **Data Download**.
#. Click **Get Student Anonymized IDs CSV**.
#. Click **Data Download** > **Get Student Anonymized IDs CSV**.
You are prompted to open or save the (course-id)-anon-id.csv file for your course. This file contains the user ID that is assigned to each student at registration and its corresponding anonymized ID. Values are included for every student who ever enrolled for your course. You are prompted to open or save the (course-id)-anon-id.csv file for your course. This file contains the user ID that is assigned to each student at registration and its corresponding anonymized ID. Values are included for every student who ever enrolled for your course.
......
...@@ -97,15 +97,11 @@ Before you can assign roles to your discussion administrators, you need their em ...@@ -97,15 +97,11 @@ Before you can assign roles to your discussion administrators, you need their em
* To get this information for a staff member, on the Instructor Dashboard click **Membership** and then select **Course Staff** from the drop-down list. * To get this information for a staff member, on the Instructor Dashboard click **Membership** and then select **Course Staff** from the drop-down list.
* To get this information for an enrolled student, on the Instructor Dashboard click **Data Download** > **Download profile information as a CSV**. * To get this information for an enrolled student, on the Instructor Dashboard click **Data Download** > **Download profile information as a CSV**.
**Tip**: These instructions are for the new Instructor Dashboard: click **Try New Beta Dashboard**.
To assign a role: To assign a role:
#. View the live version of your course. #. View the live version of your course.
#. Click **Instructor** then **Try New Beta Dashboard**. #. Click **Instructor**, then click **Membership**.
#. Click **Membership**.
#. In the Administration List Management section, use the drop-down list to select Discussion Admins, Discussion Moderators, or Discussion Community TAs. #. In the Administration List Management section, use the drop-down list to select Discussion Admins, Discussion Moderators, or Discussion Community TAs.
......
...@@ -11,7 +11,7 @@ Change Log ...@@ -11,7 +11,7 @@ Change Log
* - Date * - Date
- Change - Change
* - 05/0614 * - 05/06/14
- Added enrollment event types to the :ref:`Tracking Logs` chapter. - Added enrollment event types to the :ref:`Tracking Logs` chapter.
* - 05/05/14 * - 05/05/14
- Removed information on the Poll module. `Polls <http://edx.readthedocs.org/projects/ca/en/latest/exercises_tools/poll.html>`_ are now covered in the *Building and Running an edX Course* guide. - Removed information on the Poll module. `Polls <http://edx.readthedocs.org/projects/ca/en/latest/exercises_tools/poll.html>`_ are now covered in the *Building and Running an edX Course* guide.
...@@ -31,7 +31,7 @@ Change Log ...@@ -31,7 +31,7 @@ Change Log
* - * -
- Reformatted the :ref:`Tracking Logs` chapter to improve readability. - Reformatted the :ref:`Tracking Logs` chapter to improve readability.
* - 03/28/14 * - 03/28/14
- Added the :ref:'Data_Czar' chapter. - Added the :ref:`Data_Czar` chapter.
* - 03/24/14 * - 03/24/14
- Added the ``user_api_usercoursetag`` table to the :ref:`Student_Info` chapter and the ``assigned_user_to_partition`` and ``child_render`` event types to the :ref:`Tracking Logs` chapter. - Added the ``user_api_usercoursetag`` table to the :ref:`Student_Info` chapter and the ``assigned_user_to_partition`` and ``child_render`` event types to the :ref:`Tracking Logs` chapter.
* - 03/19/14 * - 03/19/14
......
# coding=UTF-8
""" """
Tests courseware views.py Tests courseware views.py
""" """
...@@ -46,7 +47,7 @@ class TestJumpTo(TestCase): ...@@ -46,7 +47,7 @@ class TestJumpTo(TestCase):
self.course_key = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall') self.course_key = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
def test_jumpto_invalid_location(self): def test_jumpto_invalid_location(self):
location = self.course_key.make_usage_key(None, 'NoSuchPlace') location = self.course_key.make_usage_key(None, 'NoSuchPlace')
# This is fragile, but unfortunately the problem is that within the LMS we # This is fragile, but unfortunately the problem is that within the LMS we
# can't use the reverse calls from the CMS # can't use the reverse calls from the CMS
jumpto_url = '{0}/{1}/jump_to/{2}'.format('/courses', self.course_key.to_deprecated_string(), location.to_deprecated_string()) jumpto_url = '{0}/{1}/jump_to/{2}'.format('/courses', self.course_key.to_deprecated_string(), location.to_deprecated_string())
...@@ -121,14 +122,14 @@ class ViewsTestCase(TestCase): ...@@ -121,14 +122,14 @@ class ViewsTestCase(TestCase):
# depreciated function # depreciated function
mock_user = MagicMock() mock_user = MagicMock()
mock_user.is_authenticated.return_value = False mock_user.is_authenticated.return_value = False
self.assertEquals(views.user_groups(mock_user), []) self.assertEqual(views.user_groups(mock_user), [])
def test_get_current_child(self): def test_get_current_child(self):
self.assertIsNone(views.get_current_child(MagicMock())) self.assertIsNone(views.get_current_child(MagicMock()))
mock_xmodule = MagicMock() mock_xmodule = MagicMock()
mock_xmodule.position = -1 mock_xmodule.position = -1
mock_xmodule.get_display_items.return_value = ['one', 'two'] mock_xmodule.get_display_items.return_value = ['one', 'two']
self.assertEquals(views.get_current_child(mock_xmodule), 'one') self.assertEqual(views.get_current_child(mock_xmodule), 'one')
mock_xmodule_2 = MagicMock() mock_xmodule_2 = MagicMock()
mock_xmodule_2.position = 3 mock_xmodule_2.position = 3
mock_xmodule_2.get_display_items.return_value = [] mock_xmodule_2.get_display_items.return_value = []
...@@ -206,13 +207,13 @@ class ViewsTestCase(TestCase): ...@@ -206,13 +207,13 @@ class ViewsTestCase(TestCase):
chat_settings = views.chat_settings(mock_course, mock_user) chat_settings = views.chat_settings(mock_course, mock_user)
# Test the proper format of all chat settings # Test the proper format of all chat settings
self.assertEquals(chat_settings['domain'], domain) self.assertEqual(chat_settings['domain'], domain)
self.assertEquals(chat_settings['room'], "a-b-c_class") self.assertEqual(chat_settings['room'], "a-b-c_class")
self.assertEquals(chat_settings['username'], "johndoe@%s" % domain) self.assertEqual(chat_settings['username'], "johndoe@%s" % domain)
# TODO: this needs to be changed once we figure out how to # TODO: this needs to be changed once we figure out how to
# generate/store a real password. # generate/store a real password.
self.assertEquals(chat_settings['password'], "johndoe@%s" % domain) self.assertEqual(chat_settings['password'], "johndoe@%s" % domain)
def test_course_mktg_about_coming_soon(self): def test_course_mktg_about_coming_soon(self):
# we should not be able to find this course # we should not be able to find this course
...@@ -450,8 +451,16 @@ class ProgressPageTests(ModuleStoreTestCase): ...@@ -450,8 +451,16 @@ class ProgressPageTests(ModuleStoreTestCase):
MakoMiddleware().process_request(self.request) MakoMiddleware().process_request(self.request)
<<<<<<< HEAD
course = CourseFactory(start=datetime(2013, 9, 16, 7, 17, 28)) course = CourseFactory(start=datetime(2013, 9, 16, 7, 17, 28))
self.course = modulestore().get_course(course.id) # pylint: disable=no-member self.course = modulestore().get_course(course.id) # pylint: disable=no-member
=======
course = CourseFactory(
start=datetime(2013, 9, 16, 7, 17, 28),
grade_cutoffs={u'çü†øƒƒ': 0.75, 'Pass': 0.5},
)
self.course = modulestore().get_instance(course.id, course.location) # pylint: disable=no-member
>>>>>>> edx/master
self.chapter = ItemFactory(category='chapter', parent_location=self.course.location) # pylint: disable=no-member self.chapter = ItemFactory(category='chapter', parent_location=self.course.location) # pylint: disable=no-member
self.section = ItemFactory(category='sequential', parent_location=self.chapter.location) self.section = ItemFactory(category='sequential', parent_location=self.chapter.location)
...@@ -460,5 +469,15 @@ class ProgressPageTests(ModuleStoreTestCase): ...@@ -460,5 +469,15 @@ class ProgressPageTests(ModuleStoreTestCase):
def test_pure_ungraded_xblock(self): def test_pure_ungraded_xblock(self):
ItemFactory(category='acid', parent_location=self.vertical.location) ItemFactory(category='acid', parent_location=self.vertical.location)
<<<<<<< HEAD
resp = views.progress(self.request, self.course.id.to_deprecated_string()) resp = views.progress(self.request, self.course.id.to_deprecated_string())
self.assertEquals(resp.status_code, 200) self.assertEquals(resp.status_code, 200)
=======
resp = views.progress(self.request, self.course.id)
self.assertEqual(resp.status_code, 200)
def test_non_asci_grade_cutoffs(self):
resp = views.progress(self.request, self.course.id)
self.assertEqual(resp.status_code, 200)
>>>>>>> edx/master
...@@ -1324,18 +1324,28 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa ...@@ -1324,18 +1324,28 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
self.assertEqual(student_json['username'], student.username) self.assertEqual(student_json['username'], student.username)
self.assertEqual(student_json['email'], student.email) self.assertEqual(student_json['email'], student.email)
@patch.object(instructor.views.api, 'anonymous_id_for_user', Mock(return_value='42'))
@patch.object(instructor.views.api, 'unique_id_for_user', Mock(return_value='41'))
def test_get_anon_ids(self): def test_get_anon_ids(self):
""" """
Test the CSV output for the anonymized user ids. Test the CSV output for the anonymized user ids.
""" """
<<<<<<< HEAD
url = reverse('get_anon_ids', kwargs={'course_id': self.course.id.to_deprecated_string()}) url = reverse('get_anon_ids', kwargs={'course_id': self.course.id.to_deprecated_string()})
with patch('instructor.views.api.unique_id_for_user') as mock_unique: with patch('instructor.views.api.unique_id_for_user') as mock_unique:
mock_unique.return_value = '42' mock_unique.return_value = '42'
response = self.client.get(url, {}) response = self.client.get(url, {})
=======
url = reverse('get_anon_ids', kwargs={'course_id': self.course.id})
response = self.client.get(url, {})
>>>>>>> edx/master
self.assertEqual(response['Content-Type'], 'text/csv') self.assertEqual(response['Content-Type'], 'text/csv')
body = response.content.replace('\r', '') body = response.content.replace('\r', '')
self.assertTrue(body.startswith('"User ID","Anonymized user ID"\n"2","42"\n')) self.assertTrue(body.startswith(
self.assertTrue(body.endswith('"7","42"\n')) '"User ID","Anonymized user ID","Course Specific Anonymized user ID"'
'\n"2","41","42"\n'
))
self.assertTrue(body.endswith('"7","41","42"\n'))
def test_list_report_downloads(self): def test_list_report_downloads(self):
url = reverse('list_report_downloads', kwargs={'course_id': self.course.id.to_deprecated_string()}) url = reverse('list_report_downloads', kwargs={'course_id': self.course.id.to_deprecated_string()})
......
...@@ -17,12 +17,13 @@ from django.core.urlresolvers import reverse ...@@ -17,12 +17,13 @@ from django.core.urlresolvers import reverse
from courseware.tests.helpers import LoginEnrollmentTestCase from courseware.tests.helpers import LoginEnrollmentTestCase
from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE
import instructor.views.legacy
from student.roles import CourseStaffRole from student.roles import CourseStaffRole
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.django import modulestore, clear_existing_modulestores from xmodule.modulestore.django import modulestore, clear_existing_modulestores
from xmodule.modulestore.locations import SlashSeparatedCourseKey from xmodule.modulestore.locations import SlashSeparatedCourseKey
from mock import patch from mock import Mock, patch
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
...@@ -51,14 +52,25 @@ class TestInstructorDashboardAnonCSV(ModuleStoreTestCase, LoginEnrollmentTestCas ...@@ -51,14 +52,25 @@ class TestInstructorDashboardAnonCSV(ModuleStoreTestCase, LoginEnrollmentTestCas
self.login(self.instructor, self.password) self.login(self.instructor, self.password)
self.enroll(self.toy) self.enroll(self.toy)
@patch.object(instructor.views.legacy, 'anonymous_id_for_user', Mock(return_value='42'))
@patch.object(instructor.views.legacy, 'unique_id_for_user', Mock(return_value='41'))
def test_download_anon_csv(self): def test_download_anon_csv(self):
course = self.toy course = self.toy
<<<<<<< HEAD
url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()}) url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()})
with patch('instructor.views.legacy.unique_id_for_user') as mock_unique: with patch('instructor.views.legacy.unique_id_for_user') as mock_unique:
mock_unique.return_value = 42 mock_unique.return_value = 42
response = self.client.post(url, {'action': 'Download CSV of all student anonymized IDs'}) response = self.client.post(url, {'action': 'Download CSV of all student anonymized IDs'})
=======
url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id})
response = self.client.post(url, {'action': 'Download CSV of all student anonymized IDs'})
>>>>>>> edx/master
self.assertEqual(response['Content-Type'], 'text/csv') self.assertEqual(response['Content-Type'], 'text/csv')
body = response.content.replace('\r', '') body = response.content.replace('\r', '')
self.assertEqual(body, '"User ID","Anonymized user ID"\n"2","42"\n') self.assertEqual(
body,
('"User ID","Anonymized user ID","Course Specific Anonymized user ID"'
'\n"2","41","42"\n')
)
...@@ -33,7 +33,7 @@ from django_comment_common.models import ( ...@@ -33,7 +33,7 @@ from django_comment_common.models import (
) )
from courseware.models import StudentModule from courseware.models import StudentModule
from student.models import unique_id_for_user, CourseEnrollment from student.models import CourseEnrollment, unique_id_for_user, anonymous_id_for_user
import instructor_task.api import instructor_task.api
from instructor_task.api_helper import AlreadyRunningError from instructor_task.api_helper import AlreadyRunningError
from instructor_task.views import get_task_completion_info from instructor_task.views import get_task_completion_info
...@@ -630,9 +630,15 @@ def get_anon_ids(request, course_id): # pylint: disable=W0613 ...@@ -630,9 +630,15 @@ def get_anon_ids(request, course_id): # pylint: disable=W0613
students = User.objects.filter( students = User.objects.filter(
courseenrollment__course_id=course_id, courseenrollment__course_id=course_id,
).order_by('id') ).order_by('id')
<<<<<<< HEAD
header = ['User ID', 'Anonymized user ID'] header = ['User ID', 'Anonymized user ID']
rows = [[s.id, unique_id_for_user(s)] for s in students] rows = [[s.id, unique_id_for_user(s)] for s in students]
return csv_response(course_id.to_deprecated_string().replace('/', '-') + '-anon-ids.csv', header, rows) return csv_response(course_id.to_deprecated_string().replace('/', '-') + '-anon-ids.csv', header, rows)
=======
header = ['User ID', 'Anonymized user ID', 'Course Specific Anonymized user ID']
rows = [[s.id, unique_id_for_user(s), anonymous_id_for_user(s, course_id)] for s in students]
return csv_response(course_id.replace('/', '-') + '-anon-ids.csv', header, rows)
>>>>>>> edx/master
@ensure_csrf_cookie @ensure_csrf_cookie
......
...@@ -40,7 +40,6 @@ from lms.lib.xblock.runtime import quote_slashes ...@@ -40,7 +40,6 @@ from lms.lib.xblock.runtime import quote_slashes
# Submissions is a Django app that is currently installed # Submissions is a Django app that is currently installed
# from the edx-ora2 repo, although it will likely move in the future. # from the edx-ora2 repo, although it will likely move in the future.
from submissions import api as sub_api from submissions import api as sub_api
from student.models import anonymous_id_for_user
from bulk_email.models import CourseEmail, CourseAuthorization from bulk_email.models import CourseEmail, CourseAuthorization
from courseware import grades from courseware import grades
...@@ -68,7 +67,12 @@ from instructor_task.views import get_task_completion_info ...@@ -68,7 +67,12 @@ from instructor_task.views import get_task_completion_info
from edxmako.shortcuts import render_to_response, render_to_string from edxmako.shortcuts import render_to_response, render_to_string
from class_dashboard import dashboard_data from class_dashboard import dashboard_data
from psychometrics import psychoanalyze from psychometrics import psychoanalyze
from student.models import CourseEnrollment, CourseEnrollmentAllowed, unique_id_for_user from student.models import (
CourseEnrollment,
CourseEnrollmentAllowed,
unique_id_for_user,
anonymous_id_for_user
)
from student.views import course_from_id from student.views import course_from_id
import track.views import track.views
from xblock.field_data import DictFieldData from xblock.field_data import DictFieldData
...@@ -688,9 +692,15 @@ def instructor_dashboard(request, course_id): ...@@ -688,9 +692,15 @@ def instructor_dashboard(request, course_id):
courseenrollment__course_id=course_key, courseenrollment__course_id=course_key,
).order_by('id') ).order_by('id')
<<<<<<< HEAD
datatable = {'header': ['User ID', 'Anonymized user ID']} datatable = {'header': ['User ID', 'Anonymized user ID']}
datatable['data'] = [[s.id, unique_id_for_user(s)] for s in students] datatable['data'] = [[s.id, unique_id_for_user(s)] for s in students]
return return_csv(course_key.to_deprecated_string().replace('/', '-') + '-anon-ids.csv', datatable) return return_csv(course_key.to_deprecated_string().replace('/', '-') + '-anon-ids.csv', datatable)
=======
datatable = {'header': ['User ID', 'Anonymized user ID', 'Course Specific Anonymized user ID']}
datatable['data'] = [[s.id, unique_id_for_user(s), anonymous_id_for_user(s, course_id)] for s in students]
return return_csv(course_id.replace('/', '-') + '-anon-ids.csv', datatable)
>>>>>>> edx/master
#---------------------------------------- #----------------------------------------
# Group management # Group management
......
...@@ -103,7 +103,7 @@ $(function () { ...@@ -103,7 +103,7 @@ $(function () {
descending_grades = sorted(grade_cutoffs, key=lambda x: grade_cutoffs[x], reverse=True) descending_grades = sorted(grade_cutoffs, key=lambda x: grade_cutoffs[x], reverse=True)
for grade in descending_grades: for grade in descending_grades:
percent = grade_cutoffs[grade] percent = grade_cutoffs[grade]
grade_cutoff_ticks.append( [ percent, "{0} {1:.0%}".format(grade, percent) ] ) grade_cutoff_ticks.append( [ percent, u"{0} {1:.0%}".format(grade, percent) ] )
else: else:
grade_cutoff_ticks = [ ] grade_cutoff_ticks = [ ]
%> %>
......
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