Skip to content

Commit

Permalink
feat(feelings): update ux metric label
Browse files Browse the repository at this point in the history
  • Loading branch information
benzend committed Nov 19, 2024
1 parent d2df327 commit 09c3353
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 31 deletions.
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
glare-ux-metrics-rb (0.2.4)
glare-ux-metrics-rb (0.2.5)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -56,4 +56,4 @@ DEPENDENCIES
rubocop (~> 1.21)

BUNDLED WITH
2.4.21
2.4.22
159 changes: 131 additions & 28 deletions lib/glare/ux_metrics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,19 @@ def correct_data
end

module Feeling
# Run Glare::UxMetrics::Feeling::Parser.new({...}) to create a parser
class Parser
CHOICE_KEYS = %w[very_easy somewhat_easy neutral somewhat_difficult very_difficult].freeze

# @example Create a parser
# data = {
# very_easy: 0.4,
# somewhat_easy: 0.2,
# neutral: 0.1,
# somewhat_difficult: 0.05,
# very_difficult: 0.0
# }
# Glare::UxMetrics::Feeling::Parser.new(data)
def initialize(choices:)
@choices = choices
end
Expand Down Expand Up @@ -111,15 +121,24 @@ def parse
choices[:somewhat_difficult].to_f -
choices[:very_difficult].to_f


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

Result.new(result: result, threshold: threshold, label: threshold)
label = if threshold == "positive"
"High Sentiment"
elsif threshold == "neutral"
"Avg Sentiment"
else
"Low Sentiment"
end

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

class InvalidDataError < Error
Expand Down Expand Up @@ -169,30 +188,30 @@ def valid?
end

def parse
positive = sentiment['positive']
neutral = sentiment['neutral']
negative = sentiment['negative']
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']
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'
"positive"
elsif result > 0.1
'neutral'
"neutral"
else
'negative'
"negative"
end

label = if threshold == 'positive'
label = if threshold == "positive"
"High Expectations"
elsif threshold == 'neutral'
elsif threshold == "neutral"
"Met Expectations"
else
"Failed Expectations"
Expand Down Expand Up @@ -301,11 +320,11 @@ def parse(question_index:)
label = selected_scored_question[:fraction]

threshold = if %w[5/5 4/5].include? label
'positive'
"positive"
elsif label == "3/5"
'neutral'
"neutral"
else
'negative'
"negative"
end

Result.new(result: result, threshold: threshold, label: label)
Expand Down Expand Up @@ -356,6 +375,12 @@ def valid?
missing_attributes = CHOICE_KEYS - choices.keys.map(&:to_s)
return false unless missing_attributes.empty?

return false unless choices.values.all? do |v|
return Glare::Util.str_is_integer?(v) if v.is_a?(String)

true if v.is_a?(Float) || v.is_a?(Integer)
end

true
end

Expand All @@ -367,19 +392,19 @@ def parse
choices[:very_dissatisfied].to_f

threshold = if result >= 0.7
'positive'
"positive"
elsif result > 0.5
'neutral'
"neutral"
else
'negative'
"negative"
end

label = if threshold == 'positive'
'High Satisfaction'
elsif threshold == 'neutral'
'Average Satisfaction'
label = if threshold == "positive"
"High Satisfaction"
elsif threshold == "neutral"
"Average Satisfaction"
else
'Low Satisfaction'
"Low Satisfaction"
end

Result.new(result: result, threshold: threshold, label: label)
Expand Down Expand Up @@ -601,6 +626,84 @@ def correct_data
end
end

module Frequency
class Parser
CHOICE_KEYS = %w[very_frequently frequently occasionally rarely].freeze

def initialize(choices:)
@choices = choices
end

attr_reader :choices

def valid?
return false unless choices.is_a?(Hash) && choices.size

missing_attributes = CHOICE_KEYS - choices.keys.map(&:to_s)
return false unless missing_attributes.empty?

return false unless choices.values.all? do |v|
return Glare::Util.str_is_integer?(v) if v.is_a?(String)

return true if v.is_a?(Float) || v.is_a?(Integer)

false
end

true
end

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

def result
@result ||= choices[:very_frequently].to_f +
choices[:frequently].to_f -
choices[:occasionally].to_f -
choices[:rarely].to_f
end

def threshold
@threshold ||= if result > 0.3
"positive"
elsif result >= 0.1
"neutral"
else
"negative"
end
end

def label
@label ||= if threshold == "positive"
"High"
elsif threshold == "neutral"
"Avg"
else
"Low"
end
end

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

def correct_data
{
choices: {
very_frequently: "string|integer|float",
frequently: "string|integer|float",
occasionally: "string|integer|float",
rarely: "string|integer|float",
}
}.to_json
end
end
end
end


class Result
def initialize(result:, threshold:, label:)
@result = result
Expand Down
2 changes: 1 addition & 1 deletion lib/glare/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

module Glare
module UxMetrics
VERSION = "0.2.4"
VERSION = "0.2.5"
end
end
23 changes: 23 additions & 0 deletions sig/glare/ux_metrics.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,29 @@ module Glare
end
end

module Frequency
class Parser
CHOICE_KEYS: Array[String]
attr_reader choices: Hash[::Symbol | ::String, ::String | ::Float | ::Integer]

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

def valid?: -> bool

def parse: -> Result

@result: Float
def result: -> Float

@threshold: String
def threshold: -> String

class InvalidDataError < Error
def correct_data: -> String
end
end
end

class Result
attr_reader result: Float
attr_reader label: String
Expand Down

0 comments on commit 09c3353

Please sign in to comment.