From 6d0e7c7615e15de5c269fc68dd78599b02bf706b Mon Sep 17 00:00:00 2001 From: Maurice Date: Tue, 10 Nov 2026 15:22:44 +0100 Subject: [PATCH 1/5] Answer Questions --- numpy_questions.py | 15 ++++++++---- sklearn_questions.py | 54 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/numpy_questions.py b/numpy_questions.py index 21fcec4b..ed82eedd 100644 --- a/numpy_questions.py +++ b/numpy_questions.py @@ -15,6 +15,7 @@ This will be enforced with `flake8`. You can check that there is no flake8 errors by calling `flake8` at the root of the repo. """ + import numpy as np @@ -37,12 +38,12 @@ def max_index(X): If the input is not a numpy array or if the shape is not 2D. """ - i = 0 - j = 0 + i = np.max(X) + j = np.argmax(X) # TODO - return i, j + return np.array(i, j) def wallis_product(n_terms): @@ -64,4 +65,10 @@ def wallis_product(n_terms): """ # XXX : The n_terms is an int that corresponds to the number of # terms in the product. For example 10000. - return 0. + + my_pi = 1 + + for i in range(n_terms): + my_pi *= (4 * (i**2)) / (4 * (i**2) - 1) + + return my_pi diff --git a/sklearn_questions.py b/sklearn_questions.py index f65038c6..c884f522 100644 --- a/sklearn_questions.py +++ b/sklearn_questions.py @@ -19,6 +19,7 @@ for the methods you code and for the class. The docstring will be checked using `pydocstyle` that you can also call at the root of the repo. """ + import numpy as np from sklearn.base import BaseEstimator from sklearn.base import ClassifierMixin @@ -35,40 +36,69 @@ def __init__(self): # noqa: D107 pass def fit(self, X, y): - """Write docstring. + """Memorizes the examples in X and their classes in y + + Variables: + X -> features of the training data + y -> classes of the training data - And describe parameters + Returns: + self-> fitted One-Nearest-Neighbor model """ + X, y = check_X_y(X, y) check_classification_targets(y) self.classes_ = np.unique(y) self.n_features_in_ = X.shape[1] + self.X_train_ = X.copy() + self.y_train_ = y.copy() + # XXX fix + return self def predict(self, X): - """Write docstring. + """Predicts the class of the given X, from the class of the Nearest Neighbor in the training set + + Variables: + X -> features table from which we want to predict the class + self -> fitted model - And describe parameters + Returns: + y_pred -> the predicted classes for X """ - check_is_fitted(self) + check_is_fitted(self, ["X_train_", "y_train_"]) X = check_array(X) - y_pred = np.full( - shape=len(X), fill_value=self.classes_[0], - dtype=self.classes_.dtype - ) + if X.shape[1] != self.n_features_in_: + raise ValueError + + y_pred = np.empty(len(X), dtype=self.y_train_.dtype) + + for i, x in enumerate(X): + distances = np.sum((self.X_train_ - x) ** 2, axis=1) + nearest_index = np.argmin(distances) + + y_pred[i] = self.y_train_[nearest_index] + + return y_pred # XXX fix return y_pred def score(self, X, y): - """Write docstring. + """Calculates the accuracy (i.e. proportion of right answers) of the model on the given data X and labels y + + Variables: + X -> features table from which we want to predict the class + y -> true classes of the data in X + self -> fitted model - And describe parameters + Returns: + accuracy -> the accuracy of the model on the given data X and labels y """ X, y = check_X_y(X, y) y_pred = self.predict(X) # XXX fix - return y_pred.sum() + return np.mean(y_pred == y) From e8697e057eac42cc8d2c6db82efe6802a605c625 Mon Sep 17 00:00:00 2001 From: Maurice Date: Tue, 10 Nov 2026 16:12:28 +0100 Subject: [PATCH 2/5] Adjusted Format --- sklearn_questions.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sklearn_questions.py b/sklearn_questions.py index c884f522..dd91dc3c 100644 --- a/sklearn_questions.py +++ b/sklearn_questions.py @@ -59,7 +59,8 @@ def fit(self, X, y): return self def predict(self, X): - """Predicts the class of the given X, from the class of the Nearest Neighbor in the training set + """Predicts the class of the given X, + from the class of the Nearest Neighbor in the training set Variables: X -> features table from which we want to predict the class @@ -87,7 +88,8 @@ def predict(self, X): return y_pred def score(self, X, y): - """Calculates the accuracy (i.e. proportion of right answers) of the model on the given data X and labels y + """Calculates the accuracy (i.e. proportion of right answers) + of the model given data X and labels y Variables: X -> features table from which we want to predict the class From 527f350081f176705e4a6750cd90488ce38c6a97 Mon Sep 17 00:00:00 2001 From: Maurice Date: Tue, 10 Nov 2026 18:19:18 +0100 Subject: [PATCH 3/5] Update numpy and sklearn answers --- numpy_questions.py | 24 ++++++----- sklearn_questions.py | 94 +++++++++++++++++++++++--------------------- 2 files changed, 64 insertions(+), 54 deletions(-) diff --git a/numpy_questions.py b/numpy_questions.py index ed82eedd..c2dd9d0c 100644 --- a/numpy_questions.py +++ b/numpy_questions.py @@ -38,12 +38,12 @@ def max_index(X): If the input is not a numpy array or if the shape is not 2D. """ - i = np.max(X) - j = np.argmax(X) + if not isinstance(X, np.ndarray): + raise ValueError("X must be a numpy array.") + if X.ndim != 2: + raise ValueError("X must be 2D.") - # TODO - - return np.array(i, j) + return np.unravel_index(np.argmax(X), X.shape) def wallis_product(n_terms): @@ -66,9 +66,15 @@ def wallis_product(n_terms): # XXX : The n_terms is an int that corresponds to the number of # terms in the product. For example 10000. - my_pi = 1 + if n_terms < 0: + raise ValueError("n_terms must be non-negative.") + + if n_terms == 0: + return 1.0 + + product = 1.0 - for i in range(n_terms): - my_pi *= (4 * (i**2)) / (4 * (i**2) - 1) + for i in range(1, n_terms + 1): + product *= (4 * i**2) / (4 * i**2 - 1) - return my_pi + return 2 * product diff --git a/sklearn_questions.py b/sklearn_questions.py index dd91dc3c..8fda897e 100644 --- a/sklearn_questions.py +++ b/sklearn_questions.py @@ -21,86 +21,90 @@ """ import numpy as np -from sklearn.base import BaseEstimator -from sklearn.base import ClassifierMixin -from sklearn.utils.validation import check_X_y -from sklearn.utils.validation import check_array -from sklearn.utils.validation import check_is_fitted +from sklearn.base import BaseEstimator, ClassifierMixin from sklearn.utils.multiclass import check_classification_targets +from sklearn.utils.validation import check_array, check_is_fitted, check_X_y -class OneNearestNeighbor(BaseEstimator, ClassifierMixin): +class OneNearestNeighbor(ClassifierMixin, BaseEstimator): "OneNearestNeighbor classifier." - def __init__(self): # noqa: D107 + def __init__(self): pass def fit(self, X, y): - """Memorizes the examples in X and their classes in y - - Variables: - X -> features of the training data - y -> classes of the training data - - Returns: - self-> fitted One-Nearest-Neighbor model + """Store the training samples and their labels. + + Parameters + ---------- + X : array-like of shape (n_samples, n_features) + Training samples. + y : array-like of shape (n_samples,) + Class labels. + + Returns + ------- + self : OneNearestNeighbor + The fitted classifier. """ - X, y = check_X_y(X, y) check_classification_targets(y) - self.classes_ = np.unique(y) - self.n_features_in_ = X.shape[1] self.X_train_ = X.copy() self.y_train_ = y.copy() - - # XXX fix + self.classes_ = np.unique(y) + self.n_features_in_ = X.shape[1] return self def predict(self, X): - """Predicts the class of the given X, - from the class of the Nearest Neighbor in the training set + """Predict labels using the nearest training sample. - Variables: - X -> features table from which we want to predict the class - self -> fitted model + Parameters + ---------- + X : array-like of shape (n_samples, n_features) + Samples to classify. - Returns: - y_pred -> the predicted classes for X + Returns + ------- + y_pred : ndarray of shape (n_samples,) + Predicted class labels. """ - check_is_fitted(self, ["X_train_", "y_train_"]) + + check_is_fitted(self, ["X_train_", "y_train_", "n_features_in_"]) X = check_array(X) if X.shape[1] != self.n_features_in_: - raise ValueError + raise ValueError( + f"X has {X.shape[1]} features, but " + f"{self.__class__.__name__} is expecting " + f"{self.n_features_in_} features as input." + ) - y_pred = np.empty(len(X), dtype=self.y_train_.dtype) + y_pred = np.empty(X.shape[0], dtype=self.y_train_.dtype) for i, x in enumerate(X): distances = np.sum((self.X_train_ - x) ** 2, axis=1) nearest_index = np.argmin(distances) - y_pred[i] = self.y_train_[nearest_index] return y_pred - # XXX fix - return y_pred def score(self, X, y): - """Calculates the accuracy (i.e. proportion of right answers) - of the model given data X and labels y - - Variables: - X -> features table from which we want to predict the class - y -> true classes of the data in X - self -> fitted model - - Returns: - accuracy -> the accuracy of the model on the given data X and labels y + """Return the mean accuracy on the given data. + + Parameters + ---------- + X : array-like of shape (n_samples, n_features) + Samples to score. + y : array-like of shape (n_samples,) + True class labels. + + Returns + ------- + score : float + The mean accuracy. """ X, y = check_X_y(X, y) y_pred = self.predict(X) - - # XXX fix return np.mean(y_pred == y) From 798fbf07b75574dfb58fe7dadabbff00c0340066 Mon Sep 17 00:00:00 2001 From: Maurice Date: Tue, 10 Nov 2026 18:23:01 +0100 Subject: [PATCH 4/5] Update numpy and sklearn answers --- sklearn_questions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn_questions.py b/sklearn_questions.py index 8fda897e..e55d1622 100644 --- a/sklearn_questions.py +++ b/sklearn_questions.py @@ -27,10 +27,11 @@ class OneNearestNeighbor(ClassifierMixin, BaseEstimator): - "OneNearestNeighbor classifier." + """OneNearestNeighbor classifier.""" def __init__(self): pass + """Initialize the OneNearestNeighbor classifier.""" def fit(self, X, y): """Store the training samples and their labels. @@ -59,7 +60,6 @@ def fit(self, X, y): def predict(self, X): """Predict labels using the nearest training sample. - Parameters ---------- X : array-like of shape (n_samples, n_features) From a4afb9b992ff7e607233d16f46a7a1602fefaf8e Mon Sep 17 00:00:00 2001 From: Maurice Date: Tue, 10 Nov 2026 18:30:02 +0100 Subject: [PATCH 5/5] Fix docstring formatting in sklearn_questions --- sklearn_questions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn_questions.py b/sklearn_questions.py index e55d1622..421826f3 100644 --- a/sklearn_questions.py +++ b/sklearn_questions.py @@ -30,8 +30,8 @@ class OneNearestNeighbor(ClassifierMixin, BaseEstimator): """OneNearestNeighbor classifier.""" def __init__(self): - pass """Initialize the OneNearestNeighbor classifier.""" + pass def fit(self, X, y): """Store the training samples and their labels. @@ -60,6 +60,7 @@ def fit(self, X, y): def predict(self, X): """Predict labels using the nearest training sample. + Parameters ---------- X : array-like of shape (n_samples, n_features) @@ -70,7 +71,6 @@ def predict(self, X): y_pred : ndarray of shape (n_samples,) Predicted class labels. """ - check_is_fitted(self, ["X_train_", "y_train_", "n_features_in_"]) X = check_array(X)