File size: 2,051 Bytes
eb3f5d1
128b1df
d389578
6754ccb
d389578
c8ed6c2
 
128b1df
eb3f5d1
6754ccb
 
 
128b1df
 
d389578
128b1df
 
a2d02fa
 
6754ccb
d389578
 
 
 
6754ccb
 
128b1df
6754ccb
e3813ff
 
 
7c32c70
 
 
 
 
 
 
 
 
d389578
 
 
6754ccb
 
128b1df
6754ccb
d389578
 
 
6754ccb
 
 
 
 
7c32c70
 
a2d02fa
 
 
 
 
7c32c70
6754ccb
 
 
eb3f5d1
 
 
 
6754ccb
 
eb3f5d1
a2d02fa
eb3f5d1
a2d02fa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import random
import typing
from abc import abstractmethod
from dataclasses import field
from typing import Any, Dict, Hashable, List

from .artifact import Artifact
from .dataclass import AbstractField
from .random_utils import new_random_generator


class Collection(Artifact):
    items: typing.Collection = AbstractField()

    def __getitem__(self, key: Hashable) -> Any:
        try:
            return self.items[key]
        except LookupError as e:
            raise LookupError(f"Cannot find item {key!r} in {self!r}") from e

    @abstractmethod
    def keys(self) -> List[Hashable]:
        pass


class ListCollection(Collection):
    items: List[Artifact] = field(default_factory=list)

    def __len__(self):
        return len(self.items)

    def append(self, item):
        self.items.append(item)

    def extend(self, other):
        self.items.extend(other.items)

    def __add__(self, other):
        return ListCollection(self.items.__add__(other.items))

    def keys(self) -> List[int]:
        return list(range(len(self)))


class DictCollection(Collection):
    items: Dict[str, Artifact] = field(default_factory=dict)

    def keys(self) -> List[Hashable]:
        return list(self.items.keys())


class ItemPicker(Artifact):
    item: object = None

    def __call__(self, collection: Collection):
        try:
            return collection[int(self.item)]
        except (
            SyntaxError,
            KeyError,
            ValueError,
        ):  # in case picking from a dictionary
            return collection[self.item]


class RandomPicker(Artifact):
    random_generator: random.Random = field(
        default_factory=lambda: new_random_generator(sub_seed="random_picker")
    )

    def __call__(self, collection: Collection):
        if isinstance(collection, ListCollection):
            return self.random_generator.choice(list(collection.items))
        if isinstance(collection, DictCollection):
            return self.random_generator.choice(list(collection.items.values()))
        return None