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