0

So this is my first time ever writing code in Python and I wanted to do a little project. I thought about what I wanted to do and figured people might want to know how many days until each holiday.

How should I go about finding the difference between today's date and the holidays?

from datetime import datetime, timedelta
now = datetime.now() + timedelta(days = 10)

def get_user_holiday():
    holiday = input("What is your favorite holiday? ")

    if holiday == "New Year's Day":
        new_years_Day = datetime(now.year, 1, 1)
    elif holiday == "Martin Luther King Jr. Day":
        martin_luther_king_jr_Day = datetime(now.year, 1, 21)
    elif holiday == "Groundhog Day":
        groundhog_Day = datetime(now.year, 2, 2)
    elif holiday == "Valentine's Day":
        valentines_Day = datetime(now.year, 2, 14)
    elif holiday == "Ash Wednesday":
        ash_Wednesday = datetime(now.year, 3, 6)
    elif holiday == "St. Patrick's Day":
        st_patricks_Day = datetime(now.year, 3, 17)
    elif holiday == "April Fool's Day":
        april_fools_Day = datetime(now.year, 4, 1)
    elif holiday == "Palm Sunday":
        palm_Sunday = datetime(now.year, 4, 14)
    elif holiday == "Good Friday":
        good_Friday = datetime(now.year, 4, 19)
    elif holiday == "Easter Day":
        easter_Day = datetime(now.year, 4, 21)
    elif holiday == "Mother's Day":
        mothers_Day = datetime(now.year, 5, 12)
    elif holiday == "Memorial Day":
        memorial_Day = datetime(now.year, 5, 27)
    elif holiday == "Father's Day":
        fathers_Day = datetime(now.year, 6, 16)
    elif holiday == "Independence Day":
        independence_Day = datetime(now.year, 7, 4)
    elif holiday == "Labor Day":
        labor_Day = datetime(now.year, 9, 2)
    elif holiday == "Columbus Day":
        columbus_Day = datetime(now.year, 10, 4)
    elif holiday == "Halloween Day":
        halloween_Day = datetime(now.year, 10, 31)
    elif holiday == "Veterans Day":
        veterans_Day = datetime(now.year, 11, 11)
    elif holiday == "Thanksgiving Day":
        thanksgiving_Day = datetime(now.year, 11, 28)
    elif holiday == "Hanukkah Day":
        hanukkah_Day = datetime(now.year, 12, 22)
    elif holiday == "Christmas Day":
        christmas_Day = datetime(now.year, 12, 25)
    elif holiday == "New Year's Eve Day":
        new_years_eve_Day = datetime(now.year, 12, 31)
    else:
        print("Not a valid holiday. ")
    return holiday

This is what I edited the code to.

from datetime import datetime, timedelta
now = datetime.now()

def get_user_holiday():
    global now
    holiday = input("What is your favorite holiday? ")

    if holiday == "New Year's Day":
        return datetime(now.year, 1, 1)
    elif holiday == "Martin Luther King Jr. Day":
        return datetime(now.year, 1, 21)
    elif holiday == "Groundhog Day":
        return datetime(now.year, 2, 2)
    elif holiday == "Valentine's Day":
        return datetime(now.year, 2, 14)
    elif holiday == "Ash Wednesday":
        return datetime(now.year, 3, 6)
    elif holiday == "St. Patrick's Day":
        return datetime(now.year, 3, 17)
    elif holiday == "April Fool's Day":
        return datetime(now.year, 4, 1)
    elif holiday == "Palm Sunday":
        return datetime(now.year, 4, 14)
    elif holiday == "Good Friday":
        return datetime(now.year, 4, 19)
    elif holiday == "Easter Day":
        return datetime(now.year, 4, 21)
    elif holiday == "Mother's Day":
        return datetime(now.year, 5, 12)
    elif holiday == "Memorial Day":
        return datetime(now.year, 5, 27)
    elif holiday == "Father's Day":
        return datetime(now.year, 6, 16)
    elif holiday == "Independence Day":
        return datetime(now.year, 7, 4)
    elif holiday == "Labor Day":
        return datetime(now.year, 9, 2)
    elif holiday == "Columbus Day":
        return datetime(now.year, 10, 4)
    elif holiday == "Halloween Day":
        return datetime(now.year, 10, 31)
    elif holiday == "Veterans Day":
        return datetime(now.year, 11, 11)
    elif holiday == "Thanksgiving Day":
        return datetime(now.year, 11, 28)
    elif holiday == "Hanukkah Day":
        return datetime(now.year, 12, 22)
    elif holiday == "Christmas Day":
        return datetime(now.year, 12, 25)
    elif holiday == "New Year's Eve Day":
        return datetime(now.year, 12, 31)
    else:
        print("Not a valid holiday. ")
    return holiday

def calculate_dates(holiday, now):
    diff = holiday - now
    if diff.days >= 0:  # holiday is upcoming this year
        return diff.days
    else:  # next holiday occurs next year
        return ((holiday + timedelta(years = 1)) - now).days

hd = get_user_holiday()
now = datetime.now()
calc = calculate_dates(hd, now)

print(calc)
TechByte
  • 3
  • 4
  • Quits working how? If there's an error, you need to include it, with the traceback. See [mre] for reference. – wjandrea Oct 03 '19 at 04:33
  • 1
    You're always returning the users entered string, not the calculated date (and I'm not sure I understand why you add 10 days or 2000 years to now) – OneCricketeer Oct 03 '19 at 04:34
  • straight question, 'hd' holds a string & how can you expect it to have attributes like day and month ? – Kris Oct 03 '19 at 04:34
  • I went ahead and edited a few things because everything after the return holiday was messed up in some way, shape or form. I'm just wondering how to go about finishing the code. – TechByte Oct 03 '19 at 04:44
  • I added the 10 days to 'timedelta' to make the 'now.year' show the current year without changing the import from 'from datetime import datetime' to 'import datetime.' – TechByte Oct 03 '19 at 04:52

1 Answers1

0

To start, you'll need to return the datetime objects for the holiday, for example

now = datetime.now()

def get_user_holiday():
    global now 
    holiday = input("What is your favorite holiday? ")

    if holiday == "New Year's Day":
        return datetime(now.year, 1, 1)

Then, I'm not sure about the math being performed in the calculate function because you're always adding one to the current year, which means you're skipping over holidays that haven't happened yet for the current year, unless that's what the max() call is for

But I would try this

def calculate_dates(holiday, now): 
    diff = holiday - now 
    if diff.days >= 0:  # holiday is upcoming this year 
        return diff.days
    else:  # next holiday occurs next year .timedelta doesn't support years, so this is my workaround 
        return ((holiday + timedelta(days = 365)) - now).days

However, keep in mind that dates of certain holidays are different every year, so this result won't be truly accurate

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • How would I call this? When importing this code, I no longer have the option to input a holiday. – TechByte Oct 03 '19 at 05:29
  • So like with the new code, I get this error. Traceback (most recent call last): File "C:/Users/rmulr/.PyCharmCE2018.3/config/scratches/new.py", line 65, in calc = calculate_dates(hd, now) File "C:/Users/rmulr/.PyCharmCE2018.3/config/scratches/new.py", line 57, in calculate_dates diff = holiday - now TypeError: unsupported operand type(s) for -: 'str' and 'datetime.datetime' – TechByte Oct 03 '19 at 20:20
  • The only way I see you get that error is if you didn't type in a holiday correctly, then you still do `return holiday`, which is a str type, not a datetime – OneCricketeer Oct 03 '19 at 20:40
  • I have no idea. This is the error I am getting. 'What is your favorite holiday? Valentine's Day Traceback (most recent call last): File "C:/Users/rmulr/.PyCharmCE2018.3/config/scratches/test.py", line 65, in calc = calculate_dates(hd, now) File "C:/Users/rmulr/.PyCharmCE2018.3/config/scratches/test.py", line 61, in calculate_dates return ((holiday + timedelta(years = 1)) - now).days TypeError: 'years' is an invalid keyword argument for __new__() Process finished with exit code 1' – TechByte Oct 04 '19 at 03:56
  • It only happens to the holidays that have already happened. Labor Day and up. Believe it has something to do with the arguments of timedelta in the else: return under def calculate_dates. – TechByte Oct 04 '19 at 03:59
  • Oops, yeah. I didn't test this code :) timedelta indeed does not support years as an argument https://stackoverflow.com/questions/54394327/using-datetime-timedelta-to-add-years – OneCricketeer Oct 04 '19 at 04:01
  • What else can I put in place of it? Sorry, I am very new at this. Wait, just checked the link. – TechByte Oct 04 '19 at 04:04
  • Okay, thanks. Do you mind explaining what timedelta and the def calculate_dates actually does in this context? – TechByte Oct 04 '19 at 04:05
  • How can I make it skip over the calculate_dates when an invalid holiday is typed in? It goes ahead and prints "Not a valid holiday.", but then gives an error "Line 57: TypeError: unsupported operand type(s) for Sub: 'str' and 'datetime'". – TechByte Oct 04 '19 at 19:49
  • Rather than `return holiday`, do `return None`. Then only run `caclulate_dates` when `if hd is not None` is True – OneCricketeer Oct 04 '19 at 20:15