mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-23 21:11:08 +00:00
Add missing type hints in matrix
directory (#6612)
* Update count_islands_in_matrix.py * Update matrix_class.py * Update matrix_operation.py * Update nth_fibonacci_using_matrix_exponentiation.py * Update searching_in_sorted_matrix.py * Update count_islands_in_matrix.py * Update matrix_class.py * Update matrix_operation.py * Update rotate_matrix.py * Update sherman_morrison.py * Update spiral_print.py * Update count_islands_in_matrix.py * formatting * formatting * Update matrix_class.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
a84fb58271
commit
46842e8c5b
|
@ -4,12 +4,12 @@
|
|||
|
||||
|
||||
class matrix: # Public class to implement a graph
|
||||
def __init__(self, row: int, col: int, graph: list):
|
||||
def __init__(self, row: int, col: int, graph: list[list[bool]]) -> None:
|
||||
self.ROW = row
|
||||
self.COL = col
|
||||
self.graph = graph
|
||||
|
||||
def is_safe(self, i, j, visited) -> bool:
|
||||
def is_safe(self, i: int, j: int, visited: list[list[bool]]) -> bool:
|
||||
return (
|
||||
0 <= i < self.ROW
|
||||
and 0 <= j < self.COL
|
||||
|
@ -17,7 +17,8 @@ class matrix: # Public class to implement a graph
|
|||
and self.graph[i][j]
|
||||
)
|
||||
|
||||
def diffs(self, i, j, visited): # Checking all 8 elements surrounding nth element
|
||||
def diffs(self, i: int, j: int, visited: list[list[bool]]) -> None:
|
||||
# Checking all 8 elements surrounding nth element
|
||||
rowNbr = [-1, -1, -1, 0, 0, 1, 1, 1] # Coordinate order
|
||||
colNbr = [-1, 0, 1, -1, 1, -1, 0, 1]
|
||||
visited[i][j] = True # Make those cells visited
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# An OOP approach to representing and manipulating matrices
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
class Matrix:
|
||||
"""
|
||||
|
@ -54,7 +56,9 @@ class Matrix:
|
|||
[6. -12. 6.]
|
||||
[-3. 6. -3.]]
|
||||
>>> print(matrix.inverse())
|
||||
None
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: Only matrices with a non-zero determinant have an inverse
|
||||
|
||||
Determinant is an int, float, or Nonetype
|
||||
>>> matrix.determinant()
|
||||
|
@ -101,10 +105,9 @@ class Matrix:
|
|||
[198. 243. 288. 304.]
|
||||
[306. 378. 450. 472.]
|
||||
[414. 513. 612. 640.]]
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, rows):
|
||||
def __init__(self, rows: list[list[int]]):
|
||||
error = TypeError(
|
||||
"Matrices must be formed from a list of zero or more lists containing at "
|
||||
"least one and the same number of values, each of which must be of type "
|
||||
|
@ -125,42 +128,43 @@ class Matrix:
|
|||
self.rows = []
|
||||
|
||||
# MATRIX INFORMATION
|
||||
def columns(self):
|
||||
def columns(self) -> list[list[int]]:
|
||||
return [[row[i] for row in self.rows] for i in range(len(self.rows[0]))]
|
||||
|
||||
@property
|
||||
def num_rows(self):
|
||||
def num_rows(self) -> int:
|
||||
return len(self.rows)
|
||||
|
||||
@property
|
||||
def num_columns(self):
|
||||
def num_columns(self) -> int:
|
||||
return len(self.rows[0])
|
||||
|
||||
@property
|
||||
def order(self):
|
||||
def order(self) -> tuple[int, int]:
|
||||
return (self.num_rows, self.num_columns)
|
||||
|
||||
@property
|
||||
def is_square(self):
|
||||
def is_square(self) -> bool:
|
||||
return self.order[0] == self.order[1]
|
||||
|
||||
def identity(self):
|
||||
def identity(self) -> Matrix:
|
||||
values = [
|
||||
[0 if column_num != row_num else 1 for column_num in range(self.num_rows)]
|
||||
for row_num in range(self.num_rows)
|
||||
]
|
||||
return Matrix(values)
|
||||
|
||||
def determinant(self):
|
||||
def determinant(self) -> int:
|
||||
if not self.is_square:
|
||||
return None
|
||||
return 0
|
||||
if self.order == (0, 0):
|
||||
return 1
|
||||
if self.order == (1, 1):
|
||||
return self.rows[0][0]
|
||||
return int(self.rows[0][0])
|
||||
if self.order == (2, 2):
|
||||
return (self.rows[0][0] * self.rows[1][1]) - (
|
||||
self.rows[0][1] * self.rows[1][0]
|
||||
return int(
|
||||
(self.rows[0][0] * self.rows[1][1])
|
||||
- (self.rows[0][1] * self.rows[1][0])
|
||||
)
|
||||
else:
|
||||
return sum(
|
||||
|
@ -168,10 +172,10 @@ class Matrix:
|
|||
for column in range(self.num_columns)
|
||||
)
|
||||
|
||||
def is_invertable(self):
|
||||
def is_invertable(self) -> bool:
|
||||
return bool(self.determinant())
|
||||
|
||||
def get_minor(self, row, column):
|
||||
def get_minor(self, row: int, column: int) -> int:
|
||||
values = [
|
||||
[
|
||||
self.rows[other_row][other_column]
|
||||
|
@ -183,12 +187,12 @@ class Matrix:
|
|||
]
|
||||
return Matrix(values).determinant()
|
||||
|
||||
def get_cofactor(self, row, column):
|
||||
def get_cofactor(self, row: int, column: int) -> int:
|
||||
if (row + column) % 2 == 0:
|
||||
return self.get_minor(row, column)
|
||||
return -1 * self.get_minor(row, column)
|
||||
|
||||
def minors(self):
|
||||
def minors(self) -> Matrix:
|
||||
return Matrix(
|
||||
[
|
||||
[self.get_minor(row, column) for column in range(self.num_columns)]
|
||||
|
@ -196,7 +200,7 @@ class Matrix:
|
|||
]
|
||||
)
|
||||
|
||||
def cofactors(self):
|
||||
def cofactors(self) -> Matrix:
|
||||
return Matrix(
|
||||
[
|
||||
[
|
||||
|
@ -209,25 +213,27 @@ class Matrix:
|
|||
]
|
||||
)
|
||||
|
||||
def adjugate(self):
|
||||
def adjugate(self) -> Matrix:
|
||||
values = [
|
||||
[self.cofactors().rows[column][row] for column in range(self.num_columns)]
|
||||
for row in range(self.num_rows)
|
||||
]
|
||||
return Matrix(values)
|
||||
|
||||
def inverse(self):
|
||||
def inverse(self) -> Matrix:
|
||||
determinant = self.determinant()
|
||||
return None if not determinant else self.adjugate() * (1 / determinant)
|
||||
if not determinant:
|
||||
raise TypeError("Only matrices with a non-zero determinant have an inverse")
|
||||
return self.adjugate() * (1 / determinant)
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return str(self.rows)
|
||||
|
||||
def __str__(self):
|
||||
def __str__(self) -> str:
|
||||
if self.num_rows == 0:
|
||||
return "[]"
|
||||
if self.num_rows == 1:
|
||||
return "[[" + ". ".join(self.rows[0]) + "]]"
|
||||
return "[[" + ". ".join(str(self.rows[0])) + "]]"
|
||||
return (
|
||||
"["
|
||||
+ "\n ".join(
|
||||
|
@ -240,7 +246,7 @@ class Matrix:
|
|||
)
|
||||
|
||||
# MATRIX MANIPULATION
|
||||
def add_row(self, row, position=None):
|
||||
def add_row(self, row: list[int], position: int | None = None) -> None:
|
||||
type_error = TypeError("Row must be a list containing all ints and/or floats")
|
||||
if not isinstance(row, list):
|
||||
raise type_error
|
||||
|
@ -256,7 +262,7 @@ class Matrix:
|
|||
else:
|
||||
self.rows = self.rows[0:position] + [row] + self.rows[position:]
|
||||
|
||||
def add_column(self, column, position=None):
|
||||
def add_column(self, column: list[int], position: int | None = None) -> None:
|
||||
type_error = TypeError(
|
||||
"Column must be a list containing all ints and/or floats"
|
||||
)
|
||||
|
@ -278,18 +284,18 @@ class Matrix:
|
|||
]
|
||||
|
||||
# MATRIX OPERATIONS
|
||||
def __eq__(self, other):
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, Matrix):
|
||||
raise TypeError("A Matrix can only be compared with another Matrix")
|
||||
return self.rows == other.rows
|
||||
|
||||
def __ne__(self, other):
|
||||
def __ne__(self, other: object) -> bool:
|
||||
return not self == other
|
||||
|
||||
def __neg__(self):
|
||||
def __neg__(self) -> Matrix:
|
||||
return self * -1
|
||||
|
||||
def __add__(self, other):
|
||||
def __add__(self, other: Matrix) -> Matrix:
|
||||
if self.order != other.order:
|
||||
raise ValueError("Addition requires matrices of the same order")
|
||||
return Matrix(
|
||||
|
@ -299,7 +305,7 @@ class Matrix:
|
|||
]
|
||||
)
|
||||
|
||||
def __sub__(self, other):
|
||||
def __sub__(self, other: Matrix) -> Matrix:
|
||||
if self.order != other.order:
|
||||
raise ValueError("Subtraction requires matrices of the same order")
|
||||
return Matrix(
|
||||
|
@ -309,9 +315,11 @@ class Matrix:
|
|||
]
|
||||
)
|
||||
|
||||
def __mul__(self, other):
|
||||
def __mul__(self, other: Matrix | int | float) -> Matrix:
|
||||
if isinstance(other, (int, float)):
|
||||
return Matrix([[element * other for element in row] for row in self.rows])
|
||||
return Matrix(
|
||||
[[int(element * other) for element in row] for row in self.rows]
|
||||
)
|
||||
elif isinstance(other, Matrix):
|
||||
if self.num_columns != other.num_rows:
|
||||
raise ValueError(
|
||||
|
@ -329,7 +337,7 @@ class Matrix:
|
|||
"A Matrix can only be multiplied by an int, float, or another matrix"
|
||||
)
|
||||
|
||||
def __pow__(self, other):
|
||||
def __pow__(self, other: int) -> Matrix:
|
||||
if not isinstance(other, int):
|
||||
raise TypeError("A Matrix can only be raised to the power of an int")
|
||||
if not self.is_square:
|
||||
|
@ -348,7 +356,7 @@ class Matrix:
|
|||
return result
|
||||
|
||||
@classmethod
|
||||
def dot_product(cls, row, column):
|
||||
def dot_product(cls, row: list[int], column: list[int]) -> int:
|
||||
return sum(row[i] * column[i] for i in range(len(row)))
|
||||
|
||||
|
||||
|
|
|
@ -4,8 +4,10 @@ Functions for 2D matrix operations
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
def add(*matrix_s: list[list]) -> list[list]:
|
||||
|
||||
def add(*matrix_s: list[list[int]]) -> list[list[int]]:
|
||||
"""
|
||||
>>> add([[1,2],[3,4]],[[2,3],[4,5]])
|
||||
[[3, 5], [7, 9]]
|
||||
|
@ -25,7 +27,7 @@ def add(*matrix_s: list[list]) -> list[list]:
|
|||
raise TypeError("Expected a matrix, got int/list instead")
|
||||
|
||||
|
||||
def subtract(matrix_a: list[list], matrix_b: list[list]) -> list[list]:
|
||||
def subtract(matrix_a: list[list[int]], matrix_b: list[list[int]]) -> list[list[int]]:
|
||||
"""
|
||||
>>> subtract([[1,2],[3,4]],[[2,3],[4,5]])
|
||||
[[-1, -1], [-1, -1]]
|
||||
|
@ -45,7 +47,7 @@ def subtract(matrix_a: list[list], matrix_b: list[list]) -> list[list]:
|
|||
raise TypeError("Expected a matrix, got int/list instead")
|
||||
|
||||
|
||||
def scalar_multiply(matrix: list[list], n: int | float) -> list[list]:
|
||||
def scalar_multiply(matrix: list[list[int]], n: int | float) -> list[list[float]]:
|
||||
"""
|
||||
>>> scalar_multiply([[1,2],[3,4]],5)
|
||||
[[5, 10], [15, 20]]
|
||||
|
@ -55,7 +57,7 @@ def scalar_multiply(matrix: list[list], n: int | float) -> list[list]:
|
|||
return [[x * n for x in row] for row in matrix]
|
||||
|
||||
|
||||
def multiply(matrix_a: list[list], matrix_b: list[list]) -> list[list]:
|
||||
def multiply(matrix_a: list[list[int]], matrix_b: list[list[int]]) -> list[list[int]]:
|
||||
"""
|
||||
>>> multiply([[1,2],[3,4]],[[5,5],[7,5]])
|
||||
[[19, 15], [43, 35]]
|
||||
|
@ -77,7 +79,7 @@ def multiply(matrix_a: list[list], matrix_b: list[list]) -> list[list]:
|
|||
]
|
||||
|
||||
|
||||
def identity(n: int) -> list[list]:
|
||||
def identity(n: int) -> list[list[int]]:
|
||||
"""
|
||||
:param n: dimension for nxn matrix
|
||||
:type n: int
|
||||
|
@ -89,7 +91,9 @@ def identity(n: int) -> list[list]:
|
|||
return [[int(row == column) for column in range(n)] for row in range(n)]
|
||||
|
||||
|
||||
def transpose(matrix: list[list], return_map: bool = True) -> list[list] | map[list]:
|
||||
def transpose(
|
||||
matrix: list[list[int]], return_map: bool = True
|
||||
) -> list[list[int]] | map[list[int]]:
|
||||
"""
|
||||
>>> transpose([[1,2],[3,4]]) # doctest: +ELLIPSIS
|
||||
<map object at ...
|
||||
|
@ -108,7 +112,7 @@ def transpose(matrix: list[list], return_map: bool = True) -> list[list] | map[l
|
|||
raise TypeError("Expected a matrix, got int/list instead")
|
||||
|
||||
|
||||
def minor(matrix: list[list], row: int, column: int) -> list[list]:
|
||||
def minor(matrix: list[list[int]], row: int, column: int) -> list[list[int]]:
|
||||
"""
|
||||
>>> minor([[1, 2], [3, 4]], 1, 1)
|
||||
[[1]]
|
||||
|
@ -117,7 +121,7 @@ def minor(matrix: list[list], row: int, column: int) -> list[list]:
|
|||
return [row[:column] + row[column + 1 :] for row in minor]
|
||||
|
||||
|
||||
def determinant(matrix: list[list]) -> int:
|
||||
def determinant(matrix: list[list[int]]) -> Any:
|
||||
"""
|
||||
>>> determinant([[1, 2], [3, 4]])
|
||||
-2
|
||||
|
@ -133,7 +137,7 @@ def determinant(matrix: list[list]) -> int:
|
|||
)
|
||||
|
||||
|
||||
def inverse(matrix: list[list]) -> list[list] | None:
|
||||
def inverse(matrix: list[list[int]]) -> list[list[float]] | None:
|
||||
"""
|
||||
>>> inverse([[1, 2], [3, 4]])
|
||||
[[-2.0, 1.0], [1.5, -0.5]]
|
||||
|
@ -157,27 +161,27 @@ def inverse(matrix: list[list]) -> list[list] | None:
|
|||
return scalar_multiply(adjugate, 1 / det)
|
||||
|
||||
|
||||
def _check_not_integer(matrix: list[list]) -> bool:
|
||||
def _check_not_integer(matrix: list[list[int]]) -> bool:
|
||||
return not isinstance(matrix, int) and not isinstance(matrix[0], int)
|
||||
|
||||
|
||||
def _shape(matrix: list[list]) -> tuple[int, int]:
|
||||
def _shape(matrix: list[list[int]]) -> tuple[int, int]:
|
||||
return len(matrix), len(matrix[0])
|
||||
|
||||
|
||||
def _verify_matrix_sizes(
|
||||
matrix_a: list[list], matrix_b: list[list]
|
||||
) -> tuple[tuple, tuple]:
|
||||
matrix_a: list[list[int]], matrix_b: list[list[int]]
|
||||
) -> tuple[tuple[int, int], tuple[int, int]]:
|
||||
shape = _shape(matrix_a) + _shape(matrix_b)
|
||||
if shape[0] != shape[3] or shape[1] != shape[2]:
|
||||
raise ValueError(
|
||||
"operands could not be broadcast together with shape "
|
||||
f"operands could not be broadcast together with shape "
|
||||
f"({shape[0], shape[1]}), ({shape[2], shape[3]})"
|
||||
)
|
||||
return (shape[0], shape[2]), (shape[1], shape[3])
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
matrix_a = [[12, 10], [3, 9]]
|
||||
matrix_b = [[3, 4], [7, 4]]
|
||||
matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34], [41, 42, 43, 44]]
|
||||
|
|
|
@ -16,7 +16,7 @@ We can decrease the n times multiplication by following the divide and conquer a
|
|||
"""
|
||||
|
||||
|
||||
def multiply(matrix_a, matrix_b):
|
||||
def multiply(matrix_a: list[list[int]], matrix_b: list[list[int]]) -> list[list[int]]:
|
||||
matrix_c = []
|
||||
n = len(matrix_a)
|
||||
for i in range(n):
|
||||
|
@ -30,11 +30,11 @@ def multiply(matrix_a, matrix_b):
|
|||
return matrix_c
|
||||
|
||||
|
||||
def identity(n):
|
||||
def identity(n: int) -> list[list[int]]:
|
||||
return [[int(row == column) for column in range(n)] for row in range(n)]
|
||||
|
||||
|
||||
def nth_fibonacci_matrix(n):
|
||||
def nth_fibonacci_matrix(n: int) -> int:
|
||||
"""
|
||||
>>> nth_fibonacci_matrix(100)
|
||||
354224848179261915075
|
||||
|
@ -54,7 +54,7 @@ def nth_fibonacci_matrix(n):
|
|||
return res_matrix[0][0]
|
||||
|
||||
|
||||
def nth_fibonacci_bruteforce(n):
|
||||
def nth_fibonacci_bruteforce(n: int) -> int:
|
||||
"""
|
||||
>>> nth_fibonacci_bruteforce(100)
|
||||
354224848179261915075
|
||||
|
@ -70,7 +70,7 @@ def nth_fibonacci_bruteforce(n):
|
|||
return fib1
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
for ordinal in "0th 1st 2nd 3rd 10th 100th 1000th".split():
|
||||
n = int("".join(c for c in ordinal if c in "0123456789")) # 1000th --> 1000
|
||||
print(
|
||||
|
|
|
@ -8,7 +8,7 @@ https://stackoverflow.com/questions/42519/how-do-you-rotate-a-two-dimensional-ar
|
|||
from __future__ import annotations
|
||||
|
||||
|
||||
def make_matrix(row_size: int = 4) -> list[list]:
|
||||
def make_matrix(row_size: int = 4) -> list[list[int]]:
|
||||
"""
|
||||
>>> make_matrix()
|
||||
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
|
||||
|
@ -25,7 +25,7 @@ def make_matrix(row_size: int = 4) -> list[list]:
|
|||
return [[1 + x + y * row_size for x in range(row_size)] for y in range(row_size)]
|
||||
|
||||
|
||||
def rotate_90(matrix: list[list]) -> list[list]:
|
||||
def rotate_90(matrix: list[list[int]]) -> list[list[int]]:
|
||||
"""
|
||||
>>> rotate_90(make_matrix())
|
||||
[[4, 8, 12, 16], [3, 7, 11, 15], [2, 6, 10, 14], [1, 5, 9, 13]]
|
||||
|
@ -37,7 +37,7 @@ def rotate_90(matrix: list[list]) -> list[list]:
|
|||
# OR.. transpose(reverse_column(matrix))
|
||||
|
||||
|
||||
def rotate_180(matrix: list[list]) -> list[list]:
|
||||
def rotate_180(matrix: list[list[int]]) -> list[list[int]]:
|
||||
"""
|
||||
>>> rotate_180(make_matrix())
|
||||
[[16, 15, 14, 13], [12, 11, 10, 9], [8, 7, 6, 5], [4, 3, 2, 1]]
|
||||
|
@ -49,7 +49,7 @@ def rotate_180(matrix: list[list]) -> list[list]:
|
|||
# OR.. reverse_column(reverse_row(matrix))
|
||||
|
||||
|
||||
def rotate_270(matrix: list[list]) -> list[list]:
|
||||
def rotate_270(matrix: list[list[int]]) -> list[list[int]]:
|
||||
"""
|
||||
>>> rotate_270(make_matrix())
|
||||
[[13, 9, 5, 1], [14, 10, 6, 2], [15, 11, 7, 3], [16, 12, 8, 4]]
|
||||
|
@ -61,22 +61,22 @@ def rotate_270(matrix: list[list]) -> list[list]:
|
|||
# OR.. transpose(reverse_row(matrix))
|
||||
|
||||
|
||||
def transpose(matrix: list[list]) -> list[list]:
|
||||
def transpose(matrix: list[list[int]]) -> list[list[int]]:
|
||||
matrix[:] = [list(x) for x in zip(*matrix)]
|
||||
return matrix
|
||||
|
||||
|
||||
def reverse_row(matrix: list[list]) -> list[list]:
|
||||
def reverse_row(matrix: list[list[int]]) -> list[list[int]]:
|
||||
matrix[:] = matrix[::-1]
|
||||
return matrix
|
||||
|
||||
|
||||
def reverse_column(matrix: list[list]) -> list[list]:
|
||||
def reverse_column(matrix: list[list[int]]) -> list[list[int]]:
|
||||
matrix[:] = [x[::-1] for x in matrix]
|
||||
return matrix
|
||||
|
||||
|
||||
def print_matrix(matrix: list[list]) -> None:
|
||||
def print_matrix(matrix: list[list[int]]) -> None:
|
||||
for i in matrix:
|
||||
print(*i)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ from __future__ import annotations
|
|||
|
||||
|
||||
def search_in_a_sorted_matrix(
|
||||
mat: list[list], m: int, n: int, key: int | float
|
||||
mat: list[list[int]], m: int, n: int, key: int | float
|
||||
) -> None:
|
||||
"""
|
||||
>>> search_in_a_sorted_matrix(
|
||||
|
@ -30,7 +30,7 @@ def search_in_a_sorted_matrix(
|
|||
print(f"Key {key} not found")
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
mat = [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]]
|
||||
x = int(input("Enter the element to be searched:"))
|
||||
print(mat)
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
class Matrix:
|
||||
"""
|
||||
<class Matrix>
|
||||
Matrix structure.
|
||||
"""
|
||||
|
||||
def __init__(self, row: int, column: int, default_value: float = 0):
|
||||
def __init__(self, row: int, column: int, default_value: float = 0) -> None:
|
||||
"""
|
||||
<method Matrix.__init__>
|
||||
Initialize matrix with given size and default value.
|
||||
|
||||
Example:
|
||||
>>> a = Matrix(2, 3, 1)
|
||||
>>> a
|
||||
|
@ -20,7 +24,7 @@ class Matrix:
|
|||
self.row, self.column = row, column
|
||||
self.array = [[default_value for c in range(column)] for r in range(row)]
|
||||
|
||||
def __str__(self):
|
||||
def __str__(self) -> str:
|
||||
"""
|
||||
<method Matrix.__str__>
|
||||
Return string representation of this matrix.
|
||||
|
@ -37,7 +41,7 @@ class Matrix:
|
|||
string_format_identifier = "%%%ds" % (max_element_length,)
|
||||
|
||||
# Make string and return
|
||||
def single_line(row_vector):
|
||||
def single_line(row_vector: list[float]) -> str:
|
||||
nonlocal string_format_identifier
|
||||
line = "["
|
||||
line += ", ".join(string_format_identifier % (obj,) for obj in row_vector)
|
||||
|
@ -47,14 +51,13 @@ class Matrix:
|
|||
s += "\n".join(single_line(row_vector) for row_vector in self.array)
|
||||
return s
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return str(self)
|
||||
|
||||
def validateIndices(self, loc: tuple):
|
||||
def validateIndices(self, loc: tuple[int, int]) -> bool:
|
||||
"""
|
||||
<method Matrix.validateIndices>
|
||||
Check if given indices are valid to pick element from matrix.
|
||||
|
||||
Example:
|
||||
>>> a = Matrix(2, 6, 0)
|
||||
>>> a.validateIndices((2, 7))
|
||||
|
@ -69,11 +72,10 @@ class Matrix:
|
|||
else:
|
||||
return True
|
||||
|
||||
def __getitem__(self, loc: tuple):
|
||||
def __getitem__(self, loc: tuple[int, int]) -> Any:
|
||||
"""
|
||||
<method Matrix.__getitem__>
|
||||
Return array[row][column] where loc = (row, column).
|
||||
|
||||
Example:
|
||||
>>> a = Matrix(3, 2, 7)
|
||||
>>> a[1, 0]
|
||||
|
@ -82,11 +84,10 @@ class Matrix:
|
|||
assert self.validateIndices(loc)
|
||||
return self.array[loc[0]][loc[1]]
|
||||
|
||||
def __setitem__(self, loc: tuple, value: float):
|
||||
def __setitem__(self, loc: tuple[int, int], value: float) -> None:
|
||||
"""
|
||||
<method Matrix.__setitem__>
|
||||
Set array[row][column] = value where loc = (row, column).
|
||||
|
||||
Example:
|
||||
>>> a = Matrix(2, 3, 1)
|
||||
>>> a[1, 2] = 51
|
||||
|
@ -98,11 +99,10 @@ class Matrix:
|
|||
assert self.validateIndices(loc)
|
||||
self.array[loc[0]][loc[1]] = value
|
||||
|
||||
def __add__(self, another):
|
||||
def __add__(self, another: Matrix) -> Matrix:
|
||||
"""
|
||||
<method Matrix.__add__>
|
||||
Return self + another.
|
||||
|
||||
Example:
|
||||
>>> a = Matrix(2, 1, -4)
|
||||
>>> b = Matrix(2, 1, 3)
|
||||
|
@ -123,11 +123,10 @@ class Matrix:
|
|||
result[r, c] = self[r, c] + another[r, c]
|
||||
return result
|
||||
|
||||
def __neg__(self):
|
||||
def __neg__(self) -> Matrix:
|
||||
"""
|
||||
<method Matrix.__neg__>
|
||||
Return -self.
|
||||
|
||||
Example:
|
||||
>>> a = Matrix(2, 2, 3)
|
||||
>>> a[0, 1] = a[1, 0] = -2
|
||||
|
@ -143,14 +142,13 @@ class Matrix:
|
|||
result[r, c] = -self[r, c]
|
||||
return result
|
||||
|
||||
def __sub__(self, another):
|
||||
def __sub__(self, another: Matrix) -> Matrix:
|
||||
return self + (-another)
|
||||
|
||||
def __mul__(self, another):
|
||||
def __mul__(self, another: int | float | Matrix) -> Matrix:
|
||||
"""
|
||||
<method Matrix.__mul__>
|
||||
Return self * another.
|
||||
|
||||
Example:
|
||||
>>> a = Matrix(2, 3, 1)
|
||||
>>> a[0,2] = a[1,2] = 3
|
||||
|
@ -177,11 +175,10 @@ class Matrix:
|
|||
else:
|
||||
raise TypeError(f"Unsupported type given for another ({type(another)})")
|
||||
|
||||
def transpose(self):
|
||||
def transpose(self) -> Matrix:
|
||||
"""
|
||||
<method Matrix.transpose>
|
||||
Return self^T.
|
||||
|
||||
Example:
|
||||
>>> a = Matrix(2, 3)
|
||||
>>> for r in range(2):
|
||||
|
@ -201,7 +198,7 @@ class Matrix:
|
|||
result[c, r] = self[r, c]
|
||||
return result
|
||||
|
||||
def ShermanMorrison(self, u, v):
|
||||
def ShermanMorrison(self, u: Matrix, v: Matrix) -> Any:
|
||||
"""
|
||||
<method Matrix.ShermanMorrison>
|
||||
Apply Sherman-Morrison formula in O(n^2).
|
||||
|
@ -211,7 +208,6 @@ class Matrix:
|
|||
impossible to calculate.
|
||||
Warning: This method doesn't check if self is invertible.
|
||||
Make sure self is invertible before execute this method.
|
||||
|
||||
Example:
|
||||
>>> ainv = Matrix(3, 3, 0)
|
||||
>>> for i in range(3): ainv[i,i] = 1
|
||||
|
@ -243,7 +239,7 @@ class Matrix:
|
|||
# Testing
|
||||
if __name__ == "__main__":
|
||||
|
||||
def test1():
|
||||
def test1() -> None:
|
||||
# a^(-1)
|
||||
ainv = Matrix(3, 3, 0)
|
||||
for i in range(3):
|
||||
|
@ -256,11 +252,11 @@ if __name__ == "__main__":
|
|||
v[0, 0], v[1, 0], v[2, 0] = 4, -2, 5
|
||||
print(f"u is {u}")
|
||||
print(f"v is {v}")
|
||||
print(f"uv^T is {u * v.transpose()}")
|
||||
print("uv^T is %s" % (u * v.transpose()))
|
||||
# Sherman Morrison
|
||||
print(f"(a + uv^T)^(-1) is {ainv.ShermanMorrison(u, v)}")
|
||||
|
||||
def test2():
|
||||
def test2() -> None:
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
"""
|
||||
This program print the matrix in spiral form.
|
||||
This problem has been solved through recursive way.
|
||||
|
||||
Matrix must satisfy below conditions
|
||||
i) matrix should be only one or two dimensional
|
||||
ii) number of column of all rows should be equal
|
||||
"""
|
||||
|
||||
from collections.abc import Iterable
|
||||
|
||||
|
||||
def check_matrix(matrix):
|
||||
def check_matrix(matrix: list[list[int]]) -> bool:
|
||||
# must be
|
||||
if matrix and isinstance(matrix, Iterable):
|
||||
if isinstance(matrix[0], Iterable):
|
||||
matrix = list(list(row) for row in matrix)
|
||||
if matrix and isinstance(matrix, list):
|
||||
if isinstance(matrix[0], list):
|
||||
prev_len = 0
|
||||
for row in matrix:
|
||||
if prev_len == 0:
|
||||
|
@ -29,32 +27,48 @@ def check_matrix(matrix):
|
|||
return result
|
||||
|
||||
|
||||
def spiralPrint(a):
|
||||
def spiral_print_clockwise(a: list[list[int]]) -> None:
|
||||
"""
|
||||
>>> spiral_print_clockwise([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
8
|
||||
12
|
||||
11
|
||||
10
|
||||
9
|
||||
5
|
||||
6
|
||||
7
|
||||
"""
|
||||
if check_matrix(a) and len(a) > 0:
|
||||
matRow = len(a)
|
||||
if isinstance(a[0], Iterable):
|
||||
matCol = len(a[0])
|
||||
a = list(list(row) for row in a)
|
||||
mat_row = len(a)
|
||||
if isinstance(a[0], list):
|
||||
mat_col = len(a[0])
|
||||
else:
|
||||
for dat in a:
|
||||
print(dat),
|
||||
print(dat)
|
||||
return
|
||||
|
||||
# horizotal printing increasing
|
||||
for i in range(0, matCol):
|
||||
print(a[0][i]),
|
||||
for i in range(0, mat_col):
|
||||
print(a[0][i])
|
||||
# vertical printing down
|
||||
for i in range(1, matRow):
|
||||
print(a[i][matCol - 1]),
|
||||
for i in range(1, mat_row):
|
||||
print(a[i][mat_col - 1])
|
||||
# horizotal printing decreasing
|
||||
if matRow > 1:
|
||||
for i in range(matCol - 2, -1, -1):
|
||||
print(a[matRow - 1][i]),
|
||||
if mat_row > 1:
|
||||
for i in range(mat_col - 2, -1, -1):
|
||||
print(a[mat_row - 1][i])
|
||||
# vertical printing up
|
||||
for i in range(matRow - 2, 0, -1):
|
||||
print(a[i][0]),
|
||||
remainMat = [row[1 : matCol - 1] for row in a[1 : matRow - 1]]
|
||||
if len(remainMat) > 0:
|
||||
spiralPrint(remainMat)
|
||||
for i in range(mat_row - 2, 0, -1):
|
||||
print(a[i][0])
|
||||
remain_mat = [row[1 : mat_col - 1] for row in a[1 : mat_row - 1]]
|
||||
if len(remain_mat) > 0:
|
||||
spiral_print_clockwise(remain_mat)
|
||||
else:
|
||||
return
|
||||
else:
|
||||
|
@ -64,5 +78,5 @@ def spiralPrint(a):
|
|||
|
||||
# driver code
|
||||
if __name__ == "__main__":
|
||||
a = ([1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12])
|
||||
spiralPrint(a)
|
||||
a = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
|
||||
spiral_print_clockwise(a)
|
||||
|
|
Loading…
Reference in New Issue
Block a user