From a6c8cd6ed9b54d7d15c2f29da324f2b76281289b Mon Sep 17 00:00:00 2001 From: Pavel Alimov <42354122+Krekep@users.noreply.github.com> Date: Tue, 17 Sep 2024 19:31:30 +0300 Subject: [PATCH 1/7] Update task1.md --- project/__main__.py | 1 - project/my_module.py | 86 ++++++++++++++++++++++++++++++++++++++++++++ project/tests.py | 34 ++++++++++++++++++ tasks/task1.md | 3 +- 4 files changed, 122 insertions(+), 2 deletions(-) delete mode 100644 project/__main__.py create mode 100644 project/my_module.py create mode 100644 project/tests.py diff --git a/project/__main__.py b/project/__main__.py deleted file mode 100644 index 344b363a..00000000 --- a/project/__main__.py +++ /dev/null @@ -1 +0,0 @@ -print("exec sources directory") diff --git a/project/my_module.py b/project/my_module.py new file mode 100644 index 00000000..deceb9e3 --- /dev/null +++ b/project/my_module.py @@ -0,0 +1,86 @@ +# Operation on vectors + +def the_scalar_product_of_vectors(vector_1, vector_2): + """ + Функция the_scalar_product_of_vectors проверяет, имеют ли векторы одинаковую длину. Если нет, она возвращает None. + В противном случае, функция вычисляет скалярное произведение, перемножая соответствующие элементы векторов и суммируя результаты. + Параметры: + vector_1 (list): Первый вектор, представленный в виде списка чисел. + vector_2 (list): Второй вектор, представленный в виде списка чисел. + Возвращаемое значение: + int: Скалярное произведение векторов vector_1 и vector_2, если они имеют одинаковую длину. + None: Если векторы имеют разную длину. + """ + if len(vector_1) != len(vector_2): + return None + else: + p = 0 + for i in range(len(vector_1)): + p += vector_1[i] * vector_2[i] + return p + + +def vector_length(vector): + """" + Функция vector_length вычисляет длину вектора, представленного в виде списка чисел. + Параметры: + vector (list): Вектор, представленный в виде списка чисел. + Возвращаемое значение: + int: Длина вектора, округленная до целого числа + """ + s = 0 + for i in vector: + s += i**2 + return int(pow(s, 0.5)) + + +def the_angle_between_the_vectors(vector_1, vector_2): + """ + Функция the_angle_between_the_vectors вычисляет угол между двумя векторами, + заданными в виде списков чисел, используя скалярное произведение и длины векторов. + Параметры: + vector_1 (list): Первый вектор, представленный в виде списка чисел. + vector_2 (list): Второй вектор, представленный в виде списка чисел. + Возвращаемое значение: + float: Угол между векторами в радианах, c точностью до двух знаков после запятой. + + """ + s = the_scalar_product_of_vectors(vector_1, vector_2) + angle = s / (vector_length(vector_1)*vector_length(vector_2)) + return round(angle, 2) + + +# Operations on matrices + + +def matrix_addition(matrix_1, matrix_2): + if len(matrix_1) != len(matrix_2) or len(matrix_1[0]) != len(matrix_2[0]): + return None + else: + matrix_sum = [[0]*len(matrix_1[0]) for i in range(len(matrix_1))] + for i in range(len(matrix_1)): + for j in range(len(matrix_1[0])): + matrix_sum[i][j] = matrix_1[i][j] + matrix_2[i][j] + return matrix_sum + + +def matrix_multiplication(matrix_1, matrix_2): + if len(matrix_1[0]) != len(matrix_2): + return None + else: + matrix_mult = [[0]*len(matrix_2[0]) for i in range(len(matrix_1))] + for i in range(len(matrix_1)): + for j in range(len(matrix_2[0])): + for r in range(len(matrix_2)): + matrix_mult[i][j] += int(matrix_1[i][r]) * int(matrix_2[r][j]) + return matrix_mult + + +def matrix_transposition(matrix): + matrix_trans = [[0]*len(matrix) for i in range(len(matrix[0]))] + for i in range(len(matrix)): + for j in range(len(matrix[0])): + matrix_trans[j][i] = matrix[i][j] + return matrix_trans + + diff --git a/project/tests.py b/project/tests.py new file mode 100644 index 00000000..bcb470ea --- /dev/null +++ b/project/tests.py @@ -0,0 +1,34 @@ +from .my_module import * + + +def test_1_the_scalar_product_of_vectors(): + assert the_scalar_product_of_vectors([2, -5], [-1, 0]) == -2 + + +def test_2_the_scalar_product_of_vectors(): + assert the_scalar_product_of_vectors([1, 1], [2, 1, 4, 9]) is None + + +def test_3_the_scalar_product_of_vectors(): + assert the_scalar_product_of_vectors([1, 2, -4], [6, -1, 1]) == 0 + + +def test_1_vector_length(): + assert vector_length([3, 4, 0]) == 5 + + +def test_2_vector_length(): + assert vector_length([-5, 8]) == int(pow(89, 0.5)) + + +def test_3_vector_length(): + assert vector_length([-2, 0, 5]) == int(pow(29, 0.5)) + + + + + + + + + diff --git a/tasks/task1.md b/tasks/task1.md index 2d067506..c8bc0c35 100644 --- a/tasks/task1.md +++ b/tasks/task1.md @@ -1,6 +1,6 @@ # Задача 1. Инициализация рабочего окружения -* **Дедлайн**: 27.09.2024, 23:59 +* **Дедлайн**: 03.10.2024, 23:59 * Полный балл: 5 ## Задача @@ -13,3 +13,4 @@ - [ ] Операции над матрицами: сложение, умножение, транспонирование. - [ ] Добавить тесты покрывающие реализованную функциональность. - [ ] Добавить запуск тестов с помощью `pytest` в `.github/workflows/`. +- [ ] Добавить статическую проверку типов с помощью `mypy` в `.github/workflows/`. From f90a53bd5924866aa1ea60b11ef9213f49c37640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D1=84=D0=B8=D1=8F=20=D0=A5=D1=80=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D0=BD=D0=BA=D0=BE=D0=B2=D0=B0?= Date: Thu, 3 Oct 2024 16:03:39 +0300 Subject: [PATCH 2/7] commit message --- project/my_module.py | 107 ++++++++++++++++++++++++++++++------------- project/tests.py | 52 +++++++++++++++++++++ 2 files changed, 128 insertions(+), 31 deletions(-) diff --git a/project/my_module.py b/project/my_module.py index deceb9e3..81fafc9c 100644 --- a/project/my_module.py +++ b/project/my_module.py @@ -1,15 +1,18 @@ # Operation on vectors +from math import pi, acos def the_scalar_product_of_vectors(vector_1, vector_2): """ - Функция the_scalar_product_of_vectors проверяет, имеют ли векторы одинаковую длину. Если нет, она возвращает None. - В противном случае, функция вычисляет скалярное произведение, перемножая соответствующие элементы векторов и суммируя результаты. - Параметры: - vector_1 (list): Первый вектор, представленный в виде списка чисел. - vector_2 (list): Второй вектор, представленный в виде списка чисел. - Возвращаемое значение: - int: Скалярное произведение векторов vector_1 и vector_2, если они имеют одинаковую длину. - None: Если векторы имеют разную длину. + Function the_scalar_product_of_vectors checks whether the vectors have the same length. If not, it returns None. + Otherwise, the function calculates the scalar product by multiplying the corresponding elements of the vectors + and summing the results. + Parameters: + vector_1 (list): The first vector, represented as a list of numbers. + vector_2 (list): The second vector, represented as a list of numbers. + Return value: + int: The scalar product of vectors vector_1 and vector_2, if they have the same length. + None: If the vectors have different lengths. + """ if len(vector_1) != len(vector_2): return None @@ -22,42 +25,56 @@ def the_scalar_product_of_vectors(vector_1, vector_2): def vector_length(vector): """" - Функция vector_length вычисляет длину вектора, представленного в виде списка чисел. - Параметры: - vector (list): Вектор, представленный в виде списка чисел. - Возвращаемое значение: - int: Длина вектора, округленная до целого числа - """ + The vector_length function calculates the length of a vector represented as a list of numbers. + Parameters: + vector (list): A vector represented as a list of numbers. + Return value: + int: The length of the vector, rounded to an integer + + """ s = 0 for i in vector: s += i**2 - return int(pow(s, 0.5)) + return round(pow(s, 0.5), 2) def the_angle_between_the_vectors(vector_1, vector_2): """ - Функция the_angle_between_the_vectors вычисляет угол между двумя векторами, - заданными в виде списков чисел, используя скалярное произведение и длины векторов. - Параметры: - vector_1 (list): Первый вектор, представленный в виде списка чисел. - vector_2 (list): Второй вектор, представленный в виде списка чисел. - Возвращаемое значение: - float: Угол между векторами в радианах, c точностью до двух знаков после запятой. + The_angle_between_the_vectors function calculates the angle between two vectors + given as lists of numbers using the scalar product and the lengths of the vectors. + Parameters: + vector_1 (list): The first vector, represented as a list of numbers. + vector_2 (list): The second vector, represented as a list of numbers. + Return value: + float: The angle between the vectors in radians, with an accuracy of two decimal places. """ s = the_scalar_product_of_vectors(vector_1, vector_2) - angle = s / (vector_length(vector_1)*vector_length(vector_2)) - return round(angle, 2) + angle = s / (vector_length(vector_1) * vector_length(vector_2)) + print(s, vector_length(vector_1), vector_length(vector_2)) + angle = acos(angle)*180/pi + return round(angle) # Operations on matrices def matrix_addition(matrix_1, matrix_2): + """ + Adds two matrices together. + Args: + matrix_1 (list of lists): The first matrix. + matrix_2 (list of lists): The second matrix. + Returns: + list of lists: The sum of the two matrices, or None if the matrices have + different dimensions. + Raises: + TypeError: If either input is not a list of lists. + """ if len(matrix_1) != len(matrix_2) or len(matrix_1[0]) != len(matrix_2[0]): return None else: - matrix_sum = [[0]*len(matrix_1[0]) for i in range(len(matrix_1))] + matrix_sum = [[0]*len(matrix_1[0]) for _ in range(len(matrix_1))] for i in range(len(matrix_1)): for j in range(len(matrix_1[0])): matrix_sum[i][j] = matrix_1[i][j] + matrix_2[i][j] @@ -65,10 +82,22 @@ def matrix_addition(matrix_1, matrix_2): def matrix_multiplication(matrix_1, matrix_2): + """ + The matrix_multiplication function multiplies two matrices represented as nested lists. + Parameters: + matrix_1 (list of lists): The first matrix. + matrix_2 (list of lists): The second matrix. + Return value: + list of lists: The product of two matrices if the number of columns in the first matrix is equal to the number of rows in the second matrix. + None: If the number of columns in the first matrix is not equal to the number of rows in the second matrix. + Exceptions: + TypeError: Occurs if one or both of the input arguments are not lists or nested lists. + + """ if len(matrix_1[0]) != len(matrix_2): return None else: - matrix_mult = [[0]*len(matrix_2[0]) for i in range(len(matrix_1))] + matrix_mult = [[0]*len(matrix_2[0]) for _ in range(len(matrix_1))] for i in range(len(matrix_1)): for j in range(len(matrix_2[0])): for r in range(len(matrix_2)): @@ -77,10 +106,26 @@ def matrix_multiplication(matrix_1, matrix_2): def matrix_transposition(matrix): - matrix_trans = [[0]*len(matrix) for i in range(len(matrix[0]))] - for i in range(len(matrix)): - for j in range(len(matrix[0])): - matrix_trans[j][i] = matrix[i][j] - return matrix_trans + """ + The matrix_transposition function transposes a matrix represented as a nested list. + Transposing a matrix means exchanging rows and columns. + The function passes through each element of the original matrix matrix using nested for loops. + For each matrix[i][j] element (row i, column j), the function assigns the value of the matrix_trans[j][i] element + (row j, column i). Thus, the rows and columns of the original matrix are swapped. + Parameters: + matrix (list of lists): The matrix to be transposed. + Return value: + list of lists: A transposed matrix represented as a nested list. + Exceptions: + TypeError: Occurs if the input argument is not a list or a nested list. + """ + if not matrix: + return [] + else: + matrix_trans = [[0]*len(matrix) for _ in range(len(matrix[0]))] + for i in range(len(matrix)): + for j in range(len(matrix[0])): + matrix_trans[j][i] = matrix[i][j] + return matrix_trans diff --git a/project/tests.py b/project/tests.py index bcb470ea..6a1e56f6 100644 --- a/project/tests.py +++ b/project/tests.py @@ -25,10 +25,62 @@ def test_3_vector_length(): assert vector_length([-2, 0, 5]) == int(pow(29, 0.5)) +def test_1_the_angle_between_the_vectors(): + assert the_angle_between_the_vectors([1, 1, -2], [1, 0, -1]) == 30 +def test_2_the_angle_between_the_vectors(): + assert the_angle_between_the_vectors([2, -2, 0], [3, 0, -3]) == 60 +def test_1_matrix_addition(): + assert matrix_addition([[1, 2], [3, 4]], [[5, 6], [7, 8]]) == [[6, 8], [10, 12]] +def test_2_matrix_addition(): + assert matrix_addition([[1, 2], [3, 4]], [[5, 6, 7], [8, 9, 10]]) is None + + +def test_3_matrix_addition(): + assert matrix_addition([[]], [[]]) == [[]] + + +def test_4_matrix_addition(): + assert matrix_addition([[1]], [[2]]) == [[3]] + + +def test_5_matrix_addition(): + assert matrix_addition([[-1, -2], [-3, -4]], [[1, 2], [3, 4]]) == [[0, 0], [0, 0]] + + +def test_1_matrix_multiplication(): + assert matrix_multiplication([[1, 2], [3, 4]], [[5, 6], [7, 8]]) == [[19, 22], [43, 50]] + + +def test_2_matrix_multiplication(): + assert matrix_multiplication([[1, 2, 3], [3, 4, 1]], [[5, 6, 7], [8, 9, 10]]) is None + + +def test_3_matrix_multiplication(): + assert matrix_multiplication([[1]], [[2]]) == [[2]] + + +def test_4_matrix_multiplication(): + assert matrix_multiplication([[]], [[]]) is None + +def test_1_matrix_transposition(): + assert matrix_transposition([[1, 2, 3], [4, 5, 6]]) == [[1, 4], [2, 5], [3, 6]] + + +def test_2_matrix_transposition(): + assert matrix_transposition([]) == [] + + +def test_3_matrix_transposition(): + assert matrix_transposition([[1]]) == [[1]] + + +def test_4_matrix_transposition(): + assert matrix_transposition([[1, 2], [3, 4]]) == [[1, 3], [2, 4]] + From a8cfe85e64d6c75b4fd46430eb7c67db338d75c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D1=84=D0=B8=D1=8F=20=D0=A5=D1=80=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D0=BD=D0=BA=D0=BE=D0=B2=D0=B0?= Date: Thu, 3 Oct 2024 21:21:30 +0300 Subject: [PATCH 3/7] dz1 --- .github/workflows/code_style.yml | 35 ++---- ....py => operation_on_vectors_and_matrix.py} | 50 ++++++-- project/tests.py | 86 -------------- tests/test_basic.py | 18 --- tests/test_matrix.py | 107 ++++++++++++++++++ tests/test_vectors.py | 54 +++++++++ 6 files changed, 213 insertions(+), 137 deletions(-) rename project/{my_module.py => operation_on_vectors_and_matrix.py} (85%) delete mode 100644 project/tests.py delete mode 100644 tests/test_basic.py create mode 100644 tests/test_matrix.py create mode 100644 tests/test_vectors.py diff --git a/.github/workflows/code_style.yml b/.github/workflows/code_style.yml index bd1ae279..bbdeee6c 100644 --- a/.github/workflows/code_style.yml +++ b/.github/workflows/code_style.yml @@ -27,31 +27,18 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - name: Set up Git repository - uses: actions/checkout@v2 - - # Setup Python with version from matrix - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} - - # Install requirements - - name: Install requirements - - # Runs command-line programs using the operating system's shell + python-version: '3.x' + - name: Install dependencies run: | - python -m pip install --upgrade pip wheel setuptools - python -m pip install -r requirements.txt - python -m pip list - - # Install pre-commit from .pre-commit-config.yaml - - name: Install pre-commit + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Run pytest run: | - pre-commit install - - # Run pre-commit on all the files in the repo - - name: Run pre-commit + python ./scripts/run_tests.py + - name: Run mypy run: | - pre-commit run --all-files --color always --verbose --show-diff-on-failure + mypy project/ diff --git a/project/my_module.py b/project/operation_on_vectors_and_matrix.py similarity index 85% rename from project/my_module.py rename to project/operation_on_vectors_and_matrix.py index 81fafc9c..9e858c0c 100644 --- a/project/my_module.py +++ b/project/operation_on_vectors_and_matrix.py @@ -1,15 +1,21 @@ # Operation on vectors from math import pi, acos -def the_scalar_product_of_vectors(vector_1, vector_2): + + +def the_scalar_product_of_vectors(vector_1: list[int], vector_2: list[int]): """ Function the_scalar_product_of_vectors checks whether the vectors have the same length. If not, it returns None. - Otherwise, the function calculates the scalar product by multiplying the corresponding elements of the vectors + Otherwise, the function calculates the scalar pro1duct by multiplying the corresponding elements of the vectors and summing the results. + Parameters: + ----------- vector_1 (list): The first vector, represented as a list of numbers. vector_2 (list): The second vector, represented as a list of numbers. + Return value: + ------------- int: The scalar product of vectors vector_1 and vector_2, if they have the same length. None: If the vectors have different lengths. @@ -23,12 +29,16 @@ def the_scalar_product_of_vectors(vector_1, vector_2): return p -def vector_length(vector): - """" +def vector_length(vector: list[int]): + """ The vector_length function calculates the length of a vector represented as a list of numbers. + Parameters: + ----------- vector (list): A vector represented as a list of numbers. + Return value: + ------------- int: The length of the vector, rounded to an integer """ @@ -38,20 +48,23 @@ def vector_length(vector): return round(pow(s, 0.5), 2) -def the_angle_between_the_vectors(vector_1, vector_2): +def the_angle_between_the_vectors(vector_1: list[int], vector_2: list[int]): """ The_angle_between_the_vectors function calculates the angle between two vectors given as lists of numbers using the scalar product and the lengths of the vectors. + Parameters: + ----------- vector_1 (list): The first vector, represented as a list of numbers. vector_2 (list): The second vector, represented as a list of numbers. + Return value: + ------------- float: The angle between the vectors in radians, with an accuracy of two decimal places. """ s = the_scalar_product_of_vectors(vector_1, vector_2) angle = s / (vector_length(vector_1) * vector_length(vector_2)) - print(s, vector_length(vector_1), vector_length(vector_2)) angle = acos(angle)*180/pi return round(angle) @@ -59,13 +72,17 @@ def the_angle_between_the_vectors(vector_1, vector_2): # Operations on matrices -def matrix_addition(matrix_1, matrix_2): +def matrix_addition(matrix_1: list[list], matrix_2: list[list]): """ Adds two matrices together. + Args: + ----- matrix_1 (list of lists): The first matrix. matrix_2 (list of lists): The second matrix. + Returns: + -------- list of lists: The sum of the two matrices, or None if the matrices have different dimensions. Raises: @@ -81,16 +98,22 @@ def matrix_addition(matrix_1, matrix_2): return matrix_sum -def matrix_multiplication(matrix_1, matrix_2): +def matrix_multiplication(matrix_1: list[list], matrix_2: list[list]): """ The matrix_multiplication function multiplies two matrices represented as nested lists. + Parameters: + ----------- matrix_1 (list of lists): The first matrix. matrix_2 (list of lists): The second matrix. + Return value: + ------------- list of lists: The product of two matrices if the number of columns in the first matrix is equal to the number of rows in the second matrix. None: If the number of columns in the first matrix is not equal to the number of rows in the second matrix. + Exceptions: + ----------- TypeError: Occurs if one or both of the input arguments are not lists or nested lists. """ @@ -105,18 +128,24 @@ def matrix_multiplication(matrix_1, matrix_2): return matrix_mult -def matrix_transposition(matrix): +def matrix_transposition(matrix: list[list]): """ The matrix_transposition function transposes a matrix represented as a nested list. Transposing a matrix means exchanging rows and columns. The function passes through each element of the original matrix matrix using nested for loops. For each matrix[i][j] element (row i, column j), the function assigns the value of the matrix_trans[j][i] element (row j, column i). Thus, the rows and columns of the original matrix are swapped. + Parameters: + ----------- matrix (list of lists): The matrix to be transposed. + Return value: + ------------- list of lists: A transposed matrix represented as a nested list. + Exceptions: + ----------- TypeError: Occurs if the input argument is not a list or a nested list. """ @@ -129,3 +158,6 @@ def matrix_transposition(matrix): for j in range(len(matrix[0])): matrix_trans[j][i] = matrix[i][j] return matrix_trans + + + diff --git a/project/tests.py b/project/tests.py deleted file mode 100644 index 6a1e56f6..00000000 --- a/project/tests.py +++ /dev/null @@ -1,86 +0,0 @@ -from .my_module import * - - -def test_1_the_scalar_product_of_vectors(): - assert the_scalar_product_of_vectors([2, -5], [-1, 0]) == -2 - - -def test_2_the_scalar_product_of_vectors(): - assert the_scalar_product_of_vectors([1, 1], [2, 1, 4, 9]) is None - - -def test_3_the_scalar_product_of_vectors(): - assert the_scalar_product_of_vectors([1, 2, -4], [6, -1, 1]) == 0 - - -def test_1_vector_length(): - assert vector_length([3, 4, 0]) == 5 - - -def test_2_vector_length(): - assert vector_length([-5, 8]) == int(pow(89, 0.5)) - - -def test_3_vector_length(): - assert vector_length([-2, 0, 5]) == int(pow(29, 0.5)) - - -def test_1_the_angle_between_the_vectors(): - assert the_angle_between_the_vectors([1, 1, -2], [1, 0, -1]) == 30 - - -def test_2_the_angle_between_the_vectors(): - assert the_angle_between_the_vectors([2, -2, 0], [3, 0, -3]) == 60 - - -def test_1_matrix_addition(): - assert matrix_addition([[1, 2], [3, 4]], [[5, 6], [7, 8]]) == [[6, 8], [10, 12]] - - -def test_2_matrix_addition(): - assert matrix_addition([[1, 2], [3, 4]], [[5, 6, 7], [8, 9, 10]]) is None - - -def test_3_matrix_addition(): - assert matrix_addition([[]], [[]]) == [[]] - - -def test_4_matrix_addition(): - assert matrix_addition([[1]], [[2]]) == [[3]] - - -def test_5_matrix_addition(): - assert matrix_addition([[-1, -2], [-3, -4]], [[1, 2], [3, 4]]) == [[0, 0], [0, 0]] - - -def test_1_matrix_multiplication(): - assert matrix_multiplication([[1, 2], [3, 4]], [[5, 6], [7, 8]]) == [[19, 22], [43, 50]] - - -def test_2_matrix_multiplication(): - assert matrix_multiplication([[1, 2, 3], [3, 4, 1]], [[5, 6, 7], [8, 9, 10]]) is None - - -def test_3_matrix_multiplication(): - assert matrix_multiplication([[1]], [[2]]) == [[2]] - - -def test_4_matrix_multiplication(): - assert matrix_multiplication([[]], [[]]) is None - -def test_1_matrix_transposition(): - assert matrix_transposition([[1, 2, 3], [4, 5, 6]]) == [[1, 4], [2, 5], [3, 6]] - - -def test_2_matrix_transposition(): - assert matrix_transposition([]) == [] - - -def test_3_matrix_transposition(): - assert matrix_transposition([[1]]) == [[1]] - - -def test_4_matrix_transposition(): - assert matrix_transposition([[1, 2], [3, 4]]) == [[1, 3], [2, 4]] - - diff --git a/tests/test_basic.py b/tests/test_basic.py deleted file mode 100644 index 4811167b..00000000 --- a/tests/test_basic.py +++ /dev/null @@ -1,18 +0,0 @@ -import pytest -import project # on import will print something from __init__ file - - -def setup_module(module): - print("basic setup module") - - -def teardown_module(module): - print("basic teardown module") - - -def test_1(): - assert 1 + 1 == 2 - - -def test_2(): - assert "1" + "1" == "11" diff --git a/tests/test_matrix.py b/tests/test_matrix.py new file mode 100644 index 00000000..6c840004 --- /dev/null +++ b/tests/test_matrix.py @@ -0,0 +1,107 @@ +from project.operation_on_vectors_and_matrix import * + +import pytest + + +def test_matrix_addition_valid(): + matrix_1 = [[1, 2], [3, 4]] + matrix_2 = [[5, 6], [7, 8]] + expected_result = [[6, 8], [10, 12]] + assert matrix_addition(matrix_1, matrix_2) == expected_result + + +def test_matrix_addition_different_dimensions(): + matrix_1 = [[1, 2], [3, 4]] + matrix_2 = [[5, 6, 7], [8, 9, 10]] + assert matrix_addition(matrix_1, matrix_2) is None + + +def test_matrix_addition_empty(): + matrix_1 = [[]] + matrix_2 = [[]] + assert matrix_addition(matrix_1, matrix_2) == [[]] + + +def test_matrix_addition_single_element(): + matrix_1 = [[1]] + matrix_2 = [[2]] + expected_result = [[3]] + assert matrix_addition(matrix_1, matrix_2) == expected_result + + +def test_matrix_addition_negative_numbers(): + matrix_1 = [[-1, -2], [-3, -4]] + matrix_2 = [[1, 2], [3, 4]] + expected_result = [[0, 0], [0, 0]] + assert matrix_addition(matrix_1, matrix_2) == expected_result + + +def test_matrix_multiplication_valid(): + matrix_1 = [[1, 2], [3, 4]] + matrix_2 = [[5, 6], [7, 8]] + expected_result = [[19, 22], [43, 50]] + assert matrix_multiplication(matrix_1, matrix_2) == expected_result + + +def test_matrix_multiplication_different_dimensions(): + matrix_1 = [[1, 2], [3, 4]] + matrix_2 = [[5, 6, 7, 0], [8, 9, 10, 11], [1, 2, 3, 4]] + assert matrix_multiplication(matrix_1, matrix_2) is None + + +def test_matrix_multiplication_empty(): + matrix_1 = [[]] + matrix_2 = [[]] + assert matrix_multiplication(matrix_1, matrix_2) is None + + +def test_matrix_multiplication_single_element(): + matrix_1 = [[1]] + matrix_2 = [[2]] + expected_result = [[2]] + assert matrix_multiplication(matrix_1, matrix_2) == expected_result + + +def test_matrix_multiplication_identity(): + matrix_1 = [[1, 2], [3, 4]] + matrix_2 = [[1, 0], [0, 1]] + assert matrix_multiplication(matrix_1, matrix_2) == matrix_1 + + +def test_matrix_multiplication_negative_numbers(): + matrix_1 = [[-1, -2], [-3, -4]] + matrix_2 = [[1, 2], [3, 4]] + expected_result = [[-7, -10], [-15, -22]] + assert matrix_multiplication(matrix_1, matrix_2) == expected_result + + +def test_matrix_transposition_valid(): + matrix = [[1, 2, 3], [4, 5, 6]] + expected_result = [[1, 4], [2, 5], [3, 6]] + assert matrix_transposition(matrix) == expected_result + + +def test_matrix_transposition_empty(): + matrix = [] + assert matrix_transposition(matrix) == [] + + +def test_matrix_transposition_single_element(): + matrix = [[1]] + assert matrix_transposition(matrix) == [[1]] + + +def test_matrix_transposition_square(): + matrix = [[1, 2], [3, 4]] + expected_result = [[1, 3], [2, 4]] + assert matrix_transposition(matrix) == expected_result + + +def test_matrix_transposition_invalid_input_type(): + with pytest.raises(TypeError): + matrix_transposition(1) # Не список + + +def test_matrix_transposition_invalid_input_type_2(): + with pytest.raises(TypeError): + matrix_transposition([[1, 2], 3]) # Не список списков diff --git a/tests/test_vectors.py b/tests/test_vectors.py new file mode 100644 index 00000000..8eba9c45 --- /dev/null +++ b/tests/test_vectors.py @@ -0,0 +1,54 @@ +from project.operation_on_vectors_and_matrix import * + +import pytest + + +def test_scalar_product_valid(): + vector_1 = [1, 2, 3] + vector_2 = [4, 5, 6] + assert the_scalar_product_of_vectors(vector_1, vector_2) == 32 + + +def test_scalar_product_different_lengths(): + vector_1 = [1, 2, 3] + vector_2 = [4, 5] + assert the_scalar_product_of_vectors(vector_1, vector_2) is None + + +def test_vector_length_valid(): + vector = [3, 4] + assert vector_length(vector) == 5.0 + + +def test_vector_length_empty(): + vector = [] + assert vector_length(vector) == 0.0 + + +def test_vector_length_negative(): + vector = [-3, -4] + assert vector_length(vector) == 5.0 + + +def test_vector_length_zero(): + vector = [0, 0, 0] + assert vector_length(vector) == 0.0 + + +def test_angle_between_vectors_valid(): + vector_1 = [1, 2] + vector_2 = [3, 4] + assert the_angle_between_the_vectors(vector_1, vector_2) == 11 + + +def test_angle_between_vectors_orthogonal(): + vector_1 = [1, 0] + vector_2 = [0, 1] + assert the_angle_between_the_vectors(vector_1, vector_2) == 90 + + +def test_angle_between_vectors_different_lengths(): + vector_1 = [1, 2, 3] + vector_2 = [4, 5] + with pytest.raises(TypeError): + the_angle_between_the_vectors(vector_1, vector_2) From 8ebef8b5320f0c052c22855505bfdb6a49f05984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D1=84=D0=B8=D1=8F=20=D0=A5=D1=80=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D0=BD=D0=BA=D0=BE=D0=B2=D0=B0?= Date: Thu, 3 Oct 2024 21:27:03 +0300 Subject: [PATCH 4/7] dz1 --- .github/workflows/code_style.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/code_style.yml b/.github/workflows/code_style.yml index bbdeee6c..6889b8ac 100644 --- a/.github/workflows/code_style.yml +++ b/.github/workflows/code_style.yml @@ -39,6 +39,4 @@ jobs: - name: Run pytest run: | python ./scripts/run_tests.py - - name: Run mypy - run: | - mypy project/ + From 76c3111d027fa41355bc54a8c2d1e67ca442a107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D1=84=D0=B8=D1=8F=20=D0=A5=D1=80=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D0=BD=D0=BA=D0=BE=D0=B2=D0=B0?= Date: Thu, 3 Oct 2024 21:29:30 +0300 Subject: [PATCH 5/7] dz1 --- .github/workflows/code_style.yml | 4 +++- requirements.txt | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/code_style.yml b/.github/workflows/code_style.yml index 6889b8ac..bbdeee6c 100644 --- a/.github/workflows/code_style.yml +++ b/.github/workflows/code_style.yml @@ -39,4 +39,6 @@ jobs: - name: Run pytest run: | python ./scripts/run_tests.py - + - name: Run mypy + run: | + mypy project/ diff --git a/requirements.txt b/requirements.txt index 30544ac2..eb066a16 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ black pre-commit pytest +mypy From 9b24ac30089f60210566cf88890e4144f2ac65c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D1=84=D0=B8=D1=8F=20=D0=A5=D1=80=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D0=BD=D0=BA=D0=BE=D0=B2=D0=B0?= Date: Thu, 3 Oct 2024 22:36:15 +0300 Subject: [PATCH 6/7] fix workflows --- .github/workflows/lint.yml | 41 ++++++++++ .github/workflows/mypy.yml | 41 ++++++++++ .../workflows/{code_style.yml => pytest.yml} | 5 +- ...s_and_matrix.py => operation_on_matrix.py} | 74 ------------------- project/operation_on_vectors.py | 72 ++++++++++++++++++ tests/test_matrix.py | 9 ++- tests/test_vectors.py | 2 +- 7 files changed, 164 insertions(+), 80 deletions(-) create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/mypy.yml rename .github/workflows/{code_style.yml => pytest.yml} (93%) rename project/{operation_on_vectors_and_matrix.py => operation_on_matrix.py} (58%) create mode 100644 project/operation_on_vectors.py diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..3fbf6c03 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,41 @@ +# This is a basic workflow to help you get started with Actions + +name: Check lint + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events + [ push, pull_request ] + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + + # This workflow contains a single job called "style" + style: + + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # A strategy creates a build matrix for your jobs + strategy: + + # You can define a matrix of different job configurations + matrix: + + # Each option you define in the matrix has a key and value + python-version: [ 3.8 ] + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Pre commit + run: | + pre-commit run --all-files --color always --verbose --show-diff-on-failure diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml new file mode 100644 index 00000000..2529d97c --- /dev/null +++ b/.github/workflows/mypy.yml @@ -0,0 +1,41 @@ +# This is a basic workflow to help you get started with Actions + +name: Check mypy + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events + [ push, pull_request ] + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + + # This workflow contains a single job called "style" + style: + + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # A strategy creates a build matrix for your jobs + strategy: + + # You can define a matrix of different job configurations + matrix: + + # Each option you define in the matrix has a key and value + python-version: [ 3.8 ] + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Run mypy + run: | + mypy project/ tests/ diff --git a/.github/workflows/code_style.yml b/.github/workflows/pytest.yml similarity index 93% rename from .github/workflows/code_style.yml rename to .github/workflows/pytest.yml index bbdeee6c..3c3f3c47 100644 --- a/.github/workflows/code_style.yml +++ b/.github/workflows/pytest.yml @@ -1,6 +1,6 @@ # This is a basic workflow to help you get started with Actions -name: Check code style +name: Check pytest # Controls when the workflow will run on: @@ -39,6 +39,3 @@ jobs: - name: Run pytest run: | python ./scripts/run_tests.py - - name: Run mypy - run: | - mypy project/ diff --git a/project/operation_on_vectors_and_matrix.py b/project/operation_on_matrix.py similarity index 58% rename from project/operation_on_vectors_and_matrix.py rename to project/operation_on_matrix.py index 9e858c0c..8a24eb53 100644 --- a/project/operation_on_vectors_and_matrix.py +++ b/project/operation_on_matrix.py @@ -1,74 +1,3 @@ -# Operation on vectors - -from math import pi, acos - - -def the_scalar_product_of_vectors(vector_1: list[int], vector_2: list[int]): - """ - Function the_scalar_product_of_vectors checks whether the vectors have the same length. If not, it returns None. - Otherwise, the function calculates the scalar pro1duct by multiplying the corresponding elements of the vectors - and summing the results. - - Parameters: - ----------- - vector_1 (list): The first vector, represented as a list of numbers. - vector_2 (list): The second vector, represented as a list of numbers. - - Return value: - ------------- - int: The scalar product of vectors vector_1 and vector_2, if they have the same length. - None: If the vectors have different lengths. - - """ - if len(vector_1) != len(vector_2): - return None - else: - p = 0 - for i in range(len(vector_1)): - p += vector_1[i] * vector_2[i] - return p - - -def vector_length(vector: list[int]): - """ - The vector_length function calculates the length of a vector represented as a list of numbers. - - Parameters: - ----------- - vector (list): A vector represented as a list of numbers. - - Return value: - ------------- - int: The length of the vector, rounded to an integer - - """ - s = 0 - for i in vector: - s += i**2 - return round(pow(s, 0.5), 2) - - -def the_angle_between_the_vectors(vector_1: list[int], vector_2: list[int]): - """ - The_angle_between_the_vectors function calculates the angle between two vectors - given as lists of numbers using the scalar product and the lengths of the vectors. - - Parameters: - ----------- - vector_1 (list): The first vector, represented as a list of numbers. - vector_2 (list): The second vector, represented as a list of numbers. - - Return value: - ------------- - float: The angle between the vectors in radians, with an accuracy of two decimal places. - - """ - s = the_scalar_product_of_vectors(vector_1, vector_2) - angle = s / (vector_length(vector_1) * vector_length(vector_2)) - angle = acos(angle)*180/pi - return round(angle) - - # Operations on matrices @@ -158,6 +87,3 @@ def matrix_transposition(matrix: list[list]): for j in range(len(matrix[0])): matrix_trans[j][i] = matrix[i][j] return matrix_trans - - - diff --git a/project/operation_on_vectors.py b/project/operation_on_vectors.py new file mode 100644 index 00000000..3983d0b6 --- /dev/null +++ b/project/operation_on_vectors.py @@ -0,0 +1,72 @@ +# Operation on vectors + +from math import pi, acos + + +def the_scalar_product_of_vectors(vector_1: list[int], vector_2: list[int]): + """ + Function the_scalar_product_of_vectors checks whether the vectors have the same length. If not, it returns None. + Otherwise, the function calculates the scalar pro1duct by multiplying the corresponding elements of the vectors + and summing the results. + + Parameters: + ----------- + vector_1 (list): The first vector, represented as a list of numbers. + vector_2 (list): The second vector, represented as a list of numbers. + + Return value: + ------------- + int: The scalar product of vectors vector_1 and vector_2, if they have the same length. + None: If the vectors have different lengths. + + """ + if len(vector_1) != len(vector_2): + return None + else: + p = 0 + for i in range(len(vector_1)): + p += vector_1[i] * vector_2[i] + return p + + +def vector_length(vector: list[int]): + """ + The vector_length function calculates the length of a vector represented as a list of numbers. + + Parameters: + ----------- + vector (list): A vector represented as a list of numbers. + + Return value: + ------------- + int: The length of the vector, rounded to an integer + + """ + s = 0 + for i in vector: + s += i**2 + return round(pow(s, 0.5), 2) + + +def the_angle_between_the_vectors(vector_1: list[int], vector_2: list[int]): + """ + The_angle_between_the_vectors function calculates the angle between two vectors + given as lists of numbers using the scalar product and the lengths of the vectors. + + Parameters: + ----------- + vector_1 (list): The first vector, represented as a list of numbers. + vector_2 (list): The second vector, represented as a list of numbers. + + Return value: + ------------- + float: The angle between the vectors in radians, with an accuracy of two decimal places. + + """ + s = the_scalar_product_of_vectors(vector_1, vector_2) + angle = s / (vector_length(vector_1) * vector_length(vector_2)) + angle = acos(angle)*180/pi + return round(angle) + + + diff --git a/tests/test_matrix.py b/tests/test_matrix.py index 6c840004..68a9fe9f 100644 --- a/tests/test_matrix.py +++ b/tests/test_matrix.py @@ -1,4 +1,4 @@ -from project.operation_on_vectors_and_matrix import * +from project.operation_on_matrix import * import pytest @@ -43,6 +43,13 @@ def test_matrix_multiplication_valid(): assert matrix_multiplication(matrix_1, matrix_2) == expected_result +def test_matrix_multiplication(): + matrix_1 = [[1, 2, 4], [3, 4, 9]] + matrix_2 = [[5, 6], [7, 8], [9, 0]] + expected_result = [[55, 22], [124, 50]] + assert matrix_multiplication(matrix_1, matrix_2) == expected_result + + def test_matrix_multiplication_different_dimensions(): matrix_1 = [[1, 2], [3, 4]] matrix_2 = [[5, 6, 7, 0], [8, 9, 10, 11], [1, 2, 3, 4]] diff --git a/tests/test_vectors.py b/tests/test_vectors.py index 8eba9c45..405ab7e4 100644 --- a/tests/test_vectors.py +++ b/tests/test_vectors.py @@ -1,4 +1,4 @@ -from project.operation_on_vectors_and_matrix import * +from project.operation_on_vectors import * import pytest From 8860f56c27a9f22ece5c908493980c0f245ffe1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D1=84=D0=B8=D1=8F=20=D0=A5=D1=80=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D0=BD=D0=BA=D0=BE=D0=B2=D0=B0?= Date: Thu, 3 Oct 2024 22:42:07 +0300 Subject: [PATCH 7/7] fix pre-commit errors --- project/operation_on_matrix.py | 6 +++--- project/operation_on_vectors.py | 5 +---- requirements.txt | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/project/operation_on_matrix.py b/project/operation_on_matrix.py index 8a24eb53..a4d757ec 100644 --- a/project/operation_on_matrix.py +++ b/project/operation_on_matrix.py @@ -20,7 +20,7 @@ def matrix_addition(matrix_1: list[list], matrix_2: list[list]): if len(matrix_1) != len(matrix_2) or len(matrix_1[0]) != len(matrix_2[0]): return None else: - matrix_sum = [[0]*len(matrix_1[0]) for _ in range(len(matrix_1))] + matrix_sum = [[0] * len(matrix_1[0]) for _ in range(len(matrix_1))] for i in range(len(matrix_1)): for j in range(len(matrix_1[0])): matrix_sum[i][j] = matrix_1[i][j] + matrix_2[i][j] @@ -49,7 +49,7 @@ def matrix_multiplication(matrix_1: list[list], matrix_2: list[list]): if len(matrix_1[0]) != len(matrix_2): return None else: - matrix_mult = [[0]*len(matrix_2[0]) for _ in range(len(matrix_1))] + matrix_mult = [[0] * len(matrix_2[0]) for _ in range(len(matrix_1))] for i in range(len(matrix_1)): for j in range(len(matrix_2[0])): for r in range(len(matrix_2)): @@ -82,7 +82,7 @@ def matrix_transposition(matrix: list[list]): if not matrix: return [] else: - matrix_trans = [[0]*len(matrix) for _ in range(len(matrix[0]))] + matrix_trans = [[0] * len(matrix) for _ in range(len(matrix[0]))] for i in range(len(matrix)): for j in range(len(matrix[0])): matrix_trans[j][i] = matrix[i][j] diff --git a/project/operation_on_vectors.py b/project/operation_on_vectors.py index 3983d0b6..df0d3083 100644 --- a/project/operation_on_vectors.py +++ b/project/operation_on_vectors.py @@ -65,8 +65,5 @@ def the_angle_between_the_vectors(vector_1: list[int], vector_2: list[int]): """ s = the_scalar_product_of_vectors(vector_1, vector_2) angle = s / (vector_length(vector_1) * vector_length(vector_2)) - angle = acos(angle)*180/pi + angle = acos(angle) * 180 / pi return round(angle) - - - diff --git a/requirements.txt b/requirements.txt index eb066a16..61500b18 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ black +mypy pre-commit pytest -mypy