academic_benchmarks 0.0.8 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/lib/academic_benchmarks/api/auth.rb +7 -5
- data/lib/academic_benchmarks/api/constants.rb +2 -20
- data/lib/academic_benchmarks/api/handle.rb +2 -22
- data/lib/academic_benchmarks/api/standards.rb +130 -85
- data/lib/academic_benchmarks/lib/attr_to_vals.rb +7 -0
- data/lib/academic_benchmarks/lib/inst_vars_to_hash.rb +2 -0
- data/lib/academic_benchmarks/standards/authority.rb +36 -10
- data/lib/academic_benchmarks/standards/disciplines.rb +21 -0
- data/lib/academic_benchmarks/standards/document.rb +15 -7
- data/lib/academic_benchmarks/standards/education_levels.rb +21 -0
- data/lib/academic_benchmarks/standards/grade.rb +5 -6
- data/lib/academic_benchmarks/standards/number.rb +23 -0
- data/lib/academic_benchmarks/standards/publication.rb +59 -0
- data/lib/academic_benchmarks/standards/section.rb +23 -0
- data/lib/academic_benchmarks/standards/standard.rb +38 -71
- data/lib/academic_benchmarks/standards/standards_forest.rb +4 -38
- data/lib/academic_benchmarks/standards/standards_tree.rb +2 -63
- data/lib/academic_benchmarks/standards/statement.rb +21 -0
- data/lib/academic_benchmarks/standards/subject.rb +4 -5
- data/lib/academic_benchmarks/standards/utilizations.rb +19 -0
- metadata +52 -20
- data/lib/academic_benchmarks/lib/remove_obsolete_children.rb +0 -10
- data/lib/academic_benchmarks/standards/course.rb +0 -22
- data/lib/academic_benchmarks/standards/has_relations.rb +0 -21
- data/lib/academic_benchmarks/standards/parent.rb +0 -41
- data/lib/academic_benchmarks/standards/subject_doc.rb +0 -22
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'academic_benchmarks/lib/attr_to_vals'
|
2
|
+
require 'academic_benchmarks/lib/inst_vars_to_hash'
|
3
|
+
|
4
|
+
module AcademicBenchmarks
|
5
|
+
module Standards
|
6
|
+
class Disciplines
|
7
|
+
include AttrToVals
|
8
|
+
include InstVarsToHash
|
9
|
+
|
10
|
+
attr_accessor :subjects
|
11
|
+
|
12
|
+
def self.from_hash(hash)
|
13
|
+
self.new(subjects: hash["subjects"])
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(subjects:)
|
17
|
+
@subjects = attr_to_vals(Subject, subjects)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,23 +1,31 @@
|
|
1
|
-
|
2
|
-
require_relative '../lib/remove_obsolete_children'
|
1
|
+
require 'academic_benchmarks/lib/inst_vars_to_hash'
|
3
2
|
|
4
3
|
module AcademicBenchmarks
|
5
4
|
module Standards
|
6
5
|
class Document
|
7
6
|
include InstVarsToHash
|
8
|
-
include RemoveObsoleteChildren
|
9
7
|
|
10
|
-
attr_accessor :
|
8
|
+
attr_accessor :guid, :descr, :publication, :adopt_year, :children
|
9
|
+
alias_method :description, :descr
|
11
10
|
|
12
11
|
def self.from_hash(hash)
|
13
|
-
self.new(
|
12
|
+
self.new(guid: hash["guid"], descr: hash["descr"], publication: hash["publication"], adopt_year: hash["adopt_year"])
|
14
13
|
end
|
15
14
|
|
16
|
-
def initialize(
|
17
|
-
@title = title
|
15
|
+
def initialize(guid:, descr:, publication:, adopt_year:, children: [])
|
18
16
|
@guid = guid
|
17
|
+
@descr = descr
|
18
|
+
@publication = attr_to_val_or_nil(Publication, publication)
|
19
|
+
@adopt_year = adopt_year
|
19
20
|
@children = children
|
20
21
|
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def attr_to_val_or_nil(klass, hash)
|
26
|
+
return nil if hash.nil?
|
27
|
+
klass.from_hash(hash)
|
28
|
+
end
|
21
29
|
end
|
22
30
|
end
|
23
31
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'academic_benchmarks/lib/attr_to_vals'
|
2
|
+
require 'academic_benchmarks/lib/inst_vars_to_hash'
|
3
|
+
|
4
|
+
module AcademicBenchmarks
|
5
|
+
module Standards
|
6
|
+
class EducationLevels
|
7
|
+
include AttrToVals
|
8
|
+
include InstVarsToHash
|
9
|
+
|
10
|
+
attr_accessor :grades
|
11
|
+
|
12
|
+
def self.from_hash(hash)
|
13
|
+
self.new(grades: hash["grades"])
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(grades:)
|
17
|
+
@grades = attr_to_vals(Grade, grades)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,19 +1,18 @@
|
|
1
|
-
|
1
|
+
require 'academic_benchmarks/lib/inst_vars_to_hash'
|
2
2
|
|
3
3
|
module AcademicBenchmarks
|
4
4
|
module Standards
|
5
5
|
class Grade
|
6
6
|
include InstVarsToHash
|
7
7
|
|
8
|
-
attr_accessor :
|
8
|
+
attr_accessor :code
|
9
9
|
|
10
10
|
def self.from_hash(hash)
|
11
|
-
self.new(
|
11
|
+
self.new(code: hash["code"])
|
12
12
|
end
|
13
13
|
|
14
|
-
def initialize(
|
15
|
-
@
|
16
|
-
@low = low
|
14
|
+
def initialize(code:)
|
15
|
+
@code = code
|
17
16
|
end
|
18
17
|
end
|
19
18
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'academic_benchmarks/lib/inst_vars_to_hash'
|
2
|
+
|
3
|
+
module AcademicBenchmarks
|
4
|
+
module Standards
|
5
|
+
class Number
|
6
|
+
include InstVarsToHash
|
7
|
+
|
8
|
+
attr_accessor :enhanced, :raw
|
9
|
+
|
10
|
+
def self.from_hash(hash)
|
11
|
+
self.new(
|
12
|
+
enhanced: hash["enhanced"],
|
13
|
+
raw: hash["raw"]
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(enhanced:, raw:)
|
18
|
+
@enhanced = enhanced
|
19
|
+
@raw = raw
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'academic_benchmarks/lib/attr_to_vals'
|
2
|
+
require 'academic_benchmarks/lib/inst_vars_to_hash'
|
3
|
+
|
4
|
+
module AcademicBenchmarks
|
5
|
+
module Standards
|
6
|
+
class Publication
|
7
|
+
include AttrToVals
|
8
|
+
include InstVarsToHash
|
9
|
+
|
10
|
+
attr_accessor :acronym, :descr, :guid, :authorities, :children
|
11
|
+
|
12
|
+
alias_method :code, :acronym
|
13
|
+
alias_method :description, :descr
|
14
|
+
|
15
|
+
def self.from_hash(hash)
|
16
|
+
self.new(
|
17
|
+
acronym: hash["acronym"],
|
18
|
+
descr: hash["descr"],
|
19
|
+
guid: hash["guid"],
|
20
|
+
authorities: hash["authorities"]
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(acronym:, descr:, guid:, authorities:, children: [])
|
25
|
+
@acronym = acronym
|
26
|
+
@descr = descr
|
27
|
+
@guid = guid
|
28
|
+
@authorities = attr_to_vals(Authority, authorities)
|
29
|
+
@children = children
|
30
|
+
end
|
31
|
+
|
32
|
+
# Children are standards, so rebranch them so we have
|
33
|
+
# the following structure:
|
34
|
+
#
|
35
|
+
# Publication -> Document -> Section -> Standard
|
36
|
+
def rebranch_children
|
37
|
+
@seen = Set.new()
|
38
|
+
@guid_to_obj = {}
|
39
|
+
new_children = []
|
40
|
+
@children.each do |child|
|
41
|
+
doc = reparent(child.document, new_children)
|
42
|
+
sec = reparent(child.section, doc.children)
|
43
|
+
sec.children.push(child)
|
44
|
+
end
|
45
|
+
@children.replace(new_children)
|
46
|
+
remove_instance_variable('@seen')
|
47
|
+
remove_instance_variable('@guid_to_obj')
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def reparent(object, children)
|
53
|
+
cached_object = (@guid_to_obj[object.guid] ||= object)
|
54
|
+
children.push(cached_object) if @seen.add? cached_object.guid
|
55
|
+
cached_object
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'academic_benchmarks/lib/inst_vars_to_hash'
|
2
|
+
|
3
|
+
module AcademicBenchmarks
|
4
|
+
module Standards
|
5
|
+
class Section
|
6
|
+
include InstVarsToHash
|
7
|
+
|
8
|
+
attr_accessor :guid, :descr, :children
|
9
|
+
|
10
|
+
alias_method :description, :descr
|
11
|
+
|
12
|
+
def self.from_hash(hash)
|
13
|
+
self.new(descr: hash["descr"], guid: hash["guid"])
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(guid:, descr:, children: [])
|
17
|
+
@guid = guid
|
18
|
+
@descr = descr
|
19
|
+
@children = children
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,80 +1,51 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'academic_benchmarks/lib/attr_to_vals'
|
2
|
+
require 'academic_benchmarks/lib/inst_vars_to_hash'
|
3
3
|
|
4
4
|
module AcademicBenchmarks
|
5
5
|
module Standards
|
6
6
|
class Standard
|
7
|
+
include AttrToVals
|
7
8
|
include InstVarsToHash
|
8
|
-
include RemoveObsoleteChildren
|
9
9
|
|
10
|
-
attr_reader :status, :
|
11
|
-
attr_writer :
|
12
|
-
attr_accessor :guid,
|
13
|
-
:
|
14
|
-
:
|
10
|
+
attr_reader :status, :children
|
11
|
+
attr_writer :education_levels
|
12
|
+
attr_accessor :guid,
|
13
|
+
:statement,
|
14
|
+
:number, :stem, :label, :level,
|
15
|
+
:seq,
|
16
|
+
:section,
|
17
|
+
:document, :disciplines,
|
18
|
+
:utilizations,
|
15
19
|
:parent, :parent_guid
|
16
20
|
|
17
|
-
|
18
|
-
|
21
|
+
# Before standards are rebranched in Authority#rebranch_children
|
22
|
+
# or Document#rebranch_children, they have the following structure.
|
23
|
+
#
|
24
|
+
# Standard
|
25
|
+
# |-> Document
|
26
|
+
# | |-> Publication
|
27
|
+
# | |-> Authority
|
28
|
+
# |-> Section
|
29
|
+
#
|
19
30
|
def initialize(data)
|
20
|
-
|
21
|
-
@guid =
|
22
|
-
@
|
23
|
-
@label =
|
24
|
-
@level =
|
25
|
-
@
|
26
|
-
@number =
|
27
|
-
@status =
|
28
|
-
@
|
29
|
-
@subject = attr_to_val_or_nil(Subject, data, "subject")
|
30
|
-
@deepest = data["deepest"]
|
31
|
-
@version = data["version"]
|
31
|
+
attributes = data["attributes"]
|
32
|
+
@guid = attributes["guid"]
|
33
|
+
@education_levels = attr_to_val_or_nil(EducationLevels, attributes, "education_levels")
|
34
|
+
@label = attributes["label"]
|
35
|
+
@level = attributes["level"]
|
36
|
+
@section = attr_to_val_or_nil(Section, attributes, "section")
|
37
|
+
@number = attr_to_val_or_nil(Number, attributes, "number")
|
38
|
+
@status = attributes["status"]
|
39
|
+
@disciplines = attr_to_val_or_nil(Disciplines, attributes, "disciplines")
|
32
40
|
@children = []
|
33
|
-
@document = attr_to_val_or_nil(Document,
|
34
|
-
@
|
35
|
-
@
|
36
|
-
@
|
37
|
-
@subject_doc = attr_to_val_or_nil(SubjectDoc, data, "subject_doc")
|
38
|
-
@has_relations = attr_to_val_or_nil(HasRelations, data, "has_relations")
|
39
|
-
|
40
|
-
# Parent guid extraction can be a little more complicated
|
41
|
-
if data["parent"] && data["parent"].is_a?(String)
|
42
|
-
@parent_guid = data["parent"]
|
43
|
-
elsif data["parent"] && data["parent"].is_a?(Hash)
|
44
|
-
@parent_guid = data["parent"]["guid"]
|
45
|
-
end
|
41
|
+
@document = attr_to_val_or_nil(Document, attributes, "document")
|
42
|
+
@statement = attr_to_val_or_nil(Statement, attributes, "statement")
|
43
|
+
@utilizations = attr_to_vals(Utilizations, attributes["utilizations"])
|
44
|
+
@parent_guid = data.dig("relationships", "parent", "data", "id")
|
46
45
|
end
|
47
46
|
|
48
47
|
alias_method :from_hash, :initialize
|
49
48
|
|
50
|
-
def active?
|
51
|
-
status == "Active"
|
52
|
-
end
|
53
|
-
|
54
|
-
def obsolete?
|
55
|
-
status == "Obsolete"
|
56
|
-
end
|
57
|
-
|
58
|
-
def deepest?
|
59
|
-
deepest == 'Y'
|
60
|
-
end
|
61
|
-
|
62
|
-
def status=(status)
|
63
|
-
unless %w[Active Obsolete].include?(status)
|
64
|
-
raise ArgumentError.new(
|
65
|
-
"Standard status must be either 'Active' or 'Obsolete'"
|
66
|
-
)
|
67
|
-
end
|
68
|
-
@status = status
|
69
|
-
end
|
70
|
-
|
71
|
-
def deepest=(deepest)
|
72
|
-
unless %w[Y N].include?(deepest)
|
73
|
-
raise ArgumentError.new("Standard deepest must be either 'Y' or 'N'")
|
74
|
-
end
|
75
|
-
@deepest = deepest
|
76
|
-
end
|
77
|
-
|
78
49
|
def add_child(child)
|
79
50
|
raise StandardError.new("Tried to add self as a child") if self == child
|
80
51
|
|
@@ -94,17 +65,13 @@ module AcademicBenchmarks
|
|
94
65
|
@children.count > 0
|
95
66
|
end
|
96
67
|
|
97
|
-
def
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
def grade
|
102
|
-
return @grade if @grade
|
68
|
+
def education_levels
|
69
|
+
return @education_levels if @education_levels
|
103
70
|
|
104
|
-
# check to see if one of our parents has
|
71
|
+
# check to see if one of our parents has education levels. Use that if so
|
105
72
|
p = parent
|
106
73
|
while p
|
107
|
-
return p.
|
74
|
+
return p.education_levels if p.education_levels
|
108
75
|
p = p.parent
|
109
76
|
end
|
110
77
|
nil
|
@@ -1,36 +1,17 @@
|
|
1
1
|
module AcademicBenchmarks
|
2
2
|
module Standards
|
3
3
|
class StandardsForest
|
4
|
-
attr_reader :trees, :
|
5
|
-
|
6
|
-
|
7
|
-
# adding standards to the tree (since the tree is unordered,
|
8
|
-
# this would otherwise be an expensive operation).
|
9
|
-
#
|
10
|
-
# The initial data hash can also be optionally saved to
|
11
|
-
# permit testing and internal consistency checks
|
12
|
-
|
13
|
-
def initialize(
|
14
|
-
data_hash,
|
15
|
-
save_guid_to_standard_hash: true,
|
16
|
-
save_initial_data_hash: false,
|
17
|
-
include_obsoletes: true
|
18
|
-
)
|
19
|
-
@data_hash = data_hash.dup.freeze if save_initial_data_hash
|
4
|
+
attr_reader :trees, :orphans
|
5
|
+
|
6
|
+
def initialize(data_hash)
|
20
7
|
@guid_to_standard = {} # a hash of guids to standards
|
21
8
|
@trees = []
|
22
9
|
@orphans = []
|
23
10
|
process_items(data_hash)
|
24
11
|
|
25
|
-
@trees.delete_if(&:obsolete?) unless include_obsoletes
|
26
|
-
|
27
12
|
# upgrade the hash data to a StandardsTree object
|
28
13
|
@trees.map! do |item|
|
29
|
-
StandardsTree.new(
|
30
|
-
item,
|
31
|
-
build_item_hash: save_guid_to_standard_hash,
|
32
|
-
include_obsoletes: include_obsoletes
|
33
|
-
)
|
14
|
+
StandardsTree.new(item)
|
34
15
|
end
|
35
16
|
|
36
17
|
# We will still have the guid-to-standards saved at the Tree level,
|
@@ -47,21 +28,6 @@ module AcademicBenchmarks
|
|
47
28
|
StandardsTree.new(root).tap{ |st| st.add_orphans(@orphans) }
|
48
29
|
end
|
49
30
|
|
50
|
-
def add_standard(standard)
|
51
|
-
if standard.is_a?(Standard)
|
52
|
-
raise StandardError.new(
|
53
|
-
"adding standards is not currently implemented"
|
54
|
-
)
|
55
|
-
elsif standard.is_a?(Hash)
|
56
|
-
add_standard(Standard.new(standard))
|
57
|
-
else
|
58
|
-
raise ArgumentError.new(
|
59
|
-
"standard must be an 'AcademicBenchmarks::Standards::Standard' " \
|
60
|
-
"or a 'Hash' but was a #{standard.class}"
|
61
|
-
)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
31
|
def single_tree?
|
66
32
|
@trees.count == 1
|
67
33
|
end
|
@@ -6,40 +6,10 @@ module AcademicBenchmarks
|
|
6
6
|
attr_reader :root, :orphans
|
7
7
|
delegate :children, :to_s, :to_h, :to_json, to: :root
|
8
8
|
|
9
|
-
|
10
|
-
# addition of standards to the tree. since the tree is unordered,
|
11
|
-
# adding to it can be expensive without this
|
12
|
-
|
13
|
-
def initialize(root, build_item_hash: true, include_obsoletes: true)
|
9
|
+
def initialize(root)
|
14
10
|
@orphans = []
|
15
11
|
@root = root
|
16
|
-
|
17
|
-
|
18
|
-
if build_item_hash
|
19
|
-
@item_hash = {}
|
20
|
-
go_ahead_and_build_item_hash
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def add_standard(standard)
|
25
|
-
if standard.is_a?(Standard)
|
26
|
-
parent = @item_hash ? @item_hash[standard.parent_guid] : find_parent(standard)
|
27
|
-
unless parent
|
28
|
-
raise StandardError.new(
|
29
|
-
"Parent of standard not found in tree. Parent guid is " \
|
30
|
-
"'#{standard.parent_guid}' and child guid is '#{standard.guid}'"
|
31
|
-
)
|
32
|
-
end
|
33
|
-
parent.add_child(standard)
|
34
|
-
standard.parent = parent
|
35
|
-
elsif standard.is_a?(Hash)
|
36
|
-
add_standard(Standard.new(standard))
|
37
|
-
else
|
38
|
-
raise ArgumentError.new(
|
39
|
-
"standard must be an 'AcademicBenchmarks::Standards::Standard' " \
|
40
|
-
"or a 'Hash' but was a #{standard.class}"
|
41
|
-
)
|
42
|
-
end
|
12
|
+
root.rebranch_children if root.is_a?(Authority) || root.is_a?(Publication)
|
43
13
|
end
|
44
14
|
|
45
15
|
def add_orphan(orphan)
|
@@ -53,37 +23,6 @@ module AcademicBenchmarks
|
|
53
23
|
def has_orphans?
|
54
24
|
@orphans.present?
|
55
25
|
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
def go_ahead_and_build_item_hash
|
60
|
-
@item_hash[@root.guid] = @root
|
61
|
-
add_children_to_item_hash(@root)
|
62
|
-
end
|
63
|
-
|
64
|
-
def add_children_to_item_hash(parent)
|
65
|
-
parent.children.each do |child|
|
66
|
-
@item_hash[child.guid] = child
|
67
|
-
add_children_to_item_hash(child) if child.has_children?
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def find_parent(standard)
|
72
|
-
return @root if @root.guid == standard.parent_guid
|
73
|
-
check_children_for_parent(standard.parent_guid, @root)
|
74
|
-
end
|
75
|
-
|
76
|
-
# does a depth-first search
|
77
|
-
def check_children_for_parent(parent_guid, standard)
|
78
|
-
standard.children.each do |child|
|
79
|
-
return child if child.guid == parent_guid
|
80
|
-
check_children_for_parent(parent_guid, child) if child.has_children?
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def prune_obsolete_branches
|
85
|
-
root.remove_obsolete_children
|
86
|
-
end
|
87
26
|
end
|
88
27
|
end
|
89
28
|
end
|