patternpythonMinor
Python Day Finder
Viewed 0 times
daypythonfinder
Problem
I have made a Python program to find the day of the week of an inputted date. I did not want to use the
I want to improve on appropriately putting certain tasks in functions, so my program is easier to read and follow. I would like to know if the logic in my program makes sense, and if there is anything that could have been done easier. If things could have been in a more "Pythonic" way, that would be nice to know too.
Here is the code -
```
month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
day_names = ["Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday"]
SYEAR = 2016
SMONTH = 1
SDAY = 1
def is_leap_year(year):
if year % 4 == 0:
if year % 100 == 0:
if year % 400 == 0:
return True
else:
return False
else:
return True
return False
def calc_year(year):
days = 0
tyear = SYEAR
while not tyear == year:
if tyear year:
if is_leap_year(tyear - 1):
days -= 366
else:
days -= 365
tyear -= 1
return days
def calc_month(month, year):
days = 0
tmonth = SMONTH
while not tmonth == month:
if tmonth == 2 and is_leap_year(year):
days += 1
days += month_days[tmonth - 1]
tmonth += 1
return days
def calc_day(day):
days = 0
tday = SDAY
while not tday == day:
tday += 1
days += 1
return days
def find_day(date):
total = calc_month(date[0], date[2]) + calc_day(date[1]) + calc_year(date[2])
if total : ").split()
month = int(date[0])
day = int(date[1])
year = int(date[2])
if month > 12 or month month_days[month - 1] or day <= 0:
if not (day == 29 and month == 2):
print("Invalid day")
else:
print(find_day((month, d
time or datetime module, like in this answer, as I found that a bit too easy. (I like to challenge myself)I want to improve on appropriately putting certain tasks in functions, so my program is easier to read and follow. I would like to know if the logic in my program makes sense, and if there is anything that could have been done easier. If things could have been in a more "Pythonic" way, that would be nice to know too.
Here is the code -
```
month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
day_names = ["Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday"]
SYEAR = 2016
SMONTH = 1
SDAY = 1
def is_leap_year(year):
if year % 4 == 0:
if year % 100 == 0:
if year % 400 == 0:
return True
else:
return False
else:
return True
return False
def calc_year(year):
days = 0
tyear = SYEAR
while not tyear == year:
if tyear year:
if is_leap_year(tyear - 1):
days -= 366
else:
days -= 365
tyear -= 1
return days
def calc_month(month, year):
days = 0
tmonth = SMONTH
while not tmonth == month:
if tmonth == 2 and is_leap_year(year):
days += 1
days += month_days[tmonth - 1]
tmonth += 1
return days
def calc_day(day):
days = 0
tday = SDAY
while not tday == day:
tday += 1
days += 1
return days
def find_day(date):
total = calc_month(date[0], date[2]) + calc_day(date[1]) + calc_year(date[2])
if total : ").split()
month = int(date[0])
day = int(date[1])
year = int(date[2])
if month > 12 or month month_days[month - 1] or day <= 0:
if not (day == 29 and month == 2):
print("Invalid day")
else:
print(find_day((month, d
Solution
Your code looks quite good. You mostly stick to PEP8 though you might want to implement a distance of two empty lines in-between functions on module-level.
Regarding code optimization you may want to make
Furthermore, you can make
Also I find it a bit intricately, that you pass a tuple
I suggest changing that to:
However, if you really want to handle
Regarding code optimization you may want to make
month_days and day_names tuples since they do not change and thus may be implemented as invariant constants. While doing this you can also capitalize their names to indicate that they are global constants as you did with the other module-level variables:MONTH_DAYS = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
DAY_NAMES = ("Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday")Furthermore, you can make
is_leap_year a one-liner, since the if-else blocks and zero-comparisons are a bit verbose for my taste of "pythonicness":def is_leap_year(year):
return not year % 4 and (year % 100 or not year % 400)Also I find it a bit intricately, that you pass a tuple
date to find_day and then access its members via indexes.I suggest changing that to:
def find_day(month, day, year):
total = calc_month(month, year) + calc_day(day) + calc_year(year)
if total : ").split()
month = int(date[0])
day = int(date[1])
year = int(date[2])
if month > 12 or month month_days[month - 1] or day <= 0:
if not (day == 29 and month == 2):
print("Invalid day")
else:
print(find_day(month, day, year))However, if you really want to handle
date as such a tuple for later re-use, I recommend that you use tuple unpacking in find_day instead of index accessing for better readability:def find_day(date):
month, day, year = date
total = calc_month(month, year) + calc_day(day) + calc_year(year)
if total < 0:
return day_names[total % -7]
else:
return day_names[total % 7]Code Snippets
MONTH_DAYS = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
DAY_NAMES = ("Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday")def is_leap_year(year):
return not year % 4 and (year % 100 or not year % 400)def find_day(month, day, year):
total = calc_month(month, year) + calc_day(day) + calc_year(year)
if total < 0:
return day_names[total % -7]
else:
return day_names[total % 7]
def main():
date = input("Enter a day like so <MM, DD, YYYY>: ").split()
month = int(date[0])
day = int(date[1])
year = int(date[2])
if month > 12 or month <= 0:
print("Invalid month")
elif day > month_days[month - 1] or day <= 0:
if not (day == 29 and month == 2):
print("Invalid day")
else:
print(find_day(month, day, year))def find_day(date):
month, day, year = date
total = calc_month(month, year) + calc_day(day) + calc_year(year)
if total < 0:
return day_names[total % -7]
else:
return day_names[total % 7]Context
StackExchange Code Review Q#152287, answer score: 4
Revisions (0)
No revisions yet.