diff --git a/__main__.py b/__main__.py index 53c2c43..eb598cf 100644 --- a/__main__.py +++ b/__main__.py @@ -1,5 +1,21 @@ +from doomsday.date import is_valid_date +from doomsday.algorithm import get_weekday_for_date + def main() -> None: - print("Hello world") + + stop = False + + while not stop : + input_date = input("\n Enter a date and I'll get the day (quit to stop the programm) : ") + print("\n") + + if input_date.lower() == "quit" : + stop = True + else : + if is_valid_date(input_date): + print("You asked for " + get_weekday_for_date(input_date)) + + print("bye bye") main() diff --git a/doomsday/algorithm.py b/doomsday/algorithm.py index cf81d60..424bc82 100644 --- a/doomsday/algorithm.py +++ b/doomsday/algorithm.py @@ -1,2 +1,95 @@ +from doomsday.toolbox import is_leap_year +from doomsday.toolbox import parse_date_to_ints + +from doomsday.const import DAYS + def get_weekday_for_date(date: str) -> str: - return "Sunday" + ''' + Returns the right day asked from the date (it's magic) + ''' + split_date: list[int] = parse_date_to_ints(date) + + year: int = split_date[0] + month: int = split_date[1] + day: int = split_date[2] + + doomsday: int = get_doomsday(month, year) + anchor_day: int = get_anchor_day(year) + + out_day = int((anchor_day + ((day - doomsday) % 7)) % 7) + + return DAYS()[out_day] + + +def get_anchor_day(year: int) -> int: + ''' + Get the anchor day of the year + ''' + + anchor = year - ((year // 100) * 100) + + if anchor % 2 != 0 : + anchor += 11 + anchor /= 2 + + + if anchor % 2 != 0 : + anchor += 11 + + anchor = 7 - (anchor % 7) + century_anchor: int = get_century_anchor(year) + + return anchor + century_anchor + + +def get_century_anchor(year: int) -> int: + ''' + Subshit from get_anchor_day() getting the century anchor + ''' + + century_basis = year // 100 + + if century_basis % 4 == 15 % 4 : + return 3 + elif century_basis % 4 == 16 % 4 : + return 2 + elif century_basis % 4 == 17 % 4 : + return 0 + else : + return 5 + + +def get_doomsday(month: int, year: int) -> int: + ''' + Get the doomsday of the date + ''' + # april, june, august, october, december + if month in [4, 6, 8, 10, 12] : + return month + + # march + if month == 3 : + return 0 + + # january, february + if (month == 1) : + if(is_leap_year(year)) : + return 11 + else : + return 10 + + #february + if (month == 2) : + if(is_leap_year(year)) : + return 22 + else : + return 21 + + # may, july, september, november + for tuple in [[5, 9], [7, 11]] : + if month in tuple : + if tuple.index(month) == 1 : + return tuple[0] + else : + return tuple[1] + diff --git a/doomsday/const.py b/doomsday/const.py new file mode 100644 index 0000000..d8fad97 --- /dev/null +++ b/doomsday/const.py @@ -0,0 +1,6 @@ +def PHALANX_MONTH() -> list[int] : + return [1, 3, 5, 7, 8, 10, 12] + +def DAYS() -> list[str] : + return ["Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday"] \ No newline at end of file diff --git a/doomsday/date.py b/doomsday/date.py index 0f8e737..9596ecc 100644 --- a/doomsday/date.py +++ b/doomsday/date.py @@ -1,2 +1,132 @@ +import doomsday.toolbox as tool + +import doomsday.errors as EEEE + +from doomsday.const import PHALANX_MONTH + def is_valid_date(date: str) -> bool: + ''' + Check if date = fine (don't ask questions). + ''' + if is_valid_format(date) : + split_date: list[int] = tool.parse_date_to_ints(date) + + if (is_valid_year(split_date[0]) and + is_valid_month(split_date[1]) and + is_valid_day(split_date)) : + return True + + + return False + + +def is_valid_day(date: list[int]) -> bool: + ''' + day = gud ? + ''' + year: int = date[0] + month: int = date[1] + day: int = date[2] + + is_valid = False + + if day > 0 : + + if month == 2 : + is_valid = is_valid_day_case_february(year, day) + + elif month in PHALANX_MONTH() : + if day < 32 : + + is_valid = True + + else : + if day < 31 : + + is_valid = True + + if not is_valid : + EEEE.wrong_day(day, month, tool.is_leap_year(year)) + + return is_valid + + +def is_valid_day_case_february(year: int, day: int) -> bool: + ''' + Subshit from is_valid_day() checking for february. + ''' + if tool.is_leap_year(year) : + if day < 30 : + + return True + + else : + if day < 29 : + + return True + + return False + + +def is_valid_month(month: int) -> bool: + ''' + is month valid + ''' + if month < 1 or month > 12 : + EEEE.wrong_month(month) + + return False + return True + + +def is_valid_year(year: int) -> bool: + ''' + Does the year fulfill is role correctly in our requirements ? + ''' + + if year < 1583 : + EEEE.wrong_year(year) + + return False + + return True + + +def is_valid_format(date: str) -> bool: + ''' + Says if the date format is fine. + ''' + + split_date = tool.split_date(date) + + if len(split_date) == 3 : + + return check_year_month_day(split_date) + + else : + EEEE.wrong_format() + + return False + + +def check_year_month_day(split_date: list[str]) -> bool : + ''' + Subshit from is_valid_format() helping to tell date format validity for + each date part individually. + ''' + if (len(split_date[0]) == 0 or + len(split_date[1]) < 1 and len(split_date[1]) > 2 or + len(split_date[2]) < 1 and len(split_date[2]) > 2 ): + + EEEE.wrong_format() + + return False + + for element in split_date : + if (not element.isnumeric()) : + EEEE.not_numeric_value(element) + + return False + + return True \ No newline at end of file diff --git a/doomsday/errors.py b/doomsday/errors.py new file mode 100644 index 0000000..b70811d --- /dev/null +++ b/doomsday/errors.py @@ -0,0 +1,56 @@ +from doomsday.const import PHALANX_MONTH +########################### Date validity ###################################### + +def wrong_format() : + print("******* Error Format *******") + print("Date Format not valid. Follow this case : YYYY-mm-dd") + print("****************************") + + +def not_numeric_value(value: str) : + print("******* Error Format *******") + print("One of your value is not numerical :") + print(f"--> {value} <--") + print("Try again with only numerical values.") + print("****************************") + + +def wrong_month(value: int) : + print("******* Error Value *******") + print(f"You entered {value} as month.") + print("The month must be between 01 and 12.") + print("***************************") + + +def wrong_year(value: int) : + print("******* Error Value *******") + print(f"You entered {value} as year.") + print("The year must be past 1583.") + print("***************************") + + +def wrong_day(day: int, month: int, is_leap: bool) : + print("******* Error Value *******") + print(f"For month number {month}, you entered {day} as day.") + + if month == 2 : + wrong_day_case_february(day, month, is_leap) + + elif month in PHALANX_MONTH() : + print("In your case, the day must be between 01 and 31") + + else : + print("In your case, the day must be between 01 and 30") + print("***************************") + + +def wrong_day_case_february(day: int, month: int, is_leap: bool) : + + if is_leap : + print ("Your year is leap") + print("The day must be between 01 and 29.") + else : + print("Your year is not leap") + print("The day must be between 01 and 28.") + +################################################################################ \ No newline at end of file diff --git a/doomsday/toolbox.py b/doomsday/toolbox.py new file mode 100644 index 0000000..3c310bf --- /dev/null +++ b/doomsday/toolbox.py @@ -0,0 +1,57 @@ +def is_leap_year(year: int) -> bool: + ''' + Check if the year is a leap year. + ''' + if year % 100 == 0: + if year % 400 == 0: + + return True + + elif year % 4 == 0: + + return True + + return False + + +def parse_date_to_ints(date: str) -> list[int] : + ''' + Get a list of each individual parts of the date. + ''' + return date_elements_to_ints(split_date(date)) + + +def date_elements_to_ints(split_date: list[str]) -> list[int] : + ''' + Return the int side of the force. You'd ask me why did I made two + different functions to get the same result. + AHAHAHAAAAAHHH, behold my tremendous genius (and -1 on my score) !!! + ''' + + split_date_int: list[int] = [] + + for date_part in split_date : + split_date_int.append(int(date_part)) + + return split_date_int + + +def split_date(date: str) -> list[str]: + ''' + Give an array containing each elements of the date. + -> if not a date, return an array containing only the string + ''' + + if "-" in date : + return date.split("-") + + elif "." in date : + return date.split(".") + + elif "/" in date : + return date.split("/") + + elif "_" in date : + return date.split("_") + + return date.split() \ No newline at end of file