Files
edx-platform/lms/djangoapps/course_home_api/progress/api.py
Justin Hynes 919615635e feat: optionally emit course completion analytics when a learner enters the courseware (#36507)
This PR attempts to improve the ability to collect analytics about learner's progress
in their courses. Currently, the only place we regularly calculate course progress is
when a learner visits the "Progress" tab in the courseware.

Now, _optionally_, when a learner visits the home page of their course, we will enqueue
a Celery task that will calculate their progress and emit a tracking event.

This event is gated by use of the COURSE_HOME_SEND_COURSE_PROGRESS_ANALYTICS_FOR_STUDENT
waffle flag.
2025-04-29 13:46:09 -04:00

44 lines
1.7 KiB
Python

"""
Python APIs exposed for the progress tracking functionality of the course home API.
"""
from django.contrib.auth import get_user_model
from opaque_keys.edx.keys import CourseKey
from lms.djangoapps.courseware.courses import get_course_blocks_completion_summary
User = get_user_model()
def calculate_progress_for_learner_in_course(course_key: CourseKey, user: User) -> dict:
"""
Calculate a given learner's progress in the specified course run.
"""
summary = get_course_blocks_completion_summary(course_key, user)
if not summary:
return {}
complete_count = summary.get("complete_count", 0)
locked_count = summary.get("locked_count", 0)
incomplete_count = summary.get("incomplete_count", 0)
# This completion calculation mirrors the logic used in the CompletionDonutChart component on the Learning MFE's
# Progress tab. It's duplicated here to enable backend reporting on learner progress. Ideally, this logic should be
# refactored in the future so that the calculation is handled solely on the backend, eliminating the need for it to
# be done in the frontend.
num_total_units = complete_count + incomplete_count + locked_count
complete_percentage = round(complete_count / num_total_units, 2)
locked_percentage = round(locked_count / num_total_units, 2)
incomplete_percentage = 1.00 - complete_percentage - locked_percentage
return {
"complete_count": complete_count,
"locked_count": locked_count,
"incomplete_count": incomplete_count,
"total_count": num_total_units,
"complete_percentage": complete_percentage,
"locked_percentage": locked_percentage,
"incomplete_percentage": incomplete_percentage
}