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 +4 -4
- data/lib/unitwise/atom.rb +7 -5
- data/lib/unitwise/base.rb +23 -2
- data/lib/unitwise/compound.rb +6 -4
- data/lib/unitwise/functional.rb +74 -27
- data/lib/unitwise/measurement.rb +3 -11
- data/lib/unitwise/scale.rb +17 -7
- data/lib/unitwise/term.rb +18 -17
- data/lib/unitwise/unit.rb +10 -5
- data/lib/unitwise/version.rb +1 -1
- data/test/support/scale_tests.rb +4 -6
- data/test/unitwise/functional_test.rb +2 -3
- data/test/unitwise/measurement_test.rb +0 -1
- data/unitwise.gemspec +21 -18
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 856dafc49ff1ab7e67a413b4d624f967d54ab8e0
|
4
|
+
data.tar.gz: a4960934e8a31ca2c7906f20c76af4b544dd6a69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
4
|
-
# shared functionality
|
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
|
data/lib/unitwise/compound.rb
CHANGED
@@ -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? { |
|
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,
|
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,
|
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
|
data/lib/unitwise/functional.rb
CHANGED
@@ -6,44 +6,84 @@ module Unitwise
|
|
6
6
|
class Functional < Scale
|
7
7
|
extend Math
|
8
8
|
|
9
|
-
def self.
|
10
|
-
|
9
|
+
def self.to_cel(x)
|
10
|
+
x - 273.15
|
11
11
|
end
|
12
12
|
|
13
|
-
def self.
|
14
|
-
|
13
|
+
def self.from_cel(x)
|
14
|
+
x + 273.15
|
15
15
|
end
|
16
16
|
|
17
|
-
def self.
|
18
|
-
|
17
|
+
def self.to_degf(x)
|
18
|
+
9.0 * x / 5.0 - 459.67
|
19
19
|
end
|
20
20
|
|
21
|
-
def self.
|
22
|
-
|
21
|
+
def self.from_degf(x)
|
22
|
+
5.0 / 9 * (x + 459.67)
|
23
23
|
end
|
24
24
|
|
25
|
-
def self.
|
26
|
-
|
25
|
+
def self.to_hpX(x)
|
26
|
+
-log10(x)
|
27
27
|
end
|
28
28
|
|
29
|
-
def self.
|
30
|
-
|
29
|
+
def self.from_hpX(x)
|
30
|
+
10 ** -x
|
31
31
|
end
|
32
32
|
|
33
|
-
def self.
|
34
|
-
|
33
|
+
def self.to_hpC(x)
|
34
|
+
-log(x) / log(100)
|
35
35
|
end
|
36
36
|
|
37
|
-
def self.
|
38
|
-
|
37
|
+
def self.from_hpC(x)
|
38
|
+
100 ** -x
|
39
39
|
end
|
40
40
|
|
41
|
-
def self.
|
42
|
-
|
41
|
+
def self.to_tan100(x)
|
42
|
+
100 * tan(x)
|
43
43
|
end
|
44
44
|
|
45
|
-
def self.
|
46
|
-
|
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
|
62
|
-
# @
|
63
|
-
# @
|
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
|
68
|
-
self.class.send(:"
|
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
|
data/lib/unitwise/measurement.rb
CHANGED
@@ -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
|
156
|
-
|
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
|
-
|
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
|
|
data/lib/unitwise/scale.rb
CHANGED
@@ -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
|
-
|
50
|
-
|
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
|
-
#
|
54
|
-
#
|
55
|
-
# @
|
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
|
-
|
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.
|
66
|
-
#
|
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
|
-
(
|
71
|
-
(atom ? atom.scalar : 1)) ** exponent
|
69
|
+
def scalar(magnitude = 1)
|
70
|
+
calculate(atom ? atom.scalar(magnitude) : 1)
|
72
71
|
end
|
73
72
|
|
74
|
-
#
|
75
|
-
# @
|
76
|
-
# @
|
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
|
-
|
82
|
-
|
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.
|
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)
|
data/lib/unitwise/version.rb
CHANGED
data/test/support/scale_tests.rb
CHANGED
@@ -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 "#
|
61
|
-
it "must return
|
62
|
-
cel.
|
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
|
11
|
-
back_again = subject.send function, there
|
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
|
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 =
|
7
|
+
gem.name = 'unitwise'
|
8
8
|
gem.version = Unitwise::VERSION
|
9
|
-
gem.authors = [
|
10
|
-
gem.email = [
|
11
|
-
gem.description =
|
12
|
-
|
13
|
-
gem.
|
14
|
-
|
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(
|
18
|
-
gem.require_paths = [
|
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
|
21
|
-
gem.add_dependency
|
22
|
-
gem.add_dependency
|
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
|
25
|
-
gem.add_development_dependency
|
26
|
-
gem.add_development_dependency
|
27
|
-
gem.add_development_dependency
|
28
|
-
gem.add_development_dependency
|
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.
|
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
|
+
date: 2014-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: liner
|