-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
re organize project structure and include functionality to allow for …
…tests, cleaner project structure and __main__.py included for console usage. new quick sort algorithm added. unit tests for sorting algorithms and parser tests. extra setup.py functionality added and name renamed to 'sorter' small readme changes.
- Loading branch information
Brett
committed
Apr 14, 2018
1 parent
99c66ba
commit f350548
Showing
8 changed files
with
250 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,15 @@ | ||
from setuptools import setup | ||
from setuptools import setup, find_packages | ||
|
||
setup( | ||
name='py-custom-sorters', | ||
version='0.1.1', | ||
url='https://github.com/becurrie/py-custom-sorters', | ||
license='MIT', | ||
author='becurrie', | ||
name='sorter', | ||
author_email='[email protected]', | ||
description='Sort Integers in the console.', | ||
py_modules=['sorter'], | ||
author='becurrie', | ||
version='0.1.2', | ||
description='sort integers with different sorting algorithms.', | ||
packages=find_packages(), | ||
py_modules=['sorter.sorter'], | ||
entry_points={'console_scripts': ['sorter = sorter.sorter:main']}, | ||
license='MIT', | ||
url='https://github.com/becurrie/py-custom-sorters', | ||
keywords=['sorting', 'algorithm', 'console', 'application'], | ||
) |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import sys | ||
|
||
from sorter.sorter import main | ||
|
||
if __name__ == "__main__": | ||
# Allow import run through __name__ = __main__ idiom. | ||
main(sys.argv) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import argparse | ||
import os | ||
import sys | ||
import timeit | ||
|
||
from sorter.sorts import * | ||
|
||
|
||
def parse_args(args): | ||
"""Create the parser and add all required arguments before parsing | ||
user input and returning the parser.parse_args() results. | ||
""" | ||
parser = argparse.ArgumentParser(description='sort some integers.') | ||
|
||
group = parser.add_mutually_exclusive_group(required=True) | ||
group.add_argument('-i', '--integers', type=int, nargs='+', | ||
help='integer(s) being sorted.') | ||
group.add_argument('-g', '--generate', type=int, | ||
help='generate a random list of integers to sort.') | ||
parser.add_argument('-s', '--sort', type=str, required=True, | ||
choices=['bubble', 'bogo', 'merge', 'selection', 'quick'], | ||
help='type of sort being performed.') | ||
|
||
return parser.parse_args(args) | ||
|
||
|
||
def print_results(sort_type, original_list, sorted_list, time): | ||
"""Print an original list, sorted list and time required to sort the original list.""" | ||
print('\tSort Type: [%s]' % str.upper(sort_type)) | ||
print('\tOriginal List:') | ||
for original_chunk in print_list_chunks(original_list, 20): | ||
print('\t' + str(original_chunk)[1:-1]) | ||
|
||
print('\n\tSorted List:') | ||
for sorted_chunk in print_list_chunks(sorted_list, 20): | ||
print('\t' + str(sorted_chunk)[1:-1]) | ||
|
||
# Print time required to sort list. | ||
print('\tTime(seconds): %s' % time) | ||
|
||
|
||
def print_list_chunks(integer_list, n): | ||
"""Simple helper method to print out a list in chunks.""" | ||
for i in range(0, len(integer_list), n): | ||
yield integer_list[i:i + n] | ||
|
||
|
||
def generate_integer_list(size): | ||
"""Generate a list of Integers between specified size value.""" | ||
integer_list = list() | ||
for i in range(0, size): | ||
integer_list.append(random.randint(0, 1000)) | ||
|
||
return integer_list | ||
|
||
|
||
def sort(sort_type, integers): | ||
"""Sort a list of integers based on the type of sort specified.""" | ||
if sort_type == 'bubble': | ||
initial = timeit.default_timer() | ||
sorted_list = bubble_sort(integers) | ||
final = timeit.default_timer() | ||
print_results(sort_type, integers, sorted_list, final - initial) | ||
|
||
elif sort_type == 'bogo': | ||
initial = timeit.default_timer() | ||
sorted_list = bogo_sort(integers) | ||
final = timeit.default_timer() | ||
print_results(sort_type, integers, sorted_list, final - initial) | ||
|
||
elif sort_type == 'selection': | ||
initial = timeit.default_timer() | ||
sorted_list = selection_sort(integers) | ||
final = timeit.default_timer() | ||
print_results(sort_type, integers, sorted_list, final - initial) | ||
|
||
elif sort_type == 'merge': | ||
initial = timeit.default_timer() | ||
original = list(integers) | ||
sorted_list = merge_sort(integers) | ||
final = timeit.default_timer() | ||
print_results(sort_type, original, sorted_list, final - initial) | ||
|
||
elif sort_type == 'quick': | ||
initial = timeit.default_timer() | ||
original = list(integers) | ||
quick_sort(integers) | ||
final = timeit.default_timer() | ||
|
||
# Slightly different print call, quick_sort sorts in place. | ||
# A new list isn't made, args.integers becomes sorted. | ||
print_results(sort_type, original, integers, final - initial) | ||
|
||
|
||
def main(args): | ||
"""Main method. build arguments, clear console and parse arguments""" | ||
args = parse_args(args[1:]) | ||
|
||
# Clear system terminal based on operating system name. | ||
if os.name == 'posix': | ||
os.system('clear') | ||
elif os.name == 'nt': | ||
os.system('cls') | ||
|
||
# Check for generate argument specified and create random list. | ||
if args.generate: | ||
args.integers = generate_integer_list(args.generate) | ||
|
||
# Main sort() method call from main. | ||
sort(args.sort, args.integers) | ||
|
||
|
||
if __name__ == "__main__": | ||
# Allow import run through __name__ = __main__ idiom. | ||
main(sys.argv) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import unittest | ||
|
||
from sorter.sorts import * | ||
|
||
from sorter.sorter import parse_args | ||
|
||
|
||
class TestParsing(unittest.TestCase): | ||
|
||
def test_integers(self): | ||
"""Test the optional one of: integers argument.""" | ||
parser = parse_args(['-i', '1', '3', '6', '9', '-s', 'bubble']) | ||
self.assertTrue(parser.integers) | ||
|
||
def test_generate(self): | ||
"""Test the optional one of: generate argument.""" | ||
parser = parse_args(['-g', '100', '-s', 'bubble']) | ||
self.assertTrue(parser.generate) | ||
|
||
def test_sort(self): | ||
"""Test the required sort argument.""" | ||
parser = parse_args(['-g', '10', '-s', 'bubble']) | ||
self.assertTrue(parser.sort) | ||
|
||
|
||
class TestSorts(unittest.TestCase): | ||
|
||
def setUp(self): | ||
"""Simple setup function to create the actual/expected | ||
lists that each sort method should produce if working as | ||
intended. | ||
""" | ||
self.actual = [5, 7, 4, 9, 1, 2] | ||
self.expected = [1, 2, 4, 5, 7, 9] | ||
|
||
def test_bubble(self): | ||
"""Test the bubble_sort function.""" | ||
integers = bubble_sort(self.actual) | ||
self.assertEqual(self.expected, integers) | ||
|
||
def test_selection(self): | ||
"""Test the selection_sort function.""" | ||
integers = bubble_sort(self.actual) | ||
self.assertEqual(self.expected, integers) | ||
|
||
def test_bogo(self): | ||
"""Test the bogo_sort function.""" | ||
integers = bogo_sort(self.actual) | ||
self.assertEqual(self.expected, integers) | ||
|
||
def test_merge(self): | ||
"""Test the merge_sort function.""" | ||
integers = merge_sort(self.actual) | ||
self.assertEqual(self.expected, integers) | ||
|
||
def test_quick(self): | ||
"""Test the quick_sort function. This test is slightly different | ||
because the quick_sort method sorts in place and doesn't return | ||
a new sorted list. | ||
""" | ||
clone = self.actual | ||
quick_sort(clone) | ||
self.assertEqual(self.expected, clone) |