Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/networkx/utils/misc.py @ 0:26e78fe6e8c4 draft
"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author | shellac |
---|---|
date | Sat, 02 May 2020 07:14:21 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:26e78fe6e8c4 |
---|---|
1 """ | |
2 Miscellaneous Helpers for NetworkX. | |
3 | |
4 These are not imported into the base networkx namespace but | |
5 can be accessed, for example, as | |
6 | |
7 >>> import networkx | |
8 >>> networkx.utils.is_string_like('spam') | |
9 True | |
10 """ | |
11 # Authors: Aric Hagberg (hagberg@lanl.gov), | |
12 # Dan Schult(dschult@colgate.edu), | |
13 # Ben Edwards(bedwards@cs.unm.edu) | |
14 | |
15 # Copyright (C) 2004-2019 by | |
16 # Aric Hagberg <hagberg@lanl.gov> | |
17 # Dan Schult <dschult@colgate.edu> | |
18 # Pieter Swart <swart@lanl.gov> | |
19 # All rights reserved. | |
20 # BSD license. | |
21 from collections import defaultdict | |
22 from collections import deque | |
23 import warnings | |
24 import sys | |
25 import uuid | |
26 from itertools import tee, chain | |
27 import networkx as nx | |
28 | |
29 # itertools.accumulate is only available on Python 3.2 or later. | |
30 # | |
31 # Once support for Python versions less than 3.2 is dropped, this code should | |
32 # be removed. | |
33 try: | |
34 from itertools import accumulate | |
35 except ImportError: | |
36 import operator | |
37 | |
38 # The code for this function is from the Python 3.5 documentation, | |
39 # distributed under the PSF license: | |
40 # <https://docs.python.org/3.5/library/itertools.html#itertools.accumulate> | |
41 def accumulate(iterable, func=operator.add): | |
42 it = iter(iterable) | |
43 try: | |
44 total = next(it) | |
45 except StopIteration: | |
46 return | |
47 yield total | |
48 for element in it: | |
49 total = func(total, element) | |
50 yield total | |
51 | |
52 # 2.x/3.x compatibility | |
53 try: | |
54 basestring | |
55 except NameError: | |
56 basestring = str | |
57 unicode = str | |
58 | |
59 # some cookbook stuff | |
60 # used in deciding whether something is a bunch of nodes, edges, etc. | |
61 # see G.add_nodes and others in Graph Class in networkx/base.py | |
62 | |
63 | |
64 def is_string_like(obj): # from John Hunter, types-free version | |
65 """Check if obj is string.""" | |
66 return isinstance(obj, basestring) | |
67 | |
68 | |
69 def iterable(obj): | |
70 """ Return True if obj is iterable with a well-defined len().""" | |
71 if hasattr(obj, "__iter__"): | |
72 return True | |
73 try: | |
74 len(obj) | |
75 except: | |
76 return False | |
77 return True | |
78 | |
79 | |
80 def flatten(obj, result=None): | |
81 """ Return flattened version of (possibly nested) iterable object. """ | |
82 if not iterable(obj) or is_string_like(obj): | |
83 return obj | |
84 if result is None: | |
85 result = [] | |
86 for item in obj: | |
87 if not iterable(item) or is_string_like(item): | |
88 result.append(item) | |
89 else: | |
90 flatten(item, result) | |
91 return obj.__class__(result) | |
92 | |
93 | |
94 def make_list_of_ints(sequence): | |
95 """Return list of ints from sequence of integral numbers. | |
96 | |
97 All elements of the sequence must satisfy int(element) == element | |
98 or a ValueError is raised. Sequence is iterated through once. | |
99 | |
100 If sequence is a list, the non-int values are replaced with ints. | |
101 So, no new list is created | |
102 """ | |
103 msg = 'sequence is not all integers: %s' | |
104 if not isinstance(sequence, list): | |
105 result = [] | |
106 for i in sequence: | |
107 try: | |
108 ii = int(i) | |
109 except ValueError: | |
110 raise nx.NetworkXError(msg % i) from None | |
111 if ii != i: | |
112 raise nx.NetworkXError(msg % i) | |
113 result.append(ii) | |
114 return result | |
115 # original sequence is a list... in-place conversion to ints | |
116 for indx, i in enumerate(sequence): | |
117 if isinstance(i, int): | |
118 continue | |
119 try: | |
120 ii = int(i) | |
121 except ValueError: | |
122 raise nx.NetworkXError(msg % i) from None | |
123 if ii != i: | |
124 raise nx.NetworkXError(msg % i) | |
125 sequence[indx] = ii | |
126 return sequence | |
127 | |
128 | |
129 def is_list_of_ints(intlist): | |
130 """ Return True if list is a list of ints. """ | |
131 if not isinstance(intlist, list): | |
132 return False | |
133 for i in intlist: | |
134 if not isinstance(i, int): | |
135 return False | |
136 return True | |
137 | |
138 | |
139 PY2 = sys.version_info[0] == 2 | |
140 if PY2: | |
141 def make_str(x): | |
142 """Returns the string representation of t.""" | |
143 if isinstance(x, unicode): | |
144 return x | |
145 else: | |
146 # Note, this will not work unless x is ascii-encoded. | |
147 # That is good, since we should be working with unicode anyway. | |
148 # Essentially, unless we are reading a file, we demand that users | |
149 # convert any encoded strings to unicode before using the library. | |
150 # | |
151 # Also, the str() is necessary to convert integers, etc. | |
152 # unicode(3) works, but unicode(3, 'unicode-escape') wants a buffer | |
153 # | |
154 return unicode(str(x), 'unicode-escape') | |
155 else: | |
156 def make_str(x): | |
157 """Returns the string representation of t.""" | |
158 return str(x) | |
159 | |
160 | |
161 def generate_unique_node(): | |
162 """ Generate a unique node label.""" | |
163 return str(uuid.uuid1()) | |
164 | |
165 | |
166 def default_opener(filename): | |
167 """Opens `filename` using system's default program. | |
168 | |
169 Parameters | |
170 ---------- | |
171 filename : str | |
172 The path of the file to be opened. | |
173 | |
174 """ | |
175 from subprocess import call | |
176 | |
177 cmds = {'darwin': ['open'], | |
178 'linux': ['xdg-open'], | |
179 'linux2': ['xdg-open'], | |
180 'win32': ['cmd.exe', '/C', 'start', '']} | |
181 cmd = cmds[sys.platform] + [filename] | |
182 call(cmd) | |
183 | |
184 | |
185 def dict_to_numpy_array(d, mapping=None): | |
186 """Convert a dictionary of dictionaries to a numpy array | |
187 with optional mapping.""" | |
188 try: | |
189 return dict_to_numpy_array2(d, mapping) | |
190 except (AttributeError, TypeError): | |
191 # AttributeError is when no mapping was provided and v.keys() fails. | |
192 # TypeError is when a mapping was provided and d[k1][k2] fails. | |
193 return dict_to_numpy_array1(d, mapping) | |
194 | |
195 | |
196 def dict_to_numpy_array2(d, mapping=None): | |
197 """Convert a dictionary of dictionaries to a 2d numpy array | |
198 with optional mapping. | |
199 | |
200 """ | |
201 import numpy | |
202 if mapping is None: | |
203 s = set(d.keys()) | |
204 for k, v in d.items(): | |
205 s.update(v.keys()) | |
206 mapping = dict(zip(s, range(len(s)))) | |
207 n = len(mapping) | |
208 a = numpy.zeros((n, n)) | |
209 for k1, i in mapping.items(): | |
210 for k2, j in mapping.items(): | |
211 try: | |
212 a[i, j] = d[k1][k2] | |
213 except KeyError: | |
214 pass | |
215 return a | |
216 | |
217 | |
218 def dict_to_numpy_array1(d, mapping=None): | |
219 """Convert a dictionary of numbers to a 1d numpy array | |
220 with optional mapping. | |
221 | |
222 """ | |
223 import numpy | |
224 if mapping is None: | |
225 s = set(d.keys()) | |
226 mapping = dict(zip(s, range(len(s)))) | |
227 n = len(mapping) | |
228 a = numpy.zeros(n) | |
229 for k1, i in mapping.items(): | |
230 i = mapping[k1] | |
231 a[i] = d[k1] | |
232 return a | |
233 | |
234 | |
235 def is_iterator(obj): | |
236 """Returns True if and only if the given object is an iterator | |
237 object. | |
238 | |
239 """ | |
240 has_next_attr = hasattr(obj, '__next__') or hasattr(obj, 'next') | |
241 return iter(obj) is obj and has_next_attr | |
242 | |
243 | |
244 def arbitrary_element(iterable): | |
245 """Returns an arbitrary element of `iterable` without removing it. | |
246 | |
247 This is most useful for "peeking" at an arbitrary element of a set, | |
248 but can be used for any list, dictionary, etc., as well:: | |
249 | |
250 >>> arbitrary_element({3, 2, 1}) | |
251 1 | |
252 >>> arbitrary_element('hello') | |
253 'h' | |
254 | |
255 This function raises a :exc:`ValueError` if `iterable` is an | |
256 iterator (because the current implementation of this function would | |
257 consume an element from the iterator):: | |
258 | |
259 >>> iterator = iter([1, 2, 3]) | |
260 >>> arbitrary_element(iterator) | |
261 Traceback (most recent call last): | |
262 ... | |
263 ValueError: cannot return an arbitrary item from an iterator | |
264 | |
265 """ | |
266 if is_iterator(iterable): | |
267 raise ValueError('cannot return an arbitrary item from an iterator') | |
268 # Another possible implementation is ``for x in iterable: return x``. | |
269 return next(iter(iterable)) | |
270 | |
271 | |
272 # Recipe from the itertools documentation. | |
273 def consume(iterator): | |
274 "Consume the iterator entirely." | |
275 # Feed the entire iterator into a zero-length deque. | |
276 deque(iterator, maxlen=0) | |
277 | |
278 | |
279 # Recipe from the itertools documentation. | |
280 def pairwise(iterable, cyclic=False): | |
281 "s -> (s0, s1), (s1, s2), (s2, s3), ..." | |
282 a, b = tee(iterable) | |
283 first = next(b, None) | |
284 if cyclic is True: | |
285 return zip(a, chain(b, (first,))) | |
286 return zip(a, b) | |
287 | |
288 | |
289 def groups(many_to_one): | |
290 """Converts a many-to-one mapping into a one-to-many mapping. | |
291 | |
292 `many_to_one` must be a dictionary whose keys and values are all | |
293 :term:`hashable`. | |
294 | |
295 The return value is a dictionary mapping values from `many_to_one` | |
296 to sets of keys from `many_to_one` that have that value. | |
297 | |
298 For example:: | |
299 | |
300 >>> from networkx.utils import groups | |
301 >>> many_to_one = {'a': 1, 'b': 1, 'c': 2, 'd': 3, 'e': 3} | |
302 >>> groups(many_to_one) # doctest: +SKIP | |
303 {1: {'a', 'b'}, 2: {'c'}, 3: {'d', 'e'}} | |
304 | |
305 """ | |
306 one_to_many = defaultdict(set) | |
307 for v, k in many_to_one.items(): | |
308 one_to_many[k].add(v) | |
309 return dict(one_to_many) | |
310 | |
311 | |
312 def to_tuple(x): | |
313 """Converts lists to tuples. | |
314 | |
315 For example:: | |
316 | |
317 >>> from networkx.utils import to_tuple | |
318 >>> a_list = [1, 2, [1, 4]] | |
319 >>> to_tuple(a_list) | |
320 (1, 2, (1, 4)) | |
321 | |
322 """ | |
323 if not isinstance(x, (tuple, list)): | |
324 return x | |
325 return tuple(map(to_tuple, x)) | |
326 | |
327 | |
328 def create_random_state(random_state=None): | |
329 """Returns a numpy.random.RandomState instance depending on input. | |
330 | |
331 Parameters | |
332 ---------- | |
333 random_state : int or RandomState instance or None optional (default=None) | |
334 If int, return a numpy.random.RandomState instance set with seed=int. | |
335 if numpy.random.RandomState instance, return it. | |
336 if None or numpy.random, return the global random number generator used | |
337 by numpy.random. | |
338 """ | |
339 import numpy as np | |
340 | |
341 if random_state is None or random_state is np.random: | |
342 return np.random.mtrand._rand | |
343 if isinstance(random_state, np.random.RandomState): | |
344 return random_state | |
345 if isinstance(random_state, int): | |
346 return np.random.RandomState(random_state) | |
347 msg = '%r cannot be used to generate a numpy.random.RandomState instance' | |
348 raise ValueError(msg % random_state) | |
349 | |
350 | |
351 class PythonRandomInterface(object): | |
352 try: | |
353 def __init__(self, rng=None): | |
354 import numpy | |
355 if rng is None: | |
356 self._rng = numpy.random.mtrand._rand | |
357 self._rng = rng | |
358 except ImportError: | |
359 msg = 'numpy not found, only random.random available.' | |
360 warnings.warn(msg, ImportWarning) | |
361 | |
362 def random(self): | |
363 return self._rng.random_sample() | |
364 | |
365 def uniform(self, a, b): | |
366 return a + (b - a) * self._rng.random_sample() | |
367 | |
368 def randrange(self, a, b=None): | |
369 return self._rng.randint(a, b) | |
370 | |
371 def choice(self, seq): | |
372 return seq[self._rng.randint(0, len(seq))] | |
373 | |
374 def gauss(self, mu, sigma): | |
375 return self._rng.normal(mu, sigma) | |
376 | |
377 def shuffle(self, seq): | |
378 return self._rng.shuffle(seq) | |
379 | |
380 # Some methods don't match API for numpy RandomState. | |
381 # Commented out versions are not used by NetworkX | |
382 | |
383 def sample(self, seq, k): | |
384 return self._rng.choice(list(seq), size=(k,), replace=False) | |
385 | |
386 def randint(self, a, b): | |
387 return self._rng.randint(a, b + 1) | |
388 | |
389 # exponential as expovariate with 1/argument, | |
390 def expovariate(self, scale): | |
391 return self._rng.exponential(1/scale) | |
392 | |
393 # pareto as paretovariate with 1/argument, | |
394 def paretovariate(self, shape): | |
395 return self._rng.pareto(shape) | |
396 | |
397 # weibull as weibullvariate multiplied by beta, | |
398 # def weibullvariate(self, alpha, beta): | |
399 # return self._rng.weibull(alpha) * beta | |
400 # | |
401 # def triangular(self, low, high, mode): | |
402 # return self._rng.triangular(low, mode, high) | |
403 # | |
404 # def choices(self, seq, weights=None, cum_weights=None, k=1): | |
405 # return self._rng.choice(seq | |
406 | |
407 | |
408 def create_py_random_state(random_state=None): | |
409 """Returns a random.Random instance depending on input. | |
410 | |
411 Parameters | |
412 ---------- | |
413 random_state : int or random number generator or None (default=None) | |
414 If int, return a random.Random instance set with seed=int. | |
415 if random.Random instance, return it. | |
416 if None or the `random` package, return the global random number | |
417 generator used by `random`. | |
418 if np.random package, return the global numpy random number | |
419 generator wrapped in a PythonRandomInterface class. | |
420 if np.random.RandomState instance, return it wrapped in | |
421 PythonRandomInterface | |
422 if a PythonRandomInterface instance, return it | |
423 """ | |
424 import random | |
425 try: | |
426 import numpy as np | |
427 if random_state is np.random: | |
428 return PythonRandomInterface(np.random.mtrand._rand) | |
429 if isinstance(random_state, np.random.RandomState): | |
430 return PythonRandomInterface(random_state) | |
431 if isinstance(random_state, PythonRandomInterface): | |
432 return random_state | |
433 has_numpy = True | |
434 except ImportError: | |
435 has_numpy = False | |
436 | |
437 if random_state is None or random_state is random: | |
438 return random._inst | |
439 if isinstance(random_state, random.Random): | |
440 return random_state | |
441 if isinstance(random_state, int): | |
442 return random.Random(random_state) | |
443 msg = '%r cannot be used to generate a random.Random instance' | |
444 raise ValueError(msg % random_state) | |
445 | |
446 | |
447 # fixture for pytest | |
448 def setup_module(module): | |
449 import pytest | |
450 numpy = pytest.importorskip('numpy') |