ExAbby.Experiments (ex_abby v0.3.0)

The Experiments context.

Summary

Functions

Archives an experiment, optionally setting a winner variation. Archived experiments will not accept new trials.

Creates a new experiment with given name and optional description.

Returns a summary of results for a given experiment: variations, total trials, and details for both success types including counts, amounts, and rates.

Formats a list of experiment results into a consistent response tuple. Returns either

Gets all trials for a session ID across all experiments.

Gets a single experiment with its variations. Returns nil if the experiment does not exist.

Gets an experiment by name.

Gets or creates an experiment by name.

Gets or creates a trial for a session. Returns {:error, :experiment_archived} if the experiment is archived.

Gets or creates trials for multiple experiments for a session. Returns a list of {variation, status} tuples in the same order as the experiment names.

Gets or creates a trial for a user. Returns {:error, :experiment_archived} if the experiment is archived.

Gets all session trials for a user, grouped by experiment.

Gets all trials for a user, grouped by experiment.

Gets a variation by ID.

Gets a variation by experiment_name and variation name.

Links a session-based trial to a user by updating the trial's user_id. This allows tracking the same experiment across both session and user contexts.

Lists experiments with their variations preloaded.

Lists experiments that have trials for the given session_id.

Lists experiments that have trials for the given user_id.

Calculate a naive p-value for the difference in conversion rates among variations. For multi-variate, we might do pairwise comparisons or a more advanced approach (ANOVA, etc.). Here is a simple demonstration using a 2-proportion z-test for a pair of variations. For multiple variations, you could do them pairwise.

Records successes for multiple experiments with consistent error handling. Returns either

Records successes for session-based experiments.

Records a success for a trial.

Records successes for user-based experiments.

Sets a specific variation for a session trial. Returns {:ok, trial} if successful, {:error, reason} otherwise.

Unarchives an experiment, clearing the winner variation.

Updates an experiment with the given attributes.

Updates the variation for a specific trial.

Allows updating variation weights for an experiment. Example

Functions

archive_experiment(experiment_id, winner_variation \\ nil)

Archives an experiment, optionally setting a winner variation. Archived experiments will not accept new trials.

Arguments

  • experiment_id - The ID of the experiment to archive
  • winner_variation - Optional winner: variation ID (integer) or name (string)

Examples

archive_experiment(123)                    # Archive without winner
archive_experiment(123, "variant_a")       # Archive with winner by name
archive_experiment(123, 456)               # Archive with winner by ID

create_experiment(name, description \\ nil)

Creates a new experiment with given name and optional description.

experiment_summary(experiment_name)

Returns a summary of results for a given experiment: variations, total trials, and details for both success types including counts, amounts, and rates.

Example output: [ %{

variation_id: 1,
variation_name: "Variation A",
trials: 100,
success1: %{
  count: 20,
  amount: 150.5,
  rate: 0.20,
  amount_per_trial: 1.505
},
success2: %{
  count: 15,
  amount: 75.25,
  rate: 0.15,
  amount_per_trial: 0.7525
}

}, ... ]

format_experiment_results(results)

Formats a list of experiment results into a consistent response tuple. Returns either:

  • {:ok, %{experiment_name => result}} if all successful
  • {:error, %{successful: [...], failed: [...]}} if any failed

get_all_trials_by_session(session_id)

Gets all trials for a session ID across all experiments.

get_experiment_by_id(id)

Gets a single experiment with its variations. Returns nil if the experiment does not exist.

get_experiment_by_name(name)

Gets an experiment by name.

get_or_create_experiment(name)

Gets or creates an experiment by name.

get_or_create_session_trial(experiment_name, session_id)

Gets or creates a trial for a session. Returns {:error, :experiment_archived} if the experiment is archived.

get_or_create_session_trials(experiment_names, session_id)

Gets or creates trials for multiple experiments for a session. Returns a list of {variation, status} tuples in the same order as the experiment names.

get_or_create_user_trial(experiment_name, user_id)

Gets or creates a trial for a user. Returns {:error, :experiment_archived} if the experiment is archived.

get_or_create_user_trials(experiment_names, user_id)

get_session_trials(session_id)

Gets all session trials for a user, grouped by experiment.

get_trial_by_session(experiment_id, session_id)

Gets a trial by session ID.

get_trial_by_user(experiment_id, user_id)

get_user_trials(user_id)

Gets all trials for a user, grouped by experiment.

get_variation(id)

Gets a variation by ID.

get_variation_by_name(experiment_name, var_name)

Gets a variation by experiment_name and variation name.

list_experiments(opts \\ [])

Lists experiments with their variations preloaded.

Options

  • :status - Filter by status: :active, :archived, or :all (default: :all)

Examples

list_experiments()                      # All experiments
list_experiments(status: :active)       # Only active (non-archived)
list_experiments(status: :archived)     # Only archived

list_experiments_with_session_trials(session_id)

Lists experiments that have trials for the given session_id.

list_experiments_with_user_trials(user_id)

Lists experiments that have trials for the given user_id.

p_value_for_two_variations(experiment_name, var_name_a, var_name_b)

Calculate a naive p-value for the difference in conversion rates among variations. For multi-variate, we might do pairwise comparisons or a more advanced approach (ANOVA, etc.). Here is a simple demonstration using a 2-proportion z-test for a pair of variations. For multiple variations, you could do them pairwise.

record_multiple_successes(experiment_names, record_fn)

Records successes for multiple experiments with consistent error handling. Returns either:

  • {:ok, %{experiment_name => {:ok, trial}}} if all successful
  • {:error, %{successful: [...], failed: [...]}} if any failed

record_session_successes(session_id, experiment_names, opts \\ [])

Records successes for session-based experiments.

record_success(trial, opts \\ [])

Records a success for a trial.

Options

  • :amount - Optional numeric value to track with the success (default: 0.0)
  • :success_type - Type of success to record, either :success1 or :success2 (default: :success1)

record_success_for_session(experiment_name, session_id, opts \\ [])

record_success_for_user(experiment_name, user_id, opts \\ [])

Records a success for a trial.

record_user_successes(user_id, experiment_names, opts \\ [])

Records successes for user-based experiments.

set_session_trial_variation(session_id, experiment_name, variation_name)

Sets a specific variation for a session trial. Returns {:ok, trial} if successful, {:error, reason} otherwise.

unarchive_experiment(experiment_id)

Unarchives an experiment, clearing the winner variation.

update_experiment(experiment, attrs)

Updates an experiment with the given attributes.

Examples

iex> update_experiment(experiment, %{start_time: "2024-01-01", end_time: "2024-12-31"})
{:ok, %Experiment{}}

update_trial_variation(trial_id, variation_id)

Updates the variation for a specific trial.

update_variation_weights(experiment_name, variation_weights)

Allows updating variation weights for an experiment. Example:

update_variation_weights("exp_homepage", [
  {"Variation A", 1.0},
  {"Variation B", 2.0}
])

update_weight(variation, weight, changed_by \\ "system")

upsert_experiment_and_update_weights(experiment_name, description, variations, opts \\ [])

Creates or updates an experiment with variations.

Options

  • :update_weights - Whether to update existing variation weights (default: true)
  • :success1_label - Label for success1 metric
  • :success2_label - Label for success2 metric
  • :archived - Set to true to archive the experiment (only updates if explicitly provided)
  • :winner - Winner variation name (string) - only used when archived: true