I hope I’ll be going next semester to Germany as an Erasmus student, and I’m now struggling with the Learning Agreement, courses, and timetables. In particular, there are a lot of interesting courses being offered by my guest university, but there are many factors to take into account when deciding what course you’re going to take, and one of them is timetable compatibility.

So, after a lot of struggle with the university’s website and trying to find some timetables, I’ve thought of making a timetable where I’ll put all the courses I’m interested in, so that I can see which ones are compatible with each other, i.e., which ones don’t overlap.

But the timetable has time slots of 15 minutes, from 8:00 to 18:15, and, of course, I’m naturally lazy. I don’t want to create a spreadsheet with as many rows as the 15-minutes-slots there are in the timetable!

And here’s when Python comes to the rescue!

I’ve coded a Python class that represents time, and which has methods for addition and logical comparison:

class Time:
def __init__(self, hour, minutes):
self.hour = hour
self.minutes = minutes
def normalize(self):
hour = self.hour
minutes = self.minutes
quotient = minutes / 60
if quotient > 0:
hour += quotient
minutes = minutes % 60
self.hour = hour
self.minutes = minutes
return self
def __add__(self, t):
"""add two times (sum)"""
hour = self.hour + t.hour
minutes = self.minutes + t.minutes
res = Time(hour, minutes)
res.normalize()
return res
def __mul__(self, k):
"""multiply a time and an integer constant k (product)"""
hour = self.hour * k
minutes = self.minutes * k
res = Time(hour, minutes)
res.normalize()
return res
def __lt__(self, t):
"""less than"""
if self.hour < t.hour or (self.hour == t.hour and self.minutes < t.minutes):
return True
else:
return False
def __eq__(self, t):
"""equal"""
if self.hour == t.hour and self.minutes == t.minutes:
return True
else:
return False
def __le__(self, t):
"""less or equal"""
return self < t or self == t
def __gt__(self, t):
"""greater than"""
return not self <= t
def __ge__(self, t):
"""greater or equal"""
return self > t or self == t
def __ne__(self, t):
"""not equal"""
return not self == t
def __str__(self):
hour = fill(str(self.hour), 2, '0')
minutes = fill(str(self.minutes), 2, '0')
return '%s:%s' % (hour, minutes)

I’ve implemented all the basic logical operators for comparison, because they’re very easy to implement, but we won’t be needing all of them.

In addition, I’ve also coded the `__str__`

method, which allows you to convert `Time`

objects into Python strings by just using the `str()`

function. This method needs a function called `fill`

, which is intended to pad or fill a string with some character, so that the string reaches a given maximum size. That is, for example, when you have a string `'8'`

that you want to be 2 characters long; you would fill it with zeroes until you reach that length: `'08'`

. The code for this function is pretty simple:

def fill(s, size, c=' ', position='before'):
"""s: string; c: char"""
if position == 'before':
s = c * (size - len(s)) + s
elif position == 'after':
s += c * (size - len(s))
return s

And, finally, this is the function to generate the time slots from a start time up to a given end time by some time increment:

def generate_timetable(start_time, interval=Time(0, 15), times=5, end_time=None):
timetable = []
if end_time is None:
end_time = start_time + interval*times
time = start_time
while time < end_time:
timetable.append(tuple([time, time + interval]))
time += interval
return timetable

In my case, I’ll just execute the following in the Python interpreter:

start_time = Time(8, 0)
end_time = Time(18, 15)
for start, end in generate_timetable(start_time, end_time=end_time):
print '%s-%s' % (start, end)

This prints the time slots that should go into each row of the spreadsheet, so I’ll just have to copy that, and I’ll be able to start filling my timetable!