was 0.5.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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: