inci_score 4.1.4 → 4.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 81748de653f3df8bca12f42b32322214040c71f4b943bbea225e12f8683e35f2
4
- data.tar.gz: aa461eb90bc58f31a55bd6263cab0a64b1cb22f7ffde4fec202531df6710bbc7
3
+ metadata.gz: 07a79ba247cd43e62ef0988548df410598bf87cb653fd1540f8c6e419a31d03a
4
+ data.tar.gz: d0ea4f382824592d33d5bc6ec8bc5d3f88c6a704d24f093259a90da77bf3c6c9
5
5
  SHA512:
6
- metadata.gz: 5592961b10ec6bbef156e83358c880776cba5ffdd00c5ec42c804f7acf86cf7a9ebf832cda9da4345e670ab139d3682e787aedf272db5cf2469fc5afedcff86e
7
- data.tar.gz: 560ef5d1da9749a4adfaae809fd04d2efa9ec56dd1e2ab9b39644d950c35b335fc412dda6d72adfa9bb033877a6cb41d7052d9a75a7a38dacd9ab6ebd1c510b8
6
+ metadata.gz: 5b92528b5d0ef275afce0db6c5d8039eb48daa2e08c098cd5d768dc61be10c2bfa72c24795dea1f28ebc54ef3287beb60449a4a41930e19283072a7c3948cc6f
7
+ data.tar.gz: e414756b761775502d54ab4e62e20385148a1a706fed3057ad5a74b47be7ee8274cddcde235d357851158e3e5b28f9961e7873dd675125291b1c226b6f2dc71f
data/config/catalog.yml CHANGED
@@ -2054,6 +2054,7 @@ isododecane: 3
2054
2054
  isodonis japonicus: 0
2055
2055
  isodonis torichocarpus: 0
2056
2056
  isoeugenol: 3
2057
+ isohexadecane: 3
2057
2058
  isolaureth-10: 3
2058
2059
  isolaureth-3: 3
2059
2060
  isolaureth-6: 3
@@ -4,20 +4,19 @@ require 'optparse'
4
4
 
5
5
  module InciScore
6
6
  class CLI
7
- attr_reader :args, :io, :catalog
7
+ attr_reader :args, :io
8
8
  attr_accessor :src
9
9
 
10
- def initialize(args:, io: STDOUT, catalog: Config::CATALOG)
10
+ def initialize(args:, io: STDOUT)
11
11
  @args = args
12
12
  @io = io
13
- @catalog = catalog
14
13
  @src = nil
15
14
  end
16
15
 
17
16
  def call
18
17
  parser.parse!(args)
19
18
  return io.puts(%q{Specify inci list as: --src='aqua, parfum, etc'}) unless src
20
- computer = Computer.new(src: src, catalog: catalog)
19
+ computer = Computer.new(src: src)
21
20
  io.puts computer.call
22
21
  end
23
22
 
@@ -5,12 +5,11 @@ module InciScore
5
5
  TOLERANCE = 30.0
6
6
  DECIMALS = 2
7
7
 
8
- attr_reader :src, :catalog, :rules, :ingredients, :components, :unrecognized
8
+ attr_reader :src, :rules, :ingredients, :components, :unrecognized
9
9
 
10
- def initialize(src:, catalog: Config::CATALOG, rules: Normalizer::DEFAULT_RULES)
10
+ def initialize(src:, rules: Normalizer::DEFAULT_RULES)
11
11
  @unrecognized = []
12
12
  @src = src
13
- @catalog = catalog
14
13
  @rules = rules
15
14
  @ingredients = Normalizer.new(src: src, rules: rules).call
16
15
  @components = fetch_components
@@ -21,7 +20,6 @@ module InciScore
21
20
  Response.new(components: components,
22
21
  unrecognized: unrecognized,
23
22
  score: score,
24
- valid: valid?,
25
23
  precision: precision)
26
24
  end
27
25
 
@@ -41,7 +39,7 @@ module InciScore
41
39
 
42
40
  def fetch_components
43
41
  ingredients.map do |ingredient|
44
- Recognizer.new(ingredient, catalog).call.tap do |component|
42
+ Recognizer.new(ingredient).call.tap do |component|
45
43
  unrecognized << ingredient unless component
46
44
  end
47
45
  end.compact
@@ -2,15 +2,14 @@
2
2
 
3
3
  module InciScore
4
4
  class Recognizer
5
- DEFAULT_RULES = [Rules::Key, Rules::Levenshtein, Rules::Digits, Rules::Hazard, Rules::Tokens].freeze
5
+ DEFAULT_RULES = [Rules::Key, Rules::Levenshtein, Rules::Hazard, Rules::Prefix, Rules::Tokens].freeze
6
6
 
7
7
  Component = Struct.new(:name, :hazard)
8
8
 
9
- attr_reader :ingredient, :catalog, :rules, :applied
9
+ attr_reader :ingredient, :rules, :applied
10
10
 
11
- def initialize(ingredient, catalog, rules = DEFAULT_RULES, wrapper = Ingredient)
11
+ def initialize(ingredient, rules = DEFAULT_RULES, wrapper = Ingredient)
12
12
  @ingredient = wrapper.new(ingredient)
13
- @catalog = catalog
14
13
  @rules = rules
15
14
  @applied = []
16
15
  freeze
@@ -20,7 +19,7 @@ module InciScore
20
19
  return if ingredient.to_s.empty?
21
20
  component = find_component
22
21
  return unless component
23
- Component.new(component, catalog[component])
22
+ Component.new(component, Config::CATALOG[component])
24
23
  end
25
24
 
26
25
  private
@@ -35,7 +34,7 @@ module InciScore
35
34
 
36
35
  def apply(rule)
37
36
  ingredient.values.map do |value|
38
- rule.call(value, catalog)
37
+ rule.call(value)
39
38
  end.find(&:itself)
40
39
  end
41
40
  end
@@ -7,9 +7,9 @@ module InciScore
7
7
  module Rules
8
8
  TOLERANCE = 3
9
9
 
10
- Key = ->(src, catalog) { src if catalog.has_key?(src) }
10
+ Key = ->(src) { src if Config::CATALOG.has_key?(src) }
11
11
 
12
- Hazard = ->(src, _) { 'generic-hazard' if Config::HAZARDS.any? { |h| src.include?(h) } }
12
+ Hazard = ->(src) { 'generic-hazard' if Config::HAZARDS.any? { |h| src.include?(h) } }
13
13
 
14
14
  module Levenshtein
15
15
  extend self
@@ -20,12 +20,12 @@ module InciScore
20
20
  end
21
21
  end
22
22
 
23
- def call(src, catalog)
23
+ def call(src)
24
24
  return if src.empty?
25
25
  size = src.size
26
26
  farthest = Result.new(nil, size)
27
27
  initial = src[0]
28
- result = catalog.reduce(farthest) do |nearest, (component, _)|
28
+ result = Config::CATALOG.reduce(farthest) do |nearest, (component, _)|
29
29
  next nearest unless component.start_with?(initial)
30
30
  next nearest if component.size > (size + TOLERANCE)
31
31
  d = src.distance(component)
@@ -36,15 +36,15 @@ module InciScore
36
36
  end
37
37
  end
38
38
 
39
- module Digits
39
+ module Prefix
40
40
  extend self
41
41
 
42
42
  MIN_MEANINGFUL = 7
43
43
 
44
- def call(src, catalog)
44
+ def call(src)
45
45
  return if src.size < TOLERANCE
46
46
  digits = src[0, MIN_MEANINGFUL]
47
- catalog.detect { |component, _| component.start_with?(digits) }.to_a.first
47
+ Config::CATALOG.detect { |component, _| component.start_with?(digits) }.to_a.first
48
48
  end
49
49
  end
50
50
 
@@ -53,9 +53,10 @@ module InciScore
53
53
 
54
54
  UNMATCHABLE = %w[extract oil sodium acid sulfate].freeze
55
55
 
56
- def call(src, catalog)
56
+ def call(src)
57
+ return if src.size <= TOLERANCE
57
58
  tokens(src).each do |token|
58
- catalog.each do |component, _|
59
+ Config::CATALOG.each do |component, _|
59
60
  return component if component.include?(token)
60
61
  end
61
62
  end
@@ -65,7 +66,8 @@ module InciScore
65
66
  private
66
67
 
67
68
  def tokens(src)
68
- (src.split(' ') - UNMATCHABLE).reject { |t| t.size < TOLERANCE }.sort! { |a, b| b.size <=> a.size }
69
+ words = src.split(' ').map { |w| w.split('-') }.flatten
70
+ (words - UNMATCHABLE).reject { |t| t.size < TOLERANCE }.sort! { |a, b| b.size <=> a.size }
69
71
  end
70
72
  end
71
73
  end
@@ -4,19 +4,18 @@ require 'oj'
4
4
 
5
5
  module InciScore
6
6
  class Response
7
- attr_reader :components, :score, :unrecognized, :valid, :precision
7
+ attr_reader :components, :score, :unrecognized, :precision
8
8
 
9
9
  def initialize(options = {})
10
10
  @components = options.fetch(:components) { [] }
11
11
  @score = options.fetch(:score) { 0.0 }
12
12
  @unrecognized = options.fetch(:unrecognized) { [] }
13
- @valid = options.fetch(:valid) { false }
14
13
  @precision = options.fetch(:precision) { 0 }
15
14
  freeze
16
15
  end
17
16
 
18
17
  def to_json
19
- data = { components: components.map(&:to_h), unrecognized: unrecognized, score: score, valid: valid, precision: precision }.freeze
18
+ data = { components: components.map(&:to_h), unrecognized: unrecognized, score: score, precision: precision }.freeze
20
19
  Oj.dump(data, mode: :compat)
21
20
  end
22
21
 
@@ -24,8 +23,6 @@ module InciScore
24
23
  %Q{
25
24
  TOTAL SCORE:
26
25
  \t#{score}
27
- VALID STATE:
28
- \t#{valid}
29
26
  PRECISION:
30
27
  \t#{precision}
31
28
  COMPONENTS:
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module InciScore
4
- VERSION = '4.1.4'
4
+ VERSION = '4.2.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inci_score
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.4
4
+ version: 4.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - costajob