Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-analytics-data-api
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
edx
edx-analytics-data-api
Commits
5cbcb347
Commit
5cbcb347
authored
Mar 14, 2014
by
Brian Wilson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Suppress variant from non-submission problem-check events if not rerandomize.
Change-Id: I44b132e333e20fb32d032722406b61748a5a71fd
parent
846e0424
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
36 additions
and
12 deletions
+36
-12
edx/analytics/tasks/answer_dist.py
+11
-8
edx/analytics/tasks/launchers/remote.py
+4
-0
edx/analytics/tasks/tests/test_answer_dist.py
+21
-4
No files found.
edx/analytics/tasks/answer_dist.py
View file @
5cbcb347
...
@@ -175,7 +175,7 @@ class LastProblemCheckEventMixin(object):
...
@@ -175,7 +175,7 @@ class LastProblemCheckEventMixin(object):
if
answer_id
not
in
correct_map
:
if
answer_id
not
in
correct_map
:
log
.
error
(
"Unexpected answer_id
%
s not in correct_map:
%
s"
,
answer_id
,
event
)
log
.
error
(
"Unexpected answer_id
%
s not in correct_map:
%
s"
,
answer_id
,
event
)
continue
continue
correctness
=
correct_map
[
answer_id
]
.
get
(
'correctness'
)
in
[
'correct'
]
correctness
=
correct_map
[
answer_id
]
.
get
(
'correctness'
)
==
'correct'
variant
=
event
.
get
(
'state'
,
{})
.
get
(
'seed'
)
variant
=
event
.
get
(
'state'
,
{})
.
get
(
'seed'
)
...
@@ -275,7 +275,8 @@ class AnswerDistributionPerCourseMixin(object):
...
@@ -275,7 +275,8 @@ class AnswerDistributionPerCourseMixin(object):
problem_id
=
most_recent_answer
.
get
(
'problem_id'
)
problem_id
=
most_recent_answer
.
get
(
'problem_id'
)
problem_display_name
=
most_recent_answer
.
get
(
'problem_display_name'
)
problem_display_name
=
most_recent_answer
.
get
(
'problem_display_name'
)
most_recent_question
=
most_recent_answer
.
get
(
'question'
,
''
)
most_recent_question
=
most_recent_answer
.
get
(
'question'
,
''
)
answer_uses_code
=
(
'answer_value_id'
in
most_recent_answer
)
answer_uses_value_id
=
(
'answer_value_id'
in
most_recent_answer
)
answer_uses_variant
=
(
most_recent_answer
.
get
(
'variant'
,
''
)
!=
''
)
answer_dist
=
{}
answer_dist
=
{}
for
_timestamp
,
value_string
in
reversed
(
values
):
for
_timestamp
,
value_string
in
reversed
(
values
):
answer
=
json
.
loads
(
value_string
)
answer
=
json
.
loads
(
value_string
)
...
@@ -291,7 +292,7 @@ class AnswerDistributionPerCourseMixin(object):
...
@@ -291,7 +292,7 @@ class AnswerDistributionPerCourseMixin(object):
# We only want this from the most recent answer that has
# We only want this from the most recent answer that has
# this value.
# this value.
if
answer_grouping_key
not
in
answer_dist
:
if
answer_grouping_key
not
in
answer_dist
:
if
answer_uses_
code
:
if
answer_uses_
value_id
:
# The most recent overall answer indicates that
# The most recent overall answer indicates that
# the code should be returned as such. If this
# the code should be returned as such. If this
# particular answer did not have 'submission'
# particular answer did not have 'submission'
...
@@ -317,19 +318,21 @@ class AnswerDistributionPerCourseMixin(object):
...
@@ -317,19 +318,21 @@ class AnswerDistributionPerCourseMixin(object):
# If there is no variant, then the question should be
# If there is no variant, then the question should be
# the same, and we want to go with the most recently
# the same, and we want to go with the most recently
# defined value.
# defined value.
if
answer
.
get
(
'variant'
)
:
if
answer
_uses_variant
:
question
=
answer
.
get
(
'question'
,
''
)
question
=
answer
.
get
(
'question'
,
''
)
variant
=
answer
.
get
(
'variant'
)
or
''
else
:
else
:
question
=
most_recent_question
question
=
most_recent_question
variant
=
''
# Key values here should match those used in get_column_order().
# Key values here should match those used in get_column_order().
answer_dist
[
answer_grouping_key
]
=
{
answer_dist
[
answer_grouping_key
]
=
{
'ModuleID'
:
problem_id
,
'ModuleID'
:
problem_id
,
'PartID'
:
answer_id
,
'PartID'
:
answer_id
,
'ValueID'
:
value_id
,
'ValueID'
:
value_id
or
''
,
'AnswerValue'
:
answer_value
,
'AnswerValue'
:
answer_value
or
''
,
'Variant'
:
answer
.
get
(
'variant'
)
,
'Variant'
:
variant
,
'Problem Display Name'
:
problem_display_name
,
'Problem Display Name'
:
problem_display_name
or
''
,
'Question'
:
question
,
'Question'
:
question
,
'Correct Answer'
:
'1'
if
answer
.
get
(
'correct'
)
else
'0'
,
'Correct Answer'
:
'1'
if
answer
.
get
(
'correct'
)
else
'0'
,
'Count'
:
0
,
'Count'
:
0
,
...
...
edx/analytics/tasks/launchers/remote.py
View file @
5cbcb347
...
@@ -28,6 +28,7 @@ def main():
...
@@ -28,6 +28,7 @@ def main():
sys
.
exit
(
return_code
)
sys
.
exit
(
return_code
)
def
run_task_playbook
(
arguments
,
uid
):
def
run_task_playbook
(
arguments
,
uid
):
"""
"""
Execute the ansible playbook that triggers and monitors the remote task execution.
Execute the ansible playbook that triggers and monitors the remote task execution.
...
@@ -39,6 +40,7 @@ def run_task_playbook(arguments, uid):
...
@@ -39,6 +40,7 @@ def run_task_playbook(arguments, uid):
extra_vars
=
convert_args_to_extra_vars
(
arguments
,
uid
)
extra_vars
=
convert_args_to_extra_vars
(
arguments
,
uid
)
return
run_ansible
((
'task.yml'
,
'-e'
,
extra_vars
),
arguments
.
verbose
,
executable
=
'ansible-playbook'
)
return
run_ansible
((
'task.yml'
,
'-e'
,
extra_vars
),
arguments
.
verbose
,
executable
=
'ansible-playbook'
)
def
convert_args_to_extra_vars
(
arguments
,
uid
):
def
convert_args_to_extra_vars
(
arguments
,
uid
):
"""
"""
Generate the set of variables that need to be passed in to ansible since they are expected to be set by the
Generate the set of variables that need to be passed in to ansible since they are expected to be set by the
...
@@ -60,6 +62,7 @@ def convert_args_to_extra_vars(arguments, uid):
...
@@ -60,6 +62,7 @@ def convert_args_to_extra_vars(arguments, uid):
extra_vars
[
'wait_for_task'
]
=
True
extra_vars
[
'wait_for_task'
]
=
True
return
' '
.
join
([
"{}='{}'"
.
format
(
k
,
extra_vars
[
k
])
for
k
in
extra_vars
])
return
' '
.
join
([
"{}='{}'"
.
format
(
k
,
extra_vars
[
k
])
for
k
in
extra_vars
])
def
run_ansible
(
args
,
verbose
,
executable
=
'ansible'
):
def
run_ansible
(
args
,
verbose
,
executable
=
'ansible'
):
"""
"""
Execute ansible passing in the provided arguments.
Execute ansible passing in the provided arguments.
...
@@ -95,6 +98,7 @@ def run_ansible(args, verbose, executable='ansible'):
...
@@ -95,6 +98,7 @@ def run_ansible(args, verbose, executable='ansible'):
return
proc
.
returncode
return
proc
.
returncode
def
download_logs
(
arguments
,
uid
):
def
download_logs
(
arguments
,
uid
):
"""
"""
Connect to the remote machine and download the logs produced by luigi.
Connect to the remote machine and download the logs produced by luigi.
...
...
edx/analytics/tasks/tests/test_answer_dist.py
View file @
5cbcb347
...
@@ -443,13 +443,13 @@ class AnswerDistributionPerCourseReduceTest(unittest.TestCase):
...
@@ -443,13 +443,13 @@ class AnswerDistributionPerCourseReduceTest(unittest.TestCase):
def
_get_expected_output
(
self
,
answer_data
,
**
kwargs
):
def
_get_expected_output
(
self
,
answer_data
,
**
kwargs
):
"""Get an expected reducer output based on the input."""
"""Get an expected reducer output based on the input."""
expected_output
=
{
expected_output
=
{
"Problem Display Name"
:
answer_data
.
get
(
'problem_display_name'
),
"Problem Display Name"
:
answer_data
.
get
(
'problem_display_name'
)
or
""
,
"Count"
:
1
,
"Count"
:
1
,
"PartID"
:
self
.
answer_id
,
"PartID"
:
self
.
answer_id
,
"Question"
:
answer_data
.
get
(
'question'
),
"Question"
:
answer_data
.
get
(
'question'
)
or
""
,
"AnswerValue"
:
answer_data
.
get
(
'answer'
),
"AnswerValue"
:
answer_data
.
get
(
'answer'
)
or
answer_data
.
get
(
'answer_value_id'
)
or
""
,
"ValueID"
:
""
,
"ValueID"
:
""
,
"Variant"
:
answer_data
.
get
(
'variant'
),
"Variant"
:
answer_data
.
get
(
'variant'
)
or
""
,
"Correct Answer"
:
"1"
if
answer_data
[
'correct'
]
else
'0'
,
"Correct Answer"
:
"1"
if
answer_data
[
'correct'
]
else
'0'
,
"ModuleID"
:
self
.
problem_id
,
"ModuleID"
:
self
.
problem_id
,
}
}
...
@@ -551,6 +551,23 @@ class AnswerDistributionPerCourseReduceTest(unittest.TestCase):
...
@@ -551,6 +551,23 @@ class AnswerDistributionPerCourseReduceTest(unittest.TestCase):
expected_output_2
=
self
.
_get_expected_output
(
answer_data_2
)
expected_output_2
=
self
.
_get_expected_output
(
answer_data_2
)
self
.
_check_output
([
input_data_1
,
input_data_2
],
(
expected_output_1
,
expected_output_2
))
self
.
_check_output
([
input_data_1
,
input_data_2
],
(
expected_output_1
,
expected_output_2
))
def
test_two_answer_event_different_old_and_new
(
self
):
answer_data_1
=
self
.
_get_non_submission_answer_data
(
answer_value_id
=
"first"
)
answer_data_2
=
self
.
_get_answer_data
(
problem_display_name
=
self
.
problem_display_name
)
input_data_1
=
(
self
.
earlier_timestamp
,
json
.
dumps
(
answer_data_1
))
input_data_2
=
(
self
.
timestamp
,
json
.
dumps
(
answer_data_2
))
expected_output_2
=
self
.
_get_expected_output
(
answer_data_2
)
# An older non-submission-based event should inherit some
# information from a newer submission-based event.
# In particular, the Variant, the Question, and Problem Display Name.
expected_output_1
=
self
.
_get_expected_output
(
answer_data_1
,
Variant
=
""
,
Question
=
expected_output_2
[
'Question'
],
)
expected_output_1
[
'Problem Display Name'
]
=
expected_output_2
[
'Problem Display Name'
]
self
.
_check_output
([
input_data_1
,
input_data_2
],
(
expected_output_1
,
expected_output_2
))
def
test_two_answer_event_different_variant
(
self
):
def
test_two_answer_event_different_variant
(
self
):
answer_data_1
=
self
.
_get_answer_data
(
variant
=
123
)
answer_data_1
=
self
.
_get_answer_data
(
variant
=
123
)
answer_data_2
=
self
.
_get_answer_data
(
variant
=
456
)
answer_data_2
=
self
.
_get_answer_data
(
variant
=
456
)
...
...
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