Update upstream source from tag 'upstream/1.0.1'
Update to upstream version '1.0.1'
with Debian dir 90d870717857263c2fda7e59bebd9db39aaf6beb
Diane Trout
4 years ago
0 | 0 | Metadata-Version: 1.1 |
1 | 1 | Name: HeapDict |
2 | Version: 1.0.0 | |
2 | Version: 1.0.1 | |
3 | 3 | Summary: a heap with decrease-key and increase-key operations |
4 | 4 | Home-page: http://stutzbachenterprises.com/ |
5 | 5 | Author: Stutzbach Enterprises, LLC |
14 | 14 | |
15 | 15 | :: |
16 | 16 | |
17 | hd = heapdict() | |
18 | hd[obj1] = priority1 | |
19 | hd[obj2] = priority2 | |
20 | # ... | |
21 | obj = hd.pop() | |
17 | hd = heapdict() | |
18 | hd[obj1] = priority1 | |
19 | hd[obj2] = priority2 | |
20 | # ... | |
21 | (obj, priority) = hd.popitem() | |
22 | 22 | |
23 | 23 | Compared to an ordinary dict, a heapdict has the following differences: |
24 | 24 | |
25 | 25 | popitem(): |
26 | Remove and return the (key, priority) pair with the lowest | |
27 | priority, instead of a random object. | |
26 | Remove and return the (key, priority) pair with the lowest | |
27 | priority, instead of a random object. | |
28 | 28 | |
29 | 29 | peekitem(): |
30 | Return the (key, priority) pair with the lowest priority, without | |
31 | removing it. | |
30 | Return the (key, priority) pair with the lowest priority, without | |
31 | removing it. | |
32 | 32 | |
33 | 33 | Unlike the Python standard library's heapq module, the heapdict |
34 | 34 | supports efficiently changing the priority of an existing object |
0 | 0 | LICENSE |
1 | 1 | MANIFEST.in |
2 | 2 | README.rst |
3 | ez_setup.py | |
4 | 3 | heapdict.py |
5 | 4 | setup.py |
6 | 5 | test_heap.py |
8 | 7 | HeapDict.egg-info/SOURCES.txt |
9 | 8 | HeapDict.egg-info/dependency_links.txt |
10 | 9 | HeapDict.egg-info/top_level.txt |
11 | HeapDict.egg-info/zip-safe | |
12 | heapdict.egg-info/SOURCES.txt⏎ | |
10 | HeapDict.egg-info/zip-safe⏎ |
0 | 0 | include heapdict.py |
1 | include ez_setup.py | |
2 | 1 | include LICENSE |
3 | 2 | include test_heap.py |
4 | 3 | include setup.py |
0 | 0 | Metadata-Version: 1.1 |
1 | 1 | Name: HeapDict |
2 | Version: 1.0.0 | |
2 | Version: 1.0.1 | |
3 | 3 | Summary: a heap with decrease-key and increase-key operations |
4 | 4 | Home-page: http://stutzbachenterprises.com/ |
5 | 5 | Author: Stutzbach Enterprises, LLC |
14 | 14 | |
15 | 15 | :: |
16 | 16 | |
17 | hd = heapdict() | |
18 | hd[obj1] = priority1 | |
19 | hd[obj2] = priority2 | |
20 | # ... | |
21 | obj = hd.pop() | |
17 | hd = heapdict() | |
18 | hd[obj1] = priority1 | |
19 | hd[obj2] = priority2 | |
20 | # ... | |
21 | (obj, priority) = hd.popitem() | |
22 | 22 | |
23 | 23 | Compared to an ordinary dict, a heapdict has the following differences: |
24 | 24 | |
25 | 25 | popitem(): |
26 | Remove and return the (key, priority) pair with the lowest | |
27 | priority, instead of a random object. | |
26 | Remove and return the (key, priority) pair with the lowest | |
27 | priority, instead of a random object. | |
28 | 28 | |
29 | 29 | peekitem(): |
30 | Return the (key, priority) pair with the lowest priority, without | |
31 | removing it. | |
30 | Return the (key, priority) pair with the lowest priority, without | |
31 | removing it. | |
32 | 32 | |
33 | 33 | Unlike the Python standard library's heapq module, the heapdict |
34 | 34 | supports efficiently changing the priority of an existing object |
10 | 10 | hd[obj1] = priority1 |
11 | 11 | hd[obj2] = priority2 |
12 | 12 | # ... |
13 | obj = hd.pop() | |
13 | (obj, priority) = hd.popitem() | |
14 | 14 | |
15 | 15 | Compared to an ordinary dict, a heapdict has the following differences: |
16 | 16 |
0 | #!python | |
1 | """Bootstrap setuptools installation | |
2 | ||
3 | If you want to use setuptools in your package's setup.py, just include this | |
4 | file in the same directory with it, and add this to the top of your setup.py:: | |
5 | ||
6 | from ez_setup import use_setuptools | |
7 | use_setuptools() | |
8 | ||
9 | If you want to require a specific version of setuptools, set a download | |
10 | mirror, or use an alternate download directory, you can do so by supplying | |
11 | the appropriate options to ``use_setuptools()``. | |
12 | ||
13 | This file can also be run as a script to install or upgrade setuptools. | |
14 | """ | |
15 | import sys | |
16 | DEFAULT_VERSION = "0.6c9" | |
17 | DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] | |
18 | ||
19 | md5_data = { | |
20 | 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', | |
21 | 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', | |
22 | 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', | |
23 | 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', | |
24 | 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', | |
25 | 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', | |
26 | 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', | |
27 | 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', | |
28 | 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', | |
29 | 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', | |
30 | 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', | |
31 | 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', | |
32 | 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', | |
33 | 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', | |
34 | 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', | |
35 | 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', | |
36 | 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', | |
37 | 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', | |
38 | 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', | |
39 | 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', | |
40 | 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', | |
41 | 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', | |
42 | 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', | |
43 | 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', | |
44 | 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', | |
45 | 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', | |
46 | 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', | |
47 | 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', | |
48 | 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', | |
49 | 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', | |
50 | 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03', | |
51 | 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a', | |
52 | 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6', | |
53 | 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a', | |
54 | } | |
55 | ||
56 | import sys, os | |
57 | try: from hashlib import md5 | |
58 | except ImportError: from md5 import md5 | |
59 | ||
60 | def _validate_md5(egg_name, data): | |
61 | if egg_name in md5_data: | |
62 | digest = md5(data).hexdigest() | |
63 | if digest != md5_data[egg_name]: | |
64 | print >>sys.stderr, ( | |
65 | "md5 validation of %s failed! (Possible download problem?)" | |
66 | % egg_name | |
67 | ) | |
68 | sys.exit(2) | |
69 | return data | |
70 | ||
71 | def use_setuptools( | |
72 | version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, | |
73 | download_delay=15 | |
74 | ): | |
75 | """Automatically find/download setuptools and make it available on sys.path | |
76 | ||
77 | `version` should be a valid setuptools version number that is available | |
78 | as an egg for download under the `download_base` URL (which should end with | |
79 | a '/'). `to_dir` is the directory where setuptools will be downloaded, if | |
80 | it is not already available. If `download_delay` is specified, it should | |
81 | be the number of seconds that will be paused before initiating a download, | |
82 | should one be required. If an older version of setuptools is installed, | |
83 | this routine will print a message to ``sys.stderr`` and raise SystemExit in | |
84 | an attempt to abort the calling script. | |
85 | """ | |
86 | was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules | |
87 | def do_download(): | |
88 | egg = download_setuptools(version, download_base, to_dir, download_delay) | |
89 | sys.path.insert(0, egg) | |
90 | import setuptools; setuptools.bootstrap_install_from = egg | |
91 | try: | |
92 | import pkg_resources | |
93 | except ImportError: | |
94 | return do_download() | |
95 | try: | |
96 | pkg_resources.require("setuptools>="+version); return | |
97 | except pkg_resources.VersionConflict, e: | |
98 | if was_imported: | |
99 | print >>sys.stderr, ( | |
100 | "The required version of setuptools (>=%s) is not available, and\n" | |
101 | "can't be installed while this script is running. Please install\n" | |
102 | " a more recent version first, using 'easy_install -U setuptools'." | |
103 | "\n\n(Currently using %r)" | |
104 | ) % (version, e.args[0]) | |
105 | sys.exit(2) | |
106 | else: | |
107 | del pkg_resources, sys.modules['pkg_resources'] # reload ok | |
108 | return do_download() | |
109 | except pkg_resources.DistributionNotFound: | |
110 | return do_download() | |
111 | ||
112 | def download_setuptools( | |
113 | version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, | |
114 | delay = 15 | |
115 | ): | |
116 | """Download setuptools from a specified location and return its filename | |
117 | ||
118 | `version` should be a valid setuptools version number that is available | |
119 | as an egg for download under the `download_base` URL (which should end | |
120 | with a '/'). `to_dir` is the directory where the egg will be downloaded. | |
121 | `delay` is the number of seconds to pause before an actual download attempt. | |
122 | """ | |
123 | import urllib2, shutil | |
124 | egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) | |
125 | url = download_base + egg_name | |
126 | saveto = os.path.join(to_dir, egg_name) | |
127 | src = dst = None | |
128 | if not os.path.exists(saveto): # Avoid repeated downloads | |
129 | try: | |
130 | from distutils import log | |
131 | if delay: | |
132 | log.warn(""" | |
133 | --------------------------------------------------------------------------- | |
134 | This script requires setuptools version %s to run (even to display | |
135 | help). I will attempt to download it for you (from | |
136 | %s), but | |
137 | you may need to enable firewall access for this script first. | |
138 | I will start the download in %d seconds. | |
139 | ||
140 | (Note: if this machine does not have network access, please obtain the file | |
141 | ||
142 | %s | |
143 | ||
144 | and place it in this directory before rerunning this script.) | |
145 | ---------------------------------------------------------------------------""", | |
146 | version, download_base, delay, url | |
147 | ); from time import sleep; sleep(delay) | |
148 | log.warn("Downloading %s", url) | |
149 | src = urllib2.urlopen(url) | |
150 | # Read/write all in one block, so we don't create a corrupt file | |
151 | # if the download is interrupted. | |
152 | data = _validate_md5(egg_name, src.read()) | |
153 | dst = open(saveto,"wb"); dst.write(data) | |
154 | finally: | |
155 | if src: src.close() | |
156 | if dst: dst.close() | |
157 | return os.path.realpath(saveto) | |
158 | ||
159 | ||
160 | ||
161 | ||
162 | ||
163 | ||
164 | ||
165 | ||
166 | ||
167 | ||
168 | ||
169 | ||
170 | ||
171 | ||
172 | ||
173 | ||
174 | ||
175 | ||
176 | ||
177 | ||
178 | ||
179 | ||
180 | ||
181 | ||
182 | ||
183 | ||
184 | ||
185 | ||
186 | ||
187 | ||
188 | ||
189 | ||
190 | ||
191 | ||
192 | ||
193 | ||
194 | def main(argv, version=DEFAULT_VERSION): | |
195 | """Install or upgrade setuptools and EasyInstall""" | |
196 | try: | |
197 | import setuptools | |
198 | except ImportError: | |
199 | egg = None | |
200 | try: | |
201 | egg = download_setuptools(version, delay=0) | |
202 | sys.path.insert(0,egg) | |
203 | from setuptools.command.easy_install import main | |
204 | return main(list(argv)+[egg]) # we're done here | |
205 | finally: | |
206 | if egg and os.path.exists(egg): | |
207 | os.unlink(egg) | |
208 | else: | |
209 | if setuptools.__version__ == '0.0.1': | |
210 | print >>sys.stderr, ( | |
211 | "You have an obsolete version of setuptools installed. Please\n" | |
212 | "remove it from your system entirely before rerunning this script." | |
213 | ) | |
214 | sys.exit(2) | |
215 | ||
216 | req = "setuptools>="+version | |
217 | import pkg_resources | |
218 | try: | |
219 | pkg_resources.require(req) | |
220 | except pkg_resources.VersionConflict: | |
221 | try: | |
222 | from setuptools.command.easy_install import main | |
223 | except ImportError: | |
224 | from easy_install import main | |
225 | main(list(argv)+[download_setuptools(delay=0)]) | |
226 | sys.exit(0) # try to force an exit | |
227 | else: | |
228 | if argv: | |
229 | from setuptools.command.easy_install import main | |
230 | main(argv) | |
231 | else: | |
232 | print "Setuptools version",version,"or greater has been installed." | |
233 | print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' | |
234 | ||
235 | def update_md5(filenames): | |
236 | """Update our built-in md5 registry""" | |
237 | ||
238 | import re | |
239 | ||
240 | for name in filenames: | |
241 | base = os.path.basename(name) | |
242 | f = open(name,'rb') | |
243 | md5_data[base] = md5(f.read()).hexdigest() | |
244 | f.close() | |
245 | ||
246 | data = [" %r: %r,\n" % it for it in md5_data.items()] | |
247 | data.sort() | |
248 | repl = "".join(data) | |
249 | ||
250 | import inspect | |
251 | srcfile = inspect.getsourcefile(sys.modules[__name__]) | |
252 | f = open(srcfile, 'rb'); src = f.read(); f.close() | |
253 | ||
254 | match = re.search("\nmd5_data = {\n([^}]+)}", src) | |
255 | if not match: | |
256 | print >>sys.stderr, "Internal error!" | |
257 | sys.exit(2) | |
258 | ||
259 | src = src[:match.start(1)] + repl + src[match.end(1):] | |
260 | f = open(srcfile,'w') | |
261 | f.write(src) | |
262 | f.close() | |
263 | ||
264 | ||
265 | if __name__=='__main__': | |
266 | if len(sys.argv)>2 and sys.argv[1]=='--md5update': | |
267 | update_md5(sys.argv[2:]) | |
268 | else: | |
269 | main(sys.argv[1:]) | |
270 | ||
271 | ||
272 | ||
273 | ||
274 | ||
275 |
0 | import collections | |
0 | try: | |
1 | from collections.abc import MutableMapping | |
2 | except ImportError: | |
3 | from collections import MutableMapping | |
4 | ||
1 | 5 | |
2 | 6 | def doc(s): |
3 | 7 | if hasattr(s, '__call__'): |
4 | 8 | s = s.__doc__ |
9 | ||
5 | 10 | def f(g): |
6 | 11 | g.__doc__ = s |
7 | 12 | return g |
8 | 13 | return f |
9 | 14 | |
10 | class heapdict(collections.MutableMapping): | |
15 | ||
16 | class heapdict(MutableMapping): | |
11 | 17 | __marker = object() |
12 | 18 | |
13 | @staticmethod | |
14 | def _parent(i): | |
15 | return ((i - 1) >> 1) | |
16 | ||
17 | @staticmethod | |
18 | def _left(i): | |
19 | return ((i << 1) + 1) | |
20 | ||
21 | @staticmethod | |
22 | def _right(i): | |
23 | return ((i+1) << 1) | |
24 | ||
25 | 19 | def __init__(self, *args, **kw): |
26 | 20 | self.heap = [] |
27 | 21 | self.d = {} |
29 | 23 | |
30 | 24 | @doc(dict.clear) |
31 | 25 | def clear(self): |
32 | self.heap.clear() | |
26 | del self.heap[:] | |
33 | 27 | self.d.clear() |
34 | 28 | |
35 | 29 | @doc(dict.__setitem__) |
42 | 36 | self._decrease_key(len(self.heap)-1) |
43 | 37 | |
44 | 38 | def _min_heapify(self, i): |
45 | l = self._left(i) | |
46 | r = self._right(i) | |
47 | 39 | n = len(self.heap) |
48 | if l < n and self.heap[l][0] < self.heap[i][0]: | |
49 | low = l | |
50 | else: | |
51 | low = i | |
52 | if r < n and self.heap[r][0] < self.heap[low][0]: | |
53 | low = r | |
40 | h = self.heap | |
41 | while True: | |
42 | # calculate the offset of the left child | |
43 | l = (i << 1) + 1 | |
44 | # calculate the offset of the right child | |
45 | r = (i + 1) << 1 | |
46 | if l < n and h[l][0] < h[i][0]: | |
47 | low = l | |
48 | else: | |
49 | low = i | |
50 | if r < n and h[r][0] < h[low][0]: | |
51 | low = r | |
54 | 52 | |
55 | if low != i: | |
53 | if low == i: | |
54 | break | |
55 | ||
56 | 56 | self._swap(i, low) |
57 | self._min_heapify(low) | |
57 | i = low | |
58 | 58 | |
59 | 59 | def _decrease_key(self, i): |
60 | 60 | while i: |
61 | parent = self._parent(i) | |
62 | if self.heap[parent][0] < self.heap[i][0]: break | |
61 | # calculate the offset of the parent | |
62 | parent = (i - 1) >> 1 | |
63 | if self.heap[parent][0] < self.heap[i][0]: | |
64 | break | |
63 | 65 | self._swap(i, parent) |
64 | 66 | i = parent |
65 | 67 | |
66 | 68 | def _swap(self, i, j): |
67 | self.heap[i], self.heap[j] = self.heap[j], self.heap[i] | |
68 | self.heap[i][2] = i | |
69 | self.heap[j][2] = j | |
69 | h = self.heap | |
70 | h[i], h[j] = h[j], h[i] | |
71 | h[i][2] = i | |
72 | h[j][2] = j | |
70 | 73 | |
71 | 74 | @doc(dict.__delitem__) |
72 | 75 | def __delitem__(self, key): |
73 | 76 | wrapper = self.d[key] |
74 | 77 | while wrapper[2]: |
75 | parentpos = self._parent(wrapper[2]) | |
78 | # calculate the offset of the parent | |
79 | parentpos = (wrapper[2] - 1) >> 1 | |
76 | 80 | parent = self.heap[parentpos] |
77 | 81 | self._swap(wrapper[2], parent[2]) |
78 | 82 | self.popitem() |
91 | 95 | if len(self.heap) == 1: |
92 | 96 | self.heap.pop() |
93 | 97 | else: |
94 | self.heap[0] = self.heap.pop(-1) | |
98 | self.heap[0] = self.heap.pop() | |
95 | 99 | self.heap[0][2] = 0 |
96 | 100 | self._min_heapify(0) |
97 | 101 | del self.d[wrapper[1]] |
98 | return wrapper[1], wrapper[0] | |
102 | return wrapper[1], wrapper[0] | |
99 | 103 | |
100 | 104 | @doc(dict.__len__) |
101 | 105 | def __len__(self): |
105 | 109 | """D.peekitem() -> (k, v), return the (key, value) pair with lowest value;\n but raise KeyError if D is empty.""" |
106 | 110 | return (self.heap[0][1], self.heap[0][0]) |
107 | 111 | |
112 | ||
108 | 113 | del doc |
109 | 114 | __all__ = ['heapdict'] |
0 | 0 | #!/usr/bin/env |
1 | 1 | |
2 | import sys | |
3 | if sys.version_info[0] <= 2: | |
4 | import ez_setup | |
5 | ez_setup.use_setuptools() | |
6 | from setuptools import setup, Extension | |
7 | else: | |
8 | from distutils.core import setup, Extension | |
2 | from setuptools import setup | |
9 | 3 | |
10 | 4 | setup(name='HeapDict', |
11 | version='1.0.0', | |
5 | version='1.0.1', | |
12 | 6 | description='a heap with decrease-key and increase-key operations', |
13 | 7 | author='Stutzbach Enterprises, LLC', |
14 | 8 | author_email='daniel@stutzbachenterprises.com', |
34 | 28 | ], |
35 | 29 | |
36 | 30 | long_description=open('README.rst').read(), |
37 | ||
38 | 31 | ) |
0 | 0 | #!/usr/bin/python |
1 | 1 | from __future__ import print_function |
2 | import random | |
3 | import sys | |
4 | import unittest | |
2 | 5 | from heapdict import heapdict |
3 | import random | |
4 | import unittest | |
5 | import sys | |
6 | 6 | try: |
7 | import test.support as test_support # Python 3 | |
7 | # Python 3 | |
8 | import test.support as test_support | |
8 | 9 | except ImportError: |
9 | import test.test_support as test_support # Python 2 | |
10 | # Python 2 | |
11 | import test.test_support as test_support | |
10 | 12 | |
11 | 13 | N = 100 |
12 | 14 | |
15 | ||
13 | 16 | class TestHeap(unittest.TestCase): |
17 | ||
14 | 18 | def check_invariants(self, h): |
15 | for i in range(len(h)): | |
16 | self.assertEqual(h.heap[i][2], i) | |
17 | if i > 0: | |
18 | self.assertTrue(h.heap[h._parent(i)][0] <= h.heap[i][0]) | |
19 | # the 3rd entry of each heap entry is the position in the heap | |
20 | for i, e in enumerate(h.heap): | |
21 | self.assertEqual(e[2], i) | |
22 | # the parent of each heap element must not be larger than the element | |
23 | for i in range(1, len(h.heap)): | |
24 | parent = (i - 1) >> 1 | |
25 | self.assertLessEqual(h.heap[parent][0], h.heap[i][0]) | |
19 | 26 | |
20 | 27 | def make_data(self): |
21 | 28 | pairs = [(random.random(), random.random()) for i in range(N)] |
27 | 34 | |
28 | 35 | pairs.sort(key=lambda x: x[1], reverse=True) |
29 | 36 | return h, pairs, d |
30 | ||
37 | ||
31 | 38 | def test_popitem(self): |
32 | h, pairs, d = self.make_data() | |
39 | h, pairs, _ = self.make_data() | |
33 | 40 | while pairs: |
34 | 41 | v = h.popitem() |
35 | 42 | v2 = pairs.pop(-1) |
41 | 48 | for i in range(N): |
42 | 49 | h[i] = 0 |
43 | 50 | for i in range(N): |
44 | k, v = h.popitem() | |
51 | _, v = h.popitem() | |
45 | 52 | self.assertEqual(v, 0) |
46 | 53 | self.check_invariants(h) |
47 | 54 | |
48 | 55 | def test_peek(self): |
49 | h, pairs, d = self.make_data() | |
56 | h, pairs, _ = self.make_data() | |
50 | 57 | while pairs: |
51 | 58 | v = h.peekitem()[0] |
52 | 59 | h.popitem() |
55 | 62 | self.assertEqual(len(h), 0) |
56 | 63 | |
57 | 64 | def test_iter(self): |
58 | h, pairs, d = self.make_data() | |
65 | h, _, d = self.make_data() | |
59 | 66 | self.assertEqual(list(h), list(d)) |
60 | 67 | |
61 | 68 | def test_keys(self): |
62 | h, pairs, d = self.make_data() | |
69 | h, _, d = self.make_data() | |
63 | 70 | self.assertEqual(list(sorted(h.keys())), list(sorted(d.keys()))) |
64 | 71 | |
65 | 72 | def test_values(self): |
66 | h, pairs, d = self.make_data() | |
73 | h, _, d = self.make_data() | |
67 | 74 | self.assertEqual(list(sorted(h.values())), list(sorted(d.values()))) |
68 | 75 | |
69 | 76 | def test_del(self): |
70 | h, pairs, d = self.make_data() | |
77 | h, pairs, _ = self.make_data() | |
71 | 78 | k, v = pairs.pop(N//2) |
72 | 79 | del h[k] |
73 | 80 | while pairs: |
77 | 84 | self.assertEqual(len(h), 0) |
78 | 85 | |
79 | 86 | def test_change(self): |
80 | h, pairs, d = self.make_data() | |
87 | h, pairs, _ = self.make_data() | |
81 | 88 | k, v = pairs[N//2] |
82 | 89 | h[k] = 0.5 |
83 | 90 | pairs[N//2] = (k, 0.5) |
84 | pairs.sort(key = lambda x: x[1], reverse=True) | |
91 | pairs.sort(key=lambda x: x[1], reverse=True) | |
85 | 92 | while pairs: |
86 | 93 | v = h.popitem() |
87 | 94 | v2 = pairs.pop(-1) |
88 | 95 | self.assertEqual(v, v2) |
89 | 96 | self.assertEqual(len(h), 0) |
90 | 97 | |
91 | #============================================================================== | |
98 | def test_clear(self): | |
99 | h, _, _ = self.make_data() | |
100 | h.clear() | |
101 | self.assertEqual(len(h), 0) | |
102 | ||
92 | 103 | |
93 | 104 | def test_main(verbose=None): |
94 | from types import BuiltinFunctionType | |
95 | ||
96 | 105 | test_classes = [TestHeap] |
97 | 106 | test_support.run_unittest(*test_classes) |
98 | 107 | |
100 | 109 | if verbose and hasattr(sys, "gettotalrefcount"): |
101 | 110 | import gc |
102 | 111 | counts = [None] * 5 |
103 | for i in xrange(len(counts)): | |
112 | for i in range(len(counts)): | |
104 | 113 | test_support.run_unittest(*test_classes) |
105 | 114 | gc.collect() |
106 | 115 | counts[i] = sys.gettotalrefcount() |
107 | 116 | print(counts) |
108 | 117 | |
118 | ||
109 | 119 | if __name__ == "__main__": |
110 | 120 | test_main(verbose=True) |