calcpace 1.9.3 → 1.9.5
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 +4 -4
- data/CHANGELOG.md +50 -1
- data/Gemfile.lock +2 -2
- data/README.md +40 -2
- data/lib/calcpace/age_grading.rb +198 -0
- data/lib/calcpace/cameron_predictor.rb +1 -1
- data/lib/calcpace/data/wma_2023_open_standards.yml +30 -0
- data/lib/calcpace/data/wma_2023_road.yml +16 -0
- data/lib/calcpace/pace_calculator.rb +6 -5
- data/lib/calcpace/race_predictor.rb +1 -1
- data/lib/calcpace/race_splits.rb +2 -2
- data/lib/calcpace/version.rb +1 -1
- data/lib/calcpace.rb +2 -0
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: db7effb21592146022bf3df34ecdb8a8688fb4d79d618c43c5b99a9912ac967a
|
|
4
|
+
data.tar.gz: 2e009f5c0fa7856f65c3f8a447fa9a4de2e51e5057bf1606810d3bc38e3d9a02
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 129467189d43ea17a4ac31f371e813b08a12d7d0482a3f4717414087db3ffa0f5134478e5134cb512c5c6f242f7eab57b2172bf40b61107ed7a204f2043bf78e
|
|
7
|
+
data.tar.gz: c716d04864bdf92ab64259c938a05d1cce552a9c35738f1b7b76848b4c32d36119ed71c9ddcd8c0725b4002c660eee8cb51e5a020fdf9ac7d29d062ea3801002
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,54 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.9.5] - 2026-05-02
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Age-grading module (`AgeGrading`) with:
|
|
14
|
+
- `age_grade(distance_km, time, age:, sex:)`
|
|
15
|
+
- `age_grade_percent(distance_km, time, age:, sex:)`
|
|
16
|
+
- `age_grade_label(percent)`
|
|
17
|
+
- Versioned data file loader using YAML + `YAML.safe_load` from
|
|
18
|
+
`lib/calcpace/data/wma_2023_road.yml`
|
|
19
|
+
- Interpolation support for in-between ages (e.g., 57 between 55 and 60)
|
|
20
|
+
- Initial road-race support: 5K, 10K, half marathon, marathon
|
|
21
|
+
- WMA 2023 one-year age factors integrated for `M`/`F` road distances in meters
|
|
22
|
+
- Source: World Masters Athletics (WMA) competition rules documents
|
|
23
|
+
https://world-masters-athletics.org/documents/competition-rules/
|
|
24
|
+
- Race-style age-factored time rounding up to the next hundredth
|
|
25
|
+
- Test suite for validation, interpolation, and error handling
|
|
26
|
+
|
|
27
|
+
## [1.9.4] - 2026-04-18
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
- Standard race distance support for **100K** (100.0 km)
|
|
31
|
+
- Supported in `PaceCalculator`, `RacePredictor`, `CameronPredictor`, and `RaceSplits`
|
|
32
|
+
- Updated `list_races` to include 100K
|
|
33
|
+
- Added integration tests for 100K race distance across all modules
|
|
34
|
+
|
|
35
|
+
## [1.9.3] - 2026-04-05
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
- VO2max Estimator module (`Vo2maxEstimator`)
|
|
39
|
+
- Daniels & Gilbert (1979) formula for VO2max estimation from race results
|
|
40
|
+
- Performance level labels (Elite, Excellent, etc.)
|
|
41
|
+
- Improved time validation using strict `check_time` and `convert_to_seconds`
|
|
42
|
+
- Updated YARD documentation for all calculation methods
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
- Gemspec formatting and line length constraints
|
|
46
|
+
- README structure and documentation examples
|
|
47
|
+
|
|
48
|
+
## [1.9.2] - 2026-03-31
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
- Track Calculator module (`TrackCalculator`)
|
|
52
|
+
- Haversine distance calculation for GPS coordinates
|
|
53
|
+
- Elevation gain and loss analysis
|
|
54
|
+
- Automated track splits based on GPS points
|
|
55
|
+
|
|
8
56
|
## [1.9.1] - 2026-03-30
|
|
9
57
|
|
|
10
58
|
### Changed
|
|
@@ -116,5 +164,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
116
164
|
|
|
117
165
|
See git history for changes in earlier versions.
|
|
118
166
|
|
|
119
|
-
[Unreleased]: https://github.com/0jonjo/calcpace/compare/v1.
|
|
167
|
+
[Unreleased]: https://github.com/0jonjo/calcpace/compare/v1.9.5...HEAD
|
|
168
|
+
[1.9.5]: https://github.com/0jonjo/calcpace/compare/v1.9.4...v1.9.5
|
|
120
169
|
[1.6.0]: https://github.com/0jonjo/calcpace/releases/tag/v1.6.0
|
data/Gemfile.lock
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
GEM
|
|
2
2
|
remote: https://rubygems.org/
|
|
3
3
|
specs:
|
|
4
|
-
addressable (2.
|
|
4
|
+
addressable (2.9.0)
|
|
5
5
|
public_suffix (>= 2.0.2, < 8.0)
|
|
6
6
|
ast (2.4.3)
|
|
7
7
|
bigdecimal (4.1.0)
|
|
8
8
|
date (3.5.1)
|
|
9
9
|
docile (1.4.1)
|
|
10
|
-
erb (6.0.
|
|
10
|
+
erb (6.0.4)
|
|
11
11
|
json (2.19.2)
|
|
12
12
|
json-schema (6.2.0)
|
|
13
13
|
addressable (~> 2.8)
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Calcpace [](https://badge.fury.io/rb/calcpace)
|
|
2
2
|
|
|
3
3
|
A Ruby gem for running and cycling calculations: pace, time, distance, unit conversions, race predictions, GPS track analysis, and VO2max estimation.
|
|
4
4
|
|
|
@@ -64,7 +64,7 @@ calc.pace_mi_to_km('08:00') # => "00:04:58"
|
|
|
64
64
|
```ruby
|
|
65
65
|
calc.race_time_clock('05:00', 'marathon') # => "03:30:58"
|
|
66
66
|
calc.race_pace_clock('04:00:00', 'marathon') # => "00:05:41"
|
|
67
|
-
calc.list_races # => { '5k' => 5.0, '10k' => 10.0, 'half_marathon' => 21.0975, ... }
|
|
67
|
+
calc.list_races # => { '5k' => 5.0, '10k' => 10.0, 'half_marathon' => 21.0975, 'marathon' => 42.195, '100k' => 100.0, ... }
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
---
|
|
@@ -124,6 +124,44 @@ calc.track_splits(points, 1.0) # => [{ km: 1, elapsed: 312, pace: "05:12" }, ...
|
|
|
124
124
|
|
|
125
125
|
---
|
|
126
126
|
|
|
127
|
+
### Age Grading (Road Races)
|
|
128
|
+
|
|
129
|
+
Age grading compares race results across different ages and sexes by using
|
|
130
|
+
age factors and open standards.
|
|
131
|
+
|
|
132
|
+
```ruby
|
|
133
|
+
result = calc.age_grade(10.0, '00:45:00', age: 55, sex: :male)
|
|
134
|
+
# => {
|
|
135
|
+
# age_grade_percent: 64.6,
|
|
136
|
+
# category: "Local Class",
|
|
137
|
+
# age_graded_time_seconds: 2376.0,
|
|
138
|
+
# age_graded_time_clock: "00:39:36",
|
|
139
|
+
# open_standard_seconds: 1571.0,
|
|
140
|
+
# open_standard_clock: "00:26:11",
|
|
141
|
+
# factor: 0.88,
|
|
142
|
+
# table_version: "WMA_2023_ONE_YEAR_FACTORS_V1"
|
|
143
|
+
# }
|
|
144
|
+
|
|
145
|
+
calc.age_grade_percent(5.0, '00:22:30', age: 40, sex: :female) # => 74.1
|
|
146
|
+
calc.age_grade_label(74.1) # => "Regional Class"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Supported distances: 5K, 10K, half marathon, marathon.
|
|
150
|
+
|
|
151
|
+
Age factors are based on WMA 2023 one-year age grading tables:
|
|
152
|
+
https://world-masters-athletics.org/documents/competition-rules/
|
|
153
|
+
|
|
154
|
+
Open standards used in `open_standard_seconds` / `open_standard_clock` are loaded
|
|
155
|
+
from the bundled WMA 2023 open standards dataset
|
|
156
|
+
(`lib/calcpace/data/wma_2023_open_standards.yml`).
|
|
157
|
+
|
|
158
|
+
Field meanings:
|
|
159
|
+
- `age_graded_time_clock`: your result after applying the WMA age factor (normalized performance time).
|
|
160
|
+
- `open_standard_clock`: the open standard reference time used to compute the percentage for that distance/sex.
|
|
161
|
+
- `age_grade_percent`: `(open_standard_seconds / age_graded_time_seconds) * 100`.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
127
165
|
### VO2max Estimation
|
|
128
166
|
|
|
129
167
|
Estimate aerobic fitness from a race result using the **Daniels & Gilbert formula** (1979):
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'yaml'
|
|
4
|
+
|
|
5
|
+
# Module for age-grading race performances with a versioned table
|
|
6
|
+
#
|
|
7
|
+
# Age grading allows fairer comparison across ages by applying an age factor
|
|
8
|
+
# to the raw performance time.
|
|
9
|
+
#
|
|
10
|
+
# Current scope:
|
|
11
|
+
# - Common road distances: 5K, 10K, half marathon, marathon
|
|
12
|
+
# - Sex: male/female
|
|
13
|
+
# - Age: 18+
|
|
14
|
+
# - Data file is versioned and replaceable (`lib/calcpace/data/wma_2023_road.yml`)
|
|
15
|
+
#
|
|
16
|
+
# Returned values include:
|
|
17
|
+
# - age grade percentage
|
|
18
|
+
# - age-graded time
|
|
19
|
+
# - open standard time for the selected distance/sex
|
|
20
|
+
# - performance category
|
|
21
|
+
# rubocop:disable Metrics/ModuleLength
|
|
22
|
+
module AgeGrading
|
|
23
|
+
DATA_PATH = File.expand_path('data/wma_2023_road.yml', __dir__).freeze
|
|
24
|
+
OPEN_STANDARDS_DATA_PATH = File.expand_path('data/wma_2023_open_standards.yml', __dir__).freeze
|
|
25
|
+
WMA_DATA = YAML.safe_load_file(DATA_PATH, permitted_classes: [],
|
|
26
|
+
aliases: false).freeze
|
|
27
|
+
OPEN_STANDARDS_DATA = YAML.safe_load_file(OPEN_STANDARDS_DATA_PATH, permitted_classes: [],
|
|
28
|
+
aliases: false).freeze
|
|
29
|
+
TABLE_VERSION = OPEN_STANDARDS_DATA.fetch('meta').fetch('table_version').freeze
|
|
30
|
+
|
|
31
|
+
AGE_GRADE_LABELS = OPEN_STANDARDS_DATA.fetch('age_grade_classifications').map do |entry|
|
|
32
|
+
{ min: entry.fetch('min').to_f, label: entry.fetch('label') }
|
|
33
|
+
end.freeze
|
|
34
|
+
|
|
35
|
+
DISTANCE_TO_METERS = {
|
|
36
|
+
5.0 => '5000',
|
|
37
|
+
10.0 => '10000',
|
|
38
|
+
21.0975 => '21097',
|
|
39
|
+
42.195 => '42195'
|
|
40
|
+
}.freeze
|
|
41
|
+
RACE_TO_METERS = {
|
|
42
|
+
'5k' => '5000',
|
|
43
|
+
'10k' => '10000',
|
|
44
|
+
'half_marathon' => '21097',
|
|
45
|
+
'marathon' => '42195'
|
|
46
|
+
}.freeze
|
|
47
|
+
|
|
48
|
+
SUPPORTED_DISTANCES_KM = DISTANCE_TO_METERS.keys.freeze
|
|
49
|
+
|
|
50
|
+
# Returns a full age-grading report for a race performance
|
|
51
|
+
#
|
|
52
|
+
# @param distance_km [Numeric, String, Symbol] race distance in kilometres
|
|
53
|
+
# (5.0, 10.0, 21.0975, 42.195) or race key (:5k, :10k, :half_marathon, :marathon)
|
|
54
|
+
# @param time [String, Numeric] performance time as HH:MM:SS / MM:SS, or total seconds
|
|
55
|
+
# @param age [Integer] athlete age (must be >= 18)
|
|
56
|
+
# @param sex [String, Symbol] male or female
|
|
57
|
+
# @return [Hash] age-grading result details
|
|
58
|
+
def age_grade(distance_km, time, age:, sex:)
|
|
59
|
+
distance_m = normalize_distance(distance_km)
|
|
60
|
+
seconds = parse_time_seconds(time)
|
|
61
|
+
age_value = normalize_age(age)
|
|
62
|
+
sex_value = normalize_sex(sex)
|
|
63
|
+
|
|
64
|
+
check_positive(seconds, 'Time')
|
|
65
|
+
|
|
66
|
+
factor = interpolated_factor(sex_value, age_value, distance_m)
|
|
67
|
+
age_graded_time = round_up_hundredth(seconds * factor)
|
|
68
|
+
open_standard = open_standard_seconds(sex_value, distance_m)
|
|
69
|
+
grade_percent = (open_standard / age_graded_time) * 100.0
|
|
70
|
+
rounded_percent = grade_percent.round(1)
|
|
71
|
+
|
|
72
|
+
{
|
|
73
|
+
age_grade_percent: rounded_percent,
|
|
74
|
+
category: age_grade_label(rounded_percent),
|
|
75
|
+
age_graded_time_seconds: age_graded_time,
|
|
76
|
+
age_graded_time_clock: convert_to_clocktime(age_graded_time),
|
|
77
|
+
open_standard_seconds: open_standard,
|
|
78
|
+
open_standard_clock: convert_to_clocktime(open_standard),
|
|
79
|
+
factor: factor.round(4),
|
|
80
|
+
table_version: TABLE_VERSION
|
|
81
|
+
}
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Returns only the age-grade percentage
|
|
85
|
+
#
|
|
86
|
+
# @param distance_km [Numeric] race distance in kilometres
|
|
87
|
+
# @param time [String, Numeric] performance time
|
|
88
|
+
# @param age [Integer] athlete age
|
|
89
|
+
# @param sex [String, Symbol] male or female
|
|
90
|
+
# @return [Float] age-grade percentage
|
|
91
|
+
def age_grade_percent(distance_km, time, age:, sex:)
|
|
92
|
+
age_grade(distance_km, time, age: age, sex: sex)[:age_grade_percent]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Returns a descriptive label for an age-grade percentage
|
|
96
|
+
#
|
|
97
|
+
# @param percent [Numeric] age-grade percentage
|
|
98
|
+
# @return [String] category label
|
|
99
|
+
def age_grade_label(percent)
|
|
100
|
+
percent_value = begin
|
|
101
|
+
Float(percent)
|
|
102
|
+
rescue ArgumentError, TypeError
|
|
103
|
+
raise ArgumentError, 'Age-grade percent must be a numeric value greater than or equal to 0'
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
raise ArgumentError, 'Age-grade percent must be greater than or equal to 0' if percent_value.negative?
|
|
107
|
+
|
|
108
|
+
AGE_GRADE_LABELS.find { |entry| percent_value >= entry[:min] }[:label]
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
private
|
|
112
|
+
|
|
113
|
+
def normalize_distance(distance_km)
|
|
114
|
+
if distance_km.is_a?(String) || distance_km.is_a?(Symbol)
|
|
115
|
+
key = distance_km.to_s.strip.downcase
|
|
116
|
+
return RACE_TO_METERS.fetch(key) if RACE_TO_METERS.key?(key)
|
|
117
|
+
|
|
118
|
+
raise ArgumentError,
|
|
119
|
+
"Unsupported race '#{distance_km}'. Supported: #{RACE_TO_METERS.keys.join(', ')}"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
distance = distance_km.to_f
|
|
123
|
+
check_positive(distance, 'Distance')
|
|
124
|
+
|
|
125
|
+
match = SUPPORTED_DISTANCES_KM.find { |value| (distance - value).abs <= 0.001 }
|
|
126
|
+
return DISTANCE_TO_METERS.fetch(match) if match
|
|
127
|
+
|
|
128
|
+
raise ArgumentError,
|
|
129
|
+
"Unsupported distance #{distance_km}km. Supported: #{SUPPORTED_DISTANCES_KM.join(', ')}"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def parse_time_seconds(time)
|
|
133
|
+
return time.to_f if time.is_a?(Numeric)
|
|
134
|
+
|
|
135
|
+
check_time(time.to_s)
|
|
136
|
+
convert_to_seconds(time.to_s)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def normalize_age(age)
|
|
140
|
+
age_value = Integer(age)
|
|
141
|
+
rescue ArgumentError, TypeError
|
|
142
|
+
raise ArgumentError, 'Age must be an integer greater than or equal to 18'
|
|
143
|
+
else
|
|
144
|
+
raise ArgumentError, 'Age must be at least 18' if age_value < 18
|
|
145
|
+
|
|
146
|
+
age_value
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def normalize_sex(sex)
|
|
150
|
+
normalized = sex.to_s.strip.downcase.to_sym
|
|
151
|
+
return normalized if %i[male female].include?(normalized)
|
|
152
|
+
|
|
153
|
+
raise ArgumentError, "Sex must be 'male' or 'female'"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def interpolated_factor(sex, age, distance_m)
|
|
157
|
+
table = factor_table(sex, distance_m)
|
|
158
|
+
ages = table.keys.map(&:to_i).sort
|
|
159
|
+
|
|
160
|
+
return table.fetch(ages.first).to_f if age <= ages.first
|
|
161
|
+
return table.fetch(ages.last).to_f if age >= ages.last
|
|
162
|
+
|
|
163
|
+
lower_age, upper_age = neighboring_ages(ages, age)
|
|
164
|
+
return table.fetch(lower_age).to_f if lower_age == upper_age
|
|
165
|
+
|
|
166
|
+
interpolated_value(table, lower_age, upper_age, age)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def factor_table(sex, distance_m)
|
|
170
|
+
WMA_DATA.fetch(sex_key(sex)).fetch(distance_m)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def sex_key(sex)
|
|
174
|
+
sex == :male ? 'M' : 'F'
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def open_standard_seconds(sex, distance_m)
|
|
178
|
+
OPEN_STANDARDS_DATA.fetch('open_standards_seconds').fetch(sex_key(sex)).fetch(distance_m).to_f
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def round_up_hundredth(value)
|
|
182
|
+
(value * 100.0).ceil / 100.0
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def neighboring_ages(ages, age)
|
|
186
|
+
lower_age = ages.select { |value| value <= age }.max
|
|
187
|
+
upper_age = ages.select { |value| value >= age }.min
|
|
188
|
+
[lower_age, upper_age]
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def interpolated_value(table, lower_age, upper_age, age)
|
|
192
|
+
lower_factor = table.fetch(lower_age).to_f
|
|
193
|
+
upper_factor = table.fetch(upper_age).to_f
|
|
194
|
+
ratio = (age - lower_age).to_f / (upper_age - lower_age)
|
|
195
|
+
lower_factor + ((upper_factor - lower_factor) * ratio)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
# rubocop:enable Metrics/ModuleLength
|
|
@@ -24,7 +24,7 @@ module CameronPredictor
|
|
|
24
24
|
|
|
25
25
|
# Predicts race time using the Cameron formula
|
|
26
26
|
#
|
|
27
|
-
# @param from_race [String, Symbol] known race distance ('5k', '10k', 'half_marathon', 'marathon', etc.)
|
|
27
|
+
# @param from_race [String, Symbol] known race distance ('5k', '10k', 'half_marathon', 'marathon', '100k', etc.)
|
|
28
28
|
# @param from_time [String, Numeric] time achieved at known distance (HH:MM:SS or seconds)
|
|
29
29
|
# @param to_race [String, Symbol] target race distance to predict
|
|
30
30
|
# @return [Float] predicted time in seconds
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
source: "WMA/Masters Rankings age grading tables (2023)"
|
|
3
|
+
url: "https://howardgrubb.co.uk/athletics/wmatnf23.html"
|
|
4
|
+
table_version: "WMA_2023_ONE_YEAR_FACTORS_V1"
|
|
5
|
+
|
|
6
|
+
age_grade_classifications:
|
|
7
|
+
- min: 100.0
|
|
8
|
+
label: "Approximate World Record Level"
|
|
9
|
+
- min: 90.0
|
|
10
|
+
label: "World Class"
|
|
11
|
+
- min: 80.0
|
|
12
|
+
label: "National Class"
|
|
13
|
+
- min: 70.0
|
|
14
|
+
label: "Regional Class"
|
|
15
|
+
- min: 60.0
|
|
16
|
+
label: "Local Class"
|
|
17
|
+
- min: 0.0
|
|
18
|
+
label: "Developing"
|
|
19
|
+
|
|
20
|
+
open_standards_seconds:
|
|
21
|
+
M:
|
|
22
|
+
"5000": 755.0
|
|
23
|
+
"10000": 1571.0
|
|
24
|
+
"21097": 3451.0
|
|
25
|
+
"42195": 7269.0
|
|
26
|
+
F:
|
|
27
|
+
"5000": 846.0
|
|
28
|
+
"10000": 1741.0
|
|
29
|
+
"21097": 3772.0
|
|
30
|
+
"42195": 8044.0
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
F:
|
|
3
|
+
"1500": { 30: 1.0000, 31: 1.0000, 32: 1.0000, 33: 0.9960, 34: 0.9886, 35: 0.9812, 36: 0.9738, 37: 0.9664, 38: 0.9590, 39: 0.9515, 40: 0.9441, 41: 0.9367, 42: 0.9293, 43: 0.9218, 44: 0.9144, 45: 0.9069, 46: 0.8995, 47: 0.8921, 48: 0.8846, 49: 0.8772, 50: 0.8697, 51: 0.8623, 52: 0.8548, 53: 0.8473, 54: 0.8399, 55: 0.8324, 56: 0.8249, 57: 0.8175, 58: 0.8100, 59: 0.8025, 60: 0.7951, 61: 0.7876, 62: 0.7801, 63: 0.7726, 64: 0.7651, 65: 0.7576, 66: 0.7501, 67: 0.7427, 68: 0.7352, 69: 0.7277, 70: 0.7202, 71: 0.7127, 72: 0.7052, 73: 0.6976, 74: 0.6897, 75: 0.6812, 76: 0.6722, 77: 0.6628, 78: 0.6529, 79: 0.6425, 80: 0.6316, 81: 0.6202, 82: 0.6083, 83: 0.5960, 84: 0.5832, 85: 0.5698, 86: 0.5561, 87: 0.5418, 88: 0.5270, 89: 0.5118, 90: 0.4960, 91: 0.4798, 92: 0.4631, 93: 0.4460, 94: 0.4283, 95: 0.4102, 96: 0.3915, 97: 0.3724, 98: 0.3528, 99: 0.3327, 100: 0.3122, 101: 0.2911, 102: 0.2696, 103: 0.2476, 104: 0.2251, 105: 0.2021, 106: 0.1787, 107: 0.1547, 108: 0.1303, 109: 0.1054, 110: 0.0800 }
|
|
4
|
+
"3000": { 30: 1.0000, 31: 1.0000, 32: 1.0000, 33: 1.0000, 34: 1.0000, 35: 1.0000, 36: 1.0000, 37: 1.0000, 38: 0.9930, 39: 0.9849, 40: 0.9767, 41: 0.9685, 42: 0.9603, 43: 0.9521, 44: 0.9438, 45: 0.9355, 46: 0.9271, 47: 0.9188, 48: 0.9104, 49: 0.9019, 50: 0.8935, 51: 0.8850, 52: 0.8765, 53: 0.8680, 54: 0.8594, 55: 0.8509, 56: 0.8423, 57: 0.8336, 58: 0.8250, 59: 0.8163, 60: 0.8076, 61: 0.7989, 62: 0.7901, 63: 0.7813, 64: 0.7725, 65: 0.7637, 66: 0.7549, 67: 0.7460, 68: 0.7371, 69: 0.7282, 70: 0.7193, 71: 0.7103, 72: 0.7013, 73: 0.6923, 74: 0.6833, 75: 0.6743, 76: 0.6652, 77: 0.6561, 78: 0.6470, 79: 0.6379, 80: 0.6288, 81: 0.6196, 82: 0.6098, 83: 0.5993, 84: 0.5881, 85: 0.5762, 86: 0.5637, 87: 0.5505, 88: 0.5366, 89: 0.5220, 90: 0.5067, 91: 0.4908, 92: 0.4742, 93: 0.4569, 94: 0.4390, 95: 0.4204, 96: 0.4010, 97: 0.3811, 98: 0.3604, 99: 0.3391, 100: 0.3171, 101: 0.2944, 102: 0.2711, 103: 0.2470, 104: 0.2223, 105: 0.1970, 106: 0.1709, 107: 0.1442, 108: 0.1168, 109: 0.0887, 110: 0.0600 }
|
|
5
|
+
"5000": { 30: 1.0000, 31: 1.0000, 32: 1.0000, 33: 1.0000, 34: 1.0000, 35: 0.9974, 36: 0.9904, 37: 0.9833, 38: 0.9761, 39: 0.9689, 40: 0.9615, 41: 0.9541, 42: 0.9467, 43: 0.9392, 44: 0.9316, 45: 0.9239, 46: 0.9162, 47: 0.9084, 48: 0.9006, 49: 0.8926, 50: 0.8847, 51: 0.8766, 52: 0.8685, 53: 0.8603, 54: 0.8521, 55: 0.8438, 56: 0.8355, 57: 0.8271, 58: 0.8186, 59: 0.8101, 60: 0.8015, 61: 0.7929, 62: 0.7842, 63: 0.7755, 64: 0.7667, 65: 0.7578, 66: 0.7489, 67: 0.7399, 68: 0.7309, 69: 0.7219, 70: 0.7128, 71: 0.7036, 72: 0.6944, 73: 0.6851, 74: 0.6758, 75: 0.6665, 76: 0.6571, 77: 0.6476, 78: 0.6381, 79: 0.6286, 80: 0.6190, 81: 0.6094, 82: 0.5997, 83: 0.5893, 84: 0.5783, 85: 0.5665, 86: 0.5541, 87: 0.5410, 88: 0.5272, 89: 0.5127, 90: 0.4975, 91: 0.4816, 92: 0.4650, 93: 0.4478, 94: 0.4299, 95: 0.4112, 96: 0.3919, 97: 0.3719, 98: 0.3513, 99: 0.3299, 100: 0.3079, 101: 0.2852, 102: 0.2618, 103: 0.2377, 104: 0.2129, 105: 0.1875, 106: 0.1613, 107: 0.1345, 108: 0.1070, 109: 0.0788, 110: 0.0500 }
|
|
6
|
+
"10000": { 30: 1.0000, 31: 1.0000, 32: 1.0000, 33: 1.0000, 34: 0.9937, 35: 0.9869, 36: 0.9801, 37: 0.9731, 38: 0.9661, 39: 0.9591, 40: 0.9519, 41: 0.9447, 42: 0.9374, 43: 0.9301, 44: 0.9227, 45: 0.9152, 46: 0.9077, 47: 0.9001, 48: 0.8925, 49: 0.8848, 50: 0.8770, 51: 0.8692, 52: 0.8613, 53: 0.8533, 54: 0.8453, 55: 0.8373, 56: 0.8291, 57: 0.8210, 58: 0.8127, 59: 0.8045, 60: 0.7961, 61: 0.7877, 62: 0.7793, 63: 0.7708, 64: 0.7623, 65: 0.7537, 66: 0.7450, 67: 0.7363, 68: 0.7276, 69: 0.7188, 70: 0.7100, 71: 0.7011, 72: 0.6922, 73: 0.6832, 74: 0.6742, 75: 0.6651, 76: 0.6560, 77: 0.6468, 78: 0.6376, 79: 0.6284, 80: 0.6191, 81: 0.6098, 82: 0.6004, 83: 0.5903, 84: 0.5795, 85: 0.5679, 86: 0.5556, 87: 0.5425, 88: 0.5287, 89: 0.5142, 90: 0.4990, 91: 0.4830, 92: 0.4662, 93: 0.4488, 94: 0.4306, 95: 0.4116, 96: 0.3920, 97: 0.3716, 98: 0.3505, 99: 0.3286, 100: 0.3060, 101: 0.2827, 102: 0.2586, 103: 0.2339, 104: 0.2084, 105: 0.1821, 106: 0.1551, 107: 0.1275, 108: 0.0990, 109: 0.0699, 110: 0.0400 }
|
|
7
|
+
"21097": { 30: 1.0000, 31: 1.0000, 32: 1.0000, 33: 0.9935, 34: 0.9869, 35: 0.9802, 36: 0.9734, 37: 0.9666, 38: 0.9596, 39: 0.9526, 40: 0.9455, 41: 0.9384, 42: 0.9311, 43: 0.9238, 44: 0.9164, 45: 0.9090, 46: 0.9014, 47: 0.8938, 48: 0.8862, 49: 0.8784, 50: 0.8706, 51: 0.8627, 52: 0.8548, 53: 0.8468, 54: 0.8387, 55: 0.8306, 56: 0.8224, 57: 0.8141, 58: 0.8058, 59: 0.7974, 60: 0.7889, 61: 0.7804, 62: 0.7718, 63: 0.7632, 64: 0.7545, 65: 0.7457, 66: 0.7369, 67: 0.7280, 68: 0.7191, 69: 0.7101, 70: 0.7011, 71: 0.6920, 72: 0.6828, 73: 0.6736, 74: 0.6644, 75: 0.6551, 76: 0.6457, 77: 0.6363, 78: 0.6268, 79: 0.6173, 80: 0.6078, 81: 0.5982, 82: 0.5879, 83: 0.5769, 84: 0.5653, 85: 0.5530, 86: 0.5401, 87: 0.5265, 88: 0.5122, 89: 0.4972, 90: 0.4816, 91: 0.4653, 92: 0.4484, 93: 0.4307, 94: 0.4125, 95: 0.3935, 96: 0.3739, 97: 0.3536, 98: 0.3327, 99: 0.3111, 100: 0.2888, 101: 0.2659, 102: 0.2424, 103: 0.2181, 104: 0.1932, 105: 0.1677, 106: 0.1414, 107: 0.1146, 108: 0.0870, 109: 0.0588, 110: 0.0300 }
|
|
8
|
+
"42195": { 30: 1.0000, 31: 1.0000, 32: 1.0000, 33: 1.0000, 34: 1.0000, 35: 0.9982, 36: 0.9918, 37: 0.9854, 38: 0.9789, 39: 0.9722, 40: 0.9654, 41: 0.9585, 42: 0.9515, 43: 0.9444, 44: 0.9371, 45: 0.9298, 46: 0.9223, 47: 0.9148, 48: 0.9071, 49: 0.8993, 50: 0.8915, 51: 0.8835, 52: 0.8754, 53: 0.8672, 54: 0.8590, 55: 0.8506, 56: 0.8421, 57: 0.8336, 58: 0.8249, 59: 0.8162, 60: 0.8073, 61: 0.7984, 62: 0.7894, 63: 0.7803, 64: 0.7711, 65: 0.7618, 66: 0.7524, 67: 0.7430, 68: 0.7335, 69: 0.7239, 70: 0.7142, 71: 0.7044, 72: 0.6946, 73: 0.6846, 74: 0.6746, 75: 0.6646, 76: 0.6544, 77: 0.6442, 78: 0.6339, 79: 0.6235, 80: 0.6131, 81: 0.6025, 82: 0.5914, 83: 0.5795, 84: 0.5670, 85: 0.5538, 86: 0.5400, 87: 0.5254, 88: 0.5103, 89: 0.4944, 90: 0.4779, 91: 0.4608, 92: 0.4429, 93: 0.4245, 94: 0.4053, 95: 0.3855, 96: 0.3651, 97: 0.3439, 98: 0.3222, 99: 0.2997, 100: 0.2767, 101: 0.2529, 102: 0.2285, 103: 0.2035, 104: 0.1778, 105: 0.1515, 106: 0.1245, 107: 0.0968, 108: 0.0685, 109: 0.0396, 110: 0.0100 }
|
|
9
|
+
|
|
10
|
+
M:
|
|
11
|
+
"1500": { 30: 1.0000, 31: 1.0000, 32: 1.0000, 33: 0.9973, 34: 0.9911, 35: 0.9849, 36: 0.9786, 37: 0.9723, 38: 0.9660, 39: 0.9596, 40: 0.9532, 41: 0.9468, 42: 0.9403, 43: 0.9338, 44: 0.9272, 45: 0.9206, 46: 0.9140, 47: 0.9073, 48: 0.9006, 49: 0.8939, 50: 0.8871, 51: 0.8803, 52: 0.8734, 53: 0.8666, 54: 0.8596, 55: 0.8527, 56: 0.8457, 57: 0.8387, 58: 0.8316, 59: 0.8246, 60: 0.8174, 61: 0.8103, 62: 0.8031, 63: 0.7959, 64: 0.7887, 65: 0.7814, 66: 0.7741, 67: 0.7668, 68: 0.7594, 69: 0.7520, 70: 0.7446, 71: 0.7371, 72: 0.7296, 73: 0.7221, 74: 0.7146, 75: 0.7070, 76: 0.6994, 77: 0.6918, 78: 0.6835, 79: 0.6746, 80: 0.6651, 81: 0.6549, 82: 0.6440, 83: 0.6325, 84: 0.6204, 85: 0.6076, 86: 0.5942, 87: 0.5801, 88: 0.5654, 89: 0.5501, 90: 0.5341, 91: 0.5175, 92: 0.5002, 93: 0.4823, 94: 0.4638, 95: 0.4446, 96: 0.4248, 97: 0.4043, 98: 0.3832, 99: 0.3614, 100: 0.3390, 101: 0.3160, 102: 0.2923, 103: 0.2680, 104: 0.2431, 105: 0.2175, 106: 0.1913, 107: 0.1644, 108: 0.1369, 109: 0.1088, 110: 0.0800 }
|
|
12
|
+
"3000": { 30: 1.0000, 31: 1.0000, 32: 1.0000, 33: 1.0000, 34: 1.0000, 35: 0.9993, 36: 0.9922, 37: 0.9851, 38: 0.9780, 39: 0.9708, 40: 0.9636, 41: 0.9564, 42: 0.9491, 43: 0.9419, 44: 0.9345, 45: 0.9272, 46: 0.9199, 47: 0.9125, 48: 0.9051, 49: 0.8976, 50: 0.8901, 51: 0.8827, 52: 0.8751, 53: 0.8676, 54: 0.8600, 55: 0.8524, 56: 0.8448, 57: 0.8372, 58: 0.8295, 59: 0.8218, 60: 0.8141, 61: 0.8064, 62: 0.7986, 63: 0.7908, 64: 0.7830, 65: 0.7752, 66: 0.7674, 67: 0.7595, 68: 0.7516, 69: 0.7437, 70: 0.7357, 71: 0.7278, 72: 0.7198, 73: 0.7118, 74: 0.7038, 75: 0.6957, 76: 0.6877, 77: 0.6796, 78: 0.6715, 79: 0.6634, 80: 0.6552, 81: 0.6464, 82: 0.6367, 83: 0.6263, 84: 0.6151, 85: 0.6032, 86: 0.5905, 87: 0.5771, 88: 0.5629, 89: 0.5480, 90: 0.5323, 91: 0.5158, 92: 0.4986, 93: 0.4806, 94: 0.4619, 95: 0.4425, 96: 0.4222, 97: 0.4013, 98: 0.3795, 99: 0.3570, 100: 0.3338, 101: 0.3098, 102: 0.2851, 103: 0.2596, 104: 0.2333, 105: 0.2063, 106: 0.1785, 107: 0.1500, 108: 0.1208, 109: 0.0908, 110: 0.0600 }
|
|
13
|
+
"5000": { 30: 1.0000, 31: 1.0000, 32: 1.0000, 33: 1.0000, 34: 1.0000, 35: 1.0000, 36: 1.0000, 37: 0.9943, 38: 0.9863, 39: 0.9782, 40: 0.9701, 41: 0.9621, 42: 0.9540, 43: 0.9460, 44: 0.9380, 45: 0.9299, 46: 0.9219, 47: 0.9139, 48: 0.9059, 49: 0.8980, 50: 0.8900, 51: 0.8820, 52: 0.8740, 53: 0.8661, 54: 0.8582, 55: 0.8502, 56: 0.8423, 57: 0.8344, 58: 0.8265, 59: 0.8185, 60: 0.8106, 61: 0.8028, 62: 0.7949, 63: 0.7870, 64: 0.7791, 65: 0.7713, 66: 0.7634, 67: 0.7556, 68: 0.7477, 69: 0.7399, 70: 0.7321, 71: 0.7242, 72: 0.7164, 73: 0.7086, 74: 0.7008, 75: 0.6930, 76: 0.6852, 77: 0.6775, 78: 0.6697, 79: 0.6619, 80: 0.6541, 81: 0.6464, 82: 0.6367, 83: 0.6263, 84: 0.6151, 85: 0.6032, 86: 0.5905, 87: 0.5771, 88: 0.5629, 89: 0.5480, 90: 0.5323, 91: 0.5158, 92: 0.4986, 93: 0.4806, 94: 0.4619, 95: 0.4425, 96: 0.4222, 97: 0.4013, 98: 0.3795, 99: 0.3570, 100: 0.3338, 101: 0.3098, 102: 0.2851, 103: 0.2596, 104: 0.2333, 105: 0.2063, 106: 0.1785, 107: 0.1500, 108: 0.1208, 109: 0.0908, 110: 0.0600 }
|
|
14
|
+
"10000": { 30: 1.0000, 31: 1.0000, 32: 1.0000, 33: 1.0000, 34: 0.9973, 35: 0.9897, 36: 0.9822, 37: 0.9747, 38: 0.9672, 39: 0.9597, 40: 0.9523, 41: 0.9449, 42: 0.9375, 43: 0.9301, 44: 0.9228, 45: 0.9155, 46: 0.9082, 47: 0.9009, 48: 0.8937, 49: 0.8865, 50: 0.8793, 51: 0.8722, 52: 0.8650, 53: 0.8579, 54: 0.8509, 55: 0.8438, 56: 0.8368, 57: 0.8298, 58: 0.8228, 59: 0.8158, 60: 0.8089, 61: 0.8019, 62: 0.7950, 63: 0.7882, 64: 0.7813, 65: 0.7745, 66: 0.7677, 67: 0.7609, 68: 0.7541, 69: 0.7474, 70: 0.7407, 71: 0.7340, 72: 0.7273, 73: 0.7206, 74: 0.7140, 75: 0.7073, 76: 0.7007, 77: 0.6942, 78: 0.6868, 79: 0.6787, 80: 0.6698, 81: 0.6601, 82: 0.6496, 83: 0.6383, 84: 0.6263, 85: 0.6135, 86: 0.5999, 87: 0.5856, 88: 0.5704, 89: 0.5545, 90: 0.5378, 91: 0.5203, 92: 0.5021, 93: 0.4830, 94: 0.4632, 95: 0.4426, 96: 0.4213, 97: 0.3991, 98: 0.3762, 99: 0.3524, 100: 0.3279, 101: 0.3027, 102: 0.2766, 103: 0.2498, 104: 0.2221, 105: 0.1937, 106: 0.1646, 107: 0.1346, 108: 0.1038, 109: 0.0723, 110: 0.0400 }
|
|
15
|
+
"21097": { 30: 1.0000, 31: 1.0000, 32: 1.0000, 33: 1.0000, 34: 1.0000, 35: 0.9953, 36: 0.9885, 37: 0.9816, 38: 0.9748, 39: 0.9680, 40: 0.9612, 41: 0.9544, 42: 0.9476, 43: 0.9408, 44: 0.9340, 45: 0.9272, 46: 0.9204, 47: 0.9137, 48: 0.9069, 49: 0.9002, 50: 0.8934, 51: 0.8867, 52: 0.8799, 53: 0.8732, 54: 0.8665, 55: 0.8598, 56: 0.8531, 57: 0.8464, 58: 0.8397, 59: 0.8331, 60: 0.8264, 61: 0.8197, 62: 0.8131, 63: 0.8064, 64: 0.7998, 65: 0.7931, 66: 0.7865, 67: 0.7799, 68: 0.7733, 69: 0.7666, 70: 0.7600, 71: 0.7534, 72: 0.7468, 73: 0.7396, 74: 0.7318, 75: 0.7233, 76: 0.7142, 77: 0.7044, 78: 0.6941, 79: 0.6831, 80: 0.6715, 81: 0.6592, 82: 0.6463, 83: 0.6328, 84: 0.6187, 85: 0.6039, 86: 0.5885, 87: 0.5725, 88: 0.5558, 89: 0.5385, 90: 0.5206, 91: 0.5021, 92: 0.4829, 93: 0.4631, 94: 0.4426, 95: 0.4216, 96: 0.3999, 97: 0.3776, 98: 0.3546, 99: 0.3310, 100: 0.3068, 101: 0.2820, 102: 0.2565, 103: 0.2304, 104: 0.2036, 105: 0.1763, 106: 0.1483, 107: 0.1197, 108: 0.0904, 109: 0.0605, 110: 0.0300 }
|
|
16
|
+
"42195": { 30: 1.0000, 31: 1.0000, 32: 1.0000, 33: 1.0000, 34: 1.0000, 35: 1.0000, 36: 1.0000, 37: 1.0000, 38: 0.9947, 39: 0.9876, 40: 0.9804, 41: 0.9733, 42: 0.9661, 43: 0.9589, 44: 0.9517, 45: 0.9445, 46: 0.9372, 47: 0.9299, 48: 0.9226, 49: 0.9153, 50: 0.9079, 51: 0.9005, 52: 0.8931, 53: 0.8857, 54: 0.8783, 55: 0.8708, 56: 0.8633, 57: 0.8558, 58: 0.8483, 59: 0.8407, 60: 0.8331, 61: 0.8255, 62: 0.8179, 63: 0.8103, 64: 0.8026, 65: 0.7950, 66: 0.7873, 67: 0.7796, 68: 0.7718, 69: 0.7641, 70: 0.7563, 71: 0.7485, 72: 0.7407, 73: 0.7329, 74: 0.7250, 75: 0.7165, 76: 0.7074, 77: 0.6976, 78: 0.6871, 79: 0.6760, 80: 0.6643, 81: 0.6519, 82: 0.6388, 83: 0.6251, 84: 0.6108, 85: 0.5958, 86: 0.5801, 87: 0.5638, 88: 0.5469, 89: 0.5293, 90: 0.5110, 91: 0.4921, 92: 0.4726, 93: 0.4524, 94: 0.4316, 95: 0.4101, 96: 0.3879, 97: 0.3651, 98: 0.3417, 99: 0.3176, 100: 0.2929, 101: 0.2675, 102: 0.2415, 103: 0.2148, 104: 0.1875, 105: 0.1595, 106: 0.1309, 107: 0.1017, 108: 0.0718, 109: 0.0412, 110: 0.0100 }
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# Module for calculating race times and paces for standard distances
|
|
4
4
|
#
|
|
5
5
|
# This module provides convenience methods for calculating finish times
|
|
6
|
-
# and paces for common race distances like 5K, 10K, half-marathon, and
|
|
6
|
+
# and paces for common race distances like 5K, 10K, half-marathon, marathon, and 100K.
|
|
7
7
|
module PaceCalculator
|
|
8
8
|
# Standard race distances in kilometers
|
|
9
9
|
RACE_DISTANCES = {
|
|
@@ -11,6 +11,7 @@ module PaceCalculator
|
|
|
11
11
|
'10k' => 10.0,
|
|
12
12
|
'half_marathon' => 21.0975,
|
|
13
13
|
'marathon' => 42.195,
|
|
14
|
+
'100k' => 100.0,
|
|
14
15
|
'1mile' => 1.60934,
|
|
15
16
|
'5mile' => 8.04672,
|
|
16
17
|
'10mile' => 16.0934
|
|
@@ -19,7 +20,7 @@ module PaceCalculator
|
|
|
19
20
|
# Calculates the finish time for a race given a pace per kilometer
|
|
20
21
|
#
|
|
21
22
|
# @param pace_per_km [Numeric, String] pace in seconds per km or time string (MM:SS)
|
|
22
|
-
# @param race [String, Symbol] race distance ('5k', '10k', 'half_marathon', 'marathon')
|
|
23
|
+
# @param race [String, Symbol] race distance ('5k', '10k', 'half_marathon', 'marathon', '100k')
|
|
23
24
|
# @return [Float] total time in seconds
|
|
24
25
|
# @raise [ArgumentError] if race distance is not recognized
|
|
25
26
|
#
|
|
@@ -36,7 +37,7 @@ module PaceCalculator
|
|
|
36
37
|
# Calculates the finish time for a race and returns it as a clock time string
|
|
37
38
|
#
|
|
38
39
|
# @param pace_per_km [Numeric, String] pace in seconds per km or time string (MM:SS)
|
|
39
|
-
# @param race [String, Symbol] race distance ('5k', '10k', 'half_marathon', 'marathon')
|
|
40
|
+
# @param race [String, Symbol] race distance ('5k', '10k', 'half_marathon', 'marathon', '100k')
|
|
40
41
|
# @return [String] finish time in HH:MM:SS format
|
|
41
42
|
#
|
|
42
43
|
# @example
|
|
@@ -49,7 +50,7 @@ module PaceCalculator
|
|
|
49
50
|
# Calculates the required pace per kilometer to finish a race in a target time
|
|
50
51
|
#
|
|
51
52
|
# @param target_time [Numeric, String] target finish time in seconds or time string (HH:MM:SS)
|
|
52
|
-
# @param race [String, Symbol] race distance ('5k', '10k', 'half_marathon', 'marathon')
|
|
53
|
+
# @param race [String, Symbol] race distance ('5k', '10k', 'half_marathon', 'marathon', '100k')
|
|
53
54
|
# @return [Float] required pace in seconds per kilometer
|
|
54
55
|
#
|
|
55
56
|
# @example
|
|
@@ -65,7 +66,7 @@ module PaceCalculator
|
|
|
65
66
|
# Calculates the required pace and returns it as a clock time string
|
|
66
67
|
#
|
|
67
68
|
# @param target_time [Numeric, String] target finish time in seconds or time string (HH:MM:SS)
|
|
68
|
-
# @param race [String, Symbol] race distance ('5k', '10k', 'half_marathon', 'marathon')
|
|
69
|
+
# @param race [String, Symbol] race distance ('5k', '10k', 'half_marathon', 'marathon', '100k')
|
|
69
70
|
# @return [String] required pace in MM:SS format
|
|
70
71
|
#
|
|
71
72
|
# @example
|
|
@@ -19,7 +19,7 @@ module RacePredictor
|
|
|
19
19
|
# - D2 = target distance
|
|
20
20
|
# - 1.06 = endurance/fatigue factor (longer races require proportionally more time)
|
|
21
21
|
#
|
|
22
|
-
# @param from_race [String, Symbol] known race distance ('5k', '10k', 'half_marathon', 'marathon', etc.)
|
|
22
|
+
# @param from_race [String, Symbol] known race distance ('5k', '10k', 'half_marathon', 'marathon', '100k', etc.)
|
|
23
23
|
# @param from_time [String, Numeric] time achieved at known distance (HH:MM:SS or seconds)
|
|
24
24
|
# @param to_race [String, Symbol] target race distance to predict
|
|
25
25
|
# @return [Float] predicted time in seconds
|
data/lib/calcpace/race_splits.rb
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
module RaceSplits
|
|
8
8
|
# Calculates split times for a race
|
|
9
9
|
#
|
|
10
|
-
# @param race [String, Symbol] race distance ('5k', '10k', 'half_marathon', 'marathon', etc.)
|
|
10
|
+
# @param race [String, Symbol] race distance ('5k', '10k', 'half_marathon', 'marathon', '100k', etc.)
|
|
11
11
|
# @param target_time [String] target finish time in HH:MM:SS or MM:SS format
|
|
12
12
|
# @param split_distance [String, Numeric] distance for each split ('5k', '1k', '1mile', or numeric in km)
|
|
13
13
|
# @param strategy [Symbol] pacing strategy - :even (default), :negative, or :positive
|
|
@@ -42,7 +42,7 @@ module RaceSplits
|
|
|
42
42
|
if split_distance.is_a?(Numeric)
|
|
43
43
|
split_distance.to_f
|
|
44
44
|
elsif split_distance.is_a?(String)
|
|
45
|
-
# Try to get from RACE_DISTANCES first (includes standard distances like '5k', '1mile', etc.)
|
|
45
|
+
# Try to get from RACE_DISTANCES first (includes standard distances like '5k', '100k', '1mile', etc.)
|
|
46
46
|
distance_key = split_distance.to_s.downcase
|
|
47
47
|
|
|
48
48
|
# Check if it's a standard race distance
|
data/lib/calcpace/version.rb
CHANGED
data/lib/calcpace.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative 'calcpace/calculator'
|
|
4
4
|
require_relative 'calcpace/cameron_predictor'
|
|
5
|
+
require_relative 'calcpace/age_grading'
|
|
5
6
|
require_relative 'calcpace/checker'
|
|
6
7
|
require_relative 'calcpace/converter'
|
|
7
8
|
require_relative 'calcpace/converter_chain'
|
|
@@ -35,6 +36,7 @@ require_relative 'calcpace/vo2max_estimator'
|
|
|
35
36
|
#
|
|
36
37
|
# @see https://github.com/0jonjo/calcpace
|
|
37
38
|
class Calcpace
|
|
39
|
+
include AgeGrading
|
|
38
40
|
include Calculator
|
|
39
41
|
include CameronPredictor
|
|
40
42
|
include Checker
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: calcpace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.9.
|
|
4
|
+
version: 1.9.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- João Gilberto Saraiva
|
|
@@ -31,11 +31,14 @@ files:
|
|
|
31
31
|
- Rakefile
|
|
32
32
|
- calcpace.gemspec
|
|
33
33
|
- lib/calcpace.rb
|
|
34
|
+
- lib/calcpace/age_grading.rb
|
|
34
35
|
- lib/calcpace/calculator.rb
|
|
35
36
|
- lib/calcpace/cameron_predictor.rb
|
|
36
37
|
- lib/calcpace/checker.rb
|
|
37
38
|
- lib/calcpace/converter.rb
|
|
38
39
|
- lib/calcpace/converter_chain.rb
|
|
40
|
+
- lib/calcpace/data/wma_2023_open_standards.yml
|
|
41
|
+
- lib/calcpace/data/wma_2023_road.yml
|
|
39
42
|
- lib/calcpace/errors.rb
|
|
40
43
|
- lib/calcpace/pace_calculator.rb
|
|
41
44
|
- lib/calcpace/pace_converter.rb
|