From 2c00b74cc02b55e26d68fef108596aae56080d5a Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Sat, 8 Aug 2026 10:05:05 +0200 Subject: feat: Persist Cotacol ride values --- ride/difficulty_test.go | 30 +++++++++++++++--------------- ride/ride.go | 6 ++++-- 2 files changed, 19 insertions(+), 17 deletions(-) (limited to 'ride') diff --git a/ride/difficulty_test.go b/ride/difficulty_test.go index 4b72037..142ac0a 100644 --- a/ride/difficulty_test.go +++ b/ride/difficulty_test.go @@ -7,48 +7,48 @@ import ( "github.com/stretchr/testify/assert" ) -func TestDifficultyScoreConstantClimb(t *testing.T) { +func TestCotacolConstantClimb(t *testing.T) { r := RideBuilder{precision: 100}.WithSection("2km at 7%").Build() - assert.InDelta(t, 98.0, r.DifficultyScore(), 1e-9) + assert.InDelta(t, 98.0, ride.Cotacol(r), 1e-9) } -func TestDifficultyScoreIgnoresDescent(t *testing.T) { +func TestCotacolIgnoresDescent(t *testing.T) { r := RideBuilder{precision: 100}.WithSection("2km at 7%").WithSection("2km at -7%").Build() - assert.InDelta(t, 98.0, r.DifficultyScore(), 1e-9) + assert.InDelta(t, 98.0, ride.Cotacol(r), 1e-9) } -func TestDifficultyScoreFlatIsZero(t *testing.T) { +func TestCotacolFlatIsZero(t *testing.T) { r := RideBuilder{precision: 100}.WithSection("5km at 0%").Build() - assert.Zero(t, r.DifficultyScore()) + assert.Zero(t, ride.Cotacol(r)) } -func TestDifficultyScoreSteepShortCountsMore(t *testing.T) { +func TestCotacolSteepShortCountsMore(t *testing.T) { steep := RideBuilder{precision: 100}.WithSection("0.5km at 14%").Build() long := RideBuilder{precision: 100}.WithSection("1km at 7%").Build() - assert.InDelta(t, 98.0, steep.DifficultyScore(), 1e-9) - assert.InDelta(t, 49.0, long.DifficultyScore(), 1e-9) + assert.InDelta(t, 98.0, ride.Cotacol(steep), 1e-9) + assert.InDelta(t, 49.0, ride.Cotacol(long), 1e-9) } -func TestDifficultyScorePrecisionInvariant(t *testing.T) { +func TestCotacolPrecisionInvariant(t *testing.T) { coarse := RideBuilder{precision: 100}.WithSection("3km at 5%").Build() fine := RideBuilder{precision: 50}.WithSection("3km at 5%").Build() - assert.InDelta(t, coarse.DifficultyScore(), fine.DifficultyScore(), 1e-9) + assert.InDelta(t, ride.Cotacol(coarse), ride.Cotacol(fine), 1e-9) } -func TestDifficultyScoreExampleRide(t *testing.T) { +func TestCotacolExampleRide(t *testing.T) { r, err := ride.ParseFile(parser, "../examples/2022-07-21.Pogacar.gpx") assert.NoError(t, err) - assert.InDelta(t, 3049.0, r.DifficultyScore(), 1) + assert.InDelta(t, 3049.0, ride.Cotacol(r), 1) } -func TestDifficultyScoreClimbNotAtStart(t *testing.T) { +func TestCotacolClimbNotAtStart(t *testing.T) { r := RideBuilder{precision: 100}.WithSection("1km at 0%").WithSection("2km at 7%").Build() climbs := r.AllClimbs() assert.Len(t, climbs, 1) assert.InDelta(t, 98.0, climbs[0].DifficultyScore(), 1e-9) } -func TestDifficultyScoreHautacamClimbfinderReference(t *testing.T) { +func TestCotacolHautacamClimbfinderReference(t *testing.T) { r, err := ride.ParseFile(parser, "../examples/2022-07-21.Pogacar.gpx") assert.NoError(t, err) climbs := r.AllClimbs() diff --git a/ride/ride.go b/ride/ride.go index ef91272..52f95b8 100644 --- a/ride/ride.go +++ b/ride/ride.go @@ -245,8 +245,10 @@ func (r *Ride) ScoreFromKm(start, end float64) float64 { return Score(*r, i, j) } -func (r *Ride) DifficultyScore() float64 { - return difficultyScore(*r, 0, r.Len()-1) +const CotacolAlgorithmVersion = "v1" + +func Cotacol(ride Ride) float64 { + return difficultyScore(ride, 0, ride.Len()-1) } func difficultyScore(r Ride, startIndex, endIndex int) float64 { -- cgit v1.2.3