calcpace 1.5.3 → 1.5.4

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: 8f81c674297297f5dc9d2d29055c08472339dee66afb992657627444101abc89
4
- data.tar.gz: f85b35535b3e6ddcb26a6156de8ddfa3ed06ac6870d1354b4f6c88c3b91c95d6
3
+ metadata.gz: 522046fd25c06347010dd5eaafafead682c8f112b559e0d6932cad8131170441
4
+ data.tar.gz: 20b0c9a3a1fb855bedfcac50463ef223ae200466404901207a9c082b4e54eb8c
5
5
  SHA512:
6
- metadata.gz: b2a1a7bcc0ad7991d8866d40b4db5d1f90e3d0eab27ff0865ed5030afb8b3eba75dd67d475bfa8ec88bef8e89b4083cd87fb04532962750278c6e6e3b26d858d
7
- data.tar.gz: 28bc176b51fbca833b855c00050e8d006327c9023b5fa17157df8d7eeffee17b79d396c7fa46458061b0835977054b78381254927fde0d3a470b5efcc6178be9
6
+ metadata.gz: 1b4bf0d96394bff3711b5691499e4719e8f57fec6850ad96a87376bd339e5b478b645e827acda80be8cc1aa48b40b642e53aa8cdc050f308dda2a5c7b0d38a29
7
+ data.tar.gz: be6fd9bd85c4b20c479f57d2637342dce116bc24c2fc0a5f867b5cd0a014e4534875e4d1ef29fd29aacb3cf0e06d564bc81f06171ced58a3aa9a850ef6e55b7f
@@ -0,0 +1,28 @@
1
+ name: Tests
2
+ on:
3
+ push:
4
+ branches: [ "main" ]
5
+ pull_request:
6
+ branches: [ "main" ]
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ ruby: ['2.7', '3.0', '3.1', '3.2', '3.3', '3.4']
15
+ steps:
16
+ - name: Checkout code
17
+ uses: actions/checkout@v4
18
+ - name: Set up Ruby
19
+ uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby }}
22
+ bundler-cache: true
23
+ - name: Install Bundler
24
+ run: gem install bundler
25
+ - name: Build Gem
26
+ run: gem build calcpace.gemspec
27
+ - name: Run tests
28
+ run: bundle exec rake
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ calcpace-*
2
+ calcpace.*
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.4.2
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'minitest', '~> 5.25'
6
+ gem 'rake', '~> 13.2'
7
+ gem 'rake-compiler', '~> 1.0'
8
+ gem 'rdoc', '~> 6.2'
9
+ gem 'rubocop', '~> 1.69'
data/Gemfile.lock ADDED
@@ -0,0 +1,55 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ ast (2.4.2)
5
+ date (3.4.1)
6
+ json (2.10.2)
7
+ language_server-protocol (3.17.0.4)
8
+ lint_roller (1.1.0)
9
+ minitest (5.25.4)
10
+ parallel (1.26.3)
11
+ parser (3.3.7.1)
12
+ ast (~> 2.4.1)
13
+ racc
14
+ psych (5.2.3)
15
+ date
16
+ stringio
17
+ racc (1.8.1)
18
+ rainbow (3.1.1)
19
+ rake (13.2.1)
20
+ rake-compiler (1.2.9)
21
+ rake
22
+ rdoc (6.12.0)
23
+ psych (>= 4.0.0)
24
+ regexp_parser (2.10.0)
25
+ rubocop (1.73.2)
26
+ json (~> 2.3)
27
+ language_server-protocol (~> 3.17.0.2)
28
+ lint_roller (~> 1.1.0)
29
+ parallel (~> 1.10)
30
+ parser (>= 3.3.0.2)
31
+ rainbow (>= 2.2.2, < 4.0)
32
+ regexp_parser (>= 2.9.3, < 3.0)
33
+ rubocop-ast (>= 1.38.0, < 2.0)
34
+ ruby-progressbar (~> 1.7)
35
+ unicode-display_width (>= 2.4.0, < 4.0)
36
+ rubocop-ast (1.38.1)
37
+ parser (>= 3.3.1.0)
38
+ ruby-progressbar (1.13.0)
39
+ stringio (3.1.5)
40
+ unicode-display_width (3.1.4)
41
+ unicode-emoji (~> 4.0, >= 4.0.4)
42
+ unicode-emoji (4.0.4)
43
+
44
+ PLATFORMS
45
+ ruby
46
+
47
+ DEPENDENCIES
48
+ minitest (~> 5.25)
49
+ rake (~> 13.2)
50
+ rake-compiler (~> 1.0)
51
+ rdoc (~> 6.2)
52
+ rubocop (~> 1.69)
53
+
54
+ BUNDLED WITH
55
+ 2.4.22
data/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # Calcpace [![Gem Version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=rb&r=r&ts=1683906897&type=6e&v=1.5.4&x2=0)](https://badge.fury.io/rb/calcpace)
2
+
3
+ Calcpace is a Ruby gem designed for calculations and conversions related to distance and time. It can calculate velocity, pace, total time, and distance, accepting time in various formats, including HH:MM:SS. The gem supports conversion to 42 different units, including kilometers, miles, meters, and feet. It also provides methods to validate input.
4
+
5
+ ## Installation
6
+
7
+ ### Add to your Gemfile
8
+
9
+ ```ruby
10
+ gem 'calcpace', '~> 1.5.4'
11
+ ```
12
+
13
+ Then run:
14
+
15
+ ```bash
16
+ bundle install
17
+ ```
18
+
19
+ ### Install the gem manually
20
+
21
+ ```bash
22
+ gem install calcpace
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ Before performing any calculations or conversions, create a new instance of Calcpace:
28
+
29
+ ```ruby
30
+ require 'calcpace'
31
+
32
+ calculate = Calcpace.new
33
+ ```
34
+
35
+ ### Calculate using Integers or Floats
36
+
37
+ Calcpace provides methods to calculate velocity, pace, total time, and distance. The methods are unit-agnostic, and the return value is a float. Here are some examples:
38
+
39
+ ```ruby
40
+ calculate.velocity(3625, 12275) # => 3.386206896551724
41
+ calculate.pace(3665, 12) # => 305.4166666666667
42
+ calculate.time(210, 12) # => 2520.0
43
+ calculate.distance(9660, 120) # => 80.5
44
+ ```
45
+
46
+ Tip: Use the `round` method to round a float. For example:
47
+
48
+ ```ruby
49
+ calculate.velocity(3625, 12275).round(3) # => 3.386
50
+ ```
51
+
52
+ Remember:
53
+
54
+ - Velocity is the distance divided by the time (e.g., m/s or km/h).
55
+ - Pace is the time divided by the distance (e.g., minutes/km or minutes/miles).
56
+ - Total time is the distance divided by the velocity.
57
+ - Distance is the velocity multiplied by the time.
58
+
59
+ ### Calculate using Clocktime
60
+
61
+ Calcpace also provides methods to calculate using clocktime (HH:MM:SS or MM:SS format string). The return value will be in seconds or clocktime, depending on the method called, except for `checked_distance`. Here are some examples:
62
+
63
+ ```ruby
64
+ # The return will be in the unit you input/seconds or seconds/unit you input
65
+ calculate.checked_velocity('01:00:00', 12275) # => 3.4097222222222223
66
+ calculate.checked_pace('01:21:32', 10) # => 489.2
67
+ calculate.checked_time('00:05:31', 12.6) # => 4170.599999999999
68
+
69
+ calculate.checked_distance('01:21:32', '00:06:27') # => 12.640826873385013
70
+
71
+ # The return will be in clocktime
72
+ calculate.clock_pace('01:21:32', 10) # => "00:08:09"
73
+ calculate.clock_velocity('01:00:00', 10317) # => "00:00:02"
74
+ calculate.clock_time('00:05:31', 12.6) # => "01:09:30"
75
+ ```
76
+
77
+ Note: Using the `clock` methods may be less precise than using other methods due to conversions.
78
+
79
+ You can also use BigDecimal for more precise calculations. For example:
80
+
81
+ ```ruby
82
+ require 'bigdecimal'
83
+ calculate.checked_velocity('10:00:00', 10317).to_d # => #<BigDecimal:7f9f1b8b1d08,'0.2865833333 333333E1',27(36)>
84
+ ```
85
+
86
+ To learn more about BigDecimal, check the [documentation](https://ruby-doc.org/stdlib-2.7.1/libdoc/bigdecimal/rdoc/BigDecimal.html).
87
+
88
+ ### Convert Distances and Velocities
89
+
90
+ Use the `convert` method to convert a distance or velocity. The first parameter is the value to be converted, and the second parameter is the unit to which the value will be converted. The unit must be a string with the abbreviation of the unit. The gem supports 26 different units, including kilometers, miles, meters, knots, and feet.
91
+
92
+ Here are some examples:
93
+
94
+ ```ruby
95
+ converter.convert(10, :km_to_meters) # => 1000
96
+ converter.convert(10, :mi_to_km) # => 16.0934
97
+ converter.convert(1, :nautical_mi_to_km) # => 1.852
98
+ converter.convert(1, :km_h_to_m_s) # => 0.277778
99
+ converter.convert(1, :m_s_to_mi_h) # => 2.23694
100
+ ```
101
+
102
+ | Conversion Unit | Description |
103
+ |----------------------|-----------------------------|
104
+ | :km_to_mi | Kilometers to Miles |
105
+ | :mi_to_km | Miles to Kilometers |
106
+ | :nautical_mi_to_km | Nautical Miles to Kilometers |
107
+ | :km_to_nautical_mi | Kilometers to Nautical Miles |
108
+ | :meters_to_km | Meters to Kilometers |
109
+ | :km_to_meters | Kilometers to Meters |
110
+ | :meters_to_mi | Meters to Miles |
111
+ | :mi_to_meters | Miles to Meters |
112
+ | :m_s_to_km_h | Meters per Second to Kilometers per Hour |
113
+ | :km_h_to_m_s | Kilometers per Hour to Meters per Second |
114
+ | :m_s_to_mi_h | Meters per Second to Miles per Hour |
115
+ | :mi_h_to_m_s | Miles per Hour to Meters per Second |
116
+ | :m_s_to_feet_s | Meters per Second to Feet per Second |
117
+ | :feet_s_to_m_s | Feet per Second to Meters per Second |
118
+ | :km_h_to_mi_h | Kilometers per Hour to Miles per Hour |
119
+ | :mi_h_to_km_h | Miles per Hour to Kilometers per Hour |
120
+
121
+ You can list all the available units [here](/lib/calcpace/converter.rb), or using `list` methods:
122
+
123
+ ```ruby
124
+ converter.list_all
125
+ converter.list_distance
126
+ converter.list_speed
127
+ ```
128
+
129
+ ### Other Useful Methods
130
+
131
+ Calcpace also provides other useful methods:
132
+
133
+ ```ruby
134
+ converter = Calcpace.new
135
+ converter.convert_to_seconds('01:00:00') # => 3600
136
+ converter.convert_to_clocktime(3600) # => '01:00:00'
137
+ converter.converto_to_clocktime(100000) # => '1 03:46:40'
138
+ converter.check_time('01:00:00') # => nil
139
+ ```
140
+
141
+ ### Errors
142
+
143
+ The gem now raises specific custom error classes for invalid inputs, allowing for more precise error handling. These errors inherit from `Calcpace::Error`.
144
+
145
+ - `Calcpace::NonPositiveInputError`: Raised when a numeric input is not positive.
146
+ - `Calcpace::InvalidTimeFormatError`: Raised when a time string is not in the expected `HH:MM:SS` or `MM:SS` format.
147
+
148
+ For example:
149
+
150
+ ```ruby
151
+ begin
152
+ calculate.pace(945, -1)
153
+ rescue Calcpace::NonPositiveInputError => e
154
+ puts e.message # => "Input must be a positive number"
155
+ end
156
+
157
+ begin
158
+ calculate.checked_time('string', 10)
159
+ rescue Calcpace::InvalidTimeFormatError => e
160
+ puts e.message # => "It must be a valid time in the XX:XX:XX or XX:XX format"
161
+ end
162
+ ```
163
+
164
+ ### Testing
165
+
166
+ To run the tests, clone the repository and run:
167
+
168
+ ```bash
169
+ bundle exec rake
170
+ ```
171
+
172
+ ### Supported Ruby Versions
173
+
174
+ The tests are run using Ruby versions from 2.7.8 to 3.4.2, as specified in the `.github/workflows/test.yml` file.
175
+
176
+ ## Contributing
177
+
178
+ We welcome contributions to Calcpace! To contribute, clone this repository and submit a pull request. Please ensure that your code adheres to our style and includes tests where appropriate.
179
+
180
+ ## License
181
+
182
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/test_task'
4
+
5
+ Minitest::TestTask.create(:test) do |t|
6
+ t.libs << 'test'
7
+ t.libs << 'lib'
8
+ t.warning = false
9
+ end
10
+
11
+ task default: :test
@@ -1,68 +1,68 @@
1
- # frozen_string_literal: true
2
-
3
- # Module to calculate time, distance, pace and velocity
4
- module Calculator
5
- def velocity(time, distance)
6
- validate_positive(time, distance)
7
- distance.to_f / time
8
- end
9
-
10
- def checked_velocity(time, distance)
11
- seconds = convert_to_seconds(validate_time(time))
12
- velocity(seconds, distance)
13
- end
14
-
15
- def clock_velocity(time, distance)
16
- convert_to_clocktime(checked_velocity(time, distance))
17
- end
18
-
19
- def pace(time, distance)
20
- validate_positive(time, distance)
21
- time.to_f / distance
22
- end
23
-
24
- def checked_pace(time, distance)
25
- seconds = convert_to_seconds(validate_time(time))
26
- pace(seconds, distance)
27
- end
28
-
29
- def clock_pace(time, distance)
30
- convert_to_clocktime(checked_pace(time, distance))
31
- end
32
-
33
- def time(velocity, distance)
34
- validate_positive(velocity, distance)
35
- velocity * distance
36
- end
37
-
38
- def checked_time(velocity, distance)
39
- velocity_seconds = convert_to_seconds(validate_time(velocity))
40
- time(velocity_seconds, distance)
41
- end
42
-
43
- def clock_time(velocity, distance)
44
- convert_to_clocktime(checked_time(velocity, distance))
45
- end
46
-
47
- def distance(time, velocity)
48
- validate_positive(time, velocity)
49
- time.to_f / velocity
50
- end
51
-
52
- def checked_distance(time, velocity)
53
- time_seconds = convert_to_seconds(validate_time(time))
54
- velocity_seconds = convert_to_seconds(validate_time(velocity))
55
- distance(time_seconds, velocity_seconds)
56
- end
57
-
58
- private
59
-
60
- def validate_positive(*values)
61
- values.each { |value| check_positive(value) }
62
- end
63
-
64
- def validate_time(time)
65
- check_time(time)
66
- time
67
- end
68
- end
1
+ # frozen_string_literal: true
2
+
3
+ # Module to calculate time, distance, pace and velocity
4
+ module Calculator
5
+ def velocity(time, distance)
6
+ validate_positive(time, distance)
7
+ distance.to_f / time
8
+ end
9
+
10
+ def checked_velocity(time, distance)
11
+ seconds = convert_to_seconds(validate_time(time))
12
+ velocity(seconds, distance)
13
+ end
14
+
15
+ def clock_velocity(time, distance)
16
+ convert_to_clocktime(checked_velocity(time, distance))
17
+ end
18
+
19
+ def pace(time, distance)
20
+ validate_positive(time, distance)
21
+ time.to_f / distance
22
+ end
23
+
24
+ def checked_pace(time, distance)
25
+ seconds = convert_to_seconds(validate_time(time))
26
+ pace(seconds, distance)
27
+ end
28
+
29
+ def clock_pace(time, distance)
30
+ convert_to_clocktime(checked_pace(time, distance))
31
+ end
32
+
33
+ def time(velocity, distance)
34
+ validate_positive(velocity, distance)
35
+ velocity * distance
36
+ end
37
+
38
+ def checked_time(velocity, distance)
39
+ velocity_seconds = convert_to_seconds(validate_time(velocity))
40
+ time(velocity_seconds, distance)
41
+ end
42
+
43
+ def clock_time(velocity, distance)
44
+ convert_to_clocktime(checked_time(velocity, distance))
45
+ end
46
+
47
+ def distance(time, velocity)
48
+ validate_positive(time, velocity)
49
+ time.to_f / velocity
50
+ end
51
+
52
+ def checked_distance(time, velocity)
53
+ time_seconds = convert_to_seconds(validate_time(time))
54
+ velocity_seconds = convert_to_seconds(validate_time(velocity))
55
+ distance(time_seconds, velocity_seconds)
56
+ end
57
+
58
+ private
59
+
60
+ def validate_positive(*values)
61
+ values.each { |value| check_positive(value) }
62
+ end
63
+
64
+ def validate_time(time)
65
+ check_time(time)
66
+ time
67
+ end
68
+ end
@@ -1,15 +1,20 @@
1
- # frozen_string_literal: true
2
-
3
- # Module to check if the input is valid or of the correct type
4
- module Checker
5
- def check_positive(number)
6
- raise ArgumentError, 'It must be a positive number' unless number.is_a?(Numeric) && number.positive?
7
- end
8
-
9
- def check_time(time_string)
10
- return if time_string =~ /\A\d{1,2}:\d{2}:\d{2}\z/
11
-
12
- raise ArgumentError,
13
- 'It must be a valid time in the format XX:XX:XX'
14
- end
15
- end
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'errors'
4
+
5
+ # Module to check if the input is valid or of the correct type
6
+ module Checker
7
+ def check_positive(number)
8
+ return if number.is_a?(Numeric) && number.positive?
9
+
10
+ raise Calcpace::NonPositiveInputError,
11
+ 'It must be a positive number'
12
+ end
13
+
14
+ def check_time(time_string)
15
+ return if time_string =~ /\A\d{1,2}:\d{2}:\d{2}\z/ ||
16
+ time_string =~ /\A\d{1,2}:\d{2}\z/
17
+
18
+ raise Calcpace::InvalidTimeFormatError, 'It must be a valid time in the XX:XX:XX or XX:XX format'
19
+ end
20
+ end
@@ -1,87 +1,93 @@
1
- # frozen_string_literal: true
2
-
3
- # Module to convert units
4
- module Converter
5
- module Distance
6
- KM_TO_MI = 0.621371
7
- MI_TO_KM = 1.60934
8
- NAUTICAL_MI_TO_KM = 1.852
9
- KM_TO_NAUTICAL_MI = 0.539957
10
- METERS_TO_KM = 0.001
11
- KM_TO_METERS = 1000
12
- METERS_TO_MI = 0.000621371
13
- MI_TO_METERS = 1609.34
14
- METERS_TO_FEET = 3.28084
15
- FEET_TO_METERS = 0.3048
16
- METERS_TO_YARDS = 1.09361
17
- YARDS_TO_METERS = 0.9144
18
- METERS_TO_INCHES = 39.3701
19
- INCHES_TO_METERS = 0.0254
20
- KM_TO_YARDS = 1093.61
21
- YARDS_TO_KM = 0.0009144
22
- KM_TO_FEET = 3280.84
23
- FEET_TO_KM = 0.0003048
24
- KM_TO_INCHES = 39_370.1
25
- INCHES_TO_KM = 0.0000254
26
- MI_TO_YARDS = 1760
27
- YARDS_TO_MI = 0.000568182
28
- MI_TO_FEET = 5280
29
- FEET_TO_MI = 0.000189394
30
- MI_TO_INCHES = 63_360
31
- INCHES_TO_MI = 0.0000157828
32
- end
33
-
34
- module Speed
35
- M_S_TO_KM_H = 3.6
36
- KM_H_TO_M_S = 0.277778
37
- M_S_TO_MI_H = 2.23694
38
- MI_H_TO_M_S = 0.44704
39
- M_S_TO_NAUTICAL_MI_H = 1.94384
40
- NAUTICAL_MI_H_TO_M_S = 0.514444
41
- M_S_TO_FEET_S = 3.28084
42
- FEET_S_TO_M_S = 0.3048
43
- M_S_TO_KNOTS = 1.94384
44
- KNOTS_TO_M_S = 0.514444
45
- KM_H_TO_MI_H = 0.621371
46
- MI_H_TO_KM_H = 1.60934
47
- KM_H_TO_NAUTICAL_MI_H = 0.539957
48
- NAUTICAL_MI_H_TO_KM_H = 1.852
49
- MI_H_TO_NAUTICAL_MI_H = 0.868976
50
- NAUTICAL_MI_H_TO_MI_H = 1.15078
51
- end
52
-
53
- def convert(value, unit)
54
- check_positive(value)
55
- unit_constant = constant(unit)
56
- value * unit_constant
57
- end
58
-
59
- def convert_to_seconds(time)
60
- hour, minute, seconds = time.split(':').map(&:to_i)
61
- (hour * 3600) + (minute * 60) + seconds
62
- end
63
-
64
- def convert_to_clocktime(seconds)
65
- days = seconds / 86_400
66
- format = days.to_i.positive? ? "#{days} %H:%M:%S" : '%H:%M:%S'
67
- Time.at(seconds).utc.strftime(format)
68
- end
69
-
70
- def constant(symbol)
71
- Distance.const_get(symbol.to_s.upcase)
72
- rescue NameError
73
- Speed.const_get(symbol.to_s.upcase)
74
- end
75
-
76
- def list_all
77
- (Distance.constants + Speed.constants).map { |c| c.downcase.to_sym }
78
- end
79
-
80
- def list_speed
81
- Speed.constants.map { |c| c.downcase.to_sym }
82
- end
83
-
84
- def list_distance
85
- Distance.constants.map { |c| c.downcase.to_sym }
86
- end
87
- end
1
+ # frozen_string_literal: true
2
+
3
+ # Module to convert units
4
+ module Converter
5
+ module Distance
6
+ KM_TO_MI = 0.621371
7
+ MI_TO_KM = 1.60934
8
+ NAUTICAL_MI_TO_KM = 1.852
9
+ KM_TO_NAUTICAL_MI = 0.539957
10
+ METERS_TO_KM = 0.001
11
+ KM_TO_METERS = 1000
12
+ METERS_TO_MI = 0.000621371
13
+ MI_TO_METERS = 1609.34
14
+ METERS_TO_FEET = 3.28084
15
+ FEET_TO_METERS = 0.3048
16
+ METERS_TO_YARDS = 1.09361
17
+ YARDS_TO_METERS = 0.9144
18
+ METERS_TO_INCHES = 39.3701
19
+ INCHES_TO_METERS = 0.0254
20
+ KM_TO_YARDS = 1093.61
21
+ YARDS_TO_KM = 0.0009144
22
+ KM_TO_FEET = 3280.84
23
+ FEET_TO_KM = 0.0003048
24
+ KM_TO_INCHES = 39_370.1
25
+ INCHES_TO_KM = 0.0000254
26
+ MI_TO_YARDS = 1760
27
+ YARDS_TO_MI = 0.000568182
28
+ MI_TO_FEET = 5280
29
+ FEET_TO_MI = 0.000189394
30
+ MI_TO_INCHES = 63_360
31
+ INCHES_TO_MI = 0.0000157828
32
+ end
33
+
34
+ module Speed
35
+ M_S_TO_KM_H = 3.6
36
+ KM_H_TO_M_S = 0.277778
37
+ M_S_TO_MI_H = 2.23694
38
+ MI_H_TO_M_S = 0.44704
39
+ M_S_TO_NAUTICAL_MI_H = 1.94384
40
+ NAUTICAL_MI_H_TO_M_S = 0.514444
41
+ M_S_TO_FEET_S = 3.28084
42
+ FEET_S_TO_M_S = 0.3048
43
+ M_S_TO_KNOTS = 1.94384
44
+ KNOTS_TO_M_S = 0.514444
45
+ KM_H_TO_MI_H = 0.621371
46
+ MI_H_TO_KM_H = 1.60934
47
+ KM_H_TO_NAUTICAL_MI_H = 0.539957
48
+ NAUTICAL_MI_H_TO_KM_H = 1.852
49
+ MI_H_TO_NAUTICAL_MI_H = 0.868976
50
+ NAUTICAL_MI_H_TO_MI_H = 1.15078
51
+ end
52
+
53
+ def convert(value, unit)
54
+ check_positive(value)
55
+ unit_constant = constant(unit)
56
+ value * unit_constant
57
+ end
58
+
59
+ def convert_to_seconds(time)
60
+ parts = time.split(':').map(&:to_i)
61
+ if parts.length == 2
62
+ minute, seconds = parts
63
+ (minute * 60) + seconds
64
+ else
65
+ hour, minute, seconds = parts
66
+ (hour * 3600) + (minute * 60) + seconds
67
+ end
68
+ end
69
+
70
+ def convert_to_clocktime(seconds)
71
+ days = seconds / 86_400
72
+ format = days.to_i.positive? ? "#{days} %H:%M:%S" : '%H:%M:%S'
73
+ Time.at(seconds).utc.strftime(format)
74
+ end
75
+
76
+ def constant(symbol)
77
+ Distance.const_get(symbol.to_s.upcase)
78
+ rescue NameError
79
+ Speed.const_get(symbol.to_s.upcase)
80
+ end
81
+
82
+ def list_all
83
+ (Distance.constants + Speed.constants).map { |c| c.downcase.to_sym }
84
+ end
85
+
86
+ def list_speed
87
+ Speed.constants.map { |c| c.downcase.to_sym }
88
+ end
89
+
90
+ def list_distance
91
+ Distance.constants.map { |c| c.downcase.to_sym }
92
+ end
93
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Calcpace
4
+ class Error < StandardError; end
5
+
6
+ class InvalidTimeFormatError < Error; end
7
+
8
+ class NonPositiveInputError < Error; end
9
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Calcpace
4
+ VERSION = '1.5.4'
5
+ end
data/lib/calcpace.rb CHANGED
@@ -1,14 +1,15 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'calcpace/calculator'
4
- require_relative 'calcpace/checker'
5
- require_relative 'calcpace/converter'
6
-
7
- # Main class to calculate velocity, pace, time, distance and velocity
8
- class Calcpace
9
- include Calculator
10
- include Checker
11
- include Converter
12
-
13
- def initialize; end
14
- end
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'calcpace/calculator'
4
+ require_relative 'calcpace/checker'
5
+ require_relative 'calcpace/converter'
6
+ require_relative 'calcpace/errors'
7
+
8
+ # Main class to calculate velocity, pace, time, distance and velocity
9
+ class Calcpace
10
+ include Calculator
11
+ include Checker
12
+ include Converter
13
+
14
+ def initialize; end
15
+ end
metadata CHANGED
@@ -1,105 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calcpace
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 1.5.4
5
5
  platform: ruby
6
6
  authors:
7
- - Joao Gilberto Saraiva
8
- bindir: bin
7
+ - João Gilberto Saraiva
8
+ bindir: exe
9
9
  cert_chain: []
10
- date: 2025-03-22 00:00:00.000000000 Z
11
- dependencies:
12
- - !ruby/object:Gem::Dependency
13
- name: minitest
14
- requirement: !ruby/object:Gem::Requirement
15
- requirements:
16
- - - "~>"
17
- - !ruby/object:Gem::Version
18
- version: '5.25'
19
- type: :development
20
- prerelease: false
21
- version_requirements: !ruby/object:Gem::Requirement
22
- requirements:
23
- - - "~>"
24
- - !ruby/object:Gem::Version
25
- version: '5.25'
26
- - !ruby/object:Gem::Dependency
27
- name: rake
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - "~>"
31
- - !ruby/object:Gem::Version
32
- version: '13.2'
33
- type: :development
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: '13.2'
40
- - !ruby/object:Gem::Dependency
41
- name: rake-compiler
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: '1.0'
47
- type: :development
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: '1.0'
54
- - !ruby/object:Gem::Dependency
55
- name: rdoc
56
- requirement: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '6.2'
61
- type: :development
62
- prerelease: false
63
- version_requirements: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '6.2'
68
- - !ruby/object:Gem::Dependency
69
- name: rubocop
70
- requirement: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '1.69'
75
- type: :development
76
- prerelease: false
77
- version_requirements: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '1.69'
82
- description: It is designed for calculations related to distance, speed and time.
83
- The gem also supports conversion to 42 different units of distance and velocity,
84
- including metric, nautical and imperial units.
85
- email: joaogilberto@tuta.io
10
+ date: 2025-06-28 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Calcpace provides methods to calculate and convert values related to
13
+ pace, distance, time, and speed. It supports various time formats and unit conversions.
14
+ email:
15
+ - joaogilberto@tuta.io
86
16
  executables: []
87
17
  extensions: []
88
18
  extra_rdoc_files: []
89
19
  files:
20
+ - ".github/workflows/tests.yml"
21
+ - ".gitignore"
22
+ - ".ruby-version"
23
+ - Gemfile
24
+ - Gemfile.lock
25
+ - README.md
26
+ - Rakefile.rb
90
27
  - lib/calcpace.rb
91
28
  - lib/calcpace/calculator.rb
92
29
  - lib/calcpace/checker.rb
93
30
  - lib/calcpace/converter.rb
94
- - test/calcpace/test_calculator.rb
95
- - test/calcpace/test_checker.rb
96
- - test/calcpace/test_converter.rb
97
- homepage: https://github.com/0jonjo/calcpace
31
+ - lib/calcpace/errors.rb
32
+ - lib/calcpace/version.rb
33
+ homepage: https://github.com/jonjo/calcpace
98
34
  licenses:
99
35
  - MIT
100
36
  metadata:
101
- source_code_uri: https://github.com/0jonjo/calcpace
102
- post_install_message: It's time to calculate! Thank you for installing Calcpace.
37
+ source_code_uri: https://github.com/jonjo/calcpace
38
+ changelog_uri: https://github.com/jonjo/calcpace/blob/main/CHANGELOG.md
103
39
  rdoc_options: []
104
40
  require_paths:
105
41
  - lib
@@ -114,11 +50,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
50
  - !ruby/object:Gem::Version
115
51
  version: '0'
116
52
  requirements: []
117
- rubygems_version: 3.6.6
53
+ rubygems_version: 3.6.2
118
54
  specification_version: 4
119
- summary: 'Calcpace: calculate total, distance, speed, and convert distances and velocity
120
- in an easy way.'
121
- test_files:
122
- - test/calcpace/test_calculator.rb
123
- - test/calcpace/test_checker.rb
124
- - test/calcpace/test_converter.rb
55
+ summary: A Ruby gem for pace, distance, and time calculations.
56
+ test_files: []
@@ -1,117 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'minitest/autorun'
4
- require_relative '../../lib/calcpace'
5
-
6
- class TestCalculator < Minitest::Test
7
- def setup
8
- @checker = Calcpace.new
9
- end
10
-
11
- def test_velocity
12
- assert_equal 3.333, @checker.velocity(3600, 12_000).round(3)
13
- assert_equal 12.3, @checker.velocity(5841, 71_844.3)
14
- assert_equal 3.6, @checker.velocity(10_000, 36_000.0)
15
- assert_raises(ArgumentError) { @checker.velocity(0, 10) }
16
- assert_raises(ArgumentError) { @checker.velocity(10, -1) }
17
- end
18
-
19
- def test_checked_velocity
20
- assert_raises(ArgumentError) { @checker.checked_velocity('', 10) }
21
- assert_raises(ArgumentError) { @checker.checked_velocity('invalid', 10) }
22
- assert_raises(ArgumentError) { @checker.checked_velocity('00:00:00', 0) }
23
- assert_raises(ArgumentError) { @checker.checked_velocity('00:00:00', -1) }
24
- assert_equal 2.778, @checker.checked_velocity('01:00:00', 10_000).round(3)
25
- assert_equal 10, @checker.checked_velocity('00:00:01', 10)
26
- assert_equal 12.3, @checker.checked_velocity('01:37:21', 71_844.3)
27
- end
28
-
29
- def test_clock_velocity
30
- assert_raises(ArgumentError) { @checker.clock_velocity('', 10) }
31
- assert_raises(ArgumentError) { @checker.clock_velocity('invalid', 10) }
32
- assert_raises(ArgumentError) { @checker.clock_velocity('00:00:00', 0) }
33
- assert_raises(ArgumentError) { @checker.clock_velocity('00:00:00', -1) }
34
- assert_equal '00:00:02', @checker.clock_velocity('01:00:00', 10_000)
35
- assert_equal '00:00:12', @checker.clock_velocity('01:37:21', 71_844.3)
36
- end
37
-
38
- def test_pace
39
- assert_equal 300, @checker.pace(3600, 12)
40
- assert_equal 122.81076923076924, @checker.pace(71_844.3, 585.0)
41
- assert_raises(ArgumentError) { @checker.pace(0, 10) }
42
- assert_raises(ArgumentError) { @checker.pace(10, -1) }
43
- end
44
-
45
- def test_checked_pace
46
- assert_raises(ArgumentError) { @checker.checked_pace('', 10) }
47
- assert_raises(ArgumentError) { @checker.checked_pace('invalid', 10) }
48
- assert_raises(ArgumentError) { @checker.checked_pace('00:00:00', 0) }
49
- assert_raises(ArgumentError) { @checker.checked_pace('00:00:00', -1) }
50
- assert_equal 360, @checker.checked_pace('01:00:00', 10)
51
- assert_equal 474.8780487804878, @checker.checked_pace('01:37:21', 12.3)
52
- end
53
-
54
- def test_clock_pace
55
- assert_raises(ArgumentError) { @checker.clock_pace('', 10) }
56
- assert_raises(ArgumentError) { @checker.clock_pace('invalid', 10) }
57
- assert_raises(ArgumentError) { @checker.clock_pace('00:00:00', 0) }
58
- assert_raises(ArgumentError) { @checker.clock_pace('00:00:00', -1) }
59
- assert_equal '00:06:00', @checker.clock_pace('01:00:00', 10)
60
- assert_equal '00:07:54', @checker.clock_pace('01:37:21', 12.3)
61
- end
62
-
63
- def test_time
64
- assert_equal 43_200, @checker.time(3600, 12)
65
- assert_equal 5841.0, @checker.time(12.3, 474.8780487804878)
66
- assert_raises(ArgumentError) { @checker.time(0, 10) }
67
- assert_raises(ArgumentError) { @checker.time(10, -1) }
68
- end
69
-
70
- def test_checked_time
71
- assert_raises(ArgumentError) { @checker.checked_time('', 10) }
72
- assert_raises(ArgumentError) { @checker.checked_time('invalid', 10) }
73
- assert_raises(ArgumentError) { @checker.checked_time('00:00:00', 0) }
74
- assert_raises(ArgumentError) { @checker.checked_time('00:00:00', -1) }
75
- assert_equal 3600, @checker.checked_time('00:05:00', 12)
76
- assert_equal 71_844.3, @checker.checked_time('01:37:21', 12.3)
77
- end
78
-
79
- def test_clock_time
80
- assert_raises(ArgumentError) { @checker.clock_time('', 10) }
81
- assert_raises(ArgumentError) { @checker.clock_time('invalid', 10) }
82
- assert_raises(ArgumentError) { @checker.clock_time('00:00:00', 0) }
83
- assert_raises(ArgumentError) { @checker.clock_time('00:00:00', -1) }
84
- assert_equal '01:00:00', @checker.clock_time('00:05:00', 12)
85
- end
86
-
87
- def test_distance
88
- assert_equal 30, @checker.distance(3600, 120)
89
- assert_equal 12.3, @checker.distance(5841.0, 474.8780487804878)
90
- assert_raises(ArgumentError) { @checker.distance(0, 10) }
91
- assert_raises(ArgumentError) { @checker.distance(10, -1) }
92
- end
93
-
94
- def test_checked_distance
95
- assert_raises(ArgumentError) { @checker.checked_distance('', '00:05:00') }
96
- assert_raises(ArgumentError) { @checker.checked_distance('01:00:00', '') }
97
- assert_equal 18.0, @checker.checked_distance('01:30:00', '00:05:00')
98
- assert_equal 15.493, @checker.checked_distance('01:37:21', '00:06:17').round(3)
99
- end
100
-
101
- def test_readme_examples_one
102
- assert_equal 3.386206896551724, @checker.velocity(3625, 12_275)
103
- assert_equal 305.4166666666667, @checker.pace(3665, 12)
104
- assert_equal 2520.0, @checker.time(210, 12)
105
- assert_equal 80.5, @checker.distance(9660, 120)
106
- end
107
-
108
- def test_readme_examples_two
109
- assert_equal 2.8658333333333332, @checker.checked_velocity('01:00:00', 10_317)
110
- assert_equal '00:00:02', @checker.clock_velocity('01:00:00', 10_317)
111
- assert_equal 489.2, @checker.checked_pace('01:21:32', 10)
112
- assert_equal '00:08:09', @checker.clock_pace('01:21:32', 10)
113
- assert_equal 4170.599999999999, @checker.checked_time('00:05:31', 12.6)
114
- assert_equal '01:09:30', @checker.clock_time('00:05:31', 12.6)
115
- assert_equal 12.640826873385013, @checker.checked_distance('01:21:32', '00:06:27')
116
- end
117
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'minitest/autorun'
4
- require_relative '../../lib/calcpace'
5
-
6
- class TestChecker < Minitest::Test
7
- def setup
8
- @checker = Calcpace.new
9
- end
10
-
11
- def test_check_positive
12
- assert_raises(ArgumentError) { @checker.check_positive(-1) }
13
- assert_raises(ArgumentError) { @checker.check_positive(0) }
14
- assert_nil @checker.check_positive(1)
15
- end
16
-
17
- def test_check_time
18
- assert_raises(ArgumentError) { @checker.check_time('') }
19
- assert_nil @checker.check_time('00:00:00')
20
- end
21
- end
@@ -1,79 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'minitest/autorun'
4
- require_relative '../../lib/calcpace'
5
-
6
- class TestConverter < Minitest::Test
7
- def setup
8
- @checker = Calcpace.new
9
- end
10
-
11
- def test_convert_to_seconds
12
- assert_equal 4262, @checker.convert_to_seconds('01:11:02')
13
- end
14
-
15
- def test_convert_to_clocktime
16
- assert_equal '01:11:02', @checker.convert_to_clocktime(4262)
17
- end
18
-
19
- def test_convert_to_clocktime_more_than_24_hours
20
- assert_equal '1 03:46:40', @checker.convert_to_clocktime(100_000)
21
- end
22
-
23
- def test_convert_distance_one
24
- assert_equal 0.621371, @checker.convert(1, :km_to_mi)
25
- assert_equal 1.60934, @checker.convert(1, :mi_to_km)
26
- assert_equal 1.852, @checker.convert(1, :nautical_mi_to_km)
27
- assert_equal 0.539957, @checker.convert(1, :km_to_nautical_mi)
28
- assert_equal 0.001, @checker.convert(1, :meters_to_km)
29
- assert_equal 1000, @checker.convert(1, :km_to_meters)
30
- end
31
-
32
- def test_convert_distance_two
33
- assert_equal 0.000621371, @checker.convert(1, :meters_to_mi)
34
- assert_equal 1609.34, @checker.convert(1, :mi_to_meters)
35
- assert_equal 3.28084, @checker.convert(1, :meters_to_feet)
36
- assert_equal 0.3048, @checker.convert(1, :feet_to_meters)
37
- assert_equal 1.09361, @checker.convert(1, :meters_to_yards)
38
- end
39
-
40
- def test_convert_distance_three
41
- assert_equal 0.9144, @checker.convert(1, :yards_to_meters)
42
- assert_equal 39.3701, @checker.convert(1, :meters_to_inches)
43
- assert_equal 0.0254, @checker.convert(1, :inches_to_meters)
44
- end
45
-
46
- def test_convert_velocity_one
47
- assert_equal 3.60, @checker.convert(1, :m_s_to_km_h)
48
- assert_equal 0.277778, @checker.convert(1, :km_h_to_m_s)
49
- assert_equal 2.23694, @checker.convert(1, :m_s_to_mi_h)
50
- assert_equal 0.44704, @checker.convert(1, :mi_h_to_m_s)
51
- assert_equal 1.94384, @checker.convert(1, :m_s_to_nautical_mi_h)
52
- end
53
-
54
- def test_convert_velocity_two
55
- assert_equal 0.514444, @checker.convert(1, :nautical_mi_h_to_m_s)
56
- assert_equal 0.621371, @checker.convert(1, :km_h_to_mi_h)
57
- assert_equal 1.60934, @checker.convert(1, :mi_h_to_km_h)
58
- assert_equal 1.94384, @checker.convert(1, :m_s_to_knots)
59
- assert_equal 0.514444, @checker.convert(1, :knots_to_m_s)
60
- end
61
-
62
- def test_constant
63
- assert_equal 0.621371, @checker.constant(:km_to_mi)
64
- assert_equal 1.60934, @checker.constant(:mi_to_km)
65
- assert_equal 1.852, @checker.constant(:nautical_mi_to_km)
66
- end
67
-
68
- def test_list_all
69
- assert_equal 42, @checker.list_all.size
70
- end
71
-
72
- def test_list_speed
73
- assert_equal 16, @checker.list_speed.size
74
- end
75
-
76
- def test_list_distance_constants
77
- assert_equal 26, @checker.list_distance.size
78
- end
79
- end