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
8b5c66c9
Commit
8b5c66c9
authored
Oct 17, 2014
by
Dennis Jen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated enrollment/gender endpoint to aggregate gender counts by day.
parent
646ad4a1
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
90 additions
and
21 deletions
+90
-21
AUTHORS
+1
-0
analytics_data_api/v0/constants.py
+5
-0
analytics_data_api/v0/models.py
+15
-2
analytics_data_api/v0/serializers.py
+7
-3
analytics_data_api/v0/tests/test_views.py
+28
-6
analytics_data_api/v0/views/courses.py
+34
-10
No files found.
AUTHORS
View file @
8b5c66c9
Ben Patterson <bpatterson@edx.org>
Ben Patterson <bpatterson@edx.org>
Carlos Andrés Rocha <rocha@edx.org>
Carlos Andrés Rocha <rocha@edx.org>
Clinton Blackburn <cblackburn@edx.org>
Clinton Blackburn <cblackburn@edx.org>
Dennis Jen <djen@edx.org>
Ed Zarecor <ed@edx.org>
Ed Zarecor <ed@edx.org>
Gabe Mulley <gabe@edx.org>
Gabe Mulley <gabe@edx.org>
Jason Bau <jbau@stanford.edu>
Jason Bau <jbau@stanford.edu>
...
...
analytics_data_api/v0/constants.py
View file @
8b5c66c9
...
@@ -2,3 +2,8 @@ from iso3166 import Country
...
@@ -2,3 +2,8 @@ from iso3166 import Country
UNKNOWN_COUNTRY_CODE
=
u'UNKNOWN'
UNKNOWN_COUNTRY_CODE
=
u'UNKNOWN'
UNKNOWN_COUNTRY
=
Country
(
UNKNOWN_COUNTRY_CODE
,
None
,
None
,
None
)
UNKNOWN_COUNTRY
=
Country
(
UNKNOWN_COUNTRY_CODE
,
None
,
None
,
None
)
FEMALE_GENDER
=
u'female'
MALE_GENDER
=
u'male'
OTHER_GENDER
=
u'other'
UNKNOWN_GENDER
=
u'unknown'
analytics_data_api/v0/models.py
View file @
8b5c66c9
from
django.db
import
models
from
django.db
import
models
from
iso3166
import
countries
from
iso3166
import
countries
from
analytics_data_api.v0.constants
import
UNKNOWN_COUNTRY
from
analytics_data_api.v0.constants
import
UNKNOWN_COUNTRY
,
FEMALE_GENDER
,
MALE_GENDER
,
OTHER_GENDER
,
UNKNOWN_GENDER
class
CourseActivityWeekly
(
models
.
Model
):
class
CourseActivityWeekly
(
models
.
Model
):
...
@@ -75,7 +75,20 @@ class CourseEnrollmentByEducation(BaseCourseEnrollment):
...
@@ -75,7 +75,20 @@ class CourseEnrollmentByEducation(BaseCourseEnrollment):
class
CourseEnrollmentByGender
(
BaseCourseEnrollment
):
class
CourseEnrollmentByGender
(
BaseCourseEnrollment
):
gender
=
models
.
CharField
(
max_length
=
255
,
null
=
False
)
CLEANED_GENDERS
=
{
'f'
:
FEMALE_GENDER
,
'm'
:
MALE_GENDER
,
'o'
:
OTHER_GENDER
}
gender
=
models
.
CharField
(
max_length
=
255
,
null
=
True
,
db_column
=
'gender'
)
@property
def
cleaned_gender
(
self
):
"""
Returns the gender with full names and 'unknown' replacing null/None.
"""
return
self
.
CLEANED_GENDERS
.
get
(
self
.
gender
,
UNKNOWN_GENDER
)
class
Meta
(
BaseCourseEnrollment
.
Meta
):
class
Meta
(
BaseCourseEnrollment
.
Meta
):
db_table
=
'course_enrollment_gender_daily'
db_table
=
'course_enrollment_gender_daily'
...
...
analytics_data_api/v0/serializers.py
View file @
8b5c66c9
from
django.conf
import
settings
from
django.conf
import
settings
from
rest_framework
import
serializers
from
rest_framework
import
serializers
from
analytics_data_api.v0
import
models
from
analytics_data_api.v0
import
models
from
analytics_data_api.v0.models
import
CourseActivityWeekly
class
CourseActivityByWeekSerializer
(
serializers
.
ModelSerializer
):
class
CourseActivityByWeekSerializer
(
serializers
.
ModelSerializer
):
...
@@ -97,9 +96,14 @@ class CourseEnrollmentByCountrySerializer(BaseCourseEnrollmentModelSerializer):
...
@@ -97,9 +96,14 @@ class CourseEnrollmentByCountrySerializer(BaseCourseEnrollmentModelSerializer):
class
CourseEnrollmentByGenderSerializer
(
BaseCourseEnrollmentModelSerializer
):
class
CourseEnrollmentByGenderSerializer
(
BaseCourseEnrollmentModelSerializer
):
female
=
serializers
.
IntegerField
(
required
=
False
)
male
=
serializers
.
IntegerField
(
required
=
False
)
other
=
serializers
.
IntegerField
(
required
=
False
)
unknown
=
serializers
.
IntegerField
(
required
=
False
)
class
Meta
(
object
):
class
Meta
(
object
):
model
=
models
.
CourseEnrollmentByGender
model
=
models
.
CourseEnrollmentByGender
fields
=
(
'course_id'
,
'date'
,
'
gender'
,
'count
'
,
'created'
)
fields
=
(
'course_id'
,
'date'
,
'
female'
,
'male'
,
'other'
,
'unknown
'
,
'created'
)
class
CourseEnrollmentByEducationSerializer
(
BaseCourseEnrollmentModelSerializer
):
class
CourseEnrollmentByEducationSerializer
(
BaseCourseEnrollmentModelSerializer
):
...
@@ -126,6 +130,6 @@ class CourseActivityWeeklySerializer(serializers.ModelSerializer):
...
@@ -126,6 +130,6 @@ class CourseActivityWeeklySerializer(serializers.ModelSerializer):
created
=
serializers
.
DateTimeField
(
format
=
settings
.
DATETIME_FORMAT
)
created
=
serializers
.
DateTimeField
(
format
=
settings
.
DATETIME_FORMAT
)
class
Meta
(
object
):
class
Meta
(
object
):
model
=
CourseActivityWeekly
model
=
models
.
CourseActivityWeekly
# TODO: Add 'posted_forum' here to restore forum data
# TODO: Add 'posted_forum' here to restore forum data
fields
=
(
'interval_start'
,
'interval_end'
,
'course_id'
,
'any'
,
'attempted_problem'
,
'played_video'
,
'created'
)
fields
=
(
'interval_start'
,
'interval_end'
,
'course_id'
,
'any'
,
'attempted_problem'
,
'played_video'
,
'created'
)
analytics_data_api/v0/tests/test_views.py
View file @
8b5c66c9
...
@@ -314,18 +314,40 @@ class CourseEnrollmentByGenderViewTests(CourseEnrollmentViewTestCaseMixin, TestC
...
@@ -314,18 +314,40 @@ class CourseEnrollmentByGenderViewTests(CourseEnrollmentViewTestCaseMixin, TestC
def
generate_data
(
self
,
course_id
=
None
):
def
generate_data
(
self
,
course_id
=
None
):
course_id
=
course_id
or
self
.
course_id
course_id
=
course_id
or
self
.
course_id
G
(
self
.
model
,
course_id
=
course_id
,
gender
=
'm'
,
date
=
self
.
date
,
count
=
34
)
genders
=
[
'f'
,
'm'
,
'o'
,
None
]
G
(
self
.
model
,
course_id
=
course_id
,
gender
=
'f'
,
date
=
self
.
date
,
count
=
45
)
days
=
2
G
(
self
.
model
,
course_id
=
course_id
,
gender
=
'f'
,
date
=
self
.
date
-
datetime
.
timedelta
(
days
=
2
),
count
=
45
)
for
day
in
range
(
days
):
for
gender
in
genders
:
G
(
self
.
model
,
course_id
=
course_id
,
date
=
self
.
date
-
datetime
.
timedelta
(
days
=
day
),
gender
=
gender
,
count
=
100
+
day
)
def
setUp
(
self
):
def
setUp
(
self
):
super
(
CourseEnrollmentByGenderViewTests
,
self
)
.
setUp
()
super
(
CourseEnrollmentByGenderViewTests
,
self
)
.
setUp
()
self
.
generate_data
()
self
.
generate_data
()
def
format_as_response
(
self
,
*
args
):
def
format_as_response
(
self
,
*
args
):
return
[
response
=
[]
{
'course_id'
:
unicode
(
ce
.
course_id
),
'count'
:
ce
.
count
,
'date'
:
ce
.
date
.
strftime
(
settings
.
DATE_FORMAT
),
'gender'
:
ce
.
gender
,
'created'
:
ce
.
created
.
strftime
(
settings
.
DATETIME_FORMAT
)}
for
ce
in
args
]
# Group by date
for
_key
,
group
in
groupby
(
args
,
lambda
x
:
x
.
date
):
# Iterate over groups and create a single item with genders
item
=
{}
for
enrollment
in
group
:
item
.
update
({
'created'
:
enrollment
.
created
.
strftime
(
settings
.
DATETIME_FORMAT
),
'course_id'
:
unicode
(
enrollment
.
course_id
),
'date'
:
enrollment
.
date
.
strftime
(
settings
.
DATE_FORMAT
),
enrollment
.
cleaned_gender
:
enrollment
.
count
})
response
.
append
(
item
)
return
response
# pylint: disable=no-member,no-value-for-parameter
# pylint: disable=no-member,no-value-for-parameter
...
...
analytics_data_api/v0/views/courses.py
View file @
8b5c66c9
...
@@ -83,7 +83,7 @@ class CourseActivityWeeklyView(BaseCourseView):
...
@@ -83,7 +83,7 @@ class CourseActivityWeeklyView(BaseCourseView):
<dd>The number of unique users who created a new post, responded to a post, or submitted a comment on any forum in the course.</dd>
<dd>The number of unique users who created a new post, responded to a post, or submitted a comment on any forum in the course.</dd>
</dl>
</dl>
If no start or end dates are passed, the data for the latest date is returned. All dates
should
are in the UTC zone.
If no start or end dates are passed, the data for the latest date is returned. All dates are in the UTC zone.
Data is sorted chronologically (earliest to latest).
Data is sorted chronologically (earliest to latest).
...
@@ -248,7 +248,7 @@ class CourseEnrollmentByBirthYearView(BaseCourseEnrollmentView):
...
@@ -248,7 +248,7 @@ class CourseEnrollmentByBirthYearView(BaseCourseEnrollmentView):
Returns the enrollment of a course with users binned by their birth years.
Returns the enrollment of a course with users binned by their birth years.
If no start or end dates are passed, the data for the latest date is returned. All dates
should
are in the UTC zone.
If no start or end dates are passed, the data for the latest date is returned. All dates are in the UTC zone.
Data is sorted chronologically (earliest to latest).
Data is sorted chronologically (earliest to latest).
...
@@ -269,7 +269,7 @@ class CourseEnrollmentByEducationView(BaseCourseEnrollmentView):
...
@@ -269,7 +269,7 @@ class CourseEnrollmentByEducationView(BaseCourseEnrollmentView):
Returns the enrollment of a course with users binned by their education levels.
Returns the enrollment of a course with users binned by their education levels.
If no start or end dates are passed, the data for the latest date is returned. All dates
should
are in the UTC zone.
If no start or end dates are passed, the data for the latest date is returned. All dates are in the UTC zone.
Data is sorted chronologically (earliest to latest).
Data is sorted chronologically (earliest to latest).
...
@@ -287,14 +287,15 @@ class CourseEnrollmentByGenderView(BaseCourseEnrollmentView):
...
@@ -287,14 +287,15 @@ class CourseEnrollmentByGenderView(BaseCourseEnrollmentView):
"""
"""
Course enrollment broken down by user gender
Course enrollment broken down by user gender
Returns the enrollment of a course w
ith users binned by their genders
.
Returns the enrollment of a course w
here each row/item contains user genders for the day
.
Genders:
Genders:
m - male
male
f - female
female
o - other
other
unknown
If no start or end dates are passed, the data for the latest date is returned. All dates
should
are in the UTC zone.
If no start or end dates are passed, the data for the latest date is returned. All dates are in the UTC zone.
Data is sorted chronologically (earliest to latest).
Data is sorted chronologically (earliest to latest).
...
@@ -307,12 +308,35 @@ class CourseEnrollmentByGenderView(BaseCourseEnrollmentView):
...
@@ -307,12 +308,35 @@ class CourseEnrollmentByGenderView(BaseCourseEnrollmentView):
serializer_class
=
serializers
.
CourseEnrollmentByGenderSerializer
serializer_class
=
serializers
.
CourseEnrollmentByGenderSerializer
model
=
models
.
CourseEnrollmentByGender
model
=
models
.
CourseEnrollmentByGender
def
get_queryset
(
self
):
queryset
=
super
(
CourseEnrollmentByGenderView
,
self
)
.
get_queryset
()
formatted_data
=
[]
for
key
,
group
in
groupby
(
queryset
,
lambda
x
:
(
x
.
course_id
,
x
.
date
)):
# Iterate over groups and create a single item with gender data
item
=
{
u'course_id'
:
key
[
0
],
u'date'
:
key
[
1
],
u'created'
:
None
}
for
enrollment
in
group
:
gender
=
enrollment
.
cleaned_gender
.
lower
()
count
=
item
.
get
(
gender
,
0
)
count
+=
enrollment
.
count
item
[
gender
]
=
count
item
[
u'created'
]
=
max
(
enrollment
.
created
,
item
[
u'created'
])
if
item
[
u'created'
]
else
enrollment
.
created
formatted_data
.
append
(
item
)
return
formatted_data
class
CourseEnrollmentView
(
BaseCourseEnrollmentView
):
class
CourseEnrollmentView
(
BaseCourseEnrollmentView
):
"""
"""
Returns the enrollment count for the specified course.
Returns the enrollment count for the specified course.
If no start or end dates are passed, the data for the latest date is returned. All dates
should
are in the UTC zone.
If no start or end dates are passed, the data for the latest date is returned. All dates are in the UTC zone.
Data is sorted chronologically (earliest to latest).
Data is sorted chronologically (earliest to latest).
...
@@ -337,7 +361,7 @@ class CourseEnrollmentByLocationView(BaseCourseEnrollmentView):
...
@@ -337,7 +361,7 @@ class CourseEnrollmentByLocationView(BaseCourseEnrollmentView):
Countries are denoted by their <a href="http://www.iso.org/iso/country_codes/country_codes" target="_blank">ISO 3166 country code</a>.
Countries are denoted by their <a href="http://www.iso.org/iso/country_codes/country_codes" target="_blank">ISO 3166 country code</a>.
If no start or end dates are passed, the data for the latest date is returned. All dates
should
are in the UTC zone.
If no start or end dates are passed, the data for the latest date is returned. All dates are in the UTC zone.
Data is sorted chronologically (earliest to latest).
Data is sorted chronologically (earliest to latest).
...
...
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