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")
20anyways, which renders the problem even worse. \$\endgroup\$un_ambiguous_wordinstead ofunambiguous_wordwas sort of odd for me... \$\endgroup\$