Skip to content
Snippets Groups Projects
Commit 8b4b5a45 authored by Calen Pennington's avatar Calen Pennington
Browse files

Move stable_bucketing into its own library to minimize circular dependencies

parent 3c220d11
No related merge requests found
"""
An implementation of a stable bucketing algorithm that can be used
to reliably group users into experiments.
"""
import hashlib
import re
def stable_bucketing_hash_group(group_name, group_count, username):
"""
Return the bucket that a user should be in for a given stable bucketing assignment.
This function has been verified to return the same values as the stable bucketing
functions in javascript and the master experiments table.
Arguments:
group_name: The name of the grouping/experiment.
group_count: How many groups to bucket users into.
username: The username of the user being bucketed.
"""
hasher = hashlib.md5()
hasher.update(group_name.encode('utf-8'))
hasher.update(username.encode('utf-8'))
hash_str = hasher.hexdigest()
return int(re.sub('[8-9a-f]', '1', re.sub('[0-7]', '0', hash_str)), 2) % group_count
......@@ -4,9 +4,7 @@ Utilities to facilitate experimentation
from __future__ import absolute_import
import hashlib
import logging
import re
from decimal import Decimal
import six
......@@ -27,6 +25,9 @@ from openedx.features.course_duration_limits.models import CourseDurationLimitCo
from student.models import CourseEnrollment
from xmodule.partitions.partitions_service import get_all_partitions_for_course, get_user_partition_groups
# Import this for backwards compatibility (so that anyone importing this function from here doesn't break)
from .stable_bucketing import stable_bucketing_hash_group # pylint: disable=unused-import
logger = logging.getLogger(__name__)
......@@ -386,23 +387,3 @@ def get_program_context(course, user_enrollments):
}
return program_key
# TODO: clean up as part of REVEM-199 (START)
def stable_bucketing_hash_group(group_name, group_count, username):
"""
Return the bucket that a user should be in for a given stable bucketing assignment.
This function has been verified to return the same values as the stable bucketing
functions in javascript and the master experiments table.
Arguments:
group_name: The name of the grouping/experiment.
group_count: How many groups to bucket users into.
username: The username of the user being bucketed.
"""
hasher = hashlib.md5()
hasher.update(group_name.encode('utf-8'))
hasher.update(username.encode('utf-8'))
hash_str = hasher.hexdigest()
return int(re.sub('[8-9a-f]', '1', re.sub('[0-7]', '0', hash_str)), 2) % group_count
......@@ -15,7 +15,7 @@ from eventtracking import tracker
from course_modes.models import CourseMode
from courseware.date_summary import verified_upgrade_deadline_link
from lms.djangoapps.experiments.utils import stable_bucketing_hash_group
from lms.djangoapps.experiments.stable_bucketing import stable_bucketing_hash_group
from openedx.core.djangoapps.catalog.utils import get_course_run_details
from openedx.core.djangoapps.schedules.resolvers import (
BinnedSchedulesBaseResolver,
......
......@@ -8,8 +8,10 @@ Keep in mind that the code in this file only applies to discounts controlled in
not other discounts like coupons or enterprise/program offers configured in ecommerce.
"""
import crum
from course_modes.models import CourseMode
from entitlements.models import CourseEntitlement
from lms.djangoapps.experiments.stable_bucketing import stable_bucketing_hash_group
from openedx.core.djangoapps.waffle_utils import WaffleFlag, WaffleFlagNamespace
from openedx.features.discounts.models import DiscountRestrictionConfig
from student.models import CourseEnrollment
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment