From 1090b80ca93b5b32c81f7e406248bde11e96495f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?xavier=20dupr=C3=A9?= Date: Tue, 19 Jul 2022 23:27:46 +0200 Subject: [PATCH] Uses f strings --- _doc/examples/plot_constraint_kmeans.py | 8 ++--- .../ut_documentation/test_nb_search_keras.py | 3 +- _unittests/ut_plotting/test_plot_gallery.py | 4 +-- .../test_LONG_search_images_keras.py | 2 +- .../test_LONG_search_images_torch.py | 2 +- mlinsights/helpers/parameters.py | 6 ++-- mlinsights/helpers/pipeline.py | 11 ++++--- mlinsights/metrics/correlations.py | 4 +-- mlinsights/mlbatch/cache_model.py | 8 ++--- mlinsights/mlmodel/_kmeans_022.py | 2 +- mlinsights/mlmodel/_kmeans_constraint_.py | 13 ++++----- mlinsights/mlmodel/categories_to_integers.py | 8 ++--- mlinsights/mlmodel/classification_kmeans.py | 6 ++-- mlinsights/mlmodel/decision_tree_logreg.py | 2 +- mlinsights/mlmodel/extended_features.py | 9 +++--- mlinsights/mlmodel/kmeans_constraint.py | 3 +- mlinsights/mlmodel/kmeans_l1.py | 13 ++++----- mlinsights/mlmodel/ml_featurizer.py | 2 +- mlinsights/mlmodel/piecewise_estimator.py | 3 +- mlinsights/mlmodel/predictable_tsne.py | 6 ++-- mlinsights/mlmodel/quantile_regression.py | 2 +- mlinsights/mlmodel/sklearn_testing.py | 24 +++++++-------- mlinsights/mlmodel/sklearn_text.py | 3 +- .../mlmodel/sklearn_transform_inv_fct.py | 8 ++--- mlinsights/mlmodel/transfer_transformer.py | 3 +- mlinsights/mltree/tree_digitize.py | 5 ++-- mlinsights/mltree/tree_structure.py | 4 +-- mlinsights/plotting/gallery.py | 4 +-- mlinsights/plotting/visualize.py | 29 +++++++++---------- .../search_engine_predictions_images.py | 20 ++++++------- .../search_rank/search_engine_vectors.py | 2 +- mlinsights/sklapi/sklearn_base.py | 8 ++--- .../sklapi/sklearn_base_transform_learner.py | 14 ++++----- .../sklapi/sklearn_base_transform_stacking.py | 8 ++--- mlinsights/sklapi/sklearn_parameters.py | 6 ++-- mlinsights/timeseries/agg.py | 6 ++-- mlinsights/timeseries/ar.py | 2 +- mlinsights/timeseries/metrics.py | 3 +- mlinsights/timeseries/patterns.py | 8 ++--- mlinsights/timeseries/utils.py | 11 ++++--- setup.py | 12 ++++---- 41 files changed, 137 insertions(+), 160 deletions(-) diff --git a/_doc/examples/plot_constraint_kmeans.py b/_doc/examples/plot_constraint_kmeans.py index 0b93e33a..7b8c2be9 100644 --- a/_doc/examples/plot_constraint_kmeans.py +++ b/_doc/examples/plot_constraint_kmeans.py @@ -57,7 +57,7 @@ x = [km.cluster_centers_[i, 0], km.cluster_centers_[i, 0]] y = [km.cluster_centers_[i, 1], km.cluster_centers_[i, 1]] ax.plot(x, y, colors[i] + '+') -ax.set_title('KMeans 4 clusters\n%r' % hist) +ax.set_title(f'KMeans 4 clusters\n{hist!r}') ax.legend() ##################################### @@ -94,9 +94,9 @@ x = [km2.cluster_centers_[i, 0], km2.cluster_centers_[i, 0]] y = [km2.cluster_centers_[i, 1], km2.cluster_centers_[i, 1]] ax[1].plot(x, y, colors[i] + '+') -ax[0].set_title('ConstraintKMeans 4 clusters (gains)\n%r' % hist1) +ax[0].set_title(f'ConstraintKMeans 4 clusters (gains)\n{hist1!r}') ax[0].legend() -ax[1].set_title('ConstraintKMeans 4 clusters (distances)\n%r' % hist2) +ax[1].set_title(f'ConstraintKMeans 4 clusters (distances)\n{hist2!r}') ax[1].legend() @@ -129,7 +129,7 @@ def plot_delaunay(ax, edges, points): x = [km.cluster_centers_[i, 0], km.cluster_centers_[i, 0]] y = [km.cluster_centers_[i, 1], km.cluster_centers_[i, 1]] ax[0].plot(x, y, colors[i] + '+') -ax[0].set_title("ConstraintKMeans 4 clusters\nstrategy='weights'\n%r" % hist) +ax[0].set_title(f"ConstraintKMeans 4 clusters\nstrategy='weights'\n{hist!r}") ax[0].legend() cls = km.cluster_centers_iter_ diff --git a/_unittests/ut_documentation/test_nb_search_keras.py b/_unittests/ut_documentation/test_nb_search_keras.py index ad65d82c..ad47951f 100644 --- a/_unittests/ut_documentation/test_nb_search_keras.py +++ b/_unittests/ut_documentation/test_nb_search_keras.py @@ -31,8 +31,7 @@ def test_notebook_search_images(self): except (SyntaxError, ModuleNotFoundError, AttributeError, ImportError) as e: warnings.warn( - "tensorflow is probably not available yet on python 3.7: " - "{0}".format(e)) + f"tensorflow is probably not available yet on python 3.7: {e}") return self.assertTrue(mlinsights is not None) diff --git a/_unittests/ut_plotting/test_plot_gallery.py b/_unittests/ut_plotting/test_plot_gallery.py index be1aada2..5dfb55e5 100644 --- a/_unittests/ut_plotting/test_plot_gallery.py +++ b/_unittests/ut_plotting/test_plot_gallery.py @@ -57,7 +57,7 @@ def test_plot_gallery_url(self): try: fig, ax = plot_gallery_images(files, return_figure=True) except http.client.RemoteDisconnected as e: - warnings.warn("Unable to fetch image {0}'".format(e)) + warnings.warn(f"Unable to fetch image {e}'") return img = os.path.join(temp, "gallery.png") fig.savefig(img) @@ -68,7 +68,7 @@ def test_plot_gallery_url(self): ax = plot_gallery_images(files, return_figure=False, ax=ax) self.assertNotEmpty(ax) except http.client.RemoteDisconnected as e: - warnings.warn("Unable to fetch image {0}'".format(e)) + warnings.warn(f"Unable to fetch image {e}'") return diff --git a/_unittests/ut_search_rank/test_LONG_search_images_keras.py b/_unittests/ut_search_rank/test_LONG_search_images_keras.py index d576f6d7..bd5b6fba 100644 --- a/_unittests/ut_search_rank/test_LONG_search_images_keras.py +++ b/_unittests/ut_search_rank/test_LONG_search_images_keras.py @@ -31,7 +31,7 @@ def test_search_predictions_keras(self): except (SyntaxError, ModuleNotFoundError, AttributeError, ImportError) as e: warnings.warn( - "Issue with tensorflow or keras: {0}".format(e)) + f"Issue with tensorflow or keras: {e}") return from keras.preprocessing.image import ImageDataGenerator # pylint: disable=E0401,E0611 from keras.preprocessing.image import img_to_array, load_img # pylint: disable=E0401,E0611 diff --git a/_unittests/ut_search_rank/test_LONG_search_images_torch.py b/_unittests/ut_search_rank/test_LONG_search_images_torch.py index 94e0aa03..6b97525b 100644 --- a/_unittests/ut_search_rank/test_LONG_search_images_torch.py +++ b/_unittests/ut_search_rank/test_LONG_search_images_torch.py @@ -32,7 +32,7 @@ def test_search_predictions_torch(self): import torchvision.models as tmodels # pylint: disable=E0401,C0415 except (SyntaxError, ModuleNotFoundError) as e: warnings.warn( - "torch is not available: {0}".format(e)) + f"torch is not available: {e}") return from torchvision import datasets, transforms # pylint: disable=E0401 from torch.utils.data import DataLoader # pylint: disable=E0401 diff --git a/mlinsights/helpers/parameters.py b/mlinsights/helpers/parameters.py index b740f0ce..fd544609 100644 --- a/mlinsights/helpers/parameters.py +++ b/mlinsights/helpers/parameters.py @@ -13,7 +13,7 @@ def format_value(v): @return a string """ return ("'{0}'".format(v.replace("'", "\\'")) - if isinstance(v, str) else "{0}".format(v)) + if isinstance(v, str) else f"{v}") def format_parameters(pdict): @@ -33,7 +33,7 @@ def format_parameters(pdict): """ res = [] for k, v in sorted(pdict.items()): - res.append('{0}={1}'.format(k, format_value(v))) + res.append(f'{k}={format_value(v)}') return ", ".join(res) @@ -52,5 +52,5 @@ def format_function_call(name, pdict): d = dict(i=2, x=6.7, s="r") print(format_function_call("fct", d)) """ - res = '{0}({1})'.format(name, format_parameters(pdict)) + res = f'{name}({format_parameters(pdict)})' return "\n".join(textwrap.wrap(res, width=70, subsequent_indent=' ')) diff --git a/mlinsights/helpers/pipeline.py b/mlinsights/helpers/pipeline.py index 1a24ed02..1a34d98e 100644 --- a/mlinsights/helpers/pipeline.py +++ b/mlinsights/helpers/pipeline.py @@ -71,7 +71,7 @@ class PassThrough: pass else: raise TypeError( # pragma: no cover - "pipe is not a scikit-learn object: {}\n{}".format(type(pipe), pipe)) + f"pipe is not a scikit-learn object: {type(pipe)}\n{pipe}") class BaseEstimatorDebugInformation: @@ -112,8 +112,7 @@ def to_str(self, nrows=5): """ Tries to produce a readable message. """ - rows = ['BaseEstimatorDebugInformation({})'.format( - self.model.__class__.__name__)] + rows = [f'BaseEstimatorDebugInformation({self.model.__class__.__name__})'] for k in sorted(self.inputs): if k in self.outputs: rows.append(' ' + k + '(') @@ -126,7 +125,7 @@ def to_str(self, nrows=5): rows.append(' )') else: raise KeyError( # pragma: no cover - "Unable to find output for method '{}'.".format(k)) + f"Unable to find output for method '{k}'.") return "\n".join(rows) def display(self, data, nrows): @@ -139,9 +138,9 @@ def display(self, data, nrows): rows = rows[:nrows] rows.append('...') if hasattr(data, 'shape'): - rows.insert(0, "shape=%r type=%r" % (data.shape, type(data))) + rows.insert(0, f"shape={data.shape!r} type={type(data)!r}") else: - rows.insert(0, "type=%r" % type(data)) # pragma: no cover + rows.insert(0, f"type={type(data)!r}") # pragma: no cover return "\n".join(rows) diff --git a/mlinsights/metrics/correlations.py b/mlinsights/metrics/correlations.py index 6777436b..8a689de9 100644 --- a/mlinsights/metrics/correlations.py +++ b/mlinsights/metrics/correlations.py @@ -126,13 +126,13 @@ def non_linear_correlations(df, model, draws=5, minmax=False): xj_test = df_test[:, j:j + 1] if len(xj_test) == 0 or len(xi_test) == 0: raise ValueError( # pragma: no cover - "One column is empty i={0} j={1}.".format(i, j)) + f"One column is empty i={i} j={j}.") mod = clone(model) try: mod.fit(xi_train, xj_train.ravel()) except Exception as e: # pragma: no cover raise ValueError( - "Unable to compute correlation for i={0} j={1}.".format(i, j)) from e + f"Unable to compute correlation for i={i} j={j}.") from e v = mod.predict(xi_test) c = (1 - numpy.var(v - xj_test.ravel())) co = max(c, 0) ** 0.5 diff --git a/mlinsights/mlbatch/cache_model.py b/mlinsights/mlbatch/cache_model.py index 4e66b46c..4f657260 100644 --- a/mlinsights/mlbatch/cache_model.py +++ b/mlinsights/mlbatch/cache_model.py @@ -31,7 +31,7 @@ def cache(self, params, value): key = MLCache.as_key(params) if key in self.cached: raise KeyError( # pragma: no cover - "Key {0} already exists".format(params)) + f"Key {params} already exists") self.cached[key] = value self.count_[key] = 0 @@ -77,7 +77,7 @@ def as_key(params): elif isinstance(v, tuple): if not all(map(lambda e: isinstance(e, (int, float, str)), v)): raise TypeError( # pragma: no cover - "Unable to create a key with value '{0}':{1}".format(k, v)) + f"Unable to create a key with value '{k}':{v}") return str(v) elif isinstance(v, numpy.ndarray): # id(v) may have been better but @@ -87,7 +87,7 @@ def as_key(params): sv = "" else: raise TypeError( # pragma: no cover - "Unable to create a key with value '{0}':{1}".format(k, v)) + f"Unable to create a key with value '{k}':{v}") els.append((k, sv)) return str(els) @@ -122,7 +122,7 @@ def create_cache(name): global _caches # pylint: disable=W0603,W0602 if name in _caches: raise RuntimeError( # pragma: no cover - "cache '{0}' already exists.".format(name)) + f"cache '{name}' already exists.") cache = MLCache(name) _caches[name] = cache diff --git a/mlinsights/mlmodel/_kmeans_022.py b/mlinsights/mlmodel/_kmeans_022.py index 500694c5..5f92116e 100644 --- a/mlinsights/mlmodel/_kmeans_022.py +++ b/mlinsights/mlmodel/_kmeans_022.py @@ -45,7 +45,7 @@ def _labels_inertia_precompute_dense(norm, X, sample_weight, centers, distances) X=X, Y=centers, metric='manhattan') else: # pragma no cover raise NotImplementedError( - "Not implemented for norm '{}'.".format(norm)) + f"Not implemented for norm '{norm}'.") # cython k-means code assumes int32 inputs labels = labels.astype(numpy.int32, copy=False) if n_samples == distances.shape[0]: diff --git a/mlinsights/mlmodel/_kmeans_constraint_.py b/mlinsights/mlmodel/_kmeans_constraint_.py index 764d8e83..21be5dae 100644 --- a/mlinsights/mlmodel/_kmeans_constraint_.py +++ b/mlinsights/mlmodel/_kmeans_constraint_.py @@ -47,7 +47,7 @@ def linearize_matrix(mat, *adds): res[i, k + 3] = am[a, b] return res raise NotImplementedError( # pragma: no cover - "This kind of sparse matrix is not handled: {0}".format(type(mat))) + f"This kind of sparse matrix is not handled: {type(mat)}") else: n = mat.shape[0] c = mat.shape[1] @@ -91,7 +91,7 @@ def constraint_kmeans(X, labels, sample_weight, centers, inertia, """ if labels.dtype != numpy.int32: raise TypeError( # pragma: no cover - "Labels must be an array of int not '{0}'".format(labels.dtype)) + f"Labels must be an array of int not '{labels.dtype}'") if strategy == 'weights': return _constraint_kmeans_weights( @@ -222,8 +222,7 @@ def _constraint_association(leftover, counters, labels, leftclose, distances_clo return _constraint_association_gain( leftover, counters, labels, leftclose, distances_close, centers, X, x_squared_norms, limit, strategy, state=state) - raise ValueError("Unknwon strategy '{0}'.".format( - strategy)) # pragma: no cover + raise ValueError(f"Unknwon strategy '{strategy}'.") # pragma: no cover def _compute_strategy_coefficient(distances, strategy, labels): @@ -235,7 +234,7 @@ def _compute_strategy_coefficient(distances, strategy, labels): dist = distances[ar, labels] return distances - dist[:, numpy.newaxis] raise ValueError( # pragma: no cover - "Unknwon strategy '{0}'.".format(strategy)) + f"Unknwon strategy '{strategy}'.") def _randomize_index(index, weights): @@ -479,7 +478,7 @@ def loopf(h, sumi): neg = (counters < ave).sum() if neg > 0: raise RuntimeError( # pragma: no cover - "The algorithm failed, counters={0}".format(counters)) + f"The algorithm failed, counters={counters}") _switch_clusters(labels, distances) distances_close[:] = distances[numpy.arange(X.shape[0]), labels] @@ -540,7 +539,7 @@ def _constraint_kmeans_weights(X, labels, sample_weight, centers, inertia, it, if len(set(labels)) != centers.shape[0]: if verbose and fLOG: # pragma: no cover if isinstance(verbose, int) and verbose >= 10: - fLOG("CKMeans new weights: w=%r" % weights) + fLOG(f"CKMeans new weights: w={weights!r}") else: fLOG("CKMeans new weights") weights[:] = 1 diff --git a/mlinsights/mlmodel/categories_to_integers.py b/mlinsights/mlmodel/categories_to_integers.py index f5e92e9f..34272f5d 100644 --- a/mlinsights/mlmodel/categories_to_integers.py +++ b/mlinsights/mlmodel/categories_to_integers.py @@ -73,7 +73,7 @@ def fit(self, X, y=None, **fit_params): """ if not isinstance(X, pandas.DataFrame): raise TypeError( # pragma: no cover - "this transformer only accept Dataframes, not {0}".format(type(X))) + f"this transformer only accept Dataframes, not {type(X)}") if self.columns: columns = self.columns else: @@ -89,7 +89,7 @@ def fit(self, X, y=None, **fit_params): nb = len(distinct) if nb >= max_cat: raise ValueError( # pragma: no cover - "Too many categories ({0}) for one column '{1}' max_cat={2}".format(nb, c, max_cat)) + f"Too many categories ({nb}) for one column '{c}' max_cat={max_cat}") self._categories[c] = dict((c, i) for i, c in enumerate(list(sorted(distinct)))) self._schema = self._build_schema() @@ -107,7 +107,7 @@ def _build_schema(self): new_vector = {} last = 0 for c, v in self._categories.items(): - sch = [(_[1], "{0}={1}".format(c, _[1])) + sch = [(_[1], f"{c}={_[1]}") for _ in sorted((n, d) for d, n in v.items())] if self.remove: sch = [d for d in sch if d[1] not in self.remove] @@ -133,7 +133,7 @@ def transform(self, X, y=None, **fit_params): """ if not isinstance(X, pandas.DataFrame): raise TypeError( # pragma: no cover - "X is not a dataframe: {0}".format(type(X))) + f"X is not a dataframe: {type(X)}") if self.single: b = not self.skip_errors diff --git a/mlinsights/mlmodel/classification_kmeans.py b/mlinsights/mlmodel/classification_kmeans.py index 9fbc528f..8bfd185c 100644 --- a/mlinsights/mlmodel/classification_kmeans.py +++ b/mlinsights/mlmodel/classification_kmeans.py @@ -156,7 +156,7 @@ def set_params(self, **values): pc[k[2:]] = v else: raise ValueError( # pragma: no cover - "Unexpected parameter name '{0}'".format(k)) + f"Unexpected parameter name '{k}'") self.clus.set_params(**pc) self.estimator.set_params(**pe) @@ -165,8 +165,8 @@ def __repr__(self): # pylint: disable=W0222 Overloads `repr` as *scikit-learn* now relies on the constructor signature. """ - el = ', '.join(['%s=%r' % (k, v) + el = ', '.join([f'{k}={v!r}' for k, v in self.get_params().items()]) - text = "%s(%s)" % (self.__class__.__name__, el) + text = f"{self.__class__.__name__}({el})" lines = textwrap.wrap(text, subsequent_indent=' ') return "\n".join(lines) diff --git a/mlinsights/mlmodel/decision_tree_logreg.py b/mlinsights/mlmodel/decision_tree_logreg.py index 57a9fdb4..39051a83 100644 --- a/mlinsights/mlmodel/decision_tree_logreg.py +++ b/mlinsights/mlmodel/decision_tree_logreg.py @@ -409,7 +409,7 @@ def fit(self, X, y, sample_weight=None): if self.strategy == 'perpendicular': return self._fit_perpendicular(X, y, sample_weight) raise ValueError( - "Unknown strategy '{}'.".format(self.strategy)) + f"Unknown strategy '{self.strategy}'.") def _fit_parallel(self, X, y, sample_weight): "Implements the parallel strategy." diff --git a/mlinsights/mlmodel/extended_features.py b/mlinsights/mlmodel/extended_features.py index fcaf8fcf..66224dc9 100644 --- a/mlinsights/mlmodel/extended_features.py +++ b/mlinsights/mlmodel/extended_features.py @@ -60,7 +60,7 @@ def get_feature_names(self, input_features=None): if self.kind == 'poly-slow': return self._get_feature_names_poly(input_features) raise ValueError( # pragma: no cover - "Unknown extended features '{}'.".format(self.kind)) + f"Unknown extended features '{self.kind}'.") def _get_feature_names_poly(self, input_features=None): """ @@ -72,8 +72,7 @@ def _get_feature_names_poly(self, input_features=None): i for i in range(0, self.n_input_features_)] elif len(input_features) != self.n_input_features_: raise ValueError( # pragma: no cover - "input_features should contain {} strings.".format( - self.n_input_features_)) + f"input_features should contain {self.n_input_features_} strings.") names = ["1"] if self.poly_include_bias else [] n = self.n_input_features_ @@ -126,7 +125,7 @@ def fit(self, X, y=None): elif self.kind == 'poly-slow': return self._fit_poly(X, y) raise ValueError( # pragma: no cover - "Unknown extended features '{}'.".format(self.kind)) + f"Unknown extended features '{self.kind}'.") def _fit_poly(self, X, y=None): """ @@ -155,7 +154,7 @@ def transform(self, X): if self.kind == 'poly-slow': return self._transform_poly_slow(X) raise ValueError( # pragma: no cover - "Unknown extended features '{}'.".format(self.kind)) + f"Unknown extended features '{self.kind}'.") def _transform_poly(self, X): """ diff --git a/mlinsights/mlmodel/kmeans_constraint.py b/mlinsights/mlmodel/kmeans_constraint.py index 8d77b3c0..7cbd8380 100644 --- a/mlinsights/mlmodel/kmeans_constraint.py +++ b/mlinsights/mlmodel/kmeans_constraint.py @@ -85,8 +85,7 @@ def __init__(self, n_clusters=8, init='k-means++', n_init=10, max_iter=500, self.history = history self.learning_rate = learning_rate if strategy not in ConstraintKMeans._strategy_value: - raise ValueError('strategy must be in {0}'.format( - ConstraintKMeans._strategy_value)) + raise ValueError(f'strategy must be in {ConstraintKMeans._strategy_value}') def fit(self, X, y=None, sample_weight=None, fLOG=None): """ diff --git a/mlinsights/mlmodel/kmeans_l1.py b/mlinsights/mlmodel/kmeans_l1.py index 1680ff86..979c788a 100644 --- a/mlinsights/mlmodel/kmeans_l1.py +++ b/mlinsights/mlmodel/kmeans_l1.py @@ -77,7 +77,7 @@ def _k_init(norm, X, n_clusters, random_state, n_local_trials=None): dist_fct = lambda x, y: manhattan_distances(x, y) else: raise NotImplementedError( # pragma no cover - "norm must be 'L1' or 'L2' not '{}'.".format(norm)) + f"norm must be 'L1' or 'L2' not '{norm}'.") closest_dist_sq = dist_fct(centers[0, numpy.newaxis], X) current_pot = closest_dist_sq.sum() @@ -396,7 +396,7 @@ def _tolerance(norm, X, tol): variances = numpy.sum(numpy.abs(X), axis=0) / X.shape[0] return variances.sum() raise NotImplementedError( # pragma no cover - "not implemented for norm '{}'.".format(norm)) + f"not implemented for norm '{norm}'.") class KMeansL1L2(KMeans): @@ -526,7 +526,7 @@ def fit(self, X, y=None, sample_weight=None): self._fit_l1(X=X, y=y, sample_weight=sample_weight) else: raise NotImplementedError( # pragma no cover - "Norm is not 'L1' or 'L2' but '{}'.".format(self.norm)) + f"Norm is not 'L1' or 'L2' but '{self.norm}'.") return self def _fit_l1(self, X, y=None, sample_weight=None): @@ -597,8 +597,7 @@ def _fit_l1(self, X, y=None, sample_weight=None): kmeans_single = _kmeans_single_lloyd else: raise ValueError( # pragma no cover - "Algorithm must be 'auto', 'full' or 'elkan', got" - " %s" % str(algorithm)) + f"Algorithm must be 'auto', 'full' or 'elkan', got {str(algorithm)}") seeds = random_state.randint(numpy.iinfo(numpy.int32).max, size=n_init) @@ -647,7 +646,7 @@ def transform(self, X): if self.norm == 'L1': return self._transform_l1(X) raise NotImplementedError( # pragma no cover - "Norm is not L1 or L2 but '{}'.".format(self.norm)) + f"Norm is not L1 or L2 but '{self.norm}'.") def _transform_l1(self, X): """ @@ -679,7 +678,7 @@ def predict(self, X, sample_weight=None): if self.norm == 'L1': return self._predict_l1(X, sample_weight=sample_weight) raise NotImplementedError( # pragma no cover - "Norm is not L1 or L2 but '{}'.".format(self.norm)) + f"Norm is not L1 or L2 but '{self.norm}'.") def _predict_l1(self, X, sample_weight=None, return_distances=False): """ diff --git a/mlinsights/mlmodel/ml_featurizer.py b/mlinsights/mlmodel/ml_featurizer.py index cdfc49be..0daea4c2 100644 --- a/mlinsights/mlmodel/ml_featurizer.py +++ b/mlinsights/mlmodel/ml_featurizer.py @@ -67,7 +67,7 @@ def is_vector(X): return False return True raise TypeError( # pragma no cover - "Unable to guess if X is a vector, type(X)={0}".format(type(X))) + f"Unable to guess if X is a vector, type(X)={type(X)}") def wrap_predict_sklearn(X, fct, many): diff --git a/mlinsights/mlmodel/piecewise_estimator.py b/mlinsights/mlmodel/piecewise_estimator.py index 769c87ec..f150a9d7 100644 --- a/mlinsights/mlmodel/piecewise_estimator.py +++ b/mlinsights/mlmodel/piecewise_estimator.py @@ -110,8 +110,7 @@ def __init__(self, binner=None, estimator=None, n_jobs=None, verbose=False): "estimator cannot be null.") if binner is None: raise TypeError( # pragma: no cover - "Unsupported options for binner=='tree' and model {}.".format( - type(estimator))) + f"Unsupported options for binner=='tree' and model {type(estimator)}.") elif binner == "bins": binner = KBinsDiscretizer() self.binner = binner diff --git a/mlinsights/mlmodel/predictable_tsne.py b/mlinsights/mlmodel/predictable_tsne.py index 4b5ec85c..e54dad46 100644 --- a/mlinsights/mlmodel/predictable_tsne.py +++ b/mlinsights/mlmodel/predictable_tsne.py @@ -49,16 +49,14 @@ def __init__(self, normalizer=None, transformer=None, estimator=None, self.keep_tsne_outputs = keep_tsne_outputs if normalizer is not None and not hasattr(normalizer, "transform"): raise AttributeError( # pragma: no cover - "normalizer {} does not have a 'transform' method.".format( - type(normalizer))) + f"normalizer {type(normalizer)} does not have a 'transform' method.") if not hasattr(transformer, "fit_transform"): raise AttributeError( # pragma: no cover "transformer {} does not have a 'fit_transform' method.".format( type(transformer))) if not hasattr(estimator, "predict"): raise AttributeError( # pragma: no cover - "estimator {} does not have a 'predict' method.".format( - type(estimator))) + f"estimator {type(estimator)} does not have a 'predict' method.") self.normalize = normalize def fit(self, X, y, sample_weight=None): diff --git a/mlinsights/mlmodel/quantile_regression.py b/mlinsights/mlmodel/quantile_regression.py index 6530b9ca..2afaac5a 100644 --- a/mlinsights/mlmodel/quantile_regression.py +++ b/mlinsights/mlmodel/quantile_regression.py @@ -161,7 +161,7 @@ def compute_z(Xm, beta, Y, W, delta=0.0001): self.n_iter_ = i if self.verbose: print( # pragma: no cover - '[QuantileLinearRegression.fit] iter={0} error={1}'.format(i + 1, E)) + f'[QuantileLinearRegression.fit] iter={i + 1} error={E}') if lastE is not None and lastE == E: break lastE = E diff --git a/mlinsights/mlmodel/sklearn_testing.py b/mlinsights/mlmodel/sklearn_testing.py index 621c20d9..921dd584 100644 --- a/mlinsights/mlmodel/sklearn_testing.py +++ b/mlinsights/mlmodel/sklearn_testing.py @@ -102,8 +102,7 @@ def assertIsInstance(self, inst, cltype): "checks that one instance is from one type" if not isinstance(inst, cltype): raise AssertionError( - "Unexpected type {} != {}.".format( - type(inst), cltype)) + f"Unexpected type {type(inst)} != {cltype}.") cls = _ExtTestCase return cls() @@ -136,7 +135,7 @@ def test_sklearn_clone(fct_model, ext=None, copy_fitted=False): p1 = pprint.pformat(p1) p2 = pprint.pformat(p2) raise AssertionError( - "Differences between\n----\n{0}\n----\n{1}".format(p1, p2)) from e + f"Differences between\n----\n{p1}\n----\n{p2}") from e for k in sorted(p1): if isinstance(p1[k], BaseEstimator) and isinstance(p2[k], BaseEstimator): @@ -149,15 +148,14 @@ def test_sklearn_clone(fct_model, ext=None, copy_fitted=False): ext.assertEqual(p1[k], p2[k]) except AssertionError: # pragma no cover raise AssertionError( # pylint: disable=W0707 - "Difference for key '{0}'\n==1 {1}\n==2 {2}".format( - k, p1[k], p2[k])) + f"Difference for key '{k}'\n==1 {p1[k]}\n==2 {p2[k]}") return conv, cloned def _assert_list_equal(l1, l2, ext): if len(l1) != len(l2): raise AssertionError( # pragma no cover - "Lists have different length {0} != {1}".format(len(l1), len(l2))) + f"Lists have different length {len(l1)} != {len(l2)}") for a, b in zip(l1, l2): if isinstance(a, tuple) and isinstance(b, tuple): _assert_tuple_equal(a, b, ext) @@ -167,13 +165,13 @@ def _assert_list_equal(l1, l2, ext): def _assert_dict_equal(a, b, ext): if not isinstance(a, dict): # pragma no cover - raise TypeError('a is not dict but {0}'.format(type(a))) + raise TypeError(f'a is not dict but {type(a)}') if not isinstance(b, dict): # pragma no cover - raise TypeError('b is not dict but {0}'.format(type(b))) + raise TypeError(f'b is not dict but {type(b)}') rows = [] for key in sorted(b): if key not in a: - rows.append("** Added key '{0}' in b".format(key)) + rows.append(f"** Added key '{key}' in b") elif isinstance(a[key], BaseEstimator) and isinstance(b[key], BaseEstimator): assert_estimator_equal(a[key], b[key], ext) else: @@ -183,7 +181,7 @@ def _assert_dict_equal(a, b, ext): key, id(a[key]), id(b[key]), a[key], b[key])) for key in sorted(a): if key not in b: - rows.append("** Removed key '{0}' in a".format(key)) + rows.append(f"** Removed key '{key}' in a") if len(rows) > 0: raise AssertionError( # pragma: no cover "Dictionaries are different\n{0}".format('\n'.join(rows))) @@ -192,7 +190,7 @@ def _assert_dict_equal(a, b, ext): def _assert_tuple_equal(t1, t2, ext): if len(t1) != len(t2): # pragma no cover raise AssertionError( - "Lists have different length {0} != {1}".format(len(t1), len(t2))) + f"Lists have different length {len(t1)} != {len(t2)}") for a, b in zip(t1, t2): if isinstance(a, BaseEstimator) and isinstance(b, BaseEstimator): assert_estimator_equal(a, b, ext) @@ -293,7 +291,7 @@ def adjust(obj1, obj2): v1 = getattr(obj1, k) if callable(v1): raise RuntimeError( # pragma: no cover - "Cannot migrate trained parameters for {}.".format(obj1)) + f"Cannot migrate trained parameters for {obj1}.") elif isinstance(v1, BaseEstimator): v1 = getattr(obj1, k) setattr(obj2, k, clone_with_fitted_parameters(v1)) @@ -305,7 +303,7 @@ def adjust(obj1, obj2): setattr(obj2, k, clone_with_fitted_parameters(v1)) else: raise RuntimeError( # pragma: no cover - "Cloned object is missing '{0}' in {1}.".format(k, obj2)) + f"Cloned object is missing '{k}' in {obj2}.") if isinstance(est, BaseEstimator): cloned = clone(est) diff --git a/mlinsights/mlmodel/sklearn_text.py b/mlinsights/mlmodel/sklearn_text.py index d1953037..9be713b8 100644 --- a/mlinsights/mlmodel/sklearn_text.py +++ b/mlinsights/mlmodel/sklearn_text.py @@ -61,8 +61,7 @@ def space_join(tokens): new_tokens.extend(token) else: raise TypeError( # pragma: no cover - "Unable to build a n-grams out of {}.".format( - tokens)) + f"Unable to build a n-grams out of {tokens}.") return tuple(new_tokens) for n in range(min_n, diff --git a/mlinsights/mlmodel/sklearn_transform_inv_fct.py b/mlinsights/mlmodel/sklearn_transform_inv_fct.py index b83687fe..8d97c660 100644 --- a/mlinsights/mlmodel/sklearn_transform_inv_fct.py +++ b/mlinsights/mlmodel/sklearn_transform_inv_fct.py @@ -51,8 +51,7 @@ def __init__(self, fct, fct_inv=None): opts = self.__class__.available_fcts() if fct not in opts: raise ValueError( # pragma: no cover - "Unknown fct '{}', it should in {}.".format( - fct, list(sorted(opts)))) + f"Unknown fct '{fct}', it should in {list(sorted(opts))}.") else: if fct_inv is None: raise ValueError( @@ -173,8 +172,7 @@ def _find_closest(self, cl): if self.knn_perm_.dtype in (numpy.int32, numpy.int64): return int(res) raise NotImplementedError( # pragma: no cover - "The function does not work for type {}.".format( - self.knn_perm_.dtype)) + f"The function does not work for type {self.knn_perm_.dtype}.") def transform(self, X, y): """ @@ -207,7 +205,7 @@ def transform(self, X, y): # y is probababilies or raw score if len(y.shape) != 2: raise RuntimeError( - "yp should be a matrix but has shape {}.".format(y.shape)) + f"yp should be a matrix but has shape {y.shape}.") cl = [(v, k) for k, v in self.permutation_.items()] cl.sort() new_perm = {} diff --git a/mlinsights/mlmodel/transfer_transformer.py b/mlinsights/mlmodel/transfer_transformer.py index 879d573e..eadf7e5c 100644 --- a/mlinsights/mlmodel/transfer_transformer.py +++ b/mlinsights/mlmodel/transfer_transformer.py @@ -50,8 +50,7 @@ def __init__(self, estimator, method=None, copy_estimator=True, "predict in object {}".format(type(estimator))) if not hasattr(estimator, method): raise AttributeError( # pragma: no cover - "Cannot find method '{}' in object {}".format( - method, type(estimator))) + f"Cannot find method '{method}' in object {type(estimator)}") self.method = method def fit(self, X=None, y=None, sample_weight=None): diff --git a/mlinsights/mltree/tree_digitize.py b/mlinsights/mltree/tree_digitize.py index 82a87f20..dcc1f03e 100644 --- a/mlinsights/mltree/tree_digitize.py +++ b/mlinsights/mltree/tree_digitize.py @@ -59,7 +59,7 @@ def digitize2tree(bins, right=False): """ if not right: raise RuntimeError( - "right must be True not right=%r" % right) + f"right must be True not right={right!r}") ascending = len(bins) <= 1 or bins[0] < bins[1] if not ascending: @@ -141,8 +141,7 @@ def add_nodes(parent, i, j, is_left): add_nodes(n, index, j, False) return n raise NotImplementedError( # pragma: no cover - "Unexpected case where i=%r, j=%r, is_left=%r." % ( - i, j, is_left)) + f"Unexpected case where i={i!r}, j={j!r}, is_left={is_left!r}.") index = len(bins) // 2 add_root(index) diff --git a/mlinsights/mltree/tree_structure.py b/mlinsights/mltree/tree_structure.py index 5909e1bb..88faeb47 100644 --- a/mlinsights/mltree/tree_structure.py +++ b/mlinsights/mltree/tree_structure.py @@ -15,7 +15,7 @@ def _get_tree(obj): if hasattr(obj, "tree_"): return obj.tree_ raise AttributeError( # pragma: no cover - "obj is no tree: {}".format(type(obj))) + f"obj is no tree: {type(obj)}") def tree_leave_index(model): @@ -79,7 +79,7 @@ def tree_find_common_node(tree, i, j, parents=None): if pj is not None and pj == i: return i, path_i[pos:], path_j[pos:] raise RuntimeError( # pragma: no cover - "Paths are equal, i={} and j={} must be differet.".format(i, j)) + f"Paths are equal, i={i} and j={j} must be differet.") def tree_node_parents(tree): diff --git a/mlinsights/plotting/gallery.py b/mlinsights/plotting/gallery.py index 011cae54..d79e84fc 100644 --- a/mlinsights/plotting/gallery.py +++ b/mlinsights/plotting/gallery.py @@ -40,7 +40,7 @@ def plot_gallery_images(imgs, texts=None, width=4, return_figure=False, height, width = imgs.shape if ax is not None and ax.shape != imgs.shape: raise ValueError( # pragma: no cover - "ax.shape {0} != imgs.shape {1}".format(ax.shape, imgs.shape)) + f"ax.shape {ax.shape} != imgs.shape {imgs.shape}") imgs = imgs.ravel() if texts is not None: texts = texts.ravel() @@ -77,7 +77,7 @@ def plot_gallery_images(imgs, texts=None, width=4, return_figure=False, im = Image.open(io.BytesIO(content)) except OSError as e: # pragma: no cover raise RuntimeError( - "Unable to read image '{}'.".format(img)) from e + f"Unable to read image '{img}'.") from e else: # local file if folder_image is not None: diff --git a/mlinsights/plotting/visualize.py b/mlinsights/plotting/visualize.py index 4265aea2..129be927 100644 --- a/mlinsights/plotting/visualize.py +++ b/mlinsights/plotting/visualize.py @@ -26,7 +26,7 @@ def _get_name(context, prefix='-v-', info=None, data=None): prefix = former_data[prefix] if isinstance(prefix, int): raise TypeError( # pragma: no cover - "prefix must be a string.\ninfo={}".format(info)) + f"prefix must be a string.\ninfo={info}") sug = "%s%d" % (prefix, context['n']) while sug in context['names']: context['n'] += 1 @@ -40,8 +40,7 @@ def _get_name_simple(name, data): res = data[name] if isinstance(res, int): raise RuntimeError( # pragma: no cover - "Column name is still a number and not a name: {} and {}." - "".format(name, data)) + f"Column name is still a number and not a name: {name} and {data}.") return res if isinstance(pipe, Pipeline): @@ -181,11 +180,11 @@ def _get_name_simple(name, data): info = [info] else: raise NotImplementedError( # pragma: no cover - "Not yet implemented for keyword '{}'.".format(type(pipe))) + f"Not yet implemented for keyword '{type(pipe)}'.") return info raise NotImplementedError( # pragma: no cover - "Not yet implemented for {}.".format(type(pipe))) + f"Not yet implemented for {type(pipe)}.") def pipeline2dot(pipe, data, **params): @@ -226,7 +225,7 @@ def pipeline2dot(pipe, data, **params): data['X%d' % i] = 'sch0:f%d' % i elif not isinstance(raw_data, list): raise TypeError( # pragma: no cover - "Unexpected data type: {}.".format(type(raw_data))) + f"Unexpected data type: {type(raw_data)}.") options = { 'orientation': 'portrait', @@ -240,7 +239,7 @@ def pipeline2dot(pipe, data, **params): exp = ["digraph{"] for opt in ['orientation', 'pad', 'nodesep', 'ranksep']: if opt in options: - exp.append(" {}={};".format(opt, options[opt])) + exp.append(f" {opt}={options[opt]};") fontsize = 8 info = [dict(schema_after=data)] names = OrderedDict() @@ -254,8 +253,8 @@ def pipeline2dot(pipe, data, **params): schema = line['schema_after'] labs = [] for c, col in enumerate(schema): - columns[col] = 'sch0:f{0}'.format(c) - labs.append(" {1}".format(c, col)) + columns[col] = f'sch0:f{c}' + labs.append(f" {col}") node = ' sch0[label="{0}",shape=record,fontsize={1}];'.format( "|".join(labs), params.get('fontsize', fontsize)) exp.append(node) @@ -280,20 +279,20 @@ def pipeline2dot(pipe, data, **params): inp, pprint.pformat(columns), '\n'.join(exp))) else: nc = columns.get(inp, inp) - edge = ' {0} -> node{1};'.format(nc, i) + edge = f' {nc} -> node{i};' exp.append(edge) labs = [] for c, out in enumerate(line['outputs']): - columns[out] = 'sch{0}:f{1}'.format(i, c) - labs.append(" {1}".format(c, out)) + columns[out] = f'sch{i}:f{c}' + labs.append(f" {out}") node = ' sch{0}[label="{1}",shape=record,fontsize={2}];'.format( i, "|".join(labs), params.get('fontsize', fontsize)) exp.append(node) for out in line['outputs']: nc = columns[out] - edge = ' node{1} -> {0};'.format(nc, i) + edge = f' node{i} -> {nc};' if edge not in exp: exp.append(edge) @@ -345,9 +344,9 @@ def pipeline2str(pipe, indent=3): for coor, model, vs in enumerate_pipeline_models(pipe): spaces = " " * indent * (len(coor) - 1) if vs is None: - msg = "{}{}".format(spaces, model.__class__.__name__) + msg = f"{spaces}{model.__class__.__name__}" else: v = ','.join(map(str, vs)) - msg = "{}{}({})".format(spaces, model.__class__.__name__, v) + msg = f"{spaces}{model.__class__.__name__}({v})" rows.append(msg) return "\n".join(rows) diff --git a/mlinsights/search_rank/search_engine_predictions_images.py b/mlinsights/search_rank/search_engine_predictions_images.py index b0bb698f..22f74347 100644 --- a/mlinsights/search_rank/search_engine_predictions_images.py +++ b/mlinsights/search_rank/search_engine_predictions_images.py @@ -56,8 +56,7 @@ def _prepare_fit(self, data=None, features=None, metadata=None, "".format(type(iter_images))) if iter_images.batch_size != 1: raise ValueError( # pragma: no cover - "batch_size must be 1 not {0}".format( - iter_images.batch_size)) + f"batch_size must be 1 not {iter_images.batch_size}") self.iter_images_ = iter_images if n is None: n = len(iter_images) @@ -66,7 +65,7 @@ def _prepare_fit(self, data=None, features=None, metadata=None, "Iterator does not iterate on images but numpy arrays (not implemented).") else: raise TypeError( # pragma: no cover - "Unexpected data type {0}.".format(type(data))) + f"Unexpected data type {type(data)}.") def get_current_index(flow): "get current index" @@ -87,11 +86,11 @@ def accessor(iter_images): im, name = acc(i, it) if not isinstance(name, str): raise TypeError( # pragma: no cover - "name should be a string, not {0}".format(type(name))) + f"name should be a string, not {type(name)}") yield im[0], dict(name=name, i=i) if fLOG and i % 10000 == 0: fLOG( - '[SearchEnginePredictionImages.fit] i={}/{} - {}'.format(i, n, name)) + f'[SearchEnginePredictionImages.fit] i={i}/{n} - {name}') super()._prepare_fit(data=iterator_feature_meta(), transform=transform) def fit(self, iter_images, n=None, fLOG=None): # pylint: disable=W0237 @@ -127,22 +126,21 @@ def kneighbors(self, iter_images, n_neighbors=None): # pylint: disable=W0237 X = from_numpy(iter_images[numpy.newaxis, :, :, :]) return super().kneighbors(X, n_neighbors=n_neighbors) raise RuntimeError( # pragma: no cover - "Unknown module '{0}'.".format(self.module_)) + f"Unknown module '{self.module_}'.") elif "keras" in str(iter_images): # pragma: no cover if self.module_ != "keras": raise RuntimeError( # pragma: no cover - "Keras object but {0} was used to train the KNN.".format(self.module_)) + f"Keras object but {self.module_} was used to train the KNN.") # We delay the import as keras backend is not necessarily installed. # keras, it expects an iterator. from keras.preprocessing.image import Iterator # pylint: disable=E0401,C0415,E0611 from keras_preprocessing.image import DirectoryIterator, NumpyArrayIterator # pylint: disable=E0401,C0415,E0611 if not isinstance(iter_images, (Iterator, DirectoryIterator, NumpyArrayIterator)): raise NotImplementedError( # pragma: no cover - "iter_images must be a keras Iterator. No option implemented for type {0}.".format(type(iter_images))) + f"iter_images must be a keras Iterator. No option implemented for type {type(iter_images)}.") if iter_images.batch_size != 1: raise ValueError( # pragma: no cover - "batch_size must be 1 not {0}".format( - iter_images.batch_size)) + f"batch_size must be 1 not {iter_images.batch_size}") for img in iter_images: X = img[0] break @@ -150,7 +148,7 @@ def kneighbors(self, iter_images, n_neighbors=None): # pylint: disable=W0237 elif "torch" in str(type(iter_images)): if self.module_ != "torch": raise RuntimeError( # pragma: no cover - "Torch object but {0} was used to train the KNN.".format(self.module_)) + f"Torch object but {self.module_} was used to train the KNN.") # torch: it expects a tensor X = iter_images return super().kneighbors(X, n_neighbors=n_neighbors) diff --git a/mlinsights/search_rank/search_engine_vectors.py b/mlinsights/search_rank/search_engine_vectors.py index eeec1207..86a4209f 100644 --- a/mlinsights/search_rank/search_engine_vectors.py +++ b/mlinsights/search_rank/search_engine_vectors.py @@ -102,7 +102,7 @@ def transform(vec, many): if not isinstance(tradd, numpy.ndarray): if transform is None: raise TypeError( # pragma: no cover - "feature should be of type numpy.array not {}".format(type(tradd))) + f"feature should be of type numpy.array not {type(tradd)}") else: raise TypeError( # pragma: no cover "output of method transform ({}) should be of type numpy.array not {}".format( diff --git a/mlinsights/sklapi/sklearn_base.py b/mlinsights/sklapi/sklearn_base.py index 64190c35..150d69b1 100644 --- a/mlinsights/sklapi/sklearn_base.py +++ b/mlinsights/sklapi/sklearn_base.py @@ -94,13 +94,13 @@ def compare_params(p1, p2, exc=True): for k in p1: if k not in p2: if exc: - raise KeyError("Key '{0}' was removed.".format(k)) + raise KeyError(f"Key '{k}' was removed.") else: return False for k in p2: if k not in p1: if exc: - raise KeyError("Key '{0}' was added.".format(k)) + raise KeyError(f"Key '{k}' was added.") return False for k in sorted(p1): v1, v2 = p1[k], p2[k] @@ -134,7 +134,7 @@ def compare_params(p1, p2, exc=True): if not b: if exc: raise ValueError( - "Values for key '{0}' are different.\n---\n{1}\n---\n{2}".format(k, v1, v2)) + f"Values for key '{k}' are different.\n---\n{v1}\n---\n{v2}") else: return False return True @@ -143,5 +143,5 @@ def __repr__(self): """ usual """ - res = "{0}({1})".format(self.__class__.__name__, str(self.P)) + res = f"{self.__class__.__name__}({str(self.P)})" return "\n".join(textwrap.wrap(res, subsequent_indent=" ")) diff --git a/mlinsights/sklapi/sklearn_base_transform_learner.py b/mlinsights/sklapi/sklearn_base_transform_learner.py index 0123ca67..d5cfab10 100644 --- a/mlinsights/sklapi/sklearn_base_transform_learner.py +++ b/mlinsights/sklapi/sklearn_base_transform_learner.py @@ -85,7 +85,7 @@ def __init__(self, model=None, method=None, **kwargs): method = name if method is None: raise ValueError( # pragma: no cover - "Unable to guess a default method for '{0}'".format(repr(model))) + f"Unable to guess a default method for '{repr(model)}'") self.method = method self._set_method(method) @@ -105,12 +105,12 @@ def _set_method(self, method): self.method_ = self.model.transform else: raise ValueError( # pragma: no cover - "Unexpected method '{0}'".format(method)) + f"Unexpected method '{method}'") elif callable(method): self.method_ = method else: raise TypeError( # pragma: no cover - "Unable to find the transform method, method={0}".format(method)) + f"Unable to find the transform method, method={method}") def fit(self, X, y=None, **kwargs): """ @@ -167,15 +167,14 @@ def set_params(self, **values): del values['model'] elif not hasattr(self, 'model') or self.model is None: raise KeyError( # pragma: no cover - "Missing key '{0}' in [{1}]".format( - 'model', ', '.join(sorted(values)))) + f"Missing key 'model' in [{', '.join(sorted(values))}]") if 'method' in values: self._set_method(values['method']) del values['method'] for k in values: if not k.startswith('model__'): raise ValueError( # pragma: no cover - "Parameter '{0}' must start with 'model__'.".format(k)) + f"Parameter '{k}' must start with 'model__'.") d = len('model__') pars = {k[d:]: v for k, v in values.items()} self.model.set_params(**pars) @@ -193,6 +192,5 @@ def __repr__(self): """ rp = repr(self.model) rps = repr(self.P) - res = "{0}(model={1}, method={2}, {3})".format( - self.__class__.__name__, rp, self.method, rps) + res = f"{self.__class__.__name__}(model={rp}, method={self.method}, {rps})" return "\n".join(textwrap.wrap(res, subsequent_indent=" ")) diff --git a/mlinsights/sklapi/sklearn_base_transform_stacking.py b/mlinsights/sklapi/sklearn_base_transform_stacking.py index 13b68f98..f34911b2 100644 --- a/mlinsights/sklapi/sklearn_base_transform_stacking.py +++ b/mlinsights/sklapi/sklearn_base_transform_stacking.py @@ -68,12 +68,12 @@ def __init__(self, models=None, method=None, **kwargs): raise ValueError("models cannot be None") # pragma: no cover if not isinstance(models, list): raise TypeError( # pragma: no cover - "models must be a list not {0}".format(type(models))) + f"models must be a list not {type(models)}") if method is None: method = 'predict' if not isinstance(method, str): raise TypeError( # pragma: no cover - "Method must be a string not {0}".format(type(method))) + f"Method must be a string not {type(method)}") self.method = method if isinstance(method, list): if len(method) != len(models): @@ -153,7 +153,7 @@ def get_params(self, deep=True): for i, m in enumerate(self.models): par = m.get_params(deep) for k, v in par.items(): - res["models_{0}__".format(i) + k] = v + res[f"models_{i}__" + k] = v return res def set_params(self, **values): @@ -171,7 +171,7 @@ def set_params(self, **values): for k, v in values.items(): if not k.startswith('models_'): raise ValueError( # pragma: no cover - "Parameter '{0}' must start with 'models_'.".format(k)) + f"Parameter '{k}' must start with 'models_'.") d = len('models_') pars = [{} for m in self.models] for k, v in values.items(): diff --git a/mlinsights/sklapi/sklearn_parameters.py b/mlinsights/sklapi/sklearn_parameters.py index 932c655d..874d0d49 100644 --- a/mlinsights/sklapi/sklearn_parameters.py +++ b/mlinsights/sklapi/sklearn_parameters.py @@ -39,7 +39,7 @@ def validate(self, name, value): """ if name.startswith("_") or name.endswith("_"): raise SkException( # pragma: no cover - "Parameter name must not start by '_': '{0}'".format(name)) + f"Parameter name must not start by '_': '{name}'") @property def Keys(self): @@ -55,9 +55,9 @@ def __repr__(self): def fmt(v): "formatting function" if isinstance(v, str): - return "'{0}'".format(v) + return f"'{v}'" return repr(v) - text = ", ".join("{0}={1}".format(k, fmt(getattr(self, k))) + text = ", ".join(f"{k}={fmt(getattr(self, k))}" for k in sorted(self.Keys)) return "\n".join(textwrap.wrap(text, subsequent_indent=" ")) diff --git a/mlinsights/timeseries/agg.py b/mlinsights/timeseries/agg.py index 36e0ef8c..b6076c12 100644 --- a/mlinsights/timeseries/agg.py +++ b/mlinsights/timeseries/agg.py @@ -65,7 +65,7 @@ def round_(serie, freq, per): days=t.day, hours=t.hour, minutes=t.minute), pyres)) raise ValueError( # pragma: no cover - "Unknown frequency '{}'.".format(per)) + f"Unknown frequency '{per}'.") agg_name = _get_column_name(df) df = df.copy() @@ -74,7 +74,7 @@ def round_(serie, freq, per): df[agg_name] = round_(df[index], freq, per) else: raise ValueError( # pragma: no cover - "Unknown time unit '{}'.".format(unit)) + f"Unknown time unit '{unit}'.") if not isinstance(values, list): values = [values] if agg == 'sum': @@ -92,5 +92,5 @@ def round_(serie, freq, per): gr[c] /= su else: raise ValueError( # pragma: no cover - "Unknown aggregation '{}'.".format(agg)) + f"Unknown aggregation '{agg}'.") return gr.sort_values(agg_name).reset_index(drop=True) diff --git a/mlinsights/timeseries/ar.py b/mlinsights/timeseries/ar.py index 4ae3b734..feb98c18 100644 --- a/mlinsights/timeseries/ar.py +++ b/mlinsights/timeseries/ar.py @@ -42,7 +42,7 @@ def __init__(self, estimator="dummy", past=1, delay1=1, delay2=2, past=past, delay1=delay1, delay2=delay2, use_all_past=use_all_past) if not hasattr(self.estimator, "fit"): raise TypeError( # pragma: no cover - "estimator is not an estimator but {}".format(type(estimator))) + f"estimator is not an estimator but {type(estimator)}") def fit(self, X, y, sample_weight=None): """ diff --git a/mlinsights/timeseries/metrics.py b/mlinsights/timeseries/metrics.py index 6ea22371..405ae805 100644 --- a/mlinsights/timeseries/metrics.py +++ b/mlinsights/timeseries/metrics.py @@ -19,8 +19,7 @@ def ts_mape(expected_y, predicted_y, sample_weight=None): """ if len(expected_y) != len(predicted_y): raise ValueError( # pragma: no cover - 'Size mismatch {} != {}.'.format( - len(expected_y), len(predicted_y))) + f'Size mismatch {len(expected_y)} != {len(predicted_y)}.') expected_y = numpy.squeeze(expected_y) predicted_y = numpy.squeeze(predicted_y) mask = numpy.isnan(predicted_y) diff --git a/mlinsights/timeseries/patterns.py b/mlinsights/timeseries/patterns.py index f329e28c..6535c324 100644 --- a/mlinsights/timeseries/patterns.py +++ b/mlinsights/timeseries/patterns.py @@ -27,14 +27,14 @@ def find_ts_group_pattern(ttime, values, names, name_subset=None, """ for var, na in zip([ttime, values, names], ['ttime', 'values', 'names']): if not isinstance(var, numpy.ndarray): - raise TypeError("'{}' must an array not {}".format(na, type(var))) + raise TypeError(f"'{na}' must an array not {type(var)}") # builds features set_names = set(names) if name_subset is not None: set_names &= set(name_subset) if fLOG: fLOG( # pragma: no cover - '[find_ts_group_pattern] build features, {} groups'.format(len(set_names))) + f'[find_ts_group_pattern] build features, {len(set_names)} groups') gr_names = [] to_merge = [] for name in set_names: @@ -63,7 +63,7 @@ def find_ts_group_pattern(ttime, values, names, name_subset=None, # cluster if fLOG: fLOG( # pragma: no cover - '[find_ts_group_pattern] clustering, shape={}'.format(gr_feats.shape)) + f'[find_ts_group_pattern] clustering, shape={gr_feats.shape}') if estimator is None: estimator = KMeans() estimator.fit(gr_feats) @@ -73,7 +73,7 @@ def find_ts_group_pattern(ttime, values, names, name_subset=None, dist = estimator.transform(gr_feats) if fLOG: fLOG( # pragma: no cover - '[find_ts_group_pattern] number of clusters: {}'.format(len(set(pred)))) + f'[find_ts_group_pattern] number of clusters: {len(set(pred))}') row_name = {n: i for i, n in enumerate(gr_names)} clusters = numpy.empty(ttime.shape[0], dtype=pred.dtype) diff --git a/mlinsights/timeseries/utils.py b/mlinsights/timeseries/utils.py index 82b45160..c7d5c2a1 100644 --- a/mlinsights/timeseries/utils.py +++ b/mlinsights/timeseries/utils.py @@ -61,7 +61,7 @@ def build_ts_X_y(model, X, y, weights=None, same_rows=False): """ if not hasattr(model, "use_all_past") or not hasattr(model, "past"): raise TypeError( # pragma: no cover - "model must be of type BaseTimeSeries not {}".format(type(model))) + f"model must be of type BaseTimeSeries not {type(model)}") if same_rows: if model.use_all_past: ncol = X.shape[1] if X is not None else 0 @@ -163,10 +163,10 @@ def check_ts_X_y(model, X, y): return # pragma: no cover if X.dtype not in (numpy.float32, numpy.float64): raise TypeError( - "Features must be of type float32 and float64 not {}.".format(X.dtype)) + f"Features must be of type float32 and float64 not {X.dtype}.") if y is not None and y.dtype not in (numpy.float32, numpy.float64): raise TypeError( # pragma: no cover - "Features must be of type float32 and float64 not {}.".format(y.dtype)) + f"Features must be of type float32 and float64 not {y.dtype}.") cst = model.past if (hasattr(model, 'preprocessing_') and model.preprocessing_ is not None): cst += model.preprocessing_.context_length @@ -178,11 +178,10 @@ def check_ts_X_y(model, X, y): return # pragma: no cover if y.shape[0] != X.shape[0]: raise AssertionError( # pragma: no cover - "X and y must have the same number of rows {} != {}.".format( - X.shape[0], y.shape[0])) + f"X and y must have the same number of rows {X.shape[0]} != {y.shape[0]}.") if len(y.shape) > 1 and y.shape[1] != 1: raise AssertionError( # pragma: no cover - "y must be 1-dimensional not has shape {}.".format(y.shape)) + f"y must be 1-dimensional not has shape {y.shape}.") if y.shape[0] < cst: raise AssertionError( # pragma: no cover "y is not enough past data to predict, " diff --git a/setup.py b/setup.py index 901ccb4e..7e0ea026 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ ######### project_var_name = "mlinsights" -versionPython = "%s.%s" % (sys.version_info.major, sys.version_info.minor) +versionPython = f"{sys.version_info.major}.{sys.version_info.minor}" path = "Lib/site-packages/" + project_var_name readme = 'README.rst' history = "HISTORY.rst" @@ -74,13 +74,13 @@ def get_extensions(): folder = "mltree" if name == "_tree_digitize" else "mlmodel" if isinstance(name, tuple): m = Extension(pattern1 % (folder, name[0]), - ['mlinsights/%s/%s.pyx' % (folder, name[1])], + [f'mlinsights/{folder}/{name[1]}.pyx'], include_dirs=[numpy.get_include()], extra_compile_args=["-O3"], language='c') else: m = Extension(pattern1 % (folder, name), - ['mlinsights/%s/%s.pyx' % (folder, name)], + [f'mlinsights/{folder}/{name}.pyx'], include_dirs=[numpy.get_include()], extra_compile_args=["-O3"], language='c') @@ -100,7 +100,7 @@ def get_extensions(): ext_modules = get_extensions() except ImportError as e: warnings.warn( - "Unable to build C++ extension with missing dependencies %r." % e) + f"Unable to build C++ extension with missing dependencies {e!r}.") ext_modules = None # setup @@ -111,8 +111,8 @@ def get_extensions(): author='Xavier Dupré', author_email='xavier.dupre@gmail.com', license="MIT", - url="http://www.xavierdupre.fr/app/%s/helpsphinx/index.html" % project_var_name, - download_url="https://github.com/sdpython/%s/" % project_var_name, + url=f"http://www.xavierdupre.fr/app/{project_var_name}/helpsphinx/index.html", + download_url=f"https://github.com/sdpython/{project_var_name}/", description=DESCRIPTION, long_description=read_readme(__file__), cmdclass=default_cmdclass(),