Search code examples
pythonregexpython-3.xpython-datetime

Handling schedule in Python


I'm developing a function that binds multiple dates, but it doesn't work.

import datetime
prev_schdl = None
schdl_start_date = None
schdl_end_date = None
schdls = [(2019, 1, 1, 'aa'), (2019, 1, 5, 'vacation'), (2019, 1, 6, 'vacation'), (2019, 1, 7, 'vacation'), (2019, 1, 8, 'vacation'), (2019, 1, 9, 'vacation'), (2019, 1, 10, 'vacation'), (2019, 1, 11, 'vacation'), (2019, 1, 12, 'vacation'), (2019, 1, 13, 'vacation'), (2019, 1, 14, 'vacation'), (2019, 1, 15, 'vacation'), (2019, 1, 16, 'vacation'), (2019, 1, 17, 'vacation'), (2019, 1, 18, 'vacation'), (2019, 1, 19, 'vacation'), (2019, 1, 20, 'vacation'), (2019, 1, 21, 'vacation'), (2019, 1, 22, 'vacation'), (2019, 1, 23, 'vacation'), (2019, 1, 24, 'vacation'), (2019, 1, 25, 'vacation'), (2019, 1, 26, 'vacation'), (2019, 1, 27, 'vacation'), (2019, 1, 28, 'vacation'), (2019, 1, 29, 'vacation'), (2019, 1, 30, 'vacation'), (2019, 1, 31, 'vacation'), (2019, 2, 1, 'vacation'), (2019, 2, 2, 'vacation'), (2019, 2, 3, 'vacation'), (2019, 2, 4, 'vacation\nbb'), (2019, 2, 5, 'vacation\naa'), (2019, 2, 6, 'vacation\nbb'), (2019, 2, 7, 'vacation'), (2019, 2, 8, 'vacation'), (2019, 2, 9, 'vacation'), (2019, 2, 10, 'vacation'), (2019, 2, 11, 'vacation'), (2019, 2, 12, 'vacation'), (2019, 2, 13, 'vacation'), (2019, 2, 14, 'vacation'), (2019, 2, 15, 'vacation'), (2019, 2, 16, 'vacation'), (2019, 2, 17, 'vacation'), (2019, 2, 18, 'vacation'), (2019, 2, 19, 'vacation'), (2019, 2, 20, 'vacation'), (2019, 2, 21, 'vacation'), (2019, 2, 22, 'vacation'), (2019, 2, 23, 'vacation'), (2019, 2, 24, 'vacation'), (2019, 2, 25, 'vacation'), (2019, 2, 26, 'vacation'), (2019, 2, 27, 'vacation'), (2019, 2, 28, 'vacation')]
body = str()

for i in schdls:
    date = datetime.date(int(i[0]), int(i[1]), int(i[2]))
    prsnt_schdl = i[3]

    if prsnt_schdl:
        if not schdl_start_date:
            schdl_start_date = date
            schdl_end_date = date

        if prsnt_schdl == prev_schdl:
            schdl_end_date = date
        elif schdl_start_date:
            if not schdl_start_date == schdl_end_date:
                body = "%s%s(%s)~%s(%s):\n%s\n" % (
                    body, schdl_start_date, "weekday", schdl_end_date,
                    "weekday", prev_schdl)  # YYYY-MM-DD(Weekday)
            body = "%s%s(%s):\n%s\n" % (body, date, "weekday", prsnt_schdl)  # YYYY-MM-DD(Weekday)
            schdl_start_date = None
            schdl_end_date = None

        prev_schdl = prsnt_schdl

if prev_schdl:
    body = "%s%s(%s)~%s(%s):\n%s\n" % (body, schdl_start_date, "weekday", schdl_end_date,
                                       "weekday", prev_schdl)  # YYYY-MM-DD(Weekday)

print(body)

Expected value(body in code):

2019-01-01(weekday):
aa
2019-01-05(weekday)~2019-02-03(weekday):
vacation
2019-02-04(weekday):
vacation
bb
2019-02-05(weekday):
vacation
aa
2019-02-06(weekday):
vacation
bb
2019-02-07(weekday)~2019-02-28(weekday):
vacation

What it prints:

2019-01-01(weekday):
aa
2019-01-05(weekday):
vacation
2019-01-06(weekday)~2019-02-03(weekday):
vacation
2019-02-04(weekday):
vacation
bb
2019-02-05(weekday):
vacation
aa
2019-02-06(weekday):
vacation
bb
2019-02-07(weekday):
vacation
2019-02-08(weekday)~2019-02-28(weekday):
vacation

It prints January 5 and February 7 separately.


Solution

  • If I understand you right, simple itertools.groupby is what you need:

    from itertools import groupby
    
    schdls = [(2019, 1, 1, 'aa'), (2019, 1, 5, 'vacation'), (2019, 1, 6, 'vacation'), (2019, 1, 7, 'vacation'), (2019, 1, 8, 'vacation'), (2019, 1, 9, 'vacation'), (2019, 1, 10, 'vacation'), (2019, 1, 11, 'vacation'), (2019, 1, 12, 'vacation'), (2019, 1, 13, 'vacation'), (2019, 1, 14, 'vacation'), (2019, 1, 15, 'vacation'), (2019, 1, 16, 'vacation'), (2019, 1, 17, 'vacation'), (2019, 1, 18, 'vacation'), (2019, 1, 19, 'vacation'), (2019, 1, 20, 'vacation'), (2019, 1, 21, 'vacation'), (2019, 1, 22, 'vacation'), (2019, 1, 23, 'vacation'), (2019, 1, 24, 'vacation'), (2019, 1, 25, 'vacation'), (2019, 1, 26, 'vacation'), (2019, 1, 27, 'vacation'), (2019, 1, 28, 'vacation'), (2019, 1, 29, 'vacation'), (2019, 1, 30, 'vacation'), (2019, 1, 31, 'vacation'), (2019, 2, 1, 'vacation'), (2019, 2, 2, 'vacation'), (2019, 2, 3, 'vacation'), (2019, 2, 4, 'vacation\nbb'), (2019, 2, 5, 'vacation\naa'), (2019, 2, 6, 'vacation\nbb'), (2019, 2, 7, 'vacation'), (2019, 2, 8, 'vacation'), (2019, 2, 9, 'vacation'), (2019, 2, 10, 'vacation'), (2019, 2, 11, 'vacation'), (2019, 2, 12, 'vacation'), (2019, 2, 13, 'vacation'), (2019, 2, 14, 'vacation'), (2019, 2, 15, 'vacation'), (2019, 2, 16, 'vacation'), (2019, 2, 17, 'vacation'), (2019, 2, 18, 'vacation'), (2019, 2, 19, 'vacation'), (2019, 2, 20, 'vacation'), (2019, 2, 21, 'vacation'), (2019, 2, 22, 'vacation'), (2019, 2, 23, 'vacation'), (2019, 2, 24, 'vacation'), (2019, 2, 25, 'vacation'), (2019, 2, 26, 'vacation'), (2019, 2, 27, 'vacation'), (2019, 2, 28, 'vacation')]
    
    for v, g in groupby(schdls, lambda k: k[3]):
        l = [*g]
        if l[0] != l[-1]:
            print('{}-{:02d}-{:02d}(weekday)~{}-{:02d}-{:02d}(weekday):'.format(*l[0][:3], *l[-1][:3]))
        else:
            print('{}-{:02d}-{:02d}(weekday):'.format(*l[0][:3]))
    
        print(v)
    

    Prints:

    2019-01-01(weekday):
    aa
    2019-01-05(weekday)~2019-02-03(weekday):
    vacation
    2019-02-04(weekday):
    vacation
    bb
    2019-02-05(weekday):
    vacation
    aa
    2019-02-06(weekday):
    vacation
    bb
    2019-02-07(weekday)~2019-02-28(weekday):
    vacation