Skip to content

Enable ruff ICN001 rule #11329

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 18 additions & 20 deletions ciphers/hill_cipher.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

import string

import numpy
import numpy as np

from maths.greatest_common_divisor import greatest_common_divisor

Expand All @@ -49,11 +49,11 @@ class HillCipher:
# i.e. a total of 36 characters

# take x and return x % len(key_string)
modulus = numpy.vectorize(lambda x: x % 36)
modulus = np.vectorize(lambda x: x % 36)

to_int = numpy.vectorize(round)
to_int = np.vectorize(round)

def __init__(self, encrypt_key: numpy.ndarray) -> None:
def __init__(self, encrypt_key: np.ndarray) -> None:
"""
encrypt_key is an NxN numpy array
"""
Expand All @@ -63,7 +63,7 @@ def __init__(self, encrypt_key: numpy.ndarray) -> None:

def replace_letters(self, letter: str) -> int:
"""
>>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))
>>> hill_cipher = HillCipher(np.array([[2, 5], [1, 6]]))
>>> hill_cipher.replace_letters('T')
19
>>> hill_cipher.replace_letters('0')
Expand All @@ -73,7 +73,7 @@ def replace_letters(self, letter: str) -> int:

def replace_digits(self, num: int) -> str:
"""
>>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))
>>> hill_cipher = HillCipher(np.array([[2, 5], [1, 6]]))
>>> hill_cipher.replace_digits(19)
'T'
>>> hill_cipher.replace_digits(26)
Expand All @@ -83,10 +83,10 @@ def replace_digits(self, num: int) -> str:

def check_determinant(self) -> None:
"""
>>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))
>>> hill_cipher = HillCipher(np.array([[2, 5], [1, 6]]))
>>> hill_cipher.check_determinant()
"""
det = round(numpy.linalg.det(self.encrypt_key))
det = round(np.linalg.det(self.encrypt_key))

if det < 0:
det = det % len(self.key_string)
Expand All @@ -101,7 +101,7 @@ def check_determinant(self) -> None:

def process_text(self, text: str) -> str:
"""
>>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))
>>> hill_cipher = HillCipher(np.array([[2, 5], [1, 6]]))
>>> hill_cipher.process_text('Testing Hill Cipher')
'TESTINGHILLCIPHERR'
>>> hill_cipher.process_text('hello')
Expand All @@ -117,7 +117,7 @@ def process_text(self, text: str) -> str:

def encrypt(self, text: str) -> str:
"""
>>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))
>>> hill_cipher = HillCipher(np.array([[2, 5], [1, 6]]))
>>> hill_cipher.encrypt('testing hill cipher')
'WHXYJOLM9C6XT085LL'
>>> hill_cipher.encrypt('hello')
Expand All @@ -129,7 +129,7 @@ def encrypt(self, text: str) -> str:
for i in range(0, len(text) - self.break_key + 1, self.break_key):
batch = text[i : i + self.break_key]
vec = [self.replace_letters(char) for char in batch]
batch_vec = numpy.array([vec]).T
batch_vec = np.array([vec]).T
batch_encrypted = self.modulus(self.encrypt_key.dot(batch_vec)).T.tolist()[
0
]
Expand All @@ -140,14 +140,14 @@ def encrypt(self, text: str) -> str:

return encrypted

def make_decrypt_key(self) -> numpy.ndarray:
def make_decrypt_key(self) -> np.ndarray:
"""
>>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))
>>> hill_cipher = HillCipher(np.array([[2, 5], [1, 6]]))
>>> hill_cipher.make_decrypt_key()
array([[ 6, 25],
[ 5, 26]])
"""
det = round(numpy.linalg.det(self.encrypt_key))
det = round(np.linalg.det(self.encrypt_key))

if det < 0:
det = det % len(self.key_string)
Expand All @@ -158,16 +158,14 @@ def make_decrypt_key(self) -> numpy.ndarray:
break

inv_key = (
det_inv
* numpy.linalg.det(self.encrypt_key)
* numpy.linalg.inv(self.encrypt_key)
det_inv * np.linalg.det(self.encrypt_key) * np.linalg.inv(self.encrypt_key)
)

return self.to_int(self.modulus(inv_key))

def decrypt(self, text: str) -> str:
"""
>>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))
>>> hill_cipher = HillCipher(np.array([[2, 5], [1, 6]]))
>>> hill_cipher.decrypt('WHXYJOLM9C6XT085LL')
'TESTINGHILLCIPHERR'
>>> hill_cipher.decrypt('85FF00')
Expand All @@ -180,7 +178,7 @@ def decrypt(self, text: str) -> str:
for i in range(0, len(text) - self.break_key + 1, self.break_key):
batch = text[i : i + self.break_key]
vec = [self.replace_letters(char) for char in batch]
batch_vec = numpy.array([vec]).T
batch_vec = np.array([vec]).T
batch_decrypted = self.modulus(decrypt_key.dot(batch_vec)).T.tolist()[0]
decrypted_batch = "".join(
self.replace_digits(num) for num in batch_decrypted
Expand All @@ -199,7 +197,7 @@ def main() -> None:
row = [int(x) for x in input().split()]
hill_matrix.append(row)

hc = HillCipher(numpy.array(hill_matrix))
hc = HillCipher(np.array(hill_matrix))

print("Would you like to encrypt or decrypt some text? (1 or 2)")
option = input("\n1. Encrypt\n2. Decrypt\n")
Expand Down
54 changes: 26 additions & 28 deletions fractals/julia_sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
from collections.abc import Callable
from typing import Any

import numpy
from matplotlib import pyplot
import matplotlib.pyplot as plt
import numpy as np

c_cauliflower = 0.25 + 0.0j
c_polynomial_1 = -0.4 + 0.6j
Expand All @@ -37,22 +37,20 @@
nb_pixels = 666


def eval_exponential(c_parameter: complex, z_values: numpy.ndarray) -> numpy.ndarray:
def eval_exponential(c_parameter: complex, z_values: np.ndarray) -> np.ndarray:
"""
Evaluate $e^z + c$.
>>> eval_exponential(0, 0)
1.0
>>> abs(eval_exponential(1, numpy.pi*1.j)) < 1e-15
>>> abs(eval_exponential(1, np.pi*1.j)) < 1e-15
True
>>> abs(eval_exponential(1.j, 0)-1-1.j) < 1e-15
True
"""
return numpy.exp(z_values) + c_parameter
return np.exp(z_values) + c_parameter


def eval_quadratic_polynomial(
c_parameter: complex, z_values: numpy.ndarray
) -> numpy.ndarray:
def eval_quadratic_polynomial(c_parameter: complex, z_values: np.ndarray) -> np.ndarray:
"""
>>> eval_quadratic_polynomial(0, 2)
4
Expand All @@ -66,7 +64,7 @@ def eval_quadratic_polynomial(
return z_values * z_values + c_parameter


def prepare_grid(window_size: float, nb_pixels: int) -> numpy.ndarray:
def prepare_grid(window_size: float, nb_pixels: int) -> np.ndarray:
"""
Create a grid of complex values of size nb_pixels*nb_pixels with real and
imaginary parts ranging from -window_size to window_size (inclusive).
Expand All @@ -77,74 +75,74 @@ def prepare_grid(window_size: float, nb_pixels: int) -> numpy.ndarray:
[ 0.-1.j, 0.+0.j, 0.+1.j],
[ 1.-1.j, 1.+0.j, 1.+1.j]])
"""
x = numpy.linspace(-window_size, window_size, nb_pixels)
x = np.linspace(-window_size, window_size, nb_pixels)
x = x.reshape((nb_pixels, 1))
y = numpy.linspace(-window_size, window_size, nb_pixels)
y = np.linspace(-window_size, window_size, nb_pixels)
y = y.reshape((1, nb_pixels))
return x + 1.0j * y


def iterate_function(
eval_function: Callable[[Any, numpy.ndarray], numpy.ndarray],
eval_function: Callable[[Any, np.ndarray], np.ndarray],
function_params: Any,
nb_iterations: int,
z_0: numpy.ndarray,
z_0: np.ndarray,
infinity: float | None = None,
) -> numpy.ndarray:
) -> np.ndarray:
"""
Iterate the function "eval_function" exactly nb_iterations times.
The first argument of the function is a parameter which is contained in
function_params. The variable z_0 is an array that contains the initial
values to iterate from.
This function returns the final iterates.

>>> iterate_function(eval_quadratic_polynomial, 0, 3, numpy.array([0,1,2])).shape
>>> iterate_function(eval_quadratic_polynomial, 0, 3, np.array([0,1,2])).shape
(3,)
>>> numpy.round(iterate_function(eval_quadratic_polynomial,
>>> np.round(iterate_function(eval_quadratic_polynomial,
... 0,
... 3,
... numpy.array([0,1,2]))[0])
... np.array([0,1,2]))[0])
0j
>>> numpy.round(iterate_function(eval_quadratic_polynomial,
>>> np.round(iterate_function(eval_quadratic_polynomial,
... 0,
... 3,
... numpy.array([0,1,2]))[1])
... np.array([0,1,2]))[1])
(1+0j)
>>> numpy.round(iterate_function(eval_quadratic_polynomial,
>>> np.round(iterate_function(eval_quadratic_polynomial,
... 0,
... 3,
... numpy.array([0,1,2]))[2])
... np.array([0,1,2]))[2])
(256+0j)
"""

z_n = z_0.astype("complex64")
for _ in range(nb_iterations):
z_n = eval_function(function_params, z_n)
if infinity is not None:
numpy.nan_to_num(z_n, copy=False, nan=infinity)
z_n[abs(z_n) == numpy.inf] = infinity
np.nan_to_num(z_n, copy=False, nan=infinity)
z_n[abs(z_n) == np.inf] = infinity
return z_n


def show_results(
function_label: str,
function_params: Any,
escape_radius: float,
z_final: numpy.ndarray,
z_final: np.ndarray,
) -> None:
"""
Plots of whether the absolute value of z_final is greater than
the value of escape_radius. Adds the function_label and function_params to
the title.

>>> show_results('80', 0, 1, numpy.array([[0,1,.5],[.4,2,1.1],[.2,1,1.3]]))
>>> show_results('80', 0, 1, np.array([[0,1,.5],[.4,2,1.1],[.2,1,1.3]]))
"""

abs_z_final = (abs(z_final)).transpose()
abs_z_final[:, :] = abs_z_final[::-1, :]
pyplot.matshow(abs_z_final < escape_radius)
pyplot.title(f"Julia set of ${function_label}$, $c={function_params}$")
pyplot.show()
plt.matshow(abs_z_final < escape_radius)
plt.title(f"Julia set of ${function_label}$, $c={function_params}$")
plt.show()


def ignore_overflow_warnings() -> None:
Expand Down
34 changes: 17 additions & 17 deletions fractals/koch_snowflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,25 @@

from __future__ import annotations

import matplotlib.pyplot as plt # type: ignore
import numpy
import matplotlib.pyplot as plt
import numpy as np

# initial triangle of Koch snowflake
VECTOR_1 = numpy.array([0, 0])
VECTOR_2 = numpy.array([0.5, 0.8660254])
VECTOR_3 = numpy.array([1, 0])
VECTOR_1 = np.array([0, 0])
VECTOR_2 = np.array([0.5, 0.8660254])
VECTOR_3 = np.array([1, 0])
INITIAL_VECTORS = [VECTOR_1, VECTOR_2, VECTOR_3, VECTOR_1]

# uncomment for simple Koch curve instead of Koch snowflake
# INITIAL_VECTORS = [VECTOR_1, VECTOR_3]


def iterate(initial_vectors: list[numpy.ndarray], steps: int) -> list[numpy.ndarray]:
def iterate(initial_vectors: list[np.ndarray], steps: int) -> list[np.ndarray]:
"""
Go through the number of iterations determined by the argument "steps".
Be careful with high values (above 5) since the time to calculate increases
exponentially.
>>> iterate([numpy.array([0, 0]), numpy.array([1, 0])], 1)
>>> iterate([np.array([0, 0]), np.array([1, 0])], 1)
[array([0, 0]), array([0.33333333, 0. ]), array([0.5 , \
0.28867513]), array([0.66666667, 0. ]), array([1, 0])]
"""
Expand All @@ -50,13 +50,13 @@ def iterate(initial_vectors: list[numpy.ndarray], steps: int) -> list[numpy.ndar
return vectors


def iteration_step(vectors: list[numpy.ndarray]) -> list[numpy.ndarray]:
def iteration_step(vectors: list[np.ndarray]) -> list[np.ndarray]:
"""
Loops through each pair of adjacent vectors. Each line between two adjacent
vectors is divided into 4 segments by adding 3 additional vectors in-between
the original two vectors. The vector in the middle is constructed through a
60 degree rotation so it is bent outwards.
>>> iteration_step([numpy.array([0, 0]), numpy.array([1, 0])])
>>> iteration_step([np.array([0, 0]), np.array([1, 0])])
[array([0, 0]), array([0.33333333, 0. ]), array([0.5 , \
0.28867513]), array([0.66666667, 0. ]), array([1, 0])]
"""
Expand All @@ -74,22 +74,22 @@ def iteration_step(vectors: list[numpy.ndarray]) -> list[numpy.ndarray]:
return new_vectors


def rotate(vector: numpy.ndarray, angle_in_degrees: float) -> numpy.ndarray:
def rotate(vector: np.ndarray, angle_in_degrees: float) -> np.ndarray:
"""
Standard rotation of a 2D vector with a rotation matrix
(see https://en.wikipedia.org/wiki/Rotation_matrix )
>>> rotate(numpy.array([1, 0]), 60)
>>> rotate(np.array([1, 0]), 60)
array([0.5 , 0.8660254])
>>> rotate(numpy.array([1, 0]), 90)
>>> rotate(np.array([1, 0]), 90)
array([6.123234e-17, 1.000000e+00])
"""
theta = numpy.radians(angle_in_degrees)
c, s = numpy.cos(theta), numpy.sin(theta)
rotation_matrix = numpy.array(((c, -s), (s, c)))
return numpy.dot(rotation_matrix, vector)
theta = np.radians(angle_in_degrees)
c, s = np.cos(theta), np.sin(theta)
rotation_matrix = np.array(((c, -s), (s, c)))
return np.dot(rotation_matrix, vector)


def plot(vectors: list[numpy.ndarray]) -> None:
def plot(vectors: list[np.ndarray]) -> None:
"""
Utility function to plot the vectors using matplotlib.pyplot
No doctest was implemented since this function does not have a return value
Expand Down
2 changes: 1 addition & 1 deletion graphics/bezier_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def plot_curve(self, step_size: float = 0.01):
step_size: defines the step(s) at which to evaluate the Bezier curve.
The smaller the step size, the finer the curve produced.
"""
from matplotlib import pyplot as plt # type: ignore
from matplotlib import pyplot as plt

to_plot_x: list[float] = [] # x coordinates of points to plot
to_plot_y: list[float] = [] # y coordinates of points to plot
Expand Down
4 changes: 2 additions & 2 deletions machine_learning/gradient_descent.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
function.
"""

import numpy
import numpy as np

# List of input, output pairs
train_data = (
Expand Down Expand Up @@ -116,7 +116,7 @@ def run_gradient_descent():
temp_parameter_vector[i] = (
parameter_vector[i] - LEARNING_RATE * cost_derivative
)
if numpy.allclose(
if np.allclose(
parameter_vector,
temp_parameter_vector,
atol=absolute_error_limit,
Expand Down
Loading