unitwise 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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