-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcourse_parser.py
More file actions
143 lines (114 loc) · 5.5 KB
/
Copy pathcourse_parser.py
File metadata and controls
143 lines (114 loc) · 5.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import pandas as pd
import os
from annotate_files import get_spotlight_annotated_file_as_dictionary
from constants import COURSE_DATA_CSV, COURSE_DESCRIPTIONS_CSV, CSV_KEYS, DESCRIPTION_PLACEHOLDERS, COURSE_DATA, LECTURE_KEYS, PREPROCESSED_COURSE_DATA
def parse_courses():
"""
Parses the Course data and description csv files found in the
./data/CSV/ folder.
Returns a list of dictionaries representing courses.
"""
# Read course data file as list of dictionaries
courses = pd.read_csv(
COURSE_DATA_CSV, encoding="ISO-8859-1").filter(CSV_KEYS).to_dict(orient="records")
# Read course description into dataframe
descriptions = pd.read_csv(COURSE_DESCRIPTIONS_CSV, encoding="ISO-8859-1")
# Annotate course with description from course description csv. `Course ID` is used
# as a foreign key and then removed from the course dict.
for course in courses:
key = course.get("Course ID", None)
if key is None:
continue
key = int(key)
res = descriptions[descriptions["Course ID"] == int(key)]
if res.empty:
continue
course_descr = res["Descr"].values[0]
if not pd.isna(course_descr) and course_descr not in DESCRIPTION_PLACEHOLDERS:
course["Description"] = course_descr.strip()
# No longer need foreign key
course.pop("Course ID", None)
return courses
def get_paths_and_preprocessed_paths(base_path, base_preprocessed_path, key):
"""
Explores the path formed by appending `key` to `base_path` and `base_preprocessed_path` and returning a list of
dictionaries for each of the files found. The dictionary includes the "filepath" and the "preprocessed_file_path" for each file.
If no such path exists, None is returned.
"""
path = os.path.join(base_path, key)
preprocessed_path = os.path.join(base_preprocessed_path, key)
if not os.path.exists(path) or not os.path.exists(preprocessed_path):
return []
return [{
'filepath': os.path.join(path, f),
'preprocessed_file_path': os.path.join(preprocessed_path, f)[:-4]+".txt" #remove .pdf, add .txt
} for f in os.listdir(path)]
def get_paths(base_path, key):
"""
Explores the path formed by appending `key` to `base_path` and returning a list of
all the files found.
If no such path exists, None is returned.
"""
path = os.path.join(base_path, key)
if not os.path.exists(path):
return None
return [os.path.join(path, f) for f in os.listdir(path)]
def parse_local_courses():
"""
Parse the course data in the structured directories in the COURSE_DATA path.
Returns a list of dictionaries containing the courses found in the path.
"""
courses = []
abs_course_data_path = os.path.abspath(COURSE_DATA)
abs_preprocessed_course_data_path = os.path.abspath(PREPROCESSED_COURSE_DATA)
for course_path in os.listdir(abs_course_data_path):
course = {}
name, number = course_path.split()[0], course_path.split()[1]
course["Subject"], course["Number"] = name, number
# Use absolute paths for individual resources
preprocessed_course_path = os.path.join(abs_preprocessed_course_data_path, course_path)
course_path = os.path.join(abs_course_data_path, course_path)
# Check for course outline
outlines = []
outline_path_dicts = get_paths_and_preprocessed_paths(course_path, preprocessed_course_path, "Outlines")
for filepath_dict in outline_path_dicts:
annotations = get_spotlight_annotated_file_as_dictionary(filepath_dict['preprocessed_file_path'])
docDict = {
"annotations": annotations,
"file_path": filepath_dict['filepath']
}
outlines.append(docDict)
course["Outlines"] = outlines
# Explore lectures
lectures = parse_course_lectures(course_path, preprocessed_course_path)
course["Lectures"] = lectures
courses.append(course)
return courses
def parse_course_lectures(course_path, preprocessed_course_path):
"""
Parse the lecture data of a given course
"""
lectures = []
base_lecture_path = os.path.join(course_path, "Lectures")
base_preprocessed_lecture_path = os.path.join(preprocessed_course_path, "Lectures")
for lecture_dir in os.listdir(base_lecture_path):
lecture = {}
# Extract Lecture metadata
s = lecture_dir.split()
name, number = '_'.join(s[3:]), s[1]
lecture["Name"], lecture["Number"] = name, number
# Add all of the file paths found in the lecture_path subdirectory
lecture_path = os.path.join(base_lecture_path, lecture_dir)
preprocessed_lecture_path = os.path.join(base_preprocessed_lecture_path, lecture_dir)
for key in LECTURE_KEYS:
lecture[key] = []
filepath_dicts = get_paths_and_preprocessed_paths(lecture_path, preprocessed_lecture_path, key)
for filepath_dict in filepath_dicts:
annotations = get_spotlight_annotated_file_as_dictionary(filepath_dict['preprocessed_file_path'])
docDict = {
"annotations": annotations,
"file_path": filepath_dict['filepath']
}
lecture[key].append(docDict)
lectures.append(lecture)
return lectures