Commit 6a67dc83 by Dennis Jen Committed by Daniel Friedman

Renamed learner API field.

- discussions_contributed renamed to discussion_contributions
parent 66f541c4
...@@ -3,14 +3,12 @@ PROBLEM = 'problem' ...@@ -3,14 +3,12 @@ PROBLEM = 'problem'
VIDEO = 'video' VIDEO = 'video'
INDIVIDUAL_TYPES = [DISCUSSION, PROBLEM, VIDEO] INDIVIDUAL_TYPES = [DISCUSSION, PROBLEM, VIDEO]
DISCUSSIONS = 'discussions'
PROBLEMS = 'problems' PROBLEMS = 'problems'
VIDEOS = 'videos' VIDEOS = 'videos'
AGGREGATE_TYPES = [DISCUSSIONS, PROBLEMS, VIDEOS] AGGREGATE_TYPES = [DISCUSSION, PROBLEMS, VIDEOS]
# useful for agregating ModuleEngagement to ModuleEngagementTimeline # useful for agregating ModuleEngagement to ModuleEngagementTimeline
SINGULAR_TO_PLURAL = { SINGULAR_TO_PLURAL = {
DISCUSSION: DISCUSSIONS,
PROBLEM: PROBLEMS, PROBLEM: PROBLEMS,
VIDEO: VIDEOS, VIDEO: VIDEOS,
} }
...@@ -2,13 +2,12 @@ from analytics_data_api.constants import engagement_entity_types ...@@ -2,13 +2,12 @@ from analytics_data_api.constants import engagement_entity_types
ATTEMPTED = 'attempted' ATTEMPTED = 'attempted'
COMPLETED = 'completed' COMPLETED = 'completed'
CONTRIBUTED = 'contributed' CONTRIBUTIONS = 'contributions'
VIEWED = 'viewed' VIEWED = 'viewed'
# map entity types to events # map entity types to events
EVENTS = { EVENTS = {
engagement_entity_types.DISCUSSION: [CONTRIBUTED], engagement_entity_types.DISCUSSION: [CONTRIBUTIONS],
engagement_entity_types.DISCUSSIONS: [CONTRIBUTED],
engagement_entity_types.PROBLEM: [ATTEMPTED, COMPLETED], engagement_entity_types.PROBLEM: [ATTEMPTED, COMPLETED],
engagement_entity_types.PROBLEMS: [ATTEMPTED, COMPLETED], engagement_entity_types.PROBLEMS: [ATTEMPTED, COMPLETED],
engagement_entity_types.VIDEO: [VIEWED], engagement_entity_types.VIDEO: [VIEWED],
......
...@@ -245,7 +245,7 @@ class RosterEntry(DocType): ...@@ -245,7 +245,7 @@ class RosterEntry(DocType):
# problem_attempts_per_completed is > 1 and set to -problem_attempts if # problem_attempts_per_completed is > 1 and set to -problem_attempts if
# problem_attempts_per_completed = 1. # problem_attempts_per_completed = 1.
attempt_ratio_order = Integer() attempt_ratio_order = Integer()
discussions_contributed = Integer() discussion_contributions = Integer()
videos_watched = Integer() videos_watched = Integer()
enrollment_date = Date() enrollment_date = Date()
last_updated = Date() last_updated = Date()
...@@ -302,7 +302,7 @@ class RosterEntry(DocType): ...@@ -302,7 +302,7 @@ class RosterEntry(DocType):
)) ))
order_by_options = ( order_by_options = (
'username', 'email', 'discussions_contributed', 'problems_attempted', 'problems_completed', 'username', 'email', 'discussion_contributions', 'problems_attempted', 'problems_completed',
'problem_attempts_per_completed', 'attempt_ratio_order', 'videos_viewed' 'problem_attempts_per_completed', 'attempt_ratio_order', 'videos_viewed'
) )
sort_order_options = ('asc', 'desc') sort_order_options = ('asc', 'desc')
...@@ -405,7 +405,8 @@ class ModuleEngagementTimelineManager(models.Manager): ...@@ -405,7 +405,8 @@ class ModuleEngagementTimelineManager(models.Manager):
u'date': key, u'date': key,
} }
for engagement in group: for engagement in group:
entity_type = engagement_entity_types.SINGULAR_TO_PLURAL[engagement['entity_type']] entity_type = engagement_entity_types.SINGULAR_TO_PLURAL.get(engagement['entity_type'],
engagement['entity_type'])
engagement_type = '{}_{}'.format(entity_type, engagement['event']) engagement_type = '{}_{}'.format(entity_type, engagement['event'])
count = item.get(engagement_type, 0) count = item.get(engagement_type, 0)
count += engagement['count'] count += engagement['count']
......
...@@ -345,7 +345,7 @@ class LearnerSerializer(serializers.Serializer, DefaultIfNoneMixin): ...@@ -345,7 +345,7 @@ class LearnerSerializer(serializers.Serializer, DefaultIfNoneMixin):
engagements = {} engagements = {}
# fill in these fields will 0 if values not returned/found # fill in these fields will 0 if values not returned/found
default_if_none_fields = ['discussions_contributed', 'problems_attempted', default_if_none_fields = ['discussion_contributions', 'problems_attempted',
'problems_completed', 'videos_viewed'] 'problems_completed', 'videos_viewed']
for field in default_if_none_fields: for field in default_if_none_fields:
engagements[field] = self.default_if_none(getattr(obj, field, None), 0) engagements[field] = self.default_if_none(getattr(obj, field, None), 0)
...@@ -381,7 +381,7 @@ class EngagementDaySerializer(DefaultIfNoneMixin, serializers.Serializer): ...@@ -381,7 +381,7 @@ class EngagementDaySerializer(DefaultIfNoneMixin, serializers.Serializer):
date = serializers.DateField(format=settings.DATE_FORMAT) date = serializers.DateField(format=settings.DATE_FORMAT)
problems_attempted = serializers.IntegerField(required=True, default=0) problems_attempted = serializers.IntegerField(required=True, default=0)
problems_completed = serializers.IntegerField(required=True, default=0) problems_completed = serializers.IntegerField(required=True, default=0)
discussions_contributed = serializers.IntegerField(required=True, default=0) discussion_contributions = serializers.IntegerField(required=True, default=0)
videos_viewed = serializers.IntegerField(required=True, default=0) videos_viewed = serializers.IntegerField(required=True, default=0)
def transform_problems_attempted(self, _obj, value): def transform_problems_attempted(self, _obj, value):
...@@ -390,7 +390,7 @@ class EngagementDaySerializer(DefaultIfNoneMixin, serializers.Serializer): ...@@ -390,7 +390,7 @@ class EngagementDaySerializer(DefaultIfNoneMixin, serializers.Serializer):
def transform_problems_completed(self, _obj, value): def transform_problems_completed(self, _obj, value):
return self.default_if_none(value, 0) return self.default_if_none(value, 0)
def transform_discussions_contributed(self, _obj, value): def transform_discussion_contributions(self, _obj, value):
return self.default_if_none(value, 0) return self.default_if_none(value, 0)
def transform_videos_viewed(self, _obj, value): def transform_videos_viewed(self, _obj, value):
......
...@@ -26,7 +26,7 @@ class EngagementTimelineTests(DemoCourseMixin, VerifyCourseIdMixin, TestCaseWith ...@@ -26,7 +26,7 @@ class EngagementTimelineTests(DemoCourseMixin, VerifyCourseIdMixin, TestCaseWith
entity_id='some-type-of-id', event=engagement_events.COMPLETED, count=12) entity_id='some-type-of-id', event=engagement_events.COMPLETED, count=12)
G(models.ModuleEngagement, course_id=self.course_id, username=self.DEFAULT_USERNAME, G(models.ModuleEngagement, course_id=self.course_id, username=self.DEFAULT_USERNAME,
date=datetime.datetime(2015, 1, 2, tzinfo=pytz.utc), entity_type=engagement_entity_types.DISCUSSION, date=datetime.datetime(2015, 1, 2, tzinfo=pytz.utc), entity_type=engagement_entity_types.DISCUSSION,
entity_id='some-type-of-id', event=engagement_events.CONTRIBUTED, count=10) entity_id='some-type-of-id', event=engagement_events.CONTRIBUTIONS, count=10)
G(models.ModuleEngagement, course_id=self.course_id, username=self.DEFAULT_USERNAME, G(models.ModuleEngagement, course_id=self.course_id, username=self.DEFAULT_USERNAME,
date=datetime.datetime(2015, 1, 2, tzinfo=pytz.utc), entity_type=engagement_entity_types.VIDEO, date=datetime.datetime(2015, 1, 2, tzinfo=pytz.utc), entity_type=engagement_entity_types.VIDEO,
entity_id='some-type-of-id', event=engagement_events.VIEWED, count=44) entity_id='some-type-of-id', event=engagement_events.VIEWED, count=44)
...@@ -44,14 +44,14 @@ class EngagementTimelineTests(DemoCourseMixin, VerifyCourseIdMixin, TestCaseWith ...@@ -44,14 +44,14 @@ class EngagementTimelineTests(DemoCourseMixin, VerifyCourseIdMixin, TestCaseWith
'days': [ 'days': [
{ {
'date': '2015-01-01', 'date': '2015-01-01',
'discussions_contributed': 0, 'discussion_contributions': 0,
'problems_attempted': 100, 'problems_attempted': 100,
'problems_completed': 12, 'problems_completed': 12,
'videos_viewed': 0 'videos_viewed': 0
}, },
{ {
'date': '2015-01-02', 'date': '2015-01-02',
'discussions_contributed': 10, 'discussion_contributions': 10,
'problems_attempted': 8, 'problems_attempted': 8,
'problems_completed': 0, 'problems_completed': 0,
'videos_viewed': 44 'videos_viewed': 44
...@@ -71,7 +71,7 @@ class EngagementTimelineTests(DemoCourseMixin, VerifyCourseIdMixin, TestCaseWith ...@@ -71,7 +71,7 @@ class EngagementTimelineTests(DemoCourseMixin, VerifyCourseIdMixin, TestCaseWith
'days': [ 'days': [
{ {
'date': '2015-05-28', 'date': '2015-05-28',
'discussions_contributed': 0, 'discussion_contributions': 0,
'problems_attempted': 6923, 'problems_attempted': 6923,
'problems_completed': 0, 'problems_completed': 0,
'videos_viewed': 0 'videos_viewed': 0
...@@ -94,14 +94,14 @@ class EngagementTimelineTests(DemoCourseMixin, VerifyCourseIdMixin, TestCaseWith ...@@ -94,14 +94,14 @@ class EngagementTimelineTests(DemoCourseMixin, VerifyCourseIdMixin, TestCaseWith
'days': [ 'days': [
{ {
'date': '2015-05-26', 'date': '2015-05-26',
'discussions_contributed': 0, 'discussion_contributions': 0,
'problems_attempted': 0, 'problems_attempted': 0,
'problems_completed': 0, 'problems_completed': 0,
'videos_viewed': 1 'videos_viewed': 1
}, },
{ {
'date': '2015-05-28', 'date': '2015-05-28',
'discussions_contributed': 0, 'discussion_contributions': 0,
'problems_attempted': 6923, 'problems_attempted': 6923,
'problems_completed': 0, 'problems_completed': 0,
'videos_viewed': 0 'videos_viewed': 0
......
...@@ -60,7 +60,7 @@ class LearnerAPITestMixin(object): ...@@ -60,7 +60,7 @@ class LearnerAPITestMixin(object):
'cohort': { 'cohort': {
'type': 'string', 'index': 'not_analyzed', 'doc_values': True 'type': 'string', 'index': 'not_analyzed', 'doc_values': True
}, },
'discsussions_contributed': { 'discussion_contributions': {
'type': 'integer', 'doc_values': True 'type': 'integer', 'doc_values': True
}, },
'problems_attempted': { 'problems_attempted': {
...@@ -109,7 +109,7 @@ class LearnerAPITestMixin(object): ...@@ -109,7 +109,7 @@ class LearnerAPITestMixin(object):
enrollment_mode='honor', enrollment_mode='honor',
segments=None, segments=None,
cohort='Team edX', cohort='Team edX',
discussions_contributed=0, discussion_contributions=0,
problems_attempted=0, problems_attempted=0,
problems_completed=0, problems_completed=0,
problem_attempts_per_completed=None, problem_attempts_per_completed=None,
...@@ -129,7 +129,7 @@ class LearnerAPITestMixin(object): ...@@ -129,7 +129,7 @@ class LearnerAPITestMixin(object):
'enrollment_mode': enrollment_mode, 'enrollment_mode': enrollment_mode,
'segments': segments if segments is not None else list(), 'segments': segments if segments is not None else list(),
'cohort': cohort, 'cohort': cohort,
'discussions_contributed': discussions_contributed, 'discussion_contributions': discussion_contributions,
'problems_attempted': problems_attempted, 'problems_attempted': problems_attempted,
'problems_completed': problems_completed, 'problems_completed': problems_completed,
'problem_attempts_per_completed': problem_attempts_per_completed, 'problem_attempts_per_completed': problem_attempts_per_completed,
...@@ -179,7 +179,7 @@ class LearnerTests(VerifyCourseIdMixin, LearnerAPITestMixin, TestCaseWithAuthent ...@@ -179,7 +179,7 @@ class LearnerTests(VerifyCourseIdMixin, LearnerAPITestMixin, TestCaseWithAuthent
@ddt.unpack @ddt.unpack
def test_get_user(self, username, name, course_id, enrollment_mode, segments=None, cohort=None, def test_get_user(self, username, name, course_id, enrollment_mode, segments=None, cohort=None,
problems_attempted=None, problems_completed=None, videos_viewed=None, problems_attempted=None, problems_completed=None, videos_viewed=None,
discussions_contributed=None, problem_attempts_per_completed=None, discussion_contributions=None, problem_attempts_per_completed=None,
attempt_ratio_order=None, enrollment_date=None, last_updated=None): attempt_ratio_order=None, enrollment_date=None, last_updated=None):
self.create_learners([{ self.create_learners([{
...@@ -192,7 +192,7 @@ class LearnerTests(VerifyCourseIdMixin, LearnerAPITestMixin, TestCaseWithAuthent ...@@ -192,7 +192,7 @@ class LearnerTests(VerifyCourseIdMixin, LearnerAPITestMixin, TestCaseWithAuthent
"problems_attempted": problems_attempted, "problems_attempted": problems_attempted,
"problems_completed": problems_completed, "problems_completed": problems_completed,
"videos_viewed": videos_viewed, "videos_viewed": videos_viewed,
"discussions_contributed": discussions_contributed, "discussion_contributions": discussion_contributions,
"problem_attempts_per_completed": problem_attempts_per_completed, "problem_attempts_per_completed": problem_attempts_per_completed,
"attempt_ratio_order": attempt_ratio_order, "attempt_ratio_order": attempt_ratio_order,
"enrollment_date": enrollment_date, "enrollment_date": enrollment_date,
...@@ -214,7 +214,7 @@ class LearnerTests(VerifyCourseIdMixin, LearnerAPITestMixin, TestCaseWithAuthent ...@@ -214,7 +214,7 @@ class LearnerTests(VerifyCourseIdMixin, LearnerAPITestMixin, TestCaseWithAuthent
"problems_attempted": problems_attempted or 0, "problems_attempted": problems_attempted or 0,
"problems_completed": problems_completed or 0, "problems_completed": problems_completed or 0,
"videos_viewed": videos_viewed or 0, "videos_viewed": videos_viewed or 0,
"discussions_contributed": discussions_contributed or 0, "discussion_contributions": discussion_contributions or 0,
"problem_attempts_per_completed": problem_attempts_per_completed, "problem_attempts_per_completed": problem_attempts_per_completed,
}, },
"enrollment_date": enrollment_date, "enrollment_date": enrollment_date,
...@@ -301,7 +301,7 @@ class LearnerListTests(LearnerAPITestMixin, VerifyCourseIdMixin, TestCaseWithAut ...@@ -301,7 +301,7 @@ class LearnerListTests(LearnerAPITestMixin, VerifyCourseIdMixin, TestCaseWithAut
"problems_attempted": 43, "problems_attempted": 43,
"problems_completed": 3, "problems_completed": 3,
"videos_viewed": 6, "videos_viewed": 6,
"discussions_contributed": 0, "discussion_contributions": 0,
"problem_attempts_per_completed": 23.14, "problem_attempts_per_completed": 23.14,
}]) }])
response = self._get(self.course_id) response = self._get(self.course_id)
...@@ -314,7 +314,7 @@ class LearnerListTests(LearnerAPITestMixin, VerifyCourseIdMixin, TestCaseWithAut ...@@ -314,7 +314,7 @@ class LearnerListTests(LearnerAPITestMixin, VerifyCourseIdMixin, TestCaseWithAut
"problems_attempted": 43, "problems_attempted": 43,
"problems_completed": 3, "problems_completed": 3,
"videos_viewed": 6, "videos_viewed": 6,
"discussions_contributed": 0, "discussion_contributions": 0,
"problem_attempts_per_completed": 23.14, "problem_attempts_per_completed": 23.14,
}, },
'last_updated': '2015-09-28', 'last_updated': '2015-09-28',
...@@ -376,12 +376,12 @@ class LearnerListTests(LearnerAPITestMixin, VerifyCourseIdMixin, TestCaseWithAut ...@@ -376,12 +376,12 @@ class LearnerListTests(LearnerAPITestMixin, VerifyCourseIdMixin, TestCaseWithAut
([{'username': 'a'}, {'username': 'b'}], 'email', 'asc', [{'username': 'a'}, {'username': 'b'}]), ([{'username': 'a'}, {'username': 'b'}], 'email', 'asc', [{'username': 'a'}, {'username': 'b'}]),
([{'username': 'a'}, {'username': 'b'}], 'email', 'desc', [{'username': 'b'}, {'username': 'a'}]), ([{'username': 'a'}, {'username': 'b'}], 'email', 'desc', [{'username': 'b'}, {'username': 'a'}]),
( (
[{'username': 'a', 'discussions_contributed': 0}, {'username': 'b', 'discussions_contributed': 1}], [{'username': 'a', 'discussion_contributions': 0}, {'username': 'b', 'discussion_contributions': 1}],
'discussions_contributed', 'asc', [{'username': 'a'}, {'username': 'b'}] 'discussion_contributions', 'asc', [{'username': 'a'}, {'username': 'b'}]
), ),
( (
[{'username': 'a', 'discussions_contributed': 0}, {'username': 'b', 'discussions_contributed': 1}], [{'username': 'a', 'discussion_contributions': 0}, {'username': 'b', 'discussion_contributions': 1}],
'discussions_contributed', 'desc', [{'username': 'b'}, {'username': 'a'}] 'discussion_contributions', 'desc', [{'username': 'b'}, {'username': 'a'}]
), ),
( (
[{'username': 'a', 'problems_attempted': 0}, {'username': 'b', 'problems_attempted': 1}], [{'username': 'a', 'problems_attempted': 0}, {'username': 'b', 'problems_attempted': 1}],
......
...@@ -75,7 +75,7 @@ class LearnerView(LastUpdateMixin, CourseViewMixin, generics.RetrieveAPIView): ...@@ -75,7 +75,7 @@ class LearnerView(LastUpdateMixin, CourseViewMixin, generics.RetrieveAPIView):
This is a count of the individual problems the learner This is a count of the individual problems the learner
tried. Each problem in a course can increment this count by tried. Each problem in a course can increment this count by
a maximum of 1. a maximum of 1.
* discussions_contributed: Number of posts, responses, or * discussion_contributions: Number of posts, responses, or
comments the learner contributed to course discussions. comments the learner contributed to course discussions.
**Parameters** **Parameters**
...@@ -358,7 +358,7 @@ class CourseLearnerMetadata(CourseViewMixin, generics.RetrieveAPIView): ...@@ -358,7 +358,7 @@ class CourseLearnerMetadata(CourseViewMixin, generics.RetrieveAPIView):
* problem_attempts_per_completed: Engagement ranges for the * problem_attempts_per_completed: Engagement ranges for the
number of problem attempts per completed problem in the date number of problem attempts per completed problem in the date
range. range.
* discussions_contributed: Engagement ranges for the number of * discussion_contributions: Engagement ranges for the number of
times learners participated in discussions in the date range. times learners participated in discussions in the date range.
""" """
......
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