-1

I'm trying to extend Python - Iterate thru month dates and print a custom output and add an addtional functionality to check if a date in the given date range is national holiday, print "NH" and that corresponding date.

Ex: 2020-05-04 & 2020-05-14 are national holidays and that date alone should be printed like enter image description here

import sys
from datetime import date, datetime, timedelta

year = int(sys.argv[1])
month = int(sys.argv[2])
st_dt = int(sys.argv[3])
en_dt = int(sys.argv[4])
public_holiday = sys.argv[5].split(',')

ph = []
for d in public_holiday:
    ph.append(date(year, month, int(d)))

def daterange(startDate, endDate, delta=timedelta(days=1)):
    currentDate = startDate
    while currentDate <= endDate:
        yield currentDate
        currentDate += delta

allDays = {}
_lastDayType = None

for dte in daterange(date(year, month, st_dt), date(year, month, en_dt), delta=timedelta(days=1)):
    #print(f"sdfdsfsdf:  {dte.weekday()}")
    if dte.weekday() < 5:
         _dayType = 'working'
    else:
        _dayType = 'weekend'

    _weeknum = dte.strftime("%V")
    _key = (_weeknum, _dayType)
    if _key not in allDays:
        allDays[_key] = []
    allDays[_key].append(dte)

for k,v in allDays.items():
    week_end = ''
    gov_hol = ''
    if len(v) == 1:
        first, last = v[0], v[0]
    elif len(v) == 2 and k[1] == 'weekend':
        first, last, week_end = v[0], v[-1], 'YES'
    elif ph in allDays.values():
        gov_hol, first, last = 'NH', v[0], v[0]
    else:
        first, last = v[0], v[-1]


    print(f"{gov_hol}, {first} >> {last} >> {len(v)} >> {week_end}")

Input args: date.py 2020 5 1 31 "4, 14"

Currently, elif ph in allDays.values(): is not matching condition.

Current Output

2020-05-01 >> 2020-05-01 >> 1 >>  >> 
2020-05-02 >> 2020-05-03 >> 2 >> YES >> 
2020-05-04 >> 2020-05-08 >> 5 >>  >> 
2020-05-09 >> 2020-05-10 >> 2 >> YES >> 
2020-05-11 >> 2020-05-15 >> 5 >>  >> 
2020-05-16 >> 2020-05-17 >> 2 >> YES >> 
2020-05-18 >> 2020-05-22 >> 5 >>  >> 
2020-05-23 >> 2020-05-24 >> 2 >> YES >> 
2020-05-25 >> 2020-05-29 >> 5 >>  >> 
2020-05-30 >> 2020-05-31 >> 2 >> YES >> 

3rd column: number of days 4th column : prints "YES" if its a weekend

Rookie1999
  • 111
  • 1
  • 8
  • 1
    Please don't post images of code, data, or Tracebacks. Copy and paste it as text then format it as code (select it and type `ctrl-k`) ... [Discourage screenshots of code and/or errors](https://meta.stackoverflow.com/questions/303812/discourage-screenshots-of-code-and-or-errors) – wwii Jun 03 '20 at 15:16
  • @wwii : Apologies, Will keep in mind. – Rookie1999 Jun 03 '20 at 15:18
  • `ph` looks like it is a list, is it? – wwii Jun 03 '20 at 15:18
  • @wwii : Yes, you're right. `ph` output is `[datetime.date(2020, 5, 4), datetime.date(2020, 5, 14)]` – Rookie1999 Jun 03 '20 at 15:20
  • Does this answer your question? [Test if lists share any items in python](https://stackoverflow.com/questions/3170055/test-if-lists-share-any-items-in-python) – wwii Jun 03 '20 at 15:22
  • @wwii: No unfortunately. – Rookie1999 Jun 03 '20 at 15:24
  • ?? `a = [datetime.date(2020, 5, 4), datetime.date(2020, 5, 14)]; d = {1:datetime.date(2020, 5, 4),2:datetime.date(2020, 5, 5)}; not set(a).isdisjoint(d.values()) --> True` – wwii Jun 03 '20 at 15:32
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/215246/discussion-between-rookie1999-and-wwii). – Rookie1999 Jun 03 '20 at 16:14

1 Answers1

1

In general, everything you want the dates to be grouped by needs to be added to the dictionary keys:

year, month, st_dt, en_dt, public_holiday = 2020, 5, 1, 31, (4, 14)

ph = []
for d in public_holiday:
    ph.append(date(year, month, int(d)))

def daterange(startDate, endDate, delta=timedelta(days=1)):
    currentDate = startDate
    while currentDate <= endDate:
        yield currentDate
        currentDate += delta

allDays = {}
_lastDayType = None

for dte in daterange(date(year, month, st_dt), date(year, month, en_dt), delta=timedelta(days=1)):
    if dte.weekday() < 5:
         _dayType = 'working'
    else:
        _dayType = 'weekend'

    _hol = dte in ph                   # True or False
    _weeknum = dte.strftime("%V")
    _key = (_weeknum, _dayType, _hol)  # make unique rows!
    if _key not in allDays:
        allDays[_key] = []
    allDays[_key].append(dte)

for k,v in allDays.items():
    week_end = ''
    gov_hol = k[-1]
    if len(v) == 1:
        first, last = v[0], v[0]
    elif len(v) == 2 and k[1] == 'weekend':
        first, last, week_end = v[0], v[-1], 'YES'
    else:
        first, last = v[0], v[-1]

    print(f"{gov_hol}, {first} >> {last} >> {len(v)} >> {week_end}")

Output:

False, 2020-05-01 >> 2020-05-01 >> 1 >> NO
False, 2020-05-02 >> 2020-05-03 >> 2 >> YES
True, 2020-05-04 >> 2020-05-04 >> 1 >> NO
False, 2020-05-05 >> 2020-05-08 >> 4 >> NO
False, 2020-05-09 >> 2020-05-10 >> 2 >> YES
False, 2020-05-11 >> 2020-05-15 >> 4 >> NO
True, 2020-05-14 >> 2020-05-14 >> 1 >> NO
False, 2020-05-16 >> 2020-05-17 >> 2 >> YES
False, 2020-05-18 >> 2020-05-22 >> 5 >> NO
False, 2020-05-23 >> 2020-05-24 >> 2 >> YES
False, 2020-05-25 >> 2020-05-29 >> 5 >> NO
False, 2020-05-30 >> 2020-05-31 >> 2 >> YES
Maurice Meyer
  • 17,279
  • 4
  • 30
  • 47