| 
									
										
										
										
											2002-08-02 18:29:53 +00:00
										 |  |  | """Unittests for heapq.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from test.test_support import verify, vereq, verbose, TestFailed | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-08-03 10:10:10 +00:00
										 |  |  | from heapq import heappush, heappop, heapify, heapreplace | 
					
						
							| 
									
										
										
										
											2002-08-02 18:29:53 +00:00
										 |  |  | import random | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def check_invariant(heap): | 
					
						
							|  |  |  |     # Check the heap invariant. | 
					
						
							|  |  |  |     for pos, item in enumerate(heap): | 
					
						
							| 
									
										
										
										
											2002-08-02 19:41:54 +00:00
										 |  |  |         if pos: # pos 0 has no parent | 
					
						
							|  |  |  |             parentpos = (pos-1) >> 1 | 
					
						
							| 
									
										
										
										
											2002-08-02 18:29:53 +00:00
										 |  |  |             verify(heap[parentpos] <= item) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-08-03 02:11:26 +00:00
										 |  |  | # An iterator returning a heap's elements, smallest-first. | 
					
						
							|  |  |  | class heapiter(object): | 
					
						
							|  |  |  |     def __init__(self, heap): | 
					
						
							|  |  |  |         self.heap = heap | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def next(self): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             return heappop(self.heap) | 
					
						
							|  |  |  |         except IndexError: | 
					
						
							|  |  |  |             raise StopIteration | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __iter__(self): | 
					
						
							|  |  |  |         return self | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-08-02 18:29:53 +00:00
										 |  |  | def test_main(): | 
					
						
							|  |  |  |     # 1) Push 100 random numbers and pop them off, verifying all's OK. | 
					
						
							|  |  |  |     heap = [] | 
					
						
							|  |  |  |     data = [] | 
					
						
							|  |  |  |     check_invariant(heap) | 
					
						
							|  |  |  |     for i in range(256): | 
					
						
							|  |  |  |         item = random.random() | 
					
						
							|  |  |  |         data.append(item) | 
					
						
							|  |  |  |         heappush(heap, item) | 
					
						
							|  |  |  |         check_invariant(heap) | 
					
						
							|  |  |  |     results = [] | 
					
						
							|  |  |  |     while heap: | 
					
						
							|  |  |  |         item = heappop(heap) | 
					
						
							|  |  |  |         check_invariant(heap) | 
					
						
							|  |  |  |         results.append(item) | 
					
						
							|  |  |  |     data_sorted = data[:] | 
					
						
							|  |  |  |     data_sorted.sort() | 
					
						
							|  |  |  |     vereq(data_sorted, results) | 
					
						
							|  |  |  |     # 2) Check that the invariant holds for a sorted array | 
					
						
							|  |  |  |     check_invariant(results) | 
					
						
							|  |  |  |     # 3) Naive "N-best" algorithm | 
					
						
							|  |  |  |     heap = [] | 
					
						
							|  |  |  |     for item in data: | 
					
						
							|  |  |  |         heappush(heap, item) | 
					
						
							|  |  |  |         if len(heap) > 10: | 
					
						
							|  |  |  |             heappop(heap) | 
					
						
							|  |  |  |     heap.sort() | 
					
						
							|  |  |  |     vereq(heap, data_sorted[-10:]) | 
					
						
							| 
									
										
										
										
											2002-08-02 21:48:06 +00:00
										 |  |  |     # 4) Test heapify. | 
					
						
							|  |  |  |     for size in range(30): | 
					
						
							|  |  |  |         heap = [random.random() for dummy in range(size)] | 
					
						
							|  |  |  |         heapify(heap) | 
					
						
							|  |  |  |         check_invariant(heap) | 
					
						
							|  |  |  |     # 5) Less-naive "N-best" algorithm, much faster (if len(data) is big | 
					
						
							|  |  |  |     #    enough <wink>) than sorting all of data.  However, if we had a max | 
					
						
							| 
									
										
										
										
											2002-08-03 02:11:26 +00:00
										 |  |  |     #    heap instead of a min heap, it could go faster still via | 
					
						
							| 
									
										
										
										
											2002-08-02 21:48:06 +00:00
										 |  |  |     #    heapify'ing all of data (linear time), then doing 10 heappops | 
					
						
							|  |  |  |     #    (10 log-time steps). | 
					
						
							|  |  |  |     heap = data[:10] | 
					
						
							|  |  |  |     heapify(heap) | 
					
						
							|  |  |  |     for item in data[10:]: | 
					
						
							| 
									
										
										
										
											2002-08-03 02:11:26 +00:00
										 |  |  |         if item > heap[0]:  # this gets rarer the longer we run | 
					
						
							| 
									
										
										
										
											2002-08-03 10:10:10 +00:00
										 |  |  |             heapreplace(heap, item) | 
					
						
							| 
									
										
										
										
											2002-08-03 02:11:26 +00:00
										 |  |  |     vereq(list(heapiter(heap)), data_sorted[-10:]) | 
					
						
							| 
									
										
										
										
											2002-12-07 10:33:42 +00:00
										 |  |  |     # 6)  Exercise everything with repeated heapsort checks | 
					
						
							|  |  |  |     for trial in xrange(100): | 
					
						
							|  |  |  |         size = random.randrange(50) | 
					
						
							|  |  |  |         data = [random.randrange(25) for i in range(size)] | 
					
						
							|  |  |  |         if trial & 1:     # Half of the time, use heapify | 
					
						
							|  |  |  |             heap = data[:] | 
					
						
							|  |  |  |             heapify(heap) | 
					
						
							|  |  |  |         else:             # The rest of the time, use heappush | 
					
						
							|  |  |  |             heap = [] | 
					
						
							|  |  |  |             for item in data: | 
					
						
							|  |  |  |                 heappush(heap,item) | 
					
						
							|  |  |  |         data.sort() | 
					
						
							|  |  |  |         sorted = [heappop(heap) for i in range(size)] | 
					
						
							|  |  |  |         vereq(data, sorted) | 
					
						
							| 
									
										
										
										
											2002-08-02 18:29:53 +00:00
										 |  |  |     # Make user happy | 
					
						
							|  |  |  |     if verbose: | 
					
						
							|  |  |  |         print "All OK" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |     test_main() |