Last active
July 22, 2022 12:58
-
-
Save htsutsui/b8a3cab7d5f30e7c063648c04b5e4797 to your computer and use it in GitHub Desktop.
ELMS Moodle の参加者リストや『北海道大学 シラバス・成績入力システム』の履修者リストをいろいろするメモがてらRuby script.
This file contains 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 | |
# 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