import abc
import numpy as np
from abc import ABC, abstractmethod
from typing import Any, Callable, Iterable, Sequence, Union

PropertySequence = Union[Sequence[LikeProperty], np.ndarray]

class Operation(ABC, metaclass=abc.ABCMeta):
    def __call__(self, **params) -> Callable: ...
    @abstractmethod
    def operation(self, obj, **params) -> Any: ...

class Property(ABC, metaclass=abc.ABCMeta):
    @abstractmethod
    def get(self) -> Any: ...
    @property
    def value(self) -> Any: ...
    def transform(self, operation: Operation, **kwargs) -> Property: ...

class Constant(Property):
    def __init__(self, value) -> None: ...
    def get(self) -> Any: ...

class Source(Property):
    def __init__(self, fn: Callable, *args, **kwargs) -> None: ...
    def get(self) -> Any: ...

class Convert(Source):
    def __init__(self, p: LikeProperty, fn: Callable, *args, **kwargs) -> None: ...
    def get(self) -> Any: ...

class Iter(Property):
    def __init__(self, seq: Iterable) -> None: ...
    def get(self) -> Any: ...

class RandomUniform(Property):
    def __init__(self, low: float = ..., high: float = ...) -> None: ...
    def get(self): ...

class RandomChoice(Property):
    def __init__(self, items) -> None: ...
    def get(self): ...

class Transformer:
    def __init__(self, *operations: Operation) -> None: ...
    def __call__(self, instance: Property) -> Property: ...
