lazy_stream
Module¶
Stream class definition module
Summary of module contents:
Name | Description |
---|---|
StreamMeta | Stream metaclass. This class overloads all operators to the Stream class, but cmp/rcmp (deprecated), ternary pow (could be called with Stream.map) as well as divmod (same as pow, but this will result in a Stream of tuples). |
Stream | Stream class. Stream instances are iterables that can be seem as generators with elementwise operators. |
avoid_stream | Decorator to a class whose instances should avoid casting to a Stream when used with operators applied to them. |
tostream | Decorator to convert the function output into a Stream. Useful for generator functions. |
ControlStream | A Stream that yields a control value that can be changed at any time. You just need to set the attribute “value” for doing so, and the next value the Stream will yield is the given value. |
MemoryLeakWarning | A warning to be used when a memory leak is detected. |
StreamTeeHub | A Stream that returns a different iterator each time it is used. |
thub | Tee or “T” hub auto-copier to help working with Stream instances as well as with numbers. |
Streamix | Stream mixer of iterables. |
-
class
StreamMeta
[source]¶ Bases:
audiolazy.lazy_core.AbstractOperatorOverloaderMeta
Stream metaclass. This class overloads all operators to the Stream class, but cmp/rcmp (deprecated), ternary pow (could be called with Stream.map) as well as divmod (same as pow, but this will result in a Stream of tuples).
-
class
Stream
(*dargs)[source]¶ Bases:
collections.abc.Iterable
Stream class. Stream instances are iterables that can be seem as generators with elementwise operators.
- Examples:
If you want something like:
>>> import itertools >>> x = itertools.count() >>> y = itertools.repeat(3) >>> z = 2*x + y Traceback (most recent call last): ... TypeError: unsupported operand type(s) for *: 'int' and ...
That won’t work with standard itertools. That’s an error, and not only __mul__ but also __add__ isn’t supported by their types. On the other hand, you can use this Stream class:
>>> x = Stream(itertools.count()) # Iterable >>> y = Stream(3) # Non-iterable repeats endlessly >>> z = 2*x + y >>> z <audiolazy.lazy_stream.Stream object at 0x...> >>> z.take(12) [3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25]
If you just want to use your existing code, an “itertools” alternative is already done to help you:
>>> from audiolazy import lazy_itertools as itertools >>> x = itertools.count() >>> y = itertools.repeat(3) >>> z = 2*x + y >>> w = itertools.takewhile(lambda pair: pair[0] < 10, enumerate(z)) >>> list(el for idx, el in w) [3, 5, 7, 9, 11, 13, 15, 17, 19, 21]
All operations over Stream objects are lazy and not thread-safe.
See also
thub
- “Tee” hub to help using the Streams like numbers in equations and filters.
tee
- Just like itertools.tee, but returns a tuple of Stream instances.
Stream.tee
- Keeps the Stream usable and returns a copy to be used safely.
Stream.copy
- Same to
Stream.tee
.
In that example, after declaring z as function of x and y, you should not use x and y anymore. Use the thub() or the tee() functions, or perhaps the x.tee() or x.copy() Stream methods instead, if you need to use x again otherwhere.
-
__add__
(other)¶
-
__and__
(other)¶
-
__bool__
()[source]¶ Boolean value of a stream, called by the bool() built-in and by “if” tests. As boolean operators “and”, “or” and “not” couldn’t be overloaded, any trial to cast an instance of this class to a boolean should be seen as a mistake.
-
__call__
(*args, **kwargs)[source]¶ Returns the results from calling elementwise (where each element is assumed to be callable), with the same arguments.
-
__eq__
(other)¶
-
__floordiv__
(other)¶
-
__ge__
(other)¶
-
__getattr__
(name)[source]¶ Returns a Stream of attributes or methods, got in an elementwise fashion.
-
__gt__
(other)¶
-
__ignored_classes__
= (<class 'audiolazy.lazy_filters.LinearFilter'>, <class 'audiolazy.lazy_filters.ZFilter'>, <class 'audiolazy.lazy_filters.CascadeFilter'>, <class 'audiolazy.lazy_filters.ParallelFilter'>)¶
-
__init__
(*dargs)[source]¶ Constructor for a Stream.
Parameters: *dargs – The parameters should be iterables that will be chained together. If they’re not iterables, the stream will be an endless repeat of the given elements. If any parameter is a generator and its contents is used elsewhere, you should use the “tee” (Stream method or itertools function) before.
All operations that works on the elements will work with this iterator in a element-wise fashion (like Numpy 1D arrays). When the stream sizes differ, the resulting stream have the size of the shortest operand.
- Examples:
A finite sequence:
>>> x = Stream([1,2,3]) + Stream([8,5]) # Finite constructor >>> x <audiolazy.lazy_stream.Stream object at 0x...> >>> tuple(x) (9, 7)
But be careful:
>>> x = Stream(1,2,3) + Stream(8,5) # Periodic constructor >>> x <audiolazy.lazy_stream.Stream object at 0x...> >>> x.take(15) # Don't try "tuple" or "list": this Stream is endless! [9, 7, 11, 6, 10, 8, 9, 7, 11, 6, 10, 8, 9, 7, 11]
-
__invert__
()¶
-
__le__
(other)¶
-
__lshift__
(other)¶
-
__lt__
(other)¶
-
__matmul__
(other)¶
-
__mod__
(other)¶
-
__mul__
(other)¶
-
__ne__
(other)¶
-
__neg__
()¶
-
__nonzero__
()¶ Boolean value of a stream, called by the bool() built-in and by “if” tests. As boolean operators “and”, “or” and “not” couldn’t be overloaded, any trial to cast an instance of this class to a boolean should be seen as a mistake.
-
__or__
(other)¶
-
__pos__
()¶
-
__pow__
(other)¶
-
__radd__
(other)¶
-
__rand__
(other)¶
-
__rfloordiv__
(other)¶
-
__rlshift__
(other)¶
-
__rmatmul__
(other)¶
-
__rmod__
(other)¶
-
__rmul__
(other)¶
-
__ror__
(other)¶
-
__rpow__
(other)¶
-
__rrshift__
(other)¶
-
__rshift__
(other)¶
-
__rsub__
(other)¶
-
__rtruediv__
(other)¶
-
__rxor__
(other)¶
-
__sub__
(other)¶
-
__truediv__
(other)¶
-
__xor__
(other)¶
-
append
(*other)[source]¶ Append self with other stream(s). Chaining this way has the behaviour:
self = Stream(self, *others)
-
blocks
(*args, **kwargs)[source]¶ Interface to apply audiolazy.blocks directly in a stream, returning another stream. Use keyword args.
-
copy
()[source]¶ Returns a “T” (tee) copy of the given stream, allowing the calling stream to continue being used.
-
filter
(func)[source]¶ A lazy way to skip elements in the stream that gives False for the given function.
-
map
(func)[source]¶ A lazy way to apply the given function to each element in the stream. Useful for type casting, like:
>>> from audiolazy import count >>> count().take(5) [0, 1, 2, 3, 4] >>> my_stream = count().map(float) >>> my_stream.take(5) # A float counter [0.0, 1.0, 2.0, 3.0, 4.0]
-
peek
(n=None, constructor=<class 'list'>)[source]¶ Sees/peeks the next few items in the Stream, without removing them.
Besides that this functions keeps the Stream items, it’s the same to the
Stream.take()
method.See also
Stream.take
- Returns the n first elements from the Stream, removing them.
Note
When applied in a StreamTeeHub, this method doesn’t consume a copy. Data evaluation is done only once, i.e., after peeking the data is simply stored to be yielded again when asked for.
-
skip
(n)[source]¶ Throws away the first
n
values from the Stream.Note
Performs the evaluation lazily, i.e., the values are thrown away only after requesting the next value.
-
take
(n=None, constructor=<class 'list'>)[source]¶ Returns a container with the n first elements from the Stream, or less if there aren’t enough. Use this without args if you need only one element outside a list.
Parameters: - n – Number of elements to be taken. Defaults to None. Rounded when it’s a float, and this can be
inf
for taking all. - constructor – Container constructor function that can receie a generator as input. Defaults to
list
.
Returns: The first
n
elements of the Stream sequence, created by the given constructor unlessn == None
, which means returns the next element from the sequence outside any container. Ifn
is None, this can raise StopIteration due to lack of data in the Stream. Whenn
is a number, there’s no such exception.- Examples:
>>> Stream(5).take(3) # Three elements [5, 5, 5] >>> Stream(1.2, 2, 3).take() # One element, outside a container 1.2 >>> Stream(1.2, 2, 3).take(1) # With n = 1 argument, it'll be in a list [1.2] >>> Stream(1.2, 2, 3).take(1, constructor=tuple) # Why not a tuple? (1.2,) >>> Stream([1, 2]).take(3) # More than the Stream size, n is integer [1, 2] >>> Stream([]).take() # More than the Stream size, n is None Traceback (most recent call last): ... StopIteration
Taking rounded float quantities and “up to infinity” elements (don’t try using
inf
with endless Stream instances):>>> Stream([4, 3, 2, 3, 2]).take(3.4) [4, 3, 2] >>> Stream([4, 3, 2, 3, 2]).take(3.6) [4, 3, 2, 3] >>> Stream([4, 3, 2, 3, 2]).take(inf) [4, 3, 2, 3, 2]
See also
Stream.peek
- Returns the n first elements from the Stream, without removing them.
Note
You should avoid using take() as if this would be an iterator. Streams are iterables that can be easily part of a “for” loop, and their iterators (the ones automatically used in for loops) are slightly faster. Use iter() builtin if you need that, instead, or perhaps the blocks method.
- n – Number of elements to be taken. Defaults to None. Rounded when it’s a float, and this can be
-
avoid_stream
(cls)[source]¶ Decorator to a class whose instances should avoid casting to a Stream when used with operators applied to them.
-
tostream
(func, module_name=None)[source]¶ Decorator to convert the function output into a Stream. Useful for generator functions.
Note
Always use the
module_name
input when “decorating” a function that was defined in other module.
-
class
ControlStream
(value)[source]¶ Bases:
audiolazy.lazy_stream.Stream
A Stream that yields a control value that can be changed at any time. You just need to set the attribute “value” for doing so, and the next value the Stream will yield is the given value.
- Examples:
>>> cs = ControlStream(7) >>> data = Stream(1, 3) # [1, 3, 1, 3, 1, 3, ...] endless iterable >>> res = data + cs >>> res.take(5) [8, 10, 8, 10, 8] >>> cs.value = 9 >>> res.take(5) [12, 10, 12, 10, 12]
-
__add__
(other)¶
-
__and__
(other)¶
-
__eq__
(other)¶
-
__floordiv__
(other)¶
-
__ge__
(other)¶
-
__gt__
(other)¶
-
__invert__
()¶
-
__le__
(other)¶
-
__lshift__
(other)¶
-
__lt__
(other)¶
-
__matmul__
(other)¶
-
__mod__
(other)¶
-
__mul__
(other)¶
-
__ne__
(other)¶
-
__neg__
()¶
-
__or__
(other)¶
-
__pos__
()¶
-
__pow__
(other)¶
-
__radd__
(other)¶
-
__rand__
(other)¶
-
__rfloordiv__
(other)¶
-
__rlshift__
(other)¶
-
__rmatmul__
(other)¶
-
__rmod__
(other)¶
-
__rmul__
(other)¶
-
__ror__
(other)¶
-
__rpow__
(other)¶
-
__rrshift__
(other)¶
-
__rshift__
(other)¶
-
__rsub__
(other)¶
-
__rtruediv__
(other)¶
-
__rxor__
(other)¶
-
__sub__
(other)¶
-
__truediv__
(other)¶
-
__xor__
(other)¶
-
exception
MemoryLeakWarning
[source]¶ Bases:
Warning
A warning to be used when a memory leak is detected.
-
class
StreamTeeHub
(data, n)[source]¶ Bases:
audiolazy.lazy_stream.Stream
A Stream that returns a different iterator each time it is used.
See also
thub
- Auto-copy “tee hub” and helpful constructor alternative for this class.
-
__add__
(other)¶
-
__and__
(other)¶
-
__eq__
(other)¶
-
__floordiv__
(other)¶
-
__ge__
(other)¶
-
__gt__
(other)¶
-
__invert__
()¶
-
__le__
(other)¶
-
__lshift__
(other)¶
-
__lt__
(other)¶
-
__matmul__
(other)¶
-
__mod__
(other)¶
-
__mul__
(other)¶
-
__ne__
(other)¶
-
__neg__
()¶
-
__or__
(other)¶
-
__pos__
()¶
-
__pow__
(other)¶
-
__radd__
(other)¶
-
__rand__
(other)¶
-
__rfloordiv__
(other)¶
-
__rlshift__
(other)¶
-
__rmatmul__
(other)¶
-
__rmod__
(other)¶
-
__rmul__
(other)¶
-
__ror__
(other)¶
-
__rpow__
(other)¶
-
__rrshift__
(other)¶
-
__rshift__
(other)¶
-
__rsub__
(other)¶
-
__rtruediv__
(other)¶
-
__rxor__
(other)¶
-
__sub__
(other)¶
-
__truediv__
(other)¶
-
__xor__
(other)¶
-
append
(*other)¶ Append self with other stream(s). Chaining this way has the behaviour:
self = Stream(self, *others)
-
copy
()[source]¶ Returns a new “T” (tee) copy of this StreamTeeHub without consuming any of the copies done with the constructor.
-
filter
(func)¶ A lazy way to skip elements in the stream that gives False for the given function.
-
limit
(n)¶ Enforces the Stream to finish after
n
items.
-
map
(func)¶ A lazy way to apply the given function to each element in the stream. Useful for type casting, like:
>>> from audiolazy import count >>> count().take(5) [0, 1, 2, 3, 4] >>> my_stream = count().map(float) >>> my_stream.take(5) # A float counter [0.0, 1.0, 2.0, 3.0, 4.0]
-
skip
(n)¶ Throws away the first
n
values from the Stream.Note
Performs the evaluation lazily, i.e., the values are thrown away only after requesting the next value.
-
take
(*args, **kwargs)[source]¶ Fake function just to avoid using inherited Stream.take implicitly.
Warning
You shouldn’t need to call this method directly. If you need a Stream instance to work progressively changing it, try:
>>> data = thub([1, 2, 3], 2) # A StreamTeeHub instance >>> first_copy = Stream(data) >>> first_copy.take(2) [1, 2] >>> list(data) # Gets the second copy [1, 2, 3] >>> first_copy.take() 3
If you just want to see the first few values, try
self.peek(*args, **kwargs)
instead.>>> data = thub((9, -1, 0, 4), 2) # StreamTeeHub instance >>> data.peek() 9 >>> data.peek(3) [9, -1, 0] >>> list(data) # First copy [9, -1, 0, 4] >>> data.peek(1) [9] >>> second_copy = Stream(data) >>> second_copy.peek(2) [9, -1] >>> data.peek() # There's no third copy Traceback (most recent call last): ... IndexError: StreamTeeHub has no more copies left to use.
If you want to consume from every StreamTeeHub copy, you probably should change your code before calling the
thub()
, but you still might use:>>> data = thub(Stream(1, 2, 3), 2) >>> Stream.take(data, n=2) [1, 2] >>> Stream(data).take() # First copy 3 >>> Stream(data).take(1) # Second copy [3] >>> Stream(data) Traceback (most recent call last): ... IndexError: StreamTeeHub has no more copies left to use.
-
thub
(data, n)[source]¶ Tee or “T” hub auto-copier to help working with Stream instances as well as with numbers.
Parameters: - data – Input to be copied. Can be anything.
- n – Number of copies.
Returns: A StreamTeeHub instance, if input data is iterable. The data itself, otherwise.
- Examples:
>>> def sub_sum(x, y): ... x = thub(x, 2) # Casts to StreamTeeHub, when needed ... y = thub(y, 2) ... return (x - y) / (x + y) # Return type might be number or Stream
With numbers:
>>> sub_sum(1, 1.) 0.0
Combining number with iterable:
>>> sub_sum(3., [1, 2, 3]) <audiolazy.lazy_stream.Stream object at 0x...> >>> list(sub_sum(3., [1, 2, 3])) [0.5, 0.2, 0.0]
Both iterables (the Stream input behaves like an endless [6, 1, 6, 1, ...]):
>>> list(sub_sum([4., 3., 2., 1.], [1, 2, 3])) [0.6, 0.2, -0.2] >>> list(sub_sum([4., 3., 2., 1.], Stream(6, 1))) [-0.2, 0.5, -0.5, 0.0]
This function can also be used as a an alternative to the Stream constructor when your function has only one parameter, to avoid casting when that’s not needed:
>>> func = lambda x: 250 * thub(x, 1) >>> func(1) 250 >>> func([2] * 10) <audiolazy.lazy_stream.Stream object at 0x...> >>> func([2] * 10).take(5) [500, 500, 500, 500, 500]
-
class
Streamix
(keep=False, zero=0.0)[source]¶ Bases:
audiolazy.lazy_stream.Stream
Stream mixer of iterables.
- Examples:
With integer iterables:
>>> s1 = [-1, 1, 3, 2] >>> s2 = Stream([4, 4, 4]) >>> s3 = tuple([-3, -5, -7, -5, -7, -1]) >>> smix = Streamix(zero=0) # Default zero is 0.0, changed to keep integers >>> smix.add(0, s1) # 1st number = delta time (in samples) from last added >>> smix.add(2, s2) >>> smix.add(0, s3) >>> smix <audiolazy.lazy_stream.Streamix object at ...> >>> list(smix) [-1, 1, 4, 1, -3, -5, -7, -1]
With time constants:
>>> from audiolazy import sHz, line >>> s, Hz = sHz(10) # You probably will use 44100 or something alike, not 10 >>> sdata = list(line(2 * s, 1, -1, finish=True)) >>> smix = Streamix() >>> smix.add(0.0 * s, sdata) >>> smix.add(0.5 * s, sdata) >>> smix.add(1.0 * s, sdata) >>> result = [round(sm, 2) for sm in smix] >>> len(result) 35 >>> 0.5 * s # Let's see how many samples this is 5.0 >>> result[:7] [1.0, 0.89, 0.79, 0.68, 0.58, 1.47, 1.26] >>> result[10:17] [0.42, 0.21, 0.0, -0.21, -0.42, 0.37, 0.05] >>> result[-1] -1.0
See also
ControlStream
- Stream (iterable with operators)
sHz
- Time in seconds (s) and frequency in hertz (Hz) constants from sample rate in samples/second.
-
__add__
(other)¶
-
__and__
(other)¶
-
__eq__
(other)¶
-
__floordiv__
(other)¶
-
__ge__
(other)¶
-
__gt__
(other)¶
-
__invert__
()¶
-
__le__
(other)¶
-
__lshift__
(other)¶
-
__lt__
(other)¶
-
__matmul__
(other)¶
-
__mod__
(other)¶
-
__mul__
(other)¶
-
__ne__
(other)¶
-
__neg__
()¶
-
__or__
(other)¶
-
__pos__
()¶
-
__pow__
(other)¶
-
__radd__
(other)¶
-
__rand__
(other)¶
-
__rfloordiv__
(other)¶
-
__rlshift__
(other)¶
-
__rmatmul__
(other)¶
-
__rmod__
(other)¶
-
__rmul__
(other)¶
-
__ror__
(other)¶
-
__rpow__
(other)¶
-
__rrshift__
(other)¶
-
__rshift__
(other)¶
-
__rsub__
(other)¶
-
__rtruediv__
(other)¶
-
__rxor__
(other)¶
-
__sub__
(other)¶
-
__truediv__
(other)¶
-
__xor__
(other)¶
-
add
(delta, data)[source]¶ Adds (enqueues) an iterable event to the mixer.
Parameters: - delta – Time in samples since last added event. This can be zero and can be float. Use “s” object from sHz for time conversion.
- data – Iterable (e.g. a list, a tuple, a Stream) to be “played” by the mixer at the given time delta.
See also
sHz
- Time in seconds (s) and frequency in hertz (Hz) constants from sample rate in samples/second.