{
    "file_diffs": [
        {
            "old_file_content": "\"\"\"Pandas DataFrame↔Table conversion helpers\"\"\"\nimport numpy as np\nimport pandas as pd\nfrom pandas.api.types import (\n    is_categorical_dtype, is_object_dtype,\n    is_datetime64_any_dtype, is_numeric_dtype,\n)\n\nfrom Orange.data import (\n    Table, Domain, DiscreteVariable, StringVariable, TimeVariable,\n    ContinuousVariable,\n)\n\n__all__ = ['table_from_frame']\n\n\ndef table_from_frame(df, *, force_nominal=False):\n    \"\"\"\n    Convert pandas.DataFrame to Orange.data.Table\n\n    Parameters\n    ----------\n    df : pandas.DataFrame\n    force_nominal : boolean\n        If True, interpret ALL string columns as nominal (DiscreteVariable).\n\n    Returns\n    -------\n    Table\n    \"\"\"\n\n    def _is_discrete(s):\n        return (is_categorical_dtype(s) or\n                is_object_dtype(s) and (force_nominal or\n                                        s.nunique() < s.size**.666))\n\n    def _is_datetime(s):\n        if is_datetime64_any_dtype(s):\n            return True\n        try:\n            if is_object_dtype(s):\n                pd.to_datetime(s, infer_datetime_format=True)\n                return True\n        except Exception:  # pylint: disable=broad-except\n            pass\n        return False\n\n    # If df index is not a simple RangeIndex (or similar), put it into data\n    if not (df.index.is_integer() and (df.index.is_monotonic_increasing or\n                                       df.index.is_monotonic_decreasing)):\n        df = df.reset_index()\n\n    attrs, metas = [], []\n    X, M = [], []\n\n    # Iter over columns\n    for name, s in df.items():\n        name = str(name)\n        if _is_discrete(s):\n            discrete = s.astype('category').cat\n            attrs.append(DiscreteVariable(name, discrete.categories.astype(str).tolist()))\n            X.append(discrete.codes.replace(-1, np.nan).values)\n        elif _is_datetime(s):\n            tvar = TimeVariable(name)\n            attrs.append(tvar)\n            s = pd.to_datetime(s, infer_datetime_format=True)\n            X.append(s.astype('str').replace('NaT', np.nan).map(tvar.parse).values)\n        elif is_numeric_dtype(s):\n            attrs.append(ContinuousVariable(name))\n            X.append(s.values)\n        else:\n            metas.append(StringVariable(name))\n            M.append(s.values.astype(object))\n\n    return Table.from_numpy(Domain(attrs, None, metas),\n                            np.column_stack(X) if X else np.empty((df.shape[0], 0)),\n                            None,\n                            np.column_stack(M) if M else None)\n",
            "new_file_content": "\"\"\"Pandas DataFrame↔Table conversion helpers\"\"\"\nimport numpy as np\nimport pandas as pd\nfrom pandas.api.types import (\n    is_categorical_dtype, is_object_dtype,\n    is_datetime64_any_dtype, is_numeric_dtype,\n)\n\nfrom Orange.data import (\n    Table, Domain, DiscreteVariable, StringVariable, TimeVariable,\n    ContinuousVariable,\n)\n\n__all__ = ['table_from_frame', 'table_to_frame']\n\n\ndef table_from_frame(df, *, force_nominal=False):\n    \"\"\"\n    Convert pandas.DataFrame to Orange.data.Table\n\n    Parameters\n    ----------\n    df : pandas.DataFrame\n    force_nominal : boolean\n        If True, interpret ALL string columns as nominal (DiscreteVariable).\n\n    Returns\n    -------\n    Table\n    \"\"\"\n\n    def _is_discrete(s):\n        return (is_categorical_dtype(s) or\n                is_object_dtype(s) and (force_nominal or\n                                        s.nunique() < s.size**.666))\n\n    def _is_datetime(s):\n        if is_datetime64_any_dtype(s):\n            return True\n        try:\n            if is_object_dtype(s):\n                pd.to_datetime(s, infer_datetime_format=True)\n                return True\n        except Exception:  # pylint: disable=broad-except\n            pass\n        return False\n\n    # If df index is not a simple RangeIndex (or similar), put it into data\n    if not (df.index.is_integer() and (df.index.is_monotonic_increasing or\n                                       df.index.is_monotonic_decreasing)):\n        df = df.reset_index()\n\n    attrs, metas = [], []\n    X, M = [], []\n\n    # Iter over columns\n    for name, s in df.items():\n        name = str(name)\n        if _is_discrete(s):\n            discrete = s.astype('category').cat\n            attrs.append(DiscreteVariable(name, discrete.categories.astype(str).tolist()))\n            X.append(discrete.codes.replace(-1, np.nan).values)\n        elif _is_datetime(s):\n            tvar = TimeVariable(name)\n            attrs.append(tvar)\n            s = pd.to_datetime(s, infer_datetime_format=True)\n            X.append(s.astype('str').replace('NaT', np.nan).map(tvar.parse).values)\n        elif is_numeric_dtype(s):\n            attrs.append(ContinuousVariable(name))\n            X.append(s.values)\n        else:\n            metas.append(StringVariable(name))\n            M.append(s.values.astype(object))\n\n    return Table.from_numpy(Domain(attrs, None, metas),\n                            np.column_stack(X) if X else np.empty((df.shape[0], 0)),\n                            None,\n                            np.column_stack(M) if M else None)\n\n\ndef table_to_frame(tab):\n    \"\"\"\n    Convert Orange.data.Table to pandas.DataFrame\n\n    Parameters\n    ----------\n    tab : Table\n\n    Returns\n    -------\n    pandas.DataFrame\n    \"\"\"\n    def _column_to_series(col, vals):\n        result = ()\n        if col.is_discrete:\n            codes = pd.Series(vals).fillna(-1).astype(int)\n            result = (col.name, pd.Categorical.from_codes(codes=codes, categories=col.values,\n                                                          ordered=col.ordered))\n        elif col.is_time:\n            result = (col.name, pd.to_datetime(vals, unit='s').to_series().reset_index()[0])\n        elif col.is_continuous:\n            dt = float\n            # np.nan are not compatible with int column\n            nan_values_in_column = [t for t in vals if np.isnan(t)]\n            if col.number_of_decimals == 0 and len(nan_values_in_column) == 0:\n                dt = int\n            result = (col.name, pd.Series(vals).astype(dt))\n        elif col.is_string:\n            result = (col.name, pd.Series(vals))\n        return result\n\n    def _columns_to_series(cols, vals):\n        return [_column_to_series(col, vals[:, i]) for i, col in enumerate(cols)]\n\n    x, y, metas = [], [], []\n    domain = tab.domain\n    if domain.attributes:\n        x = _columns_to_series(domain.attributes, tab.X)\n    if domain.class_vars:\n        y_values = tab.Y.reshape(tab.Y.shape[0], len(domain.class_vars))\n        y = _columns_to_series(domain.class_vars, y_values)\n    if domain.metas:\n        metas = _columns_to_series(domain.metas, tab.metas)\n    all_series = dict(x + y + metas)\n    original_column_order = [var.name for var in tab.domain.variables]\n    unsorted_columns_df = pd.DataFrame(all_series)\n    return unsorted_columns_df[original_column_order]\n",
            "header": {
                "file": {
                    "path": "Orange/data/pandas_compat.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "965b361ef",
                "new_commit_hash": "c8aaa9c85",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/Orange/data/pandas_compat.py"
            },
            "plus_file": {
                "path": "b/Orange/data/pandas_compat.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 11,
                            "length": 7
                        },
                        "new_range": {
                            "start": 11,
                            "length": 7
                        },
                        "section": "from Orange.data import ("
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    ContinuousVariable,",
                                "type": "context"
                            },
                            {
                                "content": ")",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "__all__ = ['table_from_frame']",
                                "type": "deleted"
                            },
                            {
                                "content": "__all__ = ['table_from_frame', 'table_to_frame']",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "def table_from_frame(df, *, force_nominal=False):",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [
                        {
                            "file_name": "Orange/data/pandas_compat.py",
                            "type": "statement",
                            "name": "",
                            "content": "__all__ = ['table_from_frame', 'table_to_frame']",
                            "ast_type_str": "Assign",
                            "start_lineno": 14,
                            "end_lineno": 14,
                            "parent": null
                        }
                    ],
                    "deleted_entities": [
                        {
                            "file_name": "Orange/data/pandas_compat.py",
                            "type": "statement",
                            "name": "",
                            "content": "__all__ = ['table_from_frame']",
                            "ast_type_str": "Assign",
                            "start_lineno": 14,
                            "end_lineno": 14,
                            "parent": null
                        }
                    ]
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 76,
                            "length": 3
                        },
                        "new_range": {
                            "start": 76,
                            "length": 52
                        },
                        "section": "def table_from_frame(df, *, force_nominal=False):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "                            np.column_stack(X) if X else np.empty((df.shape[0], 0)),",
                                "type": "context"
                            },
                            {
                                "content": "                            None,",
                                "type": "context"
                            },
                            {
                                "content": "                            np.column_stack(M) if M else None)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "def table_to_frame(tab):",
                                "type": "added"
                            },
                            {
                                "content": "    \"\"\"",
                                "type": "added"
                            },
                            {
                                "content": "    Convert Orange.data.Table to pandas.DataFrame",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    Parameters",
                                "type": "added"
                            },
                            {
                                "content": "    ----------",
                                "type": "added"
                            },
                            {
                                "content": "    tab : Table",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    Returns",
                                "type": "added"
                            },
                            {
                                "content": "    -------",
                                "type": "added"
                            },
                            {
                                "content": "    pandas.DataFrame",
                                "type": "added"
                            },
                            {
                                "content": "    \"\"\"",
                                "type": "added"
                            },
                            {
                                "content": "    def _column_to_series(col, vals):",
                                "type": "added"
                            },
                            {
                                "content": "        result = ()",
                                "type": "added"
                            },
                            {
                                "content": "        if col.is_discrete:",
                                "type": "added"
                            },
                            {
                                "content": "            codes = pd.Series(vals).fillna(-1).astype(int)",
                                "type": "added"
                            },
                            {
                                "content": "            result = (col.name, pd.Categorical.from_codes(codes=codes, categories=col.values,",
                                "type": "added"
                            },
                            {
                                "content": "                                                          ordered=col.ordered))",
                                "type": "added"
                            },
                            {
                                "content": "        elif col.is_time:",
                                "type": "added"
                            },
                            {
                                "content": "            result = (col.name, pd.to_datetime(vals, unit='s').to_series().reset_index()[0])",
                                "type": "added"
                            },
                            {
                                "content": "        elif col.is_continuous:",
                                "type": "added"
                            },
                            {
                                "content": "            dt = float",
                                "type": "added"
                            },
                            {
                                "content": "            # np.nan are not compatible with int column",
                                "type": "added"
                            },
                            {
                                "content": "            nan_values_in_column = [t for t in vals if np.isnan(t)]",
                                "type": "added"
                            },
                            {
                                "content": "            if col.number_of_decimals == 0 and len(nan_values_in_column) == 0:",
                                "type": "added"
                            },
                            {
                                "content": "                dt = int",
                                "type": "added"
                            },
                            {
                                "content": "            result = (col.name, pd.Series(vals).astype(dt))",
                                "type": "added"
                            },
                            {
                                "content": "        elif col.is_string:",
                                "type": "added"
                            },
                            {
                                "content": "            result = (col.name, pd.Series(vals))",
                                "type": "added"
                            },
                            {
                                "content": "        return result",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    def _columns_to_series(cols, vals):",
                                "type": "added"
                            },
                            {
                                "content": "        return [_column_to_series(col, vals[:, i]) for i, col in enumerate(cols)]",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    x, y, metas = [], [], []",
                                "type": "added"
                            },
                            {
                                "content": "    domain = tab.domain",
                                "type": "added"
                            },
                            {
                                "content": "    if domain.attributes:",
                                "type": "added"
                            },
                            {
                                "content": "        x = _columns_to_series(domain.attributes, tab.X)",
                                "type": "added"
                            },
                            {
                                "content": "    if domain.class_vars:",
                                "type": "added"
                            },
                            {
                                "content": "        y_values = tab.Y.reshape(tab.Y.shape[0], len(domain.class_vars))",
                                "type": "added"
                            },
                            {
                                "content": "        y = _columns_to_series(domain.class_vars, y_values)",
                                "type": "added"
                            },
                            {
                                "content": "    if domain.metas:",
                                "type": "added"
                            },
                            {
                                "content": "        metas = _columns_to_series(domain.metas, tab.metas)",
                                "type": "added"
                            },
                            {
                                "content": "    all_series = dict(x + y + metas)",
                                "type": "added"
                            },
                            {
                                "content": "    original_column_order = [var.name for var in tab.domain.variables]",
                                "type": "added"
                            },
                            {
                                "content": "    unsorted_columns_df = pd.DataFrame(all_series)",
                                "type": "added"
                            },
                            {
                                "content": "    return unsorted_columns_df[original_column_order]",
                                "type": "added"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [
                        {
                            "file_name": "Orange/data/pandas_compat.py",
                            "type": "function",
                            "name": "table_to_frame",
                            "content": "def table_to_frame(tab):\n    \"\"\"\n    Convert Orange.data.Table to pandas.DataFrame\n\n    Parameters\n    ----------\n    tab : Table\n\n    Returns\n    -------\n    pandas.DataFrame\n    \"\"\"\n    def _column_to_series(col, vals):\n        result = ()\n        if col.is_discrete:\n            codes = pd.Series(vals).fillna(-1).astype(int)\n            result = (col.name, pd.Categorical.from_codes(codes=codes, categories=col.values,\n                                                          ordered=col.ordered))\n        elif col.is_time:\n            result = (col.name, pd.to_datetime(vals, unit='s').to_series().reset_index()[0])\n        elif col.is_continuous:\n            dt = float\n            # np.nan are not compatible with int column\n            nan_values_in_column = [t for t in vals if np.isnan(t)]\n            if col.number_of_decimals == 0 and len(nan_values_in_column) == 0:\n                dt = int\n            result = (col.name, pd.Series(vals).astype(dt))\n        elif col.is_string:\n            result = (col.name, pd.Series(vals))\n        return result\n\n    def _columns_to_series(cols, vals):\n        return [_column_to_series(col, vals[:, i]) for i, col in enumerate(cols)]\n\n    x, y, metas = [], [], []\n    domain = tab.domain\n    if domain.attributes:\n        x = _columns_to_series(domain.attributes, tab.X)\n    if domain.class_vars:\n        y_values = tab.Y.reshape(tab.Y.shape[0], len(domain.class_vars))\n        y = _columns_to_series(domain.class_vars, y_values)\n    if domain.metas:\n        metas = _columns_to_series(domain.metas, tab.metas)\n    all_series = dict(x + y + metas)\n    original_column_order = [var.name for var in tab.domain.variables]\n    unsorted_columns_df = pd.DataFrame(all_series)\n    return unsorted_columns_df[original_column_order]",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 81,
                            "end_lineno": 127,
                            "parent": null
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "import unittest\nimport numpy as np\nfrom Orange.data import ContinuousVariable, DiscreteVariable, TimeVariable\n\ntry:\n    import pandas as pd\nexcept ImportError:\n    pd = None\n\n@unittest.skipIf(pd is None, \"Missing package 'pandas'\")\nclass TestPandasCompat(unittest.TestCase):\n    def test_table_from_frame(self):\n        from Orange.data.pandas_compat import table_from_frame\n\n        nan = np.nan\n        df = pd.DataFrame([['a', 1, pd.Timestamp('2017-12-19')],\n                           ['b', 0, pd.Timestamp('1724-12-20')],\n                           ['c', 0, pd.Timestamp('1724-12-20')],\n                           [nan, nan, nan]])\n        table = table_from_frame(df)\n        np.testing.assert_equal(table.X,\n                                [[1, pd.Timestamp('2017-12-19').timestamp()],\n                                 [0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [['a'],\n                                                       ['b'],\n                                                       ['c'],\n                                                       [nan]])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['1', '2'])\n        self.assertEqual(types, [ContinuousVariable, TimeVariable])\n\n        # Force strings nominal\n        table = table_from_frame(df, force_nominal=True)\n        np.testing.assert_equal(table.X, [[0, 1, pd.Timestamp('2017-12-19').timestamp()],\n                                          [1, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                          [2, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                          [nan, nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [[], [], [], []])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['0', '1', '2'])\n        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])\n\n        # Include index\n        df.index = list('abaa')\n        table = table_from_frame(df)\n        np.testing.assert_equal(table.X,\n                                [[0, 1, pd.Timestamp('2017-12-19').timestamp()],\n                                 [1, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [['a'],\n                                                       ['b'],\n                                                       ['c'],\n                                                       [nan]])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['index', '1', '2'])\n        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])\n",
            "new_file_content": "import unittest\nimport numpy as np\nfrom Orange.data import ContinuousVariable, DiscreteVariable, TimeVariable, Table\n\ntry:\n    import pandas as pd\nexcept ImportError:\n    pd = None\n\n@unittest.skipIf(pd is None, \"Missing package 'pandas'\")\nclass TestPandasCompat(unittest.TestCase):\n    def test_table_from_frame(self):\n        from Orange.data.pandas_compat import table_from_frame\n\n        nan = np.nan\n        df = pd.DataFrame([['a', 1, pd.Timestamp('2017-12-19')],\n                           ['b', 0, pd.Timestamp('1724-12-20')],\n                           ['c', 0, pd.Timestamp('1724-12-20')],\n                           [nan, nan, nan]])\n        table = table_from_frame(df)\n        np.testing.assert_equal(table.X,\n                                [[1, pd.Timestamp('2017-12-19').timestamp()],\n                                 [0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [['a'],\n                                                       ['b'],\n                                                       ['c'],\n                                                       [nan]])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['1', '2'])\n        self.assertEqual(types, [ContinuousVariable, TimeVariable])\n\n        # Force strings nominal\n        table = table_from_frame(df, force_nominal=True)\n        np.testing.assert_equal(table.X, [[0, 1, pd.Timestamp('2017-12-19').timestamp()],\n                                          [1, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                          [2, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                          [nan, nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [[], [], [], []])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['0', '1', '2'])\n        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])\n\n        # Include index\n        df.index = list('abaa')\n        table = table_from_frame(df)\n        np.testing.assert_equal(table.X,\n                                [[0, 1, pd.Timestamp('2017-12-19').timestamp()],\n                                 [1, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [['a'],\n                                                       ['b'],\n                                                       ['c'],\n                                                       [nan]])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['index', '1', '2'])\n        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])\n\n    def test_table_to_frame(self):\n        from Orange.data.pandas_compat import table_to_frame\n        table = Table(\"iris\")\n        df = table_to_frame(table)\n        table_column_names = [var.name for var in table.domain.variables]\n        frame_column_names = df.columns\n\n        self.assertEqual(sorted(table_column_names), sorted(frame_column_names))\n        self.assertEqual(type(df['iris'].dtype), pd.api.types.CategoricalDtype)\n        self.assertEqual(list(df['sepal length'])[0:4], [5.1, 4.9, 4.7, 4.6])\n        self.assertEqual(list(df['iris'])[0:2], ['Iris-setosa', 'Iris-setosa'])\n",
            "header": {
                "file": {
                    "path": "Orange/data/tests/test_pandas.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "184b04537",
                "new_commit_hash": "95c0a8d2a",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/Orange/data/tests/test_pandas.py"
            },
            "plus_file": {
                "path": "b/Orange/data/tests/test_pandas.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 1,
                            "length": 6
                        },
                        "new_range": {
                            "start": 1,
                            "length": 6
                        },
                        "section": ""
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "import unittest",
                                "type": "context"
                            },
                            {
                                "content": "import numpy as np",
                                "type": "context"
                            },
                            {
                                "content": "from Orange.data import ContinuousVariable, DiscreteVariable, TimeVariable",
                                "type": "deleted"
                            },
                            {
                                "content": "from Orange.data import ContinuousVariable, DiscreteVariable, TimeVariable, Table",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "try:",
                                "type": "context"
                            },
                            {
                                "content": "    import pandas as pd",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [
                        {
                            "file_name": "Orange/data/tests/test_pandas.py",
                            "type": "statement",
                            "name": "",
                            "content": "from Orange.data import ContinuousVariable, DiscreteVariable, TimeVariable, Table",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 3,
                            "end_lineno": 3,
                            "parent": null
                        }
                    ],
                    "deleted_entities": [
                        {
                            "file_name": "Orange/data/tests/test_pandas.py",
                            "type": "statement",
                            "name": "",
                            "content": "from Orange.data import ContinuousVariable, DiscreteVariable, TimeVariable",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 3,
                            "end_lineno": 3,
                            "parent": null
                        }
                    ]
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 60,
                            "length": 3
                        },
                        "new_range": {
                            "start": 60,
                            "length": 15
                        },
                        "section": "class TestPandasCompat(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        types = [type(var) for var in table.domain.attributes]",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(names, ['index', '1', '2'])",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    def test_table_to_frame(self):",
                                "type": "added"
                            },
                            {
                                "content": "        from Orange.data.pandas_compat import table_to_frame",
                                "type": "added"
                            },
                            {
                                "content": "        table = Table(\"iris\")",
                                "type": "added"
                            },
                            {
                                "content": "        df = table_to_frame(table)",
                                "type": "added"
                            },
                            {
                                "content": "        table_column_names = [var.name for var in table.domain.variables]",
                                "type": "added"
                            },
                            {
                                "content": "        frame_column_names = df.columns",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(sorted(table_column_names), sorted(frame_column_names))",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(type(df['iris'].dtype), pd.api.types.CategoricalDtype)",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(list(df['sepal length'])[0:4], [5.1, 4.9, 4.7, 4.6])",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(list(df['iris'])[0:2], ['Iris-setosa', 'Iris-setosa'])",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "Orange/data/tests/test_pandas.py",
                            "type": "class",
                            "name": "TestPandasCompat",
                            "content": "class TestPandasCompat(unittest.TestCase):\n    def test_table_from_frame(self):\n        from Orange.data.pandas_compat import table_from_frame\n\n        nan = np.nan\n        df = pd.DataFrame([['a', 1, pd.Timestamp('2017-12-19')],\n                           ['b', 0, pd.Timestamp('1724-12-20')],\n                           ['c', 0, pd.Timestamp('1724-12-20')],\n                           [nan, nan, nan]])\n        table = table_from_frame(df)\n        np.testing.assert_equal(table.X,\n                                [[1, pd.Timestamp('2017-12-19').timestamp()],\n                                 [0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [['a'],\n                                                       ['b'],\n                                                       ['c'],\n                                                       [nan]])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['1', '2'])\n        self.assertEqual(types, [ContinuousVariable, TimeVariable])\n\n        # Force strings nominal\n        table = table_from_frame(df, force_nominal=True)\n        np.testing.assert_equal(table.X, [[0, 1, pd.Timestamp('2017-12-19').timestamp()],\n                                          [1, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                          [2, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                          [nan, nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [[], [], [], []])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['0', '1', '2'])\n        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])\n\n        # Include index\n        df.index = list('abaa')\n        table = table_from_frame(df)\n        np.testing.assert_equal(table.X,\n                                [[0, 1, pd.Timestamp('2017-12-19').timestamp()],\n                                 [1, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [['a'],\n                                                       ['b'],\n                                                       ['c'],\n                                                       [nan]])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['index', '1', '2'])\n        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])\n\n    def test_table_to_frame(self):\n        from Orange.data.pandas_compat import table_to_frame\n        table = Table(\"iris\")\n        df = table_to_frame(table)\n        table_column_names = [var.name for var in table.domain.variables]\n        frame_column_names = df.columns\n\n        self.assertEqual(sorted(table_column_names), sorted(frame_column_names))\n        self.assertEqual(type(df['iris'].dtype), pd.api.types.CategoricalDtype)\n        self.assertEqual(list(df['sepal length'])[0:4], [5.1, 4.9, 4.7, 4.6])\n        self.assertEqual(list(df['iris'])[0:2], ['Iris-setosa', 'Iris-setosa'])",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 11,
                            "end_lineno": 74,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "Orange/data/tests/test_pandas.py",
                            "type": "method",
                            "name": "TestPandasCompat.test_table_to_frame",
                            "content": "class TestPandasCompat(unittest.TestCase):\n    def test_table_from_frame(self):\n        from Orange.data.pandas_compat import table_from_frame\n\n        nan = np.nan\n        df = pd.DataFrame([['a', 1, pd.Timestamp('2017-12-19')],\n                           ['b', 0, pd.Timestamp('1724-12-20')],\n                           ['c', 0, pd.Timestamp('1724-12-20')],\n                           [nan, nan, nan]])\n        table = table_from_frame(df)\n        np.testing.assert_equal(table.X,\n                                [[1, pd.Timestamp('2017-12-19').timestamp()],\n                                 [0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [['a'],\n                                                       ['b'],\n                                                       ['c'],\n                                                       [nan]])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['1', '2'])\n        self.assertEqual(types, [ContinuousVariable, TimeVariable])\n\n        # Force strings nominal\n        table = table_from_frame(df, force_nominal=True)\n        np.testing.assert_equal(table.X, [[0, 1, pd.Timestamp('2017-12-19').timestamp()],\n                                          [1, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                          [2, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                          [nan, nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [[], [], [], []])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['0', '1', '2'])\n        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])\n\n        # Include index\n        df.index = list('abaa')\n        table = table_from_frame(df)\n        np.testing.assert_equal(table.X,\n                                [[0, 1, pd.Timestamp('2017-12-19').timestamp()],\n                                 [1, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [['a'],\n                                                       ['b'],\n                                                       ['c'],\n                                                       [nan]])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['index', '1', '2'])\n        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])\n\n    def test_table_to_frame(self):\n        from Orange.data.pandas_compat import table_to_frame\n        table = Table(\"iris\")\n        df = table_to_frame(table)\n        table_column_names = [var.name for var in table.domain.variables]\n        frame_column_names = df.columns\n\n        self.assertEqual(sorted(table_column_names), sorted(frame_column_names))\n        self.assertEqual(type(df['iris'].dtype), pd.api.types.CategoricalDtype)\n        self.assertEqual(list(df['sepal length'])[0:4], [5.1, 4.9, 4.7, 4.6])\n        self.assertEqual(list(df['iris'])[0:2], ['Iris-setosa', 'Iris-setosa'])",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 64,
                            "end_lineno": 74,
                            "parent": {
                                "file_name": "Orange/data/tests/test_pandas.py",
                                "type": "class",
                                "name": "TestPandasCompat",
                                "content": "class TestPandasCompat(unittest.TestCase):\n    def test_table_from_frame(self):\n        from Orange.data.pandas_compat import table_from_frame\n\n        nan = np.nan\n        df = pd.DataFrame([['a', 1, pd.Timestamp('2017-12-19')],\n                           ['b', 0, pd.Timestamp('1724-12-20')],\n                           ['c', 0, pd.Timestamp('1724-12-20')],\n                           [nan, nan, nan]])\n        table = table_from_frame(df)\n        np.testing.assert_equal(table.X,\n                                [[1, pd.Timestamp('2017-12-19').timestamp()],\n                                 [0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [['a'],\n                                                       ['b'],\n                                                       ['c'],\n                                                       [nan]])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['1', '2'])\n        self.assertEqual(types, [ContinuousVariable, TimeVariable])\n\n        # Force strings nominal\n        table = table_from_frame(df, force_nominal=True)\n        np.testing.assert_equal(table.X, [[0, 1, pd.Timestamp('2017-12-19').timestamp()],\n                                          [1, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                          [2, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                          [nan, nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [[], [], [], []])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['0', '1', '2'])\n        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])\n\n        # Include index\n        df.index = list('abaa')\n        table = table_from_frame(df)\n        np.testing.assert_equal(table.X,\n                                [[0, 1, pd.Timestamp('2017-12-19').timestamp()],\n                                 [1, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [['a'],\n                                                       ['b'],\n                                                       ['c'],\n                                                       [nan]])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['index', '1', '2'])\n        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])\n\n    def test_table_to_frame(self):\n        from Orange.data.pandas_compat import table_to_frame\n        table = Table(\"iris\")\n        df = table_to_frame(table)\n        table_column_names = [var.name for var in table.domain.variables]\n        frame_column_names = df.columns\n\n        self.assertEqual(sorted(table_column_names), sorted(frame_column_names))\n        self.assertEqual(type(df['iris'].dtype), pd.api.types.CategoricalDtype)\n        self.assertEqual(list(df['sepal length'])[0:4], [5.1, 4.9, 4.7, 4.6])\n        self.assertEqual(list(df['iris'])[0:2], ['Iris-setosa', 'Iris-setosa'])",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 11,
                                "end_lineno": 74,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "9764be4fa30b1ae85db3b875039f0a2983531a9d^",
    "new_commit_hash": "9764be4fa30b1ae85db3b875039f0a2983531a9d",
    "commit_message": "[ENH] Add pandas_compat.table_to_frame(tab)\n\nConvert Orange.data.Table instance to pandas dataframe\n\n[FIX] pandas_compat.table_to_frame NaN values\n\n[FIX] table_to_frame persist column order\n\n[ENH] add tests for pandas_compat.table_to_frame\n\n[FIX] pandas_compat.table_to_frame commas\n\n[FIX] pandas_compat.table_to_frame support multipe target columns",
    "commit_date": "2018-08-02T21:36:48Z",
    "metadata": {}
}
{
    "repo_name": "orange3",
    "new_commit_hash": "9764be4fa30b1ae85db3b875039f0a2983531a9d",
    "test_file_codes": [
        "import unittest\nimport numpy as np\nfrom Orange.data import ContinuousVariable, DiscreteVariable, TimeVariable, Table\n\ntry:\n    import pandas as pd\nexcept ImportError:\n    pd = None\n\n@unittest.skipIf(pd is None, \"Missing package 'pandas'\")\nclass TestPandasCompat(unittest.TestCase):\n    def test_table_from_frame(self):\n        from Orange.data.pandas_compat import table_from_frame\n\n        nan = np.nan\n        df = pd.DataFrame([['a', 1, pd.Timestamp('2017-12-19')],\n                           ['b', 0, pd.Timestamp('1724-12-20')],\n                           ['c', 0, pd.Timestamp('1724-12-20')],\n                           [nan, nan, nan]])\n        table = table_from_frame(df)\n        np.testing.assert_equal(table.X,\n                                [[1, pd.Timestamp('2017-12-19').timestamp()],\n                                 [0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [['a'],\n                                                       ['b'],\n                                                       ['c'],\n                                                       [nan]])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['1', '2'])\n        self.assertEqual(types, [ContinuousVariable, TimeVariable])\n\n        # Force strings nominal\n        table = table_from_frame(df, force_nominal=True)\n        np.testing.assert_equal(table.X, [[0, 1, pd.Timestamp('2017-12-19').timestamp()],\n                                          [1, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                          [2, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                          [nan, nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [[], [], [], []])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['0', '1', '2'])\n        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])\n\n        # Include index\n        df.index = list('abaa')\n        table = table_from_frame(df)\n        np.testing.assert_equal(table.X,\n                                [[0, 1, pd.Timestamp('2017-12-19').timestamp()],\n                                 [1, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, 0, pd.Timestamp('1724-12-20').timestamp()],\n                                 [0, nan, nan]])\n        np.testing.assert_equal(table.metas.tolist(), [['a'],\n                                                       ['b'],\n                                                       ['c'],\n                                                       [nan]])\n        names = [var.name for var in table.domain.attributes]\n        types = [type(var) for var in table.domain.attributes]\n        self.assertEqual(names, ['index', '1', '2'])\n        self.assertEqual(types, [DiscreteVariable, ContinuousVariable, TimeVariable])\n\n    def test_table_to_frame(self):\n        from Orange.data.pandas_compat import table_to_frame\n        table = Table(\"iris\")\n        df = table_to_frame(table)\n        table_column_names = [var.name for var in table.domain.variables]\n        frame_column_names = df.columns\n\n        self.assertEqual(sorted(table_column_names), sorted(frame_column_names))\n        self.assertEqual(type(df['iris'].dtype), pd.api.types.CategoricalDtype)\n        self.assertEqual(list(df['sepal length'])[0:4], [5.1, 4.9, 4.7, 4.6])\n        self.assertEqual(list(df['iris'])[0:2], ['Iris-setosa', 'Iris-setosa'])\n"
    ],
    "test_file_names": [
        "test_1.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "Starting Orange installation attempts...\nAttempting installation with Python 3.7...\nWarning: 'keywords' should be a list, got type 'tuple'\nWarning: 'classifiers' should be a list, got type 'tuple'\nWarning: 'keywords' should be a list, got type 'tuple'\nWarning: 'classifiers' should be a list, got type 'tuple'\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.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/tmpnkaqlh5h/tmp\ncreating /tmp/tmpnkaqlh5h/tmp/tmpnkaqlh5h\ncompile options: '-MMD -MF /tmp/tmpnkaqlh5h/file.c.d -c'\ncc: /tmp/tmpnkaqlh5h/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/tmprzwck5la/tmp\ncreating /tmp/tmprzwck5la/tmp/tmprzwck5la\ncompile options: '-MMD -MF /tmp/tmprzwck5la/file.c.d -c'\ncc: /tmp/tmprzwck5la/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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include -I/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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\nWarning: 'keywords' should be a list, got type 'tuple'\nWarning: 'classifiers' should be a list, got type 'tuple'\nWarning: 'keywords' should be a list, got type 'tuple'\nWarning: 'classifiers' should be a list, got type 'tuple'\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.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 '*.html' under directory 'Orange/canvas'\nwarning: no files found matching '*.css' 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/tmpzd2qp1pa/tmp\ncreating /tmp/tmpzd2qp1pa/tmp/tmpzd2qp1pa\ncompile options: '-MMD -MF /tmp/tmpzd2qp1pa/file.c.d -c'\ncc: /tmp/tmpzd2qp1pa/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/tmplg93q053/tmp\ncreating /tmp/tmplg93q053/tmp/tmplg93q053\ncompile options: '-MMD -MF /tmp/tmplg93q053/file.c.d -c'\ncc: /tmp/tmplg93q053/file.c\ncustomize UnixCCompiler using build_ext\nCreating /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/Orange3.egg-link (link to .)\nAdding Orange3 3.15.0.dev0+9764be4 to easy-install.pth file\nInstalling orange-canvas script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/bin\n\nInstalled /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d\nProcessing dependencies for Orange3==3.15.0.dev0+9764be4\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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/bin\nInstalling pip3 script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/bin\nInstalling pip3.10 script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/bin\nInstalling f2py3 script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/bin\nInstalling f2py3.7 script to /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/bin\n\nUsing /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages\nFinished processing dependencies for Orange3==3.15.0.dev0+9764be4\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 59ms\nPrepared 18 packages in 61ms\nInstalled 18 packages in 831ms\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 29 packages in 237ms\nInstalled 24 packages in 403ms\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 + pip==24.0\n + pycparser==2.21\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 + threadpoolctl==3.1.0\n + urllib3==2.0.7\n + xlrd==2.0.1\nResolved 5 packages in 9ms\nInstalled 4 packages in 84ms\n + anyqt==0.2.0\n + commonmark==0.9.1\n + docutils==0.20.1\n + pyqtgraph==0.12.4\nResolved 2 packages in 3ms\nInstalled 2 packages in 6ms\n + psycopg2==2.9.9\n + pymssql==2.3.2\nResolved 5 packages in 17ms\nInstalled 4 packages in 119ms\n + pandas==1.3.5\n + python-dateutil==2.9.0.post0\n + pytz==2024.2\n + six==1.17.0\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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,\n                 from Orange/data/_contingency.c:567:\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1830,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.venv/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,\n                 from /home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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      |  ^~~~~~~\n/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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_9764be4fa30b1ae85db3b875039f0a2983531a9d/.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": 0,
    "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_9764be4fa30b1ae85db3b875039f0a2983531a9d\ncollected 2 items\n\nr2e_tests/test_1.py ..                                                   [100%]\n\n==================================== PASSES ====================================\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::TestPandasCompat::test_table_from_frame\nPASSED r2e_tests/test_1.py::TestPandasCompat::test_table_to_frame\n============================== 2 passed in 1.82s ===============================\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_9764be4fa30b1ae85db3b875039f0a2983531a9d\ncollected 2 items\n\nr2e_tests/test_1.py .F                                                   [100%]\n\n=================================== FAILURES ===================================\n_____________________ TestPandasCompat.test_table_to_frame _____________________\n\nself = <r2e_tests.test_1.TestPandasCompat testMethod=test_table_to_frame>\n\n    def test_table_to_frame(self):\n>       from Orange.data.pandas_compat import table_to_frame\nE       ImportError: cannot import name 'table_to_frame' from 'Orange.data.pandas_compat' (/home/gcpuser/buckets/local_repoeval_bucket/repos/orange3_9764be4fa30b1ae85db3b875039f0a2983531a9d/Orange/data/pandas_compat.py)\n\nr2e_tests/test_1.py:65: ImportError\n==================================== PASSES ====================================\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::TestPandasCompat::test_table_from_frame\nFAILED r2e_tests/test_1.py::TestPandasCompat::test_table_to_frame - ImportErr...\n========================= 1 failed, 1 passed in 0.81s ==========================\n",
    "old_commit_res_stderr": ""
}
Orange/data/pandas_compat.py Orange/data/tests/test_pandas.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title**: ImportError: Unable to import `table_to_frame` from `Orange.data.pandas_compat`

**Description**:
When trying to convert an `Orange.data.Table` instance to a pandas `DataFrame` using the `table_to_frame` function, an `ImportError` is raised. This prevents the conversion process from completing successfully.

**Example Code**:
```python
from Orange.data.pandas_compat import table_to_frame
from Orange.data import Table

table = Table("iris")
df = table_to_frame(table)
```

**Expected Behavior**:
The `table_to_frame` function should be available in the `Orange.data.pandas_compat` module, allowing users to convert an `Orange.data.Table` to a pandas `DataFrame` without encountering import errors.

**Actual Behavior**:
Attempting to import `table_to_frame` results in the following error:

```
ImportError: cannot import name 'table_to_frame' from 'Orange.data.pandas_compat'
```

This error indicates that the `table_to_frame` function is not recognized or not properly exposed in the `Orange.data.pandas_compat` module.

[/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/data/pandas_compat.py
"""Pandas DataFrame↔Table conversion helpers"""
import numpy as np
import pandas as pd
from pandas.api.types import (
    is_categorical_dtype, is_object_dtype,
    is_datetime64_any_dtype, is_numeric_dtype,
)

from Orange.data import (
    Table, Domain, DiscreteVariable, StringVariable, TimeVariable,
    ContinuousVariable,
)

__all__ = ['table_from_frame']


def table_from_frame(df, *, force_nominal=False):
    """
    Convert pandas.DataFrame to Orange.data.Table

    Parameters
    ----------
    df : pandas.DataFrame
    force_nominal : boolean
        If True, interpret ALL string columns as nominal (DiscreteVariable).

    Returns
    -------
    Table
    """

    def _is_discrete(s):
        return (is_categorical_dtype(s) or
                is_object_dtype(s) and (force_nominal or
                                        s.nunique() < s.size**.666))

    def _is_datetime(s):
        if is_datetime64_any_dtype(s):
            return True
        try:
            if is_object_dtype(s):
                pd.to_datetime(s, infer_datetime_format=True)
                return True
        except Exception:  # pylint: disable=broad-except
            pass
        return False

    # If df index is not a simple RangeIndex (or similar), put it into data
    if not (df.index.is_integer() and (df.index.is_monotonic_increasing or
                                       df.index.is_monotonic_decreasing)):
        df = df.reset_index()

    attrs, metas = [], []
    X, M = [], []

    # Iter over columns
    for name, s in df.items():
        name = str(name)
        if _is_discrete(s):
            discrete = s.astype('category').cat
            attrs.append(DiscreteVariable(name, discrete.categories.astype(str).tolist()))
            X.append(discrete.codes.replace(-1, np.nan).values)
        elif _is_datetime(s):
            tvar = TimeVariable(name)
            attrs.append(tvar)
            s = pd.to_datetime(s, infer_datetime_format=True)
            X.append(s.astype('str').replace('NaT', np.nan).map(tvar.parse).values)
        elif is_numeric_dtype(s):
            attrs.append(ContinuousVariable(name))
            X.append(s.values)
        else:
            metas.append(StringVariable(name))
            M.append(s.values.astype(object))

    return Table.from_numpy(Domain(attrs, None, metas),
                            np.column_stack(X) if X else np.empty((df.shape[0], 0)),
                            None,
                            np.column_stack(M) if M else None)

```
--- 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**: ImportError: Unable to import `table_to_frame` from `Orange.data.pandas_compat`

**Description**:
When trying to convert an `Orange.data.Table` instance to a pandas `DataFrame` using the `table_to_frame` function, an `ImportError` is raised. This prevents the conversion process from completing successfully.

**Example Code**:
```python
from Orange.data.pandas_compat import table_to_frame
from Orange.data import Table

table = Table("iris")
df = table_to_frame(table)
```

**Expected Behavior**:
The `table_to_frame` function should be available in the `Orange.data.pandas_compat` module, allowing users to convert an `Orange.data.Table` to a pandas `DataFrame` without encountering import errors.

**Actual Behavior**:
Attempting to import `table_to_frame` results in the following error:

```
ImportError: cannot import name 'table_to_frame' from 'Orange.data.pandas_compat'
```

This error indicates that the `table_to_frame` function is not recognized or not properly exposed in the `Orange.data.pandas_compat` module.

[/ISSUE]
{
    "TestPandasCompat.test_table_from_frame": "PASSED",
    "TestPandasCompat.test_table_to_frame": "PASSED"
}
diff --git a/Orange/data/pandas_compat.py b/Orange/data/pandas_compat.py
index 965b361ef..c8aaa9c85 100644
--- a/Orange/data/pandas_compat.py
+++ b/Orange/data/pandas_compat.py
@@ -11,7 +11,7 @@ from Orange.data import (
     ContinuousVariable,
 )
 
-__all__ = ['table_from_frame']
+__all__ = ['table_from_frame', 'table_to_frame']
 
 
 def table_from_frame(df, *, force_nominal=False):
@@ -76,3 +76,52 @@ def table_from_frame(df, *, force_nominal=False):
                             np.column_stack(X) if X else np.empty((df.shape[0], 0)),
                             None,
                             np.column_stack(M) if M else None)
+
+
+def table_to_frame(tab):
+    """
+    Convert Orange.data.Table to pandas.DataFrame
+
+    Parameters
+    ----------
+    tab : Table
+
+    Returns
+    -------
+    pandas.DataFrame
+    """
+    def _column_to_series(col, vals):
+        result = ()
+        if col.is_discrete:
+            codes = pd.Series(vals).fillna(-1).astype(int)
+            result = (col.name, pd.Categorical.from_codes(codes=codes, categories=col.values,
+                                                          ordered=col.ordered))
+        elif col.is_time:
+            result = (col.name, pd.to_datetime(vals, unit='s').to_series().reset_index()[0])
+        elif col.is_continuous:
+            dt = float
+            # np.nan are not compatible with int column
+            nan_values_in_column = [t for t in vals if np.isnan(t)]
+            if col.number_of_decimals == 0 and len(nan_values_in_column) == 0:
+                dt = int
+            result = (col.name, pd.Series(vals).astype(dt))
+        elif col.is_string:
+            result = (col.name, pd.Series(vals))
+        return result
+
+    def _columns_to_series(cols, vals):
+        return [_column_to_series(col, vals[:, i]) for i, col in enumerate(cols)]
+
+    x, y, metas = [], [], []
+    domain = tab.domain
+    if domain.attributes:
+        x = _columns_to_series(domain.attributes, tab.X)
+    if domain.class_vars:
+        y_values = tab.Y.reshape(tab.Y.shape[0], len(domain.class_vars))
+        y = _columns_to_series(domain.class_vars, y_values)
+    if domain.metas:
+        metas = _columns_to_series(domain.metas, tab.metas)
+    all_series = dict(x + y + metas)
+    original_column_order = [var.name for var in tab.domain.variables]
+    unsorted_columns_df = pd.DataFrame(all_series)
+    return unsorted_columns_df[original_column_order]

{"Orange/data/pandas_compat.py": "\"\"\"Pandas DataFrame\u2194Table conversion helpers\"\"\"\nimport numpy as np\nimport pandas as pd\nfrom pandas.api.types import (\n    is_categorical_dtype, is_object_dtype,\n    is_datetime64_any_dtype, is_numeric_dtype,\n)\n\nfrom Orange.data import (\n    Table, Domain, DiscreteVariable, StringVariable, TimeVariable,\n    ContinuousVariable,\n)\n\n__all__ = ['table_from_frame']\n\n\ndef table_from_frame(df, *, force_nominal=False):\n    \"\"\"\n    Convert pandas.DataFrame to Orange.data.Table\n\n    Parameters\n    ----------\n    df : pandas.DataFrame\n    force_nominal : boolean\n        If True, interpret ALL string columns as nominal (DiscreteVariable).\n\n    Returns\n    -------\n    Table\n    \"\"\"\n\n    def _is_discrete(s):\n        return (is_categorical_dtype(s) or\n                is_object_dtype(s) and (force_nominal or\n                                        s.nunique() < s.size**.666))\n\n    def _is_datetime(s):\n        if is_datetime64_any_dtype(s):\n            return True\n        try:\n            if is_object_dtype(s):\n                pd.to_datetime(s, infer_datetime_format=True)\n                return True\n        except Exception:  # pylint: disable=broad-except\n            pass\n        return False\n\n    # If df index is not a simple RangeIndex (or similar), put it into data\n    if not (df.index.is_integer() and (df.index.is_monotonic_increasing or\n                                       df.index.is_monotonic_decreasing)):\n        df = df.reset_index()\n\n    attrs, metas = [], []\n    X, M = [], []\n\n    # Iter over columns\n    for name, s in df.items():\n        name = str(name)\n        if _is_discrete(s):\n            discrete = s.astype('category').cat\n            attrs.append(DiscreteVariable(name, discrete.categories.astype(str).tolist()))\n            X.append(discrete.codes.replace(-1, np.nan).values)\n        elif _is_datetime(s):\n            tvar = TimeVariable(name)\n            attrs.append(tvar)\n            s = pd.to_datetime(s, infer_datetime_format=True)\n            X.append(s.astype('str').replace('NaT', np.nan).map(tvar.parse).values)\n        elif is_numeric_dtype(s):\n            attrs.append(ContinuousVariable(name))\n            X.append(s.values)\n        else:\n            metas.append(StringVariable(name))\n            M.append(s.values.astype(object))\n\n    return Table.from_numpy(Domain(attrs, None, metas),\n                            np.column_stack(X) if X else np.empty((df.shape[0], 0)),\n                            None,\n                            np.column_stack(M) if M else None)\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**: ImportError: Unable to import `table_to_frame` from `Orange.data.pandas_compat`

**Description**:
When trying to convert an `Orange.data.Table` instance to a pandas `DataFrame` using the `table_to_frame` function, an `ImportError` is raised. This prevents the conversion process from completing successfully.

**Example Code**:
```python
from Orange.data.pandas_compat import table_to_frame
from Orange.data import Table

table = Table("iris")
df = table_to_frame(table)
```

**Expected Behavior**:
The `table_to_frame` function should be available in the `Orange.data.pandas_compat` module, allowing users to convert an `Orange.data.Table` to a pandas `DataFrame` without encountering import errors.

**Actual Behavior**:
Attempting to import `table_to_frame` results in the following error:

```
ImportError: cannot import name 'table_to_frame' from 'Orange.data.pandas_compat'
```

This error indicates that the `table_to_frame` function is not recognized or not properly exposed in the `Orange.data.pandas_compat` module.

[/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/data/pandas_compat.py
"""Pandas DataFrame↔Table conversion helpers"""
import numpy as np
import pandas as pd
from pandas.api.types import (
    is_categorical_dtype, is_object_dtype,
    is_datetime64_any_dtype, is_numeric_dtype,
)

from Orange.data import (
    Table, Domain, DiscreteVariable, StringVariable, TimeVariable,
    ContinuousVariable,
)

__all__ = ['table_from_frame']


def table_from_frame(df, *, force_nominal=False):
    """
    Convert pandas.DataFrame to Orange.data.Table

    Parameters
    ----------
    df : pandas.DataFrame
    force_nominal : boolean
        If True, interpret ALL string columns as nominal (DiscreteVariable).

    Returns
    -------
    Table
    """

    def _is_discrete(s):
        return (is_categorical_dtype(s) or
                is_object_dtype(s) and (force_nominal or
                                        s.nunique() < s.size**.666))

    def _is_datetime(s):
        if is_datetime64_any_dtype(s):
            return True
        try:
            if is_object_dtype(s):
                pd.to_datetime(s, infer_datetime_format=True)
                return True
        except Exception:  # pylint: disable=broad-except
            pass
        return False

    # If df index is not a simple RangeIndex (or similar), put it into data
    if not (df.index.is_integer() and (df.index.is_monotonic_increasing or
                                       df.index.is_monotonic_decreasing)):
        df = df.reset_index()

    attrs, metas = [], []
    X, M = [], []

    # Iter over columns
    for name, s in df.items():
        name = str(name)
        if _is_discrete(s):
            discrete = s.astype('category').cat
            attrs.append(DiscreteVariable(name, discrete.categories.astype(str).tolist()))
            X.append(discrete.codes.replace(-1, np.nan).values)
        elif _is_datetime(s):
            tvar = TimeVariable(name)
            attrs.append(tvar)
            s = pd.to_datetime(s, infer_datetime_format=True)
            X.append(s.astype('str').replace('NaT', np.nan).map(tvar.parse).values)
        elif is_numeric_dtype(s):
            attrs.append(ContinuousVariable(name))
            X.append(s.values)
        else:
            metas.append(StringVariable(name))
            M.append(s.values.astype(object))

    return Table.from_numpy(Domain(attrs, None, metas),
                            np.column_stack(X) if X else np.empty((df.shape[0], 0)),
                            None,
                            np.column_stack(M) if M else None)

```
--- 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