Skip to content

Commit

Permalink
refactor utils, add test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
victorlin committed Aug 16, 2021
1 parent a910497 commit 1162cac
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 37 deletions.
67 changes: 35 additions & 32 deletions augur/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,10 @@ def get_numerical_date_from_value(value, fmt=None, min_max_year=None, raise_erro
return [None, None] #don't send to numeric_date or will be set to today
else:
return [numeric_date(d) for d in ambig_date]
try:
return float(value)
except ValueError:
pass
try:
return numeric_date(datetime.datetime.strptime(value, fmt))
except:
pass
return None
return None

def get_numerical_dates(meta_dict, name_col = None, date_col='date', fmt=None, min_max_year=None):
if fmt:
Expand Down Expand Up @@ -174,45 +169,48 @@ def get_numerical_dates(meta_dict, name_col = None, date_col='date', fmt=None, m


def to_numeric_date_min(date):
return to_numeric_date(date, ambiguity_resolver='min')
return to_numeric_date(date, ambiguity_resolver="min")


def to_numeric_date_max(date):
return to_numeric_date(date, ambiguity_resolver='max')
return to_numeric_date(date, ambiguity_resolver="max")


def to_numeric_date(date, ambiguity_resolver='min'):
def to_numeric_date(date, ambiguity_resolver="min"):
"""Return numeric date from string, [incomplete] ISO date string, or datetime.date object.
Parameters
----------
date : str | datetime.date
ambiguity_resolver : str
'min' or 'max'
"min" or "max"
Raises
------
ValueError
If date is unparsable or ambiguity_resolver is not set properly.
Returns
-------
float
"""
if ambiguity_resolver not in {'min', 'max'}:
raise ValueError()

if type(date) is str:
if '.' in date:
return float(date)
else:
ambiguous_date = generate_ambiguous_date(date)
ambiguous_date_resolved = get_numerical_date_from_value(ambiguous_date, "%Y-%m-%d")
if type(ambiguous_date_resolved) is float:
return ambiguous_date_resolved
if type(ambiguous_date_resolved) is list:
if ambiguity_resolver == 'min':
return ambiguous_date_resolved[0]
if ambiguity_resolver == 'max':
return ambiguous_date_resolved[1]
if type(date) is datetime.date:
return numeric_date(date)
raise ValueError()
if type(date) is str and "." in date:
return float(date)
if type(date) is str:
if ambiguity_resolver not in {"min", "max"}:
raise ValueError("Ambiguous date range must be resolved by taking either min or max date.")
ambiguous_date_str = generate_ambiguous_date_str(date)
ambiguous_date_resolved = get_numerical_date_from_value(ambiguous_date_str, "%Y-%m-%d")
if type(ambiguous_date_resolved) is float:
return ambiguous_date_resolved
if type(ambiguous_date_resolved) is list:
if ambiguity_resolver == "min":
return ambiguous_date_resolved[0]
if ambiguity_resolver == "max":
return ambiguous_date_resolved[1]
raise ValueError(f"Unparsable date value: {date!r}")


def numeric_date_to_iso(numeric_date):
Expand All @@ -229,27 +227,32 @@ def numeric_date_to_iso(numeric_date):
return datetime_from_numeric(numeric_date).date()


def generate_ambiguous_date(date_str):
def generate_ambiguous_date_str(date_str):
"""Return ambiguous date (YYYY-MM-DD) from incomplete ISO date string.
Parameters
----------
date_str : str
ISO date string that can be incomplete (e.g. 2019, 2019-04, 2019-04-11)
Raises
------
ValueError
If date_str is unparsable.
Returns
-------
str
pad XX for month and/or day if missing
"""
parts = date_str.split('-')
parts = date_str.split("-")
if len(parts) == 3:
return date_str
if len(parts) == 2:
return f'{date_str}-XX'
return f"{date_str}-XX"
if len(parts) == 1:
return f'{date_str}-XX-XX'
raise ValueError()
return f"{date_str}-XX-XX"
raise ValueError(f"Unparsable date value: {date_str!r}")


class InvalidTreeError(Exception):
Expand Down
12 changes: 7 additions & 5 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ def test_to_numeric_date(self):
assert round(utils.to_numeric_date(datetime.date(2019, 4, 11)), 8) == 2019.27534247
with pytest.raises(ValueError):
utils.to_numeric_date(False)
with pytest.raises(ValueError):
utils.to_numeric_date("2019", ambiguity_resolver="invalid")

def test_to_numeric_date_ambiguity(self):
assert utils.to_numeric_date_min("2019") == utils.to_numeric_date("2019-01-01")
Expand All @@ -151,12 +153,12 @@ def test_numeric_iso_conversion(self):
iso = utils.numeric_date_to_iso(numeric_date)
assert str(iso) == orig_date

def test_generate_ambiguous_date(self):
assert str(utils.generate_ambiguous_date("2019")) == "2019-XX-XX"
assert str(utils.generate_ambiguous_date("2019-04")) == "2019-04-XX"
assert str(utils.generate_ambiguous_date("2019-04-11")) == "2019-04-11"
def test_generate_ambiguous_date_str(self):
assert str(utils.generate_ambiguous_date_str("2019")) == "2019-XX-XX"
assert str(utils.generate_ambiguous_date_str("2019-04")) == "2019-04-XX"
assert str(utils.generate_ambiguous_date_str("2019-04-11")) == "2019-04-11"
with pytest.raises(ValueError):
utils.generate_ambiguous_date("2019-04-11-invalid")
utils.generate_ambiguous_date_str("2019-04-11-invalid")

def test_read_strains(self, tmpdir):
# Write one list of filenames with some unnecessary whitespace.
Expand Down

0 comments on commit 1162cac

Please sign in to comment.