Move stable_bucketing into its own library to minimize circular dependencies
This commit is contained in:
27
lms/djangoapps/experiments/stable_bucketing.py
Normal file
27
lms/djangoapps/experiments/stable_bucketing.py
Normal file
@@ -0,0 +1,27 @@
|
||||
"""
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user