Skip to content

Instantly share code, notes, and snippets.

@aldipower
Last active March 1, 2019 14:59
Show Gist options
  • Save aldipower/4d649c10ca2ec90510bc7181419fff15 to your computer and use it in GitHub Desktop.
Save aldipower/4d649c10ca2ec90510bc7181419fff15 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"math"
"os"
"strconv"
"strings"
)
func printHelp() {
fmt.Print(`Running cadence calculator - Written by Felix Gertz
Calculates optimal cadence (steps per minute)
for specfic pace and body height relations to gain optimal hip extension.
Just put in your body height and optionally a specific pace
and you will get the optimal cadence for a natural movement of your legs
assumed they land underneath your body.
Usage:
cadence bodyHeightInCm [paceMinKm]
Example:
cadence 177
cadence 177 4:00
`)
}
// Calculates the optimal running cadence for given speed and body height
func calcCadence(speedKmh float64, bodyHeightCm int) (int) {
cadenceSpm :=
math.Ceil(160 + (speedKmh - 6) * 2.5 - (float64(bodyHeightCm) - 170) / 2)
return int(cadenceSpm)
}
func speedToPace(speedKmh float64) (string) {
paceMinkm := 60 / speedKmh
minutes := math.Floor(paceMinkm)
seconds := math.Floor((paceMinkm - minutes) * 60)
return fmt.Sprintf("%02d:%02d", int(minutes), int(seconds))
}
// Converts min/km to km/h
func paceToSpeed(pace *string) (float64, error) {
var segments []string = strings.Split(*pace, ":")
if len(segments) != 2 {
return 0, fmt.Errorf("Cannot parse pace string: %s", *pace)
}
minutes, parseErr := strconv.Atoi(segments[0]);
if parseErr != nil {
return 0,
fmt.Errorf("Cannot parse minutes portion of pace string: %s", *pace)
}
seconds, parseErr := strconv.Atoi(segments[1]);
if parseErr != nil {
return 0,
fmt.Errorf("Cannot parse seconds portion of pace string: %s", *pace)
}
return 60 / (float64(minutes) + float64(seconds) / 60), nil
}
func parseArguments() (int, string, error) {
var bodyHeight int
var pace string
var parseErr error
switch len(os.Args[1:]) {
case 2:
pace = os.Args[2]
fallthrough
case 1:
bodyHeight, parseErr = strconv.Atoi(os.Args[1])
if parseErr != nil {
return 0, "",
fmt.Errorf("Could not parse body height argument: %s", os.Args[1])
}
default:
return 0, "", fmt.Errorf("Wrong number of arguments")
}
return bodyHeight, pace, nil
}
func main() {
onError := func(err error) {
if err != nil {
printHelp()
fmt.Fprintf(os.Stderr, "\nError: %s\n", err)
os.Exit(1)
}
}
printResultline := func(speed float64, bodyHeight int) {
fmt.Printf("%s %d\n", speedToPace(speed), calcCadence(speed, bodyHeight))
}
bodyHeight, pace, err := parseArguments()
onError(err)
fmt.Printf("Pace (min/km) and cadence (spm) for %dcm body height\n", bodyHeight)
if len(pace) > 0 {
speed, err := paceToSpeed(&pace)
onError(err)
printResultline(speed, bodyHeight)
} else {
for speed := 7.0; speed <= 26.0; speed += 0.4 {
printResultline(speed, bodyHeight)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment