Skip to content

Commit 18c4335

Browse files
Optional validators and date validators
1 parent 3ceb016 commit 18c4335

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

src/penn_chime/parameters.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
from datetime import date
99
from typing import Optional
1010

11-
from .validators import Positive, StrictlyPositive, Rate
11+
from .validators import (
12+
Positive, OptionalStrictlyPositive, StrictlyPositive, Rate, Date, OptionalDate
13+
)
1214

1315
# Parameters for each disposition (hospitalized, icu, ventilated)
1416
# The rate of disposition within the population of infected
@@ -85,14 +87,14 @@ def __init__(
8587
else:
8688
raise AssertionError('population or regions must be provided.')
8789

88-
self.current_date = current_date
90+
self.current_date = Date(value=current_date)
8991

90-
self.date_first_hospitalized = date_first_hospitalized
92+
self.date_first_hospitalized = OptionalDate(value=date_first_hospitalized)
9193
self.doubling_time = doubling_time
9294

9395
self.infectious_days = StrictlyPositive(value=infectious_days)
9496
self.market_share = Rate(value=market_share)
95-
self.max_y_axis = max_y_axis
97+
self.max_y_axis = OptionalStrictlyPositive(value=max_y_axis)
9698
self.n_days = StrictlyPositive(value=n_days)
9799
self.recovered = Positive(value=recovered)
98100

src/penn_chime/validators/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
"""the callable validator design pattern"""
22

3-
from .validators import Bounded, Rate
3+
from .validators import Bounded, OptionalBounded, Rate, Date, OptionalDate
44

55
EPSILON = 1.e-7
66

7+
OptionalStrictlyPositive = OptionalBounded(lower_bound=EPSILON)
78
StrictlyPositive = Bounded(lower_bound=EPSILON)
89
Positive = Bounded(lower_bound=-EPSILON)
910
Rate = Rate() # type: ignore
11+
Date = Date() # type: ignore
12+
OptionalDate = OptionalDate() # type: ignore

src/penn_chime/validators/validators.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
"""design pattern via https://youtu.be/S_ipdVNSFlo?t=2153"""
22

33
from typing import Optional
4+
from datetime import date, datetime
45

56
from .base import Validator
67

78

89
class Bounded(Validator):
9-
10+
"""A bounded number."""
1011
def __init__(
1112
self,
1213
lower_bound: Optional[float] = None,
@@ -21,16 +22,48 @@ def __init__(
2122
}
2223

2324
def validate(self, value):
25+
"""This method implicitly validates isinstance(value, (float, int)) because it will throw a TypeError on comparison"""
2426
if (self.upper_bound is not None and value > self.upper_bound) \
2527
or (self.lower_bound is not None and value < self.lower_bound):
2628
raise ValueError(f"{value} needs to be {self.message[(self.lower_bound, self.upper_bound)]}.")
2729

2830

31+
class OptionalBounded(Bounded):
32+
"""a bounded number or a None."""
33+
def __init__(
34+
self,
35+
lower_bound: Optional[float] = None,
36+
upper_bound: Optional[float] = None) -> None:
37+
super().__init__(lower_bound=lower_bound, upper_bound=upper_bound)
38+
39+
def validate(self, value):
40+
if value is None:
41+
return None
42+
super().validate(value)
43+
2944
class Rate(Validator):
45+
"""A rate in [0,1]."""
3046
def __init__(self) -> None:
3147
pass
3248

3349
def validate(self, value):
3450
if 0 >= value or value >= 1:
35-
raise ValueError(f"{value} needs to be a rate (i.e. in [0,1])")
51+
raise ValueError(f"{value} needs to be a rate (i.e. in [0,1]).")
3652

53+
class Date(Validator):
54+
"""A date of some sort."""
55+
def __init__(self) -> None:
56+
pass
57+
58+
def validate(self, value):
59+
if not isinstance(value, (date, datetime)):
60+
raise (ValueError(f"{value} must be a date or datetime object."))
61+
62+
class OptionalDate(Date):
63+
def __init__(self) -> None:
64+
super().__init__()
65+
66+
def validate(self, value):
67+
if value is None:
68+
return None
69+
super().validate(value)

0 commit comments

Comments
 (0)