Skip to content

Commit

Permalink
36 create a global convert method to distances and velocities (#37)
Browse files Browse the repository at this point in the history
* Bump gems

* Create new convert options

* Remove old checker options

* Add options to calculate with and without checks and rename methods

* Add comment lint to Calcpace class

* Rename pace to velocity

* Update Readme with new features

* Update gemspec to 1.3.0 version

* Minor adjust in text of Readme
  • Loading branch information
0jonjo authored Sep 8, 2024
1 parent bfde063 commit 68bf723
Show file tree
Hide file tree
Showing 12 changed files with 283 additions and 239 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/calcpace-*
calcpace-*
calcpace.gemspec
3 changes: 1 addition & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ gem 'minitest', '~> 5.14'
gem 'rake', '~> 13.0'
gem 'rake-compiler', '~> 1.0'
gem 'rdoc', '~> 6.2'
gem 'rubocop', '~> 0.79'
gem 'rubocop-minitest', '~> 0.11'
gem 'rubocop', '~> 1.66'
33 changes: 15 additions & 18 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,38 @@ GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
json (2.7.2)
language_server-protocol (3.17.0.3)
minitest (5.23.1)
parallel (1.25.1)
parser (3.3.3.0)
parallel (1.26.3)
parser (3.3.5.0)
ast (~> 2.4.1)
racc
psych (5.1.2)
stringio
racc (1.8.0)
racc (1.8.1)
rainbow (3.1.1)
rake (13.2.1)
rake-compiler (1.2.7)
rake
rdoc (6.7.0)
psych (>= 4.0.0)
regexp_parser (2.9.2)
rexml (3.3.6)
strscan
rubocop (0.93.1)
rubocop (1.66.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 2.7.1.5)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8)
rexml
rubocop-ast (>= 0.6.0)
regexp_parser (>= 2.4, < 3.0)
rubocop-ast (>= 1.32.2, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (1.31.3)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.32.3)
parser (>= 3.3.1.0)
rubocop-minitest (0.27.0)
rubocop (>= 0.90, < 2.0)
ruby-progressbar (1.13.0)
stringio (3.1.1)
strscan (3.1.0)
unicode-display_width (1.8.0)
unicode-display_width (2.5.0)

PLATFORMS
ruby
Expand All @@ -45,8 +43,7 @@ DEPENDENCIES
rake (~> 13.0)
rake-compiler (~> 1.0)
rdoc (~> 6.2)
rubocop (~> 0.79)
rubocop-minitest (~> 0.11)
rubocop (~> 1.66)

RUBY VERSION
ruby 3.2.1p31
Expand Down
140 changes: 84 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
# 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 [![Gem Version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=rb&r=r&ts=1683906897&type=6e&v=1.3.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.
Calcpace is a Ruby gem that helps with calculations and conversions related to distance and time. It can calculate velocity, total time, and distance, accepting time in different formats, including HH:MM:SS. The gem supports BigDecimal to handle the calculations and it can convert to 26 different units, including kilometers, miles, meters, and feet. The gem also provides methods to check the validity of the input.

## Installation

### Add to your Gemfile

```ruby
gem 'calcpace', '~> 1.2.0'
gem 'calcpace', '~> 1.3.0'
```

Then run bundle install.
Then run `bundle install`.

### Install the gem manually

```bash
gem install calcpace
```

### Usage
## 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. 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:
Before calculating or converting any value, you must create a new instance of Calcpace. If you want to use BigDecimal to handle the calculations, you can pass `true` as a parameter when creating a new instance of Calcpace. Here are a few examples:

```ruby
require 'calcpace'
Expand All @@ -30,85 +30,113 @@ calculate_bigdecimal = Calcpace.new(true)
another_way_to_use_bigdecimal = Calcpace.new(bigdecimal: true)
```

### Calculate Pace
### Calculate Velocity

To calculate pace, provide the total time (in HH:MM:SS format) and distance (in X.X format, representing kilometers or miles). You can use the method `pace` or `pace_seconds`. If you want an extra precision in the calculations, you can pass true as parameter to the method `pace_seconds` and receive result in BigDecimal.
To calculate velocity, provide the total time and then the distance as inputs. Here are some examples:

```ruby
calculate = Calcpace.new
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) # => 474.8780487804878
calculate_bigdecimal = Calcpace.new(true)
calculate_bigdecimal.pace_seconds('01:37:21', 12.3) # => 0.474878048780487804878048780487804878049e3

calculate.velocity(3600, 12) # => 300
calculate.checked_velocity('01:00:00', 12) # => 300
calculate.checked_velocity('01:37:21', 12.3) # => 474.8780487804878
calculate.clock_velocity('string', 12) # It must be a time (RuntimeError)
calculate.clock_velocity('01:00:00', 12) # => "00:05:00"
calculate_bigdecimal.checked_velocity('01:37:21', 12.3) # => 0.474878048780487804878048780487804878049e3
```

### Calculate Total Time

To calculate total time, provide the pace (in HH:MM:SS format) and distance (in X.X format, representing kilometers or miles). You can use the method `total_time` or `total_time_seconds`. If you want an extra precision in the calculations, you can pass true as parameter to the method `total_time_seconds` and receive result in BigDecimal.
To calculate the total time, provide the velocity and then the distance as inputs. Here are some examples:

```ruby
calculate = Calcpace.new
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_bigdecimal = Calcpace.new(true)
calculate_bigdecimal.total_time_seconds('01:37:21', 12.3) # => 0.718443902439024390243902439024390243902e5
calculate.time(3600, 12) # => 43200
calculate.checked_time('01:37:21', 12.3) # => 71844.3
calculate.clock_time('00:05:00', 'string') # It must be a XX:XX:XX time (RuntimeError)
calculate.clock_time('00:05:00', 12) # => "01:00:00"
calculate_bigdecimal.checked_time('01:37:21', 12.3) # => 0.718443902439024390243902439024390243902e5
```

### Calculate Distance

To calculate distance, provide the running time (in HH:MM:SS format) and pace (in HH:MM:SS format). If you want an extra precision in the calculations, you can pass true as parameter to the method and receive result in BigDecimal.
To calculate the distance, provide the total time and then the velocity as inputs. Here are some examples:

```ruby
calculate = Calcpace.new
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
calculate.distance(3600, 120) # => 30
calculate.checked_distance('01:37:21', 'string') # It must be a time (RuntimeError)
calculate.checked_distance('01:37:21', '00:06:17') # => 15.0
calculate_bigdecimal.checked_distance('01:37:21', '00:06:17') # => 0.15493368700265251989389920424403183024e2
```

### Convert Distances
### Understanding the Methods

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.
Calcpace provides three kinds of methods to calculate:

```ruby
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
```
- Without checks (velocity, time, and distance):
- Receive inputs as integers or floats.
- Do not check the validity of the input.
- Return an error only if the input invalidates the calculation (e.g., a string in place of a number).

- With checks (checked_velocity, checked_time, and checked_distance):
- Check the validity of the input and return an error if the input is invalid.
- Accept time in "HH:MM:SS" format and return the result in seconds or the inputted distance.

- With clock (clock_velocity, clock_time):
- Same as the checked methods, but return the result in "HH:MM:SS" format.

### Convert Distances and Velocities

### Obtain the seconds of a time OR convert seconds to a time
Use the `convert` method to convert a distance or a 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.

To obtain the seconds of a time, provide the time in HH:MM:SS format.
Here are some examples:

```ruby
converter = Calcpace.new
converter.to_seconds('01:00:00') # => 3600
converter.to_seconds('string') # => It must be a time (RuntimeError)
converter.to_clocktime(3600) # => '01:00:00'
converter.to_clocktime('string') # => It must be a number (RuntimeError)
converter.convert(10, 'KM_TO_METERS') # => 1000
converter.convert(10, 'MILES_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
```

List of supported distance and velocity units:

| 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 |
| METERS_TO_FEET | Meters to Feet |
| FEET_TO_METERS | Feet to Meters |
| METERS_TO_YARDS | Meters to Yards |
| YARDS_TO_METERS | Yards to Meters |
| METERS_TO_INCHES | Meters to Inches |
| INCHES_TO_METERS | Inches 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_NAUTICAL_MI_H | Meters per Second to Nautical Miles per Hour |
| NAUTICAL_MI_H_TO_M_S | Nautical 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 |
| M_S_TO_KNOTS | Meters per Second to Knots |
| KNOTS_TO_M_S | Knots 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 |

### Other Useful Methods

Calcpace also provides other useful methods to check the validity of input.
Calcpace also provides other useful methods:

```ruby
calcpace = Calcpace.new
calcpace.check_time('01:00:00') # => nil
calcpace.check_time('01-00-00') # => It must be a XX:XX:XX time (RuntimeError)
calcpace.check_distance(10) # => nil
calcpace.check_distance('-10') # => It must be a positive number (RuntimeError)
calcpace.check_unit('km') # => nil
calcpace.check_unit('string') # => It must be a valid unit (RuntimeError)
converter = Calcpace.new
converter.convert_to_seconds('01:00:00') # => 3600
converter.convert_to_clocktime(3600) # => '01:00:00'
converter.check_time('01:00:00') # => nil
converter.check_time('01-00-00') # => It must be a XX:XX:XX time (RuntimeError)
```

## Contributing
Expand Down
16 changes: 9 additions & 7 deletions calcpace.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@

Gem::Specification.new do |s|
s.name = 'calcpace'
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 with more precision.'
s.version = '1.3.0'
s.summary = 'Calcpace: calculate total, distance, velocity and convert distances in an easy and precise way.'
s.description = 'Calcpace is a Ruby gem that helps with calculations related to distance and time. It can calculate velocity, total time, and distance. It also converts distance and velocity, check formats of time and can handle calculus with BigDecimal.'
s.authors = ['Joao Gilberto Saraiva']
s.email = '[email protected]'
s.files = ['lib/calcpace.rb', 'lib/calcpace/calculator.rb', 'lib/calcpace/checker.rb', 'lib/calcpace/converter.rb']
s.test_files = ['test/calcpace/test_calculator.rb', 'test/calcpace/test_checker.rb', 'test/calcpace/test_converter.rb']
s.files = ['lib/calcpace.rb', 'lib/calcpace/calculator.rb', 'lib/calcpace/checker.rb',
'lib/calcpace/converter.rb']
s.test_files = ['test/calcpace/test_calculator.rb', 'test/calcpace/test_checker.rb',
'test/calcpace/test_converter.rb']
s.add_development_dependency 'minitest', '~> 5.14'
s.add_development_dependency 'rake', '~> 13.0'
s.add_development_dependency 'rake-compiler', '~> 1.0'
s.add_development_dependency 'rdoc', '~> 6.2'
s.add_development_dependency 'rubocop', '~> 0.79'
s.add_development_dependency 'rubocop-minitest', '~> 0.11'
s.add_development_dependency 'rubocop', '~> 1.66'

s.required_ruby_version = '>= 2.7.0'
s.post_install_message = "It's time to calculate! Thank you for installing Calcpace."
s.metadata = { 'source_code_uri' => 'https://github.com/0jonjo/calcpace' }
Expand Down
1 change: 1 addition & 0 deletions lib/calcpace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require_relative 'calcpace/checker'
require_relative 'calcpace/converter'

# Main class to calculate velocity, time, distance and velocity
class Calcpace
include Calculator
include Checker
Expand Down
58 changes: 34 additions & 24 deletions lib/calcpace/calculator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,51 @@

require 'bigdecimal'

# Module to calculate time, distance and velocity
module Calculator
def pace(time, distance)
pace_in_seconds = pace_seconds(time, distance)
convert_to_clocktime(pace_in_seconds)
def velocity(time, distance)
time / distance
end

def pace_seconds(time, distance)
def checked_velocity(time, distance)
check_time(time)
check_distance(distance)
seconds = convert_to_seconds(time)
bigdecimal ? seconds / BigDecimal(distance.to_s) : seconds / distance
check_positive(distance)
distance_to_calc = convert_to_bigdecimal(distance)
seconds = convert_to_bigdecimal(convert_to_seconds(time))
velocity(seconds, distance_to_calc)
end

def total_time(pace, distance)
total_time_in_seconds = total_time_seconds(pace, distance)
def clock_velocity(time, distance)
velocity_in_seconds = checked_velocity(time, distance)
convert_to_clocktime(velocity_in_seconds)
end

def time(velocity, distance)
velocity * distance
end

def checked_time(velocity, distance)
check_time(velocity)
check_positive(distance)
distance_to_calc = convert_to_bigdecimal(distance)
velocity_seconds = convert_to_bigdecimal(convert_to_seconds(velocity))
time(velocity_seconds, distance_to_calc)
end

def clock_time(velocity, distance)
total_time_in_seconds = checked_time(velocity, distance)
convert_to_clocktime(total_time_in_seconds)
end

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
def distance(time, velocity)
time / velocity
end

def distance(time, pace)
def checked_distance(time, velocity)
check_time(time)
check_time(pace)
if bigdecimal
time_seconds = BigDecimal(convert_to_seconds(time).to_s)
pace_seconds = BigDecimal(convert_to_seconds(pace).to_s)
else
time_seconds = convert_to_seconds(time)
pace_seconds = convert_to_seconds(pace)
end
time_seconds / pace_seconds
check_time(velocity)
time_seconds = convert_to_bigdecimal(convert_to_seconds(time))
velocity_seconds = convert_to_bigdecimal(convert_to_seconds(velocity))
distance(time_seconds, velocity_seconds)
end
end
Loading

0 comments on commit 68bf723

Please sign in to comment.