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.
gem 'calcpace', '~> 1.7.0'Then run:
bundle installgem install calcpaceBefore performing any calculations or conversions, create a new instance of Calcpace:
require 'calcpace'
calculate = Calcpace.newCalcpace 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:
calculate.velocity(3625, 12275) # => 3.386206896551724
calculate.pace(3665, 12) # => 305.4166666666667
calculate.time(210, 12) # => 2520.0
calculate.distance(9660, 120) # => 80.5Tip: Use the round method to round a float. For example:
calculate.velocity(3625, 12275).round(3) # => 3.386Remember:
- Velocity is the distance divided by the time (e.g., m/s or km/h).
- Pace is the time divided by the distance (e.g., minutes/km or minutes/miles).
- Total time is the distance divided by the velocity.
- Distance is the velocity multiplied by the time.
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:
# The return will be in the unit you input/seconds or seconds/unit you input
calculate.checked_velocity('01:00:00', 12275) # => 3.4097222222222223
calculate.checked_pace('01:21:32', 10) # => 489.2
calculate.checked_time('00:05:31', 12.6) # => 4170.599999999999
calculate.checked_distance('01:21:32', '00:06:27') # => 12.640826873385013
# The return will be in clocktime
calculate.clock_pace('01:21:32', 10) # => "00:08:09"
calculate.clock_velocity('01:00:00', 10317) # => "00:00:02"
calculate.clock_time('00:05:31', 12.6) # => "01:09:30"Note: Using the clock methods may be less precise than using other methods due to conversions.
You can also use BigDecimal for more precise calculations. For example:
require 'bigdecimal'
calculate.checked_velocity('10:00:00', 10317).to_d # => #<BigDecimal:7f9f1b8b1d08,'0.2865833333 333333E1',27(36)>To learn more about BigDecimal, check the documentation.
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 can be a string (e.g. 'km to meters') or a symbol (e.g. :km_to_meters). The gem supports 42 different units, including kilometers, miles, meters, knots, and feet.
Here are some examples:
converter.convert(10, :km_to_meters) # => 1000
converter.convert(10, 'mi to km') # => 16.0934
converter.convert(1, :nautical_mi_to_km) # => 1.852
converter.convert(1, 'km h to m s') # => 0.277778
converter.convert(1, :m_s_to_mi_h) # => 2.23694| Conversion Unit | Description |
|---|---|
| :km_to_mi | Kilometers to Miles |
| :mi_to_km | Miles to Kilometers |
| :nautical_mi_to_km | Nautical Miles to Kilometers |
| :km_to_nautical_mi | Kilometers to Nautical Miles |
| :meters_to_km | Meters to Kilometers |
| :km_to_meters | Kilometers to Meters |
| :meters_to_mi | Meters to Miles |
| :mi_to_meters | Miles to Meters |
| :m_s_to_km_h | Meters per Second to Kilometers per Hour |
| :km_h_to_m_s | Kilometers per Hour to Meters per Second |
| :m_s_to_mi_h | Meters per Second to Miles per Hour |
| :mi_h_to_m_s | Miles per Hour to Meters per Second |
| :m_s_to_feet_s | Meters per Second to Feet per Second |
| :feet_s_to_m_s | Feet per Second to Meters per Second |
| :km_h_to_mi_h | Kilometers per Hour to Miles per Hour |
| :mi_h_to_km_h | Miles per Hour to Kilometers per Hour |
You can list all the available units here, or using list methods. The return will be a hash with the unit and a description of the unit.
converter.list_all
# => {:km_to_mi=>"KM to MI", :mi_to_km=>"MI to KM", ...}
converter.list_distance
# => {:km_to_mi=>"KM to MI", :mi_to_km=>"MI to KM", ...}
converter.list_speed
# => {:m_s_to_km_h=>"M S to KM H", :km_h_to_m_s=>"KM H to M S", ...}Perform multiple conversions in sequence with the converter chain feature:
calc = Calcpace.new
# Convert kilometers to miles to feet in one call
calc.convert_chain(1, [:km_to_mi, :mi_to_feet])
# => 3280.84 (1 km = 0.621 mi = 3280.84 feet)
# Convert with description for debugging
calc.convert_chain_with_description(100, [:meters_to_km, :km_to_mi])
# => { result: 0.0621371, description: "100 → meters_to_km → km_to_mi → 0.0621" }
# Speed conversions
calc.convert_chain(10, [:m_s_to_km_h, :km_h_to_mi_h])
# => 22.3694 (10 m/s = 36 km/h = 22.37 mi/h)Calcpace includes a race pace calculator for standard race distances (5K, 10K, half-marathon, and marathon):
calc = Calcpace.new
# Calculate finish time for a race given a pace
calc.race_time(300, '5k') # => 1500.0 (5:00/km pace for 5K = 25:00)
calc.race_time_clock('05:00', 'marathon') # => '03:30:58' (5:00/km pace for marathon)
# Calculate required pace for a target finish time
calc.race_pace('00:30:00', '5k') # => 360.0 (need 6:00/km to finish 5K in 30:00)
calc.race_pace_clock('04:00:00', 'marathon') # => '00:05:41' (need 5:41/km for 4-hour marathon)
# List available race distances
calc.list_races
# => { '5k' => 5.0, '10k' => 10.0, 'half_marathon' => 21.0975, 'marathon' => 42.195 }Supported race distances:
5k- 5 kilometers10k- 10 kilometershalf_marathon- 21.0975 kilometersmarathon- 42.195 kilometers
Calcpace also provides other useful methods:
converter = Calcpace.new
converter.convert_to_seconds('01:00:00') # => 3600
converter.convert_to_clocktime(3600) # => '01:00:00'
converter.convert_to_clocktime(100000) # => '1 03:46:40'
converter.check_time('01:00:00') # => nilThe gem now raises specific custom error classes for invalid inputs, allowing for more precise error handling. These errors inherit from Calcpace::Error.
Calcpace::NonPositiveInputError: Raised when a numeric input is not positive.Calcpace::InvalidTimeFormatError: Raised when a time string is not in the expectedHH:MM:SSorMM:SSformat.
For example:
begin
calculate.pace(945, -1)
rescue Calcpace::NonPositiveInputError => e
puts e.message # => "Distance must be a positive number"
end
begin
calculate.checked_time('string', 10)
rescue Calcpace::InvalidTimeFormatError => e
puts e.message # => "It must be a valid time in the XX:XX:XX or XX:XX format"
endTo run the tests, clone the repository and run:
bundle exec rakeThe tests are run using Ruby versions from 2.7.8 to 3.4.2, as specified in the .github/workflows/test.yml file.
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.
The gem is available as open source under the terms of the MIT License.