A date is un-ambiguous when each number may be decided to be day or month or year given the range limitation of these numbers.
For example
- \$14\$ cannot be a month number
- \$2008\$ cannot be a day number
@param un_ambiguous_date
: an un-ambiguous scrambled date,
of the format X/Y/Z where X, Y, Z correspond to
day, month, year but not necessarily in this order.
@return The date in the order 'DAY/MONTH/YEAR'.
I am particularly interested in full input validation and nice error producing, so tell me any lack of clarity/corner case missed.
For example usage see the doctests included with the function:
def order_date(un_ambiguous_date):
"""
@param un_ambiguous_date: an un-ambiguous scrambled date,
of the format X/Y/Z where X, Y, Z correspond to
day, month, year but not necessarily in this order.
@return: The date in the order 'DAY/MONTH/YEAR'.
A date is un-ambiguous when each number may be
decided to be day or month or year given the range
limitation of this numbers.
(For example 14 cannot be a month number, and
2008 cannot be a day number)
>>> order_date('3/2015/13')
'13/3/2015'
>>> order_date('2012/20/4')
'20/4/2012'
# Here both 3/4/1000 and 4/3/1000 are possible.
>>> order_date('3/4/1000')
Traceback (most recent call last):
...
ValueError: Ambiguous date was given
>>> order_date('3/3/2050')
'3/3/2050'
>>> order_date('1/1/1')
Traceback (most recent call last):
...
ValueError: The date cannot be valid
>>> order_date('12/6')
Traceback (most recent call last):
...
ValueError: The date is too short, format should be X/Y/Z
>>> order_date('2000/2000')
Traceback (most recent call last):
...
ValueError: The date is too short, format should be X/Y/Z
>>> order_date('Foo/Bar/Baz')
Traceback (most recent call last):
...
TypeError: The date should be made up of '/' separated INTEGERS
"""
try:
x, y, z = un_ambiguous_date.split('/')
except ValueError:
raise ValueError("The date is too short, format should be X/Y/Z")
try:
x, y, z = map(int, (x, y, z))
except ValueError:
raise TypeError("The date should be made up of '/' separated INTEGERS")
day = [i for i in (x,y,z) if i < 31]
month = list(set(i for i in (x,y,z) if i < 12))
year = [i for i in (x,y,z) if i > 31]
day = list(set(day) - set(month))
if not day:
day = month
# print(day, month, year)
if any(len(x) > 1 for x in (day, month, year)):
raise ValueError("Ambiguous date was given")
try:
return '/'.join(map(str, (day[0], month[0], year[0])))
except IndexError:
raise ValueError("The date cannot be valid")
20
anyways, which renders the problem even worse. \$\endgroup\$un_ambiguous_word
instead ofunambiguous_word
was sort of odd for me... \$\endgroup\$