#/usr/bin/env python3
import datetime as dt
import pandas as pd
import math
class Calendar(object):
# :(
modulecodemap = (
("COM00001C-A", "ICAR"), # Introduction to Computer Architectures 15
("COM00001H-A", "ARTS"), # Analysable Real-Time Systems 20
("COM00001I-A", "ARIN"), # Artificial Intelligence 20
("COM00002H-A", "CVIS"), # Computer Vision 20
("COM00002I-A", "COCO"), # Computability & Complexity 10
("COM00003C-A", "HACS"), # Human Aspects of Computer Science 20
("COM00003H-A", "EMBS"), # Embedded Systems Design & Implementation 20
("COM00004H-A", "ENAR"), # Enterprise Architecture 20
("COM00005C-A", "MFCS"), # Mathematical Foundations of Computer Science 20
("COM00005H-A", "GRAT"), # Computing by Graph Transformation 20
("COM00005I-A", "POPL"), # Principles of Programming Languages 20
("COM00006C-A", "NUMA"), # Numerical Analysis 10
("COM00006H-A", "ICOT"), # Information & Coding Theory 20
("COM00007C-A", "TPOP"), # Theory and Practice of Programming 20
("COM00007H-A", "INCA"), # Introduction to Neural Computing & Applications 20
("COM00007I-A", "SYAC"), # Systems Software & Compilers 30
("COM00008C-A", "SKIL"), # Skills, Knowledge & Independent Learning 5
("COM00008I-A", "SEPR"), # Software Engineering Project 30
("COM00009C-A", "FESC"), # Foundations in Electronics, Signals and Circuits 20
("COM00009H-A", "MAIG"), # Multi-Agent Interaction & Games 20
("COM00009I-A", "VIGR"), # Vision & Graphics 10
("COM00010C-A", "PROM"), # Programming of Micro-controllers 10
("COM00010H-A", "MLAP"), # Machine Learning & Applications 20
("COM00012H-A", "PCOC"), # Programming: Correctness by Construction 20
("COM00012I-A", "EMPR"), # Embedded Systems Project 30
("COM00013H-A", "PRBE"), # Project: Computer Science with Embedded Systems 40
("COM00014H-A", "PRBM"), # Project: Mathematics and Computer Science 40
("COM00015H-A", "PRBX"), # Project: Computer Science 40
("COM00016H-A", "IAPT"), # Interactive Application Programming Techniques 20
("COM00042M-A", "QIPR"), # Quantum Information Processing 10
("COM00045M-A", "QUCO"), # Quantum Computation 10
("COM00063M-A", "SAVE"), # Static Analysis & Verification 10
("COM00066M-A", "ALAS"), # Adaptive & Learning Agents 10
("COM00068M-A", "COPR"), # Constraint Programming 10
("COM00069M-A", "CRSY"), # Critical Systems 10
("COM00071M-A", "EVCO"), # Evolutionary Computation 10
("COM00073M-A", "GPIG"), # Group Project (Integrated Masters) 20
("COM00080M-A", "PRIS"), # Individual Project - Computer Science with Business Enterprise Systems 50
("COM00081M-A", "PRIA"), # Individual Project - Computer Science with Artificial Intelligence 50
("COM00081M-A", "PRIY"), # Individual Project - Computer Systems & Software Engineering 50
("COM00082M-A", "PSEC"), # Topics in Privacy & Security 10
("COM00085M-A", "SMAT"), # Software Measurement & Testing 10
("COM00087M-A", "SYAR"), # Systems Architecture 10
("COM00104M-A", "AVIS"), # Advanced Computer Vision 10
("COM00106M-A", "NLPR"), # Natural Language Processing 10
("COM00111M-A", "MODE"), # Model-Driven Engineering 10
("ELE00061M-A", "EVHW"), # Evolvable Hardware 10
("ELE00068M-A", "SWIN"), # Swarm Intelligence 10
)
def __init__(self, filename):
cols = ["start-date", "start-time", "end-date", "end-time",
"activity-type", "activity-name", "taught-by", "location",
"directions", "module", "activity-notes", "contact-details"]
self.df = pd.read_csv(filename, skipinitialspace=True, index_col=False,
skiprows=1, dayfirst=True, names=cols)
# Merge the date/time fields
self.df["start-date"] = pd.to_datetime(self.df["start-date"] + ' ' + self.df["start-time"], dayfirst=True)
self.df["end-date"] = pd.to_datetime(self.df["end-date"] + ' ' + self.df["end-time"], dayfirst=True)
self.df = self.df.drop("start-time", 1).drop("end-time", 1)
self.df.index = self.df["start-date"]
# Repurpose activity-name into something useful
self.df = self.df.rename(columns={"activity-name": "group-num"})
self.df["group-num"] = self.df["group-num"].str.split("/").str[-1].str.split().str[0]
# Get rid of useless fields
self.df = self.df.drop(["directions", "activity-notes",
"contact-details"], 1)
# Get rid of rows that are in the past
self.df = self.df[dt.datetime.now().strftime("%Y-%m-%d %H:%M") <= self.df["end-date"]]
self.df = self.df.sort()
def get_long_code(self, code):
"""raises StopIteration"""
return next((x[0] for x in self.modulecodemap if x[1] == code))
def get_next_lecture(self, code):
code = code.upper()
try:
longcode = self.get_long_code(code)
except StopIteration:
# Fine, we'll try with the existing code
longcode = code
module = self.df[self.df["module"] == longcode]
try:
first = module.iloc[0]
except:
return "Untimetabled module"
timestr = ""
if first["start-date"] is not dt.datetime.today():
timestr += first["start-date"].strftime("%Y-%m-%d")
timestr += first["start-date"].strftime(" %H:%M")
group = ""
if (module[(module["activity-type"].apply(str) == first["activity-type"]) &
(module["group-num"].apply(str) != first["group-num"])].shape[0] != 0):
group += "Group{} ".format(first["group-num"])
lecturers = first["taught-by"].split(' ') # double space
lecturerstr = lecturers[0]
for lecturer in lecturers[1:]:
if len(lecturer) + len(lecturerstr) + 3 <= 60:
lecturerstr += ", " + lecturer
else:
lecturerstr += " & others"
break
location = first["location"]
if math.isnan(location):
location = "unspecified"
return "{} {activity-type} {}in {} at {} with {}".format(code, group, location, timestr, lecturer, **first)
cal = Calendar("cs-calendar.csv")
print(cal.get_next_lecture("skil"))
#for _, row in cal.df.iterrows():
# if "Runciman" not in str(row["taught-by"]): continue
# print(row)
# input()