HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Python Day Finder

Submitted by: @import:stackexchange-codereview··
0
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 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 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.