Skip to content

Commit 01a17bd

Browse files
committed
✨ rework confidence scores to be easily comparable
1 parent 8ea8f52 commit 01a17bd

File tree

4 files changed

+96
-63
lines changed

4 files changed

+96
-63
lines changed

lib/mindee/parsing/v2/field/base_field.rb

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ class BaseField
2020
# @param indent_level [Integer] Level of indentation for rst display.
2121
def initialize(raw_prediction, indent_level = 0)
2222
@indent_level = indent_level
23-
@confidence = raw_prediction.key?('confidence') ? raw_prediction['confidence'] : nil
24-
@locations = if raw_prediction.key?('locations')
25-
raw_prediction['locations'].map do |location|
23+
confidence = raw_prediction['confidence']
24+
@confidence = FieldConfidence.new(confidence) unless confidence.nil? || confidence.empty?
25+
26+
locations = raw_prediction['locations']
27+
@locations = if locations.nil? || locations.empty?
28+
[]
29+
else
30+
locations.map do |location|
2631
FieldLocation.new(location)
2732
end
28-
else
29-
[]
3033
end
3134
end
3235

lib/mindee/parsing/v2/field/field_confidence.rb

Lines changed: 64 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,71 +19,97 @@ class FieldConfidence
1919
LOW = 'Low'
2020

2121
# List of valid values, as frozen strings.
22-
VALID_VALUES = [CERTAIN, HIGH, MEDIUM, LOW].freeze
22+
VALID_VALUES = ['Certain', 'High', 'Medium', 'Low'].freeze
2323

2424
# @param value [String] The confidence level value.
2525
# @raise [ArgumentError] If the value is not a valid confidence level.
2626
def initialize(value)
27-
unless VALID_VALUES.include?(value)
27+
case value
28+
when 'Certain' then @value = CERTAIN
29+
when 'High' then @value = HIGH
30+
when 'Medium' then @value = MEDIUM
31+
when 'Low' then @value = LOW
32+
else
2833
raise ArgumentError,
29-
"Invalid confidence level: #{value}. Must be one of: #{VALID_VALUES.join(', ')}"
34+
"Invalid confidence level: '#{value}'. Must be one of: #{VALID_VALUES.join(', ')}"
3035
end
3136

3237
@value = value
3338
end
3439

35-
# Create a FieldConfidence from a string value.
36-
# @param value [String] The confidence level string.
37-
# @return [FieldConfidence] The confidence instance.
38-
def self.from_string(value)
39-
new(value)
40-
end
41-
42-
# Check if this is a certain confidence level.
43-
# @return [Boolean] `true` if confidence is certain.
44-
def certain?
45-
@value == CERTAIN
46-
end
47-
48-
# Check if this is a high confidence level.
49-
# @return [Boolean] `true` if confidence is high.
50-
def high?
51-
@value == HIGH
52-
end
53-
54-
# Check if this is a medium confidence level.
55-
# @return [Boolean] `true` if confidence is medium.
56-
def medium?
57-
@value == MEDIUM
58-
end
59-
60-
# Check if this is a low confidence level.
61-
# @return [Boolean] `true` if confidence is low.
62-
def low?
63-
@value == LOW
64-
end
65-
6640
# String representation of the confidence level.
6741
# @return [String] The confidence level value.
6842
def to_s
6943
@value
7044
end
7145

72-
# Compare two FieldConfidence instances.
73-
# @param other [FieldConfidence] The other confidence to compare.
46+
# String representation of the confidence level.
47+
# @return [Integer] The confidence level value as an integer: 1 is LOW, 4 is HIGH.
48+
def to_i
49+
val_to_i(@value)
50+
end
51+
52+
# Equality of two FieldConfidence instances.
53+
# @param other [String, Integer, FieldConfidence] The other confidence to compare.
7454
# @return [Boolean] `true` if they have the same value.
7555
def ==(other)
76-
other.is_a?(FieldConfidence) && @value == other.value
56+
case other.class.name
57+
when 'String' then @value == other
58+
when 'Integer' then to_i == other
59+
when 'FieldConfidence' then @value == other.value
60+
else
61+
raise ArgumentError, "Invalid type: #{other.class}"
62+
end
63+
end
64+
65+
# Greater than or equality of two FieldConfidence instances.
66+
# @param other [String, Integer, FieldConfidence] The other confidence to compare.
67+
def >=(other)
68+
case other.class.name
69+
when 'String' then val_to_i(@value) >= val_to_i(other)
70+
when 'Integer' then to_i >= other
71+
when 'FieldConfidence' then val_to_i(@value) >= val_to_i(other.value)
72+
else
73+
raise ArgumentError, "Invalid type: #{other.class}"
74+
end
75+
end
76+
77+
# less than or equality of two FieldConfidence instances.
78+
# # @param other [String, Integer, FieldConfidence] The other confidence to compare.
79+
def <=(other)
80+
case other.class.name
81+
when 'String' then val_to_i(@value) <= val_to_i(other)
82+
when 'Integer' then to_i <= other
83+
when 'FieldConfidence' then val_to_i(@value) <= val_to_i(other.value)
84+
else
85+
raise ArgumentError, "Invalid type: #{other.class}"
86+
end
7787
end
7888

79-
# Make instances comparable and hashable
89+
# Aliases for the comparison operators.
8090
alias eql? ==
91+
alias gteql? >=
92+
alias lteql? <=
8193

8294
# Inspect method for debugging.
8395
# @return [String] Debug representation.
8496
def inspect
8597
"#<#{self.class.name}:#{@value}>"
8698
end
99+
100+
protected
101+
102+
def val_to_i(value)
103+
case value
104+
when CERTAIN then 4
105+
when HIGH then 3
106+
when MEDIUM then 2
107+
when LOW then 1
108+
else
109+
raise ArgumentError,
110+
"Invalid confidence level: '#{value}'. Must be one of: #{VALID_VALUES.join(', ')}"
111+
end
112+
end
87113
end
88114
end
89115
end

sig/mindee/parsing/v2/field/field_confidence.rbs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ module Mindee
1212
VALID_VALUES: Array[String]
1313
def initialize: (String) -> void
1414
def self.from_string: (String) -> FieldConfidence
15-
def certain?: -> bool
16-
def high?: -> bool
17-
def medium?: -> bool
18-
def low?: -> bool
15+
def to_i: -> int
1916
def to_s: -> String
20-
def ==: (FieldConfidence) -> bool
21-
def eql?: (FieldConfidence) -> bool
17+
def ==: (String | Integer | FieldConfidence) -> bool
18+
def eql?: (String | Integer | FieldConfidence) -> bool
19+
def <=: (String | Integer | FieldConfidence) -> bool
20+
def lteql? : (String | Integer | FieldConfidence) -> bool
21+
def >=: (String | Integer | FieldConfidence) -> bool
22+
def gteql?: (String | Integer | FieldConfidence) -> bool
2223
def inspect: -> String
24+
25+
def val_to_i: (String) -> Integer
2326
end
2427
end
2528
end

spec/parsing/v2/inference_spec.rb

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def load_v2_inference(resource_path)
2222
simple_field = Mindee::Parsing::V2::Field::SimpleField
2323
object_field = Mindee::Parsing::V2::Field::ObjectField
2424
list_field = Mindee::Parsing::V2::Field::ListField
25-
field_conf = Mindee::Parsing::V2::Field::FieldConfidence
25+
field_confidence = Mindee::Parsing::V2::Field::FieldConfidence
2626

2727
describe 'simple' do
2828
it 'loads a blank inference with valid properties' do
@@ -264,19 +264,20 @@ def load_v2_inference(resource_path)
264264
expect(polygon[3][0]).to be_within(1e-12).of(0.948849)
265265
expect(polygon[3][1]).to be_within(1e-12).of(0.244565)
266266

267-
# Confidence can be a FieldConfidence instance or a String depending on implementation.
268-
conf_value =
269-
if date_field.confidence.respond_to?(:to_s)
270-
date_field.confidence.to_s
271-
else
272-
date_field.confidence
273-
end
274-
expect(conf_value).to eq('Medium')
275-
276-
# Optional strict check if equality supports comparing with FieldConfidence constants:
277-
if defined?(field_conf) && field_conf.respond_to?(:from_string)
278-
expect(conf_value).to eq(field_conf.from_string('Medium').to_s)
279-
end
267+
confidence = date_field.confidence
268+
expect(confidence).to be_a(field_confidence)
269+
# equality
270+
expect(confidence).to eq(field_confidence::MEDIUM)
271+
expect(confidence).to eq('Medium')
272+
expect(confidence).to eq(2)
273+
# less than or equal
274+
expect(confidence).to be_lteql(field_confidence::HIGH)
275+
expect(confidence).to be_lteql('High')
276+
expect(confidence).to be_lteql(3)
277+
# greater than or equal
278+
expect(confidence).to be_gteql(field_confidence::LOW)
279+
expect(confidence).to be_gteql('Low')
280+
expect(confidence).to be_gteql(1)
280281
end
281282
end
282283
end

0 commit comments

Comments
 (0)