Is there a way to create an object that represents a certain month and can be iterated over?

At work we need to fill out a monthly pay-sheet saying all the classes we have taught. Each teacher teaches the exact same classes each day of the week.

What I am trying to do is allow the user to input a month, then create an object representing that month, and then loop over the object by day. If the day is Monday fill in the classes always taught on Monday by that teacher.

So far I have tried using the datetime module. I can figure out a way to put in a start and stop date, but not to create a month that I can handle the way I want to from a single piece of user input.

I was hoping to be able to set it up the the other employees could just input their name and the month and the program would do the rest as it isn't a tech savy environment. If anyone knows of a way this could be done with either datetime or another module I would be greatful.

2 answers

  • answered 2019-04-15 06:14 Masklinn

    dateutil.rrule is pretty much exactly what you need. The interface is a bit odd as the source material and primary use case is icalendar's recurrence rules and dateutil follows that terminology, but beyond that it should trivially handle your use-case.

  • answered 2019-04-15 06:47 Patrick Artner

    You can do this using datetime and timedelta - adding days to a starting day:

    import datetime
    
    # 0 == Monday, 1== Tuesday .... the list is the list of lessons taught on that day
    teach = {0: ["A","B"], 1:["C","D"],2:["E"],3:["A","E"], 4:["E","B","E"]}
    
    # get a starting month
    while True:
        try:
            month = int(input("Month [1-12]: "))
        except:
            continue
    
        if 1 <= month <= 12:
            break
    
    # date to start at
    start = datetime.datetime(2019,month,1)
    
    # create all days of that month 
    m = [[date, teach.get(date.weekday())]    # date  + lessons
         for date in (start + datetime.timedelta(days=n) for n in range(32))  # all days
         if date.month == month]  # only those that fit into the month
    
    print()
    for day in m:
        print(day) 
    

    Output:

    Month [1-12]: 4
    [datetime.datetime(2019, 4, 1, 0, 0), ['A', 'B']]
    [datetime.datetime(2019, 4, 2, 0, 0), ['C', 'D']]
    [datetime.datetime(2019, 4, 3, 0, 0), ['E']]
    [datetime.datetime(2019, 4, 4, 0, 0), ['A', 'E']]
    [datetime.datetime(2019, 4, 5, 0, 0), ['E', 'B', 'E']]
    [datetime.datetime(2019, 4, 6, 0, 0), None]
    [datetime.datetime(2019, 4, 7, 0, 0), None]
    [datetime.datetime(2019, 4, 8, 0, 0), ['A', 'B']]
    [datetime.datetime(2019, 4, 9, 0, 0), ['C', 'D']]
    [datetime.datetime(2019, 4, 10, 0, 0), ['E']]
    [datetime.datetime(2019, 4, 11, 0, 0), ['A', 'E']]
    [datetime.datetime(2019, 4, 12, 0, 0), ['E', 'B', 'E']]
    [datetime.datetime(2019, 4, 13, 0, 0), None]
    [datetime.datetime(2019, 4, 14, 0, 0), None]
    [datetime.datetime(2019, 4, 15, 0, 0), ['A', 'B']]
    [datetime.datetime(2019, 4, 16, 0, 0), ['C', 'D']]
    [datetime.datetime(2019, 4, 17, 0, 0), ['E']]
    [datetime.datetime(2019, 4, 18, 0, 0), ['A', 'E']]
    [datetime.datetime(2019, 4, 19, 0, 0), ['E', 'B', 'E']]
    [datetime.datetime(2019, 4, 20, 0, 0), None]
    [datetime.datetime(2019, 4, 21, 0, 0), None]
    [datetime.datetime(2019, 4, 22, 0, 0), ['A', 'B']]
    [datetime.datetime(2019, 4, 23, 0, 0), ['C', 'D']]
    [datetime.datetime(2019, 4, 24, 0, 0), ['E']]
    [datetime.datetime(2019, 4, 25, 0, 0), ['A', 'E']]
    [datetime.datetime(2019, 4, 26, 0, 0), ['E', 'B', 'E']]
    [datetime.datetime(2019, 4, 27, 0, 0), None]
    [datetime.datetime(2019, 4, 28, 0, 0), None]
    [datetime.datetime(2019, 4, 29, 0, 0), ['A', 'B']]
    [datetime.datetime(2019, 4, 30, 0, 0), ['C', 'D']]
    

    Doku:

    You would have to remove days that fall on special date where your school is closed - this only looks at the weekday.