Skip to content

Commit 83ba6a5

Browse files
committed
fix covid_hosp bool parsing
- `bool('false')` is `True` - add a helper function to parse bool from str, allowing missing and empty values note that prod database needs to be backfilled since previous acquisitions incorrectly casted 'false' and 'true' both to `True`
1 parent a512d03 commit 83ba6a5

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

src/acquisition/covid_hosp/common/utils.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,36 @@ def int_from_date(date):
3737

3838
return int(date.replace('-', ''))
3939

40+
def parse_bool(value):
41+
"""Convert a string to a boolean.
42+
43+
Parameters
44+
----------
45+
value : str
46+
Boolean-like value, like "true" or "false".
47+
48+
Returns
49+
-------
50+
bool
51+
If the string contains some version of "true" or "false".
52+
None
53+
If the string is None or empty.
54+
55+
Raises
56+
------
57+
CovidHospException
58+
If the string constains something other than a version of "true" or
59+
"false".
60+
"""
61+
62+
if not value:
63+
return None
64+
if value.lower() == 'true':
65+
return True
66+
if value.lower() == 'false':
67+
return False
68+
raise CovidHospException(f'cannot convert "{value}" to bool')
69+
4070
def get_entry(obj, *path):
4171
"""Get a deeply nested field from an arbitrary object.
4272

src/acquisition/covid_hosp/facility/database.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class Database(BaseDatabase):
2323
('zip', str),
2424
('hospital_subtype', str),
2525
('fips_code', str),
26-
('is_metro_micro', bool),
26+
('is_metro_micro', Utils.parse_bool),
2727
('total_beds_7_day_avg', float),
2828
('all_adult_hospital_beds_7_day_avg', float),
2929
('all_adult_hospital_inpatient_beds_7_day_avg', float),

tests/acquisition/covid_hosp/common/test_utils.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,29 @@ def test_int_from_date(self):
4343

4444
self.assertEqual(Utils.int_from_date('2020-11-17'), 20201117)
4545

46+
def test_parse_bool(self):
47+
"""Parse a boolean value from a string."""
48+
49+
with self.subTest(name='None'):
50+
self.assertIsNone(Utils.parse_bool(None))
51+
52+
with self.subTest(name='empty'):
53+
self.assertIsNone(Utils.parse_bool(''))
54+
55+
with self.subTest(name='true'):
56+
self.assertTrue(Utils.parse_bool('true'))
57+
self.assertTrue(Utils.parse_bool('True'))
58+
self.assertTrue(Utils.parse_bool('tRuE'))
59+
60+
with self.subTest(name='false'):
61+
self.assertFalse(Utils.parse_bool('false'))
62+
self.assertFalse(Utils.parse_bool('False'))
63+
self.assertFalse(Utils.parse_bool('fAlSe'))
64+
65+
with self.subTest(name='exception'):
66+
with self.assertRaises(CovidHospException):
67+
Utils.parse_bool('maybe')
68+
4669
def test_get_entry_success(self):
4770
"""Get a deeply nested field from an arbitrary object."""
4871

0 commit comments

Comments
 (0)