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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
import random
from ricky.param import Param
DEFAULT_RAND_MAX = 1000
DEFAULT_RAND_MIN = -1000
class ConstrainedNumber(Param):
def __init__(self, **kwargs):
self.range_min = kwargs.get('min', DEFAULT_RAND_MIN)
self.range_max = kwargs.get('max', DEFAULT_RAND_MAX)
self.forbidden = kwargs.get('forbidden')
self.forbidden_range_min = kwargs.get('forbidden_range_min')
self.forbidden_range_max = kwargs.get('forbidden_range_max')
self.enforce_int = kwargs.get('enforce_int')
self.prec = kwargs.get('prec')
if "default" not in kwargs:
self.randomize()
kwargs["default"] = self._value
super(ConstrainedNumber, self).__init__(**kwargs)
@property
def value(self):
return super(ConstrainedNumber, self).value_get()
@value.setter
def value(self, value):
if value is not None and (
value < self.range_min or
value > self.range_max
):
raise ValueError(
"Value must be between %s and %s\n" % (
self.range_min, self.range_max
)
)
if value == self.forbidden:
raise ValueError(
"Value %s is forbidden" % value
)
if (self.forbidden_range_max or self.forbidden_range_max == 0) and \
self.forbidden_range_max >= value:
raise ValueError(
"In forbidden range: Value %s is below %s" %
(value, self.forbidden_range_max)
)
if (self.forbidden_range_min or self.forbidden_range_min == 0) and \
self.forbidden_range_min <= value:
raise ValueError(
"In forbidden range: Value %s is above %s" %
(value, self.forbidden_range_min)
)
if self.enforce_int and type(value) != int:
raise ValueError(
"Value %s is not an int" % value
)
self._value = value
def __str__(self):
value_dict = {
'value': self._value,
}
for attr in (
'range_min', 'range_max', 'forbidden', 'forbidden_range_min',
'forbidden_range_max', 'enforce_int'
):
attr_val = getattr(self, attr)
if attr_val or attr_val == 0:
value_dict[attr] = attr_val
return "Constrained Number Range \"%s\":\n %s" % (self.name, value_dict)
def _generate_random(self):
value = random.uniform(self.range_min, self.range_max)
if self.prec:
value = round(value, self.prec)
if self.enforce_int:
value = int(value)
self.value = value
def randomize(self):
tries = 0
tries_max = 30
try:
self._generate_random()
except ValueError:
tries += 1
if tries < tries_max:
self._generate_random()
else:
raise ValueError(
"Unable to set random value on %s in %s tries"
) % (self.name, self.tries_max)
|