Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion __main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
from doomsday.date import *
from doomsday.algorithm import *


def main() -> None:
print("Hello world")

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()
39 changes: 38 additions & 1 deletion doomsday/algorithm.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,39 @@
from doomsday.algorithm_helper_function import *
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:
return "Sunday"
"""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]

# Finds the doomsday of a given year
doomsday: int = get_year_doomsday(year)

# 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]
40 changes: 40 additions & 0 deletions doomsday/algorithm_helper_function.py
Original file line number Diff line number Diff line change
@@ -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
Comment on lines +4 to +8
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bien

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
25 changes: 25 additions & 0 deletions doomsday/date.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,27 @@
import re
from doomsday.does_date_exist import *


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"""
format_match = re.fullmatch(r"\d{4}[-]\d{1,2}[-]\d{1,2}", date)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bien


return format_match is not None
58 changes: 58 additions & 0 deletions doomsday/does_date_exist.py
Original file line number Diff line number Diff line change
@@ -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 (1 <= month <= 12):
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