Skip to content

Commit 4561eaa

Browse files
committed
style: ruff changes - CI-CD should now pass
1 parent 04e2922 commit 4561eaa

File tree

3 files changed

+25
-37
lines changed

3 files changed

+25
-37
lines changed

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ target-version = ["py310"]
3232

3333
[tool.ruff]
3434
line-length = 88
35-
select = ["E", "F", "I", "UP", "B"]
3635
src = ["src", "tests"]
3736

37+
[tool.ruff.lint]
38+
select = ["E", "F", "I", "UP", "B"]
39+
3840
[tool.pytest.ini_options]
3941
addopts = "-q --cov=src --cov-report=term-missing"
4042

scripts/run_perceptron.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import pandas as pd
2-
import numpy as np
3-
import matplotlib.pyplot as plt
4-
51
from pathlib import Path
62

3+
import matplotlib.pyplot as plt
4+
import numpy as np
5+
import pandas as pd
6+
77
# Import from the package under src/
88
from perceptron.perceptron_class import Perceptron, plot_decision_regions
99

@@ -22,7 +22,9 @@ def main():
2222

2323
# plot data
2424
plt.scatter(X[:50, 0], X[:50, 1], color="red", marker="o", label="Setosa")
25-
plt.scatter(X[50:100, 0], X[50:100, 1], color="blue", marker="s", label="Versicolor")
25+
plt.scatter(
26+
X[50:100, 0], X[50:100, 1], color="blue", marker="s", label="Versicolor"
27+
)
2628

2729
plt.xlabel("Sepal length [cm]")
2830
plt.ylabel("Petal length [cm]")

src/perceptron/perceptron_class.py

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,15 @@
1-
import numpy as np
21
import matplotlib.pyplot as plt
2+
import numpy as np
33
from matplotlib.colors import ListedColormap
44

55

66
class Perceptron:
7-
"""Perceptron classifier.
8-
9-
Parameters
10-
----------
11-
eta : float
12-
Learning rate (between 0.0 and 1.0).
13-
n_iter : int
14-
Passes over the training dataset.
15-
random_state : int
16-
RNG seed for weight initialization.
17-
18-
Attributes
19-
----------
20-
w_ : 1d-array
21-
Weights after fitting.
22-
b_ : float
23-
Bias unit after fitting.
24-
errors_ : list[int]
25-
Number of misclassifications (updates) in each epoch.
26-
"""
7+
"""Perceptron classifier."""
278

289
def __init__(self, eta: float = 0.01, n_iter: int = 50, random_state: int = 1):
2910
self.eta = eta
3011
self.n_iter = n_iter
3112
self.random_state = random_state
32-
self.w_: np.ndarray | None = None
33-
self.b_: float | None = None
3413
self.errors_: list[int] = []
3514

3615
def fit(self, X: np.ndarray, y: np.ndarray) -> "Perceptron":
@@ -42,8 +21,9 @@ def fit(self, X: np.ndarray, y: np.ndarray) -> "Perceptron":
4221

4322
for _ in range(self.n_iter):
4423
errors = 0
45-
for xi, target in zip(X, y):
46-
update = self.eta * (target - self.predict(xi))
24+
for xi, target in zip(X, y, strict=True):
25+
update = self.eta * (int(target) - int(self.predict(xi)))
26+
assert self.w_ is not None and self.b_ is not None
4727
self.w_ += update * xi
4828
self.b_ += update
4929
errors += int(update != 0.0)
@@ -52,33 +32,37 @@ def fit(self, X: np.ndarray, y: np.ndarray) -> "Perceptron":
5232

5333
def net_input(self, X: np.ndarray) -> np.ndarray | float:
5434
"""Calculate net input."""
35+
assert self.w_ is not None and self.b_ is not None
5536
return np.dot(X, self.w_) + self.b_
5637

57-
def predict(self, X: np.ndarray) -> np.ndarray | int:
38+
def predict(self, X: np.ndarray) -> np.ndarray:
5839
"""Return class label after unit step."""
5940
return np.where(self.net_input(X) >= 0.0, 1, 0)
6041

6142

62-
def plot_decision_regions(X: np.ndarray, y: np.ndarray, classifier: Perceptron, resolution: float = 0.02) -> None:
43+
def plot_decision_regions(
44+
X: np.ndarray,
45+
y: np.ndarray,
46+
classifier: Perceptron,
47+
resolution: float = 0.02,
48+
) -> None:
6349
"""Plot decision regions for a 2D dataset and a fitted classifier."""
6450
markers = ("o", "s", "^", "v", "<")
6551
colors = ("red", "blue", "lightgreen", "gray", "cyan")
6652
cmap = ListedColormap(colors[: len(np.unique(y))])
6753

68-
# decision surface
6954
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
7055
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
7156
xx1, xx2 = np.meshgrid(
7257
np.arange(x1_min, x1_max, resolution),
7358
np.arange(x2_min, x2_max, resolution),
7459
)
75-
lab = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
76-
lab = lab.reshape(xx1.shape)
60+
grid = np.c_[xx1.ravel(), xx2.ravel()]
61+
lab = classifier.predict(grid).reshape(xx1.shape)
7762
plt.contourf(xx1, xx2, lab, alpha=0.3, cmap=cmap)
7863
plt.xlim(xx1.min(), xx1.max())
7964
plt.ylim(xx2.min(), xx2.max())
8065

81-
# class points
8266
for idx, cl in enumerate(np.unique(y)):
8367
plt.scatter(
8468
x=X[y == cl, 0],

0 commit comments

Comments
 (0)