1 """ ion toplevel module
3 ion includes general routines for common manipulations I use
5 Most modules are entirely my own work.
7 * maths (randomization, compression)
9 * data (efficient/easy representations of simple, large scale types,
12 Some modules have an additional related module -- eg ``n`` -> ``xn``.
13 ``x`` modules contain experimental code; API MAY CHANGE AT ANY TIME.
17 class LengthMismatch (ValueError):
20 def seqorsingle (value
, datatype
):
21 """Return a sequence of 'scalar's from a scalar or sequence of scalars.
25 v : sequence or scalar
26 The distinction is muddied by things like strings, which are
27 technically sequences, but more often treated as scalars.
29 datatype : if ``type (v)`` matches this type, it is considered a scalar.
30 can be a sequence, eg (int, float)
34 seq : sequence (or unmatched scalar)
37 XXX could be apropos to numpy.alen / numpy.asarray
46 except AttributeError:
51 def limititer (iter, num
= 1):
52 """Iterates through the first of the items in an iterable.
57 Typically an infinite iterable without slicability
59 the first ``num`` entries of the iterable are iterated
60 through before iteration stops.
67 # XXX rename -> squeeze_split
68 def squeezeSplit (src
, sep
):
69 """Return src splitted by sep and squeezed (removing ''s)"""
70 splitted
= src
.split(sep
)
76 """Return the binary representation of the input number, MSB-first.
81 Positive number to calculate the representation of
86 A string with one character per bit in ``value``.
87 len (bitstr) == min_nbits (value)
95 '11111111111111111111111111111111'
99 * Uses ``numpy.binary_repr`` if available (~68x speedup).
100 * You should use ``binary_repr`` directly if you need to represent
102 * Deprecated, will be obsolete in Python 3 vs the builtin ``bin()``
106 return numpy
.binary_repr (value
)
111 t
.append (chr (value
& 1 + 48))
117 a, b, c, d, a, b, c, d
119 a, a | b, b | c, c | d, d
121 useful for things such as coordinates:
123 xc, yc = piz (coords, 2)
124 # xc, yc are now matching lists of x and y coords
126 Where passing them around as 2-tuples would be woefully inefficient,
127 but working with them needs them individualized.
131 perhaps could be replaced with tuple subclass
132 Still, this is useful for other things
133 Like separating out RGB channels
136 if (len (v
) % n
> 0):
137 raise IndexError("piz() input sequence length doesn't match\
146 def read_everything (filename
, open = open):
147 """Return a string containing the entirety of the file contents."""
153 def read_everyline (filename
, open = open):
154 """Return a list containing every line in file."""
160 def cycleiter (iter, startoffset
, step
= 1):
161 """infinite cycling through rotations of a sequence.
165 iter : sequence or iterable
166 if ``iter`` doesn't have __len__ attribute,
167 it must iterate over the same number of items each time.
168 startoffset : integer
170 added to ``offset`` each iteration
175 >>> list (limititer (cycle ([0,1,2,3], 1, 1), 5))
176 [1, 2, 3, 0], [2, 3, 0, 1], [3, 0, 1, 2], [0, 1, 2, 3]
180 except AttributeError:
181 nitems
= len (list (iter))
182 iter = iter.__iter
__ ()
183 offset
= startoffset
% nitems
184 output
= [None] * nitems
186 output
[:nitems
] = foo
189 # XXX turn this into an iterator with (seq, step, nsteps) parameters.
191 """ cycle v by n steps. 01234 +1 -> 40123; -1 -> 12340"""
197 if issubclass(v
.__class
__, numpy
.ndarray
):
198 return numpy
.append (v
[-n
:], v
[:-n
])
201 return v
[-n
:] + v
[:-n
]
203 return cycleiter (v
, n
)
206 return v
[-n
:] + v
[:-n
]
208 return cycleiter (v
, n
)
211 """Calculates the number of bits needed to store an integer or long
215 num : positive integer
227 return round (notional_nbits (num
))
241 def notional_nbits (num
):
242 """Calculate the notional number of bits needed to store an integer value.
246 num : positive integer
251 A measure of bits per sized variable,
252 suitable for calculating interface efficiency.
256 >>> notional_nbits (4)
259 >>> notional_nbits (3)
264 return log (num
+ 1, 2)
266 def setattrs (object, **kwargs
):
267 """Sets attributes on an object from keyword args.
272 An object supporting the specified attributes.
273 If an object has a __dict__ attribute
274 (ie. the class is not limited via __slots__ or implemented in C)
275 then any attribute may be set on it.
276 kwargs : attribute=value pairs, optional
277 for each attribute = value pair, set ``object.attribute = value``.
279 Attribute names should be only valid Python symbol names.
280 However, when expanding a dictionary into kwargs like::
282 setattrs (obj, **{'spacy attribute': 1})
284 it is possible to assign attributes that are only accessible with
285 ``obj.__dict__['attr']`` or ``getattr (obj, 'attr')``.
286 This situation can only occur when attributes of ``object`` are freeform
287 (ie. it has a __dict__ attribute.)
291 >>> import numpy as np
292 >>> c = np.arange (16)
297 ((4, 4), dtype('float32'))
299 for key
, value
in kwargs
.items():
300 setattr (object, key
, value
)
303 # note - the following line confuses IPython.
304 # it may be inappropriate behaviour for the top level of a package
305 #__all__ = ('tupled', )