Calendar Maker

Tags: short

This program generates printable text files of monthly calendars for the month and year you enter. Dates and calendars are a tricky topic in programming because there are so many different rules for determining the number of days in a month, which years are leap years, and which day of the week a particular date falls on. Fortunately, Python’s datetime module handles these details for you. This program focuses on generating the multiline string for the monthly calendar page.

calendar_maker.py
  1"""Calendar Maker, by Al Sweigart al@inventwithpython.com
  2Create monthly calendars, saved to a text file and fit for printing.
  3This code is available at https://nostarch.com/big-book-small-python-programming
  4Tags: short"""
  5
  6import datetime
  7
  8# Set up the constants:
  9DAYS = ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
 10        'Friday', 'Saturday')
 11MONTHS = ('January', 'February', 'March', 'April', 'May', 'June', 'July',
 12          'August', 'September', 'October', 'November', 'December')
 13
 14print('Calendar Maker, by Al Sweigart al@inventwithpython.com')
 15
 16while True:  # Loop to get a year from the user.
 17    print('Enter the year for the calendar:')
 18    response = input('> ')
 19
 20    if response.isdecimal() and int(response) > 0:
 21        year = int(response)
 22        break
 23
 24    print('Please enter a numeric year, like 2023.')
 25    continue
 26
 27while True:  # Loop to get a month from the user.
 28    print('Enter the month for the calendar, 1-12:')
 29    response = input('> ')
 30
 31    if not response.isdecimal():
 32        print('Please enter a numeric month, like 3 for March.')
 33        continue
 34
 35    month = int(response)
 36    if 1 <= month <= 12:
 37        break
 38
 39    print('Please enter a number from 1 to 12.')
 40
 41
 42def getCalendarFor(year, month):
 43    calText = ''  # calText will contain the string of our calendar.
 44
 45    # Put the month and year at the top of the calendar:
 46    calText += (' ' * 34) + MONTHS[month - 1] + ' ' + str(year) + '\n'
 47
 48    # Add the days of the week labels to the calendar:
 49    # (!) Try changing this to abbreviations: SUN, MON, TUE, etc.
 50    calText += '...Sunday.....Monday....Tuesday...Wednesday...Thursday....Friday....Saturday..\n'
 51
 52    # The horizontal line string that separate weeks:
 53    weekSeparator = ('+----------' * 7) + '+\n'
 54
 55    # The blank rows have ten spaces in between the | day separators:
 56    blankRow = ('|          ' * 7) + '|\n'
 57
 58    # Get the first date in the month. (The datetime module handles all
 59    # the complicated calendar stuff for us here.)
 60    currentDate = datetime.date(year, month, 1)
 61
 62    # Roll back currentDate until it is Sunday. (weekday() returns 6
 63    # for Sunday, not 0.)
 64    while currentDate.weekday() != 6:
 65        currentDate -= datetime.timedelta(days=1)
 66
 67    while True:  # Loop over each week in the month.
 68        calText += weekSeparator
 69
 70        # dayNumberRow is the row with the day number labels:
 71        dayNumberRow = ''
 72        for i in range(7):
 73            dayNumberLabel = str(currentDate.day).rjust(2)
 74            dayNumberRow += '|' + dayNumberLabel + (' ' * 8)
 75            currentDate += datetime.timedelta(days=1) # Go to next day.
 76        dayNumberRow += '|\n'  # Add the vertical line after Saturday.
 77
 78        # Add the day number row and 3 blank rows to the calendar text.
 79        calText += dayNumberRow
 80        for i in range(3):  # (!) Try changing the 4 to a 5 or 10.
 81            calText += blankRow
 82
 83        # Check if we're done with the month:
 84        if currentDate.month != month:
 85            break
 86
 87    # Add the horizontal line at the very bottom of the calendar.
 88    calText += weekSeparator
 89    return calText
 90
 91
 92calText = getCalendarFor(year, month)
 93print(calText)  # Display the calendar.
 94
 95# Save the calendar to a text file:
 96calendarFilename = 'calendar_{}_{}.txt'.format(year, month)
 97with open(calendarFilename, 'w') as fileObj:
 98    fileObj.write(calText)
 99
100print('Saved to ' + calendarFilename)

https://inventwithpython.com/bigbookpython/project8.html