Skip to content

Commit

Permalink
Merge pull request #32 from javidahmed64592/add-pytest-coverage
Browse files Browse the repository at this point in the history
NN v1.12.1 Add pytest coverage
  • Loading branch information
javidahmed64592 authored Sep 12, 2024
2 parents 8ffb53d + 5cf49cc commit 6b72147
Show file tree
Hide file tree
Showing 12 changed files with 180 additions and 19 deletions.
3 changes: 2 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ numpy = "*"

[dev-packages]
pytest = "*"
pytest-cov = "*"
ruff = "*"
ipykernel = "*"

[requires]
python_version = "3.12"

[scripts]
test = "python -m pytest -vx"
test = "python -m pytest -vx --cov=neural_network --cov-report term-missing"
ruff = "python -m ruff check ."
96 changes: 93 additions & 3 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions neural_network/nn/layer.py → neural_network/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def __init__(
Parameters:
size (int): Size of InputLayer
activation (ActivationFunction): Layer activation function
activation (ActivationFunction): InputLayer activation function
"""
super().__init__(size, activation, [1, 1], [0, 0])

Expand Down Expand Up @@ -180,10 +180,10 @@ def __init__(
Initialise HiddenLayer object with number of nodes, activation function, weights range and bias range.
Parameters:
size (int): Size of Layer
activation (ActivationFunction): Layer activation function
weights_range (tuple[float, float]): Range for Layer weights
bias_range (tuple[float, float]): Range for Layer bias
size (int): Size of HiddenLayer
activation (ActivationFunction): HiddenLayer activation function
weights_range (tuple[float, float]): Range for HiddenLayer weights
bias_range (tuple[float, float]): Range for HiddenLayer bias
"""
super().__init__(size, activation, weights_range, bias_range)

Expand All @@ -205,7 +205,7 @@ def __init__(
Parameters:
size (int): Size of OutputLayer
activation (ActivationFunction): Layer activation function
activation (ActivationFunction): OutputLayer activation function
weights_range (tuple[float, float]): Range for OutputLayer weights
bias_range (tuple[float, float]): Range for OutputLayer bias
"""
Expand Down
2 changes: 1 addition & 1 deletion neural_network/math/matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def __init__(self, rows: int, cols: int, vals: NDArray | None = None) -> None:
Parameters:
rows (int): Number of rows in matrix
cols (int): Number of columns in matrix
vals (Optional[NDArray]): Matrix values if specified
vals (NDArray | None): Matrix values if specified
"""
self._rows = rows
self._cols = cols
Expand Down
6 changes: 2 additions & 4 deletions neural_network/neural_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

import numpy as np

from neural_network.layer import HiddenLayer, InputLayer, Layer, OutputLayer
from neural_network.math.matrix import Matrix
from neural_network.math.nn_math import calculate_error_from_expected, calculate_next_errors
from neural_network.nn.layer import HiddenLayer, InputLayer, Layer, OutputLayer


class NeuralNetwork:
Expand Down Expand Up @@ -98,12 +98,10 @@ def save(self, filepath: str) -> None:

def mutate(self, shift_vals: float) -> None:
"""
Mutate NeuralNetwork Layers by adjusting weights and biases, and potentially adding new Nodes.
Mutate NeuralNetwork Layers by adjusting weights and biases.
Parameters:
shift_vals (float): Factor to adjust Layer weights and biases by
prob_new_node (float): Probability per Layer for a new Node, range [0, 1]
prob_toggle_connection (float): Probability per Layer to toggle a random Node, range[0, 1]
"""
for layer in self.layers[1:]:
layer.mutate(shift_vals)
Expand Down
Empty file removed neural_network/nn/__init__.py
Empty file.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from setuptools import find_packages, setup

__version__ = "1.12.0"
__version__ = "1.12.1"

setup(
name="neural_network",
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import pytest

from neural_network.layer import HiddenLayer, InputLayer, OutputLayer
from neural_network.math.activation_functions import LinearActivation
from neural_network.math.matrix import Matrix
from neural_network.neural_network import NeuralNetwork
from neural_network.nn.layer import HiddenLayer, InputLayer, OutputLayer


@pytest.fixture
Expand Down
55 changes: 55 additions & 0 deletions tests/math/test_activation_functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import numpy as np

from neural_network.math.activation_functions import LinearActivation, ReluActivation, SigmoidActivation


class TestLinearActivation:
def test_given_x_when_calculating_y_then_check_calculated_correctly(self) -> None:
x = 5
expected_y = x
actual_y = LinearActivation.func(x)
assert actual_y == expected_y

def test_given_x_when_calculating_derivative_then_check_calculated_correctly(self) -> None:
x = 5
expected_y = 1
actual_y = LinearActivation.derivative(x)
assert actual_y == expected_y


class TestReluActivation:
def test_given_x_when_calculating_y_then_check_calculated_correctly(self) -> None:
x = -5
expected_y = 0
actual_y = ReluActivation.func(x)
assert actual_y == expected_y

x = 5
expected_y = x
actual_y = ReluActivation.func(x)
assert actual_y == expected_y

def test_given_x_when_calculating_derivative_then_check_calculated_correctly(self) -> None:
x = -5
expected_y = 0
actual_y = ReluActivation.derivative(x)
assert actual_y == expected_y

x = 5
expected_y = 1
actual_y = ReluActivation.derivative(x)
assert actual_y == expected_y


class TestSigmoidActivation:
def test_given_x_when_calculating_y_then_check_calculated_correctly(self) -> None:
x = 5
expected_y = 1 / (1 + np.exp(-x))
actual_y = SigmoidActivation.func(x)
assert actual_y == expected_y

def test_given_x_when_calculating_derivative_then_check_calculated_correctly(self) -> None:
x = 5
expected_y = x * (1 - x)
actual_y = SigmoidActivation.derivative(x)
assert actual_y == expected_y
17 changes: 17 additions & 0 deletions tests/math/test_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@


class TestMatrix:
def test_given_no_vals_when_creating_matrix_then_check_matrix_has_zero_vals(
self, mock_len_inputs: int, mock_len_outputs: int
) -> None:
test_matrix = Matrix(rows=mock_len_inputs, cols=mock_len_outputs)
assert not np.any(test_matrix.vals)

def test_given_shape_when_creating_random_matrix_then_check_matrix_has_correct_shape(
self, mock_weights_range: list[float], mock_len_inputs: int, mock_len_outputs: int
) -> None:
Expand Down Expand Up @@ -161,3 +167,14 @@ def test_given_matrices_when_mixing_then_check_output_has_correct_shape(self) ->
new_matrix = Matrix.mix_matrices(matrix_in_1, matrix_in_2, matrix_out)

assert np.all(new_matrix.shape == matrix_out.shape)

def test_given_matrix_when_shifting_vals_then_check_vals_are_different(self) -> None:
array = np.array([[1, 2], [4, 3], [2, 4]])

matrix_1 = Matrix.from_array(array)
matrix_2 = Matrix.from_array(array)

assert np.all(matrix_1.vals == matrix_2.vals)

matrix_1.shift_vals(0.5)
assert not np.all(matrix_1.vals == matrix_2.vals)
2 changes: 1 addition & 1 deletion tests/nn/test_layer.py → tests/test_layer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from neural_network.layer import HiddenLayer, InputLayer
from neural_network.math.matrix import Matrix
from neural_network.nn.layer import HiddenLayer, InputLayer


class TestLayer:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_neural_network.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from neural_network.layer import HiddenLayer, InputLayer, OutputLayer
from neural_network.math.activation_functions import ActivationFunction
from neural_network.neural_network import NeuralNetwork
from neural_network.nn.layer import HiddenLayer, InputLayer, OutputLayer


def make_hidden_layer(
Expand Down

0 comments on commit 6b72147

Please sign in to comment.