unit_measurements 1.3.0 → 1.5.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
  SHA256:
3
- metadata.gz: 3562e30ce7bfed682e67fbdc5c9d8d30b011a6cd16996b7efe6860622abf25d5
4
- data.tar.gz: af4224714284377ebd6aea3a78c4842078f708eeaf06500658ef45f151192373
3
+ metadata.gz: 6d1b9cef9a108d5a0930ca0fd0a2e156a5653893786eb97159c7c4c801e71970
4
+ data.tar.gz: a4ef6d728ad141f2d19ab5151ea3205ce2098710b8facf1d979b4299e8a72530
5
5
  SHA512:
6
- metadata.gz: 22a6a8f0b97a5ef1845448bcf219fbd2d0228b3d74b409e93ce596f7648d67207ea5caa64f39e0c0dd9083bf6425c1012bbf11f25624faf718f377307b698309
7
- data.tar.gz: 1a436d77f1a99a7eb838e397b0038b7aba73fe19d3acf7aa0e02dbd3d482beeb2fd6b33b648d2b02514681ba6b792076596f761dbca41fb0eab3985d84209f27
6
+ metadata.gz: 360ba9c4e48722b51fc9d9dd049ddd2217aac3c30d3de6afb66ee10d31d466d15e743f6437ceb6d7f232844378f6ca3be995447627e4264c1c25d1e7db9690e5
7
+ data.tar.gz: 8bed02dfd85b3933e128e2c390a12f5f63f15950ddadd053063822f00be4b8c3464992ad0d51440bebcbad78c7b0df1b80cdcb341b1d1dbeea0d1171ed06ffdc
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## [1.5.0](https://github.com/shivam091/unit_measurements/compare/v1.4.0...v1.5.0) - 2023-08-18
2
+
3
+ ## What's fixed
4
+
5
+ - Fixed precision in `Measurement#quantity` method
6
+
7
+ ----------
8
+
9
+ ## [1.4.0](https://github.com/shivam091/unit_measurements/compare/v1.3.0...v1.4.0) - 2023-08-17
10
+
11
+ ### What's new
12
+
13
+ - Added ability to perform `arithmetic` operations of measurements.
14
+
15
+ ----------
16
+
1
17
  ## [1.3.0](https://github.com/shivam091/unit_measurements/compare/v1.2.0...v1.3.0) - 2023-08-16
2
18
 
3
19
  ### What's new
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- unit_measurements (1.3.0)
4
+ unit_measurements (1.5.0)
5
5
  activesupport (~> 7.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -79,14 +79,14 @@ You can use `#convert_to` as:
79
79
 
80
80
  ```ruby
81
81
  UnitMeasurements::Weight.new(1, :kg).convert_to(:g)
82
- #=> 1000 g
82
+ #=> 1000.0 g
83
83
  ```
84
84
 
85
85
  If you want to modify measurement object itself, you can use `#convert_to!` method as:
86
86
 
87
87
  ```ruby
88
88
  UnitMeasurements::Weight.new(1, :kg).convert_to!(:g)
89
- #=> 1000 g
89
+ #=> 1000.0 g
90
90
  ```
91
91
 
92
92
  You can also chain call of `#convert_to` and `#convert_to!` methods as:
@@ -100,18 +100,18 @@ UnitMeasurements::Weight.new(1, :kg).convert_to(:g).convert_to(:t).convert_to!(:
100
100
 
101
101
  ```ruby
102
102
  UnitMeasurements::Weight.parse("1 kg")
103
- #=> 1 kg
103
+ #=> 1.0 kg
104
104
  ```
105
105
 
106
106
  **Parse string that mentions quantity, source unit, and target unit:**
107
107
 
108
108
  ```ruby
109
109
  UnitMeasurements::Weight.parse("1 kg to g")
110
- #=> 1000 g
110
+ #=> 1000.0 g
111
111
  UnitMeasurements::Weight.parse("1 kg as g")
112
- #=> 1000 g
112
+ #=> 1000.0 g
113
113
  UnitMeasurements::Weight.parse("1 kg in g")
114
- #=> 1000 g
114
+ #=> 1000.0 g
115
115
  ```
116
116
 
117
117
  **Parse rational numbers, source unit, and (or) target unit:**
@@ -144,58 +144,58 @@ UnitMeasurements::Weight.parse("2+3i kg to g")
144
144
 
145
145
  ```ruby
146
146
  UnitMeasurements::Weight.new(BigDecimal(2), :kg).convert_to(:g)
147
- #=> 2000 g
147
+ #=> 2000.0 g
148
148
  UnitMeasurements::Weight.new(0.2e1, :kg).convert_to(:g)
149
- #=> 2000 g
149
+ #=> 2000.0 g
150
150
  UnitMeasurements::Weight.parse("0.2e1 kg").convert_to(:g)
151
- #=> 2000 g
151
+ #=> 2000.0 g
152
152
  UnitMeasurements::Weight.parse("0.2e1 kg to g")
153
- #=> 2000 g
153
+ #=> 2000.0 g
154
154
  ```
155
155
 
156
156
  **Parse ratios, source unit, and (or) target unit:**
157
157
 
158
158
  ```ruby
159
159
  UnitMeasurements::Weight.new("1:2", :kg).convert_to(:g)
160
- #=> 500 g
160
+ #=> 500.0 g
161
161
  UnitMeasurements::Weight.parse("1:2 kg").convert_to(:g)
162
- #=> 500 g
162
+ #=> 500.0 g
163
163
  UnitMeasurements::Weight.parse("1:2 kg to g")
164
- #=> 500 g
164
+ #=> 500.0 g
165
165
  ```
166
166
 
167
167
  **Parse fractional notations, source unit, and (or) target unit:**
168
168
 
169
169
  ```ruby
170
170
  UnitMeasurements::Weight.new("1/2", :kg).convert_to(:g)
171
- #=> 500 g
171
+ #=> 500.0 g
172
172
  UnitMeasurements::Weight.parse("1/2 kg").convert_to(:g)
173
- #=> 500 g
173
+ #=> 500.0 g
174
174
  UnitMeasurements::Weight.parse("1/2 kg to g")
175
- #=> 500 g
175
+ #=> 500.0 g
176
176
  UnitMeasurements::Weight.new("½", :kg).convert_to(:g)
177
- #=> 500 g
177
+ #=> 500.0 g
178
178
  UnitMeasurements::Weight.parse("½ kg").convert_to(:g)
179
- #=> 500 g
179
+ #=> 500.0 g
180
180
  UnitMeasurements::Weight.parse("½ kg to g")
181
- #=> 500 g
181
+ #=> 500.0 g
182
182
  ```
183
183
 
184
184
  **Parse mixed fractional notations, source unit, and (or) target unit:**
185
185
 
186
186
  ```ruby
187
187
  UnitMeasurements::Weight.new("2 1/2", :kg).convert_to(:g)
188
- #=> 2500 g
188
+ #=> 2500.0 g
189
189
  UnitMeasurements::Weight.parse("2 1/2 kg").convert_to(:g)
190
- #=> 2500 g
190
+ #=> 2500.0 g
191
191
  UnitMeasurements::Weight.parse("2 1/2 kg to g")
192
- #=> 2500 g
192
+ #=> 2500.0 g
193
193
  UnitMeasurements::Weight.new("2 ½", :kg).convert_to(:g)
194
- #=> 2500 g
194
+ #=> 2500.0 g
195
195
  UnitMeasurements::Weight.parse("2 ½ kg").convert_to(:g)
196
- #=> 2500 g
196
+ #=> 2500.0 g
197
197
  UnitMeasurements::Weight.parse("2 ½ kg to g")
198
- #=> 2500 g
198
+ #=> 2500.0 g
199
199
  ```
200
200
 
201
201
  Supported special characters for fractional notations are `¼`, `½`, `¾`, `⅓`, `⅔`, `⅕`, `⅖`, `⅗`, `⅘`, `⅙`, `⅚`, `⅐`, `⅛`, `⅜`, `⅝`, `⅞`, `⅑`, `⅒`, `↉`, `⁄`.
@@ -204,17 +204,17 @@ Supported special characters for fractional notations are `¼`, `½`, `¾`, `⅓
204
204
 
205
205
  ```ruby
206
206
  UnitMeasurements::Weight.new("2e+2", :kg).convert_to(:g)
207
- #=> 200000 g
207
+ #=> 200000.0 g
208
208
  UnitMeasurements::Weight.parse("2e² kg").convert_to(:g)
209
- #=> 200000 g
209
+ #=> 200000.0 g
210
210
  UnitMeasurements::Weight.parse("2e+2 kg to g")
211
- #=> 200000 g
211
+ #=> 200000.0 g
212
212
  UnitMeasurements::Weight.new("2e⁺²", :kg).convert_to(:g)
213
- #=> 200000 g
213
+ #=> 200000.0 g
214
214
  UnitMeasurements::Weight.parse("2e⁺2 kg").convert_to(:g)
215
- #=> 200000 g
215
+ #=> 200000.0 g
216
216
  UnitMeasurements::Weight.parse("2e⁻² kg to g")
217
- #=> 20 g
217
+ #=> 20.0 g
218
218
  ```
219
219
 
220
220
  Supported special characters for exponents are `⁰`, `¹`, `²`, `³`, `⁴`, `⁵`, `⁶`, `⁷`, `⁸`, `⁹`, `⁺`, `⁻`.
@@ -236,9 +236,9 @@ UnitMeasurements::Weight.parse("2 kg").to(:st).format("%.4<quantity>f")
236
236
  **Extract the unit and the quantity from measurement:**
237
237
 
238
238
  ```ruby
239
- weight = UnitMeasurements::Weight.new(1.0, :kg)
239
+ weight = UnitMeasurements::Weight.new(1, :kg)
240
240
  weight.quantity
241
- #=> 0.1e1
241
+ #=> 1
242
242
  weight.unit
243
243
  #=> #<UnitMeasurements::Unit: kg (kilogram, kilogramme, kilogrammes, kilograms)>
244
244
  ```
@@ -322,6 +322,29 @@ UnitMeasurements::Weight.parse("1 kg") >= UnitMeasurements::Weight.parse("0.5 kg
322
322
  #=> true
323
323
  ```
324
324
 
325
+ ### Arithmetic
326
+
327
+ You have ability to perform arithmetic operations on measurements with the same or
328
+ different units within a same unit group. You can perform arithmetic operations on
329
+ measurement by either other compatible measurement or number.
330
+
331
+ **Methods:**
332
+ 1. `#+` - Adds the other measurement quantity or number to the measurement.
333
+ 2. `#-` - Subtracts the other measurement quantity or number from the measurement.
334
+ 3. `#*` - Multiplies the measurement quantity by other measurement quantity or number.
335
+ 4. `#/` - Divides the measurement quantity by other measurement quantity or number.
336
+
337
+ ```ruby
338
+ UnitMeasurements::Weight.new(1, :kg) + UnitMeasurements::Weight.new(1, :g)
339
+ #=> 1.001 kg
340
+ UnitMeasurements::Weight.new(2, :kg) - 1
341
+ #=> 1 kg
342
+ UnitMeasurements::Weight.new(2, :kg) * 2
343
+ #=> 4 kg
344
+ UnitMeasurements::Weight.new(4, :kg) / UnitMeasurements::Weight.new(2, :kg)
345
+ #=> 2 kg
346
+ ```
347
+
325
348
  ## Units
326
349
 
327
350
  The **`UnitMeasurements::Unit`** class is used to represent the units for a measurement.
@@ -0,0 +1,74 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # -*- frozen_string_literal: true -*-
3
+ # -*- warn_indent: true -*-
4
+
5
+ module UnitMeasurements
6
+ module Arithmetic
7
+ # Adds the other measurement quantity or number to the measurement.
8
+ #
9
+ # @param [Numeric or Measurement] other
10
+ #
11
+ # @example
12
+ # UnitMeasurements::Weight.new(1, :kg) + UnitMeasurements::Weight.new(1, :g)
13
+ # => 1.001 kg
14
+ #
15
+ # @return [Measurement]
16
+ def +(other)
17
+ arithmetic_operation(other, :+)
18
+ end
19
+
20
+ # Subtracts the other measurement quantity or number from the measurement.
21
+ #
22
+ # @param [Numeric or Measurement] other
23
+ #
24
+ # @example
25
+ # UnitMeasurements::Weight.new(2, :kg) - 1
26
+ # => 1 kg
27
+ #
28
+ # @return [Measurement]
29
+ def -(other)
30
+ arithmetic_operation(other, :-)
31
+ end
32
+
33
+ # Multiplies the measurement quantity by other measurement quantity or number.
34
+ #
35
+ # @param [Numeric or Measurement] other
36
+ #
37
+ # @example
38
+ # UnitMeasurements::Weight.new(2, :kg) * 2
39
+ # => 4 kg
40
+ #
41
+ # @return [Measurement]
42
+ def *(other)
43
+ arithmetic_operation(other, :*)
44
+ end
45
+
46
+ # Divides the measurement quantity by other measurement quantity or number.
47
+ #
48
+ # @param [Numeric or Measurement] other
49
+ #
50
+ # @example
51
+ # UnitMeasurements::Weight.new(4, :kg) / UnitMeasurements::Weight.new(2, :kg)
52
+ # => 2 kg
53
+ #
54
+ # @return [Measurement]
55
+ def /(other)
56
+ arithmetic_operation(other, :/)
57
+ end
58
+
59
+ private
60
+
61
+ def coerce(other)
62
+ case other
63
+ when Numeric then [self.class.new(other, self.unit), self]
64
+ when self.class then [other, self]
65
+ else raise TypeError, "Cannot coerce #{other.class} to #{self.class}"
66
+ end
67
+ end
68
+
69
+ def arithmetic_operation(other, operator)
70
+ other, _ = coerce(other)
71
+ self.class.new(self.quantity.public_send(operator, other.convert_to(self.unit).quantity), self.unit)
72
+ end
73
+ end
74
+ end
@@ -25,10 +25,11 @@ end
25
25
  require "unit_measurements/unit_group_builder"
26
26
  require "unit_measurements/unit"
27
27
  require "unit_measurements/unit_group"
28
+ require "unit_measurements/arithmetic"
29
+ require "unit_measurements/comparison"
28
30
  require "unit_measurements/normalizer"
29
31
  require "unit_measurements/parser"
30
32
  require "unit_measurements/formatter"
31
- require "unit_measurements/comparison"
32
33
  require "unit_measurements/measurement"
33
34
 
34
35
  require "unit_measurements/errors/unit_error"
@@ -6,6 +6,7 @@ module UnitMeasurements
6
6
  class Measurement
7
7
  include Formatter
8
8
  include Comparison
9
+ include Arithmetic
9
10
 
10
11
  CONVERSION_STRING_REGEXP = /(.+?)\s?(?:\s+(?:in|to|as)\s+(.+)|\z)/i.freeze
11
12
 
@@ -43,7 +44,16 @@ module UnitMeasurements
43
44
  end
44
45
 
45
46
  def to_s
46
- "#{humanized_quantity} #{unit.to_s}"
47
+ "#{quantity} #{unit}"
48
+ end
49
+
50
+ def quantity
51
+ case @quantity
52
+ when Rational
53
+ @quantity.denominator == 1 ? @quantity.numerator : @quantity
54
+ else
55
+ @quantity
56
+ end
47
57
  end
48
58
 
49
59
  class << self
@@ -91,15 +101,5 @@ module UnitMeasurements
91
101
  def unit_from_unit_or_name!(value)
92
102
  value.is_a?(Unit) ? value : self.class.unit_group.unit_for!(value)
93
103
  end
94
-
95
- def humanized_quantity
96
- case quantity
97
- when Complex
98
- quantity
99
- when Numeric
100
- num = quantity.to_r
101
- num.denominator == 1 ? num.numerator.to_s : num.to_f.to_s
102
- end
103
- end
104
104
  end
105
105
  end
@@ -3,5 +3,5 @@
3
3
  # -*- warn_indent: true -*-
4
4
 
5
5
  module UnitMeasurements
6
- VERSION = "1.3.0"
6
+ VERSION = "1.5.0"
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unit_measurements
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harshal LADHE
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-09-16 00:00:00.000000000 Z
11
+ date: 2023-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -103,6 +103,7 @@ files:
103
103
  - README.md
104
104
  - Rakefile
105
105
  - lib/unit_measurements.rb
106
+ - lib/unit_measurements/arithmetic.rb
106
107
  - lib/unit_measurements/base.rb
107
108
  - lib/unit_measurements/comparison.rb
108
109
  - lib/unit_measurements/errors/parse_error.rb