From 97e9b7cf36c8f14ff4ee8a97ae86616ffd398df2 Mon Sep 17 00:00:00 2001 From: "Marvin M. Michum" Date: Sat, 3 Aug 2019 18:11:41 -0400 Subject: [PATCH 1/4] doctest updates --- maths/zellers_congruence.py | 137 ++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 maths/zellers_congruence.py diff --git a/maths/zellers_congruence.py b/maths/zellers_congruence.py new file mode 100644 index 000000000000..36ce115bedce --- /dev/null +++ b/maths/zellers_congruence.py @@ -0,0 +1,137 @@ +import argparse +import math + +def zeller(date_input): + + """ + Zellers Congruence Algorithm + Find the day of the week for nearly any Gregorian or Julian calendar date + + >>> zeller('01-31-2010') + Your date 01-31-2010, is a Sunday! + + Validate out of range month + >>> zeller('13-31-2010') + Traceback (most recent call last): + ... + ValueError: Month must be between 1 - 12 + >>> zeller('.2-31-2010') + Traceback (most recent call last): + ... + ValueError: invalid literal for int() with base 10: '.2' + + Validate out of range date: + >>> zeller('01-33-2010') + Traceback (most recent call last): + ... + ValueError: Date must be between 1 - 31 + >>> zeller('01-.4-2010') + Traceback (most recent call last): + ... + ValueError: invalid literal for int() with base 10: '.4' + + Validate second seperator: + >>> zeller('01-31*2010') + Traceback (most recent call last): + ... + ValueError: Date seperator must be '-' or '/' + + Validate first seperator: + >>> zeller('01^31-2010') + Traceback (most recent call last): + ... + ValueError: Date seperator must be '-' or '/' + + Validate out of range year: + >>> zeller('01-31-8999') + Traceback (most recent call last): + ... + ValueError: Year out of range. There has to be some sort of limit...right? + + Test null input: + >>> zeller() + Traceback (most recent call last): + ... + TypeError: zeller() missing 1 required positional argument: 'date_input' + + Test length fo date_input: + >>> zeller('') + Traceback (most recent call last): + ... + ValueError: Must be 10 characters long + >>> zeller('01-31-19082939') + Traceback (most recent call last): + ... + ValueError: Must be 10 characters long +""" + + # Days of the week for response + days = { + '0': 'Sunday', + '1': 'Monday', + '2': 'Tuesday', + '3': 'Wednesday', + '4': 'Thursday', + '5': 'Friday', + '6': 'Saturday' + } + + # Validate + if len(date_input) >= 11 or len(date_input) <= 0: + raise ValueError("Must be 10 characters long") + + # Get month + m = int(date_input[0] + date_input[1]) + # Validate + if m >= 13 or m <= 0: + raise ValueError("Month must be between 1 - 12") + + sep_1 = str(date_input[2]) + # Validate + if sep_1 not in ["-","/"]: + raise ValueError("Date seperator must be '-' or '/'") + + # Get day + d = int(date_input[3] + date_input[4]) + # Validate + if d >= 32 or d <= 0: + raise ValueError("Date must be between 1 - 31") + + # Seperator 2 + sep_2 = str(date_input[5]) + # Validate + if sep_2 not in ["-","/"]: + raise ValueError("Date seperator must be '-' or '/'") + + # Get year + y = int(date_input[6] + date_input[7] + date_input[8] + date_input[9]) + # Arbitrary year range + if y >= 8500 or y <= 45: + raise ValueError("Year out of range. There has to be some sort of limit...right?") + + # Start math + if m <= 2: + y = y - 1 + m = m + 12 + c = int(str(y)[:2]) + k = int(str(y)[2:]) + t = int(2.6*m - 5.39) + u = int(c / 4) + v = int(k / 4) + x = d + k + z = t + u + v + x + w = z - (2 * c) + f = round(w%7) + # End math + + for i in days: + if f == int(i): + print("Your date " + date_input + ", is a " + days[i] + "!") + +if __name__ == '__main__': + import doctest + doctest.testmod() + parser = argparse.ArgumentParser(description='Find out what day of the week nearly any date is or was. Enter date as a string in the mm-dd-yyyy or mm/dd/yyyy format') + parser.add_argument('date_input', type=str, help='Date as a string (mm-dd-yyyy or mm/dd/yyyy)') + args = parser.parse_args() + zeller(args.date_input) \ No newline at end of file From f71d891156879b141a91c9b5f3df85711e2d9ef3 Mon Sep 17 00:00:00 2001 From: "Marvin M. Michum" Date: Sat, 3 Aug 2019 19:52:48 -0400 Subject: [PATCH 2/4] remove unused math import --- maths/zellers_congruence.py | 1 - 1 file changed, 1 deletion(-) diff --git a/maths/zellers_congruence.py b/maths/zellers_congruence.py index 36ce115bedce..c5ed1469597a 100644 --- a/maths/zellers_congruence.py +++ b/maths/zellers_congruence.py @@ -1,5 +1,4 @@ import argparse -import math def zeller(date_input): From d1447c0b0fa7bd49e45a0de5511927bf9676a57f Mon Sep 17 00:00:00 2001 From: "Marvin M. Michum" Date: Sun, 4 Aug 2019 19:39:35 -0400 Subject: [PATCH 3/4] cleanup --- maths/zellers_congruence.py | 72 +++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/maths/zellers_congruence.py b/maths/zellers_congruence.py index c5ed1469597a..e149177d40a7 100644 --- a/maths/zellers_congruence.py +++ b/maths/zellers_congruence.py @@ -1,13 +1,16 @@ +from __future__ import annotations +import datetime import argparse -def zeller(date_input): + +def zeller(date_input: str) -> str: """ Zellers Congruence Algorithm Find the day of the week for nearly any Gregorian or Julian calendar date >>> zeller('01-31-2010') - Your date 01-31-2010, is a Sunday! + 'Your date 01-31-2010, is a Sunday!' Validate out of range month >>> zeller('13-31-2010') @@ -65,7 +68,7 @@ def zeller(date_input): """ # Days of the week for response - days = { + days: Dict[str, str] = { '0': 'Sunday', '1': 'Monday', '2': 'Tuesday', @@ -75,57 +78,74 @@ def zeller(date_input): '6': 'Saturday' } + convert_datetime_days: Dict[int,int] = { + 0:1, + 1:2, + 2:3, + 3:4, + 4:5, + 5:6, + 6:0 + } # Validate - if len(date_input) >= 11 or len(date_input) <= 0: + if not 0 < len(date_input) < 11: raise ValueError("Must be 10 characters long") # Get month - m = int(date_input[0] + date_input[1]) + m: int = int(date_input[0] + date_input[1]) # Validate - if m >= 13 or m <= 0: + if not 0 < m < 13: raise ValueError("Month must be between 1 - 12") - sep_1 = str(date_input[2]) + sep_1:str = date_input[2] # Validate if sep_1 not in ["-","/"]: raise ValueError("Date seperator must be '-' or '/'") # Get day - d = int(date_input[3] + date_input[4]) + d: int = int(date_input[3] + date_input[4]) # Validate - if d >= 32 or d <= 0: + if not 0 < d < 32: raise ValueError("Date must be between 1 - 31") - # Seperator 2 - sep_2 = str(date_input[5]) + # Get second seperator + sep_2: str = date_input[5] # Validate if sep_2 not in ["-","/"]: raise ValueError("Date seperator must be '-' or '/'") # Get year - y = int(date_input[6] + date_input[7] + date_input[8] + date_input[9]) + y: int = int(date_input[6] + date_input[7] + date_input[8] + date_input[9]) # Arbitrary year range - if y >= 8500 or y <= 45: + if not 45 < y < 8500: raise ValueError("Year out of range. There has to be some sort of limit...right?") + # Get datetime obj + dt_ck = datetime.date(int(y), int(m), int(d)) + # Start math if m <= 2: y = y - 1 m = m + 12 - c = int(str(y)[:2]) - k = int(str(y)[2:]) - t = int(2.6*m - 5.39) - u = int(c / 4) - v = int(k / 4) - x = d + k - z = t + u + v + x - w = z - (2 * c) - f = round(w%7) + # maths var + c: int = int(str(y)[:2]) + k: int = int(str(y)[2:]) + t: int = int(2.6*m - 5.39) + u: int = int(c / 4) + v: int = int(k / 4) + x: int = int(d + k) + z: int = int(t + u + v + x) + w: int = int(z - (2 * c)) + f: int = round(w%7) # End math - for i in days: - if f == int(i): - print("Your date " + date_input + ", is a " + days[i] + "!") + # Validate math + if f != convert_datetime_days[dt_ck.weekday()]: + raise AssertionError("The date was evaluated incorrectly. Contact developer.") + + # Response + response: str = f"Your date {date_input}, is a {days[str(f)]}!" + return response if __name__ == '__main__': import doctest @@ -133,4 +153,4 @@ def zeller(date_input): parser = argparse.ArgumentParser(description='Find out what day of the week nearly any date is or was. Enter date as a string in the mm-dd-yyyy or mm/dd/yyyy format') parser.add_argument('date_input', type=str, help='Date as a string (mm-dd-yyyy or mm/dd/yyyy)') args = parser.parse_args() - zeller(args.date_input) \ No newline at end of file + zeller(args.date_input) From b89be427c34c09c87c44d633a652490ac4857ea3 Mon Sep 17 00:00:00 2001 From: "Marvin M. Michum" Date: Sun, 4 Aug 2019 19:54:00 -0400 Subject: [PATCH 4/4] cleanup - Dict fix --- maths/zellers_congruence.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/maths/zellers_congruence.py b/maths/zellers_congruence.py index e149177d40a7..e04425eec903 100644 --- a/maths/zellers_congruence.py +++ b/maths/zellers_congruence.py @@ -68,7 +68,7 @@ def zeller(date_input: str) -> str: """ # Days of the week for response - days: Dict[str, str] = { + days = { '0': 'Sunday', '1': 'Monday', '2': 'Tuesday', @@ -78,7 +78,7 @@ def zeller(date_input: str) -> str: '6': 'Saturday' } - convert_datetime_days: Dict[int,int] = { + convert_datetime_days = { 0:1, 1:2, 2:3, @@ -87,6 +87,7 @@ def zeller(date_input: str) -> str: 5:6, 6:0 } + # Validate if not 0 < len(date_input) < 11: raise ValueError("Must be 10 characters long") @@ -120,7 +121,7 @@ def zeller(date_input: str) -> str: if not 45 < y < 8500: raise ValueError("Year out of range. There has to be some sort of limit...right?") - # Get datetime obj + # Get datetime obj for validation dt_ck = datetime.date(int(y), int(m), int(d)) # Start math