Skip to content

Commit

Permalink
Merge pull request #86 from lhuggett/smallest_property
Browse files Browse the repository at this point in the history
Smallest property
  • Loading branch information
matthewrmshin authored Sep 11, 2018
2 parents 5daa363 + 71c0753 commit 61fac8d
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 1 deletion.
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ below:
* Oliver Sanders (Met Office, UK)
* Matt Shin (Met Office, UK)
* Hilary Oliver (NIWA, NZ)
* Lois Huggett (Met Office, UK)

(All contributors are identifiable with email addresses in the version control
logs or otherwise.)
Expand Down
28 changes: 28 additions & 0 deletions isodatetime/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,8 @@ def get(self, property_name):
return self.get_week_date()[2]
if property_name == "year_of_decade":
return abs(self.year) % 10
if property_name == "decade_of_century":
return (abs(self.year) % 100 - abs(self.year) % 10) / 10
if property_name == "minute_of_hour":
if self.minute_of_hour is None:
return self.get_hour_minute_second()[1]
Expand Down Expand Up @@ -1111,6 +1113,32 @@ def get_largest_truncated_property_name(self):
return attr
return None

def get_smallest_missing_property_name(self):
"""Return the smallest unit missing
from a truncated representation."""
if not self.truncated:
return None
prop_dict = self.get_truncated_properties()
attr_keys = ["year_of_century", "decade_of_century",
"year_of_decade", "month_of_year",
"week_of_year", "day_of_year", "day_of_month",
"day_of_week", "hour_of_day", "minute_of_hour",
"second_of_minute"]
attr_dict = {"year_of_century": "century",
"year_of_decade": "decade_of_century",
"month_of_year": "year_of_century",
"week_of_year": "year_of_century",
"day_of_year": "year_of_century",
"day_of_month": "month_of_year",
"day_of_week": "week_of_year",
"hour_of_day": "day_of_month",
"minute_of_hour": "hour_of_day",
"second_of_minute": "minute_of_hour"}
for attr in attr_keys:
if attr in prop_dict:
return attr_dict[attr]
return None

def get_truncated_properties(self):
"""Return a map of properties if this is a truncated representation."""
if not self.truncated:
Expand Down
131 changes: 130 additions & 1 deletion isodatetime/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,96 @@ def get_timepointparser_tests(allow_only_basic=False,
yield tz_expr, tz_info


def get_truncated_property_tests():
"""
Tests for largest truncated and
smallest missing property names
"""
test_timepoints = {
"-9001": {"year": 90,
"month_of_year": 1,
"largest_truncated_property_name": "year_of_century",
"smallest_missing_property_name": "century"},
"20960328": {"year": 96,
"month_of_year": 3,
"day_of_month": 28,
"largest_truncated_property_name": None,
"smallest_missing_property_name": None},
"-90": {"year": 90,
"largest_truncated_property_name": "year_of_century",
"smallest_missing_property_name": "century"},
"--0501": {"month_of_year": 5, "day_of_month": 1,
"largest_truncated_property_name": "month_of_year",
"smallest_missing_property_name": "year_of_century"},
"--12": {"month_of_year": 12,
"largest_truncated_property_name": "month_of_year",
"smallest_missing_property_name": "year_of_century"},
"---30": {"day_of_month": 30,
"largest_truncated_property_name": "day_of_month",
"smallest_missing_property_name": "month_of_year"},
"98354": {"year": 98,
"day_of_year": 354,
"largest_truncated_property_name": "year_of_century",
"smallest_missing_property_name": "century"},
"-034": {"day_of_year": 34,
"largest_truncated_property_name": "day_of_year",
"smallest_missing_property_name": "year_of_century"},
"00W031": {"year": 0,
"week_of_year": 3,
"day_of_week": 1,
"largest_truncated_property_name": "year_of_century",
"smallest_missing_property_name": "century"},
"99W34": {"year": 99,
"week_of_year": 34,
"largest_truncated_property_name": "year_of_century",
"smallest_missing_property_name": "century"},
"-1W02": {"year": 1,
"week_of_year": 2,
"largest_truncated_property_name": "year_of_decade",
"smallest_missing_property_name": "decade_of_century"},
"-W031": {"week_of_year": 3,
"day_of_week": 1,
"largest_truncated_property_name": "week_of_year",
"smallest_missing_property_name": "year_of_century"},
"-W32": {"week_of_year": 32,
"largest_truncated_property_name": "week_of_year",
"smallest_missing_property_name": "year_of_century"},
"-W-1": {"day_of_week": 1,
"largest_truncated_property_name": "day_of_week",
"smallest_missing_property_name": "week_of_year"},
"T04:30": {"hour_of_day": 4,
"minute_of_hour": 30,
"largest_truncated_property_name": "hour_of_day",
"smallest_missing_property_name": "day_of_month"},
"T19": {"hour_of_day": 19,
"largest_truncated_property_name": "hour_of_day",
"smallest_missing_property_name": "day_of_month"},
"T-56:12": {"minute_of_hour": 56,
"second_of_minute": 12,
"largest_truncated_property_name": "minute_of_hour",
"smallest_missing_property_name": "hour_of_day"},
"T-12": {"minute_of_hour": 12,
"largest_truncated_property_name": "minute_of_hour",
"smallest_missing_property_name": "hour_of_day"},
"T--45": {"second_of_minute": 45,
"largest_truncated_property_name": "second_of_minute",
"smallest_missing_property_name": "minute_of_hour"},
"T-12:34.45": {"minute_of_hour": 12,
"second_of_minute": 34,
"second_of_minute_decimal": 0.45,
"largest_truncated_property_name": "minute_of_hour",
"smallest_missing_property_name": "hour_of_day"},
"T-34,2": {"minute_of_hour": 34,
"minute_of_hour_decimal": 0.2,
"largest_truncated_property_name": "minute_of_hour",
"smallest_missing_property_name": "hour_of_day"},
"T--59.99": {"second_of_minute": 59,
"second_of_minute_decimal": 0.99,
"largest_truncated_property_name": "second_of_minute",
"smallest_missing_property_name": "minute_of_hour"}}
return test_timepoints


def get_timepoint_subtract_tests():
"""Yield tests for subtracting one timepoint from another."""
return [
Expand Down Expand Up @@ -925,7 +1015,6 @@ def get_local_time_zone_hours_minutes():


class TestSuite(unittest.TestCase):

"""Test the functionality of parsers and data model manipulation."""

def assertEqual(self, test, control, info=None):
Expand All @@ -951,6 +1040,46 @@ def test_days_in_year_range(self):
start_year, end_year)
)

def test_largest_truncated_property_name(self):
"""Test the largest truncated property name."""

parser = parsers.TimePointParser(
allow_truncated=True)

truncated_property_tests = get_truncated_property_tests()
for expression in truncated_property_tests.keys():
try:
test_data = parser.parse(expression)
except parsers.ISO8601SyntaxError as syn_exc:
raise ValueError("Parsing failed for {0}: {1}".format(
expression, syn_exc))

self.assertEqual(
test_data.get_largest_truncated_property_name(),
truncated_property_tests[expression]
["largest_truncated_property_name"],
info=expression)

def test_smallest_missing_property_name(self):
"""Test the smallest missing property name."""

parser = parsers.TimePointParser(
allow_truncated=True)

truncated_property_tests = get_truncated_property_tests()
for expression in truncated_property_tests.keys():
try:
test_data = parser.parse(expression)
except parsers.ISO8601SyntaxError as syn_exc:
raise ValueError("Parsing failed for {0}: {1}".format(
expression, syn_exc))

self.assertEqual(
test_data.get_smallest_missing_property_name(),
truncated_property_tests[expression]
["smallest_missing_property_name"],
info=expression)

def test_timeduration(self):
"""Test the duration class methods."""
for test_props, method, method_args, ctrl_results in (
Expand Down

0 comments on commit 61fac8d

Please sign in to comment.