unitwise 0.5.1 → 0.6.0

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
  SHA1:
3
- metadata.gz: d6ff99c65554976100b5a3cc719eb53aa95fc769
4
- data.tar.gz: f3264f24f7f00d2380f2433ac4f5c6d0b7631b04
3
+ metadata.gz: 856dafc49ff1ab7e67a413b4d624f967d54ab8e0
4
+ data.tar.gz: a4960934e8a31ca2c7906f20c76af4b544dd6a69
5
5
  SHA512:
6
- metadata.gz: 83c29762b50698411daacac88989649953282968257a932f86e224b8b9e84e5139cc912b25bf8ff4647df1dda3c6b1e5884e3285284a7b3fc463ff928ad1046c
7
- data.tar.gz: a93702efcf3fcb0f849be1a6cd6a2219c5892df763ffa14f1284c2bb45a2d75c451a9c40db141591cde42ddde0dcbeecb6efcc1386ad795bd1f65d75542e2fdd
6
+ metadata.gz: a72d207aa8b7aff3f700e7645060566c23590857be3072ba63f59bf23b578caf10e8b5e7d1c23d4b9f2350c16a2b49ef8bc524d00ecf0333f3bbef526611d261
7
+ data.tar.gz: 1c8f05c32997d78a957955f951737d5f65371f614af3b39dedf898faf50a55e281f5139e0f205af844d099c7c9d4e3232508ef7255ec6ea4c9e22252b6abfabc
data/lib/unitwise/atom.rb CHANGED
@@ -102,8 +102,12 @@ module Unitwise
102
102
  # or operate on. Base units have a scalar of 1.
103
103
  # @return [Numeric]
104
104
  # @api public
105
- def scalar
106
- base? ? 1 : scale.scalar
105
+ def scalar(x = 1)
106
+ base? ? 1 : scale.scalar(x)
107
+ end
108
+
109
+ def inverse_scalar(x = 1)
110
+ base? ? 1 : scale.inverse_scalar(x)
107
111
  end
108
112
 
109
113
  # Get a functional value that can be used with other atoms to compare with
@@ -111,9 +115,7 @@ module Unitwise
111
115
  # @param x [Numeric] The number to convert to or convert from
112
116
  # @param forward [true, false] Convert to or convert from
113
117
  # @return [Numeric] The converted value
114
- def functional(x = scalar, forward = true)
115
- scale.functional(x, forward)
116
- end
118
+
117
119
 
118
120
  # An atom may have a complex scale with several base atoms at various
119
121
  # depths. This method returns all of this atoms base level terms.
data/lib/unitwise/base.rb CHANGED
@@ -1,14 +1,24 @@
1
1
  require 'yaml'
2
2
  module Unitwise
3
- # The base class that Atom and Prefix are extended from. This class includes
4
- # shared functionality from those classes only.
3
+ # The base class that Atom and Prefix are extended from. This class provides
4
+ # shared functionality for said classes.
5
5
  class Base
6
6
  liner :names, :primary_code, :secondary_code, :symbol, :scale
7
7
 
8
+ # The list of tracked items.
9
+ # @return [Array] An array of memoized instances.
10
+ # @api public
8
11
  def self.all
9
12
  @all ||= data.map { |d| new d }
10
13
  end
11
14
 
15
+ # Find a matching instance by a specified attribute.
16
+ # @param string [String] The search term
17
+ # @param method [Symbol] The attribute to search by
18
+ # @return The first matching instance
19
+ # @example
20
+ # Unitwise::Atom.find('m')
21
+ # @api public
12
22
  def self.find(string, method = :primary_code)
13
23
  all.find do |i|
14
24
  key = i.send(method)
@@ -20,21 +30,32 @@ module Unitwise
20
30
  end
21
31
  end
22
32
 
33
+ # Setup a new instance. Takes a hash of attributes, or an array of
34
+ # attribute values.
35
+ # @api public
23
36
  def initialize(*args)
24
37
  super(*args)
25
38
  freeze
26
39
  end
27
40
 
41
+ # Setter for the names attribute. Will always set as an array.
42
+ # @api semipublic
28
43
  def names=(names)
29
44
  @names = Array(names)
30
45
  end
31
46
 
47
+ # A set of method friendly names.
48
+ # @return [Array] An array of strings
49
+ # @api semipublic
32
50
  def slugs
33
51
  names.map do |n|
34
52
  n.downcase.strip.gsub(/\s/, '_').gsub(/\W/, '')
35
53
  end
36
54
  end
37
55
 
56
+ # String representation for the instance.
57
+ # @return [String]
58
+ # @api public
38
59
  def to_s
39
60
  primary_code
40
61
  end
@@ -31,7 +31,7 @@ module Unitwise
31
31
  # @api public
32
32
  def self.search(term)
33
33
  all.select do |compound|
34
- compound.search_strings.any? { |string| Regexp.new(term).match(string) }
34
+ compound.search_strings.any? { |str| Regexp.new(term).match(str) }
35
35
  end
36
36
  end
37
37
 
@@ -48,7 +48,7 @@ module Unitwise
48
48
  instance_variable_get("@#{attr}") ||
49
49
  instance_variable_set("@#{attr}",
50
50
  if prefix
51
- prefix.send(attr).zip(atom.send(attr)).map{ |set| set.join('') }
51
+ prefix.send(attr).zip(atom.send(attr)).map { |set| set.join('') }
52
52
  else
53
53
  atom.send(attr)
54
54
  end)
@@ -64,11 +64,13 @@ module Unitwise
64
64
  end
65
65
 
66
66
  def search_strings
67
- @search_strings ||= [primary_code, secondary_code, symbol, names, slugs].flatten.uniq
67
+ @search_strings ||= [primary_code, secondary_code, symbol,
68
+ names, slugs].flatten.uniq
68
69
  end
69
70
 
70
71
  def attribute_string
71
- [:atom, :prefix, :primary_code, :secondary_code, :symbol, :names, :slugs].map do |attr|
72
+ [:atom, :prefix, :primary_code, :secondary_code,
73
+ :symbol, :names, :slugs].map do |attr|
72
74
  "#{attr}='#{send attr}'"
73
75
  end.join(', ')
74
76
  end
@@ -6,44 +6,84 @@ module Unitwise
6
6
  class Functional < Scale
7
7
  extend Math
8
8
 
9
- def self._cel(x, forward = true)
10
- forward ? x - 273.15 : x + 273.15
9
+ def self.to_cel(x)
10
+ x - 273.15
11
11
  end
12
12
 
13
- def self._degf(x, forward = true)
14
- forward ? 9.0 * x / 5.0 - 459.67 : 5.0 / 9 * (x + 459.67)
13
+ def self.from_cel(x)
14
+ x + 273.15
15
15
  end
16
16
 
17
- def self._hpX(x, forward = true)
18
- forward ? -log10(x) : 10 ** -x
17
+ def self.to_degf(x)
18
+ 9.0 * x / 5.0 - 459.67
19
19
  end
20
20
 
21
- def self._hpC(x, forward = true)
22
- forward ? -log(x) / log(100) : 100 ** -x
21
+ def self.from_degf(x)
22
+ 5.0 / 9 * (x + 459.67)
23
23
  end
24
24
 
25
- def self._tan100(x, forward = true)
26
- forward ? 100 * tan(x) : atan(x / 100)
25
+ def self.to_hpX(x)
26
+ -log10(x)
27
27
  end
28
28
 
29
- def self._ph(x, forward = true)
30
- _hpX(x,forward)
29
+ def self.from_hpX(x)
30
+ 10 ** -x
31
31
  end
32
32
 
33
- def self._ld(x, forward = true)
34
- forward ? log2(x) : 2 ** x
33
+ def self.to_hpC(x)
34
+ -log(x) / log(100)
35
35
  end
36
36
 
37
- def self._ln(x, forward = true)
38
- forward ? log(x) : Math::E ** x
37
+ def self.from_hpC(x)
38
+ 100 ** -x
39
39
  end
40
40
 
41
- def self._lg(x, forward = true)
42
- forward ? log10(x) : 10 ** x
41
+ def self.to_tan100(x)
42
+ 100 * tan(x)
43
43
  end
44
44
 
45
- def self._2lg(x, forward = true)
46
- forward ? 2 * log10(x) : 10 ** (x / 2)
45
+ def self.from_tan100(x)
46
+ atan(x / 100)
47
+ end
48
+
49
+ def self.to_ph(x)
50
+ to_hpX(x)
51
+ end
52
+
53
+ def self.from_ph(x)
54
+ from_hpX(x)
55
+ end
56
+
57
+ def self.to_ld(x)
58
+ log2(x)
59
+ end
60
+
61
+ def self.from_ld(x)
62
+ 2 ** x
63
+ end
64
+
65
+ def self.to_ln(x)
66
+ log(x)
67
+ end
68
+
69
+ def self.from_ln(x)
70
+ Math::E ** x
71
+ end
72
+
73
+ def self.to_lg(x)
74
+ log10(x)
75
+ end
76
+
77
+ def self.from_lg(x)
78
+ 10 ** x
79
+ end
80
+
81
+ def self.to_2lg(x)
82
+ 2 * log10(x)
83
+ end
84
+
85
+ def self.from_2lg(x)
86
+ 10 ** (x / 2)
47
87
  end
48
88
 
49
89
  attr_reader :function_name
@@ -58,14 +98,21 @@ module Unitwise
58
98
  super(value, unit)
59
99
  end
60
100
 
61
- # Get the equivalent scalar value of a unit based on the atom's function.
62
- # @params x [Numeric]
63
- # @params forward [true, false] The direction of the conversion. Use true
64
- # when converting from the special, use false when converting to the special.
65
- # @return [Numeric]
101
+ # Get the equivalent scalar value of a magnitude on this scale
102
+ # @param magnitude [Numeric] The magnitude to find the scalar value for
103
+ # @return [Numeric] Equivalent linear scalar value
66
104
  # @api public
67
- def functional(x = scalar, forward = true)
68
- self.class.send(:"_#{function_name}", x, forward)
105
+ def scalar(magnitude = value)
106
+ self.class.send(:"from_#{function_name}", magnitude)
69
107
  end
108
+
109
+ # Get the equivalent magnitude on this scale for a scalar value
110
+ # @param scalar [Numeric] A linear scalar value
111
+ # @return [Numeric] The equivalent magnitude on this scale
112
+ # @api public
113
+ def inverse_scalar(scalar = scalar)
114
+ self.class.send(:"to_#{function_name}", scalar)
115
+ end
116
+
70
117
  end
71
118
  end
@@ -152,18 +152,10 @@ module Unitwise
152
152
  # Determine value of the unit after conversion to another unit
153
153
  # @api private
154
154
  def converted_value(other_unit)
155
- if unit.special?
156
- if other_unit.special?
157
- other_unit.functional functional(value, false)
158
- else
159
- functional(value, false) / other_unit.scalar
160
- end
155
+ if other_unit.special?
156
+ other_unit.inverse_scalar scalar
161
157
  else
162
- if other_unit.special?
163
- other_unit.functional(scalar)
164
- else
165
- scalar / other_unit.scalar
166
- end
158
+ scalar / other_unit.scalar
167
159
  end
168
160
  end
169
161
 
@@ -46,16 +46,26 @@ module Unitwise
46
46
  # @param forward [true, false] whether to convert to this unit or from it.
47
47
  # @return [Numeric]
48
48
  # @api public
49
- def functional(x = value, forward = true)
50
- unit.functional(x, forward)
49
+
50
+ # Get a scalar value for this scale.
51
+ # @param magnitude [Numeric] An optional magnitude on this scale.
52
+ # @return [Numeric] A scalar value on a linear scale
53
+ # @api public
54
+ def scalar(magnitude = value)
55
+ if special?
56
+ unit.scalar(magnitude)
57
+ else
58
+ value * unit.scalar
59
+ end
51
60
  end
52
61
 
53
- # Return a scalar value for non-special units, this will be some ratio of a
54
- # child base unit.
55
- # @return [Numeric]
62
+ # Get a magnitude based on a linear scale value. Only used by scales with
63
+ # special atoms in it's hierarchy.
64
+ # @param scalar [Numeric] A linear scalar value
65
+ # @return [Numeric] The equivalent magnitude on this scale
56
66
  # @api public
57
- def scalar
58
- value * unit.scalar
67
+ def inverse_scalar(scalar = scalar)
68
+ unit.inverse_scalar(scalar)
59
69
  end
60
70
 
61
71
  # The base terms this scale's unit is derived from
data/lib/unitwise/term.rb CHANGED
@@ -31,7 +31,7 @@ module Unitwise
31
31
  # Is this term special?
32
32
  # @return [true, false]
33
33
  def special?
34
- atom.special rescue false
34
+ atom.special? rescue false
35
35
  end
36
36
 
37
37
  # Determine how far away a unit is from a base unit.
@@ -62,26 +62,20 @@ module Unitwise
62
62
  super || 1
63
63
  end
64
64
 
65
- # The unitless value for this term. This is the equivalent value of it's
66
- # base atom
67
- # @return [Numeric]
65
+ # The unitless scalar value for this term.
66
+ # @param magnitude [Numeric] The magnitude to calculate the scalar for.
67
+ # @return [Numeric] The unitless linear scalar value.
68
68
  # @api public
69
- def scalar
70
- (factor * (prefix ? prefix.scalar : 1) *
71
- (atom ? atom.scalar : 1)) ** exponent
69
+ def scalar(magnitude = 1)
70
+ calculate(atom ? atom.scalar(magnitude) : 1)
72
71
  end
73
72
 
74
- # Get the equivalent scalar value of a unit based on the atom's function.
75
- # @params x [Numeric]
76
- # @params forward [true, false] The direction of the conversion. Use true
77
- # when converting from the special, use false when converting to the
78
- # special.
79
- # @return [Numeric]
73
+ # Calculate the magnitude for this term
74
+ # @param scalar [Numeric] The scalar for which you want the magnitude
75
+ # @return [Numeric] The magnitude on this scale.
80
76
  # @api public
81
- # @param x [Numeric] The value
82
- def functional(x = scalar, forward = true)
83
- (factor * (prefix ? prefix.scalar : 1)) *
84
- (atom ? atom.functional(x, forward) : 1) ** exponent
77
+ def inverse_scalar(scalar = scalar)
78
+ calculate(atom ? atom.inverse_scalar(scalar) : 1)
85
79
  end
86
80
 
87
81
  # The base units this term is derived from
@@ -140,5 +134,12 @@ module Unitwise
140
134
  [(factor if factor != 1), prefix.to_s,
141
135
  atom.to_s, (exponent if exponent != 1)].compact.join('')
142
136
  end
137
+
138
+ private
139
+
140
+ # @api private
141
+ def calculate(value)
142
+ (factor * (prefix ? prefix.scalar : 1) * value) ** exponent
143
+ end
143
144
  end
144
145
  end
data/lib/unitwise/unit.rb CHANGED
@@ -35,9 +35,6 @@ module Unitwise
35
35
  terms.count == 1 && terms.all?(&:special?)
36
36
  end
37
37
 
38
- def functional(x = scalar, forward = true)
39
- terms.first.functional(x, forward)
40
- end
41
38
 
42
39
  def depth
43
40
  terms.map(&:depth).max + 1
@@ -47,8 +44,16 @@ module Unitwise
47
44
  terms.flat_map(&:root_terms)
48
45
  end
49
46
 
50
- def scalar
51
- terms.map(&:scalar).reduce(&:*)
47
+ def scalar(x = 1)
48
+ terms.reduce(1) do |prod, term|
49
+ prod * term.scalar(x)
50
+ end
51
+ end
52
+
53
+ def inverse_scalar(x = 1)
54
+ terms.reduce(1) do |prod, term|
55
+ prod * term.inverse_scalar(x)
56
+ end
52
57
  end
53
58
 
54
59
  def *(other)
@@ -1,3 +1,3 @@
1
1
  module Unitwise
2
- VERSION = '0.5.1'
2
+ VERSION = '0.6.0'
3
3
  end
@@ -54,15 +54,13 @@ module ScaleTests
54
54
  it "must return value relative to terminal atoms" do
55
55
  subject.scalar.must_equal 4000
56
56
  mph.scalar.must_equal 26.8224
57
+ cel.scalar.must_equal 295.15
57
58
  end
58
59
  end
59
60
 
60
- describe "#functional" do
61
- it "must return a converted value" do
62
- cel.functional(0,true).must_equal -273.15
63
- end
64
- it "must return a de-converted value" do
65
- cel.functional(0,false).must_equal 273.15
61
+ describe "#inverse_scalar" do
62
+ it "must return the magnitude" do
63
+ cel.inverse_scalar.must_equal(22)
66
64
  end
67
65
  end
68
66
 
@@ -3,12 +3,11 @@ require 'test_helper'
3
3
  describe Unitwise::Functional do
4
4
  subject { Unitwise::Functional }
5
5
  %w{cel degf hpX hpC tan100 ph ld ln lg 2lg}.each do |function|
6
- function = :"_#{function}"
7
6
  describe function do
8
7
  it 'should convert back and forth' do
9
8
  number = rand.round(5)
10
- there = subject.send function, number, true
11
- back_again = subject.send function, there, false
9
+ there = subject.send "to_#{function}", number
10
+ back_again = subject.send "from_#{function}", there
12
11
  back_again.round(5).must_equal number
13
12
  end
14
13
  end
@@ -51,7 +51,6 @@ describe Unitwise::Measurement do
51
51
  mult.value.must_equal 180
52
52
  mult.unit.must_equal Unitwise::Unit.new("[mi_i]2/h")
53
53
  end
54
-
55
54
  it "must multiply canceling units" do
56
55
  mult = mph * hpm
57
56
  mult.value.must_equal 360
data/unitwise.gemspec CHANGED
@@ -4,26 +4,29 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'unitwise/version'
5
5
 
6
6
  Gem::Specification.new do |gem|
7
- gem.name = "unitwise"
7
+ gem.name = 'unitwise'
8
8
  gem.version = Unitwise::VERSION
9
- gem.authors = ["Josh Lewis"]
10
- gem.email = ["josh.w.lewis@gmail.com"]
11
- gem.description = %q{Ruby implementation of the Unified Code for Units of Measure (UCUM)}
12
- gem.summary = %q{Unitwise is a library for performing mathematical operations and conversions on all units defined by the Unified Code for Units of Measure(UCUM).}
13
- gem.homepage = "http://github.com/joshwlewis/unitwise"
14
- gem.license = "MIT"
9
+ gem.authors = ['Josh Lewis']
10
+ gem.email = ['josh.w.lewis@gmail.com']
11
+ gem.description = 'Ruby implementation of the Unified Code for Units of ' \
12
+ 'Measure (UCUM)'
13
+ gem.summary = 'Unitwise is a library for performing mathematical '\
14
+ 'operations and conversions on all units defined by '\
15
+ 'the Unified Code for Units of Measure(UCUM).'
16
+ gem.homepage = 'http://github.com/joshwlewis/unitwise'
17
+ gem.license = 'MIT'
15
18
 
16
- gem.files = `git ls-files`.split($/)
17
- gem.test_files = gem.files.grep(%r{^test/})
18
- gem.require_paths = ["lib"]
19
+ gem.files = `git ls-files`.split($RS)
20
+ gem.test_files = gem.files.grep(/^test\//)
21
+ gem.require_paths = ['lib']
19
22
 
20
- gem.add_dependency "liner", "~> 0.2"
21
- gem.add_dependency "signed_multiset", "~> 0.2"
22
- gem.add_dependency "parslet", "~> 1.5"
23
+ gem.add_dependency 'liner', '~> 0.2'
24
+ gem.add_dependency 'signed_multiset', '~> 0.2'
25
+ gem.add_dependency 'parslet', '~> 1.5'
23
26
 
24
- gem.add_development_dependency "minitest", ">= 5.0"
25
- gem.add_development_dependency "rake", ">= 10.0"
26
- gem.add_development_dependency "nori", "~> 2.3"
27
- gem.add_development_dependency "nokogiri", "~> 1.6"
28
- gem.add_development_dependency "coveralls", "~> 0.6"
27
+ gem.add_development_dependency 'minitest', '>= 5.0'
28
+ gem.add_development_dependency 'rake', '>= 10.0'
29
+ gem.add_development_dependency 'nori', '~> 2.3'
30
+ gem.add_development_dependency 'nokogiri', '~> 1.6'
31
+ gem.add_development_dependency 'coveralls', '~> 0.6'
29
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unitwise
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Lewis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-11 00:00:00.000000000 Z
11
+ date: 2014-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liner