Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pytest
ruff
10 changes: 5 additions & 5 deletions src/Homework #2/Extended Euclidean algorithm/alghoritm.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
x_previous, x = 1, 0
y_previous, y = 0, 1

while b != 0:
q = a // b
r = a % b

x_previous, x = x, x_previous - q * x
y_previous, y = y, y_previous - q * y

a, b = b, r

return a, x_previous, y_previous


d, x, y = extended_gcd(54, 30)

print(f"GCD(54, 30) = {d}")
print(f"Coefficients: x = {x}, y = {y}")
print(f"Factorization: 54*({x}) + 30*({y}) = {54*x + 30*y}")
print(f"Factorization: 54*({x}) + 30*({y}) = {54 * x + 30 * y}")
7 changes: 7 additions & 0 deletions src/Tests/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[pytest]
pythonpath = . .. src
testpaths = tests
addopts = -v --tb=short
python_files = test_*.py
python_classes = Test*
python_functions = test_*
7 changes: 7 additions & 0 deletions src/Tests/src/bubble_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
def bubble_sort(array: list) -> list:
for index_1 in range(len(array)):
for index_2 in range(index_1 + 1, len(array)):
if array[index_1] > array[index_2]:
array[index_1], array[index_2] = array[index_2], array[index_1]

return array
27 changes: 27 additions & 0 deletions src/Tests/src/heap_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
def heap_sort(array: list) -> list:
length = len(array)

for index in range(length // 2 - 1, -1, -1):
heapify(array, length, index)

for index in range(length - 1, 0, -1):
array[0], array[index] = array[index], array[0]
heapify(array, index, 0)

return array


def heapify(array: list, length: int, index: int) -> None:
largest = index
left = 2 * index + 1
right = 2 * index + 2

if left < length and array[left] > array[largest]:
largest = left

if right < length and array[right] > array[largest]:
largest = right

if largest != index:
array[index], array[largest] = array[largest], array[index]
heapify(array, length, largest)
10 changes: 10 additions & 0 deletions src/Tests/src/quick_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
def quick_sort(array: list) -> list:
if len(array) <= 1:
return array

pivot = array[len(array) // 2]
left = [x for x in array if x < pivot]
middle = [x for x in array if x == pivot]
right = [x for x in array if x > pivot]

return quick_sort(left) + middle + quick_sort(right)
10 changes: 10 additions & 0 deletions src/Tests/src/selection_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
def selection_sort(array: list) -> list:
for index_1 in range(len(array)):
min_idx = index_1
for index_2 in range(index_1 + 1, len(array)):
if array[index_2] < array[min_idx]:
min_idx = index_2

array[index_1], array[min_idx] = array[min_idx], array[index_1]

return array
Empty file added src/Tests/tests/__init__.py
Empty file.
31 changes: 31 additions & 0 deletions src/Tests/tests/test_heapsort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from src.heap_sort import heap_sort


def test_sort_empty_list() -> None:
assert heap_sort([]) == []


def test_sort_single_element() -> None:
assert heap_sort([5]) == [5]
assert heap_sort([-1]) == [-1]
assert heap_sort([0]) == [0]


def test_sort_positive_numbers() -> None:
assert heap_sort([3, 1, 4, 1, 5]) == [1, 1, 3, 4, 5]
assert heap_sort([5, 4, 3, 2, 1]) == [1, 2, 3, 4, 5]


def test_sort_negative_numbers() -> None:
assert heap_sort([-3, -1, -4, -1, -5]) == [-5, -4, -3, -1, -1]
assert heap_sort([-1, -2, -3, -4, -5]) == [-5, -4, -3, -2, -1]


def test_sort_mixed_numbers() -> None:
assert heap_sort([3, -1, 0, -2, 5]) == [-2, -1, 0, 3, 5]
assert heap_sort([0, -1, 1, -2, 2]) == [-2, -1, 0, 1, 2]


def test_sort_strings() -> None:
assert heap_sort(["banana", "apple", "cherry"]) == ["apple", "banana", "cherry"]
assert heap_sort(["z", "a", "m"]) == ["a", "m", "z"]
73 changes: 73 additions & 0 deletions src/Tests/tests/test_property_based.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import pytest
import random
from collections import Counter

from src.heap_sort import heap_sort
from src.quick_sort import quick_sort
from src.bubble_sort import bubble_sort
from src.selection_sort import selection_sort

SORTING_FUNCTIONS = [heap_sort, quick_sort, bubble_sort, selection_sort]


@pytest.fixture
def unsorted_lists() -> list[list]:
sizes = [5, 10, 15, 20, 30, 50]
lists = []
for size in sizes:
array = []
for _ in range(size):
array.append(random.randint(-100, 100))
lists.append(array)

return lists


@pytest.mark.parametrize("sorting_function", SORTING_FUNCTIONS)
def test_orderliness(sorting_function, unsorted_lists) -> None:
for unsorted_list in unsorted_lists:
sorted_array = sorting_function(unsorted_list)
for index in range(1, len(sorted_array)):
assert sorted_array[index] >= sorted_array[index - 1]


@pytest.mark.parametrize("sorting_function", SORTING_FUNCTIONS)
def test_elements_sameness(sorting_function, unsorted_lists) -> None:
for unsorted_list in unsorted_lists:
sorted_list = sorting_function(unsorted_list)
assert Counter(sorted_list) == Counter(unsorted_list)


@pytest.mark.parametrize("sorting_function", SORTING_FUNCTIONS)
def test_idempotency(sorting_function, unsorted_lists):
for unsorted_list in unsorted_lists:
first_sort = sorting_function(unsorted_list.copy())
second_sort = sorting_function(first_sort.copy())

assert first_sort == second_sort


@pytest.fixture(
params=[
[],
[1],
[1, 1, 1],
[1, 2, 3, 4, 5],
[5, 4, 3, 2, 1],
[1, 3, 2, 3, 1],
[-1, -5, 2, -3, 0],
[100, -100, 0, 50, -50],
[1] * 100,
list(range(100, 0, -1)),
]
)
def edge_case_list(request):
return request.param


@pytest.mark.parametrize("sorting_function", SORTING_FUNCTIONS)
def test_edge_cases(sorting_function, edge_case_list):
original = edge_case_list.copy()
sorted_list = sorting_function(edge_case_list)

assert sorted_list == sorted(original)