Changed the Structure to be a Python Library and also tests using pyTest

This commit is contained in:
Gustavo Henrique Santos Souza de Miranda 2025-05-20 02:35:32 -03:00
parent 50af9a1941
commit d57c2811bc
5 changed files with 147 additions and 107 deletions

2
goulag_sort/__init__.py Normal file
View File

@ -0,0 +1,2 @@
from .goulagsort import send_to_goulag
__all__ = ['send_to_goulag']

81
goulag_sort/goulagsort.py Normal file
View File

@ -0,0 +1,81 @@
def send_to_goulag(input_list:list)-> list :
"""Sorts a list of numbers using the unique "Goulag Sort" method.
This algorithm processes a list of numbers through a distinctive iterative and
recursive procedure, inspired by the "Stalin Sort" concept. Here's how it operates:
1. **Iterative Filtering:** It iterates through the main list. If an element
is found to be greater than its subsequent element, the subsequent element
is moved to a temporary holding list (`temp`). The main list then continues
with the remaining elements.
2. **Recursive Processing of Held Items:** If the `temp` list contains more than
one item, the `send_to_goulag` algorithm recursively processes `temp`. This
filtering and holding process continues until the sub-list contains a single
item or becomes empty.
3. **Partial Re-insertion:** After the recursive calls (or if `temp` was empty/single-item),
the algorithm attempts to re-insert the elements from `temp` back into the main list.
This re-insertion is performed by finding a suitable position where the held item
is less than the current element in the main list, maintaining a partial order.
4. **Final Appending:** Any remaining elements in `temp` that were not re-inserted
into the middle of the list are then appended to the end of the main list.
For a more detailed step-by-step explanation of the algorithm's flow, please refer to:
:ref:`goulag_sort_detailed_explanation`.
Args:
input_list (list): The list of numbers to be processed and sorted.
This list will be modified **in-place**.
Returns:
list: The list after being processed by the Goulag Sort algorithm. The result
is an ordered list.
Examples:
>>> from goulag_sort import send_to_goulag
>>> my_list = [5, 2, 8, 1, 9, 4]
>>> send_to_goulag(my_list)
[1, 2, 4, 5, 8, 9]
>>> empty_list = []
>>> send_to_goulag(empty_list)
[]
"""
idx = 0
temp = []
while True:
if not input_list:
return []
while idx < len(input_list) - 1:
if input_list[idx] > input_list[idx + 1]:
temp.append(input_list[idx + 1])
# pop(idx+1) é uma operação O(N) no pior caso
input_list.pop(idx + 1)
else:
idx += 1
# Chamada recursiva (pode adicionar complexidade se for muito frequente)
if len(temp) > 1:
temp = send_to_goulag(temp)
idx = 0
# Loop para reinserir elementos de 'temp' na lista principal
while idx < len(input_list):
if temp and input_list[idx] > temp[0]:
# Inserção no meio da lista input_list[idx:idx] = temp é O(N) no pior caso
input_list[idx:idx] = temp
temp.clear()
break
idx += 1
if len(temp) == 0:
return input_list
if temp:
input_list.extend(temp) # extend é O(k) onde k é o tamanho de temp
temp.clear()

107
main.py
View File

@ -1,107 +0,0 @@
import threading
import numpy as np
import matplotlib.pyplot as plt
import time
import copy
import random
# O algoritmo de ordenação do usuário
def send_to_goulag(input_list):
idx = 0
temp = []
while True:
# Loop interno para "filtrar" elementos maiores que o próximo
while idx < len(input_list) - 1:
if input_list[idx] > input_list[idx + 1]:
temp.append(input_list[idx + 1])
# pop(idx+1) é uma operação O(N) no pior caso
input_list.pop(idx + 1)
else:
idx += 1
# Chamada recursiva (pode adicionar complexidade se for muito frequente)
if len(temp) > 1:
temp = send_to_goulag(temp)
idx = 0
# Loop para reinserir elementos de 'temp' na lista principal
while idx < len(input_list):
if temp and input_list[idx] > temp[0]:
# Inserção no meio da lista input_list[idx:idx] = temp é O(N) no pior caso
input_list[idx:idx] = temp
temp.clear()
break
idx += 1
if len(temp) == 0:
return input_list
if temp:
input_list.extend(temp) # extend é O(k) onde k é o tamanho de temp
temp.clear()
def create_unique_random_list(size):
return random.sample(range(5120000 * 2), size)
if __name__ == "__main__":
list1 = create_unique_random_list(1000)
list3 = create_unique_random_list(4000)
list2 = create_unique_random_list(2000)
list4 = create_unique_random_list(8000)
list5 = create_unique_random_list(16000)
list6 = create_unique_random_list(32000)
list7 = create_unique_random_list(64000)
# list8 = create_unique_random_list(12800)
# list9 = create_unique_random_list(25600)
# list10 = create_unique_random_list(51200)
list1_copy = copy.deepcopy(list1)
list2_copy = copy.deepcopy(list2)
list3_copy = copy.deepcopy(list3)
list4_copy = copy.deepcopy(list4)
list5_copy = copy.deepcopy(list5)
list6_copy = copy.deepcopy(list6)
list7_copy = copy.deepcopy(list7)
# list8_copy = copy.deepcopy(list8)
# list9_copy = copy.deepcopy(list9)
# list10_copy = copy.deepcopy(list10)
list1_copy.sort()
list2_copy.sort()
list3_copy.sort()
list4_copy.sort()
list5_copy.sort()
list6_copy.sort()
list7_copy.sort()
# list8_copy.sort()
# list9_copy.sort()
# list10_copy.sort()
lists_to_sort = [list1, list2, list3, list4, list5, list6, list7]
threads = []
# Inicia uma thread para cada chamada do send_to_goulag
for i, current_list in enumerate(lists_to_sort):
# A thread chamará send_to_goulag que modificará current_list in-place
thread = threading.Thread(target=send_to_goulag, args=(current_list,))
threads.append(thread)
thread.start()
# Espera que todas as threads terminem antes de verificar os resultados
for thread in threads:
thread.join()
print(list1 == list1_copy)
print(list2 == list2_copy)
print(list3 == list3_copy)
print(list4 == list4_copy)
print(list5 == list5_copy)
print(list6 == list6_copy)
print(list7 == list7_copy)
# print(list8 == list8_copy)
# print(list9 == list9_copy)
# print(list10 == list10_copy)

22
setup.py Normal file
View File

@ -0,0 +1,22 @@
import os
from setuptools import setup, find_packages
setup(
name='goulag_sort', # Nome do seu pacote
version='0.1.0', # Versão inicial do seu pacote
packages=find_packages(), # Agora encontra o pacote 'goulag_sort' na raiz
# Removidos package_dir e where='src'
description='An intentionally inefficient sorting algorithm library.',
long_description=open('README.md').read() if os.path.exists('README.md') else '',
long_description_content_type='text/markdown',
author='Gustavo Henrique Santos Souza de Miranda',
author_email='gustavohssmiranda@gmail.com',
url='https://git.gustavomiranda.xyz/GHMiranda/GoulagSort',
classifiers=[
'Programming Language :: Python :: 3',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
],
python_requires='>=3.10',
)

42
tests/test_goulagsort.py Normal file
View File

@ -0,0 +1,42 @@
import copy
import random
import pytest
from goulag_sort import send_to_goulag
def test_empty_list():
assert send_to_goulag([]) == []
def test_single_element():
assert send_to_goulag([5]) == [5]
def test_already_sorted():
assert send_to_goulag([10,20,45,50,60,100,150]) == [10,20,45,50,60,100,150]
def test_reverse_sorted():
inputlist = [50,40,30,25,14,10,5]
expectedlist = [5,10,14,25,30,40,50]
inputlist = send_to_goulag(inputlist)
assert inputlist == expectedlist
def test_simple_sort():
inputlist = [ 622, 1010, 184, 1012, 780, 151, 708, 1020, 1013, 839, 84, 191, 831, 824, 1015, 126,
928, 963, 847, 61, 1022, 765, 566, 269, 584, 172, 121, 741, 264, 470, 332, 564, 463,
29, 315, 28, 859, 6, 1000, 486, 624, 617, 390, 176, 76, 256, 369, 764, 202, 805, 355,
715, 507, 514, 378, 772, 525, 746, 623, 37, 863, 1005, 730, 731, 321, 357, 65, 648,
310, 140, 375, 479, 926, 86, 335, 777, 684, 734, 539, 51, 265, 179, 745, 642, 806, 294,
182, 293, 768, 367, 594, 109, 481, 117, 709, 952, 403, 211, 682, 145]
expectedlist = copy.deepcopy(inputlist)
expectedlist = sorted(expectedlist)
assert send_to_goulag(inputlist) == expectedlist
def test_duplicated_sort():
inputlist = [10,20,30,30,50,65,100]
expectedList = sorted(copy.deepcopy(inputlist))
assert send_to_goulag(inputlist) == expectedList
def test_really_long_sort():
inputList = [random.randint(1,500000) for _ in range(10000)]
expectedList = sorted(copy.deepcopy(inputList))
assert send_to_goulag(inputList) == expectedList