Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit e72a562

Browse files
author
Eric Fischer
authored
Add passing_users to course summary (#170)
EDU-153
1 parent 5a85c45 commit e72a562

6 files changed

Lines changed: 25 additions & 4 deletions

File tree

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ Gabe Mulley <gabe@edx.org>
88
Jason Bau <jbau@stanford.edu>
99
John Jarvis <jarv@edx.org>
1010
Dmitry Viskov <dmitry.viskov@webenterprise.ru>
11+
Eric Fischer <efischer@edx.org>

analytics_data_api/management/commands/generate_fake_course_data.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,17 @@ def generate_daily_data(self, course_id, start_date, end_date):
161161
progress.update(1)
162162
date = date + datetime.timedelta(days=1)
163163

164-
for mode, ratio in enrollment_mode_ratios.iteritems():
164+
for index, (mode, ratio) in enumerate(enrollment_mode_ratios.iteritems()):
165165
count = int(ratio * daily_total)
166+
pass_rate = min(random.normalvariate(.45 + (.1 * index), .15), 1.0)
166167
cumulative_count = count + random.randint(0, 100)
167168
models.CourseMetaSummaryEnrollment.objects.create(
168169
course_id=course_id, catalog_course_title='Demo Course', catalog_course='Demo_Course',
169170
start_time=timezone.now() - datetime.timedelta(weeks=6),
170171
end_time=timezone.now() + datetime.timedelta(weeks=10),
171172
pacing_type='self_paced', availability='Starting Soon', enrollment_mode=mode, count=count,
172-
cumulative_count=cumulative_count, count_change_7_days=random.randint(-50, 50))
173+
cumulative_count=cumulative_count, count_change_7_days=random.randint(-50, 50),
174+
passing_users=int(cumulative_count * pass_rate))
173175

174176
models.CourseProgramMetadata.objects.create(course_id=course_id, program_id='Demo_Program',
175177
program_type='Demo', program_title='Demo Program')

analytics_data_api/v0/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class CourseMetaSummaryEnrollment(BaseCourseModel):
7878
count = models.IntegerField(null=False)
7979
cumulative_count = models.IntegerField(null=False)
8080
count_change_7_days = models.IntegerField(default=0)
81+
passing_users = models.IntegerField(default=0)
8182

8283
class Meta(BaseCourseModel.Meta):
8384
db_table = 'course_meta_summary_enrollment'

analytics_data_api/v0/serializers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ class CourseMetaSummaryEnrollmentSerializer(ModelSerializerWithCreatedField, Dyn
561561
count = serializers.IntegerField(default=0)
562562
cumulative_count = serializers.IntegerField(default=0)
563563
count_change_7_days = serializers.IntegerField(default=0)
564+
passing_users = serializers.IntegerField(default=0)
564565
enrollment_modes = serializers.SerializerMethodField()
565566
programs = serializers.SerializerMethodField()
566567

analytics_data_api/v0/tests/views/test_course_summaries.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def create_model(self, model_id, **kwargs):
3636
start_time=datetime.datetime(2016, 10, 11, tzinfo=pytz.utc),
3737
end_time=datetime.datetime(2016, 12, 18, tzinfo=pytz.utc),
3838
pacing_type='instructor', availability=kwargs['availability'], enrollment_mode=mode,
39-
count=5, cumulative_count=10, count_change_7_days=1, create=self.now,)
39+
count=5, cumulative_count=10, count_change_7_days=1, passing_users=1, create=self.now,)
4040
if 'programs' in kwargs and kwargs['programs']:
4141
# Create a link from this course to a program
4242
G(models.CourseProgramMetadata, course_id=model_id, program_id=CourseSamples.program_ids[0],
@@ -70,20 +70,23 @@ def expected_result(self, item_id, modes=None, availability='Current', programs=
7070
('count', count_factor * num_modes),
7171
('cumulative_count', cumulative_count_factor * num_modes),
7272
('count_change_7_days', count_change_factor * num_modes),
73+
('passing_users', count_change_factor * num_modes),
7374
('enrollment_modes', {}),
7475
])
7576
summary['enrollment_modes'].update({
7677
mode: {
7778
'count': count_factor,
7879
'cumulative_count': cumulative_count_factor,
7980
'count_change_7_days': count_change_factor,
81+
'passing_users': count_change_factor,
8082
} for mode in modes
8183
})
8284
summary['enrollment_modes'].update({
8385
mode: {
8486
'count': 0,
8587
'cumulative_count': 0,
8688
'count_change_7_days': 0,
89+
'passing_users': 0,
8790
} for mode in set(enrollment_modes.ALL) - set(modes)
8891
})
8992
no_prof = summary['enrollment_modes'].pop(enrollment_modes.PROFESSIONAL_NO_ID)
@@ -92,6 +95,7 @@ def expected_result(self, item_id, modes=None, availability='Current', programs=
9295
'count': prof['count'] + no_prof['count'],
9396
'cumulative_count': prof['cumulative_count'] + no_prof['cumulative_count'],
9497
'count_change_7_days': prof['count_change_7_days'] + no_prof['count_change_7_days'],
98+
'passing_users': prof['passing_users'] + no_prof['passing_users'],
9599
})
96100
if programs:
97101
summary['programs'] = [CourseSamples.program_ids[0]]
@@ -159,3 +163,10 @@ def test_programs(self):
159163
response = self.authenticated_get(self.path(exclude=self.always_exclude[:1], programs=['True']))
160164
self.assertEquals(response.status_code, 200)
161165
self.assertItemsEqual(response.data, self.all_expected_results(programs=True))
166+
167+
@ddt.data('passing_users', )
168+
def test_exclude(self, field):
169+
self.generate_data()
170+
response = self.authenticated_get(self.path(exclude=[field]))
171+
self.assertEquals(response.status_code, 200)
172+
self.assertEquals(str(response.data).count(field), 0)

analytics_data_api/v0/views/course_summaries.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ class CourseSummariesView(APIListView):
5454
model = models.CourseMetaSummaryEnrollment
5555
model_id_field = 'course_id'
5656
programs_model = models.CourseProgramMetadata
57-
count_fields = ('count', 'cumulative_count', 'count_change_7_days') # are initialized to 0 by default
57+
count_fields = ('count', 'cumulative_count', 'count_change_7_days',
58+
'passing_users') # are initialized to 0 by default
5859
summary_meta_fields = ['catalog_course_title', 'catalog_course', 'start_time', 'end_time',
5960
'pacing_type', 'availability'] # fields to extract from summary model
6061

@@ -120,6 +121,10 @@ def postprocess_field_dict(self, field_dict):
120121
# don't do expensive looping for programs if we are just going to throw it away
121122
field_dict = self.add_programs(field_dict)
122123

124+
for field in self.exclude:
125+
for mode in field_dict['enrollment_modes']:
126+
_ = field_dict['enrollment_modes'][mode].pop(field, None)
127+
123128
return field_dict
124129

125130
def add_programs(self, field_dict):

0 commit comments

Comments
 (0)