Skip to content

Instantly share code, notes, and snippets.

@lukasmartinelli
Created February 15, 2014 16:43
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lukasmartinelli/9021795 to your computer and use it in GitHub Desktop.
Save lukasmartinelli/9021795 to your computer and use it in GitHub Desktop.
Calculate the total time based on the summary and time of iCalendar Events
from icalendar import Calendar
from datetime import timedelta
from itertools import groupby
from operator import itemgetter
def calculate_time(event):
start = event['DTSTART'].dt
end = event['DTEND'].dt
return end - start
def lecturize(event):
summary = str(event['SUMMARY'])
for lecture in lectures:
if lecture in summary:
return lecture
def time_per_lecture(events):
sorted_events = sorted(events, key=itemgetter(0))
for key, group in groupby(sorted_events, itemgetter(0)):
yield (key, sum(map(itemgetter(1), group), timedelta()))
lectures = ['An1I', 'Math1I', 'Bsys1', 'CN1', 'EnglHTw', 'Prog1', 'ICTh']
file = open('examtime_export.ics', 'rb')
cal = Calendar.from_ical(file.read())
events = [(lecturize(e), calculate_time(e)) for e in cal.walk('vevent')]
used_time = dict(time_per_lecture(events))
total_time = sum(used_time.values(), timedelta())
for lecture, time in used_time.items():
print('{}\t{}h'.format(lecture, time.total_seconds() / 3600))
print('=============')
print('TOTAL\t{}h'.format(total_time.total_seconds() / 3600))
@lucbouge
Copy link

Dear Lukas,

Thanks for your Python script. Congrats for the nice style. I used it for checking next year schedules at my school, ENS Rennes in Brittany, France.

I encountered a problem. If the schedule does not contains the lectures only, then lecturize my return None, so that the sorting phase of time_per_lecture fails.

You might wish to add a filter to remove all None tuples from the events list. Here is my solution, although using filter would probably be more elegant.

events = [(lecturize(e), calculate_time(e)) for e in cal.walk('vevent')]
events = [e for e in events if e[0] != None]

Another possibility is to filter out at the construction of the events list.

Best regards,

Luc.

@weichaojie
Copy link

Perhaps it should be added such codes:
import sys
reload(sys)
sys.setdefaultencoding('utf8')

@shaundsouza96
Copy link

Hi Lukas,,

def calculate_time(event): start = event['DTSTART'].dt end = event['DTEND'].dt return start

In the code snippet above, event['DTEND'].dt throws a key error. Do you know if the module has changed since you wrote the code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment