def test_recursive_counting(self): from algs.counting import RecordedItem from ch05.challenge import recursive_two # Must be power of two N = 128 values = tuple(reversed([RecordedItem(k) for k in range(N)])) RecordedItem.clear() actual = recursive_two(values) self.assertEqual(actual[0].val, N - 1) self.assertEqual(actual[1].val, N - 2) self.assertEqual(N + N // 2 - 2, RecordedItem.report()[1])
def run_median_less_than_trial(max_k=20, output=True): """Use RecordedItem to count # of times Less-than invoked up to (but not including) max_k=20.""" tbl = DataTable([10, 15, 15], ['N', 'median_count', 'sort_median_count'], output=output) tbl.format('median_count', ',d') tbl.format('sort_median_count', ',d') trials = [2**k + 1 for k in range(8, max_k)] for n in trials: A = list([RecordedItem(i) for i in range(n)]) random.shuffle(A) # Generated external sorted to reuse list RecordedItem.clear() med2 = sorted(A)[n // 2] sort_lt = RecordedItem.report()[1] RecordedItem.clear() med1 = linear_median(A) lin_lt = RecordedItem.report()[1] assert med1 == med2 tbl.row([n, lin_lt, sort_lt]) return tbl
def test_helper(self): self.assertEqual([RecordedItem(0), RecordedItem(1)], RecordedItem.range(2))
def test_recorded_item(self): self.assertEqual(('eq', 'lt', 'gt'), RecordedItem.header())
def test_counting(self): """Test basic mechanics of RecordedItem.""" ri1 = RecordedItem(1) ri2 = RecordedItem(2) RecordedItem.clear() self.assertTrue(ri1 < ri2) self.assertEqual(0, RecordedItem.report()[0]) self.assertEqual(1, RecordedItem.report()[1]) self.assertEqual(0, RecordedItem.report()[2]) RecordedItem.clear() self.assertFalse(ri1 > ri2) self.assertEqual(0, RecordedItem.report()[0]) self.assertEqual(0, RecordedItem.report()[1]) self.assertEqual(1, RecordedItem.report()[2]) RecordedItem.clear() self.assertFalse(ri1 == ri2) self.assertEqual(1, RecordedItem.report()[0]) self.assertEqual(0, RecordedItem.report()[1]) self.assertEqual(0, RecordedItem.report()[2])
def performance_different_approaches(output=True): """Produce results on # less-than for different algorithms and data sets.""" headers = ['Algorithm', 'Ascending', 'Descending', 'Alternating'] n = 524288 tbl = DataTable([15, 10, 10, 10], headers, output=output) for hdr in headers: tbl.format(hdr, ',d') tbl.format('Algorithm', 's') # Ascending / Descending / Weave from ch01.largest_two import largest_two, sorting_two, double_two, mutable_two, tournament_two funcs = [largest_two, sorting_two, double_two, mutable_two, tournament_two] algs = [ 'largest_two', 'sorting_two', 'double_two', 'mutable_two', 'tournament_two' ] for label, func in zip(algs, funcs): RecordedItem.clear() func([RecordedItem(i) for i in range(n)]) up_count = sum(RecordedItem.report()) RecordedItem.clear() func([RecordedItem(i) for i in range(n, 0, -1)]) down_count = sum(RecordedItem.report()) RecordedItem.clear() up_down = zip(range(0, n, 2), range(n - 1, 0, -2)) func([RecordedItem(i) for i in itertools.chain(*up_down)]) weave_count = sum(RecordedItem.report()) tbl.row([label, up_count, down_count, weave_count]) return tbl
def run_largest_alternate(output=True, decimals=3): """Generate tables for largest and alternate.""" n = 8 tbl = DataTable([8, 10, 15, 10, 10], ['N', '#Less', '#LessA', 'largest', 'alternate'], output=output, decimals=decimals) tbl.format('#Less', ',d') tbl.format('#LessA', ',d') while n <= 2048: ascending = list(range(n)) largest_up = 1000 * min( timeit.repeat(stmt='largest({})'.format(ascending), setup='from ch01.largest import largest', repeat=10, number=50)) / 50 alternate_up = 1000 * min( timeit.repeat(stmt='alternate({})'.format(ascending), setup='from ch01.largest import alternate', repeat=10, number=50)) / 50 up_count = [RecordedItem(i) for i in range(n)] RecordedItem.clear() largest(up_count) largest_counts = RecordedItem.report() RecordedItem.clear() up_count = [RecordedItem(i) for i in range(n)] RecordedItem.clear() alternate(up_count) alternate_counts = RecordedItem.report() RecordedItem.clear() tbl.row([ n, sum(largest_counts), sum(alternate_counts), largest_up, alternate_up ]) n *= 2 if output: print() print('largest', tbl.best_model('largest', Model.LINEAR)) print('Alternate', tbl.best_model('alternate', Model.QUADRATIC)) return tbl