Skip to content

Commit

Permalink
feat(expectations): create metric parser
Browse files Browse the repository at this point in the history
  • Loading branch information
benzend committed Oct 14, 2024
1 parent 4e3adb0 commit 279f4da
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 2 deletions.
84 changes: 84 additions & 0 deletions lib/glare/ux-metrics/ux_metrics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,90 @@ def correct_data
end
end

module Expectations
class Data
CHOICE_KEYS = %w[matched_very_well somewhat_matched neutral somewhat_didnt_match didnt_match_at_all].freeze
SENTIMENT_KEYS = %w[positive neutral negative].freeze
def initialize(choices:, sentiment:)
@choices = choices
@sentiment = sentiment
end

attr_reader :choices, :sentiment

def valid?

if choices.is_a?(Hash) && choices.size
missing_attributes = CHOICE_KEYS - choices.keys.map(&:to_s)
return false unless missing_attributes.empty?
end

if sentiment.is_a?(Hash) && sentiment.size
missing_attributes = SENTIMENT_KEYS - sentiment.keys.map(&:to_s)
return true if missing_attributes.empty?
end

false
end

def parse
positive = sentiment['positive']
neutral = sentiment['neutral']
negative = sentiment['negative']

matched_very_well = choices['matched_very_well']
somewhat_matched = choices['somewhat_matched']
neutral_match = choices['neutral']
somewhat_didnt_match = choices['somewhat_didnt_match']
didnt_match_at_all = choices['didnt_match_at_all']

result = (matched_very_well.to_f + somewhat_matched.to_f) -
(neutral_match.to_f + somewhat_didnt_match.to_f + didnt_match_at_all.to_f)

threshold = if result > 0.3
'positive'
elsif result > 0.1
'neutral'
else
'negative'
end

label = if threshold == 'positive'
"High Expectations"
elsif threshold == 'neutral'
"Met Expectations"
else
"Failed Expectations"
end

Result.new(result: result, threshold: threshold, label: label)
end

class InvalidDataError < Error
def initialize(msg = "Data not valid. Correct data format is: \n\n#{correct_data}")
super(msg)
end

def correct_data
{
sentiment: {
positive: "string|integer|float",
neutral: "string|integer|float",
negative: "string|integer|float",
},
choices: {
matched_very_well: "string|integer|float",
somewhat_matched: "string|integer|float",
neutral: "string|integer|float",
somewhat_didnt_match: "string|integer|float",
didnt_match_at_all: "string|integer|float",
}
}.to_json
end
end
end
end

class Result
def initialize(result:, threshold:, label:)
@result = result
Expand Down
8 changes: 6 additions & 2 deletions sig/glare/ux_metrics/ux_metrics.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,16 @@ module Glare
end
end

module Feeling
module Expectations
class Data
CHOICE_KEYS: Array[String]
SENTIMENT_KEYS: Array[String]
attr_reader choices: Hash[::Symbol | ::String, ::String | ::Float | ::Integer]
attr_reader sentiment: Hash[::Symbol | ::String, ::String | ::Float | ::Integer]

def initialize: (choices: Hash[::Symbol | ::String, ::String | ::Float | ::Integer]) -> void
def initialize: (
choices: Hash[::Symbol | ::String, ::String | ::Float | ::Integer],
sentiment: Hash[::Symbol | ::String, ::String | ::Float | ::Integer]) -> void

def valid?: -> bool

Expand Down
67 changes: 67 additions & 0 deletions spec/glare/ux-metrics/ux_metrics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,71 @@
expect(data.result.is_a?(Float) && data.label.is_a?(String) && data.threshold.is_a?(String)).to eq(true)
end
end

describe Glare::UxMetrics::Feeling do
let(:feeling_data) do
{
very_easy: 0.3,
somewhat_easy: 0.4,
neutral: 0.1,
somewhat_difficult: 0.1,
very_difficult: 0.1
}
end

it "validates valid feeling data" do
data = Glare::UxMetrics::Feeling::Data.new(choices: feeling_data)
expect(data.valid?).to eq(true)
end

it "invalidates invalid feeling data" do
data = Glare::UxMetrics::Feeling::Data.new(choices: { helpful: 1 })
expect(data.valid?).to eq(false)
end

it "returns valid data" do
data = Glare::UxMetrics::Feeling::Data.new(choices: feeling_data).parse
expect(data.result.is_a?(Float) && data.label.is_a?(String) && data.threshold.is_a?(String)).to eq(true)
end
end

describe Glare::UxMetrics::Expectations do
let(:expectations_data) do
{
sentiment: {
positive: 0.5,
neutral: 0.3,
negative: 0.2
},
choices: {
matched_very_well: 0.3,
somewhat_matched: 0.4,
neutral: 0.1,
somewhat_didnt_match: 0.1,
didnt_match_at_all: 0.1,
}
}
end

it "validates valid expectations data" do
data = Glare::UxMetrics::Expectations::Data.new(
choices: expectations_data[:choices],
sentiment: expectations_data[:sentiment]
)
expect(data.valid?).to eq(true)
end

it "invalidates invalid expectations data" do
data = Glare::UxMetrics::Expectations::Data.new(choices: { helpful: 1 }, sentiment: { bla: "hi" })
expect(data.valid?).to eq(false)
end

it "returns valid data" do
data = Glare::UxMetrics::Expectations::Data.new(
choices: expectations_data[:choices],
sentiment: expectations_data[:sentiment]
).parse
expect(data.result.is_a?(Float) && data.label.is_a?(String) && data.threshold.is_a?(String)).to eq(true)
end
end
end

0 comments on commit 279f4da

Please sign in to comment.