def testGetConversionData(self): days = [datetime.combine(date.today() + timedelta(days=i), time(hour=12)) for i in range(-7, 0)] yesterday = date.today() - timedelta(days=1) experiment = Experiment(name="experiment1") experiment.save() experiment.state = Experiment.ENABLED_STATE experiment.save() experiment.start_date = yesterday experiment.save() goal_types = [GoalType.objects.create(name="%s" % i) for i in range(4)] report = DailyConversionReport.objects.create(experiment=experiment, date=yesterday, overall_test_conversion=17, overall_control_conversion=12, test_group_size=139, control_group_size=142, confidence=87.3) DailyConversionReportGoalData.objects.create(report=report, goal_type=goal_types[0], test_conversion=11, control_conversion=0, confidence=65.3) DailyConversionReportGoalData.objects.create(report=report, goal_type=goal_types[1], test_conversion=0, control_conversion=21, confidence=None) DailyConversionReportGoalData.objects.create(report=report, goal_type=goal_types[2], test_conversion=23, control_conversion=21, confidence=100) data = get_conversion_data(experiment, yesterday) self.assertEqual(data['date'], yesterday) self.assertTrue("totals" in data) self.assertTrue("goal_types" in data) self.assertEqual(4, len(data["goal_types"].keys())) for goal_type in goal_types[0:3]: self.assertTrue(goal_type.name in data["goal_types"]) goal_type_data = data["goal_types"][goal_type.name] self.assertTrue("test_count" in goal_type_data) self.assertTrue("control_count" in goal_type_data) self.assertTrue("test_rate" in goal_type_data) self.assertTrue("control_rate" in goal_type_data) self.assertTrue("improvement" in goal_type_data) self.assertTrue("confidence" in goal_type_data) self.assertEqual(None, data["goal_types"][goal_types[3].name]) self.assertEqual(139, data["test_group_size"]) self.assertEqual(142, data["control_group_size"]) totals = data["totals"] expected_test_rate = 17. / 139. * 100. expected_control_rate = 12. / 142. * 100. expected_improvement = (expected_test_rate - expected_control_rate) / expected_control_rate * 100. self.assertAlmostEqual(expected_test_rate, totals["test_rate"]) self.assertAlmostEqual(expected_control_rate, totals["control_rate"]) self.assertAlmostEqual(expected_improvement, totals["improvement"]) self.assertAlmostEqual(87.3, totals["confidence"]) self.assertEqual(17, totals["test_count"]) self.assertEqual(12, totals["control_count"]) self.assertEqual(0, data["goal_types"][goal_types[0].name]["control_rate"]) self.assertAlmostEqual(11./139*100., data["goal_types"][goal_types[0].name]["test_rate"]) self.assertEqual(None, data["goal_types"][goal_types[0].name]["improvement"]) self.assertAlmostEqual(65.3, data["goal_types"][goal_types[0].name]["confidence"]) self.assertEqual(11, data["goal_types"][goal_types[0].name]["test_count"]) self.assertEqual(0, data["goal_types"][goal_types[0].name]["control_count"]) self.assertAlmostEqual(21./142*100., data["goal_types"][goal_types[1].name]["control_rate"]) self.assertEqual(None, data["goal_types"][goal_types[1].name]["confidence"]) self.assertEqual(None, data["goal_types"][goal_types[1].name]["improvement"]) self.assertAlmostEqual((23./139-21./142)/(21./142)*100., data["goal_types"][goal_types[2].name]["improvement"])
def testGetConversionData(self): days = [ datetime.combine(date.today() + timedelta(days=i), time(hour=12)) for i in range(-7, 0) ] yesterday = date.today() - timedelta(days=1) experiment = Experiment(name="experiment1") experiment.save() experiment.state = Experiment.ENABLED_STATE experiment.save() experiment.start_date = yesterday experiment.save() goal_types = [GoalType.objects.create(name="%s" % i) for i in range(4)] report = DailyConversionReport.objects.create( experiment=experiment, date=yesterday, overall_test_conversion=17, overall_control_conversion=12, test_group_size=139, control_group_size=142, confidence=87.3) DailyConversionReportGoalData.objects.create(report=report, goal_type=goal_types[0], test_conversion=11, control_conversion=0, confidence=65.3) DailyConversionReportGoalData.objects.create(report=report, goal_type=goal_types[1], test_conversion=0, control_conversion=21, confidence=None) DailyConversionReportGoalData.objects.create(report=report, goal_type=goal_types[2], test_conversion=23, control_conversion=21, confidence=100) data = get_conversion_data(experiment, yesterday) self.assertEquals(data['date'], yesterday) self.assertTrue("totals" in data) self.assertTrue("goal_types" in data) self.assertEquals(4, len(data["goal_types"].keys())) for goal_type in goal_types[0:3]: self.assertTrue(goal_type.name in data["goal_types"]) goal_type_data = data["goal_types"][goal_type.name] self.assertTrue("test_count" in goal_type_data) self.assertTrue("control_count" in goal_type_data) self.assertTrue("test_rate" in goal_type_data) self.assertTrue("control_rate" in goal_type_data) self.assertTrue("improvement" in goal_type_data) self.assertTrue("confidence" in goal_type_data) self.assertEquals(None, data["goal_types"][goal_types[3].name]) self.assertEquals(139, data["test_group_size"]) self.assertEquals(142, data["control_group_size"]) totals = data["totals"] expected_test_rate = 17. / 139. * 100. expected_control_rate = 12. / 142. * 100. expected_improvement = (expected_test_rate - expected_control_rate ) / expected_control_rate * 100. self.assertAlmostEquals(expected_test_rate, totals["test_rate"]) self.assertAlmostEquals(expected_control_rate, totals["control_rate"]) self.assertAlmostEquals(expected_improvement, totals["improvement"]) self.assertAlmostEquals(87.3, totals["confidence"]) self.assertEquals(17, totals["test_count"]) self.assertEquals(12, totals["control_count"]) self.assertEquals( 0, data["goal_types"][goal_types[0].name]["control_rate"]) self.assertAlmostEquals( 11. / 139 * 100., data["goal_types"][goal_types[0].name]["test_rate"]) self.assertEquals( None, data["goal_types"][goal_types[0].name]["improvement"]) self.assertAlmostEquals( 65.3, data["goal_types"][goal_types[0].name]["confidence"]) self.assertEquals(11, data["goal_types"][goal_types[0].name]["test_count"]) self.assertEquals( 0, data["goal_types"][goal_types[0].name]["control_count"]) self.assertAlmostEquals( 21. / 142 * 100., data["goal_types"][goal_types[1].name]["control_rate"]) self.assertEquals(None, data["goal_types"][goal_types[1].name]["confidence"]) self.assertEquals( None, data["goal_types"][goal_types[1].name]["improvement"]) self.assertAlmostEquals( (23. / 139 - 21. / 142) / (21. / 142) * 100., data["goal_types"][goal_types[2].name]["improvement"])
def experiment_details(request, experiment_name, template_name="experiments/experiment_details.html"): """ Displays a view with details for a specific experiment. Exposes: "experiment" (the experiment model) "daily_data" (An array of dicts with: {"date", "engagement_data": { "control_group_size", "control_group_score", "test_group_size", "test_group_score", "test_group_improvement", "confidence" }, "conversion_data": { "test_group_size", "control_group_size", "goal_types": { <goal-type-name>: { "test_count", "control_count", "test_rate", "control_rate", "improvement", "confidence" } }, "totals": { "test_count", "control_count", "test_rate", "control_rate", "improvement", "confidence" } } }) """ experiment = get_object_or_404(Experiment, name=experiment_name) daily_data = [] start_date = experiment.start_date if experiment.start_date: if experiment.end_date: if experiment.end_date > date.today(): # This experiment hasn't finished yet, so don't show details for days in the future end_date = date.today() else: end_date = experiment.end_date else: end_date = date.today() - timedelta(days=1) current_date = end_date while current_date >= start_date: daily_engagement_data = None daily_conversion_data = None engagement_report = None conversion_report = None try: engagement_report = DailyEngagementReport.objects.get(experiment=experiment, date=current_date) except: l.warn("No engagement report for date %s and experiment %s" % (current_date, experiment.name)) daily_conversion_data = get_conversion_data(experiment, current_date) if engagement_report: improvement = None if engagement_report.control_score > 0: improvement = ((engagement_report.test_score - engagement_report.control_score) / engagement_report.control_score) * 100 daily_engagement_data = { "control_group_size": engagement_report.control_group_size, "control_group_score": engagement_report.control_score, "test_group_size": engagement_report.test_group_size, "test_group_score": engagement_report.test_score, "test_group_improvement": improvement, "confidence": engagement_report.confidence} daily_data.append({ "date": current_date, "conversion_data": daily_conversion_data, "engagement_data": daily_engagement_data}) current_date = current_date - timedelta(1) context_var = {"experiment": experiment, "daily_data": daily_data, "experiment_states": experiment_states, "root_path": "../../", "title": "Experiment Report"} return render_to_response(template_name, context_var, context_instance=RequestContext(request))
def experiment_details(request, experiment_name, template_name="experiments/experiment_details.html"): """ Displays a view with details for a specific experiment. Exposes: "experiment" (the experiment model) "daily_data" (An array of dicts with: {"date", "engagement_data": { "control_group_size", "control_group_score", "test_group_size", "test_group_score", "test_group_improvement", "confidence" }, "conversion_data": { "test_group_size", "control_group_size", "goal_types": { <goal-type-name>: { "test_count", "control_count", "test_rate", "control_rate", "improvement", "confidence" } }, "totals": { "test_count", "control_count", "test_rate", "control_rate", "improvement", "confidence" } } }) """ experiment = get_object_or_404(Experiment, name=experiment_name) daily_data = [] start_date = experiment.start_date if experiment.start_date: if experiment.end_date: if experiment.end_date > date.today(): # This experiment hasn't finished yet, so don't show details for days in the future end_date = date.today() else: end_date = experiment.end_date else: end_date = date.today() current_date = end_date while current_date >= start_date: daily_engagement_data = None daily_conversion_data = None engagement_report = None conversion_report = None try: engagement_report = DailyEngagementReport.objects.get( experiment=experiment, date=current_date) except: l.warn("No engagement report for date %s and experiment %s" % (current_date, experiment.name)) daily_conversion_data = get_conversion_data( experiment, current_date) if engagement_report: improvement = None if engagement_report.control_score > 0: improvement = ((engagement_report.test_score - engagement_report.control_score) / engagement_report.control_score) * 100 daily_engagement_data = { "control_group_size": engagement_report.control_group_size, "control_group_score": engagement_report.control_score, "test_group_size": engagement_report.test_group_size, "test_group_score": engagement_report.test_score, "test_group_improvement": improvement, "confidence": engagement_report.confidence } daily_data.append({ "date": current_date, "conversion_data": daily_conversion_data, "engagement_data": daily_engagement_data }) current_date = current_date - timedelta(1) context_var = { "experiment": experiment, "daily_data": daily_data, "experiment_states": experiment_states, "root_path": "../../", "title": "Experiment Report" } return render_to_response(template_name, context_var, context_instance=RequestContext(request))