Skip to content

Commit

Permalink
feat: metric engagement
Browse files Browse the repository at this point in the history
  • Loading branch information
benzend committed Oct 16, 2024
1 parent 9a90080 commit f964bdd
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 2 deletions.
2 changes: 1 addition & 1 deletion 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.2)
glare-ux-metrics-rb (0.2.3)

GEM
remote: https://rubygems.org/
Expand Down
76 changes: 76 additions & 0 deletions lib/glare/ux-metrics/ux_metrics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,69 @@ def correct_data
end
end

module Engagement
class Parser
def initialize(scores:, clicks:)
@scores = scores
@clicks = clicks
end

attr_reader :scores, :clicks

def valid?
return false unless scores.is_a?(Hash) && clicks.is_a?(Array) && scores.keys.size > 0 && clicks.size > 0

true
end

def parse
hotspot_1_clicks = clicks.filter {|click| click.hotspot.zero? }
hotspot_2_clicks = clicks.filter {|click| click.hotspot == 1 }
hotspot_3_clicks = clicks.filter {|click| click.hotspot == 3 }

primary_score = (hotspot_1_clicks.size / clicks.size.to_f) * 100
secondary_score = (hotspot_2_clicks.size / clicks.size.to_f) * 100
tertiary_score = (hotspot_3_clicks.size / clicks.size.to_f) * 100

result = primary_score + secondary_score + tertiary_score

label = if result > 0.3
"High"
elsif result >= 0.1
"Avg"
else
"Low"
end

threshold = if label == "High"
"positive"
elsif label == "Avg"
"neutral"
else
"negative"
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
{
very_satisfied: "string|integer|float",
somewhat_satisfied: "string|integer|float",
neutral: "string|integer|float",
somewhat_dissatisfied: "string|integer|float",
very_dissatisfied: "string|integer|float",
}.to_json
end
end
end
end

class Result
def initialize(result:, threshold:, label:)
@result = result
Expand All @@ -509,7 +572,20 @@ def initialize(result:, threshold:, label:)
end

attr_reader :result, :threshold, :label
end

class ClickData
def initialize(x_pos:, y_pos:, hotspot:)
@x_pos = x_pos
@y_pos = y_pos
@hotspot = hotspot
end

attr_reader :x_pos, :y_pos, :hotspot

def in_hotspot?
hotspot > -1
end
end
end
end
2 changes: 1 addition & 1 deletion lib/glare/ux-metrics/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.2"
VERSION = "0.2.3"
end
end
30 changes: 30 additions & 0 deletions sig/glare/ux_metrics/ux_metrics.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,26 @@ module Glare
end
end

module Engagement
class Parser
attr_reader scores: Hash[::Symbol | ::String, ::String | ::Float | ::Integer]
attr_reader clicks: Array[ClickData]

def initialize: (
scores: Hash[::Symbol | ::String, ::String | ::Float | ::Integer],
clicks: Array[ClickData]
) -> void

def valid?: -> bool

def parse: -> Result

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

class Result
attr_reader result: Float
attr_reader label: String
Expand All @@ -147,6 +167,16 @@ module Glare
def initialize: (result: Float, label: String, threshold: String) -> void
end

class ClickData
attr_reader hotspot: Integer
attr_reader x_pos: Float
attr_reader y_pos: Float

def initialize: (x_pos: Float, y_pos: Float, hotspot: Integer) -> void

def in_hotspot?: -> bool
end

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

describe Glare::UxMetrics::Engagement do
let(:data) do
{
scores: {
direct_success: 0.5,
indirect_success: 0.3,
failed: 0.2
},
clicks: [
Glare::UxMetrics::ClickData.new(x_pos: 0.2, y_pos: 0.2, hotspot: 0),
Glare::UxMetrics::ClickData.new(x_pos: 0.2, y_pos: 0.2, hotspot: 0),
Glare::UxMetrics::ClickData.new(x_pos: 0.2, y_pos: 0.2, hotspot: 1),
Glare::UxMetrics::ClickData.new(x_pos: 0.2, y_pos: 0.2, hotspot: 1),
Glare::UxMetrics::ClickData.new(x_pos: 0.2, y_pos: 0.2, hotspot: 2),
Glare::UxMetrics::ClickData.new(x_pos: 0.2, y_pos: 0.2, hotspot: 2),
Glare::UxMetrics::ClickData.new(x_pos: 0.2, y_pos: 0.2, hotspot: 0),
Glare::UxMetrics::ClickData.new(x_pos: 0.2, y_pos: 0.2, hotspot: 0),
Glare::UxMetrics::ClickData.new(x_pos: 0.2, y_pos: 0.2, hotspot: 0),
Glare::UxMetrics::ClickData.new(x_pos: 0.2, y_pos: 0.2, hotspot: 0),
Glare::UxMetrics::ClickData.new(x_pos: 0.2, y_pos: 0.2, hotspot: 0),
Glare::UxMetrics::ClickData.new(x_pos: 0.2, y_pos: 0.2, hotspot: 0),
]
}
end

it "validates valid engagement data" do
parser = Glare::UxMetrics::Engagement::Parser.new(
scores: data[:scores],
clicks: data[:clicks]
)
expect(parser.valid?).to eq(true)
end

it "invalidates invalid engagement data" do
parser = Glare::UxMetrics::Engagement::Parser.new(scores: { sup: "ooooo" }, clicks: [])
expect(parser.valid?).to eq(false)
end

it "returns valid data" do
parser = Glare::UxMetrics::Engagement::Parser.new(
scores: data[:scores],
clicks: data[:clicks]
).parse
expect(parser.result.is_a?(Float) && parser.label.is_a?(String) && parser.threshold.is_a?(String)).to eq(true)
end
end
end

0 comments on commit f964bdd

Please sign in to comment.