Python Application: Print a Class Schedule

Python Application: Print a Class Schedule

People learning to program often struggle with how to decompose a problem into the steps necessary to write a program to solve that problem. This is one of a series of posts in which I take a problem and go through my decision-making process that leads to a program.

Problem: Given a file of days and times for classes that a student is enrolled in, print the schedule such that it looks like a calendar. I assume that you understand statements, conditionals, loops, lists, strings, functions, and file input/output.

You can find a video with more details at https://www.youtube.com/watch?v=MEIFmJ1LQdI

Design:

I start off by working an example by hand to understand what I want the final product to look like. The data is is CSV (comma separated value) format, with the first two lines being

#student,course,monday,tuesday,wednesday,thursday,friday,startTime
Darin,CSE 2315,0,1,0,1,0,16

I can see that the first line is a header line. This is useful for a human to understand the purpose of each value between commas, but I will need to deal with it when processing the file. I notice a couple of other things:

  • the start times of a class are in military time. This is good because it is much easier to determine the time order of classes. Had the times been in regular time format, then I would have had to deal with things like determining that 11am comes before 2pm.
  • a binary flag is used to determine if a class is taught on a given day. We can see in the example above that the class is taught on Tuesdays and Thursdays because of the ones in the pattern 0,1,0,1,0.

I now take the sample schedule and on paper represent it like I would in a calendar, which looks something like this:

11 |  CSE 1310|          |  CSE 1310|          | CSE 1310 |
   --------------------------------------------------------
12 |          |          |          |          |          |
   --------------------------------------------------------
13 | MATH 1426| ENGL 1301| MATH 1426| ENGL 1301|          |
   --------------------------------------------------------
14 |          |  IE 3301 |          |  IE 3301 |          |
   --------------------------------------------------------
15 |          |          |          |          |          |
   --------------------------------------------------------
16 |          |  CSE 2315|          |  CSE 2315|          |
   --------------------------------------------------------

Note that this is slightly modified output from my program. I had to remove some spaces in order to make things line up correctly on this webpage.

Now that I have hand-constructed a calendar schedule, I also notice something else. I did not include rows for time before my first class nor rows after my last class time. This is my preferred way to create the calendar so that there is not a lot of blank rows. To produce a calendar that only displays the times from my earliest class to my latest class, I need to find the min and max times. This is where having times in military time format really helps.

At this point I think I understand enough to write the code. The overall process is this:

  1. read and save schedule.csv
  2. determine the min and max times of the classes
  3. build an initial table with empty slots. There will be five columns, one for each day of the school week, but the number of rows will be based on the min and max times.
  4. populate the schedule with the class names
  5. print the final schedule

Final Program

"""
sample data structure of output
  #    Mon        Tue        Wed        Thu        Fri
  [[ CSE 1310,          ,  CSE 1310,          ,  CSE 1310],
   [MATH 1426,          , MATH 1426,          ,          ],
   [         ,          ,          ,          ,          ],
   [         ,   IE 3301,          ,   IE 3301,          ]]


pseudocode
  get min start time
  get max stop time

  build initial 2D structure

  for each course
    add to 2D structure

  for each cell of 2D structure
    if not zero
      print course
    else
      print padding
"""

##########################################
def timeRange( d ) :
    minTime = 23   # last hour of day
    maxTime = 0    # first hour of day

    for line in d :
        t = line.split(',')
        value = int(t[7])
        if value < minTime :
            minTime = value
        if value > maxTime :
            maxTime = value

    return minTime, maxTime


##########################################
def build2D(minTime, maxTime) :
    structure = [ ]
    while minTime <= maxTime :
        structure.append([0,0,0,0,0])
        minTime += 1

    return structure


##########################################
def populateSched(data, sched, minTime) :
    # sample data:  Darin,CSE 1310,1,0,1,0,1,11
    #       index:    0      1     2 3 4 5 6  7
    for line in data :
        t = line.split(',')
        day = 2    # column index for Monday
        while day < 7 :
            if int( t[day] ) == 1 :
                # elements of table have indices [hour][day]; these need
                # to be adjusted to a 2D list that begins at [0][0]
                sched[ int(t[7]) - minTime ][ day-2 ] = t[1]  # t[1] is course name
            day += 1

##########################################
def printSchedule(hour, d) :
    rows = len( d )
    cols = len( d[0] )

    r = 0
    while r < rows :
        print("%2d |" % hour, end="")
        c = 0
        while c < cols :
            if d[r][c] == 0 :
                print("           |", end="")
            else :
                s = d[r][c].center(11)
                print("%s|" % s, end="")

            c += 1

        print()   # print newline to end row
        print("  ", "-"*61)

        hour += 1
        r += 1

##########################################
#################  main  #################

fp = open("schedule.csv", "r")
data = fp.readlines()
fp.close()

#  check for header
if data[0][0] == "#" :
    data.pop(0)

minTime, maxTime = timeRange( data )

sched = build2D(minTime, maxTime) 
populateSched(data, sched, minTime) 

print("\n")
printSchedule(minTime, sched)
print("\n")

""" schedule.csv  
#student,course,monday,tuesday,wednesday,thursday,friday,startTime
Darin,CSE 2315,0,1,0,1,0,16
Darin,CSE 1310,1,0,1,0,1,11
Darin,ENGL 1301,0,1,0,1,0,13
Darin,IE 3301,0,1,0,1,0,14
Darin,MATH 1426,1,0,1,0,0,13
"""
Comments are closed.