From 3f5c6a9877cc8e91f93f5596f71f5c81d0ca7b02 Mon Sep 17 00:00:00 2001 From: MZASU Date: Wed, 15 Nov 2023 13:28:02 +0100 Subject: [PATCH 1/7] Squelette validation de la date --- __main__.py | 11 ++++++++++- doomsday/date.py | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/__main__.py b/__main__.py index 53c2c43..3bc8aa5 100644 --- a/__main__.py +++ b/__main__.py @@ -1,5 +1,14 @@ +from doomsday.date import * + + def main() -> None: - print("Hello world") + date = input("Veuillez saisir une date au format YYYY-MM-DD: ") + + if is_valid_date(date): + print("Date valide!") + # Exécuter l'algorithme + else: + print("Erreur") main() diff --git a/doomsday/date.py b/doomsday/date.py index 0f8e737..b171ee3 100644 --- a/doomsday/date.py +++ b/doomsday/date.py @@ -1,2 +1,26 @@ def is_valid_date(date: str) -> bool: + """Verify if the date parameter is valid + + First the function verify the format, + then it verify if the date exist + """ + + if not is_format_valid(date): + print("Le format de la date n'est pas YYYY-MM-DD!") + return False + + if not does_date_exist(date): + print("La date n'existe pas!") + return False + + return True + + +def is_format_valid(date: str) -> bool: + """Verify if date follows the format YYYY-MM-DD""" + return True + + +def does_date_exist(date: str) -> bool: + """Verify if the date exist""" return True From 2554930dcc871a92b8f880c1f85dc5c9e732cb04 Mon Sep 17 00:00:00 2001 From: MZASU Date: Wed, 15 Nov 2023 13:43:39 +0100 Subject: [PATCH 2/7] =?UTF-8?q?V=C3=A9rifier=20si=20le=20format=20de=20la?= =?UTF-8?q?=20date=20est=20bon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doomsday/date.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doomsday/date.py b/doomsday/date.py index b171ee3..853d3fd 100644 --- a/doomsday/date.py +++ b/doomsday/date.py @@ -1,3 +1,6 @@ +import re + + def is_valid_date(date: str) -> bool: """Verify if the date parameter is valid @@ -18,7 +21,9 @@ def is_valid_date(date: str) -> bool: def is_format_valid(date: str) -> bool: """Verify if date follows the format YYYY-MM-DD""" - return True + format_match = re.fullmatch(r"\d{4}[-]\d{1,2}[-]\d{1,2}", date) + + return format_match is not None def does_date_exist(date: str) -> bool: From 0976fc5f13190cc3bb64a8ce1ec89c20472ca9a0 Mon Sep 17 00:00:00 2001 From: MZASU Date: Wed, 15 Nov 2023 14:46:50 +0100 Subject: [PATCH 3/7] =?UTF-8?q?V=C3=A9rifier=20si=20la=20date=20existe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Les tests passent et pycodestyle OK --- doomsday/date.py | 6 +--- doomsday/does_date_exist.py | 58 +++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 doomsday/does_date_exist.py diff --git a/doomsday/date.py b/doomsday/date.py index 853d3fd..72316af 100644 --- a/doomsday/date.py +++ b/doomsday/date.py @@ -1,4 +1,5 @@ import re +from doomsday.does_date_exist import * def is_valid_date(date: str) -> bool: @@ -24,8 +25,3 @@ def is_format_valid(date: str) -> bool: format_match = re.fullmatch(r"\d{4}[-]\d{1,2}[-]\d{1,2}", date) return format_match is not None - - -def does_date_exist(date: str) -> bool: - """Verify if the date exist""" - return True diff --git a/doomsday/does_date_exist.py b/doomsday/does_date_exist.py new file mode 100644 index 0000000..798dce5 --- /dev/null +++ b/doomsday/does_date_exist.py @@ -0,0 +1,58 @@ +LAST_DAY_OF_MONTH: list[int] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + + +def does_date_exist(date: str) -> bool: + """Verify if the date exist + + date has to be of valid format (YYYY-MM-DD)""" + + splitted_date: list[int] = split_date(date) + + year: int = splitted_date[0] + month: int = splitted_date[1] + day: int = splitted_date[2] + + # We support only dates starting from 1583 + if year < 1583: + print("L'année saisit n'est pas supportée.") + print("Veuillez saisir au date à partir de 1583-01-01") + return False + + if not (0 < month < 13): + print("Le mois saisit n'est pas valide.") + return False + + if day <= 0: + print("Le jour saisit n'est pas valide.") + return False + + if day > LAST_DAY_OF_MONTH[month-1]: + # If we are in february during a leap year we have 29 days + if month == 2 and is_leap_year(year) and day <= 29: + return True + + print("Le jour saisit n'est pas valide.") + return False + + return True + + +def is_leap_year(year: int) -> bool: + """Returns true if year is bisextile""" + divisable_by_4 = year % 4 == 0 + divisable_by_100 = year % 100 == 0 + divisable_by_400 = year % 400 == 0 + return divisable_by_4 and (not divisable_by_100 or divisable_by_400) + + +def split_date(date: str) -> list[int]: + """Splits a date into a list of ints + + date has to be of valid format (YYYY-MM-DD)""" + # Split the date in three parts using the '-' character + splitted_date_str: list[str] = date.split("-") + + # Convert the splitted date to ints + splitted_date_int: list[int] = list(map(int, splitted_date_str)) + + return splitted_date_int From cb7c0ff3709046a65fb1a579af87b9aa1f771d3f Mon Sep 17 00:00:00 2001 From: MZASU Date: Wed, 15 Nov 2023 15:55:09 +0100 Subject: [PATCH 4/7] =?UTF-8?q?Calcul=20doomsday=20d'une=20ann=C3=A9e=20OK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __main__.py | 4 +-- doomsday/algorithm.py | 16 +++++++++++ doomsday/algorithm_helper_function.py | 40 +++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 doomsday/algorithm_helper_function.py diff --git a/__main__.py b/__main__.py index 3bc8aa5..cbf3437 100644 --- a/__main__.py +++ b/__main__.py @@ -1,12 +1,12 @@ from doomsday.date import * +from doomsday.algorithm import * def main() -> None: date = input("Veuillez saisir une date au format YYYY-MM-DD: ") if is_valid_date(date): - print("Date valide!") - # Exécuter l'algorithme + print(f"Le {date} est un {get_weekday_for_date(date)}.") else: print("Erreur") diff --git a/doomsday/algorithm.py b/doomsday/algorithm.py index cf81d60..9b6964f 100644 --- a/doomsday/algorithm.py +++ b/doomsday/algorithm.py @@ -1,2 +1,18 @@ +from doomsday.algorithm_helper_function import * +from doomsday.does_date_exist import split_date + + def get_weekday_for_date(date: str) -> str: + """Return the weekday from a date + + date has to be of valid format and exist""" + + splitted_date: list[int] = split_date(date) + + year: int = splitted_date[0] + month: int = splitted_date[1] + day: int = splitted_date[2] + + doomsday: int = get_year_doomsday(year) + return "Sunday" diff --git a/doomsday/algorithm_helper_function.py b/doomsday/algorithm_helper_function.py new file mode 100644 index 0000000..abbc0e0 --- /dev/null +++ b/doomsday/algorithm_helper_function.py @@ -0,0 +1,40 @@ +def get_century_doomsday_offset(year: int) -> int: + """Returns the doomsday offset for a given century""" + + # List of the offsets and exemples + # 2000 2 + # 1700/2100 0 + # 1800/2200 5 + # 1900/2300 3 + CENTURY_OFFSETS: list[int] = [2, 0, 5, 3] + + century: int = year // 100 + + return CENTURY_OFFSETS[century % 4] + + +def get_year_doomsday(year: int) -> int: + """Return the doomsday for a given year""" + + century_offset: int = get_century_doomsday_offset(year) + + # The algorithm to find the doomsday for a year: + # 1: Get the last two digits of the year + last_2_digit: int = year % 100 + + # 2: If the number is odd add 11 + if last_2_digit % 2 == 1: + last_2_digit += 11 + + # 3: Divide the number by 2 + last_2_digit = last_2_digit // 2 + + # 4: If the number is odd add 11 + if last_2_digit % 2 == 1: + last_2_digit += 11 + + # 5: Find the difference with the next multiple of 7 + diff_with_next_multiple_of_seven: int = (7 - (last_2_digit % 7)) % 7 + + # 6: Add the century offset and apply mod 7, you have the doomsday + return (diff_with_next_multiple_of_seven + century_offset) % 7 From 87e4920dce60453bce19fdc17022f5284c0f9086 Mon Sep 17 00:00:00 2001 From: MZASU Date: Wed, 15 Nov 2023 16:28:42 +0100 Subject: [PATCH 5/7] Algorithme OK Passe les tests et pycodestyle OK --- doomsday/algorithm.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/doomsday/algorithm.py b/doomsday/algorithm.py index 9b6964f..6a2d29e 100644 --- a/doomsday/algorithm.py +++ b/doomsday/algorithm.py @@ -1,5 +1,10 @@ from doomsday.algorithm_helper_function import * -from doomsday.does_date_exist import split_date +from doomsday.does_date_exist import split_date, is_leap_year + + +MONTHS_ANCHOR: list[int] = [10, 21, 0, 4, 9, 6, 11, 8, 5, 10, 7, 12] +WEEKDAYS: list[str] = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday"] def get_weekday_for_date(date: str) -> str: @@ -13,6 +18,22 @@ def get_weekday_for_date(date: str) -> str: month: int = splitted_date[1] day: int = splitted_date[2] + # Finds the doomsday of a given year doomsday: int = get_year_doomsday(year) - return "Sunday" + # Retreive the anchor day of a given month + anchor_day: int = MONTHS_ANCHOR[month - 1] + + # During a leap year the anchor for January and February changes + # January: 10 -> 11 February: 21 -> 22 + if is_leap_year(year) and (month == 1 or month == 2): + anchor_day += 1 + + # Get the difference between the anchor day and the choosen day + diff_with_anchor: int = day - anchor_day + + # Adds the doomsday to our diff as an offset and apply mod 7 + # to get our final answer + weekday: int = (diff_with_anchor + doomsday) % 7 + + return WEEKDAYS[weekday] From 7a9bf33de8d7631a3ecea65e56895a1fa4b555e5 Mon Sep 17 00:00:00 2001 From: MZASU Date: Fri, 17 Nov 2023 10:43:20 +0100 Subject: [PATCH 6/7] Boucle si la date saisit est invalide --- __main__.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/__main__.py b/__main__.py index cbf3437..7b5d703 100644 --- a/__main__.py +++ b/__main__.py @@ -3,12 +3,13 @@ def main() -> None: - date = input("Veuillez saisir une date au format YYYY-MM-DD: ") - if is_valid_date(date): - print(f"Le {date} est un {get_weekday_for_date(date)}.") - else: - print("Erreur") + while True: + date = input("Veuillez saisir une date au format YYYY-MM-DD: ") + + if is_valid_date(date): + print(f"Le {date} est un {get_weekday_for_date(date)}.") + break main() From a673826a2ec3f260bbdcc0f81e54cf37d7e63b3a Mon Sep 17 00:00:00 2001 From: MZASU Date: Fri, 17 Nov 2023 10:50:07 +0100 Subject: [PATCH 7/7] =?UTF-8?q?Am=C3=A9liorer=20la=20clart=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doomsday/does_date_exist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doomsday/does_date_exist.py b/doomsday/does_date_exist.py index 798dce5..8727013 100644 --- a/doomsday/does_date_exist.py +++ b/doomsday/does_date_exist.py @@ -18,7 +18,7 @@ def does_date_exist(date: str) -> bool: print("Veuillez saisir au date à partir de 1583-01-01") return False - if not (0 < month < 13): + if not (1 <= month <= 12): print("Le mois saisit n'est pas valide.") return False