Last active
August 29, 2015 14:02
-
-
Save sunaku/276e7717bdf51998b3bb to your computer and use it in GitHub Desktop.
Dumps course prerequisites for the given SJSU (San Jose State University http://www.sjsu.edu/) degree program as a DOT (Graphviz http://www.graphviz.org/) graph. You can play with the resulting graph by pasting it into the Vis.js playground (http://visjs.org/examples/graph/15_dot_language_playground.html) or you can convert it into a PDF with cl…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# | |
# Usage: ruby sjsu-course-prereqs.rb [PROGRAM_INFO_URL] | |
# | |
# Dumps course prerequisites for the given SJSU degree program as a DOT graph. | |
# If no PROGRAM_INFO_URL is given, the M.S. Computer Science program is used: | |
# | |
# http://www.sjsu.edu/cs/programs/mscs/program-info/ | |
# | |
# You can convert the graph into a PDF with clickable course links like this: | |
# | |
# ruby sjsu-course-prereqs.rb | dot -Tps2 | ps2pdf - output.pdf | |
# | |
# You can play with the graph by pasting it into the Vis.js playground here: | |
# | |
# http://visjs.org/examples/graph/15_dot_language_playground.html | |
# | |
# Written in 2014 by Suraj N. Kurapati <https://github.com/sunaku> | |
# | |
program_url = ARGV.shift || 'http://www.sjsu.edu/cs/programs/mscs/program-info/' | |
#----------------------------------------------------------------------------- | |
# list courses in degree program | |
#----------------------------------------------------------------------------- | |
require 'open-uri' | |
course_urls = open(program_url).read.scan(%r{"(.*?/courses/.*?)"}).flatten | |
course_url_prefix = File.dirname(course_urls.first) | |
courses = course_urls.map do |course_url| | |
File.basename(course_url, File.extname(course_url)).sub(/(?=\d)/, ' ') | |
end | |
#----------------------------------------------------------------------------- | |
# calculate course prerequisites | |
#----------------------------------------------------------------------------- | |
def prereqs_for_courses courses, url_prefix | |
Hash[ | |
courses.map do |course| | |
course_url = url_for_course(course, url_prefix) | |
prereqs = (open(course_url).read[/Prereq.*/] rescue warn course_url) | |
.to_s.scan(/([A-Z]{2,} \d+\w*)/).flatten | |
[course, prereqs] | |
end | |
] | |
end | |
def url_for_course course, url_prefix | |
"#{url_prefix}/#{course.sub(/ /,'')}.html" | |
end | |
prereqs_by_course = {} | |
loop do | |
new_courses = courses - prereqs_by_course.keys | |
break if new_courses.empty? | |
prereqs_by_course.merge! prereqs_for_courses(new_courses, course_url_prefix) | |
courses = prereqs_by_course.to_a.flatten.uniq | |
end | |
#----------------------------------------------------------------------------- | |
# print prerequisites as a graph | |
#----------------------------------------------------------------------------- | |
graph = [ | |
'digraph G {', | |
"graph [label=#{program_url.inspect}, labelloc=t];", | |
'node [fontcolor=blue];', | |
prereqs_by_course.flat_map do |course, prereqs| | |
course_url = url_for_course(course, course_url_prefix) | |
prereqs.map {|prereq| "#{course.inspect} -> #{prereq.inspect};" } | |
.unshift("#{course.inspect} [URL=#{course_url.inspect}];") | |
end.sort.join(?\n), | |
'}' | |
].join(?\n) | |
puts graph |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment