首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >merge_sort和单元测试

merge_sort和单元测试
EN

Code Review用户
提问于 2018-04-27 23:50:11
回答 1查看 667关注 0票数 2

我做了一个合并排序,并想要求检查代码。它通过了所有单元测试。经典Mergesort算法的思想是将数组分成两部分,每一半进行排序,然后将这两部分合并成一个排序列表。

示例:

代码语言:javascript
复制
merge_sort([2,7,5,9,8,9]) -> [2,5,7,8,9,9]

merge_sort()([7,1,8,2]) -> [1,2,7,8]

merge_sort()([2]) -> [2]

[] -> [Empty] list 

合并排序

代码语言:javascript
复制
def merge(xs, ys):
    xs, ys = iter(xs), iter(ys)
    x,  y  = next(xs,None), next(ys,None)
    while x and y:
        yield min(x,y)
        if x <= y: x = next(xs, None)
        else:      y = next(ys, None)

    # Yield remaining items from whichever list isn't empty
    yield [x,y][x is None]
    for item in [xs,ys][x is None]: yield item

def merge_sort(xs):
    # from heapq import merge
    if len(xs) < 2:
        return xs

    mid = len(xs)/2
    return list(merge(merge_sort(xs[:mid]), merge_sort(xs[mid:])))



# unit testing

#!python

from merge_sort import quicksort

from sorting import merge_sort
import unittest

# Change this variable to the sort function you want to test
is_sort = quick_sort2


class IsSortedTest(unittest.TestCase):
    def test_merge_sort_on_sorted_integers(self):
        # Positive test cases (examples) with lists of sorted integers
        assert merge_sort([])  # Empty lists are vacuously sorted
        assert merge_sort([3])  # Single item is trivially sorted
        assert merge_sort([3, 3])  # Duplicate items are in order
        assert merge_sort([3, 5])
        assert merge_sort([3, 5, 7])
        # : Write more positive test cases with assert  statements
        assert merge_sort([-4, -3, -2, -1])
        assert merge_sort([-4, -4, -4, -4])
        assert merge_sort([-4, 0, 4])
        assert merge_sort([-4, 0, -0, 4])

    def test_merge_sort_on_unsorted_integers(self):
        # Negative test cases (counterexamples) with lists of unsorted integers
        assert not merge_sort([5, 3])  # is False
        assert not merge_sort([3, 5, 3])  # is False
        assert not merge_sort([7, 5, 3])  # is False
        # : Write more negative test cases with assert # is False statements
        assert not merge_sort([-11, 3, 2])  # is False
        assert not merge_sort([2, -1, 1, 1])  # is False
        assert not merge_sort([4, -3, 2, -1])  # is False

    def test_merge_sort_on_sorted_strings(self):
        # Positive test cases (examples) with lists of sorted strings
        assert merge_sort(['A'])  # Single item is trivially sorted
        assert merge_sort(['A', 'A'])  # Duplicate items are in order
        assert merge_sort(['A', 'B'])
        assert merge_sort(['A', 'B', 'C'])
        # : Write more positive test cases with assert  statements
        # You'll need a lot more than this to test sorting algorithm robustness
        # lowercase
        assert merge_sort(['a', 'b', 'c'])
        assert merge_sort(['a', 'a', 'c'])
        # Mixed
        assert merge_sort(['A', 'a', 'b'])
        assert merge_sort(['C', 'a', 'b'])
        # Testing Multiple
        assert merge_sort(['AA', 'BB', 'CC'])
        assert merge_sort(['AA', 'BA', 'CA'])
        assert merge_sort(['AAAA', 'BB', 'CCC'])
        assert merge_sort(['AA', 'AAA', 'AAAA'])

    def test_merge_sort_on_unsorted_strings(self):
        # Negative test cases (counterexamples) with lists of unsorted strings
        assert not merge_sort(['B', 'A'])  # is False
        assert not merge_sort(['A', 'B', 'A'])  # is False
        assert not merge_sort(['C', 'B', 'A'])  # is False
        # : Write more negative test cases with assert # is False statements
        # You'll need a lot more than this to test sorting algorithm robustness
        # Multiple
        assert not merge_sort(['CCC', 'BBB', 'AAA'])  # is False
        assert not merge_sort(['CCCC', 'CCC', 'C'])  # is False
        # Lowercase
        assert not merge_sort(['c', 'b', 'a'])  # is False
        assert not merge_sort(['c', 'c', 'a'])  # is False

    def test_merge_sort_on_sorted_tuples(self):
        # Positive test cases (examples) with lists of sorted tuples
        assert merge_sort([(3, 5)])  # Single item
        assert merge_sort([(3, 'A')])  # Single item
        assert merge_sort([('A', 3)])  # Single item
        assert merge_sort([('A', 'B')])  # Single item
        assert merge_sort([(3, 5), (3, 5)])  # Duplicate items
        assert merge_sort([(3, 'A'), (3, 'A')])  # Duplicate items
        assert merge_sort([('A', 3), ('A', 3)])  # Duplicate items
        assert merge_sort([('A', 'B'), ('A', 'B')])  # Duplicate items
        assert merge_sort([('A', 3), ('B', 5)])  # Both items sorted
        assert merge_sort([('A', 3), ('B', 3)])  # First item sorted
        assert merge_sort([('A', 3), ('A', 5)])  # Second item sorted
        assert merge_sort([(3, 'A'), (5, 'B')])  # Both items sorted
        assert merge_sort([(3, 'A'), (5, 'A')])  # First item sorted
        assert merge_sort([(3, 'A'), (3, 'B')])  # Second item sorted
        # : Write more positive test cases with assert  statements
        # ...

    def test_merge_sort_on_unsorted_tuples(self):
        # Negative test cases (counterexamples) with lists of unsorted tuples
        assert not merge_sort([(5, 'B'), (3, 'A')])  # is False  # Both items unsorted
        assert not merge_sort([(5, 'A'), (3, 'B')])  # is False  # First item unsorted
        assert not merge_sort([(3, 'B'), (3, 'A')])  # is False  # Second item unsorted
        assert not merge_sort([('B', 5), ('A', 3)])  # is False  # Both items unsorted
        assert not merge_sort([('B', 3), ('A', 5)])  # is False  # First item unsorted
        assert not merge_sort([('A', 5), ('A', 3)])  # is False  # Second item unsorted
        # : Write more negative test cases with assert # is False statements
        # ...



if __name__ == '__main__':
    unittest.main()
EN

回答 1

Code Review用户

回答已采纳

发布于 2018-04-28 07:56:16

代码语言:javascript
复制
while x and y:
    yield min(x,y)
    if x <= y: x = next(xs, None)
    else:      y = next(ys, None)

这是正确的。但是,请注意,它依赖于min的稳定性保证,以确保如果两个对象相等,则生成的对象与被更新的对象相同。这是一个相当微妙的假设。

为了清楚起见,我个人更愿意将yield放在if块中。它还将避免对比较进行两次测试,这对于对某些数据类型进行排序可能是一种比较昂贵的操作。

代码语言:javascript
复制
while x and y:
    if x <= y:
         yield x
         x = next(xs, None)
    else:
         yield y
         y = next(ys, None)

两者都有

代码语言:javascript
复制
from merge_sort import quicksort

代码语言:javascript
复制
is_sort = quick_sort2

看上去很困惑。快艇在这里做什么?我怀疑这是需要清理的剩余代码。

您的测试用例显示了通用和特殊用例在一系列数据类型之间的良好扩展。我建议对对象类型进行一些测试,特别是根据它们的比较函数相等的对象,但如果不是这样,则可以区分这些对象。例如

代码语言:javascript
复制
class TestObject(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __lt__(self, other):
        return self.x < other.x
    def __str__(self):
        return "LTO (%d, %d)" % (self.x, self.y)

如前所述,这些帮助检查排序的稳定性(相等的对象相对于未排序的列表保持相同的顺序)和正确性(特别是排序列表确实包含与输入相同的元素)。

我不熟悉这种编写Python测试的方法。这意味着我不能说的更多,这看起来很奇怪。我希望测试用例能够指定所需的函数输出。也许就像

代码语言:javascript
复制
assertEqual(merge_sort([3, 7, 5]), [3, 5, 7])
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/193122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档