Added methods for creating data points to the abtesteventdao

pull/14/head
Sam Bosley 13 years ago
parent f08d3c2890
commit c7e18592a6

@ -200,6 +200,19 @@ public class AndroidUtilities {
return -1; return -1;
} }
/**
* Return index of value in integer array
* @param array array to search
* @param value value to look for
* @return
*/
public static int indexOf(int[] array, int value) {
for (int i = 0; i < array.length; i++)
if (array[i] == value)
return i;
return -1;
}
/** /**
* Serializes a content value into a string * Serializes a content value into a string
*/ */

@ -1,8 +1,13 @@
package com.todoroo.astrid.dao; package com.todoroo.astrid.dao;
import com.todoroo.andlib.data.DatabaseDao; import com.todoroo.andlib.data.DatabaseDao;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.data.ABTestEvent; import com.todoroo.astrid.data.ABTestEvent;
public class ABTestEventDao extends DatabaseDao<ABTestEvent> { public class ABTestEventDao extends DatabaseDao<ABTestEvent> {
@ -16,4 +21,50 @@ public class ABTestEventDao extends DatabaseDao<ABTestEvent> {
setDatabase(database); setDatabase(database);
} }
public void createInitialTestEvent(String testName, String testVariant,
boolean newUser, boolean activeUser) {
ABTestEvent event = new ABTestEvent();
event.setValue(ABTestEvent.TEST_NAME, testName);
event.setValue(ABTestEvent.TEST_VARIANT, testVariant);
event.setValue(ABTestEvent.NEW_USER, newUser ? 1 : 0);
event.setValue(ABTestEvent.ACTIVATED_USER, activeUser ? 1 : 0);
event.setValue(ABTestEvent.TIME_INTERVAL, ABTestEvent.TIME_INTERVAL_0);
event.setValue(ABTestEvent.DATE_RECORDED, DateUtilities.now());
createNew(event);
}
public boolean createTestEventWithTimeInterval(String testName, int timeInterval) {
TodorooCursor<ABTestEvent> existing = query(Query.select(ABTestEvent.PROPERTIES)
.where(ABTestEvent.TEST_NAME.eq(testName)).orderBy(Order.asc(ABTestEvent.TIME_INTERVAL)));
try {
if (existing.getCount() == 0)
return false;
existing.moveToLast();
ABTestEvent item = new ABTestEvent(existing);
int lastRecordedTimeIntervalIndex = AndroidUtilities.indexOf(
ABTestEvent.TIME_INTERVALS, item.getValue(ABTestEvent.TIME_INTERVAL));
int currentTimeIntervalIndex = AndroidUtilities.indexOf(
ABTestEvent.TIME_INTERVALS, timeInterval);
if (lastRecordedTimeIntervalIndex < 0 || currentTimeIntervalIndex < 0
|| lastRecordedTimeIntervalIndex >= currentTimeIntervalIndex)
return false;
long now = DateUtilities.now();
for (int i = lastRecordedTimeIntervalIndex + 1; i <= currentTimeIntervalIndex; i++) {
item.clearValue(ABTestEvent.ID);
item.setValue(ABTestEvent.TIME_INTERVAL, ABTestEvent.TIME_INTERVALS[i]);
item.setValue(ABTestEvent.DATE_RECORDED, now);
createNew(item);
}
} finally {
existing.close();
}
return true;
}
} }

@ -9,18 +9,25 @@ import com.todoroo.andlib.data.Property.IntegerProperty;
import com.todoroo.andlib.data.Property.LongProperty; import com.todoroo.andlib.data.Property.LongProperty;
import com.todoroo.andlib.data.Property.StringProperty; import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.andlib.data.Table; import com.todoroo.andlib.data.Table;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.AstridApiConstants;
@SuppressWarnings("nls") @SuppressWarnings("nls")
public class ABTestEvent extends AbstractModel { public class ABTestEvent extends AbstractModel {
public static final long TEST_INTERVAL_0 = 0; public static final int TIME_INTERVAL_0 = 0;
public static final long TEST_INTERVAL_3 = 3 * DateUtilities.ONE_DAY; public static final int TIME_INTERVAL_3 = 3;
public static final long TEST_INTERVAL_7 = DateUtilities.ONE_WEEK; public static final int TIME_INTERVAL_7 = 7;
public static final long TEST_INTERVAL_14 = 2 * DateUtilities.ONE_WEEK; public static final int TIME_INTERVAL_14 = 14;
public static final long TEST_INTERVAL_21 = 3 * DateUtilities.ONE_WEEK; public static final int TIME_INTERVAL_21 = 21;
public static final int[] TIME_INTERVALS = {
TIME_INTERVAL_0,
TIME_INTERVAL_3,
TIME_INTERVAL_7,
TIME_INTERVAL_14,
TIME_INTERVAL_21
};
// --- table and uri // --- table and uri
@ -70,7 +77,7 @@ public class ABTestEvent extends AbstractModel {
* Which time interval event this data point corresponds to. * Which time interval event this data point corresponds to.
* Should be one of the time interval constants defined above. * Should be one of the time interval constants defined above.
*/ */
public static final LongProperty TIME_INTERVAL = new LongProperty( public static final IntegerProperty TIME_INTERVAL = new IntegerProperty(
TABLE, "timeInterval"); // one of the constants defined above TABLE, "timeInterval"); // one of the constants defined above
/** The actual date on which this data point was recorded. */ /** The actual date on which this data point was recorded. */
@ -92,6 +99,17 @@ public class ABTestEvent extends AbstractModel {
return defaultValues; return defaultValues;
} }
// --- data access boilerplate
public ABTestEvent() {
super();
}
public ABTestEvent(TodorooCursor<ABTestEvent> cursor) {
this();
readPropertiesFromCursor(cursor);
}
@Override @Override
public long getId() { public long getId() {
return getIdHelper(ID); return getIdHelper(ID);

@ -6,7 +6,7 @@ import java.util.Set;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.utility.Preferences; import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.service.StatisticsService; import com.todoroo.astrid.dao.ABTestEventDao;
/** /**
* Helper class to facilitate A/B testing by randomly choosing an option * Helper class to facilitate A/B testing by randomly choosing an option
@ -21,6 +21,9 @@ public class ABChooser {
@Autowired @Autowired
private ABTests abTests; private ABTests abTests;
@Autowired
private ABTestEventDao abTestEventDao;
private final Random random; private final Random random;
public ABChooser() { public ABChooser() {
@ -32,10 +35,10 @@ public class ABChooser {
* Iterates through the list of all available tests and makes sure that a choice * Iterates through the list of all available tests and makes sure that a choice
* is made for each of them * is made for each of them
*/ */
public void makeChoicesForAllTests() { public void makeChoicesForAllTests(boolean newUser, boolean activatedUser) {
Set<String> tests = abTests.getAllTestKeys(); Set<String> tests = abTests.getAllTestKeys();
for (String test : tests) { for (String test : tests) {
getChoiceForTest(test); makeChoiceForTest(test, newUser, activatedUser);
} }
} }
@ -47,21 +50,22 @@ public class ABChooser {
* The statistics session needs to be open here in order to collect statistics * The statistics session needs to be open here in order to collect statistics
* *
* @param testKey - the preference key string of the option (defined in ABTests) * @param testKey - the preference key string of the option (defined in ABTests)
* @return
*/ */
private int getChoiceForTest(String testKey) { private void makeChoiceForTest(String testKey, boolean newUser, boolean activatedUser) {
int pref = readChoiceForTest(testKey); int pref = readChoiceForTest(testKey);
if (pref > NO_OPTION) return pref; if (pref > NO_OPTION) return;
int chosen = NO_OPTION; int chosen = NO_OPTION;
if (abTests.isValidTestKey(testKey)) { if (abTests.isValidTestKey(testKey)) {
int[] optionProbs = abTests.getProbsForTestKey(testKey); int[] optionProbs = abTests.getProbsForTestKey(testKey);
String[] optionDescriptions = abTests.getDescriptionsForTestKey(testKey);
chosen = chooseOption(optionProbs); chosen = chooseOption(optionProbs);
setChoiceForTest(testKey, chosen); setChoiceForTest(testKey, chosen);
StatisticsService.reportEvent(abTests.getDescriptionForTestOption(testKey, chosen)); // Session should be open String desc = optionDescriptions[chosen];
abTestEventDao.createInitialTestEvent(testKey, desc, newUser, activatedUser);
} }
return chosen; return;
} }
/** /**

Loading…
Cancel
Save