slimeworm
slimeworm

Reputation: 13

How do I condense all these "if" statements?

I'm quite new to python and programming in general and I made this program that lets you add days to today's current date and it would output what that date would be. Not very useful, but I got quite annoyed at how much space it was taking and was wondering if it could be made smaller and more condensed, since it's quite simple. I dont actually have a clue. So if someone could show me that would be nice.

import datetime
calendar = {1:"Sunday", 2:"Monday", 3:"Tuesday", 4:"Wednesday", 5:"Thursday", 6:"Friday", 0:"Saturday"}
Day = eval(input("Enter how many days you want to look into the future: "))
todayDate = datetime.date.today()
x = todayDate.strftime("%A")
if x == "Sunday" :
    y = ((1+ Day) % 7)
    print(calendar[y]) 
    exit()
if x == "Monday" :
    y = ((2+ Day) % 7)
    print(calendar[y]) 
    exit()
if x == "Tuesday" :
    y = ((3+ Day) % 7)
    print(calendar[y]) 
    exit()
if x == "Wednesday" :
    y = ((4+ Day) % 7)
    print(calendar[y]) 
    exit()
if x == "Thursday" :
    y = ((5+ Day) % 7)
    print(calendar[y]) 
    exit()
if x == "Friday" :
    y = ((6+ Day) % 7)
    print(calendar[y]) 
    exit()
if x == "Saturday" :
    y = ((7+ Day) % 7)
    print(calendar[y]) 
    exit()

Upvotes: 0

Views: 92

Answers (4)

GBrandt
GBrandt

Reputation: 685

Usually when condensing/deduplicating code the first thing you should do is identify what is it that you're repeating a lot.

On your code, for instance, we see this "structure" many times:

if x == <SOME DAY>:
    y = ((<SOME INTEGER> + Day) % 7)
    print(calendar[y]) 
    exit()

So we'd like to abstract that away, so we only write it once (see DRY principle).

So we'd like to write something like this:

def increment_days_and_print(day, increment):
    y = ((day + increment) % 7)
    print(calendar[y]) 
    exit()

Then we can replace all that repeating code with a call to the function we defined:

def increment_days_and_print(day, increment):
    y = ((day + increment) % 7)
    print(calendar[y]) 
    exit()

calendar = {1:"Sunday", 2:"Monday", 3:"Tuesday", 4:"Wednesday", 5:"Thursday", 6:"Friday", 0:"Saturday"}
Day = eval(input("Enter how many days you want to look into the future: "))
todayDate = datetime.date.today()
x = todayDate.strftime("%A")

if x == "Sunday":
    increment_days_and_print(1, Day)
if x == "Monday":
    increment_days_and_print(2, Day)
if x == "Tuesday":
    increment_days_and_print(3, Day)
if x == "Wednesday":
    increment_days_and_print(4, Day)
if x == "Thursday":
    increment_days_and_print(5, Day)
if x == "Friday":
    increment_days_and_print(6, Day)
if x == "Saturday":
    increment_days_and_print(7, Day)

That's much better already, isn't it? We could also refactor it like this:

def increment_days_and_print(day, increment):
    y = ((day + increment) % 7)
    print(calendar[y]) 
    exit()

calendar = {1:"Sunday", 2:"Monday", 3:"Tuesday", 4:"Wednesday", 5:"Thursday", 6:"Friday", 0:"Saturday"}
Day = eval(input("Enter how many days you want to look into the future: "))
todayDate = datetime.date.today()
x = todayDate.strftime("%A")

if x == "Sunday":
    start = 1
if x == "Monday":
    start = 2
if x == "Tuesday":
    start = 3
if x == "Wednesday":
    start = 4
if x == "Thursday":
    start = 5
if x == "Friday":
    start = 6
if x == "Saturday":
    start = 7

increment_days_and_print(start, Day)

Finally, notice that we're essentially setting start to a svalue, given a value of x. This is exactly what a dict is for:

def increment_days_and_print(day, increment):
    y = ((day + increment) % 7)
    print(calendar[y]) 
    exit()

calendar = {1:"Sunday", 2:"Monday", 3:"Tuesday", 4:"Wednesday", 5:"Thursday", 6:"Friday", 0:"Saturday"}
Day = eval(input("Enter how many days you want to look into the future: "))
todayDate = datetime.date.today()
x = todayDate.strftime("%A")

weekday_numbers = {
  "Sunday": 1,
  "Monday": 2,
  "Tuesday": 3,
  "Wednesday": 4,
  "Thursday": 5,
  "Friday": 6,
  "Saturday": 0
}

start = weekday_numbers[x]

increment_days_and_print(start, Day)

Finally, doing some cleanup:

weekday_numbers = [
    (1, "Sunday"),
    (2, "Monday"),
    (3, "Tuesday"),
    (4, "Wednesday"),
    (5, "Thursday"),
    (6, "Friday"),
    (0, "Saturday")
]

num_to_weekday = dict((d, w) for (d, w) in weekday_numbers)
weekday_to_num = dict((w, d) for (d, w) in weekday_numbers)

increment = int(input("Enter how many days you want to look into the future: "))
today = datetime.date.today()
weekday = today.strftime("%A")
start = weekday_to_num[weekday]
next_day = ((start + increment) % 7)
print(num_to_weekday[next_day]) 

Since we only called the function once, we didn't need it anymore; it worked only as a tool to help us see what simplifications we could make along the way.

Upvotes: 1

Sayse
Sayse

Reputation: 43300

If you didn't wish to create an inverse dictionary there are multiple things you can do with your own code.

  • dont repeat yourself (the printing and exiting can be done after the if statement
  • use elif to avoid checking if statements unnecessarily (wouldn't currently happen with seperate exits though)
x = todayDate.strftime("%A")
if x == "Sunday" :
    y = ((1+ Day) % 7)
elif x == "Monday" :
    y = ((2+ Day) % 7)
elif x == "Tuesday" :
    y = ((3+ Day) % 7)
elif x == "Wednesday" :
    y = ((4+ Day) % 7)
elif x == "Thursday" :
    y = ((5+ Day) % 7)
elif x == "Friday" :
    y = ((6+ Day) % 7)
elif x == "Saturday" :
    y = ((7+ Day) % 7)
print(calendar[y]) 
exit()

Python 3.10 will bring along the match statement that will make this slightly more efficient

x = todayDate.strftime("%A")
match x:
    case "Sunday" :
        y = ((1+ Day) % 7)
    case "Monday" :
        y = ((2+ Day) % 7)
    case "Tuesday" :
        y = ((3+ Day) % 7)
    case "Wednesday" :
        y = ((4+ Day) % 7)
    case "Thursday" :
        y = ((5+ Day) % 7)
    case "Friday" :
        y = ((6+ Day) % 7)
    case "Saturday" :
        y = ((7+ Day) % 7)

Upvotes: 1

Mur4al
Mur4al

Reputation: 121

You can use timedelta to add any amount of time to a date.

from datetime import date, timedelta

x=5#or any amount of days you want
date = date.today()
new_date=date+timedelta(days=x)
print(new_date.strftime('%A'))

Upvotes: 1

orlp
orlp

Reputation: 117681

offset = {d: o for o, d in calendar.items()}
y = (offset[x] + day) % 7
print(calendar[y])

Upvotes: 2

Related Questions