def average(source: Observable) -> Observable: """Partially applied average operator. Computes the average of an observable sequence of values that are in the sequence or obtained by invoking a transform function on each element of the input sequence if present. Examples: >>> res = average(source) Args: source: Source observable to average. Returns: An observable sequence containing a single element with the average of the sequence of values. """ if key_mapper: return source.pipe(operators.map(key_mapper), operators.average()) def accumulator(prev, cur): return AverageValue(sum=prev.sum + cur, count=prev.count + 1) def mapper(s): if s.count == 0: raise Exception('The input sequence was empty') return s.sum / float(s.count) seed = AverageValue(sum=0, count=0) return source.pipe(operators.scan(accumulator, seed), operators.last(), operators.map(mapper))
def _to_async_generator(source: Observable): def feeder(): nonlocal future if not notifications or future.done(): return notification = notifications.pop(0) if notification.kind == "E": future.set_exception(notification.exception) elif notification.kind == "C": future.set_result(sentinel) else: future.set_result(notification.value) def on_next(value): """Takes on_next values and appends them to the notification queue""" notifications.append(value) loop.call_soon(feeder) source.pipe(ops.materialize()).subscribe(on_next) @asyncio.coroutine def gen(): """Generator producing futures""" nonlocal future loop.call_soon(feeder) future = Future() return future return gen
def partition(source: Observable) -> List[Observable]: """The partially applied `partition` operator. Returns two observables which partition the observations of the source by the given function. The first will trigger observations for those values for which the predicate returns true. The second will trigger observations for those values where the predicate returns false. The predicate is executed once for each subscribed observer. Both also propagate all error observations arising from the source and each completes when the source completes. Args: source: Source obserable to partition. Returns: A list of observables. The first triggers when the predicate returns True, and the second triggers when the predicate returns False. """ published = source.pipe(ops.publish(), ops.ref_count()) return [ published.pipe(ops.filter(predicate)), published.pipe(ops.filter(lambda x: not predicate(x))) ]
def last(source: Observable) -> Observable: """Partially applied last operator. Returns the last element of an observable sequence that satisfies the condition in the predicate if specified, else the last element. Examples: >>> res = last(source) Args: source: Source observable to get last item from. Returns: An observable sequence containing the last element in the observable sequence that satisfies the condition in the predicate. """ if predicate: return source.pipe( operators.filter(predicate), operators.last() ) return last_or_default_async(source, False)
def some(source: Observable) -> Observable: """Partially applied operator. Determines whether some element of an observable sequence satisfies a condition if present, else if some items are in the sequence. Example: >>> obs = some(source) Args: predicate -- A function to test each element for a condition. Returns: An observable sequence containing a single element determining whether some elements in the source sequence pass the test in the specified predicate if given, else if some items are in the sequence. """ def subscribe(observer, scheduler=None): def on_next(_): observer.on_next(True) observer.on_completed() def on_error(): observer.on_next(False) observer.on_completed() return source.subscribe_(on_next, observer.on_error, on_error, scheduler) if predicate: return source.pipe( ops.filter(predicate), _some(), ) return Observable(subscribe)
def partition(source: Observable) -> List[Observable]: """The partially applied `partition` operator. Returns two observables which partition the observations of the source by the given function. The first will trigger observations for those values for which the predicate returns true. The second will trigger observations for those values where the predicate returns false. The predicate is executed once for each subscribed observer. Both also propagate all error observations arising from the source and each completes when the source completes. Args: source: Source obserable to partition. Returns: A list of observables. The first triggers when the predicate returns True, and the second triggers when the predicate returns False. """ published = source.pipe( ops.publish(), ops.ref_count() ) return [ published.pipe(ops.filter(predicate)), published.pipe(ops.filter(lambda x: not predicate(x))) ]
def slice(source: Observable) -> Observable: """The partially applied slice operator. Slices the given observable. It is basically a wrapper around the operators :func:`skip <rx.operators.skip>`, :func:`skip_last <rx.operators.skip_last>`, :func:`take <rx.operators.take>`, :func:`take_last <rx.operators.take_last>` and :func:`filter <rx.operators.filter>`. The following diagram helps you remember how slices works with streams. Positive numbers are relative to the start of the events, while negative numbers are relative to the end (close) of the stream. .. code:: r---e---a---c---t---i---v---e---! 0 1 2 3 4 5 6 7 8 -8 -7 -6 -5 -4 -3 -2 -1 0 Examples: >>> result = source.slice(1, 10) >>> result = source.slice(1, -2) >>> result = source.slice(1, -1, 2) Args: source: Observable to slice Returns: A sliced observable sequence. """ if has_stop and _stop >= 0: pipeline.append(ops.take(_stop)) if has_start and _start > 0: pipeline.append(ops.skip(_start)) if has_start and _start < 0: pipeline.append(ops.take_last(abs(_start))) if has_stop and _stop < 0: pipeline.append(ops.skip_last(abs(_stop))) if has_step: if _step > 1: pipeline.append( ops.filter_indexed(lambda x, i: i % _step == 0)) elif _step < 0: # Reversing events is not supported raise TypeError('Negative step not supported.') return source.pipe(*pipeline)
def buffer_with_count(source: Observable) -> Observable: nonlocal skip if skip is None: skip = count def mapper(value): return value.pipe(ops.to_iterable(), ops.map(list)) def predicate(value): return len(value) > 0 return source.pipe(ops.window_with_count(count, skip), ops.flat_map(mapper), ops.filter(predicate))
def average(source: Observable) -> Observable: """Partially applied average operator. Computes the average of an observable sequence of values that are in the sequence or obtained by invoking a transform function on each element of the input sequence if present. Examples: >>> res = average(source) Args: source: Source observable to average. Returns: An observable sequence containing a single element with the average of the sequence of values. """ if key_mapper: return source.pipe( operators.map(key_mapper), operators.average() ) def accumulator(prev, cur): return AverageValue(sum=prev.sum+cur, count=prev.count+1) def mapper(s): if s.count == 0: raise Exception('The input sequence was empty') return s.sum / float(s.count) seed = AverageValue(sum=0, count=0) return source.pipe( operators.scan(accumulator, seed), operators.last(), operators.map(mapper) )
def slice(source: Observable) -> Observable: """The partially applied slice operator. Slices the given observable. It is basically a wrapper around the operators skip(), skip_last(), take(), take_last() and filter(). This marble diagram helps you remember how slices works with streams. Positive numbers is relative to the start of the events, while negative numbers are relative to the end (close) of the stream. r---e---a---c---t---i---v---e---| 0 1 2 3 4 5 6 7 8 -8 -7 -6 -5 -4 -3 -2 -1 0 Examples: >>> result = source.slice(1, 10) >>> result = source.slice(1, -2) >>> result = source.slice(1, -1, 2) Args: source: Observable to slice Returns: A sliced observable sequence. """ if has_stop and stop >= 0: pipeline.append(ops.take(stop)) if has_start and start > 0: pipeline.append(ops.skip(start)) if has_start and start < 0: pipeline.append(ops.take_last(abs(start))) if has_stop and stop < 0: pipeline.append(ops.skip_last(abs(stop))) if has_step: if step > 1: pipeline.append(ops.filter_indexed(lambda x, i: i % step == 0)) elif step < 0: # Reversing events is not supported raise TypeError("Negative step not supported.") return source.pipe(*pipeline)
def delay_subscription(source: Observable) -> Observable: """Time shifts the observable sequence by delaying the subscription. Exampeles. >>> res = source.delay_subscription(5) Args: source: Source subscription to delay. Returns: Time-shifted sequence. """ def mapper(_) -> Observable: return rx.empty() return source.pipe( ops.delay_with_mapper(rx.timer(duetime, scheduler=scheduler), mapper))
def delay_subscription(source: Observable) -> Observable: """Time shifts the observable sequence by delaying the subscription. Exampeles. >>> res = source.delay_subscription(5) Args: source: Source subscription to delay. Returns: Time-shifted sequence. """ def mapper(_) -> Observable: return rx.empty() return source.pipe( ops.delay_with_mapper(rx.timer(duetime, scheduler=scheduler), mapper) )
def flat_map_latest(source: Observable) -> Observable: """Projects each element of an observable sequence into a new sequence of observable sequences by incorporating the element's index and then transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence. Args: source: Source observable to flat map latest. Returns: An observable sequence whose elements are the result of invoking the transform function on each element of source producing an observable of Observable sequences and that at any point in time produces the elements of the most recent inner observable sequence that has been received. """ return source.pipe(ops.map(mapper), ops.switch_latest())
def last_or_default(source: Observable) -> Observable: """Return last or default element. Examples: >>> res = _last_or_default(source) Args: source: Observable sequence to get the last item from. Returns: Observable sequence containing the last element in the observable sequence. """ if predicate: return source.pipe( ops.filter(predicate), ops.last_or_default(None, default_value), ) return last_or_default_async(source, True, default_value)
def flat_map_latest(source: Observable) -> Observable: """Projects each element of an observable sequence into a new sequence of observable sequences by incorporating the element's index and then transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence. Args: source: Source observable to flat map latest. Returns: An observable sequence whose elements are the result of invoking the transform function on each element of source producing an observable of Observable sequences and that at any point in time produces the elements of the most recent inner observable sequence that has been received. """ return source.pipe( ops.map(mapper), ops.switch_latest() )
def throw_when(errors: Observable) -> Callable[[Observable], Observable]: return rx.pipe(merge(errors.pipe(flat_map(lambda e: throw(e)))))
def main(): xs = Observable.pipe(range) xs.subscribe(MyObserver)
def do_while(source: Observable) -> Observable: return source.pipe(ops.concat(source.pipe(ops.while_do(condition))))