was 0.5.1 → 0.7.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95d42be52374816fe8a10ac34087752ff5a4255d426d454e0a15bb77586a2184
4
- data.tar.gz: a64446e7c586129836c07b1b112f7b5e5db86f71cc4ed4bd711d4fcb593abc8d
3
+ metadata.gz: 32828b1a84ec32fd591c751dcb5df91f277af4d6bc840179b9070345f3345e24
4
+ data.tar.gz: 57bfb59c5ee299e3e0ed0376e44b4ad0c62f98ca23574cf366fc5f7461a1dd95
5
5
  SHA512:
6
- metadata.gz: 30adcbb6d298b3e972067edc741fd266eaef09f7639151cdcfeded444f3b34a75d54280902cb5e7a5c88d1437324c742c9b34b7771a576d1f4591b892e7c9368
7
- data.tar.gz: 8a734c0a5ee2dd382e73060ab69b1c881a433f61e11565cbd668f7597d40cda84c4f0d19d497ffbdd80da5b6fc2e5040af8b4dd1c4c3377929e8c68bda6723dd
6
+ metadata.gz: e006ec3f57273eafe64336a6ba55efc358bed7064a11be9ff67089a147b3683e8452c447d09caf59f306a573265ab52bc4f1fd411f25e5020b3773a55355df4d
7
+ data.tar.gz: 24f01eb4452fa8b691bbcf1c639cd16ae72d53f10920f2482281ef853ce0b0f9b792aea36c3a7498a2caf22f2ced4aecc3fa5f0e8bf46d9ee2d387c4234cbfeb
data/README.md CHANGED
@@ -25,21 +25,30 @@ require "was"
25
25
  class ReportScore < WAS::Score
26
26
  maximum_score 1000
27
27
 
28
- with :exam, "ExamScore", weight: 0.75
29
- with :practical "PracticalScore", weight: 0.25
28
+ with :exam, class_name: "ExamScore", weight: 0.75
29
+ with :practical class_name: "PracticalScore", weight: 0.25
30
30
  end
31
31
 
32
32
  class ExamScore < WAS::Score
33
- def calculation
34
- return 1 if input == "A"
35
- return 0.75 if input == "B"
36
- return 0.5 if input == "C"
33
+ context :grade_a, score: 1 do |input|
34
+ input == "A"
35
+ end
36
+
37
+ context :grade_b, score: 0.75 do |input|
38
+ input == "B"
39
+ end
40
+
41
+ context :grade_c, score: 0.5 do |input|
42
+ input == "C"
43
+ end
44
+
45
+ context :flunk do
37
46
  0
38
47
  end
39
48
  end
40
49
 
41
50
  class PracticalScore < WAS::Score
42
- def calculation
51
+ context :score do |input|
43
52
  input / 10.0
44
53
  end
45
54
  end
@@ -68,8 +77,8 @@ Omitting the `maximum_score` will return a composed percentage represented as a
68
77
  ```ruby
69
78
  # report_score.rb
70
79
  class ReportScore < WAS::Score
71
- with :exam, "ExamScore", weight: 0.75
72
- with :practical "PracticalScore", weight: 0.25
80
+ with :exam, class_name: "ExamScore", weight: 0.75
81
+ with :practical class_name: "PracticalScore", weight: 0.25
73
82
  end
74
83
  ```
75
84
 
data/lib/was/score.rb CHANGED
@@ -31,19 +31,94 @@ module WAS
31
31
  end
32
32
  end
33
33
 
34
+ def self.context(name, score: nil, &block)
35
+ @contexts ||= []
36
+ @contexts.push({ name: name, score: score, code: block })
37
+ end
38
+
34
39
  def initialize(input)
35
40
  @input = input
36
41
  end
37
42
 
38
- def calculate
39
- calculation
43
+ def calculate(option = nil)
44
+ return calculation if option != :tree
45
+
46
+ calc = calculation(:tree)
47
+ tree = if calc.is_a?(Hash)
48
+ calc.merge({ max: self.class.max_score })
49
+ else
50
+ { score: calc }.merge({ max: self.class.max_score })
51
+ end
52
+
53
+ transform_scores_relative_to_max_score(tree)
54
+ end
55
+
56
+ def calculation(option = nil)
57
+ if contexts?
58
+ context_score_calculation
59
+ else
60
+ nested_score_calcuation(option)
61
+ end
40
62
  end
41
63
 
42
- def calculation
43
- self.class.scorers.sum do |name, scorer|
64
+ private
65
+
66
+ def transform_scores_relative_to_max_score(tree, max_score = nil)
67
+ max_score = max_score || self.class.max_score
68
+ return tree if self.class.max_score == 1
69
+
70
+ tree.each do |key, value|
71
+ next if key != :with
72
+
73
+ value.each do |scorer, branch|
74
+ adjust_branch_score_and_max(branch, max_score)
75
+ end
76
+
77
+ value.transform_values! do |nested_tree|
78
+ transform_scores_relative_to_max_score(nested_tree, nested_tree[:max])
79
+ end
80
+ end
81
+ end
82
+
83
+ def adjust_branch_score_and_max(branch, max_score)
84
+ branch[:max] = branch[:max] * max_score * branch[:weight]
85
+ branch[:score] = branch[:score] * branch[:max]
86
+ end
87
+
88
+ def contexts?
89
+ !!self.class.instance_variable_get("@contexts")
90
+ end
91
+
92
+ def context_score_calculation
93
+ self.class.instance_variable_get("@contexts").each do |context|
94
+ output = context[:code].call(input)
95
+ next if !output
96
+ return context[:score] || output
97
+ end
98
+ end
99
+
100
+ def nested_score_calcuation(option)
101
+ if option == :tree
102
+ { score: sum, with: with_attribute }
103
+ else
104
+ sum
105
+ end
106
+ end
107
+
108
+ def sum
109
+ @sum ||= self.class.scorers.sum do |name, scorer|
44
110
  score = Object.const_get(scorer[:class_name]).new(input[name.to_sym]).calculate
45
111
  score * scorer[:weight]
46
112
  end * self.class.max_score
47
113
  end
114
+
115
+ def with_attribute
116
+ {}.tap do |with|
117
+ self.class.scorers.each do |name, scorer|
118
+ with[name] = Object.const_get(scorer[:class_name]).new(input[name.to_sym]).calculate(:tree)
119
+ with[name][:weight] = scorer[:weight]
120
+ end
121
+ end
122
+ end
48
123
  end
49
124
  end
data/lib/was/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WAS
4
- VERSION = "0.5.1"
4
+ VERSION = "0.7.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: was
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Connell
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-02-11 00:00:00.000000000 Z
11
+ date: 2025-02-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A simple gem/dsl for generating Weighted Average Score calculations.
14
14
  email: