Skip to content

Instantly share code, notes, and snippets.

@htsutsui
Last active July 22, 2022 12:58
Show Gist options
  • Save htsutsui/b8a3cab7d5f30e7c063648c04b5e4797 to your computer and use it in GitHub Desktop.
Save htsutsui/b8a3cab7d5f30e7c063648c04b5e4797 to your computer and use it in GitHub Desktop.
ELMS Moodle の参加者リストや『北海道大学 シラバス・成績入力システム』の履修者リストをいろいろするメモがてらRuby script.
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'csv'
# Parse student lists from
# - ELMS Moodle and
# - "HOKKAIDO Univ. Entry System of Syllabi and Academic Records"
# and compare them. The script checks only names and student IDs.
#
# - ELMS Moodle: can export CSV student list.
# - HOKKAIDO Univ. Entry System of Syllabi and Academic Records:
# can export only password encrypted xlsx file of the student list.
#
# The following may convert the encrypted xlsx to CSV.
#
# msoffcrypto-tool meibo.xlsx meibo_decrypted.xlsx -p password
# libreoffice --headless --convert-to csv:"Text - txt - csv (StarCalc)":44,34,76 --outdir . meibo_decripted.xlsx
# Simple CSV parser
def parse_csv(file)
CSV.read(file, encoding: 'BOM|UTF-8', headers: true).map do |i|
# Use hankaku space
i.to_hash.transform_values { |j| j ? j.gsub(/ |/, ' ').strip : j }
end
end
class Hash
# Parse ELMS Moodle's student list
def moodle_entry_to_list_line
return nil if self['姓'] =~ /^p\d{8}/
self['ELMS ID'] = self['ELMS ID'].scan(/\d+/)[0]
['ELMS ID', '姓', '名'].map { |j| self[j] }
end
# Parse student list of
# "HOKKAIDO Univ. Entry System of Syllabi and Academic Records."
def record_system_entry_to_list_line
%w[学生番号 氏名].map { |j| self[j] }
end
end
# The parser
def parse(file)
data = parse_csv(file)
mode = data[0]['ELMS ID'] ? :moodle : :record_system
data.map do |i|
if mode == :moodle
i.moodle_entry_to_list_line
else
i.record_system_entry_to_list_line
end
end.compact.map { |i| [i[0], i[1..i.size].join(' ')] }
end
# Check (diff) two lists
def check(src, dst)
# 0 始まりを学生だと想定
src, dst = [src, dst].map { |j| j.filter { |i| i[0] =~ /^0/ } }
return if src == dst
pp [:only_in_src, src - dst]
pp [:only_in_dst, dst - src]
end
if __FILE__ == $PROGRAM_NAME
data = parse(ARGV.shift).sort
if ARGV.size.positive?
data_record_system = parse(ARGV.shift).sort
check(data, data_record_system)
end
pp data
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment