-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
205 lines (195 loc) · 16.8 KB
/
index.html
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style/app.css" type="text/css" />
<link rel="stylesheet" href="style/ng-table.css" type="text/css" />
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js"></script>
<script src="libs/jquery/jquery-2.1.1.min.js"></script>
<script src="libs/ng-table/ng-table.js"></script>
<script src="cookies.js"></script>
<script src="Cookies.js"></script>
<script src="serialization.js"></script>
<script src="course.js"></script>
<script src="specialization.js"></script>
<script src="app.courselistcontroller.js"></script>
<script src="app.coursematrixcontroller.js"></script>
<script src="app.speclistcontroller.js"></script>
<script src="app.js"></script>
<script>
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date(); a = s.createElement(o),
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-70086439-1', 'auto');
ga('send', 'pageview');
</script>
</head>
<body ng-app="omscs-course-app" ng-init="toshow='courselist'">
<div nav-tabs class="navcontainer">
<ul class="nav">
<li><label ng-click="toshow='courselist'">Course list</label></li>
<li><label ng-click="toshow='matrix'">Courses vs Specializations</label></li>
<li><label ng-click="toshow='specializations'">Specializazion list</label></li>
<li><label ng-click="toshow='info'">Info/About</label></li>
</ul>
</div>
<div ng-controller="courselistcontroller as ctrl" ng-show="toshow=='courselist'" id="coursectrl">
<div class="config-top">
Select availability:
<select ng-options="item.id as item.text for item in ctrl.semesterOptions" ng-model="ctrl.currentSelection" required>
<option value=""></option>
</select>
Show foundational courses only:
<input type="checkbox" ng-model="onlyfoundational">
</div>
<table ng-table="ctrl.tableParams" class="table table-condensed table-bordered table-striped table-courselist">
<tr ng-repeat="course in $data" ng-show="ctrl.canShow(course.id) && (!onlyfoundational || course.foundational )" ng-class="{regular: !course.foundational, foundational: course.foundational, notavailable: !course.current, discontinued: course.available == -1, completed: course.completed}">
<td data-title="'Subject'" sortable="'subject'">{{course.subject}}</td>
<td data-title="'Course #'" sortable="'id'">{{course.id}}</td>
<td data-title="'Title'" sortable="'title'"><a target="_blank" ng-href="{{course.url}}">{{course.title}}</a></td>
<td data-title="'Available from'" sortable="'available'">{{ctrl.availabilityText(course.available)}}</td>
<td data-title="'Instructor(s)'"><label ng-repeat="i in course.instructors">{{i}}{{$last ? '' : ', '}}</label></td>
<td data-title="'Reviews'"><a target="_blank" ng-href="{{course.reviews}}" ng-show="course.reviews != ''">OMSCentral</a></td>
<td data-title="'Grades'"><a target="_blank" ng-href="{{course.grades}}" ng-show="course.reviews != ''">OMSCentral</a></td>
<td data-title="'Completed?'" class="completedbox" ng-class="{completed: course.completed}"><input type="checkbox" ng-model="course.completed" ng-change="omsapp.completedSelection(course.id)"></td>
</tr>
</table>
<div class="info-bottom">
Color codes:
<table>
<tr>
<td class="foundational">Foundational course</td>
<td class="regular">Regular course</td>
<td class="notavailable">Not available yet (as of Fall 2016)</td>
<td class="discontinued">Discountinued/not offered (as of Fall 2016)</td>
</tr>
</table>
</div>
</div>
<div ng-controller="coursematrixcontroller as ctrl" ng-show="toshow=='matrix'" id="matrixctrl">
<div class="config-top">
Select availability:
<select ng-options="item.id as item.text for item in ctrl.semesterOptions" ng-model="ctrl.currentSelection" required>
<option value=""></option>
</select>
Show foundational courses only:
<input type="checkbox" ng-model="onlyfoundational">
</div>
<table ng-table="ctrl.tableParams" class="table table-condensed table-bordered table-striped table-courselist">
<tr ng-repeat="course in $data" ng-show="ctrl.canShow(course.id) && (!onlyfoundational || course.foundational )" ng-class="{completed: course.completed}">
<td data-title="'Course #'" sortable="'id'" ng-class="{regular: !course.foundational, foundational: course.foundational, notavailable: !course.current, discontinued: course.available == -1}">{{course.id}}</td>
<td data-title="'Title'" sortable="'title'" ng-class="{regular: !course.foundational, foundational: course.foundational, notavailable: !course.current, discontinued: course.available == -1}"><a target="_blank" ng-href="{{course.url}}">{{course.title}}</a></td>
<td data-title="'Computational Perception and Robotics'" ng-class="ctrl.getCourseType(course.id, 'Computational Perception and Robotics')">{{ctrl.getCourseType(course.id, "Computational Perception and Robotics")}}</td>
<td data-title="'Computing Systems'" ng-class="ctrl.getCourseType(course.id, 'Computing Systems')">{{ctrl.getCourseType(course.id, "Computing Systems")}}</td>
<td data-title="'Interactive Intelligence'" ng-class="ctrl.getCourseType(course.id, 'Interactive Intelligence')">{{ctrl.getCourseType(course.id, "Interactive Intelligence")}}</td>
<td data-title="'Machine Learning'" ng-class="ctrl.getCourseType(course.id, 'Machine Learning')">{{ctrl.getCourseType(course.id, "Machine Learning")}}</td>
<td data-title="'Completed?'" class="completedbox" ng-class="{completed: course.completed}"><input type="checkbox" ng-model="course.completed" ng-change="omsapp.completedSelection(course.id)"></td>
</tr>
</table>
<div class="info-bottom">
Color codes:
<table>
<tr>
<td class="foundational">Foundational course</td>
<td class="regular">Regular course</td>
<td class="notavailable">Not available yet (as of Fall 2016)</td>
<td class="core">Core course in specialization (column)</td>
<td class="elective">Elective course in specialization (column)</td>
<td class="discontinued">Discountinued/not offered (as of Fall 2016)</td>
</tr>
</table>
</div>
</div>
<div ng-controller="speclistcontroller as ctrl" ng-show="toshow=='specializations'" id="speclistctrl">
<p><small>Sorry if the green table borders look weird in some cases, it is a known bug in Chrome for years now, they don't seem to want to fix it.</small></p>
<table ng-table="ctrl.tableParams" class="table table-condensed table-bordered table-striped table-courselist">
<tbody ng-repeat="spec in $data">
<!-- TODO I could solve this only by handling the first ([0]) element separately because of rowspans. Might need to investigate more -->
<tr>
<td rowspan="{{spec.numCourses}}" data-title="'Title'"><b>{{spec.title}}</b></td>
<td rowspan="{{spec.core.numCourses}}" data-title="'Core/Elective'"><b>Core courses</b><br/><i>Pick at least: {{spec.core.minCourses}}</i></td>
<td rowspan="{{spec.core.groups[0].courseList.length}}" data-title="'Course group'" ng-class="{completed: spec.core.groups[0].completed, completedbox: spec.core.groups[0].completed}">{{spec.core.groups[0].groupName}}<br /><i>Pick at least: {{spec.core.groups[0].minCourses}}</i></td>
<td data-title="'Course'" ng-init="a = ctrl.getById(spec.core.groups[0].courseList[0])" ng-class="{regular: !a.foundational, foundational: a.foundational, notavailable: !a.current, discontinued: a.available == -1, completed: a.completed}"><a target="_blank" ng-href="{{a.url}}">{{a.id}} - {{a.title}}</a></td>
<td data-title="'Completed?'" class="completedbox" ng-class="{completed: a.completed}"><input type="checkbox" ng-model="a.completed" ng-change="omsapp.completedSelection(a.id)"></td>
</tr>
<tr ng-repeat-start="group in spec.core.groups" ng-show='$index > 0'>
<td rowspan="{{group.courseList.length}}" ng-class="{completed: group.completed, completedbox: group.completed}">{{group.groupName}}<br /><i>Pick at least: {{group.minCourses}}</i></td>
<td ng-init="b = ctrl.getById(group.courseList[0])" ng-class="{regular: !b.foundational, foundational: b.foundational, notavailable: !b.current, discontinued: b.available == -1, completed: b.completed}"><a target="_blank" ng-href="{{b.url}}">{{b.id}} - {{b.title}}</a></td>
<td data-title="'Completed?'" class="completedbox" ng-class="{completed: b.completed}"><input type="checkbox" ng-model="b.completed" ng-change="omsapp.completedSelection(b.id)"></td>
</tr>
<tr ng-repeat='course in group.courseList' ng-init="c = ctrl.getById(course)" ng-show='$index> 0' ng-repeat-end>
<td ng-class="{regular: !c.foundational, foundational: c.foundational, notavailable: !c.current, discontinued: c.available == -1, completed: c.completed}"><a target="_blank" ng-href="{{c.url}}">{{c.id}} - {{c.title}}</a></td>
<td data-title="'Completed?'" class="completedbox" ng-class="{completed: c.completed}"><input type="checkbox" ng-model="c.completed" ng-change="omsapp.completedSelection(c.id)"></td>
</tr>
<tr>
<td rowspan="{{spec.electives.numCourses}}"><b>Electives</b><br /><i>Pick at least: {{spec.electives.minCourses}}</i></td>
<td rowspan="{{spec.electives.groups[0].courseList.length}}" ng-class="{completed: spec.electives.groups[0].completed, completedbox: spec.electives.groups[0].completed}">{{spec.electives.groups[0].groupName}}<br /><i>Pick at least: {{spec.electives.groups[0].minCourses}}</i></td>
<td ng-init="d = ctrl.getById(spec.electives.groups[0].courseList[0])" ng-class="{regular: !d.foundational, foundational: d.foundational, notavailable: !d.current, discontinued: d.available == -1, completed: d.completed}"><a target="_blank" ng-href="{{d.url}}">{{d.id}} - {{d.title}}</a></td>
<td data-title="'Completed?'" class="completedbox" ng-class="{completed: d.completed}"><input type="checkbox" ng-model="d.completed" ng-change="omsapp.completedSelection(d.id)"></td>
</tr>
<tr ng-repeat-start="group in spec.electives.groups" ng-show='$index > 0'>
<td rowspan="{{group.courseList.length}}" ng-class="{completed: group.completed, completedbox: group.completed}">{{group.groupName}}<br /><i>Pick at least: {{group.minCourses}}</i></td>
<td ng-init="e = ctrl.getById(group.courseList[0])" ng-class="{regular: !e.foundational, foundational: e.foundational, notavailable: !e.current, discontinued: e.available == -1, completed: e.completed}"><a target="_blank" ng-href="{{e.url}}">{{e.id}} - {{e.title}}</a></td>
<td data-title="'Completed?'" class="completedbox" ng-class="{completed: e.completed}"><input type="checkbox" ng-model="e.completed" ng-change="omsapp.completedSelection(e.id)"></td>
</tr>
<tr ng-repeat='course in group.courseList' ng-init="f = ctrl.getById(course)" ng-show='$index > 0' ng-repeat-end>
<td ng-class="{regular: !f.foundational, foundational: f.foundational, notavailable: !f.current, discontinued: f.available == -1, completed: f.completed}"><a target="_blank" ng-href="{{f.url}}">{{f.id}} - {{f.title}}</a></td>
<td data-title="'Completed?'" class="completedbox" ng-class="{completed: f.completed}"><input type="checkbox" ng-model="f.completed" ng-change="omsapp.completedSelection(f.id)"></td>
</tr>
</tbody>
</table>
<div class="info-bottom">
Color codes:
<table>
<tr>
<td class="foundational">Foundational course</td>
<td class="regular">Regular course</td>
<td class="notavailable">Not available yet (as of Fall 2016)</td>
<td class="discontinued">Discountinued/not offered (as of Fall 2016)</td>
</tr>
</table>
</div>
</div>
<div ng-show="toshow=='info'" class="infopage">
<h1>omscs-courses-app</h1>
<p>This a simple webpage/webapp to display the courses offered by <a href="http://www.omscs.gatech.edu/">Georgia Tech's OMSCS program</a>.</p>
<p>
The webpage is written in TypeScript and using the AngularJS library. The source code is <a href="https://github.com/Oszkar/omscs-courses">available on GitHub</a>.
I am not a web developer, take that into account when looking at the code.
Feel free to ontact me with ideas/suggestions or error reports. Pull requests are also welcome.
</p>
<h2>Views</h2>
<p>They are pretty straightforward.<p>
<ul>
<li><b>Course list</b> is just a list of courses with some details about them.</li>
<li><b>Courses vs Specializations</b> is a matrix view of which course is elective or core in which specialization.</li>
<li><b>Specializazion list</b> is, similarly ti the course list, a detailed view just the specializations themselves.</li>
</ul>
<h2>The data</h2>
<ul>
<li>The data is typed in manually from the official program page. This means that it can easily contain errors. Also, if something changes, I have to track that manually. Please bear that in mind.</li>
<li>In order to use the course numbers as numeric ID, I excluded the dashes from them, i.e. CS8803-001 became CS8803001.</li>
<li>
The <b>future courses</b> are mostly taken from gathering all the courses from each of the specializations' pages. The <a href="http://www.omscs.gatech.edu/courses/">official courses page</a>
usually lists the new courses for the next two semesters. Note that courses have been pushed back to later semesters before multiple times so only take them for certain when they appear in OSCAR.
Also, the specialization pages seem to be mostly a copypaste from the <a href="http://www.cc.gatech.edu/academics/degree-programs/masters/computer-science/specializations">offline MS specializations</a>.
This can mean, I think, that they list all the offline (on-campus) courses, maybe even ones that are not considered to have an online version. So be advised. Also, there may be future courses that are not part of any specialization - none of those are included in the list as there's no way of knowing other future courses than the
specialization courses.
</li>
<li>The database is just two JSONs: <a href="coursedata.json">coursedata.json</a> and <a href="specdata.json">specdata.json</a>.</li>
</ul>
<h2>Fun facts</h2>
<ul>
<li>As of Fall 2015, only 25.7% of the courses listed on the page are available. In Spring 2016, this ratio will raise to 31.4%.</li>
<li>Machine Learning specialization only possible to complete with substitute classes as of Fall 2015 (substitutes are included in this database). Even if all planned courses will be completed in 2016, it will still remain this way.</li>
<li>The offline program has non-CS(E) courses also (Modeling and Simulations and Scientific Computing specializations). Those are don't seem to be planned for the OMSCS program as of now.</li>
<li>The OMSCS program did have the High Performance Computing specialization also. It was removed sometime Fall 2015.</li>
</ul>
<h2>The author</h2>
<p>My name is Oszkar Jozsa. I started the OMSCS program Fall 2015. I am from Hungary and currently live in Tokyo, Japan. You can contact me at <i>jozsa [dot] oszkar [dot] gmail</i> or through the GitHub link above.</p>
</div>
</body>
</html>