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
fbf23f9e
Commit
fbf23f9e
authored
Oct 16, 2015
by
Tim Krones
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Clean up.
parent
dd04ee8c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
62 additions
and
83 deletions
+62
-83
problem_builder/plot.py
+35
-58
problem_builder/public/js/plot.js
+27
-25
No files found.
problem_builder/plot.py
View file @
fbf23f9e
...
...
@@ -21,6 +21,7 @@
import
json
import
logging
from
lazy.lazy
import
lazy
from
opaque_keys.edx.keys
import
CourseKey
from
xblock.core
import
XBlock
...
...
@@ -126,7 +127,7 @@ class PlotBlock(StudioEditableXBlockMixin, StudioContainerWithNestedXBlocksMixin
help
=
_
(
'Claims and questions that should be included in the plot. '
'Each line defines a triple of the form "claim, q1, q2", '
'where "claim" is arbitrary text that represents a claim
(must be quoted using double-quotes)
, '
'where "claim" is arbitrary text that represents a claim, '
'and "q1" and "q2" are IDs of scale questions. '
),
default
=
""
,
...
...
@@ -139,19 +140,26 @@ class PlotBlock(StudioEditableXBlockMixin, StudioContainerWithNestedXBlocksMixin
'q1_label'
,
'q2_label'
,
'q3_label'
,
'q4_label'
,
'claims'
)
@lazy
def
course_id
(
self
):
return
unicode
(
getattr
(
self
.
runtime
,
'course_id'
,
'course_id'
))
@lazy
def
course_key_str
(
self
):
course_key
=
CourseKey
.
from_string
(
self
.
course_id
)
return
unicode
(
course_key
)
@property
def
default_claims
(
self
):
if
not
self
.
claims
:
return
[]
return
self
.
_get_claims
(
self
.
_get_default_response
)
course_id
=
unicode
(
getattr
(
self
.
runtime
,
'course_id'
,
'course_id'
))
course_key
=
CourseKey
.
from_string
(
course_id
)
course_key_str
=
unicode
(
course_key
)
@property
def
average_claims
(
self
):
return
self
.
_get_claims
(
self
.
_get_average_response
)
user_service
=
self
.
runtime
.
service
(
self
,
'user'
)
user
=
user_service
.
get_current_user
()
username
=
user
.
opt_attrs
.
get
(
'edx-platform.username'
)
anonymous_user_id
=
user_service
.
get_anonymous_user_id
(
username
,
course_id
)
def
_get_claims
(
self
,
response_function
):
if
not
self
.
claims
:
return
[]
mentoring_block
=
self
.
get_parent
()
.
get_parent
()
question_ids
,
questions
=
mentoring_block
.
question_ids
,
mentoring_block
.
questions
...
...
@@ -161,66 +169,45 @@ class PlotBlock(StudioEditableXBlockMixin, StudioContainerWithNestedXBlocksMixin
r1
,
r2
=
None
,
None
for
question_id
,
question
in
zip
(
question_ids
,
questions
):
if
question
.
name
==
q1
:
r1
=
self
.
_default_response
(
course_key_str
,
question
,
question_id
,
anonymous_user
_id
)
r1
=
response_function
(
self
.
course_key_str
,
question
,
question
_id
)
if
question
.
name
==
q2
:
r2
=
self
.
_default_response
(
course_key_str
,
question
,
question_id
,
anonymous_user
_id
)
r2
=
response_function
(
self
.
course_key_str
,
question
,
question
_id
)
if
r1
is
not
None
and
r2
is
not
None
:
break
claims
.
append
([
claim
,
r1
,
r2
])
return
claims
def
_
default_response
(
self
,
course_key_str
,
question
,
question_id
,
user
_id
):
def
_
get_default_response
(
self
,
course_key_str
,
question
,
question
_id
):
from
.tasks
import
_get_answer
# Import here to avoid circular dependency
# 1. Obtain block_type for question
# 1. Obtain ID of current user that can be used to look up submissions
user_service
=
self
.
runtime
.
service
(
self
,
'user'
)
user
=
user_service
.
get_current_user
()
username
=
user
.
opt_attrs
.
get
(
'edx-platform.username'
)
anonymous_user_id
=
user_service
.
get_anonymous_user_id
(
username
,
self
.
course_id
)
# 2. Obtain block_type for question
question_type
=
question
.
scope_ids
.
block_type
#
2. Obtain submissions for question using course_key_str, block_id, block_type, user_id
#
3. Obtain latest submission for question
student_dict
=
{
'student_id'
:
user_id
,
'student_id'
:
anonymous_
user_id
,
'course_id'
:
course_key_str
,
'item_id'
:
question_id
,
'item_type'
:
question_type
,
}
submissions
=
sub_api
.
get_submissions
(
student_dict
,
limit
=
1
)
# Gets latest submission
#
3
. Extract response from latest submission for question
submissions
=
sub_api
.
get_submissions
(
student_dict
,
limit
=
1
)
#
4
. Extract response from latest submission for question
answer_cache
=
{}
for
submission
in
submissions
:
answer
=
_get_answer
(
question
,
submission
,
answer_cache
)
return
int
(
answer
)
@property
def
average_claims
(
self
):
if
not
self
.
claims
:
return
[]
course_id
=
unicode
(
getattr
(
self
.
runtime
,
'course_id'
,
'course_id'
))
course_key
=
CourseKey
.
from_string
(
course_id
)
course_key_str
=
unicode
(
course_key
)
mentoring_block
=
self
.
get_parent
()
.
get_parent
()
question_ids
,
questions
=
mentoring_block
.
question_ids
,
mentoring_block
.
questions
claims
=
[]
for
line
in
self
.
claims
.
split
(
'
\n
'
):
claim
,
q1
,
q2
=
line
.
split
(
', '
)
r1
,
r2
=
None
,
None
for
question_id
,
question
in
zip
(
question_ids
,
questions
):
if
question
.
name
==
q1
:
r1
=
self
.
_average_response
(
course_key_str
,
question
,
question_id
)
if
question
.
name
==
q2
:
r2
=
self
.
_average_response
(
course_key_str
,
question
,
question_id
)
if
r1
is
not
None
and
r2
is
not
None
:
break
claims
.
append
([
claim
,
r1
,
r2
])
return
claims
def
_average_response
(
self
,
course_key_str
,
question
,
question_id
):
def
_get_average_response
(
self
,
course_key_str
,
question
,
question_id
):
from
.tasks
import
_get_answer
# Import here to avoid circular dependency
# 1. Obtain block_type for question
question_type
=
question
.
scope_ids
.
block_type
# 2. Obtain
submissions for question using course_key_str, block_id, block_type
submissions
=
sub_api
.
get_all_submissions
(
course_key_str
,
question_id
,
question_type
)
# Gets latest submissions
# 3. Extract responses from submissions for question and sum them up
# 2. Obtain
latest submissions for question
submissions
=
sub_api
.
get_all_submissions
(
course_key_str
,
question_id
,
question_type
)
# 3. Extract responses from
latest
submissions for question and sum them up
answer_cache
=
{}
response_total
=
0
num_submissions
=
0
# Can't use len(submissions) because submissions is a generator
...
...
@@ -245,16 +232,6 @@ class PlotBlock(StudioEditableXBlockMixin, StudioContainerWithNestedXBlocksMixin
'average_claims'
:
self
.
average_claims
,
}
def
clean_studio_edits
(
self
,
data
):
# FIXME: Use this to clean data.claims (remove leading/trailing whitespace, etc.)
pass
def
validate_field_data
(
self
,
validation
,
data
):
# FIXME: Use this to validate data.claims:
# - Each line should be of the form "claim, q1, q2" (no quotes)
# - Entries for "claim", "q1", "q2" must point to existing blocks
pass
def
author_preview_view
(
self
,
context
):
return
Fragment
(
u"<p>{}</p>"
.
format
(
...
...
problem_builder/public/js/plot.js
View file @
fbf23f9e
function
PlotBlock
(
runtime
,
element
)
{
// Plot
// Define margins
var
margins
=
{
top
:
20
,
right
:
20
,
bottom
:
20
,
left
:
20
};
...
...
@@ -52,28 +54,31 @@ function PlotBlock(runtime, element) {
.
attr
(
"transform"
,
"translate("
+
plotWidth
/
2
+
", 0)"
)
.
call
(
yAxis
);
// Buttons
var
defaultButton
=
$
(
'.plot-default'
,
element
);
var
averageButton
=
$
(
'.plot-average'
,
element
);
var
quadrantsButton
=
$
(
'.plot-quadrants'
,
element
);
// Claims
var
defaultClaims
=
$
(
'.plot-default'
,
element
)
.
data
(
'claims'
);
var
averageClaims
=
$
(
'.plot-average'
,
element
)
.
data
(
'claims'
);
var
defaultClaims
=
defaultButton
.
data
(
'claims'
);
var
averageClaims
=
averageButton
.
data
(
'claims'
);
// Colors
var
defaultColor
=
$
(
'.plot-default'
,
element
)
.
data
(
'point-color'
);
var
averageColor
=
$
(
'.plot-average'
,
element
)
.
data
(
'point-color'
);
var
defaultColor
=
defaultButton
.
data
(
'point-color'
);
var
averageColor
=
averageButton
.
data
(
'point-color'
);
// Quadrant labels
var
q1Label
=
$
(
'.plot-quadrants'
,
element
)
.
data
(
'q1-label'
);
var
q2Label
=
$
(
'.plot-quadrants'
,
element
)
.
data
(
'q2-label'
);
var
q3Label
=
$
(
'.plot-quadrants'
,
element
)
.
data
(
'q3-label'
);
var
q4Label
=
$
(
'.plot-quadrants'
,
element
)
.
data
(
'q4-label'
);
var
q1Label
=
quadrantsButton
.
data
(
'q1-label'
);
var
q2Label
=
quadrantsButton
.
data
(
'q2-label'
);
var
q3Label
=
quadrantsButton
.
data
(
'q3-label'
);
var
q4Label
=
quadrantsButton
.
data
(
'q4-label'
);
// Event handlers
var
defaultButton
=
$
(
'.plot-default'
,
element
);
var
averageButton
=
$
(
'.plot-average'
,
element
);
function
toggleOverlay
(
claims
,
color
,
klass
,
refresh
)
{
var
selector
=
"."
+
klass
;
var
selection
=
svgContainer
.
selectAll
(
selector
);
...
...
@@ -122,18 +127,6 @@ function PlotBlock(runtime, element) {
}
}
defaultButton
.
on
(
'click'
,
function
(
event
,
refresh
)
{
toggleOverlay
(
defaultClaims
,
defaultColor
,
'claim-default'
,
refresh
);
toggleBorderColor
(
this
,
defaultColor
,
refresh
);
});
averageButton
.
on
(
'click'
,
function
(
event
)
{
toggleOverlay
(
averageClaims
,
averageColor
,
'claim-average'
);
toggleBorderColor
(
this
,
averageColor
);
});
var
quadrantsButton
=
$
(
'.plot-quadrants'
,
element
);
function
toggleQuadrantLabels
()
{
var
selection
=
svgContainer
.
selectAll
(
".quadrant-label"
);
var
quadrantLabelsOn
=
quadrantsButton
.
val
()
===
'On'
;
...
...
@@ -170,15 +163,24 @@ function PlotBlock(runtime, element) {
}
}
defaultButton
.
on
(
'click'
,
function
(
event
,
refresh
)
{
toggleOverlay
(
defaultClaims
,
defaultColor
,
'claim-default'
,
refresh
);
toggleBorderColor
(
this
,
defaultColor
,
refresh
);
});
averageButton
.
on
(
'click'
,
function
(
event
)
{
toggleOverlay
(
averageClaims
,
averageColor
,
'claim-average'
);
toggleBorderColor
(
this
,
averageColor
);
});
quadrantsButton
.
on
(
'click'
,
function
()
{
toggleQuadrantLabels
();
});
// Quadrant labels are off initially; color of button for toggling them should reflect this
quadrantsButton
.
css
(
"border-color"
,
"red"
);
//
Functions that can be called from the outside
//
API
var
dataXHR
;
...
...
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