How to write a if conditional stored in a variable?

1954
13
Jump to solution
07-10-2017 10:26 AM
VishalShah2
Occasional Contributor II

I am currently writing a script where it's to automate generating reports for end of quarter reports. Part of the naming convention for the folders includes Q1, Q2, Q3, or Q4 based on which quarter it is for based on the date it is generated. So far, my code looks like this:

import arcpy
import datetime

date = datetime.date.today()

quarter = 'Q1' if '2017-01-01' =< str(date) =< '2017-03-31' elif 'Q2' if '2017-04-01' =< str(date) =< '2017-06-30' elif 'Q3' if '2017-07-01' =< str(date) =< '2017-09-30' else 'Q4'‍‍‍‍‍‍

My issue is that I get an output of Q4 when I try

print quarter‍

. The output generated should have been Q3 as I ran this today (July 10, 2017). If I change the ending of the code to be

'Q4' if '2017-10-01' =< str(date) =< '2017-12-31'‍‍

, the result would be a syntax error. What am I doing wrong and how can I fix it but also stored the if conditional in one line and set it equal to the variable quarter?

0 Kudos
1 Solution

Accepted Solutions
AlexanderBrown5
Occasional Contributor II

Vishal,

From this example:

Python get first and last day of current calendar quarter - Stack Overflow 

You can do something like:

import bisect
import datetime as dt

def get_quarter():
    today = dt.date.today()
    qbegins = [dt.date(today.year, month, 1) for month in (1,4,7,10)]
    quarter = bisect.bisect(qbegins, today)
    return quarter
    ## Following line will return first day of the quarter
    # return str(qbegins[idx-1])


quarter_id = get_quarter()
print quarter_id

~Alex

View solution in original post

13 Replies
BlakeTerhune
MVP Regular Contributor

That is a complex set of conditional statements that should really be on separate lines. However, since your date is already a datetime object, some simple math will determine the quarter.

date = datetime.date.today()
quarter = "Q{}".format((date.month-1)//3 + 1)
print quarter‍‍‍
VishalShah2
Occasional Contributor II

Based on the responses in the other forum, something like this should work:

for m in range(1, 13):
     print (m-1)/3+1‍‍‍‍

where the outcome is:

1 1 1 2 2 2 3 3 3 4 4 4

I can't think of a way that will take my date = datetime.date.today()  and use the math they provided on that to check over my date to determine which quarter it belongs to.

**UPDATE**

Based on Blake's update, this may be the easiest solution.

0 Kudos
DanPatterson_Retired
MVP Emeritus
d = ['2017-01-01','2017-03-31', '2017-06-30', '2017-09-30', '2017-12-31']
qs = ['', 'Q1', 'Q2', 'Q3', 'Q4']
dts = ['2017-03-30', '2017-04-02', '2017-09-30','2017-12-12' ]
for i in dts:
    lt = [i <= j for j in d]
    q = qs[-sum(lt)]
    print("Date: {}, Quarter {}".format(i, q))‍‍‍‍‍‍‍‍‍‍‍‍

This example just assumes a list of dates.. modify as needed.  basic reverse slicing is used, hence the extra '' in the quarters list (qs) and Ijust included the upper date for the quarter dates (dts).  you could get this into a single list comprehension, but I am not sure that you need to go that far

AlexanderBrown5
Occasional Contributor II

Vishal,

From this example:

Python get first and last day of current calendar quarter - Stack Overflow 

You can do something like:

import bisect
import datetime as dt

def get_quarter():
    today = dt.date.today()
    qbegins = [dt.date(today.year, month, 1) for month in (1,4,7,10)]
    quarter = bisect.bisect(qbegins, today)
    return quarter
    ## Following line will return first day of the quarter
    # return str(qbegins[idx-1])


quarter_id = get_quarter()
print quarter_id

~Alex

VishalShah2
Occasional Contributor II

Alexander,

Thank you so much! I wasn't aware of bisect in python or it's functionality but I tried it the way you recommended it except instead of doing import datetime as dt, I left it as import datetime only and used my predefined date variable instead of today. still resulted in getting the right value!

KevinDunlop
Occasional Contributor III

I am not sure why you want to have it all as a 1 line.  It makes it very hard to read.  But if you must then use this code:

import arcpy
import datetime

date = datetime.date.today()
quarter = 'Q1' if '2017-01-01' <= str(date) and str(date) <= '2017-03-31' else 'Q2' if '2017-04-01' <= str(date) and str(date) <= '2017-06-30' else 'Q3' if '2017-07-01' <= str(date) and str(date) <= '2017-09-30' else 'Q4'

You had several things wrong.  First, the <= was backwards (you had =<).  Secondly, you can't do 1 > x > 3.  It has to be 1 > x and x > 3.  Finally, when you do 1 line if statements, you need to use else, not elif since you are basically doing nested if statements.  Hopefully this helps.

VishalShah2
Occasional Contributor II

Thank you for that Kevin! I am contemplating between using your method and Alexander's. As you said, having it in one line makes it harder to read (but your method is in my opinion a bit more simple compared to having to define a function).

0 Kudos
VishalShah2
Occasional Contributor II

Kevin,

On a slightly separate note, is it possible to make the year a rolling year? For example, leaving 2017 for now is fine, but say it gets to be 2018, would I have to go back into the code to change the year manually, or can the year change in the code by what year it's in?

0 Kudos
AlexanderBrown5
Occasional Contributor II

Vishal,

That is why I like the function method, you can just use the date-time module and not have to alter your code.

~Alex