We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[DOCS] Simple Model Comparison example improvement 
Currently, the Simple Model Comparison notebook lacks some explanations.
Please follow the guidelines from this issue: #543 to improve it

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `deepchecks/utils/validation.py`
Content:
```
1 # ----------------------------------------------------------------------------
2 # Copyright (C) 2021 Deepchecks (https://www.deepchecks.com)
3 #
4 # This file is part of Deepchecks.
5 # Deepchecks is distributed under the terms of the GNU Affero General
6 # Public License (version 3 or later).
7 # You should have received a copy of the GNU Affero General Public License
8 # along with Deepchecks.  If not, see <http://www.gnu.org/licenses/>.
9 # ----------------------------------------------------------------------------
10 #
11 """objects validation utilities."""
12 import typing as t
13 
14 import pandas as pd
15 
16 from deepchecks import base  # pylint: disable=unused-import, is used in type annotations
17 from deepchecks import errors
18 from deepchecks.utils.typing import Hashable, BasicModel
19 
20 __all__ = ['model_type_validation', 'ensure_hashable_or_mutable_sequence', 'validate_model', 'ensure_dataframe_type']
21 
22 
23 def model_type_validation(model: t.Any):
24     """Receive any object and check if it's an instance of a model we support.
25 
26     Raises:
27         DeepchecksValueError: If the object is not of a supported type
28     """
29     if not isinstance(model, BasicModel):
30         raise errors.DeepchecksValueError(
31             'Model must inherit from one of supported '
32             'models: sklearn.base.BaseEstimator or CatBoost, '
33             f'Received: {model.__class__.__name__}'
34         )
35 
36 
37 def validate_model(
38     data: t.Union['base.Dataset', pd.DataFrame],
39     model: t.Any
40 ):
41     """Check model is able to predict on the dataset.
42 
43     Args:
44         data (Dataset, pandas.DataFrame):
45         model (BaseEstimator):
46 
47     Raise:
48         DeepchecksValueError: if dataset does not match model
49     """
50     model_type_validation(model)
51 
52     error_message = (
53         'In order to evaluate model correctness we need not empty dataset '
54         'with the same set of features that was used to fit the model. {0}'
55     )
56 
57     if isinstance(data, base.Dataset):
58         features = data.features_columns
59         features_names = set(data.features)
60     else:
61         features = data
62         features_names = set(data.columns)
63 
64     model_features = getattr(model, 'feature_names_in_', None)
65 
66     if features is None:
67         raise errors.DeepchecksValueError(error_message.format(
68             'But function received dataset without feature columns.'
69         ))
70 
71     if len(features) == 0:
72         raise errors.DeepchecksValueError(error_message.format(
73             'But function received empty dataset.'
74         ))
75 
76     try:
77         model_features = set(model_features)  # type: ignore
78         if model_features != features_names:
79             raise errors.DeepchecksValueError(error_message.format(
80                 'But function received dataset with a different set of features.'
81             ))
82     except (TypeError, ValueError):
83         # in case if 'model.feature_names_in_' was None or not iterable
84         pass
85 
86     try:
87         model.predict(features.head(1))
88     except Exception as exc:
89         raise errors.DeepchecksValueError(
90             f'Got error when trying to predict with model on dataset: {str(exc)}'
91         )
92 
93 
94 T = t.TypeVar('T', bound=Hashable)
95 
96 
97 def ensure_hashable_or_mutable_sequence(
98     value: t.Union[T, t.MutableSequence[T]],
99     message: str = (
100         'Provided value is neither hashable nor mutable '
101         'sequence of hashable items. Got {type}')
102 ) -> t.List[T]:
103     """Validate that provided value is either hashable or mutable sequence of hashable values."""
104     if isinstance(value, Hashable):
105         return [value]
106 
107     if isinstance(value, t.MutableSequence):
108         if len(value) > 0 and not isinstance(value[0], Hashable):
109             raise errors.DeepchecksValueError(message.format(
110                 type=f'MutableSequence[{type(value).__name__}]'
111             ))
112         return list(value)
113 
114     raise errors.DeepchecksValueError(message.format(
115         type=type(value).__name__
116     ))
117 
118 
119 def ensure_dataframe_type(obj: t.Any) -> pd.DataFrame:
120     """Ensure that given object is of type DataFrame or Dataset and return it as DataFrame. else raise error.
121 
122     Args:
123         obj: Object to ensure it is DataFrame or Dataset
124 
125     Returns:
126         (pd.DataFrame)
127     """
128     if isinstance(obj, pd.DataFrame):
129         return obj
130     elif isinstance(obj, base.Dataset):
131         return obj.data
132     else:
133         raise errors.DeepchecksValueError(
134             f'dataset must be of type DataFrame or Dataset, but got: {type(obj).__name__}'
135         )
136
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/deepchecks/utils/validation.py b/deepchecks/utils/validation.py
--- a/deepchecks/utils/validation.py
+++ b/deepchecks/utils/validation.py
@@ -56,12 +56,8 @@
 
     if isinstance(data, base.Dataset):
         features = data.features_columns
-        features_names = set(data.features)
     else:
         features = data
-        features_names = set(data.columns)
-
-    model_features = getattr(model, 'feature_names_in_', None)
 
     if features is None:
         raise errors.DeepchecksValueError(error_message.format(
@@ -73,16 +69,6 @@
             'But function received empty dataset.'
         ))
 
-    try:
-        model_features = set(model_features)  # type: ignore
-        if model_features != features_names:
-            raise errors.DeepchecksValueError(error_message.format(
-                'But function received dataset with a different set of features.'
-            ))
-    except (TypeError, ValueError):
-        # in case if 'model.feature_names_in_' was None or not iterable
-        pass
-
     try:
         model.predict(features.head(1))
     except Exception as exc:

{"golden_diff": "diff --git a/deepchecks/utils/validation.py b/deepchecks/utils/validation.py\n--- a/deepchecks/utils/validation.py\n+++ b/deepchecks/utils/validation.py\n@@ -56,12 +56,8 @@\n \n     if isinstance(data, base.Dataset):\n         features = data.features_columns\n-        features_names = set(data.features)\n     else:\n         features = data\n-        features_names = set(data.columns)\n-\n-    model_features = getattr(model, 'feature_names_in_', None)\n \n     if features is None:\n         raise errors.DeepchecksValueError(error_message.format(\n@@ -73,16 +69,6 @@\n             'But function received empty dataset.'\n         ))\n \n-    try:\n-        model_features = set(model_features)  # type: ignore\n-        if model_features != features_names:\n-            raise errors.DeepchecksValueError(error_message.format(\n-                'But function received dataset with a different set of features.'\n-            ))\n-    except (TypeError, ValueError):\n-        # in case if 'model.feature_names_in_' was None or not iterable\n-        pass\n-\n     try:\n         model.predict(features.head(1))\n     except Exception as exc:\n", "issue": "[DOCS] Simple Model Comparison example improvement \nCurrently, the Simple Model Comparison notebook lacks some explanations.\r\nPlease follow the guidelines from this issue: #543 to improve it\n", "before_files": [{"content": "# ----------------------------------------------------------------------------\n# Copyright (C) 2021 Deepchecks (https://www.deepchecks.com)\n#\n# This file is part of Deepchecks.\n# Deepchecks is distributed under the terms of the GNU Affero General\n# Public License (version 3 or later).\n# You should have received a copy of the GNU Affero General Public License\n# along with Deepchecks.  If not, see <http://www.gnu.org/licenses/>.\n# ----------------------------------------------------------------------------\n#\n\"\"\"objects validation utilities.\"\"\"\nimport typing as t\n\nimport pandas as pd\n\nfrom deepchecks import base  # pylint: disable=unused-import, is used in type annotations\nfrom deepchecks import errors\nfrom deepchecks.utils.typing import Hashable, BasicModel\n\n__all__ = ['model_type_validation', 'ensure_hashable_or_mutable_sequence', 'validate_model', 'ensure_dataframe_type']\n\n\ndef model_type_validation(model: t.Any):\n    \"\"\"Receive any object and check if it's an instance of a model we support.\n\n    Raises:\n        DeepchecksValueError: If the object is not of a supported type\n    \"\"\"\n    if not isinstance(model, BasicModel):\n        raise errors.DeepchecksValueError(\n            'Model must inherit from one of supported '\n            'models: sklearn.base.BaseEstimator or CatBoost, '\n            f'Received: {model.__class__.__name__}'\n        )\n\n\ndef validate_model(\n    data: t.Union['base.Dataset', pd.DataFrame],\n    model: t.Any\n):\n    \"\"\"Check model is able to predict on the dataset.\n\n    Args:\n        data (Dataset, pandas.DataFrame):\n        model (BaseEstimator):\n\n    Raise:\n        DeepchecksValueError: if dataset does not match model\n    \"\"\"\n    model_type_validation(model)\n\n    error_message = (\n        'In order to evaluate model correctness we need not empty dataset '\n        'with the same set of features that was used to fit the model. {0}'\n    )\n\n    if isinstance(data, base.Dataset):\n        features = data.features_columns\n        features_names = set(data.features)\n    else:\n        features = data\n        features_names = set(data.columns)\n\n    model_features = getattr(model, 'feature_names_in_', None)\n\n    if features is None:\n        raise errors.DeepchecksValueError(error_message.format(\n            'But function received dataset without feature columns.'\n        ))\n\n    if len(features) == 0:\n        raise errors.DeepchecksValueError(error_message.format(\n            'But function received empty dataset.'\n        ))\n\n    try:\n        model_features = set(model_features)  # type: ignore\n        if model_features != features_names:\n            raise errors.DeepchecksValueError(error_message.format(\n                'But function received dataset with a different set of features.'\n            ))\n    except (TypeError, ValueError):\n        # in case if 'model.feature_names_in_' was None or not iterable\n        pass\n\n    try:\n        model.predict(features.head(1))\n    except Exception as exc:\n        raise errors.DeepchecksValueError(\n            f'Got error when trying to predict with model on dataset: {str(exc)}'\n        )\n\n\nT = t.TypeVar('T', bound=Hashable)\n\n\ndef ensure_hashable_or_mutable_sequence(\n    value: t.Union[T, t.MutableSequence[T]],\n    message: str = (\n        'Provided value is neither hashable nor mutable '\n        'sequence of hashable items. Got {type}')\n) -> t.List[T]:\n    \"\"\"Validate that provided value is either hashable or mutable sequence of hashable values.\"\"\"\n    if isinstance(value, Hashable):\n        return [value]\n\n    if isinstance(value, t.MutableSequence):\n        if len(value) > 0 and not isinstance(value[0], Hashable):\n            raise errors.DeepchecksValueError(message.format(\n                type=f'MutableSequence[{type(value).__name__}]'\n            ))\n        return list(value)\n\n    raise errors.DeepchecksValueError(message.format(\n        type=type(value).__name__\n    ))\n\n\ndef ensure_dataframe_type(obj: t.Any) -> pd.DataFrame:\n    \"\"\"Ensure that given object is of type DataFrame or Dataset and return it as DataFrame. else raise error.\n\n    Args:\n        obj: Object to ensure it is DataFrame or Dataset\n\n    Returns:\n        (pd.DataFrame)\n    \"\"\"\n    if isinstance(obj, pd.DataFrame):\n        return obj\n    elif isinstance(obj, base.Dataset):\n        return obj.data\n    else:\n        raise errors.DeepchecksValueError(\n            f'dataset must be of type DataFrame or Dataset, but got: {type(obj).__name__}'\n        )\n", "path": "deepchecks/utils/validation.py"}], "after_files": [{"content": "# ----------------------------------------------------------------------------\n# Copyright (C) 2021 Deepchecks (https://www.deepchecks.com)\n#\n# This file is part of Deepchecks.\n# Deepchecks is distributed under the terms of the GNU Affero General\n# Public License (version 3 or later).\n# You should have received a copy of the GNU Affero General Public License\n# along with Deepchecks.  If not, see <http://www.gnu.org/licenses/>.\n# ----------------------------------------------------------------------------\n#\n\"\"\"objects validation utilities.\"\"\"\nimport typing as t\n\nimport pandas as pd\n\nfrom deepchecks import base  # pylint: disable=unused-import, is used in type annotations\nfrom deepchecks import errors\nfrom deepchecks.utils.typing import Hashable, BasicModel\n\n__all__ = ['model_type_validation', 'ensure_hashable_or_mutable_sequence', 'validate_model', 'ensure_dataframe_type']\n\n\ndef model_type_validation(model: t.Any):\n    \"\"\"Receive any object and check if it's an instance of a model we support.\n\n    Raises:\n        DeepchecksValueError: If the object is not of a supported type\n    \"\"\"\n    if not isinstance(model, BasicModel):\n        raise errors.DeepchecksValueError(\n            'Model must inherit from one of supported '\n            'models: sklearn.base.BaseEstimator or CatBoost, '\n            f'Received: {model.__class__.__name__}'\n        )\n\n\ndef validate_model(\n    data: t.Union['base.Dataset', pd.DataFrame],\n    model: t.Any\n):\n    \"\"\"Check model is able to predict on the dataset.\n\n    Args:\n        data (Dataset, pandas.DataFrame):\n        model (BaseEstimator):\n\n    Raise:\n        DeepchecksValueError: if dataset does not match model\n    \"\"\"\n    model_type_validation(model)\n\n    error_message = (\n        'In order to evaluate model correctness we need not empty dataset '\n        'with the same set of features that was used to fit the model. {0}'\n    )\n\n    if isinstance(data, base.Dataset):\n        features = data.features_columns\n    else:\n        features = data\n\n    if features is None:\n        raise errors.DeepchecksValueError(error_message.format(\n            'But function received dataset without feature columns.'\n        ))\n\n    if len(features) == 0:\n        raise errors.DeepchecksValueError(error_message.format(\n            'But function received empty dataset.'\n        ))\n\n    try:\n        model.predict(features.head(1))\n    except Exception as exc:\n        raise errors.DeepchecksValueError(\n            f'Got error when trying to predict with model on dataset: {str(exc)}'\n        )\n\n\nT = t.TypeVar('T', bound=Hashable)\n\n\ndef ensure_hashable_or_mutable_sequence(\n    value: t.Union[T, t.MutableSequence[T]],\n    message: str = (\n        'Provided value is neither hashable nor mutable '\n        'sequence of hashable items. Got {type}')\n) -> t.List[T]:\n    \"\"\"Validate that provided value is either hashable or mutable sequence of hashable values.\"\"\"\n    if isinstance(value, Hashable):\n        return [value]\n\n    if isinstance(value, t.MutableSequence):\n        if len(value) > 0 and not isinstance(value[0], Hashable):\n            raise errors.DeepchecksValueError(message.format(\n                type=f'MutableSequence[{type(value).__name__}]'\n            ))\n        return list(value)\n\n    raise errors.DeepchecksValueError(message.format(\n        type=type(value).__name__\n    ))\n\n\ndef ensure_dataframe_type(obj: t.Any) -> pd.DataFrame:\n    \"\"\"Ensure that given object is of type DataFrame or Dataset and return it as DataFrame. else raise error.\n\n    Args:\n        obj: Object to ensure it is DataFrame or Dataset\n\n    Returns:\n        (pd.DataFrame)\n    \"\"\"\n    if isinstance(obj, pd.DataFrame):\n        return obj\n    elif isinstance(obj, base.Dataset):\n        return obj.data\n    else:\n        raise errors.DeepchecksValueError(\n            f'dataset must be of type DataFrame or Dataset, but got: {type(obj).__name__}'\n        )\n", "path": "deepchecks/utils/validation.py"}]}