Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
problem-builder
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
problem-builder
Commits
a199b820
Commit
a199b820
authored
Jul 06, 2015
by
Tim Krones
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Display data to be exported in Student Answers Dashboard XBlock.
parent
caf07144
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
122 additions
and
12 deletions
+122
-12
problem_builder/public/css/student_answers_dashboard.css
+14
-3
problem_builder/public/js/student_answers_dashboard.js
+19
-0
problem_builder/tasks.py
+62
-0
problem_builder/templates/html/student_answers_dashboard.html
+27
-9
No files found.
problem_builder/public/css/student_answers_dashboard.css
View file @
a199b820
.data-export-options
{
.data-export-options
,
.data-export-results
{
margin-top
:
2em
;
}
.data-export-actions
button
{
display
:
none
;
}
.data-export-status
{
margin-top
:
2em
;
height
:
8em
;
}
.data-export-field
{
...
...
@@ -19,4 +20,15 @@
}
.data-export-field-container
{
margin-bottom
:
1em
;
}
\ No newline at end of file
}
.data-export-results
table
{
margin-top
:
1em
;
border
:
2px
solid
gray
;
}
.data-export-results
thead
{
border-bottom
:
2px
solid
gray
;
font-weight
:
bold
;
}
.data-export-results
td
{
padding
:
5px
;
}
problem_builder/public/js/student_answers_dashboard.js
View file @
a199b820
...
...
@@ -85,6 +85,25 @@ function StudentAnswersDashboardBlock(runtime, element) {
)
));
}
// Display results
var
$resultTable
=
$
(
'.data-export-results table tbody'
);
_
.
each
(
status
.
last_export_result
.
display_data
,
function
(
row
)
{
$resultTable
.
append
(
$
(
'<tr>'
).
html
(
_
.
template
(
'<td><%= section %></td>'
+
'<td><%= subsection %></td>'
+
'<td><%= unit %></td>'
+
'<td><%= type %></td>'
+
'<td><%= question %></td>'
+
'<td><%= answer %></td>'
+
'<td><%= username %></td>'
,
row
)
));
});
}
else
{
if
(
status
.
export_pending
)
{
$statusArea
.
append
(
$
(
'<p>'
).
text
(
...
...
problem_builder/tasks.py
View file @
a199b820
...
...
@@ -8,6 +8,8 @@ from celery.utils.log import get_task_logger
from
instructor_task.models
import
ReportStore
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.keys
import
UsageKey
,
CourseKey
from
student.models
import
user_by_anonymous_id
from
submissions.models
import
StudentItem
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
...
...
@@ -71,6 +73,8 @@ def export_data(course_id, source_block_id_str, block_types, user_id, get_root=T
rows
.
append
([
""
]
+
[
block
.
scope_ids
.
block_type
for
block
in
blocks_to_include
])
rows
.
append
([
""
]
+
[
block
.
scope_ids
.
usage_id
for
block
in
blocks_to_include
])
table
=
[]
# Load the actual student submissions for each block in blocks_to_include.
# Note this requires one giant query per block (all student submissions for each block, one block at a time)
student_submissions
=
{}
# Key is student ID, value is a list with same length as blocks_to_include
...
...
@@ -88,13 +92,19 @@ def export_data(course_id, source_block_id_str, block_types, user_id, get_root=T
'item_type'
:
block_type
,
}
submissions
=
sub_api
.
get_submissions
(
student_dict
,
limit
=
1
)
for
submission
in
submissions
:
# If the student ID key doesn't exist, we're dealing with a single student and know the ID already.
student_id
=
submission
.
get
(
'student_id'
,
user_id
)
if
student_id
not
in
student_submissions
:
student_submissions
[
student_id
]
=
[
student_id
]
+
[
""
]
*
len
(
blocks_to_include
)
student_submissions
[
student_id
][
idx
]
=
submission
[
'answer'
]
# Extract data for display
table_row
=
_extract_data_for_display
(
submission
,
student_id
,
block_type
)
table
.
append
(
table_row
)
# Now change from a dict to an array ordered by student ID as we generate the remaining rows:
for
student_id
in
sorted
(
student_submissions
.
iterkeys
()):
rows
.
append
(
student_submissions
[
student_id
])
...
...
@@ -113,4 +123,56 @@ def export_data(course_id, source_block_id_str, block_types, user_id, get_root=T
"report_filename"
:
filename
,
"start_timestamp"
:
start_timestamp
,
"generation_time_s"
:
generation_time_s
,
"display_data"
:
table
,
}
def
_extract_data_for_display
(
submission
,
student_id
,
block_type
):
"""
Extract data that will be displayed on Student Answers Dashboard
from `submission`.
"""
# Username
user
=
user_by_anonymous_id
(
student_id
)
username
=
user
.
username
# Question
student_item
=
StudentItem
.
objects
.
get
(
pk
=
submission
[
'student_item'
])
block_key
=
UsageKey
.
from_string
(
student_item
.
item_id
)
block
=
modulestore
()
.
get_item
(
block_key
)
# Answer
answer
=
submission
[
'answer'
]
try
:
choices
=
block
.
children
except
AttributeError
:
pass
else
:
for
choice
in
choices
:
choice_block
=
modulestore
()
.
get_item
(
choice
)
if
choice_block
.
value
==
answer
:
answer
=
choice_block
.
content
break
# Unit
mentoring_block
=
modulestore
()
.
get_item
(
block
.
parent
)
unit
=
modulestore
()
.
get_item
(
mentoring_block
.
parent
)
# Subsection
subsection
=
modulestore
()
.
get_item
(
unit
.
parent
)
# Section
section
=
modulestore
()
.
get_item
(
subsection
.
parent
)
return
{
'section'
:
section
.
display_name
,
'subsection'
:
subsection
.
display_name
,
'unit'
:
unit
.
display_name
,
'type'
:
block_type
,
'question'
:
block
.
question
,
'answer'
:
answer
,
'username'
:
username
}
problem_builder/templates/html/student_answers_dashboard.html
View file @
a199b820
...
...
@@ -3,14 +3,6 @@
<p>
{% trans "You can export all student answers to multiple-choice questions and long-form answers to a CSV file here." %}
</p>
<div
class=
"data-export-status"
></div>
<div
class=
"data-export-actions"
>
<button
class=
"data-export-download"
>
{% trans "Download result" %}
</button>
<button
class=
"data-export-cancel"
>
{% trans "Cancel current export" %}
</button>
<button
class=
"data-export-delete"
>
{% trans "Delete result" %}
</button>
</div>
<div
class=
"data-export-options"
>
<div
class=
"data-export-field-container"
>
<div
class=
"data-export-field"
>
...
...
@@ -51,5 +43,31 @@
</div>
</div>
<div
class=
"data-export-actions"
>
<button
class=
"data-export-start"
>
{% trans "Start a new export" %}
</button>
<button
class=
"data-export-start"
>
{% trans "Start a new export" %}
</button>
</div>
<div
class=
"data-export-results"
>
<h3>
{% trans "Results" %}
</h3>
<table>
<thead>
<tr>
<td>
{% trans "Section" %}
</td>
<td>
{% trans "Subsection" %}
</td>
<td>
{% trans "Unit" %}
</td>
<td>
{% trans "Type" %}
</td>
<td>
{% trans "Question" %}
</td>
<td>
{% trans "Answer" %}
</td>
<td>
{% trans "Username" %}
</td>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div
class=
"data-export-status"
></div>
<div
class=
"data-export-actions"
>
<button
class=
"data-export-download"
>
{% trans "Download result" %}
</button>
<button
class=
"data-export-cancel"
>
{% trans "Cancel current export" %}
</button>
<button
class=
"data-export-delete"
>
{% trans "Delete result" %}
</button>
</div>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment