From c280234cf6cb45fbc6fa78b2eab9b7778b367078 Mon Sep 17 00:00:00 2001 From: Rohitesh Dutta Date: Wed, 22 Nov 2023 20:33:12 +0530 Subject: [PATCH] fix(MEG): fixed issue with Advanced implementation of MEG --- CHANGELOG.md | 6 ++ tests/core/test_mutually_exclusive_newimpl.py | 10 ++-- vwo/core/variation_decider.py | 56 +++++++------------ 3 files changed, 33 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5901d76..43ea14c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.66.0] - 2023-11-22 + +### Fixed + +- Fixed issue with Advanced implementation of MEG + ## [1.64.0] - 2023-10-10 ### Fixed diff --git a/tests/core/test_mutually_exclusive_newimpl.py b/tests/core/test_mutually_exclusive_newimpl.py index 8b0b4d9..c4cbebc 100644 --- a/tests/core/test_mutually_exclusive_newimpl.py +++ b/tests/core/test_mutually_exclusive_newimpl.py @@ -64,18 +64,20 @@ def test_traffic_weightage_campaigns(self): low_traffic_count = 0 # run through 1000 iterations of called campaign is high traffic campaign - for _ in range(1000): + for i in range(1000): + user_id = "user" + str(i) # call activate on local vwo instance and get variation - variation = vwo_instance.get_variation_name(high_traffic_campaign_key, self.user_id) + variation = vwo_instance.get_variation_name(high_traffic_campaign_key, user_id) # if valid variation returned, increment high count if variation: high_traffic_count += 1 # run through 1000 iterations of called campaign is low traffic campaign - for _ in range(1000): + for i in range(1000): + user_id = "user" + str(i) # call activate on local vwo and get variation - variation = vwo_instance.get_variation_name(low_traffic_campaign_key, self.user_id) + variation = vwo_instance.get_variation_name(low_traffic_campaign_key, user_id) # if valid variation returned, increment low count if variation: diff --git a/vwo/core/variation_decider.py b/vwo/core/variation_decider.py index 6a293b1..cbabb97 100644 --- a/vwo/core/variation_decider.py +++ b/vwo/core/variation_decider.py @@ -964,6 +964,10 @@ def _get_winner_campaign_advanced(self, user_id, eligible_campaigns, group_id): Returns: winner_campaign (dict): winner campaign from eligible_campaigns """ + if self.settings_file: + is_new_bucketing_enabled = self.settings_file.get("isNB") + else: + is_new_bucketing_enabled = False winner_campaign = None @@ -1016,15 +1020,26 @@ def _get_winner_campaign_advanced(self, user_id, eligible_campaigns, group_id): if str(eligible_campaign.get("id")) in traffic_weightage_campaigns: # Get campaign and percentage traffic + eligible_campaign["weight"] = traffic_weightage_campaigns.get(str(eligible_campaign.get("id"))) eligible_traffic_weightage_campaigns.append(eligible_campaign) - percentage_traffic_for_weightage_campaigns.append( - traffic_weightage_campaigns.get(str(eligible_campaign.get("id"))) - ) - # Select winner based on traffic weightage from eligible campaigns - winner_campaign = self._get_campaign_based_on_traffic_weightage( - eligible_traffic_weightage_campaigns, percentage_traffic_for_weightage_campaigns + """ Finding winner campaign using weighted Distibution : + 1. Re-distribute the traffic by assigning range values for each camapign in particaptingCampaignList + 2. Calculate bucket value for the given userId and groupId + 3. Get the winnerCampaign by checking the Start and End Bucket Allocations of each campaign + """ + # Allocate new range for campaigns + campaign_util.set_allocation_ranges(eligible_traffic_weightage_campaigns) + # Now retrieve the campaign from the modified_campaign_for_whitelisting + bucket_value = self.bucketer.get_bucket_value_for_user( + campaign_util.get_bucketing_seed( + is_new_bucketing_enabled=is_new_bucketing_enabled, user_id=user_id, group_id=group_id + ), + user_id, + constants.MAX_TRAFFIC_VALUE, + disable_logs=True, ) + winner_campaign = self.bucketer.get_allocated_item(eligible_traffic_weightage_campaigns, bucket_value) # log traffic weightage campaign winner self.logger.log( @@ -1036,32 +1051,3 @@ def _get_winner_campaign_advanced(self, user_id, eligible_campaigns, group_id): ) return winner_campaign - - def _get_campaign_based_on_traffic_weightage(self, campaigns, traffic_weightage): - """Returns a campaign based on traffic weightage of campaigns - - Args: - campaigns (list): campaigns eligible for traffic weightage - traffic_weightage (list): traffic distribution for each of the campaigns - - Returns: - campaign (dict): selected campaign based on random weighted traffic - """ - - cumulative_weights = [] - total_weight = 0 - - # Get the cumulative weights for the campaigns - for weight in traffic_weightage: - total_weight += weight - cumulative_weights.append(total_weight) - - # Get a weighted random - random_num = random.randint(0, total_weight - 1) - index = bisect.bisect_left(cumulative_weights, random_num) - - # Binary search returns a negative value when the generated number is between cumulative weights - if index < 0: - index = -(index + 1) - - return campaigns[index]