{
    "file_diffs": [
        {
            "old_file_content": "import math\n\nfrom AnyQt.QtWidgets import QFormLayout\nfrom AnyQt.QtCore import Qt\n\nimport numpy as np\nimport sklearn.model_selection as skl\n\nfrom Orange.widgets import gui\nfrom Orange.widgets.settings import Setting\nfrom Orange.data import Table\nfrom Orange.data.sql.table import SqlTable\nfrom Orange.widgets.utils.widgetpreview import WidgetPreview\nfrom Orange.widgets.widget import Msg, OWWidget, Input, Output\nfrom Orange.util import Reprable\n\n\nclass OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)\n\n\nclass SampleFoldIndices(Reprable):\n    def __init__(self, folds=10, stratified=False, random_state=None):\n        \"\"\"Samples data based on a number of folds.\n\n        Args:\n            folds (int): Number of folds\n            stratified (bool): Return stratified indices (if applicable).\n            random_state (Random): An initial state for replicable random\n            behavior\n\n        Returns:\n            tuple-of-arrays: A tuple of array indices one for each fold.\n\n        \"\"\"\n        self.folds = folds\n        self.stratified = stratified\n        self.random_state = random_state\n\n    def __call__(self, table):\n        if self.stratified and table.domain.has_discrete_class:\n            splitter = skl.StratifiedKFold(\n                self.folds, random_state=self.random_state)\n            splitter.get_n_splits(table.X, table.Y)\n            ind = splitter.split(table.X, table.Y)\n        else:\n            splitter = skl.KFold(\n                self.folds, random_state=self.random_state)\n            splitter.get_n_splits(table)\n            ind = splitter.split(table)\n        return tuple(ind)\n\n\nclass SampleRandomN(Reprable):\n    def __init__(self, n=0, stratified=False, replace=False,\n                 random_state=None):\n        self.n = n\n        self.stratified = stratified\n        self.replace = replace\n        self.random_state = random_state\n\n    def __call__(self, table):\n        if self.replace:\n            # pylint: disable=no-member\n            rgen = np.random.RandomState(self.random_state)\n            sample = rgen.randint(0, len(table), self.n)\n            o = np.ones(len(table))\n            o[sample] = 0\n            others = np.nonzero(o)[0]\n            return others, sample\n        if self.n == len(table):\n            rgen = np.random.RandomState(self.random_state)\n            sample = np.arange(self.n)\n            rgen.shuffle(sample)\n            return np.array([], dtype=int), sample\n        elif self.stratified and table.domain.has_discrete_class:\n            test_size = max(len(table.domain.class_var.values), self.n)\n            splitter = skl.StratifiedShuffleSplit(\n                n_splits=1, test_size=test_size,\n                train_size=len(table) - test_size,\n                random_state=self.random_state)\n            splitter.get_n_splits(table.X, table.Y)\n            ind = splitter.split(table.X, table.Y)\n        else:\n            splitter = skl.ShuffleSplit(\n                n_splits=1, test_size=self.n, random_state=self.random_state)\n            splitter.get_n_splits(table)\n            ind = splitter.split(table)\n        return next(iter(ind))\n\n\nclass SampleRandomP(Reprable):\n    def __init__(self, p=0, stratified=False, random_state=None):\n        self.p = p\n        self.stratified = stratified\n        self.random_state = random_state\n\n    def __call__(self, table):\n        n = int(math.ceil(len(table) * self.p))\n        return SampleRandomN(n, self.stratified,\n                             random_state=self.random_state)(table)\n\n\nclass SampleBootstrap(Reprable):\n    def __init__(self, size=0, random_state=None):\n        self.size = size\n        self.random_state = random_state\n\n    def __call__(self, table=None):\n        \"\"\"Bootstrap indices\n\n        Args:\n            table: Not used (but part of the signature)\n        Returns:\n            tuple (out_of_sample, sample) indices\n        \"\"\"\n        # pylint: disable=no-member\n        rgen = np.random.RandomState(self.random_state)\n        sample = rgen.randint(0, self.size, self.size)\n        sample.sort()  # not needed for the code below, just for the user\n        insample = np.ones((self.size,), dtype=np.bool)\n        insample[sample] = False\n        remaining = np.flatnonzero(insample)\n        return remaining, sample\n\n\nif __name__ == \"__main__\":  # pragma: no cover\n    WidgetPreview(OWDataSampler).run(Table(\"iris\"))\n",
            "new_file_content": "import math\n\nfrom AnyQt.QtWidgets import QFormLayout\nfrom AnyQt.QtCore import Qt\n\nimport numpy as np\nimport sklearn.model_selection as skl\n\nfrom Orange.widgets import gui\nfrom Orange.widgets.settings import Setting\nfrom Orange.data import Table\nfrom Orange.data.sql.table import SqlTable\nfrom Orange.widgets.utils.widgetpreview import WidgetPreview\nfrom Orange.widgets.widget import Msg, OWWidget, Input, Output\nfrom Orange.util import Reprable\n\n\nclass OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        self.info.set_input_summary(self.info.NoInput)\n        self.info.set_output_summary(self.info.NoInput)\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.info.set_input_summary(str(len(dataset)))\n\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.info.set_input_summary(self.info.NoInput)\n            self.info.set_output_summary(self.info.NoInput)\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n            self.info.set_output_summary(str(len(sample)))\n\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)\n\n\nclass SampleFoldIndices(Reprable):\n    def __init__(self, folds=10, stratified=False, random_state=None):\n        \"\"\"Samples data based on a number of folds.\n\n        Args:\n            folds (int): Number of folds\n            stratified (bool): Return stratified indices (if applicable).\n            random_state (Random): An initial state for replicable random\n            behavior\n\n        Returns:\n            tuple-of-arrays: A tuple of array indices one for each fold.\n\n        \"\"\"\n        self.folds = folds\n        self.stratified = stratified\n        self.random_state = random_state\n\n    def __call__(self, table):\n        if self.stratified and table.domain.has_discrete_class:\n            splitter = skl.StratifiedKFold(\n                self.folds, random_state=self.random_state)\n            splitter.get_n_splits(table.X, table.Y)\n            ind = splitter.split(table.X, table.Y)\n        else:\n            splitter = skl.KFold(\n                self.folds, random_state=self.random_state)\n            splitter.get_n_splits(table)\n            ind = splitter.split(table)\n        return tuple(ind)\n\n\nclass SampleRandomN(Reprable):\n    def __init__(self, n=0, stratified=False, replace=False,\n                 random_state=None):\n        self.n = n\n        self.stratified = stratified\n        self.replace = replace\n        self.random_state = random_state\n\n    def __call__(self, table):\n        if self.replace:\n            # pylint: disable=no-member\n            rgen = np.random.RandomState(self.random_state)\n            sample = rgen.randint(0, len(table), self.n)\n            o = np.ones(len(table))\n            o[sample] = 0\n            others = np.nonzero(o)[0]\n            return others, sample\n        if self.n == len(table):\n            rgen = np.random.RandomState(self.random_state)\n            sample = np.arange(self.n)\n            rgen.shuffle(sample)\n            return np.array([], dtype=int), sample\n        elif self.stratified and table.domain.has_discrete_class:\n            test_size = max(len(table.domain.class_var.values), self.n)\n            splitter = skl.StratifiedShuffleSplit(\n                n_splits=1, test_size=test_size,\n                train_size=len(table) - test_size,\n                random_state=self.random_state)\n            splitter.get_n_splits(table.X, table.Y)\n            ind = splitter.split(table.X, table.Y)\n        else:\n            splitter = skl.ShuffleSplit(\n                n_splits=1, test_size=self.n, random_state=self.random_state)\n            splitter.get_n_splits(table)\n            ind = splitter.split(table)\n        return next(iter(ind))\n\n\nclass SampleRandomP(Reprable):\n    def __init__(self, p=0, stratified=False, random_state=None):\n        self.p = p\n        self.stratified = stratified\n        self.random_state = random_state\n\n    def __call__(self, table):\n        n = int(math.ceil(len(table) * self.p))\n        return SampleRandomN(n, self.stratified,\n                             random_state=self.random_state)(table)\n\n\nclass SampleBootstrap(Reprable):\n    def __init__(self, size=0, random_state=None):\n        self.size = size\n        self.random_state = random_state\n\n    def __call__(self, table=None):\n        \"\"\"Bootstrap indices\n\n        Args:\n            table: Not used (but part of the signature)\n        Returns:\n            tuple (out_of_sample, sample) indices\n        \"\"\"\n        # pylint: disable=no-member\n        rgen = np.random.RandomState(self.random_state)\n        sample = rgen.randint(0, self.size, self.size)\n        sample.sort()  # not needed for the code below, just for the user\n        insample = np.ones((self.size,), dtype=np.bool)\n        insample[sample] = False\n        remaining = np.flatnonzero(insample)\n        return remaining, sample\n\n\nif __name__ == \"__main__\":  # pragma: no cover\n    WidgetPreview(OWDataSampler).run(Table(\"iris\"))\n",
            "header": {
                "file": {
                    "path": "Orange/widgets/data/owdatasampler.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "cda524f64",
                "new_commit_hash": "74174d541",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/Orange/widgets/data/owdatasampler.py"
            },
            "plus_file": {
                "path": "b/Orange/widgets/data/owdatasampler.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 70,
                            "length": 9
                        },
                        "new_range": {
                            "start": 70,
                            "length": 8
                        },
                        "section": "class OWDataSampler(OWWidget):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        self.indices = None",
                                "type": "context"
                            },
                            {
                                "content": "        self.sampled_instances = self.remaining_instances = None",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        box = gui.vBox(self.controlArea, \"Information\")",
                                "type": "deleted"
                            },
                            {
                                "content": "        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')",
                                "type": "deleted"
                            },
                            {
                                "content": "        self.outputInfoLabel = gui.widgetLabel(box, ' ')",
                                "type": "deleted"
                            },
                            {
                                "content": "        self.info.set_input_summary(self.info.NoInput)",
                                "type": "added"
                            },
                            {
                                "content": "        self.info.set_output_summary(self.info.NoInput)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")",
                                "type": "context"
                            },
                            {
                                "content": "        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "Orange/widgets/data/owdatasampler.py",
                            "type": "method",
                            "name": "OWDataSampler.__init__",
                            "content": "class OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 67,
                            "end_lineno": 155,
                            "parent": {
                                "file_name": "Orange/widgets/data/owdatasampler.py",
                                "type": "class",
                                "name": "OWDataSampler",
                                "content": "class OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 18,
                                "end_lineno": 337,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "Orange/widgets/data/owdatasampler.py",
                            "type": "class",
                            "name": "OWDataSampler",
                            "content": "class OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 18,
                            "end_lineno": 337,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 180,
                            "length": 16
                        },
                        "new_range": {
                            "start": 179,
                            "length": 14
                        },
                        "section": "class OWDataSampler(OWWidget):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            self.cb_seed.setVisible(not sql)",
                                "type": "context"
                            },
                            {
                                "content": "            self.cb_stratify.setVisible(not sql)",
                                "type": "context"
                            },
                            {
                                "content": "            self.cb_sql_dl.setVisible(sql)",
                                "type": "context"
                            },
                            {
                                "content": "            self.dataInfoLabel.setText(",
                                "type": "deleted"
                            },
                            {
                                "content": "                '{}{} instances in input dataset.'.format(*(",
                                "type": "deleted"
                            },
                            {
                                "content": "                    ('~', dataset.approx_len()) if sql else",
                                "type": "deleted"
                            },
                            {
                                "content": "                    ('', len(dataset)))))",
                                "type": "deleted"
                            },
                            {
                                "content": "            self.info.set_input_summary(str(len(dataset)))",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "            if not sql:",
                                "type": "context"
                            },
                            {
                                "content": "                self._update_sample_max_size()",
                                "type": "context"
                            },
                            {
                                "content": "                self.updateindices()",
                                "type": "context"
                            },
                            {
                                "content": "        else:",
                                "type": "context"
                            },
                            {
                                "content": "            self.dataInfoLabel.setText('No data on input.')",
                                "type": "deleted"
                            },
                            {
                                "content": "            self.outputInfoLabel.setText('')",
                                "type": "deleted"
                            },
                            {
                                "content": "            self.info.set_input_summary(self.info.NoInput)",
                                "type": "added"
                            },
                            {
                                "content": "            self.info.set_output_summary(self.info.NoInput)",
                                "type": "added"
                            },
                            {
                                "content": "            self.indices = None",
                                "type": "context"
                            },
                            {
                                "content": "            self.clear_messages()",
                                "type": "context"
                            },
                            {
                                "content": "        self.commit()",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "Orange/widgets/data/owdatasampler.py",
                            "type": "class",
                            "name": "OWDataSampler",
                            "content": "class OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 18,
                            "end_lineno": 337,
                            "parent": null
                        },
                        {
                            "file_name": "Orange/widgets/data/owdatasampler.py",
                            "type": "method",
                            "name": "OWDataSampler.set_data",
                            "content": "class OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 174,
                            "end_lineno": 195,
                            "parent": {
                                "file_name": "Orange/widgets/data/owdatasampler.py",
                                "type": "class",
                                "name": "OWDataSampler",
                                "content": "class OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 18,
                                "end_lineno": 337,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 205,
                            "length": 7
                        },
                        "new_range": {
                            "start": 202,
                            "length": 6
                        },
                        "section": "class OWDataSampler(OWWidget):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        if self.data is None:",
                                "type": "context"
                            },
                            {
                                "content": "            sample = other = None",
                                "type": "context"
                            },
                            {
                                "content": "            self.sampled_instances = self.remaining_instances = None",
                                "type": "context"
                            },
                            {
                                "content": "            self.outputInfoLabel.setText(\"\")",
                                "type": "deleted"
                            },
                            {
                                "content": "        elif isinstance(self.data, SqlTable):",
                                "type": "context"
                            },
                            {
                                "content": "            other = None",
                                "type": "context"
                            },
                            {
                                "content": "            if self.sampling_type == self.SqlProportion:",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "Orange/widgets/data/owdatasampler.py",
                            "type": "class",
                            "name": "OWDataSampler",
                            "content": "class OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 18,
                            "end_lineno": 337,
                            "parent": null
                        },
                        {
                            "file_name": "Orange/widgets/data/owdatasampler.py",
                            "type": "method",
                            "name": "OWDataSampler.commit",
                            "content": "class OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 204,
                            "end_lineno": 243,
                            "parent": {
                                "file_name": "Orange/widgets/data/owdatasampler.py",
                                "type": "class",
                                "name": "OWDataSampler",
                                "content": "class OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 18,
                                "end_lineno": 337,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 226,
                            "length": 15
                        },
                        "new_range": {
                            "start": 222,
                            "length": 10
                        },
                        "section": "class OWDataSampler(OWWidget):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            if self.sampling_type in (",
                                "type": "context"
                            },
                            {
                                "content": "                    self.FixedProportion, self.FixedSize, self.Bootstrap):",
                                "type": "context"
                            },
                            {
                                "content": "                remaining, sample = self.indices",
                                "type": "context"
                            },
                            {
                                "content": "                self.outputInfoLabel.setText(",
                                "type": "deleted"
                            },
                            {
                                "content": "                    'Outputting %d instance%s.' %",
                                "type": "deleted"
                            },
                            {
                                "content": "                    (len(sample), \"s\" * (len(sample) != 1)))",
                                "type": "deleted"
                            },
                            {
                                "content": "            elif self.sampling_type == self.CrossValidation:",
                                "type": "context"
                            },
                            {
                                "content": "                remaining, sample = self.indices[self.selectedFold - 1]",
                                "type": "context"
                            },
                            {
                                "content": "                self.outputInfoLabel.setText(",
                                "type": "deleted"
                            },
                            {
                                "content": "                    'Outputting fold %d, %d instance%s.' %",
                                "type": "deleted"
                            },
                            {
                                "content": "                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))",
                                "type": "deleted"
                            },
                            {
                                "content": "                )",
                                "type": "deleted"
                            },
                            {
                                "content": "            self.info.set_output_summary(str(len(sample)))",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "            sample = self.data[sample]",
                                "type": "context"
                            },
                            {
                                "content": "            other = self.data[remaining]",
                                "type": "context"
                            },
                            {
                                "content": "            self.sampled_instances = len(sample)",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "Orange/widgets/data/owdatasampler.py",
                            "type": "class",
                            "name": "OWDataSampler",
                            "content": "class OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 18,
                            "end_lineno": 337,
                            "parent": null
                        },
                        {
                            "file_name": "Orange/widgets/data/owdatasampler.py",
                            "type": "method",
                            "name": "OWDataSampler.commit",
                            "content": "class OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 204,
                            "end_lineno": 243,
                            "parent": {
                                "file_name": "Orange/widgets/data/owdatasampler.py",
                                "type": "class",
                                "name": "OWDataSampler",
                                "content": "class OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 18,
                                "end_lineno": 337,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "# Test methods with long descriptive names can omit docstrings\n# pylint: disable=missing-docstring\nfrom Orange.data import Table\nfrom Orange.widgets.data.owdatasampler import OWDataSampler\nfrom Orange.widgets.tests.base import WidgetTest\n\n\nclass TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data \"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))\n",
            "new_file_content": "# Test methods with long descriptive names can omit docstrings\n# pylint: disable=missing-docstring,unsubscriptable-object\nfrom unittest.mock import Mock\n\nfrom Orange.data import Table\nfrom Orange.widgets.data.owdatasampler import OWDataSampler\nfrom Orange.widgets.tests.base import WidgetTest\n\n\nclass TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))\n",
            "header": {
                "file": {
                    "path": "Orange/widgets/data/tests/test_owdatasampler.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "ffb650bcb",
                "new_commit_hash": "28fbe220c",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/Orange/widgets/data/tests/test_owdatasampler.py"
            },
            "plus_file": {
                "path": "b/Orange/widgets/data/tests/test_owdatasampler.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 1,
                            "length": 5
                        },
                        "new_range": {
                            "start": 1,
                            "length": 7
                        },
                        "section": ""
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "# Test methods with long descriptive names can omit docstrings",
                                "type": "context"
                            },
                            {
                                "content": "# pylint: disable=missing-docstring",
                                "type": "deleted"
                            },
                            {
                                "content": "# pylint: disable=missing-docstring,unsubscriptable-object",
                                "type": "added"
                            },
                            {
                                "content": "from unittest.mock import Mock",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "from Orange.data import Table",
                                "type": "context"
                            },
                            {
                                "content": "from Orange.widgets.data.owdatasampler import OWDataSampler",
                                "type": "context"
                            },
                            {
                                "content": "from Orange.widgets.tests.base import WidgetTest",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [
                        {
                            "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                            "type": "statement",
                            "name": "",
                            "content": "from unittest.mock import Mock",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 3,
                            "end_lineno": 3,
                            "parent": null
                        }
                    ],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 36,
                            "length": 6
                        },
                        "new_range": {
                            "start": 38,
                            "length": 7
                        },
                        "section": "class TestOWDataSampler(WidgetTest):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_bootstrap(self):",
                                "type": "context"
                            },
                            {
                                "content": "        output_sum = self.widget.info.set_output_summary = Mock()",
                                "type": "added"
                            },
                            {
                                "content": "        self.select_sampling_type(self.widget.Bootstrap)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        self.send_signal(\"Data\", self.iris)",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                            "type": "method",
                            "name": "TestOWDataSampler.test_bootstrap",
                            "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 40,
                            "end_lineno": 63,
                            "parent": {
                                "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                                "type": "class",
                                "name": "TestOWDataSampler",
                                "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 10,
                                "end_lineno": 155,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                            "type": "class",
                            "name": "TestOWDataSampler",
                            "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 10,
                            "end_lineno": 155,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 56,
                            "length": 6
                        },
                        "new_range": {
                            "start": 59,
                            "length": 8
                        },
                        "section": "class TestOWDataSampler(WidgetTest):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertGreater(len(in_sample), 0)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertGreater(len(in_remaining), 0)",
                                "type": "context"
                            },
                            {
                                "content": "        #Check if status bar shows correct number of output data",
                                "type": "added"
                            },
                            {
                                "content": "        output_sum.assert_called_with(str(len(sample)))",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def select_sampling_type(self, sampling_type):",
                                "type": "context"
                            },
                            {
                                "content": "        buttons = self.widget.controls.sampling_type.group.buttons()",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                            "type": "method",
                            "name": "TestOWDataSampler.test_bootstrap",
                            "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 40,
                            "end_lineno": 63,
                            "parent": {
                                "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                                "type": "class",
                                "name": "TestOWDataSampler",
                                "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 10,
                                "end_lineno": 155,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                            "type": "class",
                            "name": "TestOWDataSampler",
                            "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 10,
                            "end_lineno": 155,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 63,
                            "length": 9
                        },
                        "new_range": {
                            "start": 68,
                            "length": 11
                        },
                        "section": "class TestOWDataSampler(WidgetTest):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_no_intersection_in_outputs(self):",
                                "type": "context"
                            },
                            {
                                "content": "        \"\"\" Check whether outputs intersect and whether length of outputs sums",
                                "type": "context"
                            },
                            {
                                "content": "        to length of original data \"\"\"",
                                "type": "deleted"
                            },
                            {
                                "content": "        to length of original data and",
                                "type": "added"
                            },
                            {
                                "content": "        if status bar displays correct output for each sampling type\"\"\"",
                                "type": "added"
                            },
                            {
                                "content": "        self.send_signal(\"Data\", self.iris)",
                                "type": "context"
                            },
                            {
                                "content": "        w = self.widget",
                                "type": "context"
                            },
                            {
                                "content": "        output_sum = self.widget.info.set_output_summary = Mock()",
                                "type": "added"
                            },
                            {
                                "content": "        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        for replicable in [True, False]:",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                            "type": "class",
                            "name": "TestOWDataSampler",
                            "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data \"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 133,
                            "parent": null
                        },
                        {
                            "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                            "type": "method",
                            "name": "TestOWDataSampler.test_no_intersection_in_outputs",
                            "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data \"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 64,
                            "end_lineno": 82,
                            "parent": {
                                "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                                "type": "class",
                                "name": "TestOWDataSampler",
                                "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data \"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 133,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 80,
                            "length": 6
                        },
                        "new_range": {
                            "start": 87,
                            "length": 7
                        },
                        "section": "class TestOWDataSampler(WidgetTest):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "                    other = self.get_output(\"Remaining Data\")",
                                "type": "context"
                            },
                            {
                                "content": "                    self.assertEqual(len(self.iris), len(sample) + len(other))",
                                "type": "context"
                            },
                            {
                                "content": "                    self.assertNoIntersection(sample, other)",
                                "type": "context"
                            },
                            {
                                "content": "                    output_sum.assert_called_with(str(len(sample)))",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_bigger_size_with_replacement(self):",
                                "type": "context"
                            },
                            {
                                "content": "        \"\"\"Allow bigger output without replacement.\"\"\"",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                            "type": "class",
                            "name": "TestOWDataSampler",
                            "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 10,
                            "end_lineno": 155,
                            "parent": null
                        },
                        {
                            "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                            "type": "method",
                            "name": "TestOWDataSampler.test_no_intersection_in_outputs",
                            "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 69,
                            "end_lineno": 90,
                            "parent": {
                                "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                                "type": "class",
                                "name": "TestOWDataSampler",
                                "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 10,
                                "end_lineno": 155,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 116,
                            "length": 6
                        },
                        "new_range": {
                            "start": 124,
                            "length": 20
                        },
                        "section": "class TestOWDataSampler(WidgetTest):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        self.assertTrue((self.iris.ids != sample.ids).any())",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(set(self.iris.ids), set(sample.ids))",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_summary(self):",
                                "type": "added"
                            },
                            {
                                "content": "        \"\"\"Check if status bar is updated when data is received\"\"\"",
                                "type": "added"
                            },
                            {
                                "content": "        input_sum = self.widget.info.set_input_summary = Mock()",
                                "type": "added"
                            },
                            {
                                "content": "        data = self.iris",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        input_sum.reset_mock()",
                                "type": "added"
                            },
                            {
                                "content": "        self.send_signal(self.widget.Inputs.data, data[:])",
                                "type": "added"
                            },
                            {
                                "content": "        input_sum.assert_called_with(\"150\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        input_sum.reset_mock()",
                                "type": "added"
                            },
                            {
                                "content": "        self.send_signal(self.widget.Inputs.data, None)",
                                "type": "added"
                            },
                            {
                                "content": "        input_sum.assert_called_once()",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(input_sum.call_args[0][0].brief, \"\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    def set_fixed_sample_size(self, sample_size, with_replacement=False):",
                                "type": "context"
                            },
                            {
                                "content": "        \"\"\"Set fixed sample size and return the number of gui spin.",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                            "type": "class",
                            "name": "TestOWDataSampler",
                            "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 10,
                            "end_lineno": 155,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                            "type": "method",
                            "name": "TestOWDataSampler.test_summary",
                            "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 127,
                            "end_lineno": 139,
                            "parent": {
                                "file_name": "Orange/widgets/data/tests/test_owdatasampler.py",
                                "type": "class",
                                "name": "TestOWDataSampler",
                                "content": "class TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 10,
                                "end_lineno": 155,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "05c8ae088d8eb1c68d70422341464e822d9428cf^",
    "new_commit_hash": "05c8ae088d8eb1c68d70422341464e822d9428cf",
    "commit_message": "Merge pull request #4165 from aturanjanin/data_sampler\n\nDataSampler: data info displayed in status bar",
    "commit_date": "2019-11-11T06:38:22+01:00",
    "metadata": {}
}
{
    "repo_name": "orange3",
    "new_commit_hash": "05c8ae088d8eb1c68d70422341464e822d9428cf",
    "test_file_codes": [
        "# Test methods with long descriptive names can omit docstrings\n# pylint: disable=missing-docstring,unsubscriptable-object\nfrom unittest.mock import Mock\n\nfrom Orange.data import Table\nfrom Orange.widgets.data.owdatasampler import OWDataSampler\nfrom Orange.widgets.tests.base import WidgetTest\n\n\nclass TestOWDataSampler(WidgetTest):\n    @classmethod\n    def setUpClass(cls):\n        super().setUpClass()\n        cls.iris = Table(\"iris\")\n        cls.zoo = Table(\"zoo\")\n\n    def setUp(self):\n        self.widget = self.create_widget(OWDataSampler)  # type: OWDataSampler\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n        self.send_signal(\"Data\", self.iris)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", self.iris[:5])\n        self.assertTrue(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", None)\n        self.assertFalse(self.widget.Error.too_many_folds.is_shown())\n        self.send_signal(\"Data\", Table(self.iris.domain))\n        self.assertTrue(self.widget.Error.no_data.is_shown())\n\n    def test_stratified_on_unbalanced_data(self):\n        unbalanced_data = self.iris[:51]\n\n        self.widget.controls.stratify.setChecked(True)\n        self.send_signal(\"Data\", unbalanced_data)\n        self.assertTrue(self.widget.Warning.could_not_stratify.is_shown())\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n\n        self.send_signal(\"Data\", self.iris)\n\n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n\n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n        output_sum.assert_called_with(str(len(sample)))\n\n    def select_sampling_type(self, sampling_type):\n        buttons = self.widget.controls.sampling_type.group.buttons()\n        buttons[sampling_type].click()\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n\n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n\n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n                    output_sum.assert_called_with(str(len(sample)))\n\n    def test_bigger_size_with_replacement(self):\n        \"\"\"Allow bigger output without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertEqual(3, sample_size, 'Should be able to set a bigger size '\n                         'with replacement')\n\n    def test_bigger_size_without_replacement(self):\n        \"\"\"Lower output samples to match input's without replacement.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        sample_size = self.set_fixed_sample_size(3)\n        self.assertEqual(2, sample_size)\n\n    def test_bigger_output_warning(self):\n        \"\"\"Should warn when sample size is bigger than input.\"\"\"\n        self.send_signal('Data', self.iris[:2])\n        self.set_fixed_sample_size(3, with_replacement=True)\n        self.assertTrue(self.widget.Warning.bigger_sample.is_shown())\n\n    def test_shuffling(self):\n        self.send_signal('Data', self.iris)\n\n        self.set_fixed_sample_size(150)\n        self.assertFalse(self.widget.Warning.bigger_sample.is_shown())\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n        self.select_sampling_type(self.widget.FixedProportion)\n        self.widget.sampleSizePercentage = 100\n        self.widget.commit()\n        sample = self.get_output(\"Data Sample\")\n        self.assertTrue((self.iris.ids != sample.ids).any())\n        self.assertEqual(set(self.iris.ids), set(sample.ids))\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n        input_sum.assert_called_with(\"150\")\n\n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, None)\n        input_sum.assert_called_once()\n        self.assertEqual(input_sum.call_args[0][0].brief, \"\")\n\n    def set_fixed_sample_size(self, sample_size, with_replacement=False):\n        \"\"\"Set fixed sample size and return the number of gui spin.\n\n        Return the actual number in gui so we can check whether it is different\n        from sample_size. The number can be changed depending on the spin\n        maximum value.\n        \"\"\"\n        self.select_sampling_type(self.widget.FixedSize)\n        self.widget.controls.replacement.setChecked(with_replacement)\n        self.widget.sampleSizeSpin.setValue(sample_size)\n        self.widget.commit()\n        return self.widget.sampleSizeSpin.value()\n\n    def assertNoIntersection(self, sample, other):\n        self.assertFalse(bool(set(sample.ids) & set(other.ids)))\n"
    ],
    "test_file_names": [
        "test_1.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "Starting Orange installation attempts...\nAttempting installation with Python 3.7...\nrunning build_ext\nrunning build_src\nbuild_src\nbuilding extension \"Orange.classification._simple_tree\" sources\nbuilding extension \"Orange.classification._tree_scorers\" sources\nbuilding extension \"Orange.data._valuecount\" sources\nbuilding extension \"Orange.data._contingency\" sources\nbuilding extension \"Orange.data._io\" sources\nbuilding extension \"Orange.data._variable\" sources\nbuilding extension \"Orange.distance._distance\" sources\nbuilding extension \"Orange.preprocess._discretize\" sources\nbuilding extension \"Orange.preprocess._relieff\" sources\nbuilding extension \"Orange.projection._som\" sources\nbuilding extension \"Orange.widgets.utils._grid_density\" sources\nbuild_src: building npy-pkg config files\ncustomize UnixCCompiler\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncreating /tmp/tmpytoenb_q/tmp\ncreating /tmp/tmpytoenb_q/tmp/tmpytoenb_q\ncompile options: '-MMD -MF /tmp/tmpytoenb_q/file.c.d -c'\ncc: /tmp/tmpytoenb_q/file.c\ncustomize UnixCCompiler using build_ext\ncustomize UnixCCompiler\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncreating /tmp/tmprp0atzet/tmp\ncreating /tmp/tmprp0atzet/tmp/tmprp0atzet\ncompile options: '-MMD -MF /tmp/tmprp0atzet/file.c.d -c'\ncc: /tmp/tmprp0atzet/file.c\ncustomize UnixCCompiler using build_ext\nbuilding 'Orange.classification._simple_tree' extension\ncompiling C sources\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncreating build/temp.linux-x86_64-3.7/Orange\ncreating build/temp.linux-x86_64-3.7/Orange/classification\ncompile options: '-I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/include -I/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/include/python3.7m -c'\ncc: Orange/classification/_simple_tree.c\ncc -pthread -shared -L/tools/deps/lib build/temp.linux-x86_64-3.7/Orange/classification/_simple_tree.o -L/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib -lm -lpython3.7m -o Orange/classification/_simple_tree.cpython-37m-x86_64-linux-gnu.so\nbuilding 'Orange.classification._tree_scorers' extension\ncompiling C sources\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncompile options: '-I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/include -I/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/include/python3.7m -c'\ncc: Orange/classification/_tree_scorers.c\ncc -pthread -shared -L/tools/deps/lib build/temp.linux-x86_64-3.7/Orange/classification/_tree_scorers.o -L/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib -lm -lpython3.7m -o Orange/classification/_tree_scorers.cpython-37m-x86_64-linux-gnu.so\nbuilding 'Orange.data._valuecount' extension\ncompiling C sources\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncreating build/temp.linux-x86_64-3.7/Orange/data\ncompile options: '-I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/include -I/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/include/python3.7m -c'\ncc: Orange/data/_valuecount.c\ncc -pthread -shared -L/tools/deps/lib build/temp.linux-x86_64-3.7/Orange/data/_valuecount.o -L/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib -lm -lpython3.7m -o Orange/data/_valuecount.cpython-37m-x86_64-linux-gnu.so\nbuilding 'Orange.data._contingency' extension\ncompiling C sources\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncompile options: '-I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/include -I/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/include/python3.7m -c'\ncc: Orange/data/_contingency.c\ncc -pthread -shared -L/tools/deps/lib build/temp.linux-x86_64-3.7/Orange/data/_contingency.o -L/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib -lm -lpython3.7m -o Orange/data/_contingency.cpython-37m-x86_64-linux-gnu.so\nbuilding 'Orange.data._io' extension\ncompiling C sources\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncompile options: '-I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/include -I/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/include/python3.7m -c'\ncc: Orange/data/_io.c\ncc -pthread -shared -L/tools/deps/lib build/temp.linux-x86_64-3.7/Orange/data/_io.o -L/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib -lm -lpython3.7m -o Orange/data/_io.cpython-37m-x86_64-linux-gnu.so\nbuilding 'Orange.data._variable' extension\ncompiling C sources\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncompile options: '-I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/include -I/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/include/python3.7m -c'\ncc: Orange/data/_variable.c\ncc -pthread -shared -L/tools/deps/lib build/temp.linux-x86_64-3.7/Orange/data/_variable.o -L/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib -lm -lpython3.7m -o Orange/data/_variable.cpython-37m-x86_64-linux-gnu.so\nbuilding 'Orange.distance._distance' extension\ncompiling C sources\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncreating build/temp.linux-x86_64-3.7/Orange/distance\ncompile options: '-I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/include -I/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/include/python3.7m -c'\ncc: Orange/distance/_distance.c\ncc -pthread -shared -L/tools/deps/lib build/temp.linux-x86_64-3.7/Orange/distance/_distance.o -L/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib -lm -lpython3.7m -o Orange/distance/_distance.cpython-37m-x86_64-linux-gnu.so\nbuilding 'Orange.preprocess._discretize' extension\ncompiling C sources\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncreating build/temp.linux-x86_64-3.7/Orange/preprocess\ncompile options: '-I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/include -I/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/include/python3.7m -c'\ncc: Orange/preprocess/_discretize.c\ncc -pthread -shared -L/tools/deps/lib build/temp.linux-x86_64-3.7/Orange/preprocess/_discretize.o -L/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib -lm -lpython3.7m -o Orange/preprocess/_discretize.cpython-37m-x86_64-linux-gnu.so\nbuilding 'Orange.preprocess._relieff' extension\ncompiling C++ sources\nC compiler: c++ -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncompile options: '-I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/include -I/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/include/python3.7m -c'\nc++: Orange/preprocess/_relieff.cpp\nc++ -pthread -shared -L/tools/deps/lib build/temp.linux-x86_64-3.7/Orange/preprocess/_relieff.o -L/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib -lm -lpython3.7m -o Orange/preprocess/_relieff.cpython-37m-x86_64-linux-gnu.so\nbuilding 'Orange.projection._som' extension\ncompiling C sources\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncreating build/temp.linux-x86_64-3.7/Orange/projection\ncompile options: '-I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/include -I/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/include/python3.7m -c'\ncc: Orange/projection/_som.c\ncc -pthread -shared -L/tools/deps/lib build/temp.linux-x86_64-3.7/Orange/projection/_som.o -L/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib -lm -lpython3.7m -o Orange/projection/_som.cpython-37m-x86_64-linux-gnu.so\nbuilding 'Orange.widgets.utils._grid_density' extension\ncompiling C++ sources\nC compiler: c++ -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncreating build/temp.linux-x86_64-3.7/Orange/widgets\ncreating build/temp.linux-x86_64-3.7/Orange/widgets/utils\ncompile options: '-I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/include -I/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/include/python3.7m -c'\nc++: Orange/widgets/utils/_grid_density.cpp\nc++ -pthread -shared -L/tools/deps/lib build/temp.linux-x86_64-3.7/Orange/widgets/utils/_grid_density.o -L/home/gcpuser/.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib -lm -lpython3.7m -o Orange/widgets/utils/_grid_density.cpython-37m-x86_64-linux-gnu.so\nrunning develop\nrunning build_scripts\nrunning egg_info\nrunning build_src\nbuild_src\nbuilding extension \"Orange.classification._simple_tree\" sources\nbuilding extension \"Orange.classification._tree_scorers\" sources\nbuilding extension \"Orange.data._valuecount\" sources\nbuilding extension \"Orange.data._contingency\" sources\nbuilding extension \"Orange.data._io\" sources\nbuilding extension \"Orange.data._variable\" sources\nbuilding extension \"Orange.distance._distance\" sources\nbuilding extension \"Orange.preprocess._discretize\" sources\nbuilding extension \"Orange.preprocess._relieff\" sources\nbuilding extension \"Orange.projection._som\" sources\nbuilding extension \"Orange.widgets.utils._grid_density\" sources\nbuild_src: building npy-pkg config files\ncreating Orange3.egg-info\nwriting Orange3.egg-info/PKG-INFO\nwriting dependency_links to Orange3.egg-info/dependency_links.txt\nwriting entry points to Orange3.egg-info/entry_points.txt\nwriting requirements to Orange3.egg-info/requires.txt\nwriting top-level names to Orange3.egg-info/top_level.txt\nwriting manifest file 'Orange3.egg-info/SOURCES.txt'\nreading manifest file 'Orange3.egg-info/SOURCES.txt'\nreading manifest template 'MANIFEST.in'\nwarning: no files found matching 'README*' under directory 'Orange'\nwarning: no files found matching 'LICENSE' under directory 'Orange'\nwarning: no files found matching '*.basket' under directory 'Orange/datasets'\nwarning: no files found matching '*.js' under directory 'Orange/widgets'\nwarning: no files found matching '*.css' under directory 'Orange/widgets'\nwarning: no files found matching '*.html' under directory 'Orange/widgets'\nwarning: no files found matching 'COPYING'\nadding license file 'LICENSE'\nwriting manifest file 'Orange3.egg-info/SOURCES.txt'\nrunning build_ext\ncustomize UnixCCompiler\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncreating /tmp/tmpu_t7ogrs/tmp\ncreating /tmp/tmpu_t7ogrs/tmp/tmpu_t7ogrs\ncompile options: '-MMD -MF /tmp/tmpu_t7ogrs/file.c.d -c'\ncc: /tmp/tmpu_t7ogrs/file.c\ncustomize UnixCCompiler using build_ext\ncustomize UnixCCompiler\nC compiler: cc -pthread -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/tools/deps/include -I/tools/deps/include/ncursesw -fPIC\n\ncreating /tmp/tmp9zu90s3z/tmp\ncreating /tmp/tmp9zu90s3z/tmp/tmp9zu90s3z\ncompile options: '-MMD -MF /tmp/tmp9zu90s3z/file.c.d -c'\ncc: /tmp/tmp9zu90s3z/file.c\ncustomize UnixCCompiler using build_ext\nCreating /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/Orange3.egg-link (link to .)\nAdding Orange3 3.24.0.dev0+05c8ae0 to easy-install.pth file\nInstalling orange-canvas script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\n\nInstalled /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf\nProcessing dependencies for Orange3==3.24.0.dev0+05c8ae0\nSearching for XlsxWriter==3.2.0\nBest match: XlsxWriter 3.2.0\nAdding XlsxWriter 3.2.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for xlrd==2.0.1\nBest match: xlrd 2.0.1\nAdding xlrd 2.0.1 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for setuptools==59.8.0\nBest match: setuptools 59.8.0\nAdding setuptools 59.8.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for serverfiles==0.3.1\nBest match: serverfiles 0.3.1\nAdding serverfiles 0.3.1 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for scipy==1.7.3\nBest match: scipy 1.7.3\nAdding scipy 1.7.3 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for scikit-learn==1.0.2\nBest match: scikit-learn 1.0.2\nAdding scikit-learn 1.0.2 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for requests==2.31.0\nBest match: requests 2.31.0\nAdding requests 2.31.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for PyYAML==6.0.1\nBest match: PyYAML 6.0.1\nAdding PyYAML 6.0.1 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for python-louvain==0.16\nBest match: python-louvain 0.16\nAdding python-louvain 0.16 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for pyqtgraph==0.12.4\nBest match: pyqtgraph 0.12.4\nAdding pyqtgraph 0.12.4 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for pip==24.0\nBest match: pip 24.0\nAdding pip 24.0 to easy-install.pth file\nInstalling pip script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\nInstalling pip3 script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\nInstalling pip3.10 script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for pandas==1.3.5\nBest match: pandas 1.3.5\nAdding pandas 1.3.5 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for orange-widget-base==4.22.0\nBest match: orange-widget-base 4.22.0\nAdding orange-widget-base 4.22.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for orange-canvas-core==0.1.35\nBest match: orange-canvas-core 0.1.35\nAdding orange-canvas-core 0.1.35 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for openTSNE==1.0.1\nBest match: openTSNE 1.0.1\nAdding openTSNE 1.0.1 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for numpy==1.17.5\nBest match: numpy 1.17.5\nAdding numpy 1.17.5 to easy-install.pth file\nInstalling f2py script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\nInstalling f2py3 script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\nInstalling f2py3.7 script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for networkx==2.6.3\nBest match: networkx 2.6.3\nAdding networkx 2.6.3 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for matplotlib==3.5.3\nBest match: matplotlib 3.5.3\nAdding matplotlib 3.5.3 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for keyrings.alt==4.2.0\nBest match: keyrings.alt 4.2.0\nAdding keyrings.alt 4.2.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for keyring==24.1.1\nBest match: keyring 24.1.1\nAdding keyring 24.1.1 to easy-install.pth file\nInstalling keyring script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for joblib==1.3.2\nBest match: joblib 1.3.2\nAdding joblib 1.3.2 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for docutils==0.20.1\nBest match: docutils 0.20.1\nAdding docutils 0.20.1 to easy-install.pth file\nInstalling docutils script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for chardet==5.2.0\nBest match: chardet 5.2.0\nAdding chardet 5.2.0 to easy-install.pth file\nInstalling chardetect script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for Bottleneck==1.4.0\nBest match: Bottleneck 1.4.0\nAdding Bottleneck 1.4.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for AnyQt==0.2.0\nBest match: AnyQt 0.2.0\nAdding AnyQt 0.2.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for threadpoolctl==3.1.0\nBest match: threadpoolctl 3.1.0\nAdding threadpoolctl 3.1.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for urllib3==2.0.7\nBest match: urllib3 2.0.7\nAdding urllib3 2.0.7 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for certifi==2024.12.14\nBest match: certifi 2024.12.14\nAdding certifi 2024.12.14 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for idna==3.10\nBest match: idna 3.10\nAdding idna 3.10 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for charset-normalizer==3.4.1\nBest match: charset-normalizer 3.4.1\nAdding charset-normalizer 3.4.1 to easy-install.pth file\nInstalling normalizer script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for python-dateutil==2.9.0.post0\nBest match: python-dateutil 2.9.0.post0\nAdding python-dateutil 2.9.0.post0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for pytz==2024.2\nBest match: pytz 2024.2\nAdding pytz 2024.2 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for typing-extensions==4.7.1\nBest match: typing-extensions 4.7.1\nAdding typing-extensions 4.7.1 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for dictdiffer==0.9.0\nBest match: dictdiffer 0.9.0\nAdding dictdiffer 0.9.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for qasync==0.25.0\nBest match: qasync 0.25.0\nAdding qasync 0.25.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for requests-cache==1.1.1\nBest match: requests-cache 1.1.1\nAdding requests-cache 1.1.1 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for packaging==24.0\nBest match: packaging 24.0\nAdding packaging 24.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for importlib-metadata==6.7.0\nBest match: importlib-metadata 6.7.0\nAdding importlib-metadata 6.7.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for commonmark==0.9.1\nBest match: commonmark 0.9.1\nAdding commonmark 0.9.1 to easy-install.pth file\nInstalling cmark script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for fonttools==4.38.0\nBest match: fonttools 4.38.0\nAdding fonttools 4.38.0 to easy-install.pth file\nInstalling fonttools script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\nInstalling pyftmerge script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\nInstalling pyftsubset script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\nInstalling ttx script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for Pillow==9.5.0\nBest match: Pillow 9.5.0\nAdding Pillow 9.5.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for pyparsing==3.1.4\nBest match: pyparsing 3.1.4\nAdding pyparsing 3.1.4 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for cycler==0.11.0\nBest match: cycler 0.11.0\nAdding cycler 0.11.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for kiwisolver==1.4.5\nBest match: kiwisolver 1.4.5\nAdding kiwisolver 1.4.5 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for jaraco.classes==3.2.3\nBest match: jaraco.classes 3.2.3\nAdding jaraco.classes 3.2.3 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for SecretStorage==3.3.3\nBest match: SecretStorage 3.3.3\nAdding SecretStorage 3.3.3 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for jeepney==0.8.0\nBest match: jeepney 0.8.0\nAdding jeepney 0.8.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for importlib-resources==5.12.0\nBest match: importlib-resources 5.12.0\nAdding importlib-resources 5.12.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for six==1.17.0\nBest match: six 1.17.0\nAdding six 1.17.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for platformdirs==4.0.0\nBest match: platformdirs 4.0.0\nAdding platformdirs 4.0.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for cattrs==23.1.2\nBest match: cattrs 23.1.2\nAdding cattrs 23.1.2 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for url-normalize==1.4.3\nBest match: url-normalize 1.4.3\nAdding url-normalize 1.4.3 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for attrs==24.2.0\nBest match: attrs 24.2.0\nAdding attrs 24.2.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for zipp==3.15.0\nBest match: zipp 3.15.0\nAdding zipp 3.15.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for more-itertools==9.1.0\nBest match: more-itertools 9.1.0\nAdding more-itertools 9.1.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for cryptography==44.0.0\nBest match: cryptography 44.0.0\nAdding cryptography 44.0.0 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for exceptiongroup==1.2.2\nBest match: exceptiongroup 1.2.2\nAdding exceptiongroup 1.2.2 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for cffi==1.15.1\nBest match: cffi 1.15.1\nAdding cffi 1.15.1 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nSearching for pycparser==2.21\nBest match: pycparser 2.21\nAdding pycparser 2.21 to easy-install.pth file\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages\nFinished processing dependencies for Orange3==3.24.0.dev0+05c8ae0\nVerifying Orange installation...\n✅ Orange installation successful!\nSuccessfully installed orange using Python 3.7\n",
    "setup_res_stderr": "Using CPython 3.7.9\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 18 packages in 101ms\nPrepared 18 packages in 20ms\nInstalled 18 packages in 302ms\n + cython==0.29.37\n + exceptiongroup==1.2.2\n + importlib-metadata==6.7.0\n + iniconfig==2.0.0\n + numpy==1.17.5\n + packaging==24.0\n + pluggy==1.2.0\n + pyqt5==5.15.10\n + pyqt5-qt5==5.15.16\n + pyqt5-sip==12.13.0\n + pyqtwebengine==5.15.6\n + pyqtwebengine-qt5==5.15.16\n + pytest==7.4.4\n + setuptools==59.8.0\n + tomli==2.0.1\n + typing-extensions==4.7.1\n + wheel==0.42.0\n + zipp==3.15.0\nResolved 38 packages in 200ms\nInstalled 33 packages in 811ms\n + bottleneck==1.4.0\n + certifi==2024.12.14\n + cffi==1.15.1\n + chardet==5.2.0\n + charset-normalizer==3.4.1\n + cryptography==44.0.0\n + idna==3.10\n + importlib-resources==5.12.0\n + jaraco-classes==3.2.3\n + jeepney==0.8.0\n + joblib==1.3.2\n + keyring==24.1.1\n + keyrings-alt==4.2.0\n + more-itertools==9.1.0\n + networkx==2.6.3\n + opentsne==1.0.1\n + pandas==1.3.5\n + pip==24.0\n + pycparser==2.21\n + python-dateutil==2.9.0.post0\n + python-louvain==0.16\n + pytz==2024.2\n + pyyaml==6.0.1\n + requests==2.31.0\n + scikit-learn==1.0.2\n + scipy==1.7.3\n + secretstorage==3.3.3\n + serverfiles==0.3.1\n + six==1.17.0\n + threadpoolctl==3.1.0\n + urllib3==2.0.7\n + xlrd==2.0.1\n + xlsxwriter==3.2.0\nResolved 34 packages in 161ms\nInstalled 19 packages in 90ms\n + anyqt==0.2.0\n + attrs==24.2.0\n + cattrs==23.1.2\n + commonmark==0.9.1\n + cycler==0.11.0\n + dictdiffer==0.9.0\n + docutils==0.20.1\n + fonttools==4.38.0\n + kiwisolver==1.4.5\n + matplotlib==3.5.3\n + orange-canvas-core==0.1.35\n + orange-widget-base==4.22.0\n + pillow==9.5.0\n + platformdirs==4.0.0\n + pyparsing==3.1.4\n + pyqtgraph==0.12.4\n + qasync==0.25.0\n + requests-cache==1.1.1\n + url-normalize==1.4.3\nResolved 2 packages in 5ms\nInstalled 2 packages in 34ms\n + psycopg2==2.9.9\n + pymssql==2.3.2\nAudited 1 package in 20ms\nAudited 2 packages in 1ms\nOrange/classification/_simple_tree.c: In function ‘gain_ratio_c’:\nOrange/classification/_simple_tree.c:63:9: warning: implicit declaration of function ‘qsort_r’; did you mean ‘qsort’? [-Wimplicit-function-declaration]\n   63 |         qsort_r(base, nel, size, compar, thunk)\n      |         ^~~~~~~\nOrange/classification/_simple_tree.c:147:9: note: in expansion of macro ‘QSORT_R_FUNC’\n  147 |         QSORT_R_FUNC(examples, size, sizeof(struct Example), (void*) &compar_attr, compar_examples);\n      |         ^~~~~~~~~~~~\nIn file included from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,\n                 from Orange/classification/_tree_scorers.c:567:\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning \"Using deprecated NumPy API, disable it with \" \"#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION\" [-Wcpp]\n   17 | #warning \"Using deprecated NumPy API, disable it with \" \\\n      |  ^~~~~~~\nOrange/classification/_tree_scorers.c: In function ‘__pyx_pf_6Orange_14classification_13_tree_scorers_2find_threshold_entropy’:\nOrange/classification/_tree_scorers.c:3115:27: warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Wsign-compare]\n 3115 |   __pyx_t_7 = ((__pyx_v_N <= __pyx_v_min_leaf) != 0);\n      |                           ^~\nOrange/classification/_tree_scorers.c: In function ‘__pyx_pf_6Orange_14classification_13_tree_scorers_6find_threshold_MSE’:\nOrange/classification/_tree_scorers.c:4619:27: warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Wsign-compare]\n 4619 |   __pyx_t_1 = ((__pyx_v_N <= __pyx_v_min_leaf) != 0);\n      |                           ^~\nOrange/classification/_tree_scorers.c: In function ‘__pyx_pf_6Orange_14classification_13_tree_scorers_8find_binarization_MSE’:\nOrange/classification/_tree_scorers.c:5396:43: warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Wsign-compare]\n 5396 |           for (__pyx_t_22 = 0; __pyx_t_22 < __pyx_t_21; __pyx_t_22+=1) {\n      |                                           ^\nOrange/classification/_tree_scorers.c:5517:39: warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Wsign-compare]\n 5517 |           __pyx_t_27 = ((__pyx_v_left >= __pyx_v_min_leaf) != 0);\n      |                                       ^~\nOrange/classification/_tree_scorers.c:5523:53: warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Wsign-compare]\n 5523 |           __pyx_t_27 = (((__pyx_v_N - __pyx_v_left) >= __pyx_v_min_leaf) != 0);\n      |                                                     ^~\nOrange/classification/_tree_scorers.c: In function ‘__pyx_pf_6Orange_14classification_13_tree_scorers_14compute_predictions_csr’:\nOrange/classification/_tree_scorers.c:7051:41: warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Wsign-compare]\n 7051 |         for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) {\n      |                                         ^\nOrange/classification/_tree_scorers.c: In function ‘__pyx_pf_6Orange_14classification_13_tree_scorers_16compute_predictions_csc’:\nOrange/classification/_tree_scorers.c:7741:41: warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Wsign-compare]\n 7741 |         for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) {\n      |                                         ^\nOrange/classification/_tree_scorers.c:7801:143: warning: comparison of integer expressions of different signedness: ‘__pyx_t_5numpy_int32_t’ {aka ‘int’} and ‘unsigned int’ [-Wsign-compare]\n 7801 |               __pyx_t_17 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_indices.data + __pyx_t_18 * __pyx_v_indices.strides[0]) ))) != __pyx_v_i) != 0);\n      |                                                                                                                                               ^~\nIn file included from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,\n                 from Orange/data/_valuecount.c:567:\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning \"Using deprecated NumPy API, disable it with \" \"#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION\" [-Wcpp]\n   17 | #warning \"Using deprecated NumPy API, disable it with \" \\\n      |  ^~~~~~~\nIn file included from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,\n                 from Orange/data/_contingency.c:598:\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning \"Using deprecated NumPy API, disable it with \" \"#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION\" [-Wcpp]\n   17 | #warning \"Using deprecated NumPy API, disable it with \" \\\n      |  ^~~~~~~\nOrange/data/_io.c: In function ‘__pyx_pf_6Orange_4data_3_io_sparse_read_float.constprop’:\nOrange/data/_io.c:3881:24: warning: ‘__pyx_v_decs’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 3881 |           __pyx_v_decs = (__pyx_v_decs / 10.0);\n      |           ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~\nOrange/data/_io.c:4070:24: warning: ‘__pyx_v_value’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 4070 |           __pyx_t_10 = PyFloat_FromDouble(__pyx_v_value); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 221, __pyx_L5_error)\n      |                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nOrange/data/_io.c:480:40: warning: ‘__pyx_v_attr_index’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n  480 |   #define PyInt_FromLong               PyLong_FromLong\n      |                                        ^~~~~~~~~~~~~~~\nOrange/data/_io.c:1301:7: note: ‘__pyx_v_attr_index’ was declared here\n 1301 |   int __pyx_v_attr_index;\n      |       ^~~~~~~~~~~~~~~~~~\nOrange/data/_io.c:2935:25: warning: ‘__pyx_v_atomp’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 2935 |           __pyx_v_atomp = (__pyx_v_atomp + 1);\n      |           ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~\nIn file included from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,\n                 from Orange/distance/_distance.c:567:\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning \"Using deprecated NumPy API, disable it with \" \"#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION\" [-Wcpp]\n   17 | #warning \"Using deprecated NumPy API, disable it with \" \\\n      |  ^~~~~~~\nIn file included from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,\n                 from Orange/preprocess/_discretize.c:567:\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning \"Using deprecated NumPy API, disable it with \" \"#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION\" [-Wcpp]\n   17 | #warning \"Using deprecated NumPy API, disable it with \" \\\n      |  ^~~~~~~\nIn file included from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,\n                 from Orange/preprocess/_relieff.cpp:581:\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning \"Using deprecated NumPy API, disable it with \" \"#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION\" [-Wcpp]\n   17 | #warning \"Using deprecated NumPy API, disable it with \" \\\n      |  ^~~~~~~\nIn file included from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,\n                 from Orange/projection/_som.c:598:\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning \"Using deprecated NumPy API, disable it with \" \"#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION\" [-Wcpp]\n   17 | #warning \"Using deprecated NumPy API, disable it with \" \\\n      |  ^~~~~~~\nOrange/projection/_som.c: In function ‘__pyx_pw_6Orange_10projection_4_som_5update_hex’:\nOrange/projection/_som.c:3655:7: warning: ‘__pyx_v_win_y’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 3655 |   int __pyx_v_win_y;\n      |       ^~~~~~~~~~~~~\nOrange/projection/_som.c:3654:7: warning: ‘__pyx_v_win_x’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 3654 |   int __pyx_v_win_x;\n      |       ^~~~~~~~~~~~~\nOrange/projection/_som.c: In function ‘__pyx_pw_6Orange_10projection_4_som_7get_winners_sparse’:\nOrange/projection/_som.c:4547:223: warning: ‘__pyx_v_win_y’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 4547 |           *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int16_t *, __pyx_pybuffernd_winners.rcbuffer->pybuffer.buf, __pyx_t_38, __pyx_pybuffernd_winners.diminfo[0].strides, __pyx_t_39, __pyx_pybuffernd_winners.diminfo[1].strides) = __pyx_v_win_y;\n      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~\nOrange/projection/_som.c:4114:7: note: ‘__pyx_v_win_y’ was declared here\n 4114 |   int __pyx_v_win_y;\n      |       ^~~~~~~~~~~~~\nOrange/projection/_som.c:4536:223: warning: ‘__pyx_v_win_x’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 4536 |           *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int16_t *, __pyx_pybuffernd_winners.rcbuffer->pybuffer.buf, __pyx_t_36, __pyx_pybuffernd_winners.diminfo[0].strides, __pyx_t_37, __pyx_pybuffernd_winners.diminfo[1].strides) = __pyx_v_win_x;\n      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~\nOrange/projection/_som.c:4113:7: note: ‘__pyx_v_win_x’ was declared here\n 4113 |   int __pyx_v_win_x;\n      |       ^~~~~~~~~~~~~\nOrange/projection/_som.c: In function ‘__pyx_pf_6Orange_10projection_4_som_8update_sparse.constprop’:\nOrange/projection/_som.c:4746:7: warning: ‘__pyx_v_win_y’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 4746 |   int __pyx_v_win_y;\n      |       ^~~~~~~~~~~~~\nOrange/projection/_som.c:4745:7: warning: ‘__pyx_v_win_x’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 4745 |   int __pyx_v_win_x;\n      |       ^~~~~~~~~~~~~\nOrange/projection/_som.c: In function ‘__pyx_pw_6Orange_10projection_4_som_3update’:\nOrange/projection/_som.c:3141:7: warning: ‘__pyx_v_win_y’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 3141 |   int __pyx_v_win_y;\n      |       ^~~~~~~~~~~~~\nOrange/projection/_som.c: In function ‘__pyx_pw_6Orange_10projection_4_som_1get_winners’:\nOrange/projection/_som.c:2964:223: warning: ‘__pyx_v_win_y’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 2964 |           *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int16_t *, __pyx_pybuffernd_winners.rcbuffer->pybuffer.buf, __pyx_t_27, __pyx_pybuffernd_winners.diminfo[0].strides, __pyx_t_28, __pyx_pybuffernd_winners.diminfo[1].strides) = __pyx_v_win_y;\n      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~\nOrange/projection/_som.c:2665:7: note: ‘__pyx_v_win_y’ was declared here\n 2665 |   int __pyx_v_win_y;\n      |       ^~~~~~~~~~~~~\nOrange/projection/_som.c:2953:223: warning: ‘__pyx_v_win_x’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 2953 |           *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int16_t *, __pyx_pybuffernd_winners.rcbuffer->pybuffer.buf, __pyx_t_25, __pyx_pybuffernd_winners.diminfo[0].strides, __pyx_t_26, __pyx_pybuffernd_winners.diminfo[1].strides) = __pyx_v_win_x;\n      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~\nOrange/projection/_som.c:2664:7: note: ‘__pyx_v_win_x’ was declared here\n 2664 |   int __pyx_v_win_x;\n      |       ^~~~~~~~~~~~~\nOrange/projection/_som.c: In function ‘__pyx_pf_6Orange_10projection_4_som_10update_sparse_hex.constprop’:\nOrange/projection/_som.c:5515:7: warning: ‘__pyx_v_win_y’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 5515 |   int __pyx_v_win_y;\n      |       ^~~~~~~~~~~~~\nOrange/projection/_som.c:5514:7: warning: ‘__pyx_v_win_x’ may be used uninitialized in this function [-Wmaybe-uninitialized]\n 5514 |   int __pyx_v_win_x;\n      |       ^~~~~~~~~~~~~\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/setuptools/command/install.py:37: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\n  setuptools.SetuptoolsDeprecationWarning,\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/setuptools/command/easy_install.py:159: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.\n  EasyInstallDeprecationWarning,\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/setuptools/command/install.py:37: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\n  setuptools.SetuptoolsDeprecationWarning,\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf/.venv/lib/python3.7/site-packages/setuptools/command/egg_info.py:628: SetuptoolsDeprecationWarning: Custom 'build_py' does not implement 'get_data_files_without_manifest'.\nPlease extend command classes from setuptools instead of distutils.\n  SetuptoolsDeprecationWarning\n",
    "new_commit_res_code": 1,
    "new_commit_res_stdout": "============================= test session starts ==============================\nplatform linux -- Python 3.7.9, pytest-7.4.4, pluggy-1.2.0\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf\ncollected 12 items\n\nr2e_tests/test_1.py ....F...F...                                         [100%]\n\n=================================== FAILURES ===================================\n_____________________ TestOWDataSampler.test_error_message _____________________\n\nself = <Orange.widgets.data.owdatasampler.OWDataSampler object at 0x7238b5aea0f0>\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n    \n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n    \n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n    \n        if self.Error.active:\n            self.indices = None\n            return\n    \n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n    \n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n>           self.indices = self.sample(data_length, size, stratified)\n\nOrange/widgets/data/owdatasampler.py:278: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nOrange/widgets/data/owdatasampler.py:298: in sample\n    return sampler(self.data)\nOrange/widgets/data/owdatasampler.py:357: in __call__\n    self.folds, random_state=self.random_state)\n.venv/lib/python3.7/site-packages/sklearn/model_selection/_split.py:435: in __init__\n    super().__init__(n_splits=n_splits, shuffle=shuffle, random_state=random_state)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = KFold(n_splits=None, random_state=None, shuffle=None), n_splits = 10\n\n    @abstractmethod\n    def __init__(self, n_splits, *, shuffle, random_state):\n        if not isinstance(n_splits, numbers.Integral):\n            raise ValueError(\n                \"The number of folds must be of Integral type. \"\n                \"%s of type %s was passed.\" % (n_splits, type(n_splits))\n            )\n        n_splits = int(n_splits)\n    \n        if n_splits <= 1:\n            raise ValueError(\n                \"k-fold cross-validation requires at least one\"\n                \" train/test split by setting n_splits=2 or more,\"\n                \" got n_splits={0}.\".format(n_splits)\n            )\n    \n        if not isinstance(shuffle, bool):\n            raise TypeError(\"shuffle must be True or False; got {0}\".format(shuffle))\n    \n        if not shuffle and random_state is not None:  # None is the default\n            raise ValueError(\n>               \"Setting a random_state has no effect since shuffle is \"\n                \"False. You should leave \"\n                \"random_state to its default (None), or set shuffle=True.\",\n            )\nE           ValueError: Setting a random_state has no effect since shuffle is False. You should leave random_state to its default (None), or set shuffle=True.\n\n.venv/lib/python3.7/site-packages/sklearn/model_selection/_split.py:297: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestOWDataSampler testMethod=test_error_message>\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n>       self.send_signal(\"Data\", self.iris)\n\nr2e_tests/test_1.py:24: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n.venv/lib/python3.7/site-packages/orangewidget/tests/base.py:446: in send_signal\n    widget=widget, wait=wait)\n.venv/lib/python3.7/site-packages/orangewidget/tests/base.py:471: in send_signals\n    self._send_signal(widget, input, value, *args)\n.venv/lib/python3.7/site-packages/orangewidget/tests/base.py:490: in _send_signal\n    notify_input_helper(input, widget, value, *args, **kwargs)\n../../../../.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib/python3.7/functools.py:840: in wrapper\n    return dispatch(args[0].__class__)(*args, **kw)\n.venv/lib/python3.7/site-packages/orangewidget/utils/signals.py:735: in set_input_helper\n    handler(*args)\nOrange/widgets/data/owdatasampler.py:186: in set_data\n    self.updateindices()\nOrange/widgets/data/owdatasampler.py:281: in updateindices\n    self.indices = self.sample(data_length, size, stratified=False)\nOrange/widgets/data/owdatasampler.py:298: in sample\n    return sampler(self.data)\nOrange/widgets/data/owdatasampler.py:357: in __call__\n    self.folds, random_state=self.random_state)\n.venv/lib/python3.7/site-packages/sklearn/model_selection/_split.py:435: in __init__\n    super().__init__(n_splits=n_splits, shuffle=shuffle, random_state=random_state)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = KFold(n_splits=None, random_state=None, shuffle=None), n_splits = 10\n\n    @abstractmethod\n    def __init__(self, n_splits, *, shuffle, random_state):\n        if not isinstance(n_splits, numbers.Integral):\n            raise ValueError(\n                \"The number of folds must be of Integral type. \"\n                \"%s of type %s was passed.\" % (n_splits, type(n_splits))\n            )\n        n_splits = int(n_splits)\n    \n        if n_splits <= 1:\n            raise ValueError(\n                \"k-fold cross-validation requires at least one\"\n                \" train/test split by setting n_splits=2 or more,\"\n                \" got n_splits={0}.\".format(n_splits)\n            )\n    \n        if not isinstance(shuffle, bool):\n            raise TypeError(\"shuffle must be True or False; got {0}\".format(shuffle))\n    \n        if not shuffle and random_state is not None:  # None is the default\n            raise ValueError(\n>               \"Setting a random_state has no effect since shuffle is \"\n                \"False. You should leave \"\n                \"random_state to its default (None), or set shuffle=True.\",\n            )\nE           ValueError: Setting a random_state has no effect since shuffle is False. You should leave random_state to its default (None), or set shuffle=True.\n\n.venv/lib/python3.7/site-packages/sklearn/model_selection/_split.py:297: ValueError\n______________ TestOWDataSampler.test_no_intersection_in_outputs _______________\n\nself = <Orange.widgets.data.owdatasampler.OWDataSampler object at 0x72389e04d190>\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n    \n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n    \n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n    \n        if self.Error.active:\n            self.indices = None\n            return\n    \n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n    \n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n>           self.indices = self.sample(data_length, size, stratified)\n\nOrange/widgets/data/owdatasampler.py:278: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nOrange/widgets/data/owdatasampler.py:298: in sample\n    return sampler(self.data)\nOrange/widgets/data/owdatasampler.py:352: in __call__\n    self.folds, random_state=self.random_state)\n.venv/lib/python3.7/site-packages/sklearn/model_selection/_split.py:644: in __init__\n    super().__init__(n_splits=n_splits, shuffle=shuffle, random_state=random_state)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = StratifiedKFold(n_splits=None, random_state=None, shuffle=None)\nn_splits = 10\n\n    @abstractmethod\n    def __init__(self, n_splits, *, shuffle, random_state):\n        if not isinstance(n_splits, numbers.Integral):\n            raise ValueError(\n                \"The number of folds must be of Integral type. \"\n                \"%s of type %s was passed.\" % (n_splits, type(n_splits))\n            )\n        n_splits = int(n_splits)\n    \n        if n_splits <= 1:\n            raise ValueError(\n                \"k-fold cross-validation requires at least one\"\n                \" train/test split by setting n_splits=2 or more,\"\n                \" got n_splits={0}.\".format(n_splits)\n            )\n    \n        if not isinstance(shuffle, bool):\n            raise TypeError(\"shuffle must be True or False; got {0}\".format(shuffle))\n    \n        if not shuffle and random_state is not None:  # None is the default\n            raise ValueError(\n>               \"Setting a random_state has no effect since shuffle is \"\n                \"False. You should leave \"\n                \"random_state to its default (None), or set shuffle=True.\",\n            )\nE           ValueError: Setting a random_state has no effect since shuffle is False. You should leave random_state to its default (None), or set shuffle=True.\n\n.venv/lib/python3.7/site-packages/sklearn/model_selection/_split.py:297: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestOWDataSampler testMethod=test_no_intersection_in_outputs>\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n    \n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n>                   self.widget.commit()\n\nr2e_tests/test_1.py:84: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nOrange/widgets/data/owdatasampler.py:219: in commit\n    self.updateindices()\nOrange/widgets/data/owdatasampler.py:281: in updateindices\n    self.indices = self.sample(data_length, size, stratified=False)\nOrange/widgets/data/owdatasampler.py:298: in sample\n    return sampler(self.data)\nOrange/widgets/data/owdatasampler.py:357: in __call__\n    self.folds, random_state=self.random_state)\n.venv/lib/python3.7/site-packages/sklearn/model_selection/_split.py:435: in __init__\n    super().__init__(n_splits=n_splits, shuffle=shuffle, random_state=random_state)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = KFold(n_splits=None, random_state=None, shuffle=None), n_splits = 10\n\n    @abstractmethod\n    def __init__(self, n_splits, *, shuffle, random_state):\n        if not isinstance(n_splits, numbers.Integral):\n            raise ValueError(\n                \"The number of folds must be of Integral type. \"\n                \"%s of type %s was passed.\" % (n_splits, type(n_splits))\n            )\n        n_splits = int(n_splits)\n    \n        if n_splits <= 1:\n            raise ValueError(\n                \"k-fold cross-validation requires at least one\"\n                \" train/test split by setting n_splits=2 or more,\"\n                \" got n_splits={0}.\".format(n_splits)\n            )\n    \n        if not isinstance(shuffle, bool):\n            raise TypeError(\"shuffle must be True or False; got {0}\".format(shuffle))\n    \n        if not shuffle and random_state is not None:  # None is the default\n            raise ValueError(\n>               \"Setting a random_state has no effect since shuffle is \"\n                \"False. You should leave \"\n                \"random_state to its default (None), or set shuffle=True.\",\n            )\nE           ValueError: Setting a random_state has no effect since shuffle is False. You should leave random_state to its default (None), or set shuffle=True.\n\n.venv/lib/python3.7/site-packages/sklearn/model_selection/_split.py:297: ValueError\n==================================== PASSES ====================================\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_bigger_output_warning\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_bigger_size_with_replacement\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_bigger_size_without_replacement\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_bootstrap\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_image_export\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_minimum_size\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_msg_base_class\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_shuffling\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_stratified_on_unbalanced_data\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_summary\nFAILED r2e_tests/test_1.py::TestOWDataSampler::test_error_message - ValueErro...\nFAILED r2e_tests/test_1.py::TestOWDataSampler::test_no_intersection_in_outputs\n========================= 2 failed, 10 passed in 3.78s =========================\nWidgets left: 0    Max widgets: 1056 \n\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts ==============================\nplatform linux -- Python 3.7.9, pytest-7.4.4, pluggy-1.2.0\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_05c8ae088d8eb1c68d70422341464e822d9428cf\ncollected 12 items\n\nr2e_tests/test_1.py ...FF...F..F                                         [100%]\n\n=================================== FAILURES ===================================\n_______________________ TestOWDataSampler.test_bootstrap _______________________\n\nself = <r2e_tests.test_1.TestOWDataSampler testMethod=test_bootstrap>\n\n    def test_bootstrap(self):\n        output_sum = self.widget.info.set_output_summary = Mock()\n        self.select_sampling_type(self.widget.Bootstrap)\n    \n        self.send_signal(\"Data\", self.iris)\n    \n        in_input = set(self.iris.ids)\n        sample = self.get_output(\"Data Sample\")\n        in_sample = set(sample.ids)\n        in_remaining = set(self.get_output(\"Remaining Data\").ids)\n    \n        # Bootstrap should sample len(input) instances\n        self.assertEqual(len(sample), len(self.iris))\n        # Sample and remaining should cover all instances, while none\n        # should be present in both\n        self.assertEqual(len(in_sample | in_remaining), len(in_input))\n        self.assertEqual(len(in_sample & in_remaining), 0)\n        # Sampling with replacement will always produce at least one distinct\n        # instance in sample, and at least one instance in remaining with\n        # high probability (1-(1/150*2/150*...*150/150) ~= 1-2e-64)\n        self.assertGreater(len(in_sample), 0)\n        self.assertGreater(len(in_remaining), 0)\n        #Check if status bar shows correct number of output data\n>       output_sum.assert_called_with(str(len(sample)))\n\nr2e_tests/test_1.py:63: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\n_mock_self = <Mock id='124139253591824'>, args = ('150',), kwargs = {}\nexpected = \"mock('150')\"\n\n    def assert_called_with(_mock_self, *args, **kwargs):\n        \"\"\"assert that the mock was called with the specified arguments.\n    \n        Raises an AssertionError if the args and keyword args passed in are\n        different to the last call to the mock.\"\"\"\n        self = _mock_self\n        if self.call_args is None:\n            expected = self._format_mock_call_signature(args, kwargs)\n>           raise AssertionError('Expected call: %s\\nNot called' % (expected,))\nE           AssertionError: Expected call: mock('150')\nE           Not called\n\n../../../../.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib/python3.7/unittest/mock.py:869: AssertionError\n_____________________ TestOWDataSampler.test_error_message _____________________\n\nself = <Orange.widgets.data.owdatasampler.OWDataSampler object at 0x70e76c1492d0>\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n    \n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n    \n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n    \n        if self.Error.active:\n            self.indices = None\n            return\n    \n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n    \n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n>           self.indices = self.sample(data_length, size, stratified)\n\nOrange/widgets/data/owdatasampler.py:287: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nOrange/widgets/data/owdatasampler.py:307: in sample\n    return sampler(self.data)\nOrange/widgets/data/owdatasampler.py:366: in __call__\n    self.folds, random_state=self.random_state)\n.venv/lib/python3.7/site-packages/sklearn/model_selection/_split.py:435: in __init__\n    super().__init__(n_splits=n_splits, shuffle=shuffle, random_state=random_state)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = KFold(n_splits=None, random_state=None, shuffle=None), n_splits = 10\n\n    @abstractmethod\n    def __init__(self, n_splits, *, shuffle, random_state):\n        if not isinstance(n_splits, numbers.Integral):\n            raise ValueError(\n                \"The number of folds must be of Integral type. \"\n                \"%s of type %s was passed.\" % (n_splits, type(n_splits))\n            )\n        n_splits = int(n_splits)\n    \n        if n_splits <= 1:\n            raise ValueError(\n                \"k-fold cross-validation requires at least one\"\n                \" train/test split by setting n_splits=2 or more,\"\n                \" got n_splits={0}.\".format(n_splits)\n            )\n    \n        if not isinstance(shuffle, bool):\n            raise TypeError(\"shuffle must be True or False; got {0}\".format(shuffle))\n    \n        if not shuffle and random_state is not None:  # None is the default\n            raise ValueError(\n>               \"Setting a random_state has no effect since shuffle is \"\n                \"False. You should leave \"\n                \"random_state to its default (None), or set shuffle=True.\",\n            )\nE           ValueError: Setting a random_state has no effect since shuffle is False. You should leave random_state to its default (None), or set shuffle=True.\n\n.venv/lib/python3.7/site-packages/sklearn/model_selection/_split.py:297: ValueError\n\nDuring handling of the above exception, another exception occurred:\n\nself = <r2e_tests.test_1.TestOWDataSampler testMethod=test_error_message>\n\n    def test_error_message(self):\n        \"\"\" Check if error message appears and then disappears when\n        data is removed from input\"\"\"\n        self.widget.controls.sampling_type.buttons[2].click()\n>       self.send_signal(\"Data\", self.iris)\n\nr2e_tests/test_1.py:24: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n.venv/lib/python3.7/site-packages/orangewidget/tests/base.py:446: in send_signal\n    widget=widget, wait=wait)\n.venv/lib/python3.7/site-packages/orangewidget/tests/base.py:471: in send_signals\n    self._send_signal(widget, input, value, *args)\n.venv/lib/python3.7/site-packages/orangewidget/tests/base.py:490: in _send_signal\n    notify_input_helper(input, widget, value, *args, **kwargs)\n../../../../.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib/python3.7/functools.py:840: in wrapper\n    return dispatch(args[0].__class__)(*args, **kw)\n.venv/lib/python3.7/site-packages/orangewidget/utils/signals.py:735: in set_input_helper\n    handler(*args)\nOrange/widgets/data/owdatasampler.py:189: in set_data\n    self.updateindices()\nOrange/widgets/data/owdatasampler.py:290: in updateindices\n    self.indices = self.sample(data_length, size, stratified=False)\nOrange/widgets/data/owdatasampler.py:307: in sample\n    return sampler(self.data)\nOrange/widgets/data/owdatasampler.py:366: in __call__\n    self.folds, random_state=self.random_state)\n.venv/lib/python3.7/site-packages/sklearn/model_selection/_split.py:435: in __init__\n    super().__init__(n_splits=n_splits, shuffle=shuffle, random_state=random_state)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = KFold(n_splits=None, random_state=None, shuffle=None), n_splits = 10\n\n    @abstractmethod\n    def __init__(self, n_splits, *, shuffle, random_state):\n        if not isinstance(n_splits, numbers.Integral):\n            raise ValueError(\n                \"The number of folds must be of Integral type. \"\n                \"%s of type %s was passed.\" % (n_splits, type(n_splits))\n            )\n        n_splits = int(n_splits)\n    \n        if n_splits <= 1:\n            raise ValueError(\n                \"k-fold cross-validation requires at least one\"\n                \" train/test split by setting n_splits=2 or more,\"\n                \" got n_splits={0}.\".format(n_splits)\n            )\n    \n        if not isinstance(shuffle, bool):\n            raise TypeError(\"shuffle must be True or False; got {0}\".format(shuffle))\n    \n        if not shuffle and random_state is not None:  # None is the default\n            raise ValueError(\n>               \"Setting a random_state has no effect since shuffle is \"\n                \"False. You should leave \"\n                \"random_state to its default (None), or set shuffle=True.\",\n            )\nE           ValueError: Setting a random_state has no effect since shuffle is False. You should leave random_state to its default (None), or set shuffle=True.\n\n.venv/lib/python3.7/site-packages/sklearn/model_selection/_split.py:297: ValueError\n______________ TestOWDataSampler.test_no_intersection_in_outputs _______________\n\nself = <r2e_tests.test_1.TestOWDataSampler testMethod=test_no_intersection_in_outputs>\n\n    def test_no_intersection_in_outputs(self):\n        \"\"\" Check whether outputs intersect and whether length of outputs sums\n        to length of original data and\n        if status bar displays correct output for each sampling type\"\"\"\n        self.send_signal(\"Data\", self.iris)\n        w = self.widget\n        output_sum = self.widget.info.set_output_summary = Mock()\n        sampling_types = [w.FixedProportion, w.FixedSize, w.CrossValidation]\n    \n        for replicable in [True, False]:\n            for stratified in [True, False]:\n                for sampling_type in sampling_types:\n                    self.widget.cb_seed.setChecked(replicable)\n                    self.widget.cb_stratify.setChecked(stratified)\n                    self.select_sampling_type(sampling_type)\n                    self.widget.commit()\n    \n                    sample = self.get_output(\"Data Sample\")\n                    other = self.get_output(\"Remaining Data\")\n                    self.assertEqual(len(self.iris), len(sample) + len(other))\n                    self.assertNoIntersection(sample, other)\n>                   output_sum.assert_called_with(str(len(sample)))\n\nr2e_tests/test_1.py:90: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\n_mock_self = <Mock id='124139252285776'>, args = ('105',), kwargs = {}\nexpected = \"mock('105')\"\n\n    def assert_called_with(_mock_self, *args, **kwargs):\n        \"\"\"assert that the mock was called with the specified arguments.\n    \n        Raises an AssertionError if the args and keyword args passed in are\n        different to the last call to the mock.\"\"\"\n        self = _mock_self\n        if self.call_args is None:\n            expected = self._format_mock_call_signature(args, kwargs)\n>           raise AssertionError('Expected call: %s\\nNot called' % (expected,))\nE           AssertionError: Expected call: mock('105')\nE           Not called\n\n../../../../.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib/python3.7/unittest/mock.py:869: AssertionError\n________________________ TestOWDataSampler.test_summary ________________________\n\nself = <r2e_tests.test_1.TestOWDataSampler testMethod=test_summary>\n\n    def test_summary(self):\n        \"\"\"Check if status bar is updated when data is received\"\"\"\n        input_sum = self.widget.info.set_input_summary = Mock()\n        data = self.iris\n    \n        input_sum.reset_mock()\n        self.send_signal(self.widget.Inputs.data, data[:])\n>       input_sum.assert_called_with(\"150\")\n\nr2e_tests/test_1.py:134: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\n_mock_self = <Mock id='124139253176080'>, args = ('150',), kwargs = {}\nexpected = \"mock('150')\"\n\n    def assert_called_with(_mock_self, *args, **kwargs):\n        \"\"\"assert that the mock was called with the specified arguments.\n    \n        Raises an AssertionError if the args and keyword args passed in are\n        different to the last call to the mock.\"\"\"\n        self = _mock_self\n        if self.call_args is None:\n            expected = self._format_mock_call_signature(args, kwargs)\n>           raise AssertionError('Expected call: %s\\nNot called' % (expected,))\nE           AssertionError: Expected call: mock('150')\nE           Not called\n\n../../../../.local/share/uv/python/cpython-3.7.9-linux-x86_64-gnu/lib/python3.7/unittest/mock.py:869: AssertionError\n==================================== PASSES ====================================\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_bigger_output_warning\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_bigger_size_with_replacement\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_bigger_size_without_replacement\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_image_export\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_minimum_size\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_msg_base_class\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_shuffling\nPASSED r2e_tests/test_1.py::TestOWDataSampler::test_stratified_on_unbalanced_data\nFAILED r2e_tests/test_1.py::TestOWDataSampler::test_bootstrap - AssertionErro...\nFAILED r2e_tests/test_1.py::TestOWDataSampler::test_error_message - ValueErro...\nFAILED r2e_tests/test_1.py::TestOWDataSampler::test_no_intersection_in_outputs\nFAILED r2e_tests/test_1.py::TestOWDataSampler::test_summary - AssertionError:...\n========================= 4 failed, 8 passed in 2.84s ==========================\nWidgets left: 0    Max widgets: 1092 \n\n",
    "old_commit_res_stderr": ""
}
Orange/widgets/data/owdatasampler.py Orange/widgets/data/tests/test_owdatasampler.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** Status Bar Fails to Update Output Summary After Bootstrapping

**Description:**
After selecting the bootstrap sampling type and providing input data, the status bar is expected to display the number of sampled instances. However, the status bar does not update as expected, leaving it blank or showing incorrect information.

**Example Code:**
```python
widget = OWDataSampler()
widget.select_sampling_type('Bootstrap')
widget.send_signal('Data', iris_dataset)

# Expected: Status bar shows "150 instances sampled."
# Actual: Status bar remains blank or does not display the correct number.
```

**Expected Behavior:**
Upon performing bootstrap sampling, the status bar should accurately display the number of sampled instances, such as "150 instances sampled."

**Actual Behavior:**
The status bar does not update to reflect the number of sampled instances, resulting in no information being shown or incorrect data being displayed.
[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### Orange/widgets/data/owdatasampler.py
import math

from AnyQt.QtWidgets import QFormLayout
from AnyQt.QtCore import Qt

import numpy as np
import sklearn.model_selection as skl

from Orange.widgets import gui
from Orange.widgets.settings import Setting
from Orange.data import Table
from Orange.data.sql.table import SqlTable
from Orange.widgets.utils.widgetpreview import WidgetPreview
from Orange.widgets.widget import Msg, OWWidget, Input, Output
from Orange.util import Reprable


class OWDataSampler(OWWidget):
    name = "Data Sampler"
    description = "Randomly draw a subset of data points " \
                  "from the input dataset."
    icon = "icons/DataSampler.svg"
    priority = 100
    category = "Data"
    keywords = ["random"]

    _MAX_SAMPLE_SIZE = 2 ** 31 - 1

    class Inputs:
        data = Input("Data", Table)

    class Outputs:
        data_sample = Output("Data Sample", Table, default=True)
        remaining_data = Output("Remaining Data", Table)

    want_main_area = False
    resizing_enabled = False

    RandomSeed = 42
    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)
    SqlTime, SqlProportion = range(2)

    selectedFold: int

    use_seed = Setting(True)
    replacement = Setting(False)
    stratify = Setting(False)
    sql_dl = Setting(False)
    sampling_type = Setting(FixedProportion)
    sampleSizeNumber = Setting(1)
    sampleSizePercentage = Setting(70)
    sampleSizeSqlTime = Setting(1)
    sampleSizeSqlPercentage = Setting(0.1)
    number_of_folds = Setting(10)
    selectedFold = Setting(1)

    class Warning(OWWidget.Warning):
        could_not_stratify = Msg("Stratification failed\n{}")
        bigger_sample = Msg('Sample is bigger than input')

    class Error(OWWidget.Error):
        too_many_folds = Msg("Number of folds exceeds data size")
        sample_larger_than_data = Msg("Sample can't be larger than data")
        not_enough_to_stratify = Msg("Data is too small to stratify")
        no_data = Msg("Dataset is empty")

    def __init__(self):
        super().__init__()
        self.data = None
        self.indices = None
        self.sampled_instances = self.remaining_instances = None

        box = gui.vBox(self.controlArea, "Information")
        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')
        self.outputInfoLabel = gui.widgetLabel(box, ' ')

        self.sampling_box = gui.vBox(self.controlArea, "Sampling Type")
        sampling = gui.radioButtons(self.sampling_box, self, "sampling_type",
                                    callback=self.sampling_type_changed)

        def set_sampling_type(i):
            def set_sampling_type_i():
                self.sampling_type = i
                self.sampling_type_changed()
            return set_sampling_type_i

        gui.appendRadioButton(sampling, "Fixed proportion of data:")
        self.sampleSizePercentageSlider = gui.hSlider(
            gui.indentedBox(sampling), self,
            "sampleSizePercentage",
            minValue=0, maxValue=100, ticks=10, labelFormat="%d %%",
            callback=set_sampling_type(self.FixedProportion),
            addSpace=12)

        gui.appendRadioButton(sampling, "Fixed sample size")
        ibox = gui.indentedBox(sampling)
        self.sampleSizeSpin = gui.spin(
            ibox, self, "sampleSizeNumber", label="Instances: ",
            minv=1, maxv=self._MAX_SAMPLE_SIZE,
            callback=set_sampling_type(self.FixedSize),
            controlWidth=90)
        gui.checkBox(
            ibox, self, "replacement", "Sample with replacement",
            callback=set_sampling_type(self.FixedSize),
            addSpace=12)

        gui.appendRadioButton(sampling, "Cross validation")
        form = QFormLayout(
            formAlignment=Qt.AlignLeft | Qt.AlignTop,
            labelAlignment=Qt.AlignLeft,
            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)
        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)
        form.addRow("Number of folds:",
                    gui.spin(
                        ibox, self, "number_of_folds", 2, 100,
                        addToLayout=False,
                        callback=self.number_of_folds_changed))
        self.selected_fold_spin = gui.spin(
            ibox, self, "selectedFold", 1, self.number_of_folds,
            addToLayout=False, callback=self.fold_changed)
        form.addRow("Selected fold:", self.selected_fold_spin)

        gui.appendRadioButton(sampling, "Bootstrap")

        self.sql_box = gui.vBox(self.controlArea, "Sampling Type")
        sampling = gui.radioButtons(self.sql_box, self, "sampling_type",
                                    callback=self.sampling_type_changed)
        gui.appendRadioButton(sampling, "Time:")
        ibox = gui.indentedBox(sampling)
        spin = gui.spin(ibox, self, "sampleSizeSqlTime", minv=1, maxv=3600,
                        callback=set_sampling_type(self.SqlTime))
        spin.setSuffix(" sec")
        gui.appendRadioButton(sampling, "Percentage")
        ibox = gui.indentedBox(sampling)
        spin = gui.spin(ibox, self, "sampleSizeSqlPercentage", spinType=float,
                        minv=0.0001, maxv=100, step=0.1, decimals=4,
                        callback=set_sampling_type(self.SqlProportion))
        spin.setSuffix(" %")
        self.sql_box.setVisible(False)

        self.options_box = gui.vBox(self.controlArea, "Options")
        self.cb_seed = gui.checkBox(
            self.options_box, self, "use_seed",
            "Replicable (deterministic) sampling",
            callback=self.settings_changed)
        self.cb_stratify = gui.checkBox(
            self.options_box, self, "stratify",
            "Stratify sample (when possible)", callback=self.settings_changed)
        self.cb_sql_dl = gui.checkBox(
            self.options_box, self, "sql_dl", "Download data to local memory",
            callback=self.settings_changed)
        self.cb_sql_dl.setVisible(False)

        gui.button(self.buttonsArea, self, "Sample Data",
                   callback=self.commit)

    def sampling_type_changed(self):
        self.settings_changed()

    def number_of_folds_changed(self):
        self.selected_fold_spin.setMaximum(self.number_of_folds)
        self.sampling_type = self.CrossValidation
        self.settings_changed()

    def fold_changed(self):
        # a separate callback - if we decide to cache indices
        self.sampling_type = self.CrossValidation

    def settings_changed(self):
        self._update_sample_max_size()
        self.indices = None

    @Inputs.data
    def set_data(self, dataset):
        self.data = dataset
        if dataset is not None:
            sql = isinstance(dataset, SqlTable)
            self.sampling_box.setVisible(not sql)
            self.sql_box.setVisible(sql)
            self.cb_seed.setVisible(not sql)
            self.cb_stratify.setVisible(not sql)
            self.cb_sql_dl.setVisible(sql)
            self.dataInfoLabel.setText(
                '{}{} instances in input dataset.'.format(*(
                    ('~', dataset.approx_len()) if sql else
                    ('', len(dataset)))))
            if not sql:
                self._update_sample_max_size()
                self.updateindices()
        else:
            self.dataInfoLabel.setText('No data on input.')
            self.outputInfoLabel.setText('')
            self.indices = None
            self.clear_messages()
        self.commit()

    def _update_sample_max_size(self):
        """Limit number of instances to input size unless using replacement."""
        if not self.data or self.replacement:
            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)
        else:
            self.sampleSizeSpin.setMaximum(len(self.data))

    def commit(self):
        if self.data is None:
            sample = other = None
            self.sampled_instances = self.remaining_instances = None
            self.outputInfoLabel.setText("")
        elif isinstance(self.data, SqlTable):
            other = None
            if self.sampling_type == self.SqlProportion:
                sample = self.data.sample_percentage(
                    self.sampleSizeSqlPercentage, no_cache=True)
            else:
                sample = self.data.sample_time(
                    self.sampleSizeSqlTime, no_cache=True)
            if self.sql_dl:
                sample.download_data()
                sample = Table(sample)

        else:
            if self.indices is None or not self.use_seed:
                self.updateindices()
                if self.indices is None:
                    return
            if self.sampling_type in (
                    self.FixedProportion, self.FixedSize, self.Bootstrap):
                remaining, sample = self.indices
                self.outputInfoLabel.setText(
                    'Outputting %d instance%s.' %
                    (len(sample), "s" * (len(sample) != 1)))
            elif self.sampling_type == self.CrossValidation:
                remaining, sample = self.indices[self.selectedFold - 1]
                self.outputInfoLabel.setText(
                    'Outputting fold %d, %d instance%s.' %
                    (self.selectedFold, len(sample), "s" * (len(sample) != 1))
                )
            sample = self.data[sample]
            other = self.data[remaining]
            self.sampled_instances = len(sample)
            self.remaining_instances = len(other)
        self.Outputs.data_sample.send(sample)
        self.Outputs.remaining_data.send(other)

    def updateindices(self):
        self.Error.clear()
        self.Warning.clear()
        repl = True
        data_length = len(self.data)
        num_classes = len(self.data.domain.class_var.values) \
            if self.data.domain.has_discrete_class else 0

        size = None
        if not data_length:
            self.Error.no_data()
        elif self.sampling_type == self.FixedSize:
            size = self.sampleSizeNumber
            repl = self.replacement
        elif self.sampling_type == self.FixedProportion:
            size = np.ceil(self.sampleSizePercentage / 100 * data_length)
            repl = False
        elif self.sampling_type == self.CrossValidation:
            if data_length < self.number_of_folds:
                self.Error.too_many_folds()
        else:
            assert self.sampling_type == self.Bootstrap

        if not repl and size is not None and (size > data_length):
            self.Error.sample_larger_than_data()
        if not repl and data_length <= num_classes and self.stratify:
            self.Error.not_enough_to_stratify()

        if self.Error.active:
            self.indices = None
            return

        # By the above, we can safely assume there is data
        if self.sampling_type == self.FixedSize and repl and size and \
                size > len(self.data):
            # This should only be possible when using replacement
            self.Warning.bigger_sample()

        stratified = (self.stratify and
                      isinstance(self.data, Table) and
                      self.data.domain.has_discrete_class)
        try:
            self.indices = self.sample(data_length, size, stratified)
        except ValueError as ex:
            self.Warning.could_not_stratify(str(ex))
            self.indices = self.sample(data_length, size, stratified=False)

    def sample(self, data_length, size, stratified):
        rnd = self.RandomSeed if self.use_seed else None
        if self.sampling_type == self.FixedSize:
            sampler = SampleRandomN(
                size, stratified=stratified, replace=self.replacement,
                random_state=rnd)
        elif self.sampling_type == self.FixedProportion:
            sampler = SampleRandomP(
                self.sampleSizePercentage / 100, stratified=stratified,
                random_state=rnd)
        elif self.sampling_type == self.Bootstrap:
            sampler = SampleBootstrap(data_length, random_state=rnd)
        else:
            sampler = SampleFoldIndices(
                self.number_of_folds, stratified=stratified, random_state=rnd)
        return sampler(self.data)

    def send_report(self):
        if self.sampling_type == self.FixedProportion:
            tpe = "Random sample with {} % of data".format(
                self.sampleSizePercentage)
        elif self.sampling_type == self.FixedSize:
            if self.sampleSizeNumber == 1:
                tpe = "Random data instance"
            else:
                tpe = "Random sample with {} data instances".format(
                    self.sampleSizeNumber)
                if self.replacement:
                    tpe += ", with replacement"
        elif self.sampling_type == self.CrossValidation:
            tpe = "Fold {} of {}-fold cross-validation".format(
                self.selectedFold, self.number_of_folds)
        else:
            tpe = "Undefined"  # should not come here at all
        if self.stratify:
            tpe += ", stratified (if possible)"
        if self.use_seed:
            tpe += ", deterministic"
        items = [("Sampling type", tpe)]
        if self.sampled_instances is not None:
            items += [
                ("Input", "{} instances".format(len(self.data))),
                ("Sample", "{} instances".format(self.sampled_instances)),
                ("Remaining", "{} instances".format(self.remaining_instances)),
            ]
        self.report_items(items)


class SampleFoldIndices(Reprable):
    def __init__(self, folds=10, stratified=False, random_state=None):
        """Samples data based on a number of folds.

        Args:
            folds (int): Number of folds
            stratified (bool): Return stratified indices (if applicable).
            random_state (Random): An initial state for replicable random
            behavior

        Returns:
            tuple-of-arrays: A tuple of array indices one for each fold.

        """
        self.folds = folds
        self.stratified = stratified
        self.random_state = random_state

    def __call__(self, table):
        if self.stratified and table.domain.has_discrete_class:
            splitter = skl.StratifiedKFold(
                self.folds, random_state=self.random_state)
            splitter.get_n_splits(table.X, table.Y)
            ind = splitter.split(table.X, table.Y)
        else:
            splitter = skl.KFold(
                self.folds, random_state=self.random_state)
            splitter.get_n_splits(table)
            ind = splitter.split(table)
        return tuple(ind)


class SampleRandomN(Reprable):
    def __init__(self, n=0, stratified=False, replace=False,
                 random_state=None):
        self.n = n
        self.stratified = stratified
        self.replace = replace
        self.random_state = random_state

    def __call__(self, table):
        if self.replace:
            # pylint: disable=no-member
            rgen = np.random.RandomState(self.random_state)
            sample = rgen.randint(0, len(table), self.n)
            o = np.ones(len(table))
            o[sample] = 0
            others = np.nonzero(o)[0]
            return others, sample
        if self.n == len(table):
            rgen = np.random.RandomState(self.random_state)
            sample = np.arange(self.n)
            rgen.shuffle(sample)
            return np.array([], dtype=int), sample
        elif self.stratified and table.domain.has_discrete_class:
            test_size = max(len(table.domain.class_var.values), self.n)
            splitter = skl.StratifiedShuffleSplit(
                n_splits=1, test_size=test_size,
                train_size=len(table) - test_size,
                random_state=self.random_state)
            splitter.get_n_splits(table.X, table.Y)
            ind = splitter.split(table.X, table.Y)
        else:
            splitter = skl.ShuffleSplit(
                n_splits=1, test_size=self.n, random_state=self.random_state)
            splitter.get_n_splits(table)
            ind = splitter.split(table)
        return next(iter(ind))


class SampleRandomP(Reprable):
    def __init__(self, p=0, stratified=False, random_state=None):
        self.p = p
        self.stratified = stratified
        self.random_state = random_state

    def __call__(self, table):
        n = int(math.ceil(len(table) * self.p))
        return SampleRandomN(n, self.stratified,
                             random_state=self.random_state)(table)


class SampleBootstrap(Reprable):
    def __init__(self, size=0, random_state=None):
        self.size = size
        self.random_state = random_state

    def __call__(self, table=None):
        """Bootstrap indices

        Args:
            table: Not used (but part of the signature)
        Returns:
            tuple (out_of_sample, sample) indices
        """
        # pylint: disable=no-member
        rgen = np.random.RandomState(self.random_state)
        sample = rgen.randint(0, self.size, self.size)
        sample.sort()  # not needed for the code below, just for the user
        insample = np.ones((self.size,), dtype=np.bool)
        insample[sample] = False
        remaining = np.flatnonzero(insample)
        return remaining, sample


if __name__ == "__main__":  # pragma: no cover
    WidgetPreview(OWDataSampler).run(Table("iris"))

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
[ISSUE]
**Title:** Status Bar Fails to Update Output Summary After Bootstrapping

**Description:**
After selecting the bootstrap sampling type and providing input data, the status bar is expected to display the number of sampled instances. However, the status bar does not update as expected, leaving it blank or showing incorrect information.

**Example Code:**
```python
widget = OWDataSampler()
widget.select_sampling_type('Bootstrap')
widget.send_signal('Data', iris_dataset)

# Expected: Status bar shows "150 instances sampled."
# Actual: Status bar remains blank or does not display the correct number.
```

**Expected Behavior:**
Upon performing bootstrap sampling, the status bar should accurately display the number of sampled instances, such as "150 instances sampled."

**Actual Behavior:**
The status bar does not update to reflect the number of sampled instances, resulting in no information being shown or incorrect data being displayed.
[/ISSUE]
{
    "TestOWDataSampler.test_bigger_output_warning": "PASSED",
    "TestOWDataSampler.test_bigger_size_with_replacement": "PASSED",
    "TestOWDataSampler.test_bigger_size_without_replacement": "PASSED",
    "TestOWDataSampler.test_bootstrap": "PASSED",
    "TestOWDataSampler.test_image_export": "PASSED",
    "TestOWDataSampler.test_minimum_size": "PASSED",
    "TestOWDataSampler.test_msg_base_class": "PASSED",
    "TestOWDataSampler.test_shuffling": "PASSED",
    "TestOWDataSampler.test_stratified_on_unbalanced_data": "PASSED",
    "TestOWDataSampler.test_summary": "PASSED",
    "TestOWDataSampler.test_error_message": "FAILED",
    "TestOWDataSampler.test_no_intersection_in_outputs": "FAILED"
}
diff --git a/Orange/widgets/data/owdatasampler.py b/Orange/widgets/data/owdatasampler.py
index cda524f64..74174d541 100644
--- a/Orange/widgets/data/owdatasampler.py
+++ b/Orange/widgets/data/owdatasampler.py
@@ -70,9 +70,8 @@ class OWDataSampler(OWWidget):
         self.indices = None
         self.sampled_instances = self.remaining_instances = None
 
-        box = gui.vBox(self.controlArea, "Information")
-        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')
-        self.outputInfoLabel = gui.widgetLabel(box, ' ')
+        self.info.set_input_summary(self.info.NoInput)
+        self.info.set_output_summary(self.info.NoInput)
 
         self.sampling_box = gui.vBox(self.controlArea, "Sampling Type")
         sampling = gui.radioButtons(self.sampling_box, self, "sampling_type",
@@ -180,16 +179,14 @@ class OWDataSampler(OWWidget):
             self.cb_seed.setVisible(not sql)
             self.cb_stratify.setVisible(not sql)
             self.cb_sql_dl.setVisible(sql)
-            self.dataInfoLabel.setText(
-                '{}{} instances in input dataset.'.format(*(
-                    ('~', dataset.approx_len()) if sql else
-                    ('', len(dataset)))))
+            self.info.set_input_summary(str(len(dataset)))
+
             if not sql:
                 self._update_sample_max_size()
                 self.updateindices()
         else:
-            self.dataInfoLabel.setText('No data on input.')
-            self.outputInfoLabel.setText('')
+            self.info.set_input_summary(self.info.NoInput)
+            self.info.set_output_summary(self.info.NoInput)
             self.indices = None
             self.clear_messages()
         self.commit()
@@ -205,7 +202,6 @@ class OWDataSampler(OWWidget):
         if self.data is None:
             sample = other = None
             self.sampled_instances = self.remaining_instances = None
-            self.outputInfoLabel.setText("")
         elif isinstance(self.data, SqlTable):
             other = None
             if self.sampling_type == self.SqlProportion:
@@ -226,15 +222,10 @@ class OWDataSampler(OWWidget):
             if self.sampling_type in (
                     self.FixedProportion, self.FixedSize, self.Bootstrap):
                 remaining, sample = self.indices
-                self.outputInfoLabel.setText(
-                    'Outputting %d instance%s.' %
-                    (len(sample), "s" * (len(sample) != 1)))
             elif self.sampling_type == self.CrossValidation:
                 remaining, sample = self.indices[self.selectedFold - 1]
-                self.outputInfoLabel.setText(
-                    'Outputting fold %d, %d instance%s.' %
-                    (self.selectedFold, len(sample), "s" * (len(sample) != 1))
-                )
+            self.info.set_output_summary(str(len(sample)))
+
             sample = self.data[sample]
             other = self.data[remaining]
             self.sampled_instances = len(sample)

{"Orange/widgets/data/owdatasampler.py": "import math\n\nfrom AnyQt.QtWidgets import QFormLayout\nfrom AnyQt.QtCore import Qt\n\nimport numpy as np\nimport sklearn.model_selection as skl\n\nfrom Orange.widgets import gui\nfrom Orange.widgets.settings import Setting\nfrom Orange.data import Table\nfrom Orange.data.sql.table import SqlTable\nfrom Orange.widgets.utils.widgetpreview import WidgetPreview\nfrom Orange.widgets.widget import Msg, OWWidget, Input, Output\nfrom Orange.util import Reprable\n\n\nclass OWDataSampler(OWWidget):\n    name = \"Data Sampler\"\n    description = \"Randomly draw a subset of data points \" \\\n                  \"from the input dataset.\"\n    icon = \"icons/DataSampler.svg\"\n    priority = 100\n    category = \"Data\"\n    keywords = [\"random\"]\n\n    _MAX_SAMPLE_SIZE = 2 ** 31 - 1\n\n    class Inputs:\n        data = Input(\"Data\", Table)\n\n    class Outputs:\n        data_sample = Output(\"Data Sample\", Table, default=True)\n        remaining_data = Output(\"Remaining Data\", Table)\n\n    want_main_area = False\n    resizing_enabled = False\n\n    RandomSeed = 42\n    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)\n    SqlTime, SqlProportion = range(2)\n\n    selectedFold: int\n\n    use_seed = Setting(True)\n    replacement = Setting(False)\n    stratify = Setting(False)\n    sql_dl = Setting(False)\n    sampling_type = Setting(FixedProportion)\n    sampleSizeNumber = Setting(1)\n    sampleSizePercentage = Setting(70)\n    sampleSizeSqlTime = Setting(1)\n    sampleSizeSqlPercentage = Setting(0.1)\n    number_of_folds = Setting(10)\n    selectedFold = Setting(1)\n\n    class Warning(OWWidget.Warning):\n        could_not_stratify = Msg(\"Stratification failed\\n{}\")\n        bigger_sample = Msg('Sample is bigger than input')\n\n    class Error(OWWidget.Error):\n        too_many_folds = Msg(\"Number of folds exceeds data size\")\n        sample_larger_than_data = Msg(\"Sample can't be larger than data\")\n        not_enough_to_stratify = Msg(\"Data is too small to stratify\")\n        no_data = Msg(\"Dataset is empty\")\n\n    def __init__(self):\n        super().__init__()\n        self.data = None\n        self.indices = None\n        self.sampled_instances = self.remaining_instances = None\n\n        box = gui.vBox(self.controlArea, \"Information\")\n        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')\n        self.outputInfoLabel = gui.widgetLabel(box, ' ')\n\n        self.sampling_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sampling_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n\n        def set_sampling_type(i):\n            def set_sampling_type_i():\n                self.sampling_type = i\n                self.sampling_type_changed()\n            return set_sampling_type_i\n\n        gui.appendRadioButton(sampling, \"Fixed proportion of data:\")\n        self.sampleSizePercentageSlider = gui.hSlider(\n            gui.indentedBox(sampling), self,\n            \"sampleSizePercentage\",\n            minValue=0, maxValue=100, ticks=10, labelFormat=\"%d %%\",\n            callback=set_sampling_type(self.FixedProportion),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Fixed sample size\")\n        ibox = gui.indentedBox(sampling)\n        self.sampleSizeSpin = gui.spin(\n            ibox, self, \"sampleSizeNumber\", label=\"Instances: \",\n            minv=1, maxv=self._MAX_SAMPLE_SIZE,\n            callback=set_sampling_type(self.FixedSize),\n            controlWidth=90)\n        gui.checkBox(\n            ibox, self, \"replacement\", \"Sample with replacement\",\n            callback=set_sampling_type(self.FixedSize),\n            addSpace=12)\n\n        gui.appendRadioButton(sampling, \"Cross validation\")\n        form = QFormLayout(\n            formAlignment=Qt.AlignLeft | Qt.AlignTop,\n            labelAlignment=Qt.AlignLeft,\n            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)\n        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)\n        form.addRow(\"Number of folds:\",\n                    gui.spin(\n                        ibox, self, \"number_of_folds\", 2, 100,\n                        addToLayout=False,\n                        callback=self.number_of_folds_changed))\n        self.selected_fold_spin = gui.spin(\n            ibox, self, \"selectedFold\", 1, self.number_of_folds,\n            addToLayout=False, callback=self.fold_changed)\n        form.addRow(\"Selected fold:\", self.selected_fold_spin)\n\n        gui.appendRadioButton(sampling, \"Bootstrap\")\n\n        self.sql_box = gui.vBox(self.controlArea, \"Sampling Type\")\n        sampling = gui.radioButtons(self.sql_box, self, \"sampling_type\",\n                                    callback=self.sampling_type_changed)\n        gui.appendRadioButton(sampling, \"Time:\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlTime\", minv=1, maxv=3600,\n                        callback=set_sampling_type(self.SqlTime))\n        spin.setSuffix(\" sec\")\n        gui.appendRadioButton(sampling, \"Percentage\")\n        ibox = gui.indentedBox(sampling)\n        spin = gui.spin(ibox, self, \"sampleSizeSqlPercentage\", spinType=float,\n                        minv=0.0001, maxv=100, step=0.1, decimals=4,\n                        callback=set_sampling_type(self.SqlProportion))\n        spin.setSuffix(\" %\")\n        self.sql_box.setVisible(False)\n\n        self.options_box = gui.vBox(self.controlArea, \"Options\")\n        self.cb_seed = gui.checkBox(\n            self.options_box, self, \"use_seed\",\n            \"Replicable (deterministic) sampling\",\n            callback=self.settings_changed)\n        self.cb_stratify = gui.checkBox(\n            self.options_box, self, \"stratify\",\n            \"Stratify sample (when possible)\", callback=self.settings_changed)\n        self.cb_sql_dl = gui.checkBox(\n            self.options_box, self, \"sql_dl\", \"Download data to local memory\",\n            callback=self.settings_changed)\n        self.cb_sql_dl.setVisible(False)\n\n        gui.button(self.buttonsArea, self, \"Sample Data\",\n                   callback=self.commit)\n\n    def sampling_type_changed(self):\n        self.settings_changed()\n\n    def number_of_folds_changed(self):\n        self.selected_fold_spin.setMaximum(self.number_of_folds)\n        self.sampling_type = self.CrossValidation\n        self.settings_changed()\n\n    def fold_changed(self):\n        # a separate callback - if we decide to cache indices\n        self.sampling_type = self.CrossValidation\n\n    def settings_changed(self):\n        self._update_sample_max_size()\n        self.indices = None\n\n    @Inputs.data\n    def set_data(self, dataset):\n        self.data = dataset\n        if dataset is not None:\n            sql = isinstance(dataset, SqlTable)\n            self.sampling_box.setVisible(not sql)\n            self.sql_box.setVisible(sql)\n            self.cb_seed.setVisible(not sql)\n            self.cb_stratify.setVisible(not sql)\n            self.cb_sql_dl.setVisible(sql)\n            self.dataInfoLabel.setText(\n                '{}{} instances in input dataset.'.format(*(\n                    ('~', dataset.approx_len()) if sql else\n                    ('', len(dataset)))))\n            if not sql:\n                self._update_sample_max_size()\n                self.updateindices()\n        else:\n            self.dataInfoLabel.setText('No data on input.')\n            self.outputInfoLabel.setText('')\n            self.indices = None\n            self.clear_messages()\n        self.commit()\n\n    def _update_sample_max_size(self):\n        \"\"\"Limit number of instances to input size unless using replacement.\"\"\"\n        if not self.data or self.replacement:\n            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)\n        else:\n            self.sampleSizeSpin.setMaximum(len(self.data))\n\n    def commit(self):\n        if self.data is None:\n            sample = other = None\n            self.sampled_instances = self.remaining_instances = None\n            self.outputInfoLabel.setText(\"\")\n        elif isinstance(self.data, SqlTable):\n            other = None\n            if self.sampling_type == self.SqlProportion:\n                sample = self.data.sample_percentage(\n                    self.sampleSizeSqlPercentage, no_cache=True)\n            else:\n                sample = self.data.sample_time(\n                    self.sampleSizeSqlTime, no_cache=True)\n            if self.sql_dl:\n                sample.download_data()\n                sample = Table(sample)\n\n        else:\n            if self.indices is None or not self.use_seed:\n                self.updateindices()\n                if self.indices is None:\n                    return\n            if self.sampling_type in (\n                    self.FixedProportion, self.FixedSize, self.Bootstrap):\n                remaining, sample = self.indices\n                self.outputInfoLabel.setText(\n                    'Outputting %d instance%s.' %\n                    (len(sample), \"s\" * (len(sample) != 1)))\n            elif self.sampling_type == self.CrossValidation:\n                remaining, sample = self.indices[self.selectedFold - 1]\n                self.outputInfoLabel.setText(\n                    'Outputting fold %d, %d instance%s.' %\n                    (self.selectedFold, len(sample), \"s\" * (len(sample) != 1))\n                )\n            sample = self.data[sample]\n            other = self.data[remaining]\n            self.sampled_instances = len(sample)\n            self.remaining_instances = len(other)\n        self.Outputs.data_sample.send(sample)\n        self.Outputs.remaining_data.send(other)\n\n    def updateindices(self):\n        self.Error.clear()\n        self.Warning.clear()\n        repl = True\n        data_length = len(self.data)\n        num_classes = len(self.data.domain.class_var.values) \\\n            if self.data.domain.has_discrete_class else 0\n\n        size = None\n        if not data_length:\n            self.Error.no_data()\n        elif self.sampling_type == self.FixedSize:\n            size = self.sampleSizeNumber\n            repl = self.replacement\n        elif self.sampling_type == self.FixedProportion:\n            size = np.ceil(self.sampleSizePercentage / 100 * data_length)\n            repl = False\n        elif self.sampling_type == self.CrossValidation:\n            if data_length < self.number_of_folds:\n                self.Error.too_many_folds()\n        else:\n            assert self.sampling_type == self.Bootstrap\n\n        if not repl and size is not None and (size > data_length):\n            self.Error.sample_larger_than_data()\n        if not repl and data_length <= num_classes and self.stratify:\n            self.Error.not_enough_to_stratify()\n\n        if self.Error.active:\n            self.indices = None\n            return\n\n        # By the above, we can safely assume there is data\n        if self.sampling_type == self.FixedSize and repl and size and \\\n                size > len(self.data):\n            # This should only be possible when using replacement\n            self.Warning.bigger_sample()\n\n        stratified = (self.stratify and\n                      isinstance(self.data, Table) and\n                      self.data.domain.has_discrete_class)\n        try:\n            self.indices = self.sample(data_length, size, stratified)\n        except ValueError as ex:\n            self.Warning.could_not_stratify(str(ex))\n            self.indices = self.sample(data_length, size, stratified=False)\n\n    def sample(self, data_length, size, stratified):\n        rnd = self.RandomSeed if self.use_seed else None\n        if self.sampling_type == self.FixedSize:\n            sampler = SampleRandomN(\n                size, stratified=stratified, replace=self.replacement,\n                random_state=rnd)\n        elif self.sampling_type == self.FixedProportion:\n            sampler = SampleRandomP(\n                self.sampleSizePercentage / 100, stratified=stratified,\n                random_state=rnd)\n        elif self.sampling_type == self.Bootstrap:\n            sampler = SampleBootstrap(data_length, random_state=rnd)\n        else:\n            sampler = SampleFoldIndices(\n                self.number_of_folds, stratified=stratified, random_state=rnd)\n        return sampler(self.data)\n\n    def send_report(self):\n        if self.sampling_type == self.FixedProportion:\n            tpe = \"Random sample with {} % of data\".format(\n                self.sampleSizePercentage)\n        elif self.sampling_type == self.FixedSize:\n            if self.sampleSizeNumber == 1:\n                tpe = \"Random data instance\"\n            else:\n                tpe = \"Random sample with {} data instances\".format(\n                    self.sampleSizeNumber)\n                if self.replacement:\n                    tpe += \", with replacement\"\n        elif self.sampling_type == self.CrossValidation:\n            tpe = \"Fold {} of {}-fold cross-validation\".format(\n                self.selectedFold, self.number_of_folds)\n        else:\n            tpe = \"Undefined\"  # should not come here at all\n        if self.stratify:\n            tpe += \", stratified (if possible)\"\n        if self.use_seed:\n            tpe += \", deterministic\"\n        items = [(\"Sampling type\", tpe)]\n        if self.sampled_instances is not None:\n            items += [\n                (\"Input\", \"{} instances\".format(len(self.data))),\n                (\"Sample\", \"{} instances\".format(self.sampled_instances)),\n                (\"Remaining\", \"{} instances\".format(self.remaining_instances)),\n            ]\n        self.report_items(items)\n\n\nclass SampleFoldIndices(Reprable):\n    def __init__(self, folds=10, stratified=False, random_state=None):\n        \"\"\"Samples data based on a number of folds.\n\n        Args:\n            folds (int): Number of folds\n            stratified (bool): Return stratified indices (if applicable).\n            random_state (Random): An initial state for replicable random\n            behavior\n\n        Returns:\n            tuple-of-arrays: A tuple of array indices one for each fold.\n\n        \"\"\"\n        self.folds = folds\n        self.stratified = stratified\n        self.random_state = random_state\n\n    def __call__(self, table):\n        if self.stratified and table.domain.has_discrete_class:\n            splitter = skl.StratifiedKFold(\n                self.folds, random_state=self.random_state)\n            splitter.get_n_splits(table.X, table.Y)\n            ind = splitter.split(table.X, table.Y)\n        else:\n            splitter = skl.KFold(\n                self.folds, random_state=self.random_state)\n            splitter.get_n_splits(table)\n            ind = splitter.split(table)\n        return tuple(ind)\n\n\nclass SampleRandomN(Reprable):\n    def __init__(self, n=0, stratified=False, replace=False,\n                 random_state=None):\n        self.n = n\n        self.stratified = stratified\n        self.replace = replace\n        self.random_state = random_state\n\n    def __call__(self, table):\n        if self.replace:\n            # pylint: disable=no-member\n            rgen = np.random.RandomState(self.random_state)\n            sample = rgen.randint(0, len(table), self.n)\n            o = np.ones(len(table))\n            o[sample] = 0\n            others = np.nonzero(o)[0]\n            return others, sample\n        if self.n == len(table):\n            rgen = np.random.RandomState(self.random_state)\n            sample = np.arange(self.n)\n            rgen.shuffle(sample)\n            return np.array([], dtype=int), sample\n        elif self.stratified and table.domain.has_discrete_class:\n            test_size = max(len(table.domain.class_var.values), self.n)\n            splitter = skl.StratifiedShuffleSplit(\n                n_splits=1, test_size=test_size,\n                train_size=len(table) - test_size,\n                random_state=self.random_state)\n            splitter.get_n_splits(table.X, table.Y)\n            ind = splitter.split(table.X, table.Y)\n        else:\n            splitter = skl.ShuffleSplit(\n                n_splits=1, test_size=self.n, random_state=self.random_state)\n            splitter.get_n_splits(table)\n            ind = splitter.split(table)\n        return next(iter(ind))\n\n\nclass SampleRandomP(Reprable):\n    def __init__(self, p=0, stratified=False, random_state=None):\n        self.p = p\n        self.stratified = stratified\n        self.random_state = random_state\n\n    def __call__(self, table):\n        n = int(math.ceil(len(table) * self.p))\n        return SampleRandomN(n, self.stratified,\n                             random_state=self.random_state)(table)\n\n\nclass SampleBootstrap(Reprable):\n    def __init__(self, size=0, random_state=None):\n        self.size = size\n        self.random_state = random_state\n\n    def __call__(self, table=None):\n        \"\"\"Bootstrap indices\n\n        Args:\n            table: Not used (but part of the signature)\n        Returns:\n            tuple (out_of_sample, sample) indices\n        \"\"\"\n        # pylint: disable=no-member\n        rgen = np.random.RandomState(self.random_state)\n        sample = rgen.randint(0, self.size, self.size)\n        sample.sort()  # not needed for the code below, just for the user\n        insample = np.ones((self.size,), dtype=np.bool)\n        insample[sample] = False\n        remaining = np.flatnonzero(insample)\n        return remaining, sample\n\n\nif __name__ == \"__main__\":  # pragma: no cover\n    WidgetPreview(OWDataSampler).run(Table(\"iris\"))\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

Your response format must follow the template below:
<think>
Your thoughts or/and draft, like working through an exercise on scratch paper. Be as casual and as long as you want until you are confident to generate a correct solution.
</think>
<solution>
Final solution presented to the user.
</solution>
system
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** Status Bar Fails to Update Output Summary After Bootstrapping

**Description:**
After selecting the bootstrap sampling type and providing input data, the status bar is expected to display the number of sampled instances. However, the status bar does not update as expected, leaving it blank or showing incorrect information.

**Example Code:**
```python
widget = OWDataSampler()
widget.select_sampling_type('Bootstrap')
widget.send_signal('Data', iris_dataset)

# Expected: Status bar shows "150 instances sampled."
# Actual: Status bar remains blank or does not display the correct number.
```

**Expected Behavior:**
Upon performing bootstrap sampling, the status bar should accurately display the number of sampled instances, such as "150 instances sampled."

**Actual Behavior:**
The status bar does not update to reflect the number of sampled instances, resulting in no information being shown or incorrect data being displayed.
[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### Orange/widgets/data/owdatasampler.py
import math

from AnyQt.QtWidgets import QFormLayout
from AnyQt.QtCore import Qt

import numpy as np
import sklearn.model_selection as skl

from Orange.widgets import gui
from Orange.widgets.settings import Setting
from Orange.data import Table
from Orange.data.sql.table import SqlTable
from Orange.widgets.utils.widgetpreview import WidgetPreview
from Orange.widgets.widget import Msg, OWWidget, Input, Output
from Orange.util import Reprable


class OWDataSampler(OWWidget):
    name = "Data Sampler"
    description = "Randomly draw a subset of data points " \
                  "from the input dataset."
    icon = "icons/DataSampler.svg"
    priority = 100
    category = "Data"
    keywords = ["random"]

    _MAX_SAMPLE_SIZE = 2 ** 31 - 1

    class Inputs:
        data = Input("Data", Table)

    class Outputs:
        data_sample = Output("Data Sample", Table, default=True)
        remaining_data = Output("Remaining Data", Table)

    want_main_area = False
    resizing_enabled = False

    RandomSeed = 42
    FixedProportion, FixedSize, CrossValidation, Bootstrap = range(4)
    SqlTime, SqlProportion = range(2)

    selectedFold: int

    use_seed = Setting(True)
    replacement = Setting(False)
    stratify = Setting(False)
    sql_dl = Setting(False)
    sampling_type = Setting(FixedProportion)
    sampleSizeNumber = Setting(1)
    sampleSizePercentage = Setting(70)
    sampleSizeSqlTime = Setting(1)
    sampleSizeSqlPercentage = Setting(0.1)
    number_of_folds = Setting(10)
    selectedFold = Setting(1)

    class Warning(OWWidget.Warning):
        could_not_stratify = Msg("Stratification failed\n{}")
        bigger_sample = Msg('Sample is bigger than input')

    class Error(OWWidget.Error):
        too_many_folds = Msg("Number of folds exceeds data size")
        sample_larger_than_data = Msg("Sample can't be larger than data")
        not_enough_to_stratify = Msg("Data is too small to stratify")
        no_data = Msg("Dataset is empty")

    def __init__(self):
        super().__init__()
        self.data = None
        self.indices = None
        self.sampled_instances = self.remaining_instances = None

        box = gui.vBox(self.controlArea, "Information")
        self.dataInfoLabel = gui.widgetLabel(box, 'No data on input.')
        self.outputInfoLabel = gui.widgetLabel(box, ' ')

        self.sampling_box = gui.vBox(self.controlArea, "Sampling Type")
        sampling = gui.radioButtons(self.sampling_box, self, "sampling_type",
                                    callback=self.sampling_type_changed)

        def set_sampling_type(i):
            def set_sampling_type_i():
                self.sampling_type = i
                self.sampling_type_changed()
            return set_sampling_type_i

        gui.appendRadioButton(sampling, "Fixed proportion of data:")
        self.sampleSizePercentageSlider = gui.hSlider(
            gui.indentedBox(sampling), self,
            "sampleSizePercentage",
            minValue=0, maxValue=100, ticks=10, labelFormat="%d %%",
            callback=set_sampling_type(self.FixedProportion),
            addSpace=12)

        gui.appendRadioButton(sampling, "Fixed sample size")
        ibox = gui.indentedBox(sampling)
        self.sampleSizeSpin = gui.spin(
            ibox, self, "sampleSizeNumber", label="Instances: ",
            minv=1, maxv=self._MAX_SAMPLE_SIZE,
            callback=set_sampling_type(self.FixedSize),
            controlWidth=90)
        gui.checkBox(
            ibox, self, "replacement", "Sample with replacement",
            callback=set_sampling_type(self.FixedSize),
            addSpace=12)

        gui.appendRadioButton(sampling, "Cross validation")
        form = QFormLayout(
            formAlignment=Qt.AlignLeft | Qt.AlignTop,
            labelAlignment=Qt.AlignLeft,
            fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow)
        ibox = gui.indentedBox(sampling, addSpace=True, orientation=form)
        form.addRow("Number of folds:",
                    gui.spin(
                        ibox, self, "number_of_folds", 2, 100,
                        addToLayout=False,
                        callback=self.number_of_folds_changed))
        self.selected_fold_spin = gui.spin(
            ibox, self, "selectedFold", 1, self.number_of_folds,
            addToLayout=False, callback=self.fold_changed)
        form.addRow("Selected fold:", self.selected_fold_spin)

        gui.appendRadioButton(sampling, "Bootstrap")

        self.sql_box = gui.vBox(self.controlArea, "Sampling Type")
        sampling = gui.radioButtons(self.sql_box, self, "sampling_type",
                                    callback=self.sampling_type_changed)
        gui.appendRadioButton(sampling, "Time:")
        ibox = gui.indentedBox(sampling)
        spin = gui.spin(ibox, self, "sampleSizeSqlTime", minv=1, maxv=3600,
                        callback=set_sampling_type(self.SqlTime))
        spin.setSuffix(" sec")
        gui.appendRadioButton(sampling, "Percentage")
        ibox = gui.indentedBox(sampling)
        spin = gui.spin(ibox, self, "sampleSizeSqlPercentage", spinType=float,
                        minv=0.0001, maxv=100, step=0.1, decimals=4,
                        callback=set_sampling_type(self.SqlProportion))
        spin.setSuffix(" %")
        self.sql_box.setVisible(False)

        self.options_box = gui.vBox(self.controlArea, "Options")
        self.cb_seed = gui.checkBox(
            self.options_box, self, "use_seed",
            "Replicable (deterministic) sampling",
            callback=self.settings_changed)
        self.cb_stratify = gui.checkBox(
            self.options_box, self, "stratify",
            "Stratify sample (when possible)", callback=self.settings_changed)
        self.cb_sql_dl = gui.checkBox(
            self.options_box, self, "sql_dl", "Download data to local memory",
            callback=self.settings_changed)
        self.cb_sql_dl.setVisible(False)

        gui.button(self.buttonsArea, self, "Sample Data",
                   callback=self.commit)

    def sampling_type_changed(self):
        self.settings_changed()

    def number_of_folds_changed(self):
        self.selected_fold_spin.setMaximum(self.number_of_folds)
        self.sampling_type = self.CrossValidation
        self.settings_changed()

    def fold_changed(self):
        # a separate callback - if we decide to cache indices
        self.sampling_type = self.CrossValidation

    def settings_changed(self):
        self._update_sample_max_size()
        self.indices = None

    @Inputs.data
    def set_data(self, dataset):
        self.data = dataset
        if dataset is not None:
            sql = isinstance(dataset, SqlTable)
            self.sampling_box.setVisible(not sql)
            self.sql_box.setVisible(sql)
            self.cb_seed.setVisible(not sql)
            self.cb_stratify.setVisible(not sql)
            self.cb_sql_dl.setVisible(sql)
            self.dataInfoLabel.setText(
                '{}{} instances in input dataset.'.format(*(
                    ('~', dataset.approx_len()) if sql else
                    ('', len(dataset)))))
            if not sql:
                self._update_sample_max_size()
                self.updateindices()
        else:
            self.dataInfoLabel.setText('No data on input.')
            self.outputInfoLabel.setText('')
            self.indices = None
            self.clear_messages()
        self.commit()

    def _update_sample_max_size(self):
        """Limit number of instances to input size unless using replacement."""
        if not self.data or self.replacement:
            self.sampleSizeSpin.setMaximum(self._MAX_SAMPLE_SIZE)
        else:
            self.sampleSizeSpin.setMaximum(len(self.data))

    def commit(self):
        if self.data is None:
            sample = other = None
            self.sampled_instances = self.remaining_instances = None
            self.outputInfoLabel.setText("")
        elif isinstance(self.data, SqlTable):
            other = None
            if self.sampling_type == self.SqlProportion:
                sample = self.data.sample_percentage(
                    self.sampleSizeSqlPercentage, no_cache=True)
            else:
                sample = self.data.sample_time(
                    self.sampleSizeSqlTime, no_cache=True)
            if self.sql_dl:
                sample.download_data()
                sample = Table(sample)

        else:
            if self.indices is None or not self.use_seed:
                self.updateindices()
                if self.indices is None:
                    return
            if self.sampling_type in (
                    self.FixedProportion, self.FixedSize, self.Bootstrap):
                remaining, sample = self.indices
                self.outputInfoLabel.setText(
                    'Outputting %d instance%s.' %
                    (len(sample), "s" * (len(sample) != 1)))
            elif self.sampling_type == self.CrossValidation:
                remaining, sample = self.indices[self.selectedFold - 1]
                self.outputInfoLabel.setText(
                    'Outputting fold %d, %d instance%s.' %
                    (self.selectedFold, len(sample), "s" * (len(sample) != 1))
                )
            sample = self.data[sample]
            other = self.data[remaining]
            self.sampled_instances = len(sample)
            self.remaining_instances = len(other)
        self.Outputs.data_sample.send(sample)
        self.Outputs.remaining_data.send(other)

    def updateindices(self):
        self.Error.clear()
        self.Warning.clear()
        repl = True
        data_length = len(self.data)
        num_classes = len(self.data.domain.class_var.values) \
            if self.data.domain.has_discrete_class else 0

        size = None
        if not data_length:
            self.Error.no_data()
        elif self.sampling_type == self.FixedSize:
            size = self.sampleSizeNumber
            repl = self.replacement
        elif self.sampling_type == self.FixedProportion:
            size = np.ceil(self.sampleSizePercentage / 100 * data_length)
            repl = False
        elif self.sampling_type == self.CrossValidation:
            if data_length < self.number_of_folds:
                self.Error.too_many_folds()
        else:
            assert self.sampling_type == self.Bootstrap

        if not repl and size is not None and (size > data_length):
            self.Error.sample_larger_than_data()
        if not repl and data_length <= num_classes and self.stratify:
            self.Error.not_enough_to_stratify()

        if self.Error.active:
            self.indices = None
            return

        # By the above, we can safely assume there is data
        if self.sampling_type == self.FixedSize and repl and size and \
                size > len(self.data):
            # This should only be possible when using replacement
            self.Warning.bigger_sample()

        stratified = (self.stratify and
                      isinstance(self.data, Table) and
                      self.data.domain.has_discrete_class)
        try:
            self.indices = self.sample(data_length, size, stratified)
        except ValueError as ex:
            self.Warning.could_not_stratify(str(ex))
            self.indices = self.sample(data_length, size, stratified=False)

    def sample(self, data_length, size, stratified):
        rnd = self.RandomSeed if self.use_seed else None
        if self.sampling_type == self.FixedSize:
            sampler = SampleRandomN(
                size, stratified=stratified, replace=self.replacement,
                random_state=rnd)
        elif self.sampling_type == self.FixedProportion:
            sampler = SampleRandomP(
                self.sampleSizePercentage / 100, stratified=stratified,
                random_state=rnd)
        elif self.sampling_type == self.Bootstrap:
            sampler = SampleBootstrap(data_length, random_state=rnd)
        else:
            sampler = SampleFoldIndices(
                self.number_of_folds, stratified=stratified, random_state=rnd)
        return sampler(self.data)

    def send_report(self):
        if self.sampling_type == self.FixedProportion:
            tpe = "Random sample with {} % of data".format(
                self.sampleSizePercentage)
        elif self.sampling_type == self.FixedSize:
            if self.sampleSizeNumber == 1:
                tpe = "Random data instance"
            else:
                tpe = "Random sample with {} data instances".format(
                    self.sampleSizeNumber)
                if self.replacement:
                    tpe += ", with replacement"
        elif self.sampling_type == self.CrossValidation:
            tpe = "Fold {} of {}-fold cross-validation".format(
                self.selectedFold, self.number_of_folds)
        else:
            tpe = "Undefined"  # should not come here at all
        if self.stratify:
            tpe += ", stratified (if possible)"
        if self.use_seed:
            tpe += ", deterministic"
        items = [("Sampling type", tpe)]
        if self.sampled_instances is not None:
            items += [
                ("Input", "{} instances".format(len(self.data))),
                ("Sample", "{} instances".format(self.sampled_instances)),
                ("Remaining", "{} instances".format(self.remaining_instances)),
            ]
        self.report_items(items)


class SampleFoldIndices(Reprable):
    def __init__(self, folds=10, stratified=False, random_state=None):
        """Samples data based on a number of folds.

        Args:
            folds (int): Number of folds
            stratified (bool): Return stratified indices (if applicable).
            random_state (Random): An initial state for replicable random
            behavior

        Returns:
            tuple-of-arrays: A tuple of array indices one for each fold.

        """
        self.folds = folds
        self.stratified = stratified
        self.random_state = random_state

    def __call__(self, table):
        if self.stratified and table.domain.has_discrete_class:
            splitter = skl.StratifiedKFold(
                self.folds, random_state=self.random_state)
            splitter.get_n_splits(table.X, table.Y)
            ind = splitter.split(table.X, table.Y)
        else:
            splitter = skl.KFold(
                self.folds, random_state=self.random_state)
            splitter.get_n_splits(table)
            ind = splitter.split(table)
        return tuple(ind)


class SampleRandomN(Reprable):
    def __init__(self, n=0, stratified=False, replace=False,
                 random_state=None):
        self.n = n
        self.stratified = stratified
        self.replace = replace
        self.random_state = random_state

    def __call__(self, table):
        if self.replace:
            # pylint: disable=no-member
            rgen = np.random.RandomState(self.random_state)
            sample = rgen.randint(0, len(table), self.n)
            o = np.ones(len(table))
            o[sample] = 0
            others = np.nonzero(o)[0]
            return others, sample
        if self.n == len(table):
            rgen = np.random.RandomState(self.random_state)
            sample = np.arange(self.n)
            rgen.shuffle(sample)
            return np.array([], dtype=int), sample
        elif self.stratified and table.domain.has_discrete_class:
            test_size = max(len(table.domain.class_var.values), self.n)
            splitter = skl.StratifiedShuffleSplit(
                n_splits=1, test_size=test_size,
                train_size=len(table) - test_size,
                random_state=self.random_state)
            splitter.get_n_splits(table.X, table.Y)
            ind = splitter.split(table.X, table.Y)
        else:
            splitter = skl.ShuffleSplit(
                n_splits=1, test_size=self.n, random_state=self.random_state)
            splitter.get_n_splits(table)
            ind = splitter.split(table)
        return next(iter(ind))


class SampleRandomP(Reprable):
    def __init__(self, p=0, stratified=False, random_state=None):
        self.p = p
        self.stratified = stratified
        self.random_state = random_state

    def __call__(self, table):
        n = int(math.ceil(len(table) * self.p))
        return SampleRandomN(n, self.stratified,
                             random_state=self.random_state)(table)


class SampleBootstrap(Reprable):
    def __init__(self, size=0, random_state=None):
        self.size = size
        self.random_state = random_state

    def __call__(self, table=None):
        """Bootstrap indices

        Args:
            table: Not used (but part of the signature)
        Returns:
            tuple (out_of_sample, sample) indices
        """
        # pylint: disable=no-member
        rgen = np.random.RandomState(self.random_state)
        sample = rgen.randint(0, self.size, self.size)
        sample.sort()  # not needed for the code below, just for the user
        insample = np.ones((self.size,), dtype=np.bool)
        insample[sample] = False
        remaining = np.flatnonzero(insample)
        return remaining, sample


if __name__ == "__main__":  # pragma: no cover
    WidgetPreview(OWDataSampler).run(Table("iris"))

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
user