calcpace 1.15.0 → 1.16.0
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 +12 -1
- data/README.md +26 -0
- data/lib/calcpace/stride_calculator.rb +91 -0
- data/lib/calcpace/version.rb +1 -1
- data/lib/calcpace.rb +2 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5fd21092789d45d81f1cc1def219122a63cd74ead051cc59ee30b178198702f1
|
|
4
|
+
data.tar.gz: e67ee4c7a71c194ce57928993ee2e898947465d2647e8ffa5b85277386e652b2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee62a321a8a53d93f36698579ab5bb3a5e87c3ad744191219477492a63daafc100b07fe01421bba40835b8bfef84554698db605ca9279e7619473301b0e366cb
|
|
7
|
+
data.tar.gz: ed4c5799eeb409dbb595e594417cc9efbcb9a6316bdb93dc6f9288c3deae7291aef63ff78415ca172f8ea86789d894fa7c057ecd4887902a9e5e3b0b962e2add
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.16.0] - 2026-09-05
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `stride_length(pace, cadence, unit: :km)` — metres per step from a pace (clock
|
|
14
|
+
string or seconds per unit) and a cadence in steps per minute counting **both
|
|
15
|
+
feet**; Strava's API reports cadence as one-leg RPM, so callers reading it from
|
|
16
|
+
there must double it first.
|
|
17
|
+
- `cadence_for_stride(pace, stride, unit: :km)` — the inverse: the both-feet
|
|
18
|
+
cadence in steps per minute that a given stride length implies at a given pace.
|
|
19
|
+
|
|
10
20
|
## [1.15.0] - 2026-08-30
|
|
11
21
|
|
|
12
22
|
### Added
|
|
@@ -505,7 +515,8 @@ predictors are untouched.
|
|
|
505
515
|
|
|
506
516
|
See git history for changes in earlier versions.
|
|
507
517
|
|
|
508
|
-
[Unreleased]: https://github.com/0jonjo/calcpace/compare/v1.
|
|
518
|
+
[Unreleased]: https://github.com/0jonjo/calcpace/compare/v1.16.0...HEAD
|
|
519
|
+
[1.16.0]: https://github.com/0jonjo/calcpace/compare/v1.15.0...v1.16.0
|
|
509
520
|
[1.15.0]: https://github.com/0jonjo/calcpace/compare/v1.14.0...v1.15.0
|
|
510
521
|
[1.14.0]: https://github.com/0jonjo/calcpace/compare/v1.13.0...v1.14.0
|
|
511
522
|
[1.13.0]: https://github.com/0jonjo/calcpace/compare/v1.12.1...v1.13.0
|
data/README.md
CHANGED
|
@@ -417,6 +417,32 @@ pace bands, and age-grading tolerances agree to the metre.
|
|
|
417
417
|
|
|
418
418
|
---
|
|
419
419
|
|
|
420
|
+
### Stride & Cadence
|
|
421
|
+
|
|
422
|
+
Pace, cadence and stride length are one identity, so any two of them give the third:
|
|
423
|
+
|
|
424
|
+
```ruby
|
|
425
|
+
calc.stride_length('05:00', 170) # => 1.18
|
|
426
|
+
calc.stride_length('04:00', 180) # => 1.39
|
|
427
|
+
calc.stride_length('08:02', 170, unit: :mi) # => 1.18
|
|
428
|
+
|
|
429
|
+
calc.cadence_for_stride('05:00', 1.18) # => 169.5
|
|
430
|
+
calc.cadence_for_stride('05:30', 1.15) # => 158.1
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
`stride_length` returns metres per step (2 decimals); `cadence_for_stride` is its
|
|
434
|
+
inverse and returns steps per minute (1 decimal). Pace takes the same forms as
|
|
435
|
+
everywhere else — a clock string (`'05:00'`, `'00:05:00'`) or seconds per unit
|
|
436
|
+
(`300`) — and `unit:` says which unit that pace is per: `:km` (default) or `:mi`.
|
|
437
|
+
`8:02/mi` is `5:00/km` rounded down to the second (exactly 8:02.8), so the two strides
|
|
438
|
+
agree to the centimetre at this cadence.
|
|
439
|
+
|
|
440
|
+
Cadence is steps per minute counting **both feet** — the number a watch shows during a
|
|
441
|
+
run, typically 160–185 spm. Strava's API reports cadence as one-leg RPM, so a value
|
|
442
|
+
read from there must be doubled before it is passed in.
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
420
446
|
### Fitness Predictor (race times from VO2max)
|
|
421
447
|
|
|
422
448
|
The inverse of `estimate_vo2max`: what a given fitness is worth over a race.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Module relating pace, cadence and stride length
|
|
4
|
+
#
|
|
5
|
+
# The three quantities are one identity, not three measurements:
|
|
6
|
+
# speed (m/min) = unit_metres / pace_seconds * 60
|
|
7
|
+
# stride (m) = speed / cadence
|
|
8
|
+
# so any two of them give the third. Cadence here is steps per minute counting
|
|
9
|
+
# BOTH feet (spm) — the number a watch shows during a run. Strava's API reports
|
|
10
|
+
# cadence as one-leg RPM, so a caller reading it from there must double it
|
|
11
|
+
# before passing it in.
|
|
12
|
+
module StrideCalculator
|
|
13
|
+
# Calculates stride length from pace and cadence
|
|
14
|
+
#
|
|
15
|
+
# @param pace [Numeric, String] pace in seconds per unit or time string (MM:SS or HH:MM:SS)
|
|
16
|
+
# @param cadence [Numeric] cadence in steps per minute, both feet (must be > 0)
|
|
17
|
+
# @param unit [Symbol, String] unit the pace is expressed in — :km (default) or :mi
|
|
18
|
+
# @return [Float] stride length in metres per step, rounded to 2 decimals
|
|
19
|
+
# @raise [Calcpace::InvalidTimeFormatError] if pace is a string that is not a valid clock
|
|
20
|
+
# @raise [Calcpace::NonPositiveInputError] if pace or cadence is not positive
|
|
21
|
+
# @raise [Calcpace::UnsupportedUnitError] if unit is not :km or :mi
|
|
22
|
+
#
|
|
23
|
+
# @example
|
|
24
|
+
# # 300 s/km → 200 m/min; 200/170
|
|
25
|
+
# calc.stride_length('05:00', 170) #=> 1.18
|
|
26
|
+
# # numeric seconds per km
|
|
27
|
+
# calc.stride_length(300, 170) #=> 1.18
|
|
28
|
+
# # 8:02/mi is 5:00/km rounded down to the second
|
|
29
|
+
# calc.stride_length('08:02', 170, unit: :mi) #=> 1.18
|
|
30
|
+
def stride_length(pace, cadence, unit: :km)
|
|
31
|
+
speed = speed_meters_per_minute(pace, unit)
|
|
32
|
+
check_positive(cadence, 'Cadence')
|
|
33
|
+
|
|
34
|
+
(speed / cadence).round(2)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Calculates the cadence a given stride length implies at a given pace
|
|
38
|
+
#
|
|
39
|
+
# The inverse of #stride_length: it answers what turnover a runner needs to
|
|
40
|
+
# hold a pace with the stride they actually have.
|
|
41
|
+
#
|
|
42
|
+
# @param pace [Numeric, String] pace in seconds per unit or time string (MM:SS or HH:MM:SS)
|
|
43
|
+
# @param stride [Numeric] stride length in metres per step (must be > 0)
|
|
44
|
+
# @param unit [Symbol, String] unit the pace is expressed in — :km (default) or :mi
|
|
45
|
+
# @return [Float] cadence in steps per minute, both feet, rounded to 1 decimal
|
|
46
|
+
# @raise [Calcpace::InvalidTimeFormatError] if pace is a string that is not a valid clock
|
|
47
|
+
# @raise [Calcpace::NonPositiveInputError] if pace or stride is not positive
|
|
48
|
+
# @raise [Calcpace::UnsupportedUnitError] if unit is not :km or :mi
|
|
49
|
+
#
|
|
50
|
+
# @example
|
|
51
|
+
# # 200 m/min / 1.18 m
|
|
52
|
+
# calc.cadence_for_stride('05:00', 1.18) #=> 169.5
|
|
53
|
+
# calc.cadence_for_stride('05:30', 1.15) #=> 158.1
|
|
54
|
+
def cadence_for_stride(pace, stride, unit: :km)
|
|
55
|
+
speed = speed_meters_per_minute(pace, unit)
|
|
56
|
+
check_positive(stride, 'Stride')
|
|
57
|
+
|
|
58
|
+
(speed / stride).round(1)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
# Turns a pace (clock string or seconds per unit) into a running speed
|
|
64
|
+
#
|
|
65
|
+
# A String pace is checked as a clock before it is parsed, the way
|
|
66
|
+
# Calculator#validate_time, Vo2maxEstimator and AgeGrading check theirs — so
|
|
67
|
+
# '05:xx' is a format error, not a silently truncated pace. The unit is
|
|
68
|
+
# resolved first, so a bad unit wins over a bad pace, as it does in
|
|
69
|
+
# FitnessPredictor#race_times_from_vo2max.
|
|
70
|
+
#
|
|
71
|
+
# @param pace [Numeric, String] pace in seconds per unit or time string
|
|
72
|
+
# @param unit [Symbol, String] :km or :mi
|
|
73
|
+
# @return [Float] speed in metres per minute
|
|
74
|
+
def speed_meters_per_minute(pace, unit)
|
|
75
|
+
meters = pace_unit_meters(unit)
|
|
76
|
+
pace_seconds = pace_seconds_from(pace)
|
|
77
|
+
check_positive(pace_seconds, 'Pace')
|
|
78
|
+
|
|
79
|
+
meters / pace_seconds * 60.0
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# @param pace [Numeric, String] pace in seconds per unit or time string
|
|
83
|
+
# @return [Numeric] the pace in seconds
|
|
84
|
+
# @raise [Calcpace::InvalidTimeFormatError] if a string pace is not a valid clock
|
|
85
|
+
def pace_seconds_from(pace)
|
|
86
|
+
return pace unless pace.is_a?(String)
|
|
87
|
+
|
|
88
|
+
check_time(pace)
|
|
89
|
+
convert_to_seconds(pace)
|
|
90
|
+
end
|
|
91
|
+
end
|
data/lib/calcpace/version.rb
CHANGED
data/lib/calcpace.rb
CHANGED
|
@@ -13,6 +13,7 @@ require_relative 'calcpace/pace_calculator'
|
|
|
13
13
|
require_relative 'calcpace/pace_converter'
|
|
14
14
|
require_relative 'calcpace/race_predictor'
|
|
15
15
|
require_relative 'calcpace/race_splits'
|
|
16
|
+
require_relative 'calcpace/stride_calculator'
|
|
16
17
|
require_relative 'calcpace/track_calculator'
|
|
17
18
|
require_relative 'calcpace/training_zones'
|
|
18
19
|
require_relative 'calcpace/vo2max_estimator'
|
|
@@ -51,6 +52,7 @@ class Calcpace
|
|
|
51
52
|
include PaceConverter
|
|
52
53
|
include RacePredictor
|
|
53
54
|
include RaceSplits
|
|
55
|
+
include StrideCalculator
|
|
54
56
|
include TrackCalculator
|
|
55
57
|
include TrainingZones
|
|
56
58
|
include Vo2maxEstimator
|
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.
|
|
4
|
+
version: 1.16.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- João Gilberto Saraiva
|
|
@@ -49,6 +49,7 @@ files:
|
|
|
49
49
|
- lib/calcpace/pace_converter.rb
|
|
50
50
|
- lib/calcpace/race_predictor.rb
|
|
51
51
|
- lib/calcpace/race_splits.rb
|
|
52
|
+
- lib/calcpace/stride_calculator.rb
|
|
52
53
|
- lib/calcpace/track_calculator.rb
|
|
53
54
|
- lib/calcpace/training_zones.rb
|
|
54
55
|
- lib/calcpace/version.rb
|