<commit_before><?php

namespace Vimeo\ABLincoln\Experiments;

use \Vimeo\ABLincoln\Assignment;

/*
 * Abstract base class for experiments
 */
abstract class AbstractExperiment
{
    protected $name;
    protected $salt = null;

    protected $inputs;
    protected $logger_configured = false;
    protected $in_experiment = true;

    private $exposure_logged = false;
    private $auto_exposure_log = true;
    private $assigned = false;
    private $assignment;

    /**
     * Set up attributes needed for experiment
     *
     * @param mixed $inputs input value or array to determine parameter assignments, e.g. userid
     */
    public function __construct($inputs)
    {
        $this->inputs = $inputs;         // input data
        $this->name = get_class($this);  // use class name as default name
        $this->setup();                  // manually set name, salt, etc.
        $this->salt = $this->salt();     // salt defaults to experiment name

        $this->assignment = $this->_getAssignment();
    }

    /*
     * Optionally set experiment attributes before run, e.g. name and salt
     */
    public function setup() {}

    /**
     * Checks if an assignment has been made, assigns one if not
     */
    private function _requiresAssignment()
    {
        if (!$this->assigned) {
            $this->_assignSetup();
        }
    }

    /**
     * Assignment and setup that happens when we need to log data
     */
    private function _assignSetup()
    {
        $this->_configureLogger();
        $this->assign($this->assignment, $this->inputs);
        $this->in_experiment = array_key_exists('in_experiment', $this->assignment->asArray()) ? $this->assignment['in_experiment'] : $this->in_experiment;
        $this->logged = $this->_previouslyLogged();
    }

    /**
     * Get a new assignment belonging to the current experiment
     *
     * @return Assignment the current experiment's assignment
     */
    private function _getAssignment()
    {
        return new Assignment($this->salt);
    }

    /**
     * Add parameters used in experiment to current assignment
     *
     * @param Assignment $params assignment in which to place new parameters
     * @param array $inputs input data to determine parameter assignments
     */
    abstract public function assign($params, $inputs);

    /**
     * Experiment-level salt accessor
     *
     * @return string the experiment-level salt
     */
    public function salt()
    {
        return isset($this->salt) ? $this->salt : $this->name;
    }

    /**
     * Experiment-level salt setter
     *
     * @param string $value value to set the experiment-level salt
     */
    public function setSalt($value)
    {
        $this->salt = $value;
    }

    /**
     * Experiment name accessor
     *
     * @return string the experiment name
     */
    public function name()
    {
        return $this->name;
    }

    /**
     * Experiment name setter
     *
     * @param string $value value to set the experiment name
     */
    public function setName($value)
    {
        $this->name = preg_replace('/\s+/', '-', $value);
    }

    /**
     * In-experiment accessor
     *
     * @return boolean true if currently in experiment, false otherwise
     */
    public function inExperiment()
    {
        return $this->in_experiment;
    }

    /**
     * In-experiment setter
     *
     * @param boolean $value true if currently in experiment, false otherwise
     */
    public function setInExperiment($value)
    {
        $this->in_experiment = $value;
    }

    /**
     * See whether the experiment has already been exposure logged
     *
     * @return boolean true if exposure logged, false otherwise
     */
    public function exposureLogged()
    {
        return $this->exposure_logged;
    }

    /**
     * Set whether the experiment has been exposure logged
     *
     * @param boolean $value true if exposure logged, false otherwise
     */
    public function setExposureLogged($value)
    {
        $this->exposure_logged = value;
    }

    /**
     * Disables / enables auto exposure logging (enabled by default)
     *
     * @param boolean $value true to enable, false to disable
     */
    public function setAutoExposureLogging($value)
    {
        $this->auto_exposure_log = $value;
    }

    /**
     * Get an array representation of the experiment data
     *
     * @param array $extras extra data to include in array
     * @return array experiment data
     */
    protected function _asBlob($extras = array())
    {
        $this->_requiresAssignment();
        $ret = array(
            'name' => $this->name,
            'time' => time(),
            'salt' => $this->salt,
            'inputs' => $this->inputs,
            'params' => $this->assignment->asArray()
        );
        return array_merge($ret, $extras);
    }

    /**
     * Get all experiment parameters - triggers exposure log. In general, this
     * should only be used by custom loggers
     *
     * @return array experiment parameters<commit_msg>mute time warnings - assumes that time config has been set up in php.ini<commit_after><?php

namespace Vimeo\ABLincoln\Experiments;

use \Vimeo\ABLincoln\Assignment;

/*
 * Abstract base class for experiments
 */
abstract class AbstractExperiment
{
    protected $name;
    protected $salt = null;

    protected $inputs;
    protected $logger_configured = false;
    protected $in_experiment = true;

    private $exposure_logged = false;
    private $auto_exposure_log = true;
    private $assigned = false;
    private $assignment;

    /**
     * Set up attributes needed for experiment
     *
     * @param mixed $inputs input value or array to determine parameter assignments, e.g. userid
     */
    public function __construct($inputs)
    {
        $this->inputs = $inputs;         // input data
        $this->name = get_class($this);  // use class name as default name
        $this->setup();                  // manually set name, salt, etc.
        $this->salt = $this->salt();     // salt defaults to experiment name

        $this->assignment = $this->_getAssignment();
    }

    /*
     * Optionally set experiment attributes before run, e.g. name and salt
     */
    public function setup() {}

    /**
     * Checks if an assignment has been made, assigns one if not
     */
    private function _requiresAssignment()
    {
        if (!$this->assigned) {
            $this->_assignSetup();
        }
    }

    /**
     * Assignment and setup that happens when we need to log data
     */
    private function _assignSetup()
    {
        $this->_configureLogger();
        $this->assign($this->assignment, $this->inputs);
        $this->in_experiment = array_key_exists('in_experiment', $this->assignment->asArray()) ? $this->assignment['in_experiment'] : $this->in_experiment;
        $this->logged = $this->_previouslyLogged();
    }

    /**
     * Get a new assignment belonging to the current experiment
     *
     * @return Assignment the current experiment's assignment
     */
    private function _getAssignment()
    {
        return new Assignment($this->salt);
    }

    /**
     * Add parameters used in experiment to current assignment
     *
     * @param Assignment $params assignment in which to place new parameters
     * @param array $inputs input data to determine parameter assignments
     */
    abstract public function assign($params, $inputs);

    /**
     * Experiment-level salt accessor
     *
     * @return string the experiment-level salt
     */
    public function salt()
    {
        return isset($this->salt) ? $this->salt : $this->name;
    }

    /**
     * Experiment-level salt setter
     *
     * @param string $value value to set the experiment-level salt
     */
    public function setSalt($value)
    {
        $this->salt = $value;
    }

    /**
     * Experiment name accessor
     *
     * @return string the experiment name
     */
    public function name()
    {
        return $this->name;
    }

    /**
     * Experiment name setter
     *
     * @param string $value value to set the experiment name
     */
    public function setName($value)
    {
        $this->name = preg_replace('/\s+/', '-', $value);
    }

    /**
     * In-experiment accessor
     *
     * @return boolean true if currently in experiment, false otherwise
     */
    public function inExperiment()
    {
        return $this->in_experiment;
    }

    /**
     * In-experiment setter
     *
     * @param boolean $value true if currently in experiment, false otherwise
     */
    public function setInExperiment($value)
    {
        $this->in_experiment = $value;
    }

    /**
     * See whether the experiment has already been exposure logged
     *
     * @return boolean true if exposure logged, false otherwise
     */
    public function exposureLogged()
    {
        return $this->exposure_logged;
    }

    /**
     * Set whether the experiment has been exposure logged
     *
     * @param boolean $value true if exposure logged, false otherwise
     */
    public function setExposureLogged($value)
    {
        $this->exposure_logged = value;
    }

    /**
     * Disables / enables auto exposure logging (enabled by default)
     *
     * @param boolean $value true to enable, false to disable
     */
    public function setAutoExposureLogging($value)
    {
        $this->auto_exposure_log = $value;
    }

    /**
     * Get an array representation of the experiment data
     *
     * @param array $extras extra data to include in array
     * @return array experiment data
     */
    protected function _asBlob($extras = array())
    {
        $this->_requiresAssignment();
        $ret = array(
            'name' => $this->name,
            'time' => @time(),
            'salt' => $this->salt,
            'inputs' => $this->inputs,
            'params' => $this->assignment->asArray()
        );
        return array_merge($ret, $extras);
    }

    /**
     * Get all experiment parameters - triggers exposure log. In general, this
     * should only be used by custom loggers
     *
     * @return array experiment parameters
{'fraction_non_alphanumeric': 0.10919992136819344, 'fraction_numerical': 0.0, 'mean_word_length': 2.1658369632856256, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '823232', 'n_tokens_mistral': 2827, 'n_tokens_neox': 2735, 'n_words': 845}