diff --git a/README.md b/README.md index fecefc5..f7fe8de 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Calcpace [![Gem Version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=rb&r=r&ts=1683906897&type=6e&v=1.1.1&x2=0)](https://badge.fury.io/rb/calcpace) +# Calcpace [![Gem Version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=rb&r=r&ts=1683906897&type=6e&v=1.2.0&x2=0)](https://badge.fury.io/rb/calcpace) Calcpace is a Ruby gem that helps with calculations related to running/cycling activities or general purposes involving distance and time. It can calculate pace, total time, and distance, accepting time in seconds or HH:MM:SS format. It also converts distances between miles and kilometers. The results are provided in a readable format, with times in HH:MM:SS or seconds and distances in X.X format. To prevent precision problems, the gem supports BigDecimal to handle the calculations, if you need, and always returns data using the same distance unit (kilometers or miles) that was used as input. @@ -7,7 +7,7 @@ Calcpace is a Ruby gem that helps with calculations related to running/cycling a ### Add to your Gemfile ```ruby -gem 'calcpace', '~> 1.1.1' +gem 'calcpace', '~> 1.2.0' ``` Then run bundle install. @@ -20,7 +20,15 @@ gem install calcpace ### Usage - Before calculate or convert any value, you must create a new instance of Calcpace. When you call a method, it checks the digits of the time or distance to ensure that they are in the correct format. The gem always returns data using the same distance unit (kilometers or miles) that was used as input. + Before calculate or convert any value, you must create a new instance of Calcpace. When you call a method, it checks the digits of the time or distance to ensure that they are in the correct format. The gem always returns data using the same distance unit (kilometers or miles) that was used as input. If you want to use BigDecimal to handle the calculations, you can pass true as a parameter when creating a new instance of Calcpace. Like this: + +```ruby +require 'calcpace' + +calculate = Calcpace.new +calculate_bigdecimal = Calcpace.new(true) +another_way_to_use_bigdecimal = Calcpace.new(bigdecimal: true) +``` ### Calculate Pace @@ -28,11 +36,13 @@ To calculate pace, provide the total time (in HH:MM:SS format) and distance (in ```ruby calculate = Calcpace.new -calculate.pace('01:00:00', 12) # => "00:05:00" calculate.pace('string', 12) # It must be a time (RuntimeError) +calculate.pace('01:00:00', 12) # => "00:05:00" calculate.pace_seconds('01:00:00', 12) # => 300 -calculate.pace_seconds('01:37:21', 12.3, true) # => 0.474878048780487804878048780487804878049e3 calculate.pace_seconds('01:37:21', 12.3) # => 474.8780487804878 +calculate_bigdecimal = Calcpace.new(true) +calculate_bigdecimal.pace_seconds('01:37:21', 12.3) # => 0.474878048780487804878048780487804878049e3 + ``` ### Calculate Total Time @@ -41,10 +51,11 @@ To calculate total time, provide the pace (in HH:MM:SS format) and distance (in ```ruby calculate = Calcpace.new -calculate.total_time('00:05:00', 12) # => "01:00:00" calculate.total_time('00:05:00', 'string') # It must be a XX:XX:XX time (RuntimeError) +calculate.total_time('00:05:00', 12) # => "01:00:00" calculate.total_time_seconds('01:37:21', 12.3) # => 71844.3 -calculate.total_time_seconds('01:37:21', 12.3, true) # => 0.718443902439024390243902439024390243902e5 +calculate_bigdecimal = Calcpace.new(true) +calculate_bigdecimal.total_time_seconds('01:37:21', 12.3) # => 0.718443902439024390243902439024390243902e5 ``` ### Calculate Distance @@ -53,21 +64,25 @@ To calculate distance, provide the running time (in HH:MM:SS format) and pace (i ```ruby calculate = Calcpace.new -calculate.distance('01:37:21', '00:06:17') # => 15.0 -calculate.distance('01:37:21', '00:06:17', true) # => 0.15493368700265251989389920424403183024e2 calculate.distance('01:37:21', 'string') # It must be a time (RuntimeError) +calculate.distance('01:37:21', '00:06:17') # => 15.0 +calculate_bigdecimal = Calcpace.new(true) +calculate_bigdecimal.distance('01:37:21', '00:06:17') # => 0.15493368700265251989389920424403183024e2 ``` ### Convert Distances -To convert distances, provide the distance and the unit of measurement (either 'km' for kilometers or 'mi' for miles). If want to change the default round of the result (2), you can pass a second parameter to the method. +To convert distances, use one of the two methods: `convert_to_km` or `convert_to_miles`. If want to change the round the result you can use the Ruby method `round` passing the number of decimal places you want. If you need to use BigDecimal to handle the calculations, you can pass true as parameter when creating a new instance of Calcpace. ```ruby -converter = Calcpace.new -converter.convert(10, 'km') # => 6.21 -converter.convert(10, 'km', 1) # => 6.2 -converter.convert_distance(10, 'mi') # => 16.09 -converter.convert(10, 'mi', 3) # => 16.093 + converter = Calcpace.new + converter.convert_to_miles('string') # => It must be a X.X positive number (RuntimeError) + converter.convert_to_km(10) # => 16.0934 + converter.convert_to_km(10).round(1) # => 16.1 + converter.convert_to_miles(10) # => 6.21371 + converter_bigdecimal = Calcpace.new(bigdecimal = true) + converter_bigdecimal.convert_to_miles(118.32) # => 0.7352061672e2 + converter_bigdecimal.convert_to_km(118.32) # => 0.1904171088e3 ``` ### Obtain the seconds of a time OR convert seconds to a time diff --git a/calcpace.gemspec b/calcpace.gemspec index 7ae4ff3..6625282 100644 --- a/calcpace.gemspec +++ b/calcpace.gemspec @@ -2,9 +2,9 @@ Gem::Specification.new do |s| s.name = 'calcpace' - s.version = '1.1.1' + s.version = '1.2.0' s.summary = 'Calcpace: calculate time, distance, pace, velocity and convert distances in an easy and precise way.' - s.description = 'Calcpace is a Ruby gem that helps with calculations related to running/cycling activities or general purposes involving distance and time. It can calculate pace, total time, and distance. It also converts distances between miles and kilometers and check formats of time and distance. The results are provided in a readable format, with times in HH:MM:SS or seconds and distances in X.X format. If you need, the gem supports BigDecimal to handle the calculations, ' + s.description = 'Calcpace is a Ruby gem that helps with calculations related to running/cycling activities or general purposes involving distance and time. It can calculate pace, total time, and distance. It also converts distances between miles and kilometers and check formats of time and distance. The results are provided in a readable format, with times in HH:MM:SS or seconds and distances in X.X format. If you need, the gem supports BigDecimal to handle the calculations with more precision.' s.authors = ['Joao Gilberto Saraiva'] s.email = 'joaogilberto@tuta.io' s.files = ['lib/calcpace.rb', 'lib/calcpace/calculator.rb', 'lib/calcpace/checker.rb', 'lib/calcpace/converter.rb'] diff --git a/lib/calcpace.rb b/lib/calcpace.rb index c7dfcda..d247100 100644 --- a/lib/calcpace.rb +++ b/lib/calcpace.rb @@ -9,5 +9,9 @@ class Calcpace include Checker include Converter - def initialize; end + attr_reader :bigdecimal + + def initialize(bigdecimal = false) + @bigdecimal = bigdecimal + end end diff --git a/lib/calcpace/calculator.rb b/lib/calcpace/calculator.rb index fa43346..d43518d 100644 --- a/lib/calcpace/calculator.rb +++ b/lib/calcpace/calculator.rb @@ -3,31 +3,31 @@ require 'bigdecimal' module Calculator - def pace(time, distance, bigdecimal = false) - pace_in_seconds = pace_seconds(time, distance, bigdecimal) + def pace(time, distance) + pace_in_seconds = pace_seconds(time, distance) convert_to_clocktime(pace_in_seconds) end - def pace_seconds(time, distance, bigdecimal = false) + def pace_seconds(time, distance) check_time(time) check_distance(distance) seconds = convert_to_seconds(time) bigdecimal ? seconds / BigDecimal(distance.to_s) : seconds / distance end - def total_time(pace, distance, bigdecimal = false) - total_time_in_seconds = total_time_seconds(pace, distance, bigdecimal) + def total_time(pace, distance) + total_time_in_seconds = total_time_seconds(pace, distance) convert_to_clocktime(total_time_in_seconds) end - def total_time_seconds(pace, distance, bigdecimal = false) + def total_time_seconds(pace, distance) check_time(pace) check_distance(distance) pace_seconds = convert_to_seconds(pace) - bigdecimal ? pace_seconds * BigDecimal(distance.to_s) : pace_seconds * distance + @bigdecimal ? pace_seconds * BigDecimal(distance.to_s) : pace_seconds * distance end - def distance(time, pace, bigdecimal = false) + def distance(time, pace) check_time(time) check_time(pace) if bigdecimal diff --git a/lib/calcpace/converter.rb b/lib/calcpace/converter.rb index 58e4ea9..9d836f1 100644 --- a/lib/calcpace/converter.rb +++ b/lib/calcpace/converter.rb @@ -3,8 +3,10 @@ require 'bigdecimal' module Converter - KM_TO_MI = BigDecimal('0.621371') - MI_TO_KM = BigDecimal('1.60934') + KM_TO_MI_BIGDECIMAL = BigDecimal('0.621371') + KM_TO_MI = 0.621371 + MI_TO_KM_BIGDECIMAL = BigDecimal('1.60934') + MI_TO_KM = 1.60934 def to_seconds(time) check_time(time) @@ -16,11 +18,18 @@ def to_clocktime(seconds) convert_to_clocktime(seconds) end - def convert(distance, unit, round_limit = 2) + def convert_to_miles(distance) + convert(distance, 'mi') + end + + def convert_to_km(distance) + convert(distance, 'km') + end + + def convert(distance, unit) check_distance(distance) - check_unit(unit) - check_integer(round_limit) - convert_the_distance(BigDecimal(distance.to_s), unit, round_limit) + bigdecimal ? distance_to_convert = BigDecimal(distance.to_s) : distance_to_convert = distance + convert_the_distance(distance_to_convert, unit) end def convert_to_seconds(time) @@ -33,12 +42,14 @@ def convert_to_clocktime(seconds) Time.at(seconds.to_i).utc.strftime(format) end - def convert_the_distance(distance, unit, round_limit = 2) + def convert_the_distance(distance, unit) case unit - when 'km' - (distance * KM_TO_MI).round(round_limit) when 'mi' - (distance * MI_TO_KM).round(round_limit) + bigdecimal ? km_to_mi = KM_TO_MI_BIGDECIMAL : km_to_mi = KM_TO_MI + (distance * km_to_mi) + when 'km' + bigdecimal ? mi_to_km = MI_TO_KM_BIGDECIMAL : mi_to_km = MI_TO_KM + (distance * mi_to_km) end end end diff --git a/test/calcpace/test_calculator.rb b/test/calcpace/test_calculator.rb index 69a514e..be0b049 100644 --- a/test/calcpace/test_calculator.rb +++ b/test/calcpace/test_calculator.rb @@ -7,6 +7,7 @@ class TestCalculator < Minitest::Test def setup @checker = Calcpace.new + @checker_bigdecimal = Calcpace.new(bigdecimal = true) end def test_pace @@ -18,8 +19,12 @@ def test_pace assert_equal '00:07:54', @checker.pace('01:37:21', 12.3) end + def test_pace_with_bigdecimal_precision + assert_equal '00:07:54', @checker_bigdecimal.pace('01:37:21', 12.3) + end + def test_pace_without_bigdecimal_precision - assert_equal '00:07:54', @checker.pace('01:37:21', 12.3, false) + assert_equal '00:07:54', @checker.pace('01:37:21', 12.3) end def test_pace_seconds @@ -27,11 +32,11 @@ def test_pace_seconds assert_raises(RuntimeError) { @checker.pace_seconds('invalid', 10) } assert_raises(RuntimeError) { @checker.pace_seconds('00:00:00', 0) } assert_raises(RuntimeError) { @checker.pace_seconds('00:00:00', -1) } - assert_equal BigDecimal('474.8780487804878'), @checker.pace_seconds('01:37:21', 12.3) + assert_equal 474.8780487804878, @checker.pace_seconds('01:37:21', 12.3) end def test_pace_seconds_with_bigdecimal_precision - assert_equal BigDecimal('0.474878048780487804878048780487804878049e3'), @checker.pace_seconds('01:37:21', 12.3, true) + assert_equal BigDecimal('0.474878048780487804878048780487804878049e3'), @checker_bigdecimal.pace_seconds('01:37:21', 12.3) end def test_total_time @@ -52,7 +57,7 @@ def test_total_time_seconds end def test_total_time_seconds_with_bigdecimal_precision - assert_equal BigDecimal('0.718443e5'), @checker.total_time_seconds('01:37:21', 12.3, true) + assert_equal BigDecimal('0.718443e5'), @checker_bigdecimal.total_time_seconds('01:37:21', 12.3) end def test_distance @@ -63,6 +68,6 @@ def test_distance end def test_distance_with_bigdecimal_precision - assert_equal BigDecimal('0.15493368700265251989389920424403183024e2'), @checker.distance('01:37:21', '00:06:17', true) + assert_equal BigDecimal('0.15493368700265251989389920424403183024e2'), @checker_bigdecimal.distance('01:37:21', '00:06:17') end end diff --git a/test/calcpace/test_converter.rb b/test/calcpace/test_converter.rb index 45d938a..21aee9f 100644 --- a/test/calcpace/test_converter.rb +++ b/test/calcpace/test_converter.rb @@ -6,6 +6,7 @@ class TestConverter < Minitest::Test def setup @checker = Calcpace.new + @checker_bigdecimal = Calcpace.new(bigdecimal = true) end def test_convert_to_seconds @@ -30,20 +31,28 @@ def test_to_clocktime end def test_convert_the_distance - assert_equal 6.21, @checker.convert_the_distance(10, 'km') - assert_equal 6.2, @checker.convert_the_distance(10, 'km', 1) - assert_equal 6.214, @checker.convert_the_distance(10, 'km', 3) - assert_equal 16.09, @checker.convert_the_distance(10, 'mi') + assert_equal 6.21, @checker.convert_the_distance(10, 'mi').round(2) + assert_equal 6.2, @checker.convert_the_distance(10, 'mi').round(1) + assert_equal 6.214, @checker.convert_the_distance(10, 'mi').round(3) + assert_equal 16.09, @checker.convert_the_distance(10, 'km').round(2) + end + + def test_convert_the_distance_with_bigdecimal_precision + assert_equal BigDecimal('6.21371'), @checker_bigdecimal.convert_the_distance(10, 'mi') end def test_convert - assert_equal 6.21, @checker.convert(10, 'km') - assert_equal 16.09, @checker.convert(10, 'mi') - assert_equal 6.2, @checker.convert(10, 'km', 1) - assert_raises(RuntimeError) { @checker.convert(10, 'invalid') } + assert_equal 6.21, @checker.convert(10, 'mi').round(2) + assert_equal 16.09, @checker.convert(10, 'km').round(2) + assert_equal 6.2, @checker.convert(10, 'mi').round(1) assert_raises(RuntimeError) { @checker.convert(-1, 'km') } - assert_raises(RuntimeError) { @checker.convert(10, 'km', -2) } - assert_raises(RuntimeError) { @checker.convert(10, 'km', 0) } - assert_raises(RuntimeError) { @checker.convert(10, 'km', 'invalid') } + end + + def test_convert_to_miles + assert_equal 6.21, @checker.convert_to_miles(10).round(2) + end + + def test_convert_to_km + assert_equal 16.09, @checker.convert_to_km(10).round(2) end end